xref: /aoo42x/main/svgio/source/svgreader/svgnode.cxx (revision 4374d266)
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     {
39*4374d266SArmin Le Grand         /// #125258#
40*4374d266SArmin Le Grand         bool SvgNode::supportsParentStyle() const
41*4374d266SArmin Le Grand         {
42*4374d266SArmin Le Grand             return true;
43*4374d266SArmin Le Grand         }
44*4374d266SArmin Le Grand 
45ddde725dSArmin Le Grand         const SvgStyleAttributes* SvgNode::getSvgStyleAttributes() const
46ddde725dSArmin Le Grand         {
47ddde725dSArmin Le Grand             return 0;
48ddde725dSArmin Le Grand         }
49ddde725dSArmin Le Grand 
5050b37974SArmin Le Grand         const SvgStyleAttributes* SvgNode::checkForCssStyle(const rtl::OUString& rClassStr, const SvgStyleAttributes& rOriginal) const
5150b37974SArmin Le Grand         {
520906e779SArmin Le Grand             if(maCssStyleVector.empty()) // #120435# Evaluate for CSS styles only once, this cannot change
5350b37974SArmin Le Grand             {
540906e779SArmin Le Grand                 const SvgDocument& rDocument = getDocument();
550906e779SArmin Le Grand 
560906e779SArmin Le Grand                 if(rDocument.hasSvgStyleAttributesById())
5750b37974SArmin Le Grand                 {
580906e779SArmin Le Grand                     if(getClass())
590906e779SArmin Le Grand                     {
600906e779SArmin Le Grand                         // find all referenced CSS styles, a list of entries is allowed
610906e779SArmin Le Grand                         const rtl::OUString* pClassList = getClass();
620906e779SArmin Le Grand                         const sal_Int32 nLen(pClassList->getLength());
630906e779SArmin Le Grand                         sal_Int32 nPos(0);
640906e779SArmin Le Grand                         const SvgStyleAttributes* pNew = 0;
6550b37974SArmin Le Grand 
660906e779SArmin Le Grand                         skip_char(*pClassList, sal_Unicode(' '), nPos, nLen);
6750b37974SArmin Le Grand 
680906e779SArmin Le Grand                         while(nPos < nLen)
690906e779SArmin Le Grand                         {
700906e779SArmin Le Grand                             rtl::OUStringBuffer aTokenValue;
7150b37974SArmin Le Grand 
720906e779SArmin Le Grand                             copyToLimiter(*pClassList, sal_Unicode(' '), nPos, aTokenValue, nLen);
730906e779SArmin Le Grand                             skip_char(*pClassList, sal_Unicode(' '), nPos, nLen);
7450b37974SArmin Le Grand 
750906e779SArmin Le Grand                             rtl::OUString aId(rtl::OUString::createFromAscii("."));
760906e779SArmin Le Grand                             const rtl::OUString aOUTokenValue(aTokenValue.makeStringAndClear());
7750b37974SArmin Le Grand 
780906e779SArmin Le Grand                             // look for CSS style common to token
790906e779SArmin Le Grand                             aId = aId + aOUTokenValue;
800906e779SArmin Le Grand                             pNew = rDocument.findSvgStyleAttributesById(aId);
8150b37974SArmin Le Grand 
820906e779SArmin Le Grand                             if(!pNew && rClassStr.getLength())
830906e779SArmin Le Grand                             {
840906e779SArmin Le Grand                                 // look for CSS style common to class.token
850906e779SArmin Le Grand                                 aId = rClassStr + aId;
8650b37974SArmin Le Grand 
870906e779SArmin Le Grand                                 pNew = rDocument.findSvgStyleAttributesById(aId);
880906e779SArmin Le Grand                             }
8950b37974SArmin Le Grand 
900906e779SArmin Le Grand                             if(pNew)
910906e779SArmin Le Grand                             {
920906e779SArmin Le Grand                                 const_cast< SvgNode* >(this)->maCssStyleVector.push_back(pNew);
930906e779SArmin Le Grand                             }
940906e779SArmin Le Grand                         }
950906e779SArmin Le Grand                     }
960906e779SArmin Le Grand 
970906e779SArmin Le Grand                     if(maCssStyleVector.empty() && getId())
980906e779SArmin Le Grand                     {
990906e779SArmin Le Grand                         // if none found, search for CSS style equal to Id
1000906e779SArmin Le Grand                         const SvgStyleAttributes* pNew = rDocument.findSvgStyleAttributesById(*getId());
1010906e779SArmin Le Grand 
10250b37974SArmin Le Grand                         if(pNew)
10350b37974SArmin Le Grand                         {
10450b37974SArmin Le Grand                             const_cast< SvgNode* >(this)->maCssStyleVector.push_back(pNew);
10550b37974SArmin Le Grand                         }
10650b37974SArmin Le Grand                     }
10750b37974SArmin Le Grand 
1080906e779SArmin Le Grand                     if(maCssStyleVector.empty() && rClassStr.getLength())
10950b37974SArmin Le Grand                     {
1100906e779SArmin Le Grand                         // if none found, search for CSS style equal to class type
1110906e779SArmin Le Grand                         const SvgStyleAttributes* pNew = rDocument.findSvgStyleAttributesById(rClassStr);
11250b37974SArmin Le Grand 
1130906e779SArmin Le Grand                         if(pNew)
1140906e779SArmin Le Grand                         {
1150906e779SArmin Le Grand                             const_cast< SvgNode* >(this)->maCssStyleVector.push_back(pNew);
1160906e779SArmin Le Grand                         }
11750b37974SArmin Le Grand                     }
11850b37974SArmin Le Grand                 }
11950b37974SArmin Le Grand             }
12050b37974SArmin Le Grand 
1217b027e49SArmin Le Grand             if(!maCssStyleVector.empty())
12250b37974SArmin Le Grand             {
1237b027e49SArmin Le Grand                 // #123510# if CSS styles were found, create a linked list with rOriginal as parent
1247b027e49SArmin Le Grand                 // and all CSS styles as linked children, so that the style attribute has
1257b027e49SArmin Le Grand                 // priority over the CSS style. If there is no style attribute this means that
1267b027e49SArmin Le Grand                 // no values are set at rOriginal, thus it is still correct to have that order.
1270906e779SArmin Le Grand                 // Repeated style requests should only be issued from sub-Text nodes and I'm not
1280906e779SArmin Le Grand                 // sure if in-between text nodes may build other chains (should not happen). But
1290906e779SArmin Le Grand                 // it's only a re-chaining with pointers (cheap), so allow to do it every time.
13050b37974SArmin Le Grand                 SvgStyleAttributes* pCurrent = const_cast< SvgStyleAttributes* >(&rOriginal);
1310906e779SArmin Le Grand                 pCurrent->setCssStyleParent(0);
13250b37974SArmin Le Grand 
13350b37974SArmin Le Grand                 for(sal_uInt32 a(0); a < maCssStyleVector.size(); a++)
13450b37974SArmin Le Grand                 {
1357b027e49SArmin Le Grand                     SvgStyleAttributes* pNext = const_cast< SvgStyleAttributes* >(maCssStyleVector[a]);
13650b37974SArmin Le Grand 
1377b027e49SArmin Le Grand                     pCurrent->setCssStyleParent(pNext);
1387b027e49SArmin Le Grand                     pCurrent = pNext;
1397b027e49SArmin Le Grand                     pCurrent->setCssStyleParent(0);
14050b37974SArmin Le Grand                 }
14150b37974SArmin Le Grand             }
1427b027e49SArmin Le Grand 
1437b027e49SArmin Le Grand             return &rOriginal;
14450b37974SArmin Le Grand         }
14550b37974SArmin Le Grand 
146ddde725dSArmin Le Grand         SvgNode::SvgNode(
147ddde725dSArmin Le Grand             SVGToken aType,
148ddde725dSArmin Le Grand             SvgDocument& rDocument,
149ddde725dSArmin Le Grand             SvgNode* pParent)
150ddde725dSArmin Le Grand         :   maType(aType),
151ddde725dSArmin Le Grand             mrDocument(rDocument),
152ddde725dSArmin Le Grand             mpParent(pParent),
153ddde725dSArmin Le Grand             mpAlternativeParent(0),
154ddde725dSArmin Le Grand             maChildren(),
155ddde725dSArmin Le Grand             mpId(0),
156ddde725dSArmin Le Grand             mpClass(0),
15750b37974SArmin Le Grand             maXmlSpace(XmlSpace_notset),
158a275c134SArmin Le Grand             maDisplay(Display_inline),
15950b37974SArmin Le Grand             maCssStyleVector()
160ddde725dSArmin Le Grand         {
161ddde725dSArmin Le Grand             OSL_ENSURE(SVGTokenUnknown != maType, "SvgNode with unknown type created (!)");
162ddde725dSArmin Le Grand 
163ddde725dSArmin Le Grand             if(pParent)
164ddde725dSArmin Le Grand             {
165ddde725dSArmin Le Grand                 pParent->maChildren.push_back(this);
166ddde725dSArmin Le Grand             }
167ddde725dSArmin Le Grand             else
168ddde725dSArmin Le Grand             {
169ddde725dSArmin Le Grand #ifdef DBG_UTIL
170ddde725dSArmin Le Grand                 if(SVGTokenSvg != getType())
171ddde725dSArmin Le Grand                 {
172ddde725dSArmin Le Grand                     OSL_ENSURE(false, "No parent for this node (!)");
173ddde725dSArmin Le Grand                 }
174ddde725dSArmin Le Grand #endif
175ddde725dSArmin Le Grand             }
176ddde725dSArmin Le Grand         }
177ddde725dSArmin Le Grand 
178ddde725dSArmin Le Grand         SvgNode::~SvgNode()
179ddde725dSArmin Le Grand         {
180ddde725dSArmin Le Grand             while(maChildren.size())
181ddde725dSArmin Le Grand             {
182ddde725dSArmin Le Grand                 delete maChildren[maChildren.size() - 1];
183ddde725dSArmin Le Grand                 maChildren.pop_back();
184ddde725dSArmin Le Grand             }
185ddde725dSArmin Le Grand 
186ddde725dSArmin Le Grand             if(mpId) delete mpId;
187ddde725dSArmin Le Grand             if(mpClass) delete mpClass;
188ddde725dSArmin Le Grand         }
189ddde725dSArmin Le Grand 
190ddde725dSArmin Le Grand         void SvgNode::parseAttributes(const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttribs)
191ddde725dSArmin Le Grand         {
192ddde725dSArmin Le Grand             const sal_uInt32 nAttributes(xAttribs->getLength());
193175cd092SArmin Le Grand             // #122522# SVG defines that 'In general, this means that the presentation attributes have
194175cd092SArmin Le Grand             // lower priority than other CSS style rules specified in author style sheets or �style�
195175cd092SArmin Le Grand             // attributes.' in http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes
196175cd092SArmin Le Grand             // (6.4 Specifying properties using the presentation attributes SVG 1.1). That means that
197175cd092SArmin Le Grand             // e.g. font-size will appear as presentation attribute and CSS style attribute. In these
198175cd092SArmin Le Grand             // cases, CSS style attributes need to have precedence. To do so it is possible to create
199175cd092SArmin Le Grand             // a proirity system for all properties of a shape, but it will also work to parse the
200175cd092SArmin Le Grand             // presentation attributes of type 'style' last, so they will overwrite the less-prioritized
201175cd092SArmin Le Grand             // already interpreted ones. Thus, remember SVGTokenStyle entries and parse them last.
202175cd092SArmin Le Grand             // To make this work it is required that parseAttribute is only called by parseAttributes
203175cd092SArmin Le Grand             // which is the case.
204175cd092SArmin Le Grand             std::vector< sal_uInt32 > aSVGTokenStyleIndexes;
205175cd092SArmin Le Grand 
206ddde725dSArmin Le Grand             for(sal_uInt32 a(0); a < nAttributes; a++)
207ddde725dSArmin Le Grand             {
208ddde725dSArmin Le Grand                 const ::rtl::OUString aTokenName(xAttribs->getNameByIndex(a));
209175cd092SArmin Le Grand                 const SVGToken aSVGToken(StrToSVGToken(aTokenName));
210175cd092SArmin Le Grand 
211175cd092SArmin Le Grand                 if(SVGTokenStyle == aSVGToken)
212175cd092SArmin Le Grand                 {
213175cd092SArmin Le Grand                     // #122522# remember SVGTokenStyle entry
214175cd092SArmin Le Grand                     aSVGTokenStyleIndexes.push_back(a);
215175cd092SArmin Le Grand                 }
216175cd092SArmin Le Grand                 else
217175cd092SArmin Le Grand                 {
21886d02030SArmin Le Grand                     parseAttribute(aTokenName, aSVGToken, xAttribs->getValueByIndex(a));
219175cd092SArmin Le Grand                 }
220175cd092SArmin Le Grand             }
221175cd092SArmin Le Grand 
222175cd092SArmin Le Grand             // #122522# parse SVGTokenStyle entries last to override already interpreted
223175cd092SArmin Le Grand             // 'presentation attributes' of potenially the same type
224175cd092SArmin Le Grand             for(sal_uInt32 b(0); b < aSVGTokenStyleIndexes.size(); b++)
225175cd092SArmin Le Grand             {
226175cd092SArmin Le Grand                 const sal_uInt32 nSVGTokenStyleIndex(aSVGTokenStyleIndexes[b]);
227175cd092SArmin Le Grand                 const ::rtl::OUString aTokenName(xAttribs->getNameByIndex(nSVGTokenStyleIndex));
228175cd092SArmin Le Grand 
229175cd092SArmin Le Grand                 parseAttribute(aTokenName, SVGTokenStyle, xAttribs->getValueByIndex(nSVGTokenStyleIndex));
230ddde725dSArmin Le Grand             }
231ddde725dSArmin Le Grand         }
232ddde725dSArmin Le Grand 
23301e92ad6SArmin Le Grand         Display getDisplayFromContent(const rtl::OUString& aContent)
23401e92ad6SArmin Le Grand         {
23501e92ad6SArmin Le Grand             if(aContent.getLength())
23601e92ad6SArmin Le Grand             {
237e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrInline(rtl::OUString::createFromAscii("inline"));
238e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrBlock(rtl::OUString::createFromAscii("block"));
239e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrList_item(rtl::OUString::createFromAscii("list-item"));
240e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrRun_in(rtl::OUString::createFromAscii("run-in"));
241e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrCompact(rtl::OUString::createFromAscii("compact"));
242e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrMarker(rtl::OUString::createFromAscii("marker"));
243e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable(rtl::OUString::createFromAscii("table"));
244e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrInline_table(rtl::OUString::createFromAscii("inline-table"));
245e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable_row_group(rtl::OUString::createFromAscii("table-row-group"));
246e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable_header_group(rtl::OUString::createFromAscii("table-header-group"));
247e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable_footer_group(rtl::OUString::createFromAscii("table-footer-group"));
248e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable_row(rtl::OUString::createFromAscii("table-row"));
249e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable_column_group(rtl::OUString::createFromAscii("table-column-group"));
250e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable_column(rtl::OUString::createFromAscii("table-column"));
25101e92ad6SArmin Le Grand                 static rtl::OUString aStrTable_cell(rtl::OUString::createFromAscii("table-cell"));
25201e92ad6SArmin Le Grand                 static rtl::OUString aStrTable_caption(rtl::OUString::createFromAscii("table-caption"));
25301e92ad6SArmin Le Grand                 static rtl::OUString aStrNone(rtl::OUString::createFromAscii("none"));
25401e92ad6SArmin Le Grand                 static rtl::OUString aStrInherit(rtl::OUString::createFromAscii("inherit"));
25501e92ad6SArmin Le Grand 
25601e92ad6SArmin Le Grand                 if(aContent.match(aStrInline))
25701e92ad6SArmin Le Grand                 {
25801e92ad6SArmin Le Grand                     return Display_inline;
25901e92ad6SArmin Le Grand                 }
26001e92ad6SArmin Le Grand                 else if(aContent.match(aStrNone))
26101e92ad6SArmin Le Grand                 {
26201e92ad6SArmin Le Grand                     return Display_none;
26301e92ad6SArmin Le Grand                 }
26401e92ad6SArmin Le Grand                 else if(aContent.match(aStrInherit))
26501e92ad6SArmin Le Grand                 {
26601e92ad6SArmin Le Grand                     return Display_inherit;
26701e92ad6SArmin Le Grand                 }
268e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrBlock))
26901e92ad6SArmin Le Grand                 {
27001e92ad6SArmin Le Grand                     return Display_block;
27101e92ad6SArmin Le Grand                 }
272e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrList_item))
27301e92ad6SArmin Le Grand                 {
27401e92ad6SArmin Le Grand                     return Display_list_item;
27501e92ad6SArmin Le Grand                 }
276e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrRun_in))
27701e92ad6SArmin Le Grand                 {
27801e92ad6SArmin Le Grand                     return Display_run_in;
27901e92ad6SArmin Le Grand                 }
280e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrCompact))
28101e92ad6SArmin Le Grand                 {
28201e92ad6SArmin Le Grand                     return Display_compact;
28301e92ad6SArmin Le Grand                 }
284e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrMarker))
28501e92ad6SArmin Le Grand                 {
28601e92ad6SArmin Le Grand                     return Display_marker;
28701e92ad6SArmin Le Grand                 }
288e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable))
28901e92ad6SArmin Le Grand                 {
29001e92ad6SArmin Le Grand                     return Display_table;
29101e92ad6SArmin Le Grand                 }
292e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrInline_table))
29301e92ad6SArmin Le Grand                 {
29401e92ad6SArmin Le Grand                     return Display_inline_table;
29501e92ad6SArmin Le Grand                 }
296e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable_row_group))
29701e92ad6SArmin Le Grand                 {
29801e92ad6SArmin Le Grand                     return Display_table_row_group;
29901e92ad6SArmin Le Grand                 }
300e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable_header_group))
30101e92ad6SArmin Le Grand                 {
30201e92ad6SArmin Le Grand                     return Display_table_header_group;
30301e92ad6SArmin Le Grand                 }
304e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable_footer_group))
30501e92ad6SArmin Le Grand                 {
30601e92ad6SArmin Le Grand                     return Display_table_footer_group;
30701e92ad6SArmin Le Grand                 }
308e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable_row))
30901e92ad6SArmin Le Grand                 {
31001e92ad6SArmin Le Grand                     return Display_table_row;
31101e92ad6SArmin Le Grand                 }
312e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable_column_group))
31301e92ad6SArmin Le Grand                 {
31401e92ad6SArmin Le Grand                     return Display_table_column_group;
31501e92ad6SArmin Le Grand                 }
316e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable_column))
31701e92ad6SArmin Le Grand                 {
31801e92ad6SArmin Le Grand                     return Display_table_column;
31901e92ad6SArmin Le Grand                 }
32001e92ad6SArmin Le Grand                 else if(aContent.match(aStrTable_cell))
32101e92ad6SArmin Le Grand                 {
32201e92ad6SArmin Le Grand                     return Display_table_cell;
32301e92ad6SArmin Le Grand                 }
32401e92ad6SArmin Le Grand                 else if(aContent.match(aStrTable_caption))
32501e92ad6SArmin Le Grand                 {
32601e92ad6SArmin Le Grand                     return Display_table_caption;
32701e92ad6SArmin Le Grand                 }
32801e92ad6SArmin Le Grand             }
32901e92ad6SArmin Le Grand 
33001e92ad6SArmin Le Grand             // return the default
33101e92ad6SArmin Le Grand             return Display_inline;
33201e92ad6SArmin Le Grand         }
33301e92ad6SArmin Le Grand 
334e2bf1e9dSArmin Le Grand         void SvgNode::parseAttribute(const rtl::OUString& /*rTokenName*/, SVGToken aSVGToken, const rtl::OUString& aContent)
335ddde725dSArmin Le Grand         {
336ddde725dSArmin Le Grand             switch(aSVGToken)
337ddde725dSArmin Le Grand             {
338ddde725dSArmin Le Grand                 case SVGTokenId:
339ddde725dSArmin Le Grand                 {
340ddde725dSArmin Le Grand                     if(aContent.getLength())
341ddde725dSArmin Le Grand                     {
342ddde725dSArmin Le Grand                         setId(&aContent);
343ddde725dSArmin Le Grand                     }
344ddde725dSArmin Le Grand                     break;
345ddde725dSArmin Le Grand                 }
346ddde725dSArmin Le Grand                 case SVGTokenClass:
347ddde725dSArmin Le Grand                 {
348ddde725dSArmin Le Grand                     if(aContent.getLength())
349ddde725dSArmin Le Grand                     {
350ddde725dSArmin Le Grand                         setClass(&aContent);
351ddde725dSArmin Le Grand                     }
352ddde725dSArmin Le Grand                     break;
353ddde725dSArmin Le Grand                 }
354ddde725dSArmin Le Grand                 case SVGTokenXmlSpace:
355ddde725dSArmin Le Grand                 {
356ddde725dSArmin Le Grand                     if(aContent.getLength())
357ddde725dSArmin Le Grand                     {
358ddde725dSArmin Le Grand                         static rtl::OUString aStrDefault(rtl::OUString::createFromAscii("default"));
359ddde725dSArmin Le Grand                         static rtl::OUString aStrPreserve(rtl::OUString::createFromAscii("preserve"));
360ddde725dSArmin Le Grand 
361ddde725dSArmin Le Grand                         if(aContent.match(aStrDefault))
362ddde725dSArmin Le Grand                         {
363ddde725dSArmin Le Grand                             setXmlSpace(XmlSpace_default);
364ddde725dSArmin Le Grand                         }
365ddde725dSArmin Le Grand                         else if(aContent.match(aStrPreserve))
366ddde725dSArmin Le Grand                         {
367ddde725dSArmin Le Grand                             setXmlSpace(XmlSpace_preserve);
368ddde725dSArmin Le Grand                         }
369ddde725dSArmin Le Grand                     }
370ddde725dSArmin Le Grand                     break;
371ddde725dSArmin Le Grand                 }
372a275c134SArmin Le Grand                 case SVGTokenDisplay:
373a275c134SArmin Le Grand                 {
374a275c134SArmin Le Grand                     if(aContent.getLength())
375a275c134SArmin Le Grand                     {
37601e92ad6SArmin Le Grand                         setDisplay(getDisplayFromContent(aContent));
377a275c134SArmin Le Grand                     }
378a275c134SArmin Le Grand                     break;
379a275c134SArmin Le Grand                 }
380e2bf1e9dSArmin Le Grand                 default:
381e2bf1e9dSArmin Le Grand                 {
382e2bf1e9dSArmin Le Grand                     break;
383e2bf1e9dSArmin Le Grand                 }
384ddde725dSArmin Le Grand             }
385ddde725dSArmin Le Grand         }
386ddde725dSArmin Le Grand 
387ddde725dSArmin Le Grand         void SvgNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
388ddde725dSArmin Le Grand         {
389a275c134SArmin Le Grand             if(Display_none == getDisplay())
390a275c134SArmin Le Grand             {
391a275c134SArmin Le Grand                 return;
392a275c134SArmin Le Grand             }
393a275c134SArmin Le Grand 
394ddde725dSArmin Le Grand             if(!bReferenced)
395ddde725dSArmin Le Grand             {
396ddde725dSArmin Le Grand                 if(SVGTokenDefs == getType() ||
397ddde725dSArmin Le Grand                     SVGTokenSymbol == getType() ||
398ddde725dSArmin Le Grand                     SVGTokenClipPathNode == getType() ||
399ddde725dSArmin Le Grand                     SVGTokenMask == getType() ||
400ddde725dSArmin Le Grand                     SVGTokenMarker == getType() ||
401ddde725dSArmin Le Grand                     SVGTokenPattern == getType())
402ddde725dSArmin Le Grand                 {
403ddde725dSArmin Le Grand                     // do not decompose defs or symbol nodes (these hold only style-like
404ddde725dSArmin Le Grand                     // objects which may be used by referencing them) except when doing
405ddde725dSArmin Le Grand                     // so controlled referenced
406ddde725dSArmin Le Grand 
407ddde725dSArmin Le Grand                     // also do not decompose ClipPaths and Masks. These should be embedded
408ddde725dSArmin Le Grand                     // in a defs node (which gets not decomposed by itself), but you never
409ddde725dSArmin Le Grand                     // know
410ddde725dSArmin Le Grand 
411ddde725dSArmin Le Grand                     // also not directly used are Markers and Patterns, only indirecty used
412ddde725dSArmin Le Grand                     // by reference
413a275c134SArmin Le Grand 
414a275c134SArmin Le Grand                     // #121656# also do not decompose nodes which have display="none" set
415a275c134SArmin Le Grand                     // as property
416ddde725dSArmin Le Grand                     return;
417ddde725dSArmin Le Grand                 }
418ddde725dSArmin Le Grand             }
419ddde725dSArmin Le Grand 
420ddde725dSArmin Le Grand             const SvgNodeVector& rChildren = getChildren();
421ddde725dSArmin Le Grand 
422ddde725dSArmin Le Grand             if(!rChildren.empty())
423ddde725dSArmin Le Grand             {
424ddde725dSArmin Le Grand                 const sal_uInt32 nCount(rChildren.size());
425ddde725dSArmin Le Grand 
426ddde725dSArmin Le Grand                 for(sal_uInt32 a(0); a < nCount; a++)
427ddde725dSArmin Le Grand                 {
428ddde725dSArmin Le Grand                     SvgNode* pCandidate = rChildren[a];
429ddde725dSArmin Le Grand 
430a275c134SArmin Le Grand                     if(pCandidate && Display_none != pCandidate->getDisplay())
431ddde725dSArmin Le Grand                     {
432ddde725dSArmin Le Grand                         drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
433ddde725dSArmin Le Grand 
434ddde725dSArmin Le Grand                         pCandidate->decomposeSvgNode(aNewTarget, bReferenced);
435ddde725dSArmin Le Grand 
436ddde725dSArmin Le Grand                         if(aNewTarget.hasElements())
437ddde725dSArmin Le Grand                         {
438ddde725dSArmin Le Grand                             drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aNewTarget);
439ddde725dSArmin Le Grand                         }
440ddde725dSArmin Le Grand                     }
441ddde725dSArmin Le Grand                     else
442ddde725dSArmin Le Grand                     {
443ddde725dSArmin Le Grand                         OSL_ENSURE(false, "Null-Pointer in child node list (!)");
444ddde725dSArmin Le Grand                     }
445ddde725dSArmin Le Grand                 }
446025b0597SArmin Le Grand 
447025b0597SArmin Le Grand                 if(rTarget.hasElements())
448025b0597SArmin Le Grand                 {
449025b0597SArmin Le Grand                     const SvgStyleAttributes* pStyles = getSvgStyleAttributes();
450025b0597SArmin Le Grand 
451025b0597SArmin Le Grand                     if(pStyles)
452025b0597SArmin Le Grand                     {
453025b0597SArmin Le Grand                         // check if we have Title or Desc
454025b0597SArmin Le Grand                         const rtl::OUString& rTitle = pStyles->getTitle();
455025b0597SArmin Le Grand                         const rtl::OUString& rDesc = pStyles->getDesc();
456025b0597SArmin Le Grand 
457025b0597SArmin Le Grand                         if(rTitle.getLength() || rDesc.getLength())
458025b0597SArmin Le Grand                         {
459025b0597SArmin Le Grand                             // default object name is empty
460025b0597SArmin Le Grand                             rtl::OUString aObjectName;
461025b0597SArmin Le Grand 
462025b0597SArmin Le Grand                             // use path as object name when outmost element
463025b0597SArmin Le Grand                             if(SVGTokenSvg == getType())
464025b0597SArmin Le Grand                             {
465025b0597SArmin Le Grand                                 aObjectName = getDocument().getAbsolutePath();
466172c67b2SArmin Le Grand 
467172c67b2SArmin Le Grand                                 if(aObjectName.getLength())
468172c67b2SArmin Le Grand                                 {
469172c67b2SArmin Le Grand                             		INetURLObject aURL(aObjectName);
470172c67b2SArmin Le Grand 
471172c67b2SArmin Le Grand                                     aObjectName = aURL.getName(
472172c67b2SArmin Le Grand                                         INetURLObject::LAST_SEGMENT,
473172c67b2SArmin Le Grand                                         true,
474172c67b2SArmin Le Grand                                         INetURLObject::DECODE_WITH_CHARSET);
475172c67b2SArmin Le Grand                                 }
476025b0597SArmin Le Grand                             }
477025b0597SArmin Le Grand 
478025b0597SArmin Le Grand                             // pack in ObjectInfoPrimitive2D group
479025b0597SArmin Le Grand                             const drawinglayer::primitive2d::Primitive2DReference xRef(
480025b0597SArmin Le Grand                                 new drawinglayer::primitive2d::ObjectInfoPrimitive2D(
481025b0597SArmin Le Grand                                     rTarget,
482025b0597SArmin Le Grand                                     aObjectName,
483025b0597SArmin Le Grand                                     rTitle,
484025b0597SArmin Le Grand                                     rDesc));
485025b0597SArmin Le Grand 
486025b0597SArmin Le Grand                             rTarget = drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1);
487025b0597SArmin Le Grand                         }
488025b0597SArmin Le Grand                     }
489025b0597SArmin Le Grand                 }
490ddde725dSArmin Le Grand             }
491ddde725dSArmin Le Grand         }
492ddde725dSArmin Le Grand 
493e92bb418SOliver-Rainer Wittmann         const basegfx::B2DRange SvgNode::getCurrentViewPort() const
494ddde725dSArmin Le Grand         {
495ddde725dSArmin Le Grand             if(getParent())
496ddde725dSArmin Le Grand             {
497ddde725dSArmin Le Grand                 return getParent()->getCurrentViewPort();
498ddde725dSArmin Le Grand             }
499ddde725dSArmin Le Grand             else
500ddde725dSArmin Le Grand             {
501e92bb418SOliver-Rainer Wittmann                 return basegfx::B2DRange(); // return empty B2DRange
502ddde725dSArmin Le Grand             }
503ddde725dSArmin Le Grand         }
504ddde725dSArmin Le Grand 
505ddde725dSArmin Le Grand         double SvgNode::getCurrentFontSize() const
506ddde725dSArmin Le Grand         {
507ddde725dSArmin Le Grand             if(getSvgStyleAttributes())
508ddde725dSArmin Le Grand             {
509ddde725dSArmin Le Grand                 return getSvgStyleAttributes()->getFontSize().solve(*this, xcoordinate);
510ddde725dSArmin Le Grand             }
511ddde725dSArmin Le Grand             else if(getParent())
512ddde725dSArmin Le Grand             {
513ddde725dSArmin Le Grand                 return getParent()->getCurrentFontSize();
514ddde725dSArmin Le Grand             }
515ddde725dSArmin Le Grand             else
516ddde725dSArmin Le Grand             {
517ddde725dSArmin Le Grand                 return 0.0;
518ddde725dSArmin Le Grand             }
519ddde725dSArmin Le Grand         }
520ddde725dSArmin Le Grand 
521ddde725dSArmin Le Grand         double SvgNode::getCurrentXHeight() const
522ddde725dSArmin Le Grand         {
523ddde725dSArmin Le Grand             if(getSvgStyleAttributes())
524ddde725dSArmin Le Grand             {
525ddde725dSArmin Le Grand                 // for XHeight, use FontSize currently
526ddde725dSArmin Le Grand                 return getSvgStyleAttributes()->getFontSize().solve(*this, ycoordinate);
527ddde725dSArmin Le Grand             }
528ddde725dSArmin Le Grand             else if(getParent())
529ddde725dSArmin Le Grand             {
530ddde725dSArmin Le Grand                 return getParent()->getCurrentXHeight();
531ddde725dSArmin Le Grand             }
532ddde725dSArmin Le Grand             else
533ddde725dSArmin Le Grand             {
534ddde725dSArmin Le Grand                 return 0.0;
535ddde725dSArmin Le Grand             }
536ddde725dSArmin Le Grand         }
537ddde725dSArmin Le Grand 
538ddde725dSArmin Le Grand         void SvgNode::setId(const rtl::OUString* pfId)
539ddde725dSArmin Le Grand         {
540ddde725dSArmin Le Grand             if(mpId)
541ddde725dSArmin Le Grand             {
542ddde725dSArmin Le Grand                 mrDocument.removeSvgNodeFromMapper(*mpId);
543ddde725dSArmin Le Grand                 delete mpId;
544ddde725dSArmin Le Grand                 mpId = 0;
545ddde725dSArmin Le Grand             }
546ddde725dSArmin Le Grand 
547ddde725dSArmin Le Grand             if(pfId)
548ddde725dSArmin Le Grand             {
549ddde725dSArmin Le Grand                 mpId = new rtl::OUString(*pfId);
550ddde725dSArmin Le Grand                 mrDocument.addSvgNodeToMapper(*mpId, *this);
551ddde725dSArmin Le Grand             }
552ddde725dSArmin Le Grand         }
553ddde725dSArmin Le Grand 
554ddde725dSArmin Le Grand         void SvgNode::setClass(const rtl::OUString* pfClass)
555ddde725dSArmin Le Grand         {
556ddde725dSArmin Le Grand             if(mpClass)
557ddde725dSArmin Le Grand             {
558ddde725dSArmin Le Grand                 mrDocument.removeSvgNodeFromMapper(*mpClass);
559ddde725dSArmin Le Grand                 delete mpClass;
560ddde725dSArmin Le Grand                 mpClass = 0;
561ddde725dSArmin Le Grand             }
562ddde725dSArmin Le Grand 
563ddde725dSArmin Le Grand             if(pfClass)
564ddde725dSArmin Le Grand             {
565ddde725dSArmin Le Grand                 mpClass = new rtl::OUString(*pfClass);
566ddde725dSArmin Le Grand                 mrDocument.addSvgNodeToMapper(*mpClass, *this);
567ddde725dSArmin Le Grand             }
568ddde725dSArmin Le Grand         }
569ddde725dSArmin Le Grand 
570ddde725dSArmin Le Grand         XmlSpace SvgNode::getXmlSpace() const
571ddde725dSArmin Le Grand         {
572ddde725dSArmin Le Grand             if(maXmlSpace != XmlSpace_notset)
573ddde725dSArmin Le Grand             {
574ddde725dSArmin Le Grand                 return maXmlSpace;
575ddde725dSArmin Le Grand             }
576ddde725dSArmin Le Grand 
577ddde725dSArmin Le Grand             if(getParent())
578ddde725dSArmin Le Grand             {
579ddde725dSArmin Le Grand                 return getParent()->getXmlSpace();
580ddde725dSArmin Le Grand             }
581ddde725dSArmin Le Grand 
582ddde725dSArmin Le Grand             // default is XmlSpace_default
583ddde725dSArmin Le Grand             return XmlSpace_default;
584ddde725dSArmin Le Grand         }
585ddde725dSArmin Le Grand 
586ddde725dSArmin Le Grand     } // end of namespace svgreader
587ddde725dSArmin Le Grand } // end of namespace svgio
588ddde725dSArmin Le Grand 
589ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
590ddde725dSArmin Le Grand // eof
591