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