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