xref: /aoo41x/main/svgio/source/svgreader/svgnode.cxx (revision 0906e779)
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>
30025b0597SArmin Le Grand #include <drawinglayer/primitive2d/objectinfoprimitive2d.hxx>
31172c67b2SArmin Le Grand #include <tools/urlobj.hxx>
32ddde725dSArmin Le Grand 
33ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
34ddde725dSArmin Le Grand 
35ddde725dSArmin Le Grand namespace svgio
36ddde725dSArmin Le Grand {
37ddde725dSArmin Le Grand     namespace svgreader
38ddde725dSArmin Le Grand     {
39ddde725dSArmin Le Grand         const SvgStyleAttributes* SvgNode::getSvgStyleAttributes() const
40ddde725dSArmin Le Grand         {
41ddde725dSArmin Le Grand             return 0;
42ddde725dSArmin Le Grand         }
43ddde725dSArmin Le Grand 
4450b37974SArmin Le Grand         const SvgStyleAttributes* SvgNode::checkForCssStyle(const rtl::OUString& rClassStr, const SvgStyleAttributes& rOriginal) const
4550b37974SArmin Le Grand         {
46*0906e779SArmin Le Grand             if(maCssStyleVector.empty()) // #120435# Evaluate for CSS styles only once, this cannot change
4750b37974SArmin Le Grand             {
48*0906e779SArmin Le Grand                 const SvgDocument& rDocument = getDocument();
49*0906e779SArmin Le Grand 
50*0906e779SArmin Le Grand                 if(rDocument.hasSvgStyleAttributesById())
5150b37974SArmin Le Grand                 {
52*0906e779SArmin Le Grand                     if(getClass())
53*0906e779SArmin Le Grand                     {
54*0906e779SArmin Le Grand                         // find all referenced CSS styles, a list of entries is allowed
55*0906e779SArmin Le Grand                         const rtl::OUString* pClassList = getClass();
56*0906e779SArmin Le Grand                         const sal_Int32 nLen(pClassList->getLength());
57*0906e779SArmin Le Grand                         sal_Int32 nPos(0);
58*0906e779SArmin Le Grand                         const SvgStyleAttributes* pNew = 0;
5950b37974SArmin Le Grand 
60*0906e779SArmin Le Grand                         skip_char(*pClassList, sal_Unicode(' '), nPos, nLen);
6150b37974SArmin Le Grand 
62*0906e779SArmin Le Grand                         while(nPos < nLen)
63*0906e779SArmin Le Grand                         {
64*0906e779SArmin Le Grand                             rtl::OUStringBuffer aTokenValue;
6550b37974SArmin Le Grand 
66*0906e779SArmin Le Grand                             copyToLimiter(*pClassList, sal_Unicode(' '), nPos, aTokenValue, nLen);
67*0906e779SArmin Le Grand                             skip_char(*pClassList, sal_Unicode(' '), nPos, nLen);
6850b37974SArmin Le Grand 
69*0906e779SArmin Le Grand                             rtl::OUString aId(rtl::OUString::createFromAscii("."));
70*0906e779SArmin Le Grand                             const rtl::OUString aOUTokenValue(aTokenValue.makeStringAndClear());
7150b37974SArmin Le Grand 
72*0906e779SArmin Le Grand                             // look for CSS style common to token
73*0906e779SArmin Le Grand                             aId = aId + aOUTokenValue;
74*0906e779SArmin Le Grand                             pNew = rDocument.findSvgStyleAttributesById(aId);
7550b37974SArmin Le Grand 
76*0906e779SArmin Le Grand                             if(!pNew && rClassStr.getLength())
77*0906e779SArmin Le Grand                             {
78*0906e779SArmin Le Grand                                 // look for CSS style common to class.token
79*0906e779SArmin Le Grand                                 aId = rClassStr + aId;
8050b37974SArmin Le Grand 
81*0906e779SArmin Le Grand                                 pNew = rDocument.findSvgStyleAttributesById(aId);
82*0906e779SArmin Le Grand                             }
8350b37974SArmin Le Grand 
84*0906e779SArmin Le Grand                             if(pNew)
85*0906e779SArmin Le Grand                             {
86*0906e779SArmin Le Grand                                 const_cast< SvgNode* >(this)->maCssStyleVector.push_back(pNew);
87*0906e779SArmin Le Grand                             }
88*0906e779SArmin Le Grand                         }
89*0906e779SArmin Le Grand                     }
90*0906e779SArmin Le Grand 
91*0906e779SArmin Le Grand                     if(maCssStyleVector.empty() && getId())
92*0906e779SArmin Le Grand                     {
93*0906e779SArmin Le Grand                         // if none found, search for CSS style equal to Id
94*0906e779SArmin Le Grand                         const SvgStyleAttributes* pNew = rDocument.findSvgStyleAttributesById(*getId());
95*0906e779SArmin Le Grand 
9650b37974SArmin Le Grand                         if(pNew)
9750b37974SArmin Le Grand                         {
9850b37974SArmin Le Grand                             const_cast< SvgNode* >(this)->maCssStyleVector.push_back(pNew);
9950b37974SArmin Le Grand                         }
10050b37974SArmin Le Grand                     }
10150b37974SArmin Le Grand 
102*0906e779SArmin Le Grand                     if(maCssStyleVector.empty() && rClassStr.getLength())
10350b37974SArmin Le Grand                     {
104*0906e779SArmin Le Grand                         // if none found, search for CSS style equal to class type
105*0906e779SArmin Le Grand                         const SvgStyleAttributes* pNew = rDocument.findSvgStyleAttributesById(rClassStr);
10650b37974SArmin Le Grand 
107*0906e779SArmin Le Grand                         if(pNew)
108*0906e779SArmin Le Grand                         {
109*0906e779SArmin Le Grand                             const_cast< SvgNode* >(this)->maCssStyleVector.push_back(pNew);
110*0906e779SArmin Le Grand                         }
11150b37974SArmin Le Grand                     }
11250b37974SArmin Le Grand                 }
11350b37974SArmin Le Grand             }
11450b37974SArmin Le Grand 
11550b37974SArmin Le Grand             if(maCssStyleVector.empty())
11650b37974SArmin Le Grand             {
11750b37974SArmin Le Grand                 return &rOriginal;
11850b37974SArmin Le Grand             }
11950b37974SArmin Le Grand             else
12050b37974SArmin Le Grand             {
12150b37974SArmin Le Grand                 // set CssStyleParent at maCssStyleVector members to hang them in front of
122*0906e779SArmin Le Grand                 // the existing style. Build a style chain, reset parent of original for security.
123*0906e779SArmin Le Grand                 // Repeated style requests should only be issued from sub-Text nodes and I'm not
124*0906e779SArmin Le Grand                 // sure if in-between text nodes may build other chains (should not happen). But
125*0906e779SArmin Le Grand                 // it's only a re-chaining with pointers (cheap), so allow to do it every time.
12650b37974SArmin Le Grand                 SvgStyleAttributes* pCurrent = const_cast< SvgStyleAttributes* >(&rOriginal);
127*0906e779SArmin Le Grand                 pCurrent->setCssStyleParent(0);
12850b37974SArmin Le Grand 
12950b37974SArmin Le Grand                 for(sal_uInt32 a(0); a < maCssStyleVector.size(); a++)
13050b37974SArmin Le Grand                 {
13150b37974SArmin Le Grand                     SvgStyleAttributes* pCandidate = const_cast< SvgStyleAttributes* >(maCssStyleVector[maCssStyleVector.size() - a - 1]);
13250b37974SArmin Le Grand 
13350b37974SArmin Le Grand                     pCandidate->setCssStyleParent(pCurrent);
13450b37974SArmin Le Grand                     pCurrent = pCandidate;
13550b37974SArmin Le Grand                 }
13650b37974SArmin Le Grand 
13750b37974SArmin Le Grand                 return pCurrent;
13850b37974SArmin Le Grand             }
13950b37974SArmin Le Grand         }
14050b37974SArmin Le Grand 
141ddde725dSArmin Le Grand         SvgNode::SvgNode(
142ddde725dSArmin Le Grand             SVGToken aType,
143ddde725dSArmin Le Grand             SvgDocument& rDocument,
144ddde725dSArmin Le Grand             SvgNode* pParent)
145ddde725dSArmin Le Grand         :   maType(aType),
146ddde725dSArmin Le Grand             mrDocument(rDocument),
147ddde725dSArmin Le Grand             mpParent(pParent),
148ddde725dSArmin Le Grand             mpAlternativeParent(0),
149ddde725dSArmin Le Grand             maChildren(),
150ddde725dSArmin Le Grand             mpId(0),
151ddde725dSArmin Le Grand             mpClass(0),
15250b37974SArmin Le Grand             maXmlSpace(XmlSpace_notset),
15350b37974SArmin Le Grand             maCssStyleVector()
154ddde725dSArmin Le Grand         {
155ddde725dSArmin Le Grand             OSL_ENSURE(SVGTokenUnknown != maType, "SvgNode with unknown type created (!)");
156ddde725dSArmin Le Grand 
157ddde725dSArmin Le Grand             if(pParent)
158ddde725dSArmin Le Grand             {
159ddde725dSArmin Le Grand                 pParent->maChildren.push_back(this);
160ddde725dSArmin Le Grand             }
161ddde725dSArmin Le Grand             else
162ddde725dSArmin Le Grand             {
163ddde725dSArmin Le Grand #ifdef DBG_UTIL
164ddde725dSArmin Le Grand                 if(SVGTokenSvg != getType())
165ddde725dSArmin Le Grand                 {
166ddde725dSArmin Le Grand                     OSL_ENSURE(false, "No parent for this node (!)");
167ddde725dSArmin Le Grand                 }
168ddde725dSArmin Le Grand #endif
169ddde725dSArmin Le Grand             }
170ddde725dSArmin Le Grand         }
171ddde725dSArmin Le Grand 
172ddde725dSArmin Le Grand         SvgNode::~SvgNode()
173ddde725dSArmin Le Grand         {
174ddde725dSArmin Le Grand             while(maChildren.size())
175ddde725dSArmin Le Grand             {
176ddde725dSArmin Le Grand                 delete maChildren[maChildren.size() - 1];
177ddde725dSArmin Le Grand                 maChildren.pop_back();
178ddde725dSArmin Le Grand             }
179ddde725dSArmin Le Grand 
180ddde725dSArmin Le Grand             if(mpId) delete mpId;
181ddde725dSArmin Le Grand             if(mpClass) delete mpClass;
182ddde725dSArmin Le Grand         }
183ddde725dSArmin Le Grand 
184ddde725dSArmin Le Grand         void SvgNode::parseAttributes(const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttribs)
185ddde725dSArmin Le Grand         {
186ddde725dSArmin Le Grand             const sal_uInt32 nAttributes(xAttribs->getLength());
187ddde725dSArmin Le Grand 
188ddde725dSArmin Le Grand             for(sal_uInt32 a(0); a < nAttributes; a++)
189ddde725dSArmin Le Grand             {
190ddde725dSArmin Le Grand                 const ::rtl::OUString aTokenName(xAttribs->getNameByIndex(a));
191ddde725dSArmin Le Grand 
192ddde725dSArmin Le Grand                 parseAttribute(aTokenName, StrToSVGToken(aTokenName), xAttribs->getValueByIndex(a));
193ddde725dSArmin Le Grand             }
194ddde725dSArmin Le Grand         }
195ddde725dSArmin Le Grand 
196e2bf1e9dSArmin Le Grand         void SvgNode::parseAttribute(const rtl::OUString& /*rTokenName*/, SVGToken aSVGToken, const rtl::OUString& aContent)
197ddde725dSArmin Le Grand         {
198ddde725dSArmin Le Grand             switch(aSVGToken)
199ddde725dSArmin Le Grand             {
200ddde725dSArmin Le Grand                 case SVGTokenId:
201ddde725dSArmin Le Grand                 {
202ddde725dSArmin Le Grand                     if(aContent.getLength())
203ddde725dSArmin Le Grand                     {
204ddde725dSArmin Le Grand                         setId(&aContent);
205ddde725dSArmin Le Grand                     }
206ddde725dSArmin Le Grand                     break;
207ddde725dSArmin Le Grand                 }
208ddde725dSArmin Le Grand                 case SVGTokenClass:
209ddde725dSArmin Le Grand                 {
210ddde725dSArmin Le Grand                     if(aContent.getLength())
211ddde725dSArmin Le Grand                     {
212ddde725dSArmin Le Grand                         setClass(&aContent);
213ddde725dSArmin Le Grand                     }
214ddde725dSArmin Le Grand                     break;
215ddde725dSArmin Le Grand                 }
216ddde725dSArmin Le Grand                 case SVGTokenXmlSpace:
217ddde725dSArmin Le Grand                 {
218ddde725dSArmin Le Grand                     if(aContent.getLength())
219ddde725dSArmin Le Grand                     {
220ddde725dSArmin Le Grand                         static rtl::OUString aStrDefault(rtl::OUString::createFromAscii("default"));
221ddde725dSArmin Le Grand                         static rtl::OUString aStrPreserve(rtl::OUString::createFromAscii("preserve"));
222ddde725dSArmin Le Grand 
223ddde725dSArmin Le Grand                         if(aContent.match(aStrDefault))
224ddde725dSArmin Le Grand                         {
225ddde725dSArmin Le Grand                             setXmlSpace(XmlSpace_default);
226ddde725dSArmin Le Grand                         }
227ddde725dSArmin Le Grand                         else if(aContent.match(aStrPreserve))
228ddde725dSArmin Le Grand                         {
229ddde725dSArmin Le Grand                             setXmlSpace(XmlSpace_preserve);
230ddde725dSArmin Le Grand                         }
231ddde725dSArmin Le Grand                     }
232ddde725dSArmin Le Grand                     break;
233ddde725dSArmin Le Grand                 }
234e2bf1e9dSArmin Le Grand                 default:
235e2bf1e9dSArmin Le Grand                 {
236e2bf1e9dSArmin Le Grand                     break;
237e2bf1e9dSArmin Le Grand                 }
238ddde725dSArmin Le Grand             }
239ddde725dSArmin Le Grand         }
240ddde725dSArmin Le Grand 
241ddde725dSArmin Le Grand         void SvgNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
242ddde725dSArmin Le Grand         {
243ddde725dSArmin Le Grand             if(!bReferenced)
244ddde725dSArmin Le Grand             {
245ddde725dSArmin Le Grand                 if(SVGTokenDefs == getType() ||
246ddde725dSArmin Le Grand                     SVGTokenSymbol == getType() ||
247ddde725dSArmin Le Grand                     SVGTokenClipPathNode == getType() ||
248ddde725dSArmin Le Grand                     SVGTokenMask == getType() ||
249ddde725dSArmin Le Grand                     SVGTokenMarker == getType() ||
250ddde725dSArmin Le Grand                     SVGTokenPattern == getType())
251ddde725dSArmin Le Grand                 {
252ddde725dSArmin Le Grand                     // do not decompose defs or symbol nodes (these hold only style-like
253ddde725dSArmin Le Grand                     // objects which may be used by referencing them) except when doing
254ddde725dSArmin Le Grand                     // so controlled referenced
255ddde725dSArmin Le Grand 
256ddde725dSArmin Le Grand                     // also do not decompose ClipPaths and Masks. These should be embedded
257ddde725dSArmin Le Grand                     // in a defs node (which gets not decomposed by itself), but you never
258ddde725dSArmin Le Grand                     // know
259ddde725dSArmin Le Grand 
260ddde725dSArmin Le Grand                     // also not directly used are Markers and Patterns, only indirecty used
261ddde725dSArmin Le Grand                     // by reference
262ddde725dSArmin Le Grand                     return;
263ddde725dSArmin Le Grand                 }
264ddde725dSArmin Le Grand             }
265ddde725dSArmin Le Grand 
266ddde725dSArmin Le Grand             const SvgNodeVector& rChildren = getChildren();
267ddde725dSArmin Le Grand 
268ddde725dSArmin Le Grand             if(!rChildren.empty())
269ddde725dSArmin Le Grand             {
270ddde725dSArmin Le Grand                 const sal_uInt32 nCount(rChildren.size());
271ddde725dSArmin Le Grand 
272ddde725dSArmin Le Grand                 for(sal_uInt32 a(0); a < nCount; a++)
273ddde725dSArmin Le Grand                 {
274ddde725dSArmin Le Grand                     SvgNode* pCandidate = rChildren[a];
275ddde725dSArmin Le Grand 
276ddde725dSArmin Le Grand                     if(pCandidate)
277ddde725dSArmin Le Grand                     {
278ddde725dSArmin Le Grand                         drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
279ddde725dSArmin Le Grand 
280ddde725dSArmin Le Grand                         pCandidate->decomposeSvgNode(aNewTarget, bReferenced);
281ddde725dSArmin Le Grand 
282ddde725dSArmin Le Grand                         if(aNewTarget.hasElements())
283ddde725dSArmin Le Grand                         {
284ddde725dSArmin Le Grand                             drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aNewTarget);
285ddde725dSArmin Le Grand                         }
286ddde725dSArmin Le Grand                     }
287ddde725dSArmin Le Grand                     else
288ddde725dSArmin Le Grand                     {
289ddde725dSArmin Le Grand                         OSL_ENSURE(false, "Null-Pointer in child node list (!)");
290ddde725dSArmin Le Grand                     }
291ddde725dSArmin Le Grand                 }
292025b0597SArmin Le Grand 
293025b0597SArmin Le Grand                 if(rTarget.hasElements())
294025b0597SArmin Le Grand                 {
295025b0597SArmin Le Grand                     const SvgStyleAttributes* pStyles = getSvgStyleAttributes();
296025b0597SArmin Le Grand 
297025b0597SArmin Le Grand                     if(pStyles)
298025b0597SArmin Le Grand                     {
299025b0597SArmin Le Grand                         // check if we have Title or Desc
300025b0597SArmin Le Grand                         const rtl::OUString& rTitle = pStyles->getTitle();
301025b0597SArmin Le Grand                         const rtl::OUString& rDesc = pStyles->getDesc();
302025b0597SArmin Le Grand 
303025b0597SArmin Le Grand                         if(rTitle.getLength() || rDesc.getLength())
304025b0597SArmin Le Grand                         {
305025b0597SArmin Le Grand                             // default object name is empty
306025b0597SArmin Le Grand                             rtl::OUString aObjectName;
307025b0597SArmin Le Grand 
308025b0597SArmin Le Grand                             // use path as object name when outmost element
309025b0597SArmin Le Grand                             if(SVGTokenSvg == getType())
310025b0597SArmin Le Grand                             {
311025b0597SArmin Le Grand                                 aObjectName = getDocument().getAbsolutePath();
312172c67b2SArmin Le Grand 
313172c67b2SArmin Le Grand                                 if(aObjectName.getLength())
314172c67b2SArmin Le Grand                                 {
315172c67b2SArmin Le Grand                             		INetURLObject aURL(aObjectName);
316172c67b2SArmin Le Grand 
317172c67b2SArmin Le Grand                                     aObjectName = aURL.getName(
318172c67b2SArmin Le Grand                                         INetURLObject::LAST_SEGMENT,
319172c67b2SArmin Le Grand                                         true,
320172c67b2SArmin Le Grand                                         INetURLObject::DECODE_WITH_CHARSET);
321172c67b2SArmin Le Grand                                 }
322025b0597SArmin Le Grand                             }
323025b0597SArmin Le Grand 
324025b0597SArmin Le Grand                             // pack in ObjectInfoPrimitive2D group
325025b0597SArmin Le Grand                             const drawinglayer::primitive2d::Primitive2DReference xRef(
326025b0597SArmin Le Grand                                 new drawinglayer::primitive2d::ObjectInfoPrimitive2D(
327025b0597SArmin Le Grand                                     rTarget,
328025b0597SArmin Le Grand                                     aObjectName,
329025b0597SArmin Le Grand                                     rTitle,
330025b0597SArmin Le Grand                                     rDesc));
331025b0597SArmin Le Grand 
332025b0597SArmin Le Grand                             rTarget = drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1);
333025b0597SArmin Le Grand                         }
334025b0597SArmin Le Grand                     }
335025b0597SArmin Le Grand                 }
336ddde725dSArmin Le Grand             }
337ddde725dSArmin Le Grand         }
338ddde725dSArmin Le Grand 
339ddde725dSArmin Le Grand         const basegfx::B2DRange* SvgNode::getCurrentViewPort() const
340ddde725dSArmin Le Grand         {
341ddde725dSArmin Le Grand             if(getParent())
342ddde725dSArmin Le Grand             {
343ddde725dSArmin Le Grand                 return getParent()->getCurrentViewPort();
344ddde725dSArmin Le Grand             }
345ddde725dSArmin Le Grand             else
346ddde725dSArmin Le Grand             {
347ddde725dSArmin Le Grand                 return 0;
348ddde725dSArmin Le Grand             }
349ddde725dSArmin Le Grand         }
350ddde725dSArmin Le Grand 
351ddde725dSArmin Le Grand         double SvgNode::getCurrentFontSize() const
352ddde725dSArmin Le Grand         {
353ddde725dSArmin Le Grand             if(getSvgStyleAttributes())
354ddde725dSArmin Le Grand             {
355ddde725dSArmin Le Grand                 return getSvgStyleAttributes()->getFontSize().solve(*this, xcoordinate);
356ddde725dSArmin Le Grand             }
357ddde725dSArmin Le Grand             else if(getParent())
358ddde725dSArmin Le Grand             {
359ddde725dSArmin Le Grand                 return getParent()->getCurrentFontSize();
360ddde725dSArmin Le Grand             }
361ddde725dSArmin Le Grand             else
362ddde725dSArmin Le Grand             {
363ddde725dSArmin Le Grand                 return 0.0;
364ddde725dSArmin Le Grand             }
365ddde725dSArmin Le Grand         }
366ddde725dSArmin Le Grand 
367ddde725dSArmin Le Grand         double SvgNode::getCurrentXHeight() const
368ddde725dSArmin Le Grand         {
369ddde725dSArmin Le Grand             if(getSvgStyleAttributes())
370ddde725dSArmin Le Grand             {
371ddde725dSArmin Le Grand                 // for XHeight, use FontSize currently
372ddde725dSArmin Le Grand                 return getSvgStyleAttributes()->getFontSize().solve(*this, ycoordinate);
373ddde725dSArmin Le Grand             }
374ddde725dSArmin Le Grand             else if(getParent())
375ddde725dSArmin Le Grand             {
376ddde725dSArmin Le Grand                 return getParent()->getCurrentXHeight();
377ddde725dSArmin Le Grand             }
378ddde725dSArmin Le Grand             else
379ddde725dSArmin Le Grand             {
380ddde725dSArmin Le Grand                 return 0.0;
381ddde725dSArmin Le Grand             }
382ddde725dSArmin Le Grand         }
383ddde725dSArmin Le Grand 
384ddde725dSArmin Le Grand         void SvgNode::setId(const rtl::OUString* pfId)
385ddde725dSArmin Le Grand         {
386ddde725dSArmin Le Grand             if(mpId)
387ddde725dSArmin Le Grand             {
388ddde725dSArmin Le Grand                 mrDocument.removeSvgNodeFromMapper(*mpId);
389ddde725dSArmin Le Grand                 delete mpId;
390ddde725dSArmin Le Grand                 mpId = 0;
391ddde725dSArmin Le Grand             }
392ddde725dSArmin Le Grand 
393ddde725dSArmin Le Grand             if(pfId)
394ddde725dSArmin Le Grand             {
395ddde725dSArmin Le Grand                 mpId = new rtl::OUString(*pfId);
396ddde725dSArmin Le Grand                 mrDocument.addSvgNodeToMapper(*mpId, *this);
397ddde725dSArmin Le Grand             }
398ddde725dSArmin Le Grand         }
399ddde725dSArmin Le Grand 
400ddde725dSArmin Le Grand         void SvgNode::setClass(const rtl::OUString* pfClass)
401ddde725dSArmin Le Grand         {
402ddde725dSArmin Le Grand             if(mpClass)
403ddde725dSArmin Le Grand             {
404ddde725dSArmin Le Grand                 mrDocument.removeSvgNodeFromMapper(*mpClass);
405ddde725dSArmin Le Grand                 delete mpClass;
406ddde725dSArmin Le Grand                 mpClass = 0;
407ddde725dSArmin Le Grand             }
408ddde725dSArmin Le Grand 
409ddde725dSArmin Le Grand             if(pfClass)
410ddde725dSArmin Le Grand             {
411ddde725dSArmin Le Grand                 mpClass = new rtl::OUString(*pfClass);
412ddde725dSArmin Le Grand                 mrDocument.addSvgNodeToMapper(*mpClass, *this);
413ddde725dSArmin Le Grand             }
414ddde725dSArmin Le Grand         }
415ddde725dSArmin Le Grand 
416ddde725dSArmin Le Grand         XmlSpace SvgNode::getXmlSpace() const
417ddde725dSArmin Le Grand         {
418ddde725dSArmin Le Grand             if(maXmlSpace != XmlSpace_notset)
419ddde725dSArmin Le Grand             {
420ddde725dSArmin Le Grand                 return maXmlSpace;
421ddde725dSArmin Le Grand             }
422ddde725dSArmin Le Grand 
423ddde725dSArmin Le Grand             if(getParent())
424ddde725dSArmin Le Grand             {
425ddde725dSArmin Le Grand                 return getParent()->getXmlSpace();
426ddde725dSArmin Le Grand             }
427ddde725dSArmin Le Grand 
428ddde725dSArmin Le Grand             // default is XmlSpace_default
429ddde725dSArmin Le Grand             return XmlSpace_default;
430ddde725dSArmin Le Grand         }
431ddde725dSArmin Le Grand 
432ddde725dSArmin Le Grand     } // end of namespace svgreader
433ddde725dSArmin Le Grand } // end of namespace svgio
434ddde725dSArmin Le Grand 
435ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
436ddde725dSArmin Le Grand // eof
437