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