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/svgdocumenthandler.hxx> 26ddde725dSArmin Le Grand #include <svgio/svgreader/svgtoken.hxx> 27ddde725dSArmin Le Grand #include <svgio/svgreader/svgsvgnode.hxx> 28ddde725dSArmin Le Grand #include <svgio/svgreader/svggnode.hxx> 29ddde725dSArmin Le Grand #include <svgio/svgreader/svgnode.hxx> 30ddde725dSArmin Le Grand #include <svgio/svgreader/svgpathnode.hxx> 31ddde725dSArmin Le Grand #include <svgio/svgreader/svgrectnode.hxx> 32ddde725dSArmin Le Grand #include <svgio/svgreader/svggradientnode.hxx> 33ddde725dSArmin Le Grand #include <svgio/svgreader/svggradientstopnode.hxx> 34ddde725dSArmin Le Grand #include <svgio/svgreader/svgsymbolnode.hxx> 35ddde725dSArmin Le Grand #include <svgio/svgreader/svgusenode.hxx> 36ddde725dSArmin Le Grand #include <svgio/svgreader/svgcirclenode.hxx> 37ddde725dSArmin Le Grand #include <svgio/svgreader/svgellipsenode.hxx> 38ddde725dSArmin Le Grand #include <svgio/svgreader/svglinenode.hxx> 39ddde725dSArmin Le Grand #include <svgio/svgreader/svgpolynode.hxx> 40ddde725dSArmin Le Grand #include <svgio/svgreader/svgsymbolnode.hxx> 41ddde725dSArmin Le Grand #include <svgio/svgreader/svgtextnode.hxx> 42ddde725dSArmin Le Grand #include <svgio/svgreader/svgcharacternode.hxx> 43ddde725dSArmin Le Grand #include <svgio/svgreader/svgtspannode.hxx> 44ddde725dSArmin Le Grand #include <svgio/svgreader/svgtrefnode.hxx> 45ddde725dSArmin Le Grand #include <svgio/svgreader/svgtextpathnode.hxx> 46ddde725dSArmin Le Grand #include <svgio/svgreader/svgstylenode.hxx> 47ddde725dSArmin Le Grand #include <svgio/svgreader/svgimagenode.hxx> 48ddde725dSArmin Le Grand #include <svgio/svgreader/svgclippathnode.hxx> 49ddde725dSArmin Le Grand #include <svgio/svgreader/svgmasknode.hxx> 50ddde725dSArmin Le Grand #include <svgio/svgreader/svgmarkernode.hxx> 51ddde725dSArmin Le Grand #include <svgio/svgreader/svgpatternnode.hxx> 52*025b0597SArmin Le Grand #include <svgio/svgreader/svgtitledescnode.hxx> 53ddde725dSArmin Le Grand 54ddde725dSArmin Le Grand ////////////////////////////////////////////////////////////////////////////// 55ddde725dSArmin Le Grand 56ddde725dSArmin Le Grand using namespace com::sun::star; 57ddde725dSArmin Le Grand 58ddde725dSArmin Le Grand ////////////////////////////////////////////////////////////////////////////// 59ddde725dSArmin Le Grand 60ddde725dSArmin Le Grand namespace 61ddde725dSArmin Le Grand { 62ddde725dSArmin Le Grand svgio::svgreader::SvgCharacterNode* whiteSpaceHandling(svgio::svgreader::SvgNode* pNode, svgio::svgreader::SvgCharacterNode* pLast) 63ddde725dSArmin Le Grand { 64ddde725dSArmin Le Grand if(pNode) 65ddde725dSArmin Le Grand { 66ddde725dSArmin Le Grand const svgio::svgreader::SvgNodeVector& rChilds = pNode->getChildren(); 67ddde725dSArmin Le Grand const sal_uInt32 nCount(rChilds.size()); 68ddde725dSArmin Le Grand 69ddde725dSArmin Le Grand for(sal_uInt32 a(0); a < nCount; a++) 70ddde725dSArmin Le Grand { 71ddde725dSArmin Le Grand svgio::svgreader::SvgNode* pCandidate = rChilds[a]; 72ddde725dSArmin Le Grand 73ddde725dSArmin Le Grand if(pCandidate) 74ddde725dSArmin Le Grand { 75ddde725dSArmin Le Grand switch(pCandidate->getType()) 76ddde725dSArmin Le Grand { 77ddde725dSArmin Le Grand case svgio::svgreader::SVGTokenCharacter: 78ddde725dSArmin Le Grand { 79ddde725dSArmin Le Grand // clean whitespace in text span 80ddde725dSArmin Le Grand svgio::svgreader::SvgCharacterNode* pCharNode = static_cast< svgio::svgreader::SvgCharacterNode* >(pCandidate); 81ddde725dSArmin Le Grand pCharNode->whiteSpaceHandling(); 82ddde725dSArmin Le Grand 83ddde725dSArmin Le Grand // pCharNode may have lost all text. If that's the case, ignore 84ddde725dSArmin Le Grand // as invalid character node 85ddde725dSArmin Le Grand if(pCharNode->getText().getLength()) 86ddde725dSArmin Le Grand { 87ddde725dSArmin Le Grand if(pLast) 88ddde725dSArmin Le Grand { 89ddde725dSArmin Le Grand // add in-between whitespace (single space) to last 90ddde725dSArmin Le Grand // known character node 91ddde725dSArmin Le Grand pLast->addGap(); 92ddde725dSArmin Le Grand } 93ddde725dSArmin Le Grand 94ddde725dSArmin Le Grand // remember new last corected character node 95ddde725dSArmin Le Grand pLast = pCharNode; 96ddde725dSArmin Le Grand } 97ddde725dSArmin Le Grand break; 98ddde725dSArmin Le Grand } 99ddde725dSArmin Le Grand case svgio::svgreader::SVGTokenTspan: 100ddde725dSArmin Le Grand case svgio::svgreader::SVGTokenTextPath: 101ddde725dSArmin Le Grand case svgio::svgreader::SVGTokenTref: 102ddde725dSArmin Le Grand { 103ddde725dSArmin Le Grand // recursively clean whitespaces in subhierarchy 104ddde725dSArmin Le Grand pLast = whiteSpaceHandling(pCandidate, pLast); 105ddde725dSArmin Le Grand break; 106ddde725dSArmin Le Grand } 107ddde725dSArmin Le Grand default: 108ddde725dSArmin Le Grand { 109ddde725dSArmin Le Grand OSL_ENSURE(false, "Unexpected token inside SVGTokenText (!)"); 110ddde725dSArmin Le Grand break; 111ddde725dSArmin Le Grand } 112ddde725dSArmin Le Grand } 113ddde725dSArmin Le Grand } 114ddde725dSArmin Le Grand } 115ddde725dSArmin Le Grand } 116ddde725dSArmin Le Grand 117ddde725dSArmin Le Grand return pLast; 118ddde725dSArmin Le Grand } 119ddde725dSArmin Le Grand } 120ddde725dSArmin Le Grand 121ddde725dSArmin Le Grand ////////////////////////////////////////////////////////////////////////////// 122ddde725dSArmin Le Grand 123ddde725dSArmin Le Grand namespace svgio 124ddde725dSArmin Le Grand { 125ddde725dSArmin Le Grand namespace svgreader 126ddde725dSArmin Le Grand { 127ddde725dSArmin Le Grand SvgDocHdl::SvgDocHdl(const rtl::OUString& aAbsolutePath) 128ddde725dSArmin Le Grand : maDocument(aAbsolutePath), 1293aaca8a3SArmin Le Grand mpTarget(0), 1303aaca8a3SArmin Le Grand maCssContents() 131ddde725dSArmin Le Grand { 132ddde725dSArmin Le Grand } 133ddde725dSArmin Le Grand 134ddde725dSArmin Le Grand SvgDocHdl::~SvgDocHdl() 135ddde725dSArmin Le Grand { 136ddde725dSArmin Le Grand #ifdef DBG_UTIL 137ddde725dSArmin Le Grand if(mpTarget) 138ddde725dSArmin Le Grand { 139ddde725dSArmin Le Grand OSL_ENSURE(false, "SvgDocHdl destructed with active target (!)"); 140ddde725dSArmin Le Grand delete mpTarget; 141ddde725dSArmin Le Grand } 1423aaca8a3SArmin Le Grand OSL_ENSURE(!maCssContents.size(), "SvgDocHdl destructed with active css style stack entry (!)"); 143ddde725dSArmin Le Grand #endif 144ddde725dSArmin Le Grand } 145ddde725dSArmin Le Grand 146ddde725dSArmin Le Grand void SvgDocHdl::startDocument( ) throw (xml::sax::SAXException, uno::RuntimeException) 147ddde725dSArmin Le Grand { 148ddde725dSArmin Le Grand OSL_ENSURE(!mpTarget, "Already a target at document start (!)"); 1493aaca8a3SArmin Le Grand OSL_ENSURE(!maCssContents.size(), "SvgDocHdl startDocument with active css style stack entry (!)"); 150ddde725dSArmin Le Grand } 151ddde725dSArmin Le Grand 152ddde725dSArmin Le Grand void SvgDocHdl::endDocument( ) throw (xml::sax::SAXException, uno::RuntimeException) 153ddde725dSArmin Le Grand { 154ddde725dSArmin Le Grand OSL_ENSURE(!mpTarget, "Still a target at document end (!)"); 1553aaca8a3SArmin Le Grand OSL_ENSURE(!maCssContents.size(), "SvgDocHdl endDocument with active css style stack entry (!)"); 156ddde725dSArmin Le Grand } 157ddde725dSArmin Le Grand 158ddde725dSArmin Le Grand void SvgDocHdl::startElement( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs ) throw (xml::sax::SAXException, uno::RuntimeException) 159ddde725dSArmin Le Grand { 160ddde725dSArmin Le Grand if(aName.getLength()) 161ddde725dSArmin Le Grand { 162ddde725dSArmin Le Grand const SVGToken aSVGToken(StrToSVGToken(aName)); 163ddde725dSArmin Le Grand 164ddde725dSArmin Le Grand switch(aSVGToken) 165ddde725dSArmin Le Grand { 166ddde725dSArmin Le Grand /// structural elements 167ddde725dSArmin Le Grand case SVGTokenSymbol: 168ddde725dSArmin Le Grand { 169ddde725dSArmin Le Grand /// new basic node for Symbol. Content gets scanned, but 170ddde725dSArmin Le Grand /// will not be decomposed (see SvgNode::decomposeSvgNode and bReferenced) 171ddde725dSArmin Le Grand mpTarget = new SvgSymbolNode(maDocument, mpTarget); 172ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 173ddde725dSArmin Le Grand break; 174ddde725dSArmin Le Grand } 175ddde725dSArmin Le Grand case SVGTokenDefs: 176ddde725dSArmin Le Grand case SVGTokenG: 177ddde725dSArmin Le Grand { 178ddde725dSArmin Le Grand /// new node for Defs/G 179ddde725dSArmin Le Grand mpTarget = new SvgGNode(aSVGToken, maDocument, mpTarget); 180ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 181ddde725dSArmin Le Grand break; 182ddde725dSArmin Le Grand } 183ddde725dSArmin Le Grand case SVGTokenSvg: 184ddde725dSArmin Le Grand { 185ddde725dSArmin Le Grand /// new node for Svg 186ddde725dSArmin Le Grand mpTarget = new SvgSvgNode(maDocument, mpTarget); 187ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 188ddde725dSArmin Le Grand break; 189ddde725dSArmin Le Grand } 190ddde725dSArmin Le Grand case SVGTokenUse: 191ddde725dSArmin Le Grand { 192ddde725dSArmin Le Grand /// new node for Use 193ddde725dSArmin Le Grand mpTarget = new SvgUseNode(maDocument, mpTarget); 194ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 195ddde725dSArmin Le Grand break; 196ddde725dSArmin Le Grand } 197ddde725dSArmin Le Grand 198ddde725dSArmin Le Grand /// shape elements 199ddde725dSArmin Le Grand case SVGTokenCircle: 200ddde725dSArmin Le Grand { 201ddde725dSArmin Le Grand /// new node for Circle 202ddde725dSArmin Le Grand mpTarget = new SvgCircleNode(maDocument, mpTarget); 203ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 204ddde725dSArmin Le Grand break; 205ddde725dSArmin Le Grand } 206ddde725dSArmin Le Grand case SVGTokenEllipse: 207ddde725dSArmin Le Grand { 208ddde725dSArmin Le Grand /// new node for Ellipse 209ddde725dSArmin Le Grand mpTarget = new SvgEllipseNode(maDocument, mpTarget); 210ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 211ddde725dSArmin Le Grand break; 212ddde725dSArmin Le Grand } 213ddde725dSArmin Le Grand case SVGTokenLine: 214ddde725dSArmin Le Grand { 215ddde725dSArmin Le Grand /// new node for Line 216ddde725dSArmin Le Grand mpTarget = new SvgLineNode(maDocument, mpTarget); 217ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 218ddde725dSArmin Le Grand break; 219ddde725dSArmin Le Grand } 220ddde725dSArmin Le Grand case SVGTokenPath: 221ddde725dSArmin Le Grand { 222ddde725dSArmin Le Grand /// new node for Path 223ddde725dSArmin Le Grand mpTarget = new SvgPathNode(maDocument, mpTarget); 224ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 225ddde725dSArmin Le Grand break; 226ddde725dSArmin Le Grand } 227ddde725dSArmin Le Grand case SVGTokenPolygon: 228ddde725dSArmin Le Grand { 229ddde725dSArmin Le Grand /// new node for Polygon 230ddde725dSArmin Le Grand mpTarget = new SvgPolyNode(maDocument, mpTarget, false); 231ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 232ddde725dSArmin Le Grand break; 233ddde725dSArmin Le Grand } 234ddde725dSArmin Le Grand case SVGTokenPolyline: 235ddde725dSArmin Le Grand { 236ddde725dSArmin Le Grand /// new node for Polyline 237ddde725dSArmin Le Grand mpTarget = new SvgPolyNode(maDocument, mpTarget, true); 238ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 239ddde725dSArmin Le Grand break; 240ddde725dSArmin Le Grand } 241ddde725dSArmin Le Grand case SVGTokenRect: 242ddde725dSArmin Le Grand { 243ddde725dSArmin Le Grand /// new node for Rect 244ddde725dSArmin Le Grand mpTarget = new SvgRectNode(maDocument, mpTarget); 245ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 246ddde725dSArmin Le Grand break; 247ddde725dSArmin Le Grand } 248ddde725dSArmin Le Grand case SVGTokenImage: 249ddde725dSArmin Le Grand { 250ddde725dSArmin Le Grand /// new node for Image 251ddde725dSArmin Le Grand mpTarget = new SvgImageNode(maDocument, mpTarget); 252ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 253ddde725dSArmin Le Grand break; 254ddde725dSArmin Le Grand } 255ddde725dSArmin Le Grand 256*025b0597SArmin Le Grand /// title and description 257*025b0597SArmin Le Grand case SVGTokenTitle: 258*025b0597SArmin Le Grand case SVGTokenDesc: 259*025b0597SArmin Le Grand { 260*025b0597SArmin Le Grand /// new node for Title and/or Desc 261*025b0597SArmin Le Grand mpTarget = new SvgTitleDescNode(aSVGToken, maDocument, mpTarget); 262*025b0597SArmin Le Grand break; 263*025b0597SArmin Le Grand } 264*025b0597SArmin Le Grand 265ddde725dSArmin Le Grand /// gradients 266ddde725dSArmin Le Grand case SVGTokenLinearGradient: 267ddde725dSArmin Le Grand case SVGTokenRadialGradient: 268ddde725dSArmin Le Grand { 269ddde725dSArmin Le Grand mpTarget = new SvgGradientNode(aSVGToken, maDocument, mpTarget); 270ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 271ddde725dSArmin Le Grand break; 272ddde725dSArmin Le Grand } 273ddde725dSArmin Le Grand 274ddde725dSArmin Le Grand /// gradient stops 275ddde725dSArmin Le Grand case SVGTokenStop: 276ddde725dSArmin Le Grand { 277ddde725dSArmin Le Grand mpTarget = new SvgGradientStopNode(maDocument, mpTarget); 278ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 279ddde725dSArmin Le Grand break; 280ddde725dSArmin Le Grand } 281ddde725dSArmin Le Grand 282ddde725dSArmin Le Grand /// text 283ddde725dSArmin Le Grand case SVGTokenText: 284ddde725dSArmin Le Grand { 285ddde725dSArmin Le Grand mpTarget = new SvgTextNode(maDocument, mpTarget); 286ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 287ddde725dSArmin Le Grand break; 288ddde725dSArmin Le Grand } 289ddde725dSArmin Le Grand case SVGTokenTspan: 290ddde725dSArmin Le Grand { 291ddde725dSArmin Le Grand mpTarget = new SvgTspanNode(maDocument, mpTarget); 292ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 293ddde725dSArmin Le Grand break; 294ddde725dSArmin Le Grand } 295ddde725dSArmin Le Grand case SVGTokenTref: 296ddde725dSArmin Le Grand { 297ddde725dSArmin Le Grand mpTarget = new SvgTrefNode(maDocument, mpTarget); 298ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 299ddde725dSArmin Le Grand break; 300ddde725dSArmin Le Grand } 301ddde725dSArmin Le Grand case SVGTokenTextPath: 302ddde725dSArmin Le Grand { 303ddde725dSArmin Le Grand mpTarget = new SvgTextPathNode(maDocument, mpTarget); 304ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 305ddde725dSArmin Le Grand break; 306ddde725dSArmin Le Grand } 307ddde725dSArmin Le Grand 308ddde725dSArmin Le Grand /// styles (as stylesheets) 309ddde725dSArmin Le Grand case SVGTokenStyle: 310ddde725dSArmin Le Grand { 3113aaca8a3SArmin Le Grand SvgStyleNode* pNew = new SvgStyleNode(maDocument, mpTarget); 3123aaca8a3SArmin Le Grand mpTarget = pNew; 313ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 3143aaca8a3SArmin Le Grand 3153aaca8a3SArmin Le Grand if(pNew->isTextCss()) 3163aaca8a3SArmin Le Grand { 3173aaca8a3SArmin Le Grand maCssContents.push_back(rtl::OUString()); 3183aaca8a3SArmin Le Grand } 319ddde725dSArmin Le Grand break; 320ddde725dSArmin Le Grand } 321ddde725dSArmin Le Grand 322ddde725dSArmin Le Grand /// structural elements clip-path and mask. Content gets scanned, but 323ddde725dSArmin Le Grand /// will not be decomposed (see SvgNode::decomposeSvgNode and bReferenced) 324ddde725dSArmin Le Grand case SVGTokenClipPathNode: 325ddde725dSArmin Le Grand { 326ddde725dSArmin Le Grand /// new node for ClipPath 327ddde725dSArmin Le Grand mpTarget = new SvgClipPathNode(maDocument, mpTarget); 328ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 329ddde725dSArmin Le Grand break; 330ddde725dSArmin Le Grand } 331ddde725dSArmin Le Grand case SVGTokenMask: 332ddde725dSArmin Le Grand { 333ddde725dSArmin Le Grand /// new node for Mask 334ddde725dSArmin Le Grand mpTarget = new SvgMaskNode(maDocument, mpTarget); 335ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 336ddde725dSArmin Le Grand break; 337ddde725dSArmin Le Grand } 338ddde725dSArmin Le Grand 339ddde725dSArmin Le Grand /// structural element marker 340ddde725dSArmin Le Grand case SVGTokenMarker: 341ddde725dSArmin Le Grand { 342ddde725dSArmin Le Grand /// new node for marker 343ddde725dSArmin Le Grand mpTarget = new SvgMarkerNode(maDocument, mpTarget); 344ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 345ddde725dSArmin Le Grand break; 346ddde725dSArmin Le Grand } 347ddde725dSArmin Le Grand 348ddde725dSArmin Le Grand /// structural element pattern 349ddde725dSArmin Le Grand case SVGTokenPattern: 350ddde725dSArmin Le Grand { 351ddde725dSArmin Le Grand /// new node for pattern 352ddde725dSArmin Le Grand mpTarget = new SvgPatternNode(maDocument, mpTarget); 353ddde725dSArmin Le Grand mpTarget->parseAttributes(xAttribs); 354ddde725dSArmin Le Grand break; 355ddde725dSArmin Le Grand } 356ddde725dSArmin Le Grand 357ddde725dSArmin Le Grand default: 358ddde725dSArmin Le Grand { 359ddde725dSArmin Le Grand /// invalid token, ignore 360ddde725dSArmin Le Grand #ifdef DBG_UTIL 361ddde725dSArmin Le Grand myAssert( 362ddde725dSArmin Le Grand rtl::OUString::createFromAscii("Unknown Base SvgToken <") + 363ddde725dSArmin Le Grand aName + 364ddde725dSArmin Le Grand rtl::OUString::createFromAscii("> (!)")); 365ddde725dSArmin Le Grand #endif 366ddde725dSArmin Le Grand break; 367ddde725dSArmin Le Grand } 368ddde725dSArmin Le Grand } 369ddde725dSArmin Le Grand } 370ddde725dSArmin Le Grand } 371ddde725dSArmin Le Grand 372ddde725dSArmin Le Grand void SvgDocHdl::endElement( const ::rtl::OUString& aName ) throw (xml::sax::SAXException, uno::RuntimeException) 373ddde725dSArmin Le Grand { 374ddde725dSArmin Le Grand if(aName.getLength()) 375ddde725dSArmin Le Grand { 376ddde725dSArmin Le Grand const SVGToken aSVGToken(StrToSVGToken(aName)); 377ddde725dSArmin Le Grand SvgNode* pWhitespaceCheck(SVGTokenText == aSVGToken ? mpTarget : 0); 3783aaca8a3SArmin Le Grand SvgStyleNode* pCssStyle(SVGTokenStyle == aSVGToken ? static_cast< SvgStyleNode* >(mpTarget) : 0); 379*025b0597SArmin Le Grand SvgTitleDescNode* pSvgTitleDescNode(SVGTokenTitle == aSVGToken || SVGTokenDesc == aSVGToken ? static_cast< SvgTitleDescNode* >(mpTarget) : 0); 380ddde725dSArmin Le Grand 381ddde725dSArmin Le Grand switch(aSVGToken) 382ddde725dSArmin Le Grand { 383ddde725dSArmin Le Grand /// valid tokens for which a new one was created 384ddde725dSArmin Le Grand 385ddde725dSArmin Le Grand /// structural elements 386ddde725dSArmin Le Grand case SVGTokenDefs: 387ddde725dSArmin Le Grand case SVGTokenG: 388ddde725dSArmin Le Grand case SVGTokenSvg: 389ddde725dSArmin Le Grand case SVGTokenSymbol: 390ddde725dSArmin Le Grand case SVGTokenUse: 391ddde725dSArmin Le Grand 392ddde725dSArmin Le Grand /// shape elements 393ddde725dSArmin Le Grand case SVGTokenCircle: 394ddde725dSArmin Le Grand case SVGTokenEllipse: 395ddde725dSArmin Le Grand case SVGTokenLine: 396ddde725dSArmin Le Grand case SVGTokenPath: 397ddde725dSArmin Le Grand case SVGTokenPolygon: 398ddde725dSArmin Le Grand case SVGTokenPolyline: 399ddde725dSArmin Le Grand case SVGTokenRect: 400ddde725dSArmin Le Grand case SVGTokenImage: 401ddde725dSArmin Le Grand 402*025b0597SArmin Le Grand /// title and description 403*025b0597SArmin Le Grand case SVGTokenTitle: 404*025b0597SArmin Le Grand case SVGTokenDesc: 405*025b0597SArmin Le Grand 406ddde725dSArmin Le Grand /// gradients 407ddde725dSArmin Le Grand case SVGTokenLinearGradient: 408ddde725dSArmin Le Grand case SVGTokenRadialGradient: 409ddde725dSArmin Le Grand 410ddde725dSArmin Le Grand /// gradient stops 411ddde725dSArmin Le Grand case SVGTokenStop: 412ddde725dSArmin Le Grand 413ddde725dSArmin Le Grand /// text 414ddde725dSArmin Le Grand case SVGTokenText: 415ddde725dSArmin Le Grand case SVGTokenTspan: 416ddde725dSArmin Le Grand case SVGTokenTextPath: 417ddde725dSArmin Le Grand case SVGTokenTref: 418ddde725dSArmin Le Grand 419ddde725dSArmin Le Grand /// styles (as stylesheets) 420ddde725dSArmin Le Grand case SVGTokenStyle: 421ddde725dSArmin Le Grand 422ddde725dSArmin Le Grand /// structural elements clip-path and mask 423ddde725dSArmin Le Grand case SVGTokenClipPathNode: 424ddde725dSArmin Le Grand case SVGTokenMask: 425ddde725dSArmin Le Grand 426ddde725dSArmin Le Grand /// structural element marker 427ddde725dSArmin Le Grand case SVGTokenMarker: 428ddde725dSArmin Le Grand 429ddde725dSArmin Le Grand /// structural element pattern 430ddde725dSArmin Le Grand case SVGTokenPattern: 431ddde725dSArmin Le Grand 432ddde725dSArmin Le Grand /// content handling after parsing 433ddde725dSArmin Le Grand { 434ddde725dSArmin Le Grand if(mpTarget) 435ddde725dSArmin Le Grand { 436ddde725dSArmin Le Grand if(!mpTarget->getParent()) 437ddde725dSArmin Le Grand { 438ddde725dSArmin Le Grand // last element closing, save this tree 439ddde725dSArmin Le Grand maDocument.appendNode(mpTarget); 440ddde725dSArmin Le Grand } 441ddde725dSArmin Le Grand 442ddde725dSArmin Le Grand mpTarget = const_cast< SvgNode* >(mpTarget->getParent()); 443ddde725dSArmin Le Grand } 444ddde725dSArmin Le Grand else 445ddde725dSArmin Le Grand { 446ddde725dSArmin Le Grand OSL_ENSURE(false, "Closing token, but no context (!)"); 447ddde725dSArmin Le Grand } 448ddde725dSArmin Le Grand break; 449ddde725dSArmin Le Grand } 450ddde725dSArmin Le Grand default: 451ddde725dSArmin Le Grand { 452ddde725dSArmin Le Grand /// invalid token, ignore 453ddde725dSArmin Le Grand } 454ddde725dSArmin Le Grand } 455ddde725dSArmin Le Grand 456*025b0597SArmin Le Grand if(pSvgTitleDescNode && mpTarget) 457*025b0597SArmin Le Grand { 458*025b0597SArmin Le Grand const rtl::OUString aText(pSvgTitleDescNode->getText()); 459*025b0597SArmin Le Grand 460*025b0597SArmin Le Grand if(aText.getLength()) 461*025b0597SArmin Le Grand { 462*025b0597SArmin Le Grand if(SVGTokenTitle == aSVGToken) 463*025b0597SArmin Le Grand { 464*025b0597SArmin Le Grand mpTarget->parseAttribute(getStrTitle(), aSVGToken, aText); 465*025b0597SArmin Le Grand } 466*025b0597SArmin Le Grand else // if(SVGTokenDesc == aSVGToken) 467*025b0597SArmin Le Grand { 468*025b0597SArmin Le Grand mpTarget->parseAttribute(getStrDesc(), aSVGToken, aText); 469*025b0597SArmin Le Grand } 470*025b0597SArmin Le Grand } 471*025b0597SArmin Le Grand } 472*025b0597SArmin Le Grand 4733aaca8a3SArmin Le Grand if(pCssStyle && pCssStyle->isTextCss()) 4743aaca8a3SArmin Le Grand { 4753aaca8a3SArmin Le Grand // css style parsing 4763aaca8a3SArmin Le Grand if(maCssContents.size()) 4773aaca8a3SArmin Le Grand { 4783aaca8a3SArmin Le Grand // need to interpret css styles and remember them as StyleSheets 4793aaca8a3SArmin Le Grand pCssStyle->addCssStyleSheet(*(maCssContents.end() - 1)); 4803aaca8a3SArmin Le Grand maCssContents.pop_back(); 4813aaca8a3SArmin Le Grand } 4823aaca8a3SArmin Le Grand else 4833aaca8a3SArmin Le Grand { 4843aaca8a3SArmin Le Grand OSL_ENSURE(false, "Closing CssStyle, but no collector string on stack (!)"); 4853aaca8a3SArmin Le Grand } 4863aaca8a3SArmin Le Grand } 4873aaca8a3SArmin Le Grand 488ddde725dSArmin Le Grand if(pWhitespaceCheck) 489ddde725dSArmin Le Grand { 490ddde725dSArmin Le Grand // cleanup read strings 491ddde725dSArmin Le Grand whiteSpaceHandling(pWhitespaceCheck, 0); 492ddde725dSArmin Le Grand } 493ddde725dSArmin Le Grand } 494ddde725dSArmin Le Grand } 495ddde725dSArmin Le Grand 496ddde725dSArmin Le Grand void SvgDocHdl::characters( const ::rtl::OUString& aChars ) throw (xml::sax::SAXException, uno::RuntimeException) 497ddde725dSArmin Le Grand { 498*025b0597SArmin Le Grand const sal_uInt32 nLength(aChars.getLength()); 499ddde725dSArmin Le Grand 500*025b0597SArmin Le Grand if(mpTarget && nLength) 501*025b0597SArmin Le Grand { 502*025b0597SArmin Le Grand switch(mpTarget->getType()) 503ddde725dSArmin Le Grand { 504*025b0597SArmin Le Grand case SVGTokenText: 505*025b0597SArmin Le Grand case SVGTokenTspan: 506*025b0597SArmin Le Grand case SVGTokenTextPath: 507ddde725dSArmin Le Grand { 508*025b0597SArmin Le Grand const SvgNodeVector& rChilds = mpTarget->getChildren(); 509*025b0597SArmin Le Grand SvgCharacterNode* pTarget = 0; 510ddde725dSArmin Le Grand 511*025b0597SArmin Le Grand if(rChilds.size()) 512*025b0597SArmin Le Grand { 513*025b0597SArmin Le Grand pTarget = dynamic_cast< SvgCharacterNode* >(rChilds[rChilds.size() - 1]); 514*025b0597SArmin Le Grand } 515ddde725dSArmin Le Grand 516*025b0597SArmin Le Grand if(pTarget) 517*025b0597SArmin Le Grand { 518*025b0597SArmin Le Grand // concatenate to current character span 519*025b0597SArmin Le Grand pTarget->concatenate(aChars); 520ddde725dSArmin Le Grand } 521*025b0597SArmin Le Grand else 522ddde725dSArmin Le Grand { 523*025b0597SArmin Le Grand // add character span as simplified tspan (no arguments) 524*025b0597SArmin Le Grand // as direct child of SvgTextNode/SvgTspanNode/SvgTextPathNode 525*025b0597SArmin Le Grand new SvgCharacterNode(maDocument, mpTarget, aChars); 526*025b0597SArmin Le Grand } 527*025b0597SArmin Le Grand break; 528*025b0597SArmin Le Grand } 529*025b0597SArmin Le Grand case SVGTokenStyle: 530*025b0597SArmin Le Grand { 531*025b0597SArmin Le Grand SvgStyleNode& rSvgStyleNode = static_cast< SvgStyleNode& >(*mpTarget); 532ddde725dSArmin Le Grand 533*025b0597SArmin Le Grand if(rSvgStyleNode.isTextCss()) 534*025b0597SArmin Le Grand { 535*025b0597SArmin Le Grand // collect characters for css style 536*025b0597SArmin Le Grand if(maCssContents.size()) 537ddde725dSArmin Le Grand { 538*025b0597SArmin Le Grand const ::rtl::OUString aTrimmedChars(aChars.trim()); 539ddde725dSArmin Le Grand 540*025b0597SArmin Le Grand if(aTrimmedChars.getLength()) 541ddde725dSArmin Le Grand { 542*025b0597SArmin Le Grand std::vector< rtl::OUString >::iterator aString(maCssContents.end() - 1); 543*025b0597SArmin Le Grand (*aString) += aTrimmedChars; 544ddde725dSArmin Le Grand } 545ddde725dSArmin Le Grand } 546*025b0597SArmin Le Grand else 547*025b0597SArmin Le Grand { 548*025b0597SArmin Le Grand OSL_ENSURE(false, "Closing CssStyle, but no collector string on stack (!)"); 549*025b0597SArmin Le Grand } 550ddde725dSArmin Le Grand } 551*025b0597SArmin Le Grand break; 552*025b0597SArmin Le Grand } 553*025b0597SArmin Le Grand case SVGTokenTitle: 554*025b0597SArmin Le Grand case SVGTokenDesc: 555*025b0597SArmin Le Grand { 556*025b0597SArmin Le Grand SvgTitleDescNode& rSvgTitleDescNode = static_cast< SvgTitleDescNode& >(*mpTarget); 557*025b0597SArmin Le Grand 558*025b0597SArmin Le Grand // add text directly to SvgTitleDescNode 559*025b0597SArmin Le Grand rSvgTitleDescNode.concatenate(aChars); 560*025b0597SArmin Le Grand break; 561*025b0597SArmin Le Grand } 562*025b0597SArmin Le Grand default: 563*025b0597SArmin Le Grand { 564*025b0597SArmin Le Grand // characters not used by a known node 565*025b0597SArmin Le Grand break; 566ddde725dSArmin Le Grand } 567ddde725dSArmin Le Grand } 568ddde725dSArmin Le Grand } 569ddde725dSArmin Le Grand } 570ddde725dSArmin Le Grand 571e2bf1e9dSArmin Le Grand void SvgDocHdl::ignorableWhitespace(const ::rtl::OUString& /*aWhitespaces*/) throw (xml::sax::SAXException, uno::RuntimeException) 572ddde725dSArmin Le Grand { 573ddde725dSArmin Le Grand } 574ddde725dSArmin Le Grand 575e2bf1e9dSArmin Le Grand void SvgDocHdl::processingInstruction(const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/) throw (xml::sax::SAXException, uno::RuntimeException) 576ddde725dSArmin Le Grand { 577ddde725dSArmin Le Grand } 578ddde725dSArmin Le Grand 579e2bf1e9dSArmin Le Grand void SvgDocHdl::setDocumentLocator(const uno::Reference< xml::sax::XLocator >& /*xLocator*/) throw (xml::sax::SAXException, uno::RuntimeException) 580ddde725dSArmin Le Grand { 581ddde725dSArmin Le Grand } 582ddde725dSArmin Le Grand } // end of namespace svgreader 583ddde725dSArmin Le Grand } // end of namespace svgio 584ddde725dSArmin Le Grand 585ddde725dSArmin Le Grand ////////////////////////////////////////////////////////////////////////////// 586ddde725dSArmin Le Grand // eof 587