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