1ddde725dSArmin Le Grand /**************************************************************
2ddde725dSArmin Le Grand  *
3ddde725dSArmin Le Grand  * Licensed to the Apache Software Foundation (ASF) under one
4ddde725dSArmin Le Grand  * or more contributor license agreements.  See the NOTICE file
5ddde725dSArmin Le Grand  * distributed with this work for additional information
6ddde725dSArmin Le Grand  * regarding copyright ownership.  The ASF licenses this file
7ddde725dSArmin Le Grand  * to you under the Apache License, Version 2.0 (the
8ddde725dSArmin Le Grand  * "License"); you may not use this file except in compliance
9ddde725dSArmin Le Grand  * with the License.  You may obtain a copy of the License at
10ddde725dSArmin Le Grand  *
11ddde725dSArmin Le Grand  *   http://www.apache.org/licenses/LICENSE-2.0
12ddde725dSArmin Le Grand  *
13ddde725dSArmin Le Grand  * Unless required by applicable law or agreed to in writing,
14ddde725dSArmin Le Grand  * software distributed under the License is distributed on an
15ddde725dSArmin Le Grand  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16ddde725dSArmin Le Grand  * KIND, either express or implied.  See the License for the
17ddde725dSArmin Le Grand  * specific language governing permissions and limitations
18ddde725dSArmin Le Grand  * under the License.
19ddde725dSArmin Le Grand  *
20ddde725dSArmin Le Grand  *************************************************************/
21ddde725dSArmin Le Grand 
22ddde725dSArmin Le Grand // MARKER(update_precomp.py): autogen include statement, do not remove
23ddde725dSArmin Le Grand #include "precompiled_svgio.hxx"
24ddde725dSArmin Le Grand 
25ddde725dSArmin Le Grand #include <svgio/svgreader/svgdocumenthandler.hxx>
26ddde725dSArmin Le Grand #include <svgio/svgreader/svgtoken.hxx>
27ddde725dSArmin Le Grand #include <svgio/svgreader/svgsvgnode.hxx>
28ddde725dSArmin Le Grand #include <svgio/svgreader/svggnode.hxx>
29ddde725dSArmin Le Grand #include <svgio/svgreader/svgnode.hxx>
30ddde725dSArmin Le Grand #include <svgio/svgreader/svgpathnode.hxx>
31ddde725dSArmin Le Grand #include <svgio/svgreader/svgrectnode.hxx>
32ddde725dSArmin Le Grand #include <svgio/svgreader/svggradientnode.hxx>
33ddde725dSArmin Le Grand #include <svgio/svgreader/svggradientstopnode.hxx>
34ddde725dSArmin Le Grand #include <svgio/svgreader/svgsymbolnode.hxx>
35ddde725dSArmin Le Grand #include <svgio/svgreader/svgusenode.hxx>
36ddde725dSArmin Le Grand #include <svgio/svgreader/svgcirclenode.hxx>
37ddde725dSArmin Le Grand #include <svgio/svgreader/svgellipsenode.hxx>
38ddde725dSArmin Le Grand #include <svgio/svgreader/svglinenode.hxx>
39ddde725dSArmin Le Grand #include <svgio/svgreader/svgpolynode.hxx>
40ddde725dSArmin Le Grand #include <svgio/svgreader/svgsymbolnode.hxx>
41ddde725dSArmin Le Grand #include <svgio/svgreader/svgtextnode.hxx>
42ddde725dSArmin Le Grand #include <svgio/svgreader/svgcharacternode.hxx>
43ddde725dSArmin Le Grand #include <svgio/svgreader/svgtspannode.hxx>
44ddde725dSArmin Le Grand #include <svgio/svgreader/svgtrefnode.hxx>
45ddde725dSArmin Le Grand #include <svgio/svgreader/svgtextpathnode.hxx>
46ddde725dSArmin Le Grand #include <svgio/svgreader/svgstylenode.hxx>
47ddde725dSArmin Le Grand #include <svgio/svgreader/svgimagenode.hxx>
48ddde725dSArmin Le Grand #include <svgio/svgreader/svgclippathnode.hxx>
49ddde725dSArmin Le Grand #include <svgio/svgreader/svgmasknode.hxx>
50ddde725dSArmin Le Grand #include <svgio/svgreader/svgmarkernode.hxx>
51ddde725dSArmin Le Grand #include <svgio/svgreader/svgpatternnode.hxx>
52ddde725dSArmin Le Grand 
53ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
54ddde725dSArmin Le Grand 
55ddde725dSArmin Le Grand using namespace com::sun::star;
56ddde725dSArmin Le Grand 
57ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
58ddde725dSArmin Le Grand 
59ddde725dSArmin Le Grand namespace
60ddde725dSArmin Le Grand {
61ddde725dSArmin Le Grand     svgio::svgreader::SvgCharacterNode* whiteSpaceHandling(svgio::svgreader::SvgNode* pNode, svgio::svgreader::SvgCharacterNode* pLast)
62ddde725dSArmin Le Grand     {
63ddde725dSArmin Le Grand         if(pNode)
64ddde725dSArmin Le Grand         {
65ddde725dSArmin Le Grand             const svgio::svgreader::SvgNodeVector& rChilds = pNode->getChildren();
66ddde725dSArmin Le Grand             const sal_uInt32 nCount(rChilds.size());
67ddde725dSArmin Le Grand 
68ddde725dSArmin Le Grand             for(sal_uInt32 a(0); a < nCount; a++)
69ddde725dSArmin Le Grand             {
70ddde725dSArmin Le Grand                 svgio::svgreader::SvgNode* pCandidate = rChilds[a];
71ddde725dSArmin Le Grand 
72ddde725dSArmin Le Grand                 if(pCandidate)
73ddde725dSArmin Le Grand                 {
74ddde725dSArmin Le Grand                     switch(pCandidate->getType())
75ddde725dSArmin Le Grand                     {
76ddde725dSArmin Le Grand                         case svgio::svgreader::SVGTokenCharacter:
77ddde725dSArmin Le Grand                         {
78ddde725dSArmin Le Grand                             // clean whitespace in text span
79ddde725dSArmin Le Grand                             svgio::svgreader::SvgCharacterNode* pCharNode = static_cast< svgio::svgreader::SvgCharacterNode* >(pCandidate);
80ddde725dSArmin Le Grand                             pCharNode->whiteSpaceHandling();
81ddde725dSArmin Le Grand 
82ddde725dSArmin Le Grand                             // pCharNode may have lost all text. If that's the case, ignore
83ddde725dSArmin Le Grand                             // as invalid character node
84ddde725dSArmin Le Grand                             if(pCharNode->getText().getLength())
85ddde725dSArmin Le Grand                             {
86ddde725dSArmin Le Grand                                 if(pLast)
87ddde725dSArmin Le Grand                                 {
88ddde725dSArmin Le Grand                                     // add in-between whitespace (single space) to last
89ddde725dSArmin Le Grand                                     // known character node
90ddde725dSArmin Le Grand                                     pLast->addGap();
91ddde725dSArmin Le Grand                                 }
92ddde725dSArmin Le Grand 
93ddde725dSArmin Le Grand                                 // remember new last corected character node
94ddde725dSArmin Le Grand                                 pLast = pCharNode;
95ddde725dSArmin Le Grand                             }
96ddde725dSArmin Le Grand                             break;
97ddde725dSArmin Le Grand                         }
98ddde725dSArmin Le Grand                         case svgio::svgreader::SVGTokenTspan:
99ddde725dSArmin Le Grand                         case svgio::svgreader::SVGTokenTextPath:
100ddde725dSArmin Le Grand                         case svgio::svgreader::SVGTokenTref:
101ddde725dSArmin Le Grand                         {
102ddde725dSArmin Le Grand                             // recursively clean whitespaces in subhierarchy
103ddde725dSArmin Le Grand                             pLast = whiteSpaceHandling(pCandidate, pLast);
104ddde725dSArmin Le Grand                             break;
105ddde725dSArmin Le Grand                         }
106ddde725dSArmin Le Grand                         default:
107ddde725dSArmin Le Grand                         {
108ddde725dSArmin Le Grand                             OSL_ENSURE(false, "Unexpected token inside SVGTokenText (!)");
109ddde725dSArmin Le Grand                             break;
110ddde725dSArmin Le Grand                         }
111ddde725dSArmin Le Grand                     }
112ddde725dSArmin Le Grand                 }
113ddde725dSArmin Le Grand             }
114ddde725dSArmin Le Grand         }
115ddde725dSArmin Le Grand 
116ddde725dSArmin Le Grand         return pLast;
117ddde725dSArmin Le Grand     }
118ddde725dSArmin Le Grand }
119ddde725dSArmin Le Grand 
120ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
121ddde725dSArmin Le Grand 
122ddde725dSArmin Le Grand namespace svgio
123ddde725dSArmin Le Grand {
124ddde725dSArmin Le Grand     namespace svgreader
125ddde725dSArmin Le Grand     {
126ddde725dSArmin Le Grand         SvgDocHdl::SvgDocHdl(const rtl::OUString& aAbsolutePath)
127ddde725dSArmin Le Grand         :   maDocument(aAbsolutePath),
128ddde725dSArmin Le Grand             mpTarget(0)
129ddde725dSArmin Le Grand         {
130ddde725dSArmin Le Grand         }
131ddde725dSArmin Le Grand 
132ddde725dSArmin Le Grand         SvgDocHdl::~SvgDocHdl()
133ddde725dSArmin Le Grand         {
134ddde725dSArmin Le Grand #ifdef DBG_UTIL
135ddde725dSArmin Le Grand             if(mpTarget)
136ddde725dSArmin Le Grand             {
137ddde725dSArmin Le Grand                 OSL_ENSURE(false, "SvgDocHdl destructed with active target (!)");
138ddde725dSArmin Le Grand                 delete mpTarget;
139ddde725dSArmin Le Grand             }
140ddde725dSArmin Le Grand #endif
141ddde725dSArmin Le Grand         }
142ddde725dSArmin Le Grand 
143ddde725dSArmin Le Grand         void SvgDocHdl::startDocument(  ) throw (xml::sax::SAXException, uno::RuntimeException)
144ddde725dSArmin Le Grand         {
145ddde725dSArmin Le Grand             OSL_ENSURE(!mpTarget, "Already a target at document start (!)");
146ddde725dSArmin Le Grand         }
147ddde725dSArmin Le Grand 
148ddde725dSArmin Le Grand         void SvgDocHdl::endDocument(  ) throw (xml::sax::SAXException, uno::RuntimeException)
149ddde725dSArmin Le Grand         {
150ddde725dSArmin Le Grand             OSL_ENSURE(!mpTarget, "Still a target at document end (!)");
151ddde725dSArmin Le Grand         }
152ddde725dSArmin Le Grand 
153ddde725dSArmin Le Grand         void SvgDocHdl::startElement( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs ) throw (xml::sax::SAXException, uno::RuntimeException)
154ddde725dSArmin Le Grand         {
155ddde725dSArmin Le Grand             if(aName.getLength())
156ddde725dSArmin Le Grand             {
157ddde725dSArmin Le Grand                 const SVGToken aSVGToken(StrToSVGToken(aName));
158ddde725dSArmin Le Grand 
159ddde725dSArmin Le Grand                 switch(aSVGToken)
160ddde725dSArmin Le Grand                 {
161ddde725dSArmin Le Grand                     /// structural elements
162ddde725dSArmin Le Grand                     case SVGTokenSymbol:
163ddde725dSArmin Le Grand                     {
164ddde725dSArmin Le Grand                         /// new basic node for Symbol. Content gets scanned, but
165ddde725dSArmin Le Grand                         /// will not be decomposed (see SvgNode::decomposeSvgNode and bReferenced)
166ddde725dSArmin Le Grand                         mpTarget = new SvgSymbolNode(maDocument, mpTarget);
167ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
168ddde725dSArmin Le Grand                         break;
169ddde725dSArmin Le Grand                     }
170ddde725dSArmin Le Grand                     case SVGTokenDefs:
171ddde725dSArmin Le Grand                     case SVGTokenG:
172ddde725dSArmin Le Grand                     {
173ddde725dSArmin Le Grand                         /// new node for Defs/G
174ddde725dSArmin Le Grand                         mpTarget = new SvgGNode(aSVGToken, maDocument, mpTarget);
175ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
176ddde725dSArmin Le Grand                         break;
177ddde725dSArmin Le Grand                     }
178ddde725dSArmin Le Grand                     case SVGTokenSvg:
179ddde725dSArmin Le Grand                     {
180ddde725dSArmin Le Grand                         /// new node for Svg
181ddde725dSArmin Le Grand                         mpTarget = new SvgSvgNode(maDocument, mpTarget);
182ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
183ddde725dSArmin Le Grand                         break;
184ddde725dSArmin Le Grand                     }
185ddde725dSArmin Le Grand                     case SVGTokenUse:
186ddde725dSArmin Le Grand                     {
187ddde725dSArmin Le Grand                         /// new node for Use
188ddde725dSArmin Le Grand                         mpTarget = new SvgUseNode(maDocument, mpTarget);
189ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
190ddde725dSArmin Le Grand                         break;
191ddde725dSArmin Le Grand                     }
192ddde725dSArmin Le Grand 
193ddde725dSArmin Le Grand                     /// shape elements
194ddde725dSArmin Le Grand                     case SVGTokenCircle:
195ddde725dSArmin Le Grand                     {
196ddde725dSArmin Le Grand                         /// new node for Circle
197ddde725dSArmin Le Grand                         mpTarget = new SvgCircleNode(maDocument, mpTarget);
198ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
199ddde725dSArmin Le Grand                         break;
200ddde725dSArmin Le Grand                     }
201ddde725dSArmin Le Grand                     case SVGTokenEllipse:
202ddde725dSArmin Le Grand                     {
203ddde725dSArmin Le Grand                         /// new node for Ellipse
204ddde725dSArmin Le Grand                         mpTarget = new SvgEllipseNode(maDocument, mpTarget);
205ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
206ddde725dSArmin Le Grand                         break;
207ddde725dSArmin Le Grand                     }
208ddde725dSArmin Le Grand                     case SVGTokenLine:
209ddde725dSArmin Le Grand                     {
210ddde725dSArmin Le Grand                         /// new node for Line
211ddde725dSArmin Le Grand                         mpTarget = new SvgLineNode(maDocument, mpTarget);
212ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
213ddde725dSArmin Le Grand                         break;
214ddde725dSArmin Le Grand                     }
215ddde725dSArmin Le Grand                     case SVGTokenPath:
216ddde725dSArmin Le Grand                     {
217ddde725dSArmin Le Grand                         /// new node for Path
218ddde725dSArmin Le Grand                         mpTarget = new SvgPathNode(maDocument, mpTarget);
219ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
220ddde725dSArmin Le Grand                         break;
221ddde725dSArmin Le Grand                     }
222ddde725dSArmin Le Grand                     case SVGTokenPolygon:
223ddde725dSArmin Le Grand                     {
224ddde725dSArmin Le Grand                         /// new node for Polygon
225ddde725dSArmin Le Grand                         mpTarget = new SvgPolyNode(maDocument, mpTarget, false);
226ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
227ddde725dSArmin Le Grand                         break;
228ddde725dSArmin Le Grand                     }
229ddde725dSArmin Le Grand                     case SVGTokenPolyline:
230ddde725dSArmin Le Grand                     {
231ddde725dSArmin Le Grand                         /// new node for Polyline
232ddde725dSArmin Le Grand                         mpTarget = new SvgPolyNode(maDocument, mpTarget, true);
233ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
234ddde725dSArmin Le Grand                         break;
235ddde725dSArmin Le Grand                     }
236ddde725dSArmin Le Grand                     case SVGTokenRect:
237ddde725dSArmin Le Grand                     {
238ddde725dSArmin Le Grand                         /// new node for Rect
239ddde725dSArmin Le Grand                         mpTarget = new SvgRectNode(maDocument, mpTarget);
240ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
241ddde725dSArmin Le Grand                         break;
242ddde725dSArmin Le Grand                     }
243ddde725dSArmin Le Grand                     case SVGTokenImage:
244ddde725dSArmin Le Grand                     {
245ddde725dSArmin Le Grand                         /// new node for Image
246ddde725dSArmin Le Grand                         mpTarget = new SvgImageNode(maDocument, mpTarget);
247ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
248ddde725dSArmin Le Grand                         break;
249ddde725dSArmin Le Grand                     }
250ddde725dSArmin Le Grand 
251ddde725dSArmin Le Grand                     /// gradients
252ddde725dSArmin Le Grand                     case SVGTokenLinearGradient:
253ddde725dSArmin Le Grand                     case SVGTokenRadialGradient:
254ddde725dSArmin Le Grand                     {
255ddde725dSArmin Le Grand                         mpTarget = new SvgGradientNode(aSVGToken, maDocument, mpTarget);
256ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
257ddde725dSArmin Le Grand                         break;
258ddde725dSArmin Le Grand                     }
259ddde725dSArmin Le Grand 
260ddde725dSArmin Le Grand                     /// gradient stops
261ddde725dSArmin Le Grand                     case SVGTokenStop:
262ddde725dSArmin Le Grand                     {
263ddde725dSArmin Le Grand                         mpTarget = new SvgGradientStopNode(maDocument, mpTarget);
264ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
265ddde725dSArmin Le Grand                         break;
266ddde725dSArmin Le Grand                     }
267ddde725dSArmin Le Grand 
268ddde725dSArmin Le Grand                     /// text
269ddde725dSArmin Le Grand                     case SVGTokenText:
270ddde725dSArmin Le Grand                     {
271ddde725dSArmin Le Grand                         mpTarget = new SvgTextNode(maDocument, mpTarget);
272ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
273ddde725dSArmin Le Grand                         break;
274ddde725dSArmin Le Grand                     }
275ddde725dSArmin Le Grand                     case SVGTokenTspan:
276ddde725dSArmin Le Grand                     {
277ddde725dSArmin Le Grand                         mpTarget = new SvgTspanNode(maDocument, mpTarget);
278ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
279ddde725dSArmin Le Grand                         break;
280ddde725dSArmin Le Grand                     }
281ddde725dSArmin Le Grand                     case SVGTokenTref:
282ddde725dSArmin Le Grand                     {
283ddde725dSArmin Le Grand                         mpTarget = new SvgTrefNode(maDocument, mpTarget);
284ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
285ddde725dSArmin Le Grand                         break;
286ddde725dSArmin Le Grand                     }
287ddde725dSArmin Le Grand                     case SVGTokenTextPath:
288ddde725dSArmin Le Grand                     {
289ddde725dSArmin Le Grand                         mpTarget = new SvgTextPathNode(maDocument, mpTarget);
290ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
291ddde725dSArmin Le Grand                         break;
292ddde725dSArmin Le Grand                     }
293ddde725dSArmin Le Grand 
294ddde725dSArmin Le Grand                     /// styles (as stylesheets)
295ddde725dSArmin Le Grand                     case SVGTokenStyle:
296ddde725dSArmin Le Grand                     {
297ddde725dSArmin Le Grand                         mpTarget = new SvgStyleNode(maDocument, mpTarget);
298ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
299ddde725dSArmin Le Grand                         break;
300ddde725dSArmin Le Grand                     }
301ddde725dSArmin Le Grand 
302ddde725dSArmin Le Grand                     /// structural elements clip-path and mask. Content gets scanned, but
303ddde725dSArmin Le Grand                     /// will not be decomposed (see SvgNode::decomposeSvgNode and bReferenced)
304ddde725dSArmin Le Grand                     case SVGTokenClipPathNode:
305ddde725dSArmin Le Grand                     {
306ddde725dSArmin Le Grand                         /// new node for ClipPath
307ddde725dSArmin Le Grand                         mpTarget = new SvgClipPathNode(maDocument, mpTarget);
308ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
309ddde725dSArmin Le Grand                         break;
310ddde725dSArmin Le Grand                     }
311ddde725dSArmin Le Grand                     case SVGTokenMask:
312ddde725dSArmin Le Grand                     {
313ddde725dSArmin Le Grand                         /// new node for Mask
314ddde725dSArmin Le Grand                         mpTarget = new SvgMaskNode(maDocument, mpTarget);
315ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
316ddde725dSArmin Le Grand                         break;
317ddde725dSArmin Le Grand                     }
318ddde725dSArmin Le Grand 
319ddde725dSArmin Le Grand                     /// structural element marker
320ddde725dSArmin Le Grand                     case SVGTokenMarker:
321ddde725dSArmin Le Grand                     {
322ddde725dSArmin Le Grand                         /// new node for marker
323ddde725dSArmin Le Grand                         mpTarget = new SvgMarkerNode(maDocument, mpTarget);
324ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
325ddde725dSArmin Le Grand                         break;
326ddde725dSArmin Le Grand                     }
327ddde725dSArmin Le Grand 
328ddde725dSArmin Le Grand                     /// structural element pattern
329ddde725dSArmin Le Grand                     case SVGTokenPattern:
330ddde725dSArmin Le Grand                     {
331ddde725dSArmin Le Grand                         /// new node for pattern
332ddde725dSArmin Le Grand                         mpTarget = new SvgPatternNode(maDocument, mpTarget);
333ddde725dSArmin Le Grand                         mpTarget->parseAttributes(xAttribs);
334ddde725dSArmin Le Grand                         break;
335ddde725dSArmin Le Grand                     }
336ddde725dSArmin Le Grand 
337ddde725dSArmin Le Grand                     default:
338ddde725dSArmin Le Grand                     {
339ddde725dSArmin Le Grand                         /// invalid token, ignore
340ddde725dSArmin Le Grand #ifdef DBG_UTIL
341ddde725dSArmin Le Grand                         myAssert(
342ddde725dSArmin Le Grand                             rtl::OUString::createFromAscii("Unknown Base SvgToken <") +
343ddde725dSArmin Le Grand                             aName +
344ddde725dSArmin Le Grand                             rtl::OUString::createFromAscii("> (!)"));
345ddde725dSArmin Le Grand #endif
346ddde725dSArmin Le Grand                         break;
347ddde725dSArmin Le Grand                     }
348ddde725dSArmin Le Grand                 }
349ddde725dSArmin Le Grand             }
350ddde725dSArmin Le Grand         }
351ddde725dSArmin Le Grand 
352ddde725dSArmin Le Grand         void SvgDocHdl::endElement( const ::rtl::OUString& aName ) throw (xml::sax::SAXException, uno::RuntimeException)
353ddde725dSArmin Le Grand         {
354ddde725dSArmin Le Grand             if(aName.getLength())
355ddde725dSArmin Le Grand             {
356ddde725dSArmin Le Grand                 const SVGToken aSVGToken(StrToSVGToken(aName));
357ddde725dSArmin Le Grand                 SvgNode* pWhitespaceCheck(SVGTokenText == aSVGToken ? mpTarget : 0);
358ddde725dSArmin Le Grand 
359ddde725dSArmin Le Grand                 switch(aSVGToken)
360ddde725dSArmin Le Grand                 {
361ddde725dSArmin Le Grand                     /// valid tokens for which a new one was created
362ddde725dSArmin Le Grand 
363ddde725dSArmin Le Grand                     /// structural elements
364ddde725dSArmin Le Grand                     case SVGTokenDefs:
365ddde725dSArmin Le Grand                     case SVGTokenG:
366ddde725dSArmin Le Grand                     case SVGTokenSvg:
367ddde725dSArmin Le Grand                     case SVGTokenSymbol:
368ddde725dSArmin Le Grand                     case SVGTokenUse:
369ddde725dSArmin Le Grand 
370ddde725dSArmin Le Grand                     /// shape elements
371ddde725dSArmin Le Grand                     case SVGTokenCircle:
372ddde725dSArmin Le Grand                     case SVGTokenEllipse:
373ddde725dSArmin Le Grand                     case SVGTokenLine:
374ddde725dSArmin Le Grand                     case SVGTokenPath:
375ddde725dSArmin Le Grand                     case SVGTokenPolygon:
376ddde725dSArmin Le Grand                     case SVGTokenPolyline:
377ddde725dSArmin Le Grand                     case SVGTokenRect:
378ddde725dSArmin Le Grand                     case SVGTokenImage:
379ddde725dSArmin Le Grand 
380ddde725dSArmin Le Grand                     /// gradients
381ddde725dSArmin Le Grand                     case SVGTokenLinearGradient:
382ddde725dSArmin Le Grand                     case SVGTokenRadialGradient:
383ddde725dSArmin Le Grand 
384ddde725dSArmin Le Grand                     /// gradient stops
385ddde725dSArmin Le Grand                     case SVGTokenStop:
386ddde725dSArmin Le Grand 
387ddde725dSArmin Le Grand                     /// text
388ddde725dSArmin Le Grand                     case SVGTokenText:
389ddde725dSArmin Le Grand                     case SVGTokenTspan:
390ddde725dSArmin Le Grand                     case SVGTokenTextPath:
391ddde725dSArmin Le Grand                     case SVGTokenTref:
392ddde725dSArmin Le Grand 
393ddde725dSArmin Le Grand                     /// styles (as stylesheets)
394ddde725dSArmin Le Grand                     case SVGTokenStyle:
395ddde725dSArmin Le Grand 
396ddde725dSArmin Le Grand                     /// structural elements clip-path and mask
397ddde725dSArmin Le Grand                     case SVGTokenClipPathNode:
398ddde725dSArmin Le Grand                     case SVGTokenMask:
399ddde725dSArmin Le Grand 
400ddde725dSArmin Le Grand                     /// structural element marker
401ddde725dSArmin Le Grand                     case SVGTokenMarker:
402ddde725dSArmin Le Grand 
403ddde725dSArmin Le Grand                     /// structural element pattern
404ddde725dSArmin Le Grand                     case SVGTokenPattern:
405ddde725dSArmin Le Grand 
406ddde725dSArmin Le Grand                     /// content handling after parsing
407ddde725dSArmin Le Grand                     {
408ddde725dSArmin Le Grand                         if(mpTarget)
409ddde725dSArmin Le Grand                         {
410ddde725dSArmin Le Grand                             if(!mpTarget->getParent())
411ddde725dSArmin Le Grand                             {
412ddde725dSArmin Le Grand                                 // last element closing, save this tree
413ddde725dSArmin Le Grand                                 maDocument.appendNode(mpTarget);
414ddde725dSArmin Le Grand                             }
415ddde725dSArmin Le Grand 
416ddde725dSArmin Le Grand                             mpTarget = const_cast< SvgNode* >(mpTarget->getParent());
417ddde725dSArmin Le Grand                         }
418ddde725dSArmin Le Grand                         else
419ddde725dSArmin Le Grand                         {
420ddde725dSArmin Le Grand                             OSL_ENSURE(false, "Closing token, but no context (!)");
421ddde725dSArmin Le Grand                         }
422ddde725dSArmin Le Grand                         break;
423ddde725dSArmin Le Grand                     }
424ddde725dSArmin Le Grand                     default:
425ddde725dSArmin Le Grand                     {
426ddde725dSArmin Le Grand                         /// invalid token, ignore
427ddde725dSArmin Le Grand                     }
428ddde725dSArmin Le Grand                 }
429ddde725dSArmin Le Grand 
430ddde725dSArmin Le Grand                 if(pWhitespaceCheck)
431ddde725dSArmin Le Grand                 {
432ddde725dSArmin Le Grand                     // cleanup read strings
433ddde725dSArmin Le Grand                     whiteSpaceHandling(pWhitespaceCheck, 0);
434ddde725dSArmin Le Grand                 }
435ddde725dSArmin Le Grand             }
436ddde725dSArmin Le Grand         }
437ddde725dSArmin Le Grand 
438ddde725dSArmin Le Grand         void SvgDocHdl::characters( const ::rtl::OUString& aChars ) throw (xml::sax::SAXException, uno::RuntimeException)
439ddde725dSArmin Le Grand         {
440ddde725dSArmin Le Grand             if(mpTarget)
441ddde725dSArmin Le Grand             {
442ddde725dSArmin Le Grand                 const sal_uInt32 nLength(aChars.getLength());
443ddde725dSArmin Le Grand 
444ddde725dSArmin Le Grand                 if(nLength &&
445ddde725dSArmin Le Grand                     (SVGTokenText == mpTarget->getType() ||
446ddde725dSArmin Le Grand                     SVGTokenTspan == mpTarget->getType() ||
447ddde725dSArmin Le Grand                     SVGTokenTextPath == mpTarget->getType() ||
448ddde725dSArmin Le Grand                     SVGTokenStyle == mpTarget->getType()))
449ddde725dSArmin Le Grand                 {
450ddde725dSArmin Le Grand                     switch(mpTarget->getType())
451ddde725dSArmin Le Grand                     {
452ddde725dSArmin Le Grand                         case SVGTokenText:
453ddde725dSArmin Le Grand                         case SVGTokenTspan:
454ddde725dSArmin Le Grand                         case SVGTokenTextPath:
455ddde725dSArmin Le Grand                         {
456ddde725dSArmin Le Grand                             const SvgNodeVector& rChilds = mpTarget->getChildren();
457ddde725dSArmin Le Grand                             SvgCharacterNode* pTarget = 0;
458ddde725dSArmin Le Grand 
459ddde725dSArmin Le Grand                             if(rChilds.size())
460ddde725dSArmin Le Grand                             {
461ddde725dSArmin Le Grand                                 pTarget = dynamic_cast< SvgCharacterNode* >(rChilds[rChilds.size() - 1]);
462ddde725dSArmin Le Grand                             }
463ddde725dSArmin Le Grand 
464ddde725dSArmin Le Grand                             if(pTarget)
465ddde725dSArmin Le Grand                             {
466ddde725dSArmin Le Grand                                 // concatenate to current character span
467ddde725dSArmin Le Grand                                 pTarget->concatenate(aChars);
468ddde725dSArmin Le Grand                             }
469ddde725dSArmin Le Grand                             else
470ddde725dSArmin Le Grand                             {
471ddde725dSArmin Le Grand                                 // add character span as simplified tspan (no arguments)
472ddde725dSArmin Le Grand                                 // as direct child of SvgTextNode/SvgTspanNode/SvgTextPathNode
473ddde725dSArmin Le Grand                                 new SvgCharacterNode(maDocument, mpTarget, aChars);
474ddde725dSArmin Le Grand                             }
475ddde725dSArmin Le Grand                             break;
476ddde725dSArmin Le Grand                         }
477ddde725dSArmin Le Grand                         case SVGTokenStyle:
478ddde725dSArmin Le Grand                         {
479ddde725dSArmin Le Grand                             SvgStyleNode& rSvgStyleNode = static_cast< SvgStyleNode& >(*mpTarget);
480ddde725dSArmin Le Grand 
481ddde725dSArmin Le Grand                             if(rSvgStyleNode.isTextCss())
482ddde725dSArmin Le Grand                             {
483ddde725dSArmin Le Grand                                 // need to interpret css styles and remember them as StyleSheets
484ddde725dSArmin Le Grand                                 const ::rtl::OUString aTrimmedChars(aChars.trim());
485ddde725dSArmin Le Grand 
486ddde725dSArmin Le Grand                                 if(aTrimmedChars.getLength())
487ddde725dSArmin Le Grand                                 {
488ddde725dSArmin Le Grand                                     rSvgStyleNode.addCssStyleSheet(aTrimmedChars);
489ddde725dSArmin Le Grand                                 }
490ddde725dSArmin Le Grand                             }
491ddde725dSArmin Le Grand                             break;
492ddde725dSArmin Le Grand                         }
493ddde725dSArmin Le Grand                         default:
494ddde725dSArmin Le Grand                         {
495ddde725dSArmin Le Grand                             // characters not used by a known node
496ddde725dSArmin Le Grand                             break;
497ddde725dSArmin Le Grand                         }
498ddde725dSArmin Le Grand                     }
499ddde725dSArmin Le Grand                 }
500ddde725dSArmin Le Grand             }
501ddde725dSArmin Le Grand         }
502ddde725dSArmin Le Grand 
503*e2bf1e9dSArmin Le Grand         void SvgDocHdl::ignorableWhitespace(const ::rtl::OUString& /*aWhitespaces*/) throw (xml::sax::SAXException, uno::RuntimeException)
504ddde725dSArmin Le Grand         {
505ddde725dSArmin Le Grand         }
506ddde725dSArmin Le Grand 
507*e2bf1e9dSArmin Le Grand         void SvgDocHdl::processingInstruction(const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/) throw (xml::sax::SAXException, uno::RuntimeException)
508ddde725dSArmin Le Grand         {
509ddde725dSArmin Le Grand         }
510ddde725dSArmin Le Grand 
511*e2bf1e9dSArmin Le Grand         void SvgDocHdl::setDocumentLocator(const uno::Reference< xml::sax::XLocator >& /*xLocator*/) throw (xml::sax::SAXException, uno::RuntimeException)
512ddde725dSArmin Le Grand         {
513ddde725dSArmin Le Grand         }
514ddde725dSArmin Le Grand     } // end of namespace svgreader
515ddde725dSArmin Le Grand } // end of namespace svgio
516ddde725dSArmin Le Grand 
517ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
518ddde725dSArmin Le Grand // eof
519