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