xref: /aoo42x/main/svgio/source/svgreader/svgnode.cxx (revision ddde725d)
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             }
135         }
136 
137         void SvgNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
138         {
139             if(!bReferenced)
140             {
141                 if(SVGTokenDefs == getType() ||
142                     SVGTokenSymbol == getType() ||
143                     SVGTokenClipPathNode == getType() ||
144                     SVGTokenMask == getType() ||
145                     SVGTokenMarker == getType() ||
146                     SVGTokenPattern == getType())
147                 {
148                     // do not decompose defs or symbol nodes (these hold only style-like
149                     // objects which may be used by referencing them) except when doing
150                     // so controlled referenced
151 
152                     // also do not decompose ClipPaths and Masks. These should be embedded
153                     // in a defs node (which gets not decomposed by itself), but you never
154                     // know
155 
156                     // also not directly used are Markers and Patterns, only indirecty used
157                     // by reference
158                     return;
159                 }
160             }
161 
162             const SvgNodeVector& rChildren = getChildren();
163 
164             if(!rChildren.empty())
165             {
166                 const sal_uInt32 nCount(rChildren.size());
167 
168                 for(sal_uInt32 a(0); a < nCount; a++)
169                 {
170                     SvgNode* pCandidate = rChildren[a];
171 
172                     if(pCandidate)
173                     {
174                         drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
175 
176                         pCandidate->decomposeSvgNode(aNewTarget, bReferenced);
177 
178                         if(aNewTarget.hasElements())
179                         {
180                             drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aNewTarget);
181                         }
182                     }
183                     else
184                     {
185                         OSL_ENSURE(false, "Null-Pointer in child node list (!)");
186                     }
187                 }
188             }
189         }
190 
191         const basegfx::B2DRange* SvgNode::getCurrentViewPort() const
192         {
193             if(getParent())
194             {
195                 return getParent()->getCurrentViewPort();
196             }
197             else
198             {
199                 return 0;
200             }
201         }
202 
203         double SvgNode::getCurrentFontSize() const
204         {
205             if(getSvgStyleAttributes())
206             {
207                 return getSvgStyleAttributes()->getFontSize().solve(*this, xcoordinate);
208             }
209             else if(getParent())
210             {
211                 return getParent()->getCurrentFontSize();
212             }
213             else
214             {
215                 return 0.0;
216             }
217         }
218 
219         double SvgNode::getCurrentXHeight() const
220         {
221             if(getSvgStyleAttributes())
222             {
223                 // for XHeight, use FontSize currently
224                 return getSvgStyleAttributes()->getFontSize().solve(*this, ycoordinate);
225             }
226             else if(getParent())
227             {
228                 return getParent()->getCurrentXHeight();
229             }
230             else
231             {
232                 return 0.0;
233             }
234         }
235 
236         void SvgNode::setId(const rtl::OUString* pfId)
237         {
238             if(mpId)
239             {
240                 mrDocument.removeSvgNodeFromMapper(*mpId);
241                 delete mpId;
242                 mpId = 0;
243             }
244 
245             if(pfId)
246             {
247                 mpId = new rtl::OUString(*pfId);
248                 mrDocument.addSvgNodeToMapper(*mpId, *this);
249             }
250         }
251 
252         void SvgNode::setClass(const rtl::OUString* pfClass)
253         {
254             if(mpClass)
255             {
256                 mrDocument.removeSvgNodeFromMapper(*mpClass);
257                 delete mpClass;
258                 mpClass = 0;
259             }
260 
261             if(pfClass)
262             {
263                 mpClass = new rtl::OUString(*pfClass);
264                 mrDocument.addSvgNodeToMapper(*mpClass, *this);
265             }
266         }
267 
268         XmlSpace SvgNode::getXmlSpace() const
269         {
270             if(maXmlSpace != XmlSpace_notset)
271             {
272                 return maXmlSpace;
273             }
274 
275             if(getParent())
276             {
277                 return getParent()->getXmlSpace();
278             }
279 
280             // default is XmlSpace_default
281             return XmlSpace_default;
282         }
283 
284     } // end of namespace svgreader
285 } // end of namespace svgio
286 
287 //////////////////////////////////////////////////////////////////////////////
288 // eof
289