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