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