xref: /aoo41x/main/svgio/source/svgreader/svgnode.cxx (revision ddde725d)
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/svgnode.hxx>
26*ddde725dSArmin Le Grand #include <basegfx/polygon/b2dpolypolygontools.hxx>
27*ddde725dSArmin Le Grand #include <svgio/svgreader/svgdocument.hxx>
28*ddde725dSArmin Le Grand #include <svgio/svgreader/svgnode.hxx>
29*ddde725dSArmin Le Grand #include <svgio/svgreader/svgstyleattributes.hxx>
30*ddde725dSArmin Le Grand 
31*ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
32*ddde725dSArmin Le Grand 
33*ddde725dSArmin Le Grand namespace svgio
34*ddde725dSArmin Le Grand {
35*ddde725dSArmin Le Grand     namespace svgreader
36*ddde725dSArmin Le Grand     {
37*ddde725dSArmin Le Grand         const SvgStyleAttributes* SvgNode::getSvgStyleAttributes() const
38*ddde725dSArmin Le Grand         {
39*ddde725dSArmin Le Grand             return 0;
40*ddde725dSArmin Le Grand         }
41*ddde725dSArmin Le Grand 
42*ddde725dSArmin Le Grand         SvgNode::SvgNode(
43*ddde725dSArmin Le Grand             SVGToken aType,
44*ddde725dSArmin Le Grand             SvgDocument& rDocument,
45*ddde725dSArmin Le Grand             SvgNode* pParent)
46*ddde725dSArmin Le Grand         :   maType(aType),
47*ddde725dSArmin Le Grand             mrDocument(rDocument),
48*ddde725dSArmin Le Grand             mpParent(pParent),
49*ddde725dSArmin Le Grand             mpAlternativeParent(0),
50*ddde725dSArmin Le Grand             maChildren(),
51*ddde725dSArmin Le Grand             mpId(0),
52*ddde725dSArmin Le Grand             mpClass(0),
53*ddde725dSArmin Le Grand             maXmlSpace(XmlSpace_notset)
54*ddde725dSArmin Le Grand         {
55*ddde725dSArmin Le Grand             OSL_ENSURE(SVGTokenUnknown != maType, "SvgNode with unknown type created (!)");
56*ddde725dSArmin Le Grand 
57*ddde725dSArmin Le Grand             if(pParent)
58*ddde725dSArmin Le Grand             {
59*ddde725dSArmin Le Grand                 pParent->maChildren.push_back(this);
60*ddde725dSArmin Le Grand             }
61*ddde725dSArmin Le Grand             else
62*ddde725dSArmin Le Grand             {
63*ddde725dSArmin Le Grand #ifdef DBG_UTIL
64*ddde725dSArmin Le Grand                 if(SVGTokenSvg != getType())
65*ddde725dSArmin Le Grand                 {
66*ddde725dSArmin Le Grand                     OSL_ENSURE(false, "No parent for this node (!)");
67*ddde725dSArmin Le Grand                 }
68*ddde725dSArmin Le Grand #endif
69*ddde725dSArmin Le Grand             }
70*ddde725dSArmin Le Grand         }
71*ddde725dSArmin Le Grand 
72*ddde725dSArmin Le Grand         SvgNode::~SvgNode()
73*ddde725dSArmin Le Grand         {
74*ddde725dSArmin Le Grand             while(maChildren.size())
75*ddde725dSArmin Le Grand             {
76*ddde725dSArmin Le Grand                 delete maChildren[maChildren.size() - 1];
77*ddde725dSArmin Le Grand                 maChildren.pop_back();
78*ddde725dSArmin Le Grand             }
79*ddde725dSArmin Le Grand 
80*ddde725dSArmin Le Grand             if(mpId) delete mpId;
81*ddde725dSArmin Le Grand             if(mpClass) delete mpClass;
82*ddde725dSArmin Le Grand         }
83*ddde725dSArmin Le Grand 
84*ddde725dSArmin Le Grand         void SvgNode::parseAttributes(const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttribs)
85*ddde725dSArmin Le Grand         {
86*ddde725dSArmin Le Grand             const sal_uInt32 nAttributes(xAttribs->getLength());
87*ddde725dSArmin Le Grand 
88*ddde725dSArmin Le Grand             for(sal_uInt32 a(0); a < nAttributes; a++)
89*ddde725dSArmin Le Grand             {
90*ddde725dSArmin Le Grand                 const ::rtl::OUString aTokenName(xAttribs->getNameByIndex(a));
91*ddde725dSArmin Le Grand 
92*ddde725dSArmin Le Grand                 parseAttribute(aTokenName, StrToSVGToken(aTokenName), xAttribs->getValueByIndex(a));
93*ddde725dSArmin Le Grand             }
94*ddde725dSArmin Le Grand         }
95*ddde725dSArmin Le Grand 
96*ddde725dSArmin Le Grand         void SvgNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
97*ddde725dSArmin Le Grand         {
98*ddde725dSArmin Le Grand             switch(aSVGToken)
99*ddde725dSArmin Le Grand             {
100*ddde725dSArmin Le Grand                 case SVGTokenId:
101*ddde725dSArmin Le Grand                 {
102*ddde725dSArmin Le Grand                     if(aContent.getLength())
103*ddde725dSArmin Le Grand                     {
104*ddde725dSArmin Le Grand                         setId(&aContent);
105*ddde725dSArmin Le Grand                     }
106*ddde725dSArmin Le Grand                     break;
107*ddde725dSArmin Le Grand                 }
108*ddde725dSArmin Le Grand                 case SVGTokenClass:
109*ddde725dSArmin Le Grand                 {
110*ddde725dSArmin Le Grand                     if(aContent.getLength())
111*ddde725dSArmin Le Grand                     {
112*ddde725dSArmin Le Grand                         setClass(&aContent);
113*ddde725dSArmin Le Grand                     }
114*ddde725dSArmin Le Grand                     break;
115*ddde725dSArmin Le Grand                 }
116*ddde725dSArmin Le Grand                 case SVGTokenXmlSpace:
117*ddde725dSArmin Le Grand                 {
118*ddde725dSArmin Le Grand                     if(aContent.getLength())
119*ddde725dSArmin Le Grand                     {
120*ddde725dSArmin Le Grand                         static rtl::OUString aStrDefault(rtl::OUString::createFromAscii("default"));
121*ddde725dSArmin Le Grand                         static rtl::OUString aStrPreserve(rtl::OUString::createFromAscii("preserve"));
122*ddde725dSArmin Le Grand 
123*ddde725dSArmin Le Grand                         if(aContent.match(aStrDefault))
124*ddde725dSArmin Le Grand                         {
125*ddde725dSArmin Le Grand                             setXmlSpace(XmlSpace_default);
126*ddde725dSArmin Le Grand                         }
127*ddde725dSArmin Le Grand                         else if(aContent.match(aStrPreserve))
128*ddde725dSArmin Le Grand                         {
129*ddde725dSArmin Le Grand                             setXmlSpace(XmlSpace_preserve);
130*ddde725dSArmin Le Grand                         }
131*ddde725dSArmin Le Grand                     }
132*ddde725dSArmin Le Grand                     break;
133*ddde725dSArmin Le Grand                 }
134*ddde725dSArmin Le Grand             }
135*ddde725dSArmin Le Grand         }
136*ddde725dSArmin Le Grand 
137*ddde725dSArmin Le Grand         void SvgNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
138*ddde725dSArmin Le Grand         {
139*ddde725dSArmin Le Grand             if(!bReferenced)
140*ddde725dSArmin Le Grand             {
141*ddde725dSArmin Le Grand                 if(SVGTokenDefs == getType() ||
142*ddde725dSArmin Le Grand                     SVGTokenSymbol == getType() ||
143*ddde725dSArmin Le Grand                     SVGTokenClipPathNode == getType() ||
144*ddde725dSArmin Le Grand                     SVGTokenMask == getType() ||
145*ddde725dSArmin Le Grand                     SVGTokenMarker == getType() ||
146*ddde725dSArmin Le Grand                     SVGTokenPattern == getType())
147*ddde725dSArmin Le Grand                 {
148*ddde725dSArmin Le Grand                     // do not decompose defs or symbol nodes (these hold only style-like
149*ddde725dSArmin Le Grand                     // objects which may be used by referencing them) except when doing
150*ddde725dSArmin Le Grand                     // so controlled referenced
151*ddde725dSArmin Le Grand 
152*ddde725dSArmin Le Grand                     // also do not decompose ClipPaths and Masks. These should be embedded
153*ddde725dSArmin Le Grand                     // in a defs node (which gets not decomposed by itself), but you never
154*ddde725dSArmin Le Grand                     // know
155*ddde725dSArmin Le Grand 
156*ddde725dSArmin Le Grand                     // also not directly used are Markers and Patterns, only indirecty used
157*ddde725dSArmin Le Grand                     // by reference
158*ddde725dSArmin Le Grand                     return;
159*ddde725dSArmin Le Grand                 }
160*ddde725dSArmin Le Grand             }
161*ddde725dSArmin Le Grand 
162*ddde725dSArmin Le Grand             const SvgNodeVector& rChildren = getChildren();
163*ddde725dSArmin Le Grand 
164*ddde725dSArmin Le Grand             if(!rChildren.empty())
165*ddde725dSArmin Le Grand             {
166*ddde725dSArmin Le Grand                 const sal_uInt32 nCount(rChildren.size());
167*ddde725dSArmin Le Grand 
168*ddde725dSArmin Le Grand                 for(sal_uInt32 a(0); a < nCount; a++)
169*ddde725dSArmin Le Grand                 {
170*ddde725dSArmin Le Grand                     SvgNode* pCandidate = rChildren[a];
171*ddde725dSArmin Le Grand 
172*ddde725dSArmin Le Grand                     if(pCandidate)
173*ddde725dSArmin Le Grand                     {
174*ddde725dSArmin Le Grand                         drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
175*ddde725dSArmin Le Grand 
176*ddde725dSArmin Le Grand                         pCandidate->decomposeSvgNode(aNewTarget, bReferenced);
177*ddde725dSArmin Le Grand 
178*ddde725dSArmin Le Grand                         if(aNewTarget.hasElements())
179*ddde725dSArmin Le Grand                         {
180*ddde725dSArmin Le Grand                             drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aNewTarget);
181*ddde725dSArmin Le Grand                         }
182*ddde725dSArmin Le Grand                     }
183*ddde725dSArmin Le Grand                     else
184*ddde725dSArmin Le Grand                     {
185*ddde725dSArmin Le Grand                         OSL_ENSURE(false, "Null-Pointer in child node list (!)");
186*ddde725dSArmin Le Grand                     }
187*ddde725dSArmin Le Grand                 }
188*ddde725dSArmin Le Grand             }
189*ddde725dSArmin Le Grand         }
190*ddde725dSArmin Le Grand 
191*ddde725dSArmin Le Grand         const basegfx::B2DRange* SvgNode::getCurrentViewPort() const
192*ddde725dSArmin Le Grand         {
193*ddde725dSArmin Le Grand             if(getParent())
194*ddde725dSArmin Le Grand             {
195*ddde725dSArmin Le Grand                 return getParent()->getCurrentViewPort();
196*ddde725dSArmin Le Grand             }
197*ddde725dSArmin Le Grand             else
198*ddde725dSArmin Le Grand             {
199*ddde725dSArmin Le Grand                 return 0;
200*ddde725dSArmin Le Grand             }
201*ddde725dSArmin Le Grand         }
202*ddde725dSArmin Le Grand 
203*ddde725dSArmin Le Grand         double SvgNode::getCurrentFontSize() const
204*ddde725dSArmin Le Grand         {
205*ddde725dSArmin Le Grand             if(getSvgStyleAttributes())
206*ddde725dSArmin Le Grand             {
207*ddde725dSArmin Le Grand                 return getSvgStyleAttributes()->getFontSize().solve(*this, xcoordinate);
208*ddde725dSArmin Le Grand             }
209*ddde725dSArmin Le Grand             else if(getParent())
210*ddde725dSArmin Le Grand             {
211*ddde725dSArmin Le Grand                 return getParent()->getCurrentFontSize();
212*ddde725dSArmin Le Grand             }
213*ddde725dSArmin Le Grand             else
214*ddde725dSArmin Le Grand             {
215*ddde725dSArmin Le Grand                 return 0.0;
216*ddde725dSArmin Le Grand             }
217*ddde725dSArmin Le Grand         }
218*ddde725dSArmin Le Grand 
219*ddde725dSArmin Le Grand         double SvgNode::getCurrentXHeight() const
220*ddde725dSArmin Le Grand         {
221*ddde725dSArmin Le Grand             if(getSvgStyleAttributes())
222*ddde725dSArmin Le Grand             {
223*ddde725dSArmin Le Grand                 // for XHeight, use FontSize currently
224*ddde725dSArmin Le Grand                 return getSvgStyleAttributes()->getFontSize().solve(*this, ycoordinate);
225*ddde725dSArmin Le Grand             }
226*ddde725dSArmin Le Grand             else if(getParent())
227*ddde725dSArmin Le Grand             {
228*ddde725dSArmin Le Grand                 return getParent()->getCurrentXHeight();
229*ddde725dSArmin Le Grand             }
230*ddde725dSArmin Le Grand             else
231*ddde725dSArmin Le Grand             {
232*ddde725dSArmin Le Grand                 return 0.0;
233*ddde725dSArmin Le Grand             }
234*ddde725dSArmin Le Grand         }
235*ddde725dSArmin Le Grand 
236*ddde725dSArmin Le Grand         void SvgNode::setId(const rtl::OUString* pfId)
237*ddde725dSArmin Le Grand         {
238*ddde725dSArmin Le Grand             if(mpId)
239*ddde725dSArmin Le Grand             {
240*ddde725dSArmin Le Grand                 mrDocument.removeSvgNodeFromMapper(*mpId);
241*ddde725dSArmin Le Grand                 delete mpId;
242*ddde725dSArmin Le Grand                 mpId = 0;
243*ddde725dSArmin Le Grand             }
244*ddde725dSArmin Le Grand 
245*ddde725dSArmin Le Grand             if(pfId)
246*ddde725dSArmin Le Grand             {
247*ddde725dSArmin Le Grand                 mpId = new rtl::OUString(*pfId);
248*ddde725dSArmin Le Grand                 mrDocument.addSvgNodeToMapper(*mpId, *this);
249*ddde725dSArmin Le Grand             }
250*ddde725dSArmin Le Grand         }
251*ddde725dSArmin Le Grand 
252*ddde725dSArmin Le Grand         void SvgNode::setClass(const rtl::OUString* pfClass)
253*ddde725dSArmin Le Grand         {
254*ddde725dSArmin Le Grand             if(mpClass)
255*ddde725dSArmin Le Grand             {
256*ddde725dSArmin Le Grand                 mrDocument.removeSvgNodeFromMapper(*mpClass);
257*ddde725dSArmin Le Grand                 delete mpClass;
258*ddde725dSArmin Le Grand                 mpClass = 0;
259*ddde725dSArmin Le Grand             }
260*ddde725dSArmin Le Grand 
261*ddde725dSArmin Le Grand             if(pfClass)
262*ddde725dSArmin Le Grand             {
263*ddde725dSArmin Le Grand                 mpClass = new rtl::OUString(*pfClass);
264*ddde725dSArmin Le Grand                 mrDocument.addSvgNodeToMapper(*mpClass, *this);
265*ddde725dSArmin Le Grand             }
266*ddde725dSArmin Le Grand         }
267*ddde725dSArmin Le Grand 
268*ddde725dSArmin Le Grand         XmlSpace SvgNode::getXmlSpace() const
269*ddde725dSArmin Le Grand         {
270*ddde725dSArmin Le Grand             if(maXmlSpace != XmlSpace_notset)
271*ddde725dSArmin Le Grand             {
272*ddde725dSArmin Le Grand                 return maXmlSpace;
273*ddde725dSArmin Le Grand             }
274*ddde725dSArmin Le Grand 
275*ddde725dSArmin Le Grand             if(getParent())
276*ddde725dSArmin Le Grand             {
277*ddde725dSArmin Le Grand                 return getParent()->getXmlSpace();
278*ddde725dSArmin Le Grand             }
279*ddde725dSArmin Le Grand 
280*ddde725dSArmin Le Grand             // default is XmlSpace_default
281*ddde725dSArmin Le Grand             return XmlSpace_default;
282*ddde725dSArmin Le Grand         }
283*ddde725dSArmin Le Grand 
284*ddde725dSArmin Le Grand     } // end of namespace svgreader
285*ddde725dSArmin Le Grand } // end of namespace svgio
286*ddde725dSArmin Le Grand 
287*ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
288*ddde725dSArmin Le Grand // eof
289