xref: /aoo42x/main/svgio/source/svgreader/svgnode.cxx (revision 9d01bcde)
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     {
394374d266SArmin Le Grand         /// #125258#
404374d266SArmin Le Grand         bool SvgNode::supportsParentStyle() const
414374d266SArmin Le Grand         {
424374d266SArmin Le Grand             return true;
434374d266SArmin Le Grand         }
444374d266SArmin Le Grand 
45ddde725dSArmin Le Grand         const SvgStyleAttributes* SvgNode::getSvgStyleAttributes() const
46ddde725dSArmin Le Grand         {
47ddde725dSArmin Le Grand             return 0;
48ddde725dSArmin Le Grand         }
49ddde725dSArmin Le Grand 
50*9d01bcdeSArmin Le Grand         void SvgNode::fillCssStyleVector(const rtl::OUString& rClassStr)
5150b37974SArmin Le Grand         {
52*9d01bcdeSArmin Le Grand             OSL_ENSURE(!mbCssStyleVectorBuilt, "OOps, fillCssStyleVector called double ?!?");
53*9d01bcdeSArmin Le Grand             mbCssStyleVectorBuilt = true;
54*9d01bcdeSArmin Le Grand 
55*9d01bcdeSArmin Le Grand             // #125293# If we have CssStyles we need to buuild a linked list of SvgStyleAttributes
56*9d01bcdeSArmin Le Grand             // which represent this for the current object. There are various methods to
57*9d01bcdeSArmin Le Grand             // specify CssStyles which need to be taken into account in a given order:
58*9d01bcdeSArmin Le Grand             // - local CssStyle (independent from global CssStyles at SvgDocument)
59*9d01bcdeSArmin Le Grand             // - 'id' CssStyle
60*9d01bcdeSArmin Le Grand             // - 'class' CssStyle(s)
61*9d01bcdeSArmin Le Grand             // - type-dependent elements (e..g. 'rect' for all rect elements)
62*9d01bcdeSArmin Le Grand             // - local attributes (rOriginal)
63*9d01bcdeSArmin Le Grand             // - inherited attributes (up the hierarchy)
64*9d01bcdeSArmin Le Grand             // The first four will be collected in maCssStyleVector for the current element
65*9d01bcdeSArmin Le Grand             // (once, this will not change) and be linked in the needed order using the
66*9d01bcdeSArmin Le Grand             // get/setCssStyleParent at the SvgStyleAttributes which will be used preferred in
67*9d01bcdeSArmin Le Grand             // member evaluation over the existing parent hierarchy
68*9d01bcdeSArmin Le Grand 
69*9d01bcdeSArmin Le Grand             // check for local CssStyle with highest priority
70*9d01bcdeSArmin Le Grand             if(mpLocalCssStyle)
7150b37974SArmin Le Grand             {
72*9d01bcdeSArmin Le Grand                 // if we have one, use as first entry
73*9d01bcdeSArmin Le Grand                 maCssStyleVector.push_back(mpLocalCssStyle);
74*9d01bcdeSArmin Le Grand             }
750906e779SArmin Le Grand 
76*9d01bcdeSArmin Le Grand             const SvgDocument& rDocument = getDocument();
77*9d01bcdeSArmin Le Grand 
78*9d01bcdeSArmin Le Grand             if(rDocument.hasSvgStyleAttributesById())
79*9d01bcdeSArmin Le Grand             {
80*9d01bcdeSArmin Le Grand                 // check for 'id' references
81*9d01bcdeSArmin Le Grand                 if(getId())
8250b37974SArmin Le Grand                 {
83*9d01bcdeSArmin Le Grand                     // concatenate combined style name during search for CSS style equal to Id
84*9d01bcdeSArmin Le Grand                     // when travelling over node parents
85*9d01bcdeSArmin Le Grand                     rtl::OUString aConcatenatedStyleName;
86*9d01bcdeSArmin Le Grand                     const SvgNode* pCurrent = this;
87*9d01bcdeSArmin Le Grand                     const SvgStyleAttributes* pNew = 0;
88*9d01bcdeSArmin Le Grand 
89*9d01bcdeSArmin Le Grand                     while(!pNew && pCurrent)
90*9d01bcdeSArmin Le Grand                     {
91*9d01bcdeSArmin Le Grand                         if(pCurrent->getId())
92*9d01bcdeSArmin Le Grand                         {
93*9d01bcdeSArmin Le Grand                             aConcatenatedStyleName = *pCurrent->getId() + aConcatenatedStyleName;
94*9d01bcdeSArmin Le Grand                         }
95*9d01bcdeSArmin Le Grand 
96*9d01bcdeSArmin Le Grand                         if(aConcatenatedStyleName.getLength())
97*9d01bcdeSArmin Le Grand                         {
98*9d01bcdeSArmin Le Grand                             pNew = rDocument.findSvgStyleAttributesById(aConcatenatedStyleName);
99*9d01bcdeSArmin Le Grand                         }
100*9d01bcdeSArmin Le Grand 
101*9d01bcdeSArmin Le Grand                         pCurrent = pCurrent->getParent();
102*9d01bcdeSArmin Le Grand                     }
103*9d01bcdeSArmin Le Grand 
104*9d01bcdeSArmin Le Grand                     if(pNew)
1059d56236fSArmin Le Grand                     {
106*9d01bcdeSArmin Le Grand                         maCssStyleVector.push_back(pNew);
1079d56236fSArmin Le Grand                     }
108*9d01bcdeSArmin Le Grand                 }
109*9d01bcdeSArmin Le Grand 
110*9d01bcdeSArmin Le Grand                 // check for 'class' references
111*9d01bcdeSArmin Le Grand                 if(getClass())
112*9d01bcdeSArmin Le Grand                 {
113*9d01bcdeSArmin Le Grand                     // find all referenced CSS styles (a list of entries is allowed)
114*9d01bcdeSArmin Le Grand                     const rtl::OUString* pClassList = getClass();
115*9d01bcdeSArmin Le Grand                     const sal_Int32 nLen(pClassList->getLength());
116*9d01bcdeSArmin Le Grand                     sal_Int32 nPos(0);
117*9d01bcdeSArmin Le Grand                     const SvgStyleAttributes* pNew = 0;
118*9d01bcdeSArmin Le Grand 
119*9d01bcdeSArmin Le Grand                     skip_char(*pClassList, sal_Unicode(' '), nPos, nLen);
1209d56236fSArmin Le Grand 
121*9d01bcdeSArmin Le Grand                     while(nPos < nLen)
1220906e779SArmin Le Grand                     {
123*9d01bcdeSArmin Le Grand                         rtl::OUStringBuffer aTokenValue;
12450b37974SArmin Le Grand 
125*9d01bcdeSArmin Le Grand                         copyToLimiter(*pClassList, sal_Unicode(' '), nPos, aTokenValue, nLen);
1260906e779SArmin Le Grand                         skip_char(*pClassList, sal_Unicode(' '), nPos, nLen);
1279d56236fSArmin Le Grand 
128*9d01bcdeSArmin Le Grand                         rtl::OUString aId(rtl::OUString::createFromAscii("."));
129*9d01bcdeSArmin Le Grand                         const rtl::OUString aOUTokenValue(aTokenValue.makeStringAndClear());
1309d56236fSArmin Le Grand 
131*9d01bcdeSArmin Le Grand                         // look for CSS style common to token
132*9d01bcdeSArmin Le Grand                         aId = aId + aOUTokenValue;
133*9d01bcdeSArmin Le Grand                         pNew = rDocument.findSvgStyleAttributesById(aId);
13450b37974SArmin Le Grand 
135*9d01bcdeSArmin Le Grand                         if(!pNew && rClassStr.getLength())
136*9d01bcdeSArmin Le Grand                         {
137*9d01bcdeSArmin Le Grand                             // look for CSS style common to class.token
138*9d01bcdeSArmin Le Grand                             aId = rClassStr + aId;
1399d56236fSArmin Le Grand 
1400906e779SArmin Le Grand                             pNew = rDocument.findSvgStyleAttributesById(aId);
1410906e779SArmin Le Grand                         }
1429d56236fSArmin Le Grand 
1430906e779SArmin Le Grand                         if(pNew)
1440906e779SArmin Le Grand                         {
145*9d01bcdeSArmin Le Grand                             maCssStyleVector.push_back(pNew);
1460906e779SArmin Le Grand                         }
14750b37974SArmin Le Grand                     }
14850b37974SArmin Le Grand                 }
149*9d01bcdeSArmin Le Grand 
150*9d01bcdeSArmin Le Grand                 // check for class-dependent references to CssStyles
151*9d01bcdeSArmin Le Grand                 if(rClassStr.getLength())
152*9d01bcdeSArmin Le Grand                 {
153*9d01bcdeSArmin Le Grand                     // search for CSS style equal to class type
154*9d01bcdeSArmin Le Grand                     const SvgStyleAttributes* pNew = rDocument.findSvgStyleAttributesById(rClassStr);
155*9d01bcdeSArmin Le Grand 
156*9d01bcdeSArmin Le Grand                     if(pNew)
157*9d01bcdeSArmin Le Grand                     {
158*9d01bcdeSArmin Le Grand                         maCssStyleVector.push_back(pNew);
159*9d01bcdeSArmin Le Grand                     }
160*9d01bcdeSArmin Le Grand                 }
161*9d01bcdeSArmin Le Grand             }
162*9d01bcdeSArmin Le Grand         }
163*9d01bcdeSArmin Le Grand 
164*9d01bcdeSArmin Le Grand         const SvgStyleAttributes* SvgNode::checkForCssStyle(const rtl::OUString& rClassStr, const SvgStyleAttributes& rOriginal) const
165*9d01bcdeSArmin Le Grand         {
166*9d01bcdeSArmin Le Grand             if(!mbCssStyleVectorBuilt)
167*9d01bcdeSArmin Le Grand             {
168*9d01bcdeSArmin Le Grand                 // build needed CssStyleVector for local node
169*9d01bcdeSArmin Le Grand                 const_cast< SvgNode* >(this)->fillCssStyleVector(rClassStr);
17050b37974SArmin Le Grand             }
17150b37974SArmin Le Grand 
1729d56236fSArmin Le Grand             if(maCssStyleVector.empty())
1739d56236fSArmin Le Grand             {
174*9d01bcdeSArmin Le Grand                 // return given original if no CssStlyes found
1759d56236fSArmin Le Grand                 return &rOriginal;
1769d56236fSArmin Le Grand             }
1779d56236fSArmin Le Grand             else
17850b37974SArmin Le Grand             {
1799d56236fSArmin Le Grand                 // #125293# rOriginal will be the last element in the linked list; use no CssStyleParent
1809d56236fSArmin Le Grand                 // there (reset it) to ensure that the parent hierarchy will be used when it's base
1819d56236fSArmin Le Grand                 // is referenced. This new chaning inserts the CssStyles before the original style,
1829d56236fSArmin Le Grand                 // this makes the whole process much safer since the original style when used will
1839d56236fSArmin Le Grand                 // be not different to the situation without CssStyles; thus loops which may be caused
1849d56236fSArmin Le Grand                 // by trying to use the parent hierarchy of the owner of the style will be avoided
1859d56236fSArmin Le Grand                 // already in this mechanism. It's still good to keep the supportsParentStyle
1869d56236fSArmin Le Grand                 // from #125258# in place, though.
1879d56236fSArmin Le Grand                 // This chain building using pointers will be done every time when checkForCssStyle
1889d56236fSArmin Le Grand                 // is used (not the search, only the chaining). This is needed since the CssStyles
1899d56236fSArmin Le Grand                 // themselves will be potentially used multiple times. It is not expensive since it's
1909d56236fSArmin Le Grand                 // only changing some pointers.
1919d56236fSArmin Le Grand                 // The alternative would be to create the style hierarchy for every element (or even
1929d56236fSArmin Le Grand                 // for the element containing the hierarchy) in a vector of pointers and to use that.
1939d56236fSArmin Le Grand                 // Resetting the CssStyleParent on rOriginal is probably not needeed
1949d56236fSArmin Le Grand                 // but simply safer to do.
1959d56236fSArmin Le Grand                 const_cast< SvgStyleAttributes& >(rOriginal).setCssStyleParent(0);
1969d56236fSArmin Le Grand 
1979d56236fSArmin Le Grand                 // loop over the existing CssStyles and link them. There is a first one, take
1989d56236fSArmin Le Grand                 // as current
1999d56236fSArmin Le Grand                 SvgStyleAttributes* pCurrent = const_cast< SvgStyleAttributes* >(maCssStyleVector[0]);
2009d56236fSArmin Le Grand 
2019d56236fSArmin Le Grand                 for(sal_uInt32 a(1); a < maCssStyleVector.size(); a++)
20250b37974SArmin Le Grand                 {
2037b027e49SArmin Le Grand                     SvgStyleAttributes* pNext = const_cast< SvgStyleAttributes* >(maCssStyleVector[a]);
20450b37974SArmin Le Grand 
2057b027e49SArmin Le Grand                     pCurrent->setCssStyleParent(pNext);
2067b027e49SArmin Le Grand                     pCurrent = pNext;
20750b37974SArmin Le Grand                 }
2087b027e49SArmin Le Grand 
2099d56236fSArmin Le Grand                 // pCurrent is the last used CssStyle, let it point to the original style
2109d56236fSArmin Le Grand                 pCurrent->setCssStyleParent(&rOriginal);
2119d56236fSArmin Le Grand 
2129d56236fSArmin Le Grand                 // return 1st CssStyle as style chain start element (only for the
2139d56236fSArmin Le Grand                 // local element, still no hierarchy used here)
2149d56236fSArmin Le Grand                 return maCssStyleVector[0];
2159d56236fSArmin Le Grand             }
21650b37974SArmin Le Grand         }
21750b37974SArmin Le Grand 
218ddde725dSArmin Le Grand         SvgNode::SvgNode(
219ddde725dSArmin Le Grand             SVGToken aType,
220ddde725dSArmin Le Grand             SvgDocument& rDocument,
221ddde725dSArmin Le Grand             SvgNode* pParent)
222ddde725dSArmin Le Grand         :   maType(aType),
223ddde725dSArmin Le Grand             mrDocument(rDocument),
224ddde725dSArmin Le Grand             mpParent(pParent),
225ddde725dSArmin Le Grand             mpAlternativeParent(0),
226ddde725dSArmin Le Grand             maChildren(),
227ddde725dSArmin Le Grand             mpId(0),
228ddde725dSArmin Le Grand             mpClass(0),
22950b37974SArmin Le Grand             maXmlSpace(XmlSpace_notset),
230a275c134SArmin Le Grand             maDisplay(Display_inline),
231*9d01bcdeSArmin Le Grand             maCssStyleVector(),
232*9d01bcdeSArmin Le Grand             mpLocalCssStyle(0),
233*9d01bcdeSArmin Le Grand             mbCssStyleVectorBuilt(false)
234ddde725dSArmin Le Grand         {
235ddde725dSArmin Le Grand             OSL_ENSURE(SVGTokenUnknown != maType, "SvgNode with unknown type created (!)");
236ddde725dSArmin Le Grand 
237ddde725dSArmin Le Grand             if(pParent)
238ddde725dSArmin Le Grand             {
239ddde725dSArmin Le Grand                 pParent->maChildren.push_back(this);
240ddde725dSArmin Le Grand             }
241ddde725dSArmin Le Grand             else
242ddde725dSArmin Le Grand             {
243ddde725dSArmin Le Grand #ifdef DBG_UTIL
244ddde725dSArmin Le Grand                 if(SVGTokenSvg != getType())
245ddde725dSArmin Le Grand                 {
246ddde725dSArmin Le Grand                     OSL_ENSURE(false, "No parent for this node (!)");
247ddde725dSArmin Le Grand                 }
248ddde725dSArmin Le Grand #endif
249ddde725dSArmin Le Grand             }
250ddde725dSArmin Le Grand         }
251ddde725dSArmin Le Grand 
252ddde725dSArmin Le Grand         SvgNode::~SvgNode()
253ddde725dSArmin Le Grand         {
254ddde725dSArmin Le Grand             while(maChildren.size())
255ddde725dSArmin Le Grand             {
256ddde725dSArmin Le Grand                 delete maChildren[maChildren.size() - 1];
257ddde725dSArmin Le Grand                 maChildren.pop_back();
258ddde725dSArmin Le Grand             }
259ddde725dSArmin Le Grand 
260*9d01bcdeSArmin Le Grand             if(mpId)
261*9d01bcdeSArmin Le Grand             {
262*9d01bcdeSArmin Le Grand                 delete mpId;
263*9d01bcdeSArmin Le Grand             }
264*9d01bcdeSArmin Le Grand 
265*9d01bcdeSArmin Le Grand             if(mpClass)
266*9d01bcdeSArmin Le Grand             {
267*9d01bcdeSArmin Le Grand                 delete mpClass;
268*9d01bcdeSArmin Le Grand             }
269*9d01bcdeSArmin Le Grand 
270*9d01bcdeSArmin Le Grand             if(mpLocalCssStyle)
271*9d01bcdeSArmin Le Grand             {
272*9d01bcdeSArmin Le Grand                 delete mpLocalCssStyle;
273*9d01bcdeSArmin Le Grand             }
274*9d01bcdeSArmin Le Grand         }
275*9d01bcdeSArmin Le Grand 
276*9d01bcdeSArmin Le Grand         void SvgNode::readLocalCssStyle(const rtl::OUString& aContent)
277*9d01bcdeSArmin Le Grand         {
278*9d01bcdeSArmin Le Grand             if(!mpLocalCssStyle)
279*9d01bcdeSArmin Le Grand             {
280*9d01bcdeSArmin Le Grand                 // create LocalCssStyle if needed but not yet added
281*9d01bcdeSArmin Le Grand                 mpLocalCssStyle = new SvgStyleAttributes(*this);
282*9d01bcdeSArmin Le Grand             }
283*9d01bcdeSArmin Le Grand             else
284*9d01bcdeSArmin Le Grand             {
285*9d01bcdeSArmin Le Grand                 // 2nd fill would be an error
286*9d01bcdeSArmin Le Grand                 OSL_ENSURE(false, "Svg node has two local CssStyles, this may lead to problems (!)");
287*9d01bcdeSArmin Le Grand             }
288*9d01bcdeSArmin Le Grand 
289*9d01bcdeSArmin Le Grand             if(mpLocalCssStyle)
290*9d01bcdeSArmin Le Grand             {
291*9d01bcdeSArmin Le Grand                 // parse and set values to it
292*9d01bcdeSArmin Le Grand                 mpLocalCssStyle->readStyle(aContent);
293*9d01bcdeSArmin Le Grand             }
294*9d01bcdeSArmin Le Grand             else
295*9d01bcdeSArmin Le Grand             {
296*9d01bcdeSArmin Le Grand                 OSL_ENSURE(false, "Could not get/create a local CssStyle for a node (!)");
297*9d01bcdeSArmin Le Grand             }
298ddde725dSArmin Le Grand         }
299ddde725dSArmin Le Grand 
300ddde725dSArmin Le Grand         void SvgNode::parseAttributes(const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttribs)
301ddde725dSArmin Le Grand         {
302*9d01bcdeSArmin Le Grand             // no longer need to pre-sort moving 'style' entries to the back so that
303*9d01bcdeSArmin Le Grand             // values get overwritten - that was the previous, not complete solution for
304*9d01bcdeSArmin Le Grand             // handling the priorities between svg and Css properties
305ddde725dSArmin Le Grand             const sal_uInt32 nAttributes(xAttribs->getLength());
306175cd092SArmin Le Grand 
307ddde725dSArmin Le Grand             for(sal_uInt32 a(0); a < nAttributes; a++)
308ddde725dSArmin Le Grand             {
309ddde725dSArmin Le Grand                 const ::rtl::OUString aTokenName(xAttribs->getNameByIndex(a));
310175cd092SArmin Le Grand                 const SVGToken aSVGToken(StrToSVGToken(aTokenName));
311175cd092SArmin Le Grand 
312*9d01bcdeSArmin Le Grand                 parseAttribute(aTokenName, aSVGToken, xAttribs->getValueByIndex(a));
313ddde725dSArmin Le Grand             }
314ddde725dSArmin Le Grand         }
315ddde725dSArmin Le Grand 
31601e92ad6SArmin Le Grand         Display getDisplayFromContent(const rtl::OUString& aContent)
31701e92ad6SArmin Le Grand         {
31801e92ad6SArmin Le Grand             if(aContent.getLength())
31901e92ad6SArmin Le Grand             {
320e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrInline(rtl::OUString::createFromAscii("inline"));
321e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrBlock(rtl::OUString::createFromAscii("block"));
322e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrList_item(rtl::OUString::createFromAscii("list-item"));
323e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrRun_in(rtl::OUString::createFromAscii("run-in"));
324e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrCompact(rtl::OUString::createFromAscii("compact"));
325e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrMarker(rtl::OUString::createFromAscii("marker"));
326e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable(rtl::OUString::createFromAscii("table"));
327e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrInline_table(rtl::OUString::createFromAscii("inline-table"));
328e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable_row_group(rtl::OUString::createFromAscii("table-row-group"));
329e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable_header_group(rtl::OUString::createFromAscii("table-header-group"));
330e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable_footer_group(rtl::OUString::createFromAscii("table-footer-group"));
331e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable_row(rtl::OUString::createFromAscii("table-row"));
332e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable_column_group(rtl::OUString::createFromAscii("table-column-group"));
333e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable_column(rtl::OUString::createFromAscii("table-column"));
33401e92ad6SArmin Le Grand                 static rtl::OUString aStrTable_cell(rtl::OUString::createFromAscii("table-cell"));
33501e92ad6SArmin Le Grand                 static rtl::OUString aStrTable_caption(rtl::OUString::createFromAscii("table-caption"));
33601e92ad6SArmin Le Grand                 static rtl::OUString aStrNone(rtl::OUString::createFromAscii("none"));
33701e92ad6SArmin Le Grand                 static rtl::OUString aStrInherit(rtl::OUString::createFromAscii("inherit"));
33801e92ad6SArmin Le Grand 
33901e92ad6SArmin Le Grand                 if(aContent.match(aStrInline))
34001e92ad6SArmin Le Grand                 {
34101e92ad6SArmin Le Grand                     return Display_inline;
34201e92ad6SArmin Le Grand                 }
34301e92ad6SArmin Le Grand                 else if(aContent.match(aStrNone))
34401e92ad6SArmin Le Grand                 {
34501e92ad6SArmin Le Grand                     return Display_none;
34601e92ad6SArmin Le Grand                 }
34701e92ad6SArmin Le Grand                 else if(aContent.match(aStrInherit))
34801e92ad6SArmin Le Grand                 {
34901e92ad6SArmin Le Grand                     return Display_inherit;
35001e92ad6SArmin Le Grand                 }
351e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrBlock))
35201e92ad6SArmin Le Grand                 {
35301e92ad6SArmin Le Grand                     return Display_block;
35401e92ad6SArmin Le Grand                 }
355e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrList_item))
35601e92ad6SArmin Le Grand                 {
35701e92ad6SArmin Le Grand                     return Display_list_item;
35801e92ad6SArmin Le Grand                 }
359e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrRun_in))
36001e92ad6SArmin Le Grand                 {
36101e92ad6SArmin Le Grand                     return Display_run_in;
36201e92ad6SArmin Le Grand                 }
363e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrCompact))
36401e92ad6SArmin Le Grand                 {
36501e92ad6SArmin Le Grand                     return Display_compact;
36601e92ad6SArmin Le Grand                 }
367e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrMarker))
36801e92ad6SArmin Le Grand                 {
36901e92ad6SArmin Le Grand                     return Display_marker;
37001e92ad6SArmin Le Grand                 }
371e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable))
37201e92ad6SArmin Le Grand                 {
37301e92ad6SArmin Le Grand                     return Display_table;
37401e92ad6SArmin Le Grand                 }
375e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrInline_table))
37601e92ad6SArmin Le Grand                 {
37701e92ad6SArmin Le Grand                     return Display_inline_table;
37801e92ad6SArmin Le Grand                 }
379e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable_row_group))
38001e92ad6SArmin Le Grand                 {
38101e92ad6SArmin Le Grand                     return Display_table_row_group;
38201e92ad6SArmin Le Grand                 }
383e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable_header_group))
38401e92ad6SArmin Le Grand                 {
38501e92ad6SArmin Le Grand                     return Display_table_header_group;
38601e92ad6SArmin Le Grand                 }
387e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable_footer_group))
38801e92ad6SArmin Le Grand                 {
38901e92ad6SArmin Le Grand                     return Display_table_footer_group;
39001e92ad6SArmin Le Grand                 }
391e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable_row))
39201e92ad6SArmin Le Grand                 {
39301e92ad6SArmin Le Grand                     return Display_table_row;
39401e92ad6SArmin Le Grand                 }
395e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable_column_group))
39601e92ad6SArmin Le Grand                 {
39701e92ad6SArmin Le Grand                     return Display_table_column_group;
39801e92ad6SArmin Le Grand                 }
399e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable_column))
40001e92ad6SArmin Le Grand                 {
40101e92ad6SArmin Le Grand                     return Display_table_column;
40201e92ad6SArmin Le Grand                 }
40301e92ad6SArmin Le Grand                 else if(aContent.match(aStrTable_cell))
40401e92ad6SArmin Le Grand                 {
40501e92ad6SArmin Le Grand                     return Display_table_cell;
40601e92ad6SArmin Le Grand                 }
40701e92ad6SArmin Le Grand                 else if(aContent.match(aStrTable_caption))
40801e92ad6SArmin Le Grand                 {
40901e92ad6SArmin Le Grand                     return Display_table_caption;
41001e92ad6SArmin Le Grand                 }
41101e92ad6SArmin Le Grand             }
41201e92ad6SArmin Le Grand 
41301e92ad6SArmin Le Grand             // return the default
41401e92ad6SArmin Le Grand             return Display_inline;
41501e92ad6SArmin Le Grand         }
41601e92ad6SArmin Le Grand 
417e2bf1e9dSArmin Le Grand         void SvgNode::parseAttribute(const rtl::OUString& /*rTokenName*/, SVGToken aSVGToken, const rtl::OUString& aContent)
418ddde725dSArmin Le Grand         {
419ddde725dSArmin Le Grand             switch(aSVGToken)
420ddde725dSArmin Le Grand             {
421ddde725dSArmin Le Grand                 case SVGTokenId:
422ddde725dSArmin Le Grand                 {
423ddde725dSArmin Le Grand                     if(aContent.getLength())
424ddde725dSArmin Le Grand                     {
425ddde725dSArmin Le Grand                         setId(&aContent);
426ddde725dSArmin Le Grand                     }
427ddde725dSArmin Le Grand                     break;
428ddde725dSArmin Le Grand                 }
429ddde725dSArmin Le Grand                 case SVGTokenClass:
430ddde725dSArmin Le Grand                 {
431ddde725dSArmin Le Grand                     if(aContent.getLength())
432ddde725dSArmin Le Grand                     {
433ddde725dSArmin Le Grand                         setClass(&aContent);
434ddde725dSArmin Le Grand                     }
435ddde725dSArmin Le Grand                     break;
436ddde725dSArmin Le Grand                 }
437ddde725dSArmin Le Grand                 case SVGTokenXmlSpace:
438ddde725dSArmin Le Grand                 {
439ddde725dSArmin Le Grand                     if(aContent.getLength())
440ddde725dSArmin Le Grand                     {
441ddde725dSArmin Le Grand                         static rtl::OUString aStrDefault(rtl::OUString::createFromAscii("default"));
442ddde725dSArmin Le Grand                         static rtl::OUString aStrPreserve(rtl::OUString::createFromAscii("preserve"));
443ddde725dSArmin Le Grand 
444ddde725dSArmin Le Grand                         if(aContent.match(aStrDefault))
445ddde725dSArmin Le Grand                         {
446ddde725dSArmin Le Grand                             setXmlSpace(XmlSpace_default);
447ddde725dSArmin Le Grand                         }
448ddde725dSArmin Le Grand                         else if(aContent.match(aStrPreserve))
449ddde725dSArmin Le Grand                         {
450ddde725dSArmin Le Grand                             setXmlSpace(XmlSpace_preserve);
451ddde725dSArmin Le Grand                         }
452ddde725dSArmin Le Grand                     }
453ddde725dSArmin Le Grand                     break;
454ddde725dSArmin Le Grand                 }
455a275c134SArmin Le Grand                 case SVGTokenDisplay:
456a275c134SArmin Le Grand                 {
457a275c134SArmin Le Grand                     if(aContent.getLength())
458a275c134SArmin Le Grand                     {
45901e92ad6SArmin Le Grand                         setDisplay(getDisplayFromContent(aContent));
460a275c134SArmin Le Grand                     }
461a275c134SArmin Le Grand                     break;
462a275c134SArmin Le Grand                 }
463e2bf1e9dSArmin Le Grand                 default:
464e2bf1e9dSArmin Le Grand                 {
465e2bf1e9dSArmin Le Grand                     break;
466e2bf1e9dSArmin Le Grand                 }
467ddde725dSArmin Le Grand             }
468ddde725dSArmin Le Grand         }
469ddde725dSArmin Le Grand 
470ddde725dSArmin Le Grand         void SvgNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
471ddde725dSArmin Le Grand         {
472a275c134SArmin Le Grand             if(Display_none == getDisplay())
473a275c134SArmin Le Grand             {
474a275c134SArmin Le Grand                 return;
475a275c134SArmin Le Grand             }
476a275c134SArmin Le Grand 
477ddde725dSArmin Le Grand             if(!bReferenced)
478ddde725dSArmin Le Grand             {
479ddde725dSArmin Le Grand                 if(SVGTokenDefs == getType() ||
480ddde725dSArmin Le Grand                     SVGTokenSymbol == getType() ||
481ddde725dSArmin Le Grand                     SVGTokenClipPathNode == getType() ||
482ddde725dSArmin Le Grand                     SVGTokenMask == getType() ||
483ddde725dSArmin Le Grand                     SVGTokenMarker == getType() ||
484ddde725dSArmin Le Grand                     SVGTokenPattern == getType())
485ddde725dSArmin Le Grand                 {
486ddde725dSArmin Le Grand                     // do not decompose defs or symbol nodes (these hold only style-like
487ddde725dSArmin Le Grand                     // objects which may be used by referencing them) except when doing
488ddde725dSArmin Le Grand                     // so controlled referenced
489ddde725dSArmin Le Grand 
490ddde725dSArmin Le Grand                     // also do not decompose ClipPaths and Masks. These should be embedded
491ddde725dSArmin Le Grand                     // in a defs node (which gets not decomposed by itself), but you never
492ddde725dSArmin Le Grand                     // know
493ddde725dSArmin Le Grand 
494ddde725dSArmin Le Grand                     // also not directly used are Markers and Patterns, only indirecty used
495ddde725dSArmin Le Grand                     // by reference
496a275c134SArmin Le Grand 
497a275c134SArmin Le Grand                     // #121656# also do not decompose nodes which have display="none" set
498a275c134SArmin Le Grand                     // as property
499ddde725dSArmin Le Grand                     return;
500ddde725dSArmin Le Grand                 }
501ddde725dSArmin Le Grand             }
502ddde725dSArmin Le Grand 
503ddde725dSArmin Le Grand             const SvgNodeVector& rChildren = getChildren();
504ddde725dSArmin Le Grand 
505ddde725dSArmin Le Grand             if(!rChildren.empty())
506ddde725dSArmin Le Grand             {
507ddde725dSArmin Le Grand                 const sal_uInt32 nCount(rChildren.size());
508ddde725dSArmin Le Grand 
509ddde725dSArmin Le Grand                 for(sal_uInt32 a(0); a < nCount; a++)
510ddde725dSArmin Le Grand                 {
511ddde725dSArmin Le Grand                     SvgNode* pCandidate = rChildren[a];
512ddde725dSArmin Le Grand 
513a275c134SArmin Le Grand                     if(pCandidate && Display_none != pCandidate->getDisplay())
514ddde725dSArmin Le Grand                     {
515ddde725dSArmin Le Grand                         drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
516ddde725dSArmin Le Grand 
517ddde725dSArmin Le Grand                         pCandidate->decomposeSvgNode(aNewTarget, bReferenced);
518ddde725dSArmin Le Grand 
519ddde725dSArmin Le Grand                         if(aNewTarget.hasElements())
520ddde725dSArmin Le Grand                         {
521ddde725dSArmin Le Grand                             drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aNewTarget);
522ddde725dSArmin Le Grand                         }
523ddde725dSArmin Le Grand                     }
524ddde725dSArmin Le Grand                     else
525ddde725dSArmin Le Grand                     {
526ddde725dSArmin Le Grand                         OSL_ENSURE(false, "Null-Pointer in child node list (!)");
527ddde725dSArmin Le Grand                     }
528ddde725dSArmin Le Grand                 }
529025b0597SArmin Le Grand 
530025b0597SArmin Le Grand                 if(rTarget.hasElements())
531025b0597SArmin Le Grand                 {
532025b0597SArmin Le Grand                     const SvgStyleAttributes* pStyles = getSvgStyleAttributes();
533025b0597SArmin Le Grand 
534025b0597SArmin Le Grand                     if(pStyles)
535025b0597SArmin Le Grand                     {
536025b0597SArmin Le Grand                         // check if we have Title or Desc
537025b0597SArmin Le Grand                         const rtl::OUString& rTitle = pStyles->getTitle();
538025b0597SArmin Le Grand                         const rtl::OUString& rDesc = pStyles->getDesc();
539025b0597SArmin Le Grand 
540025b0597SArmin Le Grand                         if(rTitle.getLength() || rDesc.getLength())
541025b0597SArmin Le Grand                         {
542025b0597SArmin Le Grand                             // default object name is empty
543025b0597SArmin Le Grand                             rtl::OUString aObjectName;
544025b0597SArmin Le Grand 
545025b0597SArmin Le Grand                             // use path as object name when outmost element
546025b0597SArmin Le Grand                             if(SVGTokenSvg == getType())
547025b0597SArmin Le Grand                             {
548025b0597SArmin Le Grand                                 aObjectName = getDocument().getAbsolutePath();
549172c67b2SArmin Le Grand 
550172c67b2SArmin Le Grand                                 if(aObjectName.getLength())
551172c67b2SArmin Le Grand                                 {
552172c67b2SArmin Le Grand                             		INetURLObject aURL(aObjectName);
553172c67b2SArmin Le Grand 
554172c67b2SArmin Le Grand                                     aObjectName = aURL.getName(
555172c67b2SArmin Le Grand                                         INetURLObject::LAST_SEGMENT,
556172c67b2SArmin Le Grand                                         true,
557172c67b2SArmin Le Grand                                         INetURLObject::DECODE_WITH_CHARSET);
558172c67b2SArmin Le Grand                                 }
559025b0597SArmin Le Grand                             }
560025b0597SArmin Le Grand 
561025b0597SArmin Le Grand                             // pack in ObjectInfoPrimitive2D group
562025b0597SArmin Le Grand                             const drawinglayer::primitive2d::Primitive2DReference xRef(
563025b0597SArmin Le Grand                                 new drawinglayer::primitive2d::ObjectInfoPrimitive2D(
564025b0597SArmin Le Grand                                     rTarget,
565025b0597SArmin Le Grand                                     aObjectName,
566025b0597SArmin Le Grand                                     rTitle,
567025b0597SArmin Le Grand                                     rDesc));
568025b0597SArmin Le Grand 
569025b0597SArmin Le Grand                             rTarget = drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1);
570025b0597SArmin Le Grand                         }
571025b0597SArmin Le Grand                     }
572025b0597SArmin Le Grand                 }
573ddde725dSArmin Le Grand             }
574ddde725dSArmin Le Grand         }
575ddde725dSArmin Le Grand 
576e92bb418SOliver-Rainer Wittmann         const basegfx::B2DRange SvgNode::getCurrentViewPort() const
577ddde725dSArmin Le Grand         {
578ddde725dSArmin Le Grand             if(getParent())
579ddde725dSArmin Le Grand             {
580ddde725dSArmin Le Grand                 return getParent()->getCurrentViewPort();
581ddde725dSArmin Le Grand             }
582ddde725dSArmin Le Grand             else
583ddde725dSArmin Le Grand             {
584e92bb418SOliver-Rainer Wittmann                 return basegfx::B2DRange(); // return empty B2DRange
585ddde725dSArmin Le Grand             }
586ddde725dSArmin Le Grand         }
587ddde725dSArmin Le Grand 
588ddde725dSArmin Le Grand         double SvgNode::getCurrentFontSize() const
589ddde725dSArmin Le Grand         {
590ddde725dSArmin Le Grand             if(getSvgStyleAttributes())
591ddde725dSArmin Le Grand             {
592ddde725dSArmin Le Grand                 return getSvgStyleAttributes()->getFontSize().solve(*this, xcoordinate);
593ddde725dSArmin Le Grand             }
594ddde725dSArmin Le Grand             else if(getParent())
595ddde725dSArmin Le Grand             {
596ddde725dSArmin Le Grand                 return getParent()->getCurrentFontSize();
597ddde725dSArmin Le Grand             }
598ddde725dSArmin Le Grand             else
599ddde725dSArmin Le Grand             {
600ddde725dSArmin Le Grand                 return 0.0;
601ddde725dSArmin Le Grand             }
602ddde725dSArmin Le Grand         }
603ddde725dSArmin Le Grand 
604ddde725dSArmin Le Grand         double SvgNode::getCurrentXHeight() const
605ddde725dSArmin Le Grand         {
606ddde725dSArmin Le Grand             if(getSvgStyleAttributes())
607ddde725dSArmin Le Grand             {
608ddde725dSArmin Le Grand                 // for XHeight, use FontSize currently
609ddde725dSArmin Le Grand                 return getSvgStyleAttributes()->getFontSize().solve(*this, ycoordinate);
610ddde725dSArmin Le Grand             }
611ddde725dSArmin Le Grand             else if(getParent())
612ddde725dSArmin Le Grand             {
613ddde725dSArmin Le Grand                 return getParent()->getCurrentXHeight();
614ddde725dSArmin Le Grand             }
615ddde725dSArmin Le Grand             else
616ddde725dSArmin Le Grand             {
617ddde725dSArmin Le Grand                 return 0.0;
618ddde725dSArmin Le Grand             }
619ddde725dSArmin Le Grand         }
620ddde725dSArmin Le Grand 
621ddde725dSArmin Le Grand         void SvgNode::setId(const rtl::OUString* pfId)
622ddde725dSArmin Le Grand         {
623ddde725dSArmin Le Grand             if(mpId)
624ddde725dSArmin Le Grand             {
625ddde725dSArmin Le Grand                 mrDocument.removeSvgNodeFromMapper(*mpId);
626ddde725dSArmin Le Grand                 delete mpId;
627ddde725dSArmin Le Grand                 mpId = 0;
628ddde725dSArmin Le Grand             }
629ddde725dSArmin Le Grand 
630ddde725dSArmin Le Grand             if(pfId)
631ddde725dSArmin Le Grand             {
632ddde725dSArmin Le Grand                 mpId = new rtl::OUString(*pfId);
633ddde725dSArmin Le Grand                 mrDocument.addSvgNodeToMapper(*mpId, *this);
634ddde725dSArmin Le Grand             }
635ddde725dSArmin Le Grand         }
636ddde725dSArmin Le Grand 
637ddde725dSArmin Le Grand         void SvgNode::setClass(const rtl::OUString* pfClass)
638ddde725dSArmin Le Grand         {
639ddde725dSArmin Le Grand             if(mpClass)
640ddde725dSArmin Le Grand             {
641ddde725dSArmin Le Grand                 mrDocument.removeSvgNodeFromMapper(*mpClass);
642ddde725dSArmin Le Grand                 delete mpClass;
643ddde725dSArmin Le Grand                 mpClass = 0;
644ddde725dSArmin Le Grand             }
645ddde725dSArmin Le Grand 
646ddde725dSArmin Le Grand             if(pfClass)
647ddde725dSArmin Le Grand             {
648ddde725dSArmin Le Grand                 mpClass = new rtl::OUString(*pfClass);
649ddde725dSArmin Le Grand                 mrDocument.addSvgNodeToMapper(*mpClass, *this);
650ddde725dSArmin Le Grand             }
651ddde725dSArmin Le Grand         }
652ddde725dSArmin Le Grand 
653ddde725dSArmin Le Grand         XmlSpace SvgNode::getXmlSpace() const
654ddde725dSArmin Le Grand         {
655ddde725dSArmin Le Grand             if(maXmlSpace != XmlSpace_notset)
656ddde725dSArmin Le Grand             {
657ddde725dSArmin Le Grand                 return maXmlSpace;
658ddde725dSArmin Le Grand             }
659ddde725dSArmin Le Grand 
660ddde725dSArmin Le Grand             if(getParent())
661ddde725dSArmin Le Grand             {
662ddde725dSArmin Le Grand                 return getParent()->getXmlSpace();
663ddde725dSArmin Le Grand             }
664ddde725dSArmin Le Grand 
665ddde725dSArmin Le Grand             // default is XmlSpace_default
666ddde725dSArmin Le Grand             return XmlSpace_default;
667ddde725dSArmin Le Grand         }
668ddde725dSArmin Le Grand 
669ddde725dSArmin Le Grand     } // end of namespace svgreader
670ddde725dSArmin Le Grand } // end of namespace svgio
671ddde725dSArmin Le Grand 
672ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
673ddde725dSArmin Le Grand // eof
674