xref: /aoo42x/main/svgio/source/svgreader/svgnode.cxx (revision 9d56236f)
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 
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                 {
58*9d56236fSArmin Le Grand                     // #125293# If we have CssStyles we need to buuild a linked list of SvgStyleAttributes
59*9d56236fSArmin Le Grand                     // which represent this for the current object. There are various methods to
60*9d56236fSArmin Le Grand                     // specify CssStyles which need to be taken into account in a given order:
61*9d56236fSArmin Le Grand                     // - 'id' element
62*9d56236fSArmin Le Grand                     // - 'class' element(s)
63*9d56236fSArmin Le Grand                     // - type-dependent elements (e..g. 'rect' for all rect elements)
64*9d56236fSArmin Le Grand                     // - local firect attributes (rOriginal)
65*9d56236fSArmin Le Grand                     // - inherited attributes (up the hierarchy)
66*9d56236fSArmin Le Grand                     // The first three will be collected in maCssStyleVector for the current element
67*9d56236fSArmin Le Grand                     // (once, this will not change) and be linked in the needed order using the
68*9d56236fSArmin Le Grand                     // get/setCssStyleParent at the SvgStyleAttributes which will be used preferred in
69*9d56236fSArmin Le Grand                     // member evaluation over the existing parent hierarchy
70*9d56236fSArmin Le Grand 
71*9d56236fSArmin Le Grand                     // check for 'id' references
72*9d56236fSArmin Le Grand                     if(getId())
73*9d56236fSArmin Le Grand                     {
74*9d56236fSArmin Le Grand                         // search for CSS style equal to Id
75*9d56236fSArmin Le Grand                         const SvgStyleAttributes* pNew = rDocument.findSvgStyleAttributesById(*getId());
76*9d56236fSArmin Le Grand 
77*9d56236fSArmin Le Grand                         if(pNew)
78*9d56236fSArmin Le Grand                         {
79*9d56236fSArmin Le Grand                             const_cast< SvgNode* >(this)->maCssStyleVector.push_back(pNew);
80*9d56236fSArmin Le Grand                         }
81*9d56236fSArmin Le Grand                     }
82*9d56236fSArmin Le Grand 
83*9d56236fSArmin Le Grand                     // check for 'class' references
840906e779SArmin Le Grand                     if(getClass())
850906e779SArmin Le Grand                     {
860906e779SArmin Le Grand                         // find all referenced CSS styles, a list of entries is allowed
870906e779SArmin Le Grand                         const rtl::OUString* pClassList = getClass();
880906e779SArmin Le Grand                         const sal_Int32 nLen(pClassList->getLength());
890906e779SArmin Le Grand                         sal_Int32 nPos(0);
900906e779SArmin Le Grand                         const SvgStyleAttributes* pNew = 0;
9150b37974SArmin Le Grand 
920906e779SArmin Le Grand                         skip_char(*pClassList, sal_Unicode(' '), nPos, nLen);
93*9d56236fSArmin Le Grand 
940906e779SArmin Le Grand                         while(nPos < nLen)
950906e779SArmin Le Grand                         {
960906e779SArmin Le Grand                             rtl::OUStringBuffer aTokenValue;
97*9d56236fSArmin Le Grand 
980906e779SArmin Le Grand                             copyToLimiter(*pClassList, sal_Unicode(' '), nPos, aTokenValue, nLen);
990906e779SArmin Le Grand                             skip_char(*pClassList, sal_Unicode(' '), nPos, nLen);
10050b37974SArmin Le Grand 
1010906e779SArmin Le Grand                             rtl::OUString aId(rtl::OUString::createFromAscii("."));
1020906e779SArmin Le Grand                             const rtl::OUString aOUTokenValue(aTokenValue.makeStringAndClear());
103*9d56236fSArmin Le Grand 
1040906e779SArmin Le Grand                             // look for CSS style common to token
1050906e779SArmin Le Grand                             aId = aId + aOUTokenValue;
1060906e779SArmin Le Grand                             pNew = rDocument.findSvgStyleAttributesById(aId);
107*9d56236fSArmin Le Grand 
1080906e779SArmin Le Grand                             if(!pNew && rClassStr.getLength())
1090906e779SArmin Le Grand                             {
1100906e779SArmin Le Grand                                 // look for CSS style common to class.token
1110906e779SArmin Le Grand                                 aId = rClassStr + aId;
112*9d56236fSArmin Le Grand 
1130906e779SArmin Le Grand                                 pNew = rDocument.findSvgStyleAttributesById(aId);
1140906e779SArmin Le Grand                             }
115*9d56236fSArmin Le Grand 
1160906e779SArmin Le Grand                             if(pNew)
1170906e779SArmin Le Grand                             {
1180906e779SArmin Le Grand                                 const_cast< SvgNode* >(this)->maCssStyleVector.push_back(pNew);
1190906e779SArmin Le Grand                             }
1200906e779SArmin Le Grand                         }
1210906e779SArmin Le Grand                     }
12250b37974SArmin Le Grand 
123*9d56236fSArmin Le Grand                     // check for class-dependent references to CssStyles
124*9d56236fSArmin Le Grand                     if(rClassStr.getLength())
12550b37974SArmin Le Grand                     {
126*9d56236fSArmin Le Grand                         // search for CSS style equal to class type
1270906e779SArmin Le Grand                         const SvgStyleAttributes* pNew = rDocument.findSvgStyleAttributesById(rClassStr);
128*9d56236fSArmin Le Grand 
1290906e779SArmin Le Grand                         if(pNew)
1300906e779SArmin Le Grand                         {
1310906e779SArmin Le Grand                             const_cast< SvgNode* >(this)->maCssStyleVector.push_back(pNew);
1320906e779SArmin Le Grand                         }
13350b37974SArmin Le Grand                     }
13450b37974SArmin Le Grand                 }
13550b37974SArmin Le Grand             }
13650b37974SArmin Le Grand 
137*9d56236fSArmin Le Grand             if(maCssStyleVector.empty())
138*9d56236fSArmin Le Grand             {
139*9d56236fSArmin Le Grand                 // return original if no CssStlyes found
140*9d56236fSArmin Le Grand                 return &rOriginal;
141*9d56236fSArmin Le Grand             }
142*9d56236fSArmin Le Grand             else
14350b37974SArmin Le Grand             {
144*9d56236fSArmin Le Grand                 // #125293# rOriginal will be the last element in the linked list; use no CssStyleParent
145*9d56236fSArmin Le Grand                 // there (reset it) to ensure that the parent hierarchy will be used when it's base
146*9d56236fSArmin Le Grand                 // is referenced. This new chaning inserts the CssStyles before the original style,
147*9d56236fSArmin Le Grand                 // this makes the whole process much safer since the original style when used will
148*9d56236fSArmin Le Grand                 // be not different to the situation without CssStyles; thus loops which may be caused
149*9d56236fSArmin Le Grand                 // by trying to use the parent hierarchy of the owner of the style will be avoided
150*9d56236fSArmin Le Grand                 // already in this mechanism. It's still good to keep the supportsParentStyle
151*9d56236fSArmin Le Grand                 // from #125258# in place, though.
152*9d56236fSArmin Le Grand                 // This chain building using pointers will be done every time when checkForCssStyle
153*9d56236fSArmin Le Grand                 // is used (not the search, only the chaining). This is needed since the CssStyles
154*9d56236fSArmin Le Grand                 // themselves will be potentially used multiple times. It is not expensive since it's
155*9d56236fSArmin Le Grand                 // only changing some pointers.
156*9d56236fSArmin Le Grand                 // The alternative would be to create the style hierarchy for every element (or even
157*9d56236fSArmin Le Grand                 // for the element containing the hierarchy) in a vector of pointers and to use that.
158*9d56236fSArmin Le Grand                 // Resetting the CssStyleParent on rOriginal is probably not needeed
159*9d56236fSArmin Le Grand                 // but simply safer to do.
160*9d56236fSArmin Le Grand                 const_cast< SvgStyleAttributes& >(rOriginal).setCssStyleParent(0);
161*9d56236fSArmin Le Grand 
162*9d56236fSArmin Le Grand                 // loop over the existing CssStyles and link them. There is a first one, take
163*9d56236fSArmin Le Grand                 // as current
164*9d56236fSArmin Le Grand                 SvgStyleAttributes* pCurrent = const_cast< SvgStyleAttributes* >(maCssStyleVector[0]);
165*9d56236fSArmin Le Grand 
166*9d56236fSArmin Le Grand                 for(sal_uInt32 a(1); a < maCssStyleVector.size(); a++)
16750b37974SArmin Le Grand                 {
1687b027e49SArmin Le Grand                     SvgStyleAttributes* pNext = const_cast< SvgStyleAttributes* >(maCssStyleVector[a]);
16950b37974SArmin Le Grand 
1707b027e49SArmin Le Grand                     pCurrent->setCssStyleParent(pNext);
1717b027e49SArmin Le Grand                     pCurrent = pNext;
17250b37974SArmin Le Grand                 }
1737b027e49SArmin Le Grand 
174*9d56236fSArmin Le Grand                 // pCurrent is the last used CssStyle, let it point to the original style
175*9d56236fSArmin Le Grand                 pCurrent->setCssStyleParent(&rOriginal);
176*9d56236fSArmin Le Grand 
177*9d56236fSArmin Le Grand                 // return 1st CssStyle as style chain start element (only for the
178*9d56236fSArmin Le Grand                 // local element, still no hierarchy used here)
179*9d56236fSArmin Le Grand                 return maCssStyleVector[0];
180*9d56236fSArmin Le Grand             }
18150b37974SArmin Le Grand         }
18250b37974SArmin Le Grand 
183ddde725dSArmin Le Grand         SvgNode::SvgNode(
184ddde725dSArmin Le Grand             SVGToken aType,
185ddde725dSArmin Le Grand             SvgDocument& rDocument,
186ddde725dSArmin Le Grand             SvgNode* pParent)
187ddde725dSArmin Le Grand         :   maType(aType),
188ddde725dSArmin Le Grand             mrDocument(rDocument),
189ddde725dSArmin Le Grand             mpParent(pParent),
190ddde725dSArmin Le Grand             mpAlternativeParent(0),
191ddde725dSArmin Le Grand             maChildren(),
192ddde725dSArmin Le Grand             mpId(0),
193ddde725dSArmin Le Grand             mpClass(0),
19450b37974SArmin Le Grand             maXmlSpace(XmlSpace_notset),
195a275c134SArmin Le Grand             maDisplay(Display_inline),
19650b37974SArmin Le Grand             maCssStyleVector()
197ddde725dSArmin Le Grand         {
198ddde725dSArmin Le Grand             OSL_ENSURE(SVGTokenUnknown != maType, "SvgNode with unknown type created (!)");
199ddde725dSArmin Le Grand 
200ddde725dSArmin Le Grand             if(pParent)
201ddde725dSArmin Le Grand             {
202ddde725dSArmin Le Grand                 pParent->maChildren.push_back(this);
203ddde725dSArmin Le Grand             }
204ddde725dSArmin Le Grand             else
205ddde725dSArmin Le Grand             {
206ddde725dSArmin Le Grand #ifdef DBG_UTIL
207ddde725dSArmin Le Grand                 if(SVGTokenSvg != getType())
208ddde725dSArmin Le Grand                 {
209ddde725dSArmin Le Grand                     OSL_ENSURE(false, "No parent for this node (!)");
210ddde725dSArmin Le Grand                 }
211ddde725dSArmin Le Grand #endif
212ddde725dSArmin Le Grand             }
213ddde725dSArmin Le Grand         }
214ddde725dSArmin Le Grand 
215ddde725dSArmin Le Grand         SvgNode::~SvgNode()
216ddde725dSArmin Le Grand         {
217ddde725dSArmin Le Grand             while(maChildren.size())
218ddde725dSArmin Le Grand             {
219ddde725dSArmin Le Grand                 delete maChildren[maChildren.size() - 1];
220ddde725dSArmin Le Grand                 maChildren.pop_back();
221ddde725dSArmin Le Grand             }
222ddde725dSArmin Le Grand 
223ddde725dSArmin Le Grand             if(mpId) delete mpId;
224ddde725dSArmin Le Grand             if(mpClass) delete mpClass;
225ddde725dSArmin Le Grand         }
226ddde725dSArmin Le Grand 
227ddde725dSArmin Le Grand         void SvgNode::parseAttributes(const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttribs)
228ddde725dSArmin Le Grand         {
229ddde725dSArmin Le Grand             const sal_uInt32 nAttributes(xAttribs->getLength());
230175cd092SArmin Le Grand             // #122522# SVG defines that 'In general, this means that the presentation attributes have
231175cd092SArmin Le Grand             // lower priority than other CSS style rules specified in author style sheets or �style�
232175cd092SArmin Le Grand             // attributes.' in http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes
233175cd092SArmin Le Grand             // (6.4 Specifying properties using the presentation attributes SVG 1.1). That means that
234175cd092SArmin Le Grand             // e.g. font-size will appear as presentation attribute and CSS style attribute. In these
235175cd092SArmin Le Grand             // cases, CSS style attributes need to have precedence. To do so it is possible to create
236175cd092SArmin Le Grand             // a proirity system for all properties of a shape, but it will also work to parse the
237175cd092SArmin Le Grand             // presentation attributes of type 'style' last, so they will overwrite the less-prioritized
238175cd092SArmin Le Grand             // already interpreted ones. Thus, remember SVGTokenStyle entries and parse them last.
239175cd092SArmin Le Grand             // To make this work it is required that parseAttribute is only called by parseAttributes
240175cd092SArmin Le Grand             // which is the case.
241175cd092SArmin Le Grand             std::vector< sal_uInt32 > aSVGTokenStyleIndexes;
242175cd092SArmin Le Grand 
243ddde725dSArmin Le Grand             for(sal_uInt32 a(0); a < nAttributes; a++)
244ddde725dSArmin Le Grand             {
245ddde725dSArmin Le Grand                 const ::rtl::OUString aTokenName(xAttribs->getNameByIndex(a));
246175cd092SArmin Le Grand                 const SVGToken aSVGToken(StrToSVGToken(aTokenName));
247175cd092SArmin Le Grand 
248175cd092SArmin Le Grand                 if(SVGTokenStyle == aSVGToken)
249175cd092SArmin Le Grand                 {
250175cd092SArmin Le Grand                     // #122522# remember SVGTokenStyle entry
251175cd092SArmin Le Grand                     aSVGTokenStyleIndexes.push_back(a);
252175cd092SArmin Le Grand                 }
253175cd092SArmin Le Grand                 else
254175cd092SArmin Le Grand                 {
25586d02030SArmin Le Grand                     parseAttribute(aTokenName, aSVGToken, xAttribs->getValueByIndex(a));
256175cd092SArmin Le Grand                 }
257175cd092SArmin Le Grand             }
258175cd092SArmin Le Grand 
259175cd092SArmin Le Grand             // #122522# parse SVGTokenStyle entries last to override already interpreted
260175cd092SArmin Le Grand             // 'presentation attributes' of potenially the same type
261175cd092SArmin Le Grand             for(sal_uInt32 b(0); b < aSVGTokenStyleIndexes.size(); b++)
262175cd092SArmin Le Grand             {
263175cd092SArmin Le Grand                 const sal_uInt32 nSVGTokenStyleIndex(aSVGTokenStyleIndexes[b]);
264175cd092SArmin Le Grand                 const ::rtl::OUString aTokenName(xAttribs->getNameByIndex(nSVGTokenStyleIndex));
265175cd092SArmin Le Grand 
266175cd092SArmin Le Grand                 parseAttribute(aTokenName, SVGTokenStyle, xAttribs->getValueByIndex(nSVGTokenStyleIndex));
267ddde725dSArmin Le Grand             }
268ddde725dSArmin Le Grand         }
269ddde725dSArmin Le Grand 
27001e92ad6SArmin Le Grand         Display getDisplayFromContent(const rtl::OUString& aContent)
27101e92ad6SArmin Le Grand         {
27201e92ad6SArmin Le Grand             if(aContent.getLength())
27301e92ad6SArmin Le Grand             {
274e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrInline(rtl::OUString::createFromAscii("inline"));
275e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrBlock(rtl::OUString::createFromAscii("block"));
276e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrList_item(rtl::OUString::createFromAscii("list-item"));
277e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrRun_in(rtl::OUString::createFromAscii("run-in"));
278e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrCompact(rtl::OUString::createFromAscii("compact"));
279e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrMarker(rtl::OUString::createFromAscii("marker"));
280e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable(rtl::OUString::createFromAscii("table"));
281e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrInline_table(rtl::OUString::createFromAscii("inline-table"));
282e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable_row_group(rtl::OUString::createFromAscii("table-row-group"));
283e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable_header_group(rtl::OUString::createFromAscii("table-header-group"));
284e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable_footer_group(rtl::OUString::createFromAscii("table-footer-group"));
285e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable_row(rtl::OUString::createFromAscii("table-row"));
286e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable_column_group(rtl::OUString::createFromAscii("table-column-group"));
287e92bb418SOliver-Rainer Wittmann                 static rtl::OUString aStrTable_column(rtl::OUString::createFromAscii("table-column"));
28801e92ad6SArmin Le Grand                 static rtl::OUString aStrTable_cell(rtl::OUString::createFromAscii("table-cell"));
28901e92ad6SArmin Le Grand                 static rtl::OUString aStrTable_caption(rtl::OUString::createFromAscii("table-caption"));
29001e92ad6SArmin Le Grand                 static rtl::OUString aStrNone(rtl::OUString::createFromAscii("none"));
29101e92ad6SArmin Le Grand                 static rtl::OUString aStrInherit(rtl::OUString::createFromAscii("inherit"));
29201e92ad6SArmin Le Grand 
29301e92ad6SArmin Le Grand                 if(aContent.match(aStrInline))
29401e92ad6SArmin Le Grand                 {
29501e92ad6SArmin Le Grand                     return Display_inline;
29601e92ad6SArmin Le Grand                 }
29701e92ad6SArmin Le Grand                 else if(aContent.match(aStrNone))
29801e92ad6SArmin Le Grand                 {
29901e92ad6SArmin Le Grand                     return Display_none;
30001e92ad6SArmin Le Grand                 }
30101e92ad6SArmin Le Grand                 else if(aContent.match(aStrInherit))
30201e92ad6SArmin Le Grand                 {
30301e92ad6SArmin Le Grand                     return Display_inherit;
30401e92ad6SArmin Le Grand                 }
305e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrBlock))
30601e92ad6SArmin Le Grand                 {
30701e92ad6SArmin Le Grand                     return Display_block;
30801e92ad6SArmin Le Grand                 }
309e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrList_item))
31001e92ad6SArmin Le Grand                 {
31101e92ad6SArmin Le Grand                     return Display_list_item;
31201e92ad6SArmin Le Grand                 }
313e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrRun_in))
31401e92ad6SArmin Le Grand                 {
31501e92ad6SArmin Le Grand                     return Display_run_in;
31601e92ad6SArmin Le Grand                 }
317e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrCompact))
31801e92ad6SArmin Le Grand                 {
31901e92ad6SArmin Le Grand                     return Display_compact;
32001e92ad6SArmin Le Grand                 }
321e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrMarker))
32201e92ad6SArmin Le Grand                 {
32301e92ad6SArmin Le Grand                     return Display_marker;
32401e92ad6SArmin Le Grand                 }
325e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable))
32601e92ad6SArmin Le Grand                 {
32701e92ad6SArmin Le Grand                     return Display_table;
32801e92ad6SArmin Le Grand                 }
329e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrInline_table))
33001e92ad6SArmin Le Grand                 {
33101e92ad6SArmin Le Grand                     return Display_inline_table;
33201e92ad6SArmin Le Grand                 }
333e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable_row_group))
33401e92ad6SArmin Le Grand                 {
33501e92ad6SArmin Le Grand                     return Display_table_row_group;
33601e92ad6SArmin Le Grand                 }
337e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable_header_group))
33801e92ad6SArmin Le Grand                 {
33901e92ad6SArmin Le Grand                     return Display_table_header_group;
34001e92ad6SArmin Le Grand                 }
341e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable_footer_group))
34201e92ad6SArmin Le Grand                 {
34301e92ad6SArmin Le Grand                     return Display_table_footer_group;
34401e92ad6SArmin Le Grand                 }
345e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable_row))
34601e92ad6SArmin Le Grand                 {
34701e92ad6SArmin Le Grand                     return Display_table_row;
34801e92ad6SArmin Le Grand                 }
349e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable_column_group))
35001e92ad6SArmin Le Grand                 {
35101e92ad6SArmin Le Grand                     return Display_table_column_group;
35201e92ad6SArmin Le Grand                 }
353e92bb418SOliver-Rainer Wittmann                 else if(aContent.match(aStrTable_column))
35401e92ad6SArmin Le Grand                 {
35501e92ad6SArmin Le Grand                     return Display_table_column;
35601e92ad6SArmin Le Grand                 }
35701e92ad6SArmin Le Grand                 else if(aContent.match(aStrTable_cell))
35801e92ad6SArmin Le Grand                 {
35901e92ad6SArmin Le Grand                     return Display_table_cell;
36001e92ad6SArmin Le Grand                 }
36101e92ad6SArmin Le Grand                 else if(aContent.match(aStrTable_caption))
36201e92ad6SArmin Le Grand                 {
36301e92ad6SArmin Le Grand                     return Display_table_caption;
36401e92ad6SArmin Le Grand                 }
36501e92ad6SArmin Le Grand             }
36601e92ad6SArmin Le Grand 
36701e92ad6SArmin Le Grand             // return the default
36801e92ad6SArmin Le Grand             return Display_inline;
36901e92ad6SArmin Le Grand         }
37001e92ad6SArmin Le Grand 
371e2bf1e9dSArmin Le Grand         void SvgNode::parseAttribute(const rtl::OUString& /*rTokenName*/, SVGToken aSVGToken, const rtl::OUString& aContent)
372ddde725dSArmin Le Grand         {
373ddde725dSArmin Le Grand             switch(aSVGToken)
374ddde725dSArmin Le Grand             {
375ddde725dSArmin Le Grand                 case SVGTokenId:
376ddde725dSArmin Le Grand                 {
377ddde725dSArmin Le Grand                     if(aContent.getLength())
378ddde725dSArmin Le Grand                     {
379ddde725dSArmin Le Grand                         setId(&aContent);
380ddde725dSArmin Le Grand                     }
381ddde725dSArmin Le Grand                     break;
382ddde725dSArmin Le Grand                 }
383ddde725dSArmin Le Grand                 case SVGTokenClass:
384ddde725dSArmin Le Grand                 {
385ddde725dSArmin Le Grand                     if(aContent.getLength())
386ddde725dSArmin Le Grand                     {
387ddde725dSArmin Le Grand                         setClass(&aContent);
388ddde725dSArmin Le Grand                     }
389ddde725dSArmin Le Grand                     break;
390ddde725dSArmin Le Grand                 }
391ddde725dSArmin Le Grand                 case SVGTokenXmlSpace:
392ddde725dSArmin Le Grand                 {
393ddde725dSArmin Le Grand                     if(aContent.getLength())
394ddde725dSArmin Le Grand                     {
395ddde725dSArmin Le Grand                         static rtl::OUString aStrDefault(rtl::OUString::createFromAscii("default"));
396ddde725dSArmin Le Grand                         static rtl::OUString aStrPreserve(rtl::OUString::createFromAscii("preserve"));
397ddde725dSArmin Le Grand 
398ddde725dSArmin Le Grand                         if(aContent.match(aStrDefault))
399ddde725dSArmin Le Grand                         {
400ddde725dSArmin Le Grand                             setXmlSpace(XmlSpace_default);
401ddde725dSArmin Le Grand                         }
402ddde725dSArmin Le Grand                         else if(aContent.match(aStrPreserve))
403ddde725dSArmin Le Grand                         {
404ddde725dSArmin Le Grand                             setXmlSpace(XmlSpace_preserve);
405ddde725dSArmin Le Grand                         }
406ddde725dSArmin Le Grand                     }
407ddde725dSArmin Le Grand                     break;
408ddde725dSArmin Le Grand                 }
409a275c134SArmin Le Grand                 case SVGTokenDisplay:
410a275c134SArmin Le Grand                 {
411a275c134SArmin Le Grand                     if(aContent.getLength())
412a275c134SArmin Le Grand                     {
41301e92ad6SArmin Le Grand                         setDisplay(getDisplayFromContent(aContent));
414a275c134SArmin Le Grand                     }
415a275c134SArmin Le Grand                     break;
416a275c134SArmin Le Grand                 }
417e2bf1e9dSArmin Le Grand                 default:
418e2bf1e9dSArmin Le Grand                 {
419e2bf1e9dSArmin Le Grand                     break;
420e2bf1e9dSArmin Le Grand                 }
421ddde725dSArmin Le Grand             }
422ddde725dSArmin Le Grand         }
423ddde725dSArmin Le Grand 
424ddde725dSArmin Le Grand         void SvgNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const
425ddde725dSArmin Le Grand         {
426a275c134SArmin Le Grand             if(Display_none == getDisplay())
427a275c134SArmin Le Grand             {
428a275c134SArmin Le Grand                 return;
429a275c134SArmin Le Grand             }
430a275c134SArmin Le Grand 
431ddde725dSArmin Le Grand             if(!bReferenced)
432ddde725dSArmin Le Grand             {
433ddde725dSArmin Le Grand                 if(SVGTokenDefs == getType() ||
434ddde725dSArmin Le Grand                     SVGTokenSymbol == getType() ||
435ddde725dSArmin Le Grand                     SVGTokenClipPathNode == getType() ||
436ddde725dSArmin Le Grand                     SVGTokenMask == getType() ||
437ddde725dSArmin Le Grand                     SVGTokenMarker == getType() ||
438ddde725dSArmin Le Grand                     SVGTokenPattern == getType())
439ddde725dSArmin Le Grand                 {
440ddde725dSArmin Le Grand                     // do not decompose defs or symbol nodes (these hold only style-like
441ddde725dSArmin Le Grand                     // objects which may be used by referencing them) except when doing
442ddde725dSArmin Le Grand                     // so controlled referenced
443ddde725dSArmin Le Grand 
444ddde725dSArmin Le Grand                     // also do not decompose ClipPaths and Masks. These should be embedded
445ddde725dSArmin Le Grand                     // in a defs node (which gets not decomposed by itself), but you never
446ddde725dSArmin Le Grand                     // know
447ddde725dSArmin Le Grand 
448ddde725dSArmin Le Grand                     // also not directly used are Markers and Patterns, only indirecty used
449ddde725dSArmin Le Grand                     // by reference
450a275c134SArmin Le Grand 
451a275c134SArmin Le Grand                     // #121656# also do not decompose nodes which have display="none" set
452a275c134SArmin Le Grand                     // as property
453ddde725dSArmin Le Grand                     return;
454ddde725dSArmin Le Grand                 }
455ddde725dSArmin Le Grand             }
456ddde725dSArmin Le Grand 
457ddde725dSArmin Le Grand             const SvgNodeVector& rChildren = getChildren();
458ddde725dSArmin Le Grand 
459ddde725dSArmin Le Grand             if(!rChildren.empty())
460ddde725dSArmin Le Grand             {
461ddde725dSArmin Le Grand                 const sal_uInt32 nCount(rChildren.size());
462ddde725dSArmin Le Grand 
463ddde725dSArmin Le Grand                 for(sal_uInt32 a(0); a < nCount; a++)
464ddde725dSArmin Le Grand                 {
465ddde725dSArmin Le Grand                     SvgNode* pCandidate = rChildren[a];
466ddde725dSArmin Le Grand 
467a275c134SArmin Le Grand                     if(pCandidate && Display_none != pCandidate->getDisplay())
468ddde725dSArmin Le Grand                     {
469ddde725dSArmin Le Grand                         drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
470ddde725dSArmin Le Grand 
471ddde725dSArmin Le Grand                         pCandidate->decomposeSvgNode(aNewTarget, bReferenced);
472ddde725dSArmin Le Grand 
473ddde725dSArmin Le Grand                         if(aNewTarget.hasElements())
474ddde725dSArmin Le Grand                         {
475ddde725dSArmin Le Grand                             drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aNewTarget);
476ddde725dSArmin Le Grand                         }
477ddde725dSArmin Le Grand                     }
478ddde725dSArmin Le Grand                     else
479ddde725dSArmin Le Grand                     {
480ddde725dSArmin Le Grand                         OSL_ENSURE(false, "Null-Pointer in child node list (!)");
481ddde725dSArmin Le Grand                     }
482ddde725dSArmin Le Grand                 }
483025b0597SArmin Le Grand 
484025b0597SArmin Le Grand                 if(rTarget.hasElements())
485025b0597SArmin Le Grand                 {
486025b0597SArmin Le Grand                     const SvgStyleAttributes* pStyles = getSvgStyleAttributes();
487025b0597SArmin Le Grand 
488025b0597SArmin Le Grand                     if(pStyles)
489025b0597SArmin Le Grand                     {
490025b0597SArmin Le Grand                         // check if we have Title or Desc
491025b0597SArmin Le Grand                         const rtl::OUString& rTitle = pStyles->getTitle();
492025b0597SArmin Le Grand                         const rtl::OUString& rDesc = pStyles->getDesc();
493025b0597SArmin Le Grand 
494025b0597SArmin Le Grand                         if(rTitle.getLength() || rDesc.getLength())
495025b0597SArmin Le Grand                         {
496025b0597SArmin Le Grand                             // default object name is empty
497025b0597SArmin Le Grand                             rtl::OUString aObjectName;
498025b0597SArmin Le Grand 
499025b0597SArmin Le Grand                             // use path as object name when outmost element
500025b0597SArmin Le Grand                             if(SVGTokenSvg == getType())
501025b0597SArmin Le Grand                             {
502025b0597SArmin Le Grand                                 aObjectName = getDocument().getAbsolutePath();
503172c67b2SArmin Le Grand 
504172c67b2SArmin Le Grand                                 if(aObjectName.getLength())
505172c67b2SArmin Le Grand                                 {
506172c67b2SArmin Le Grand                             		INetURLObject aURL(aObjectName);
507172c67b2SArmin Le Grand 
508172c67b2SArmin Le Grand                                     aObjectName = aURL.getName(
509172c67b2SArmin Le Grand                                         INetURLObject::LAST_SEGMENT,
510172c67b2SArmin Le Grand                                         true,
511172c67b2SArmin Le Grand                                         INetURLObject::DECODE_WITH_CHARSET);
512172c67b2SArmin Le Grand                                 }
513025b0597SArmin Le Grand                             }
514025b0597SArmin Le Grand 
515025b0597SArmin Le Grand                             // pack in ObjectInfoPrimitive2D group
516025b0597SArmin Le Grand                             const drawinglayer::primitive2d::Primitive2DReference xRef(
517025b0597SArmin Le Grand                                 new drawinglayer::primitive2d::ObjectInfoPrimitive2D(
518025b0597SArmin Le Grand                                     rTarget,
519025b0597SArmin Le Grand                                     aObjectName,
520025b0597SArmin Le Grand                                     rTitle,
521025b0597SArmin Le Grand                                     rDesc));
522025b0597SArmin Le Grand 
523025b0597SArmin Le Grand                             rTarget = drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1);
524025b0597SArmin Le Grand                         }
525025b0597SArmin Le Grand                     }
526025b0597SArmin Le Grand                 }
527ddde725dSArmin Le Grand             }
528ddde725dSArmin Le Grand         }
529ddde725dSArmin Le Grand 
530e92bb418SOliver-Rainer Wittmann         const basegfx::B2DRange SvgNode::getCurrentViewPort() const
531ddde725dSArmin Le Grand         {
532ddde725dSArmin Le Grand             if(getParent())
533ddde725dSArmin Le Grand             {
534ddde725dSArmin Le Grand                 return getParent()->getCurrentViewPort();
535ddde725dSArmin Le Grand             }
536ddde725dSArmin Le Grand             else
537ddde725dSArmin Le Grand             {
538e92bb418SOliver-Rainer Wittmann                 return basegfx::B2DRange(); // return empty B2DRange
539ddde725dSArmin Le Grand             }
540ddde725dSArmin Le Grand         }
541ddde725dSArmin Le Grand 
542ddde725dSArmin Le Grand         double SvgNode::getCurrentFontSize() const
543ddde725dSArmin Le Grand         {
544ddde725dSArmin Le Grand             if(getSvgStyleAttributes())
545ddde725dSArmin Le Grand             {
546ddde725dSArmin Le Grand                 return getSvgStyleAttributes()->getFontSize().solve(*this, xcoordinate);
547ddde725dSArmin Le Grand             }
548ddde725dSArmin Le Grand             else if(getParent())
549ddde725dSArmin Le Grand             {
550ddde725dSArmin Le Grand                 return getParent()->getCurrentFontSize();
551ddde725dSArmin Le Grand             }
552ddde725dSArmin Le Grand             else
553ddde725dSArmin Le Grand             {
554ddde725dSArmin Le Grand                 return 0.0;
555ddde725dSArmin Le Grand             }
556ddde725dSArmin Le Grand         }
557ddde725dSArmin Le Grand 
558ddde725dSArmin Le Grand         double SvgNode::getCurrentXHeight() const
559ddde725dSArmin Le Grand         {
560ddde725dSArmin Le Grand             if(getSvgStyleAttributes())
561ddde725dSArmin Le Grand             {
562ddde725dSArmin Le Grand                 // for XHeight, use FontSize currently
563ddde725dSArmin Le Grand                 return getSvgStyleAttributes()->getFontSize().solve(*this, ycoordinate);
564ddde725dSArmin Le Grand             }
565ddde725dSArmin Le Grand             else if(getParent())
566ddde725dSArmin Le Grand             {
567ddde725dSArmin Le Grand                 return getParent()->getCurrentXHeight();
568ddde725dSArmin Le Grand             }
569ddde725dSArmin Le Grand             else
570ddde725dSArmin Le Grand             {
571ddde725dSArmin Le Grand                 return 0.0;
572ddde725dSArmin Le Grand             }
573ddde725dSArmin Le Grand         }
574ddde725dSArmin Le Grand 
575ddde725dSArmin Le Grand         void SvgNode::setId(const rtl::OUString* pfId)
576ddde725dSArmin Le Grand         {
577ddde725dSArmin Le Grand             if(mpId)
578ddde725dSArmin Le Grand             {
579ddde725dSArmin Le Grand                 mrDocument.removeSvgNodeFromMapper(*mpId);
580ddde725dSArmin Le Grand                 delete mpId;
581ddde725dSArmin Le Grand                 mpId = 0;
582ddde725dSArmin Le Grand             }
583ddde725dSArmin Le Grand 
584ddde725dSArmin Le Grand             if(pfId)
585ddde725dSArmin Le Grand             {
586ddde725dSArmin Le Grand                 mpId = new rtl::OUString(*pfId);
587ddde725dSArmin Le Grand                 mrDocument.addSvgNodeToMapper(*mpId, *this);
588ddde725dSArmin Le Grand             }
589ddde725dSArmin Le Grand         }
590ddde725dSArmin Le Grand 
591ddde725dSArmin Le Grand         void SvgNode::setClass(const rtl::OUString* pfClass)
592ddde725dSArmin Le Grand         {
593ddde725dSArmin Le Grand             if(mpClass)
594ddde725dSArmin Le Grand             {
595ddde725dSArmin Le Grand                 mrDocument.removeSvgNodeFromMapper(*mpClass);
596ddde725dSArmin Le Grand                 delete mpClass;
597ddde725dSArmin Le Grand                 mpClass = 0;
598ddde725dSArmin Le Grand             }
599ddde725dSArmin Le Grand 
600ddde725dSArmin Le Grand             if(pfClass)
601ddde725dSArmin Le Grand             {
602ddde725dSArmin Le Grand                 mpClass = new rtl::OUString(*pfClass);
603ddde725dSArmin Le Grand                 mrDocument.addSvgNodeToMapper(*mpClass, *this);
604ddde725dSArmin Le Grand             }
605ddde725dSArmin Le Grand         }
606ddde725dSArmin Le Grand 
607ddde725dSArmin Le Grand         XmlSpace SvgNode::getXmlSpace() const
608ddde725dSArmin Le Grand         {
609ddde725dSArmin Le Grand             if(maXmlSpace != XmlSpace_notset)
610ddde725dSArmin Le Grand             {
611ddde725dSArmin Le Grand                 return maXmlSpace;
612ddde725dSArmin Le Grand             }
613ddde725dSArmin Le Grand 
614ddde725dSArmin Le Grand             if(getParent())
615ddde725dSArmin Le Grand             {
616ddde725dSArmin Le Grand                 return getParent()->getXmlSpace();
617ddde725dSArmin Le Grand             }
618ddde725dSArmin Le Grand 
619ddde725dSArmin Le Grand             // default is XmlSpace_default
620ddde725dSArmin Le Grand             return XmlSpace_default;
621ddde725dSArmin Le Grand         }
622ddde725dSArmin Le Grand 
623ddde725dSArmin Le Grand     } // end of namespace svgreader
624ddde725dSArmin Le Grand } // end of namespace svgio
625ddde725dSArmin Le Grand 
626ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
627ddde725dSArmin Le Grand // eof
628