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/svgsvgnode.hxx> 26ddde725dSArmin Le Grand #include <drawinglayer/geometry/viewinformation2d.hxx> 27ddde725dSArmin Le Grand #include <drawinglayer/primitive2d/transformprimitive2d.hxx> 28ddde725dSArmin Le Grand #include <drawinglayer/primitive2d/maskprimitive2d.hxx> 29ddde725dSArmin Le Grand #include <basegfx/polygon/b2dpolygontools.hxx> 30ddde725dSArmin Le Grand #include <basegfx/polygon/b2dpolygon.hxx> 31ddde725dSArmin Le Grand #include <basegfx/matrix/b2dhommatrixtools.hxx> 32*41923119SArmin Le Grand #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> 33*41923119SArmin Le Grand #include <drawinglayer/primitive2d/hiddengeometryprimitive2d.hxx> 34ddde725dSArmin Le Grand 35ddde725dSArmin Le Grand ////////////////////////////////////////////////////////////////////////////// 36ddde725dSArmin Le Grand 37ddde725dSArmin Le Grand namespace svgio 38ddde725dSArmin Le Grand { 39ddde725dSArmin Le Grand namespace svgreader 40ddde725dSArmin Le Grand { 41ddde725dSArmin Le Grand SvgSvgNode::SvgSvgNode( 42ddde725dSArmin Le Grand SvgDocument& rDocument, 43ddde725dSArmin Le Grand SvgNode* pParent) 44ddde725dSArmin Le Grand : SvgNode(SVGTokenSvg, rDocument, pParent), 45ddde725dSArmin Le Grand maSvgStyleAttributes(*this), 46ddde725dSArmin Le Grand mpViewBox(0), 47ddde725dSArmin Le Grand maSvgAspectRatio(), 48ddde725dSArmin Le Grand maX(), 49ddde725dSArmin Le Grand maY(), 50ddde725dSArmin Le Grand maWidth(), 51ddde725dSArmin Le Grand maHeight(), 52ddde725dSArmin Le Grand maVersion() 53ddde725dSArmin Le Grand { 54ddde725dSArmin Le Grand if(!getParent()) 55ddde725dSArmin Le Grand { 56ddde725dSArmin Le Grand // initial fill is black 57ddde725dSArmin Le Grand maSvgStyleAttributes.setFill(SvgPaint(basegfx::BColor(0.0, 0.0, 0.0), true, true)); 58ddde725dSArmin Le Grand } 59ddde725dSArmin Le Grand } 60ddde725dSArmin Le Grand 61ddde725dSArmin Le Grand SvgSvgNode::~SvgSvgNode() 62ddde725dSArmin Le Grand { 63ddde725dSArmin Le Grand if(mpViewBox) delete mpViewBox; 64ddde725dSArmin Le Grand } 65ddde725dSArmin Le Grand 66ddde725dSArmin Le Grand const SvgStyleAttributes* SvgSvgNode::getSvgStyleAttributes() const 67ddde725dSArmin Le Grand { 68ddde725dSArmin Le Grand return &maSvgStyleAttributes; 69ddde725dSArmin Le Grand } 70ddde725dSArmin Le Grand 71ddde725dSArmin Le Grand void SvgSvgNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent) 72ddde725dSArmin Le Grand { 73ddde725dSArmin Le Grand // call parent 74ddde725dSArmin Le Grand SvgNode::parseAttribute(rTokenName, aSVGToken, aContent); 75ddde725dSArmin Le Grand 76ddde725dSArmin Le Grand // read style attributes 77ddde725dSArmin Le Grand maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent); 78ddde725dSArmin Le Grand 79ddde725dSArmin Le Grand // parse own 80ddde725dSArmin Le Grand switch(aSVGToken) 81ddde725dSArmin Le Grand { 82ddde725dSArmin Le Grand case SVGTokenStyle: 83ddde725dSArmin Le Grand { 84ddde725dSArmin Le Grand maSvgStyleAttributes.readStyle(aContent); 85ddde725dSArmin Le Grand break; 86ddde725dSArmin Le Grand } 87ddde725dSArmin Le Grand case SVGTokenViewBox: 88ddde725dSArmin Le Grand { 89ddde725dSArmin Le Grand const basegfx::B2DRange aRange(readViewBox(aContent, *this)); 90ddde725dSArmin Le Grand 91ddde725dSArmin Le Grand if(!aRange.isEmpty()) 92ddde725dSArmin Le Grand { 93ddde725dSArmin Le Grand setViewBox(&aRange); 94ddde725dSArmin Le Grand } 95ddde725dSArmin Le Grand break; 96ddde725dSArmin Le Grand } 97ddde725dSArmin Le Grand case SVGTokenPreserveAspectRatio: 98ddde725dSArmin Le Grand { 99ddde725dSArmin Le Grand setSvgAspectRatio(readSvgAspectRatio(aContent)); 100ddde725dSArmin Le Grand break; 101ddde725dSArmin Le Grand } 102ddde725dSArmin Le Grand case SVGTokenX: 103ddde725dSArmin Le Grand { 104ddde725dSArmin Le Grand SvgNumber aNum; 105ddde725dSArmin Le Grand 106ddde725dSArmin Le Grand if(readSingleNumber(aContent, aNum)) 107ddde725dSArmin Le Grand { 108ddde725dSArmin Le Grand setX(aNum); 109ddde725dSArmin Le Grand } 110ddde725dSArmin Le Grand break; 111ddde725dSArmin Le Grand } 112ddde725dSArmin Le Grand case SVGTokenY: 113ddde725dSArmin Le Grand { 114ddde725dSArmin Le Grand SvgNumber aNum; 115ddde725dSArmin Le Grand 116ddde725dSArmin Le Grand if(readSingleNumber(aContent, aNum)) 117ddde725dSArmin Le Grand { 118ddde725dSArmin Le Grand setY(aNum); 119ddde725dSArmin Le Grand } 120ddde725dSArmin Le Grand break; 121ddde725dSArmin Le Grand } 122ddde725dSArmin Le Grand case SVGTokenWidth: 123ddde725dSArmin Le Grand { 124ddde725dSArmin Le Grand SvgNumber aNum; 125ddde725dSArmin Le Grand 126ddde725dSArmin Le Grand if(readSingleNumber(aContent, aNum)) 127ddde725dSArmin Le Grand { 128ddde725dSArmin Le Grand if(aNum.isPositive()) 129ddde725dSArmin Le Grand { 130ddde725dSArmin Le Grand setWidth(aNum); 131ddde725dSArmin Le Grand } 132ddde725dSArmin Le Grand } 133ddde725dSArmin Le Grand break; 134ddde725dSArmin Le Grand } 135ddde725dSArmin Le Grand case SVGTokenHeight: 136ddde725dSArmin Le Grand { 137ddde725dSArmin Le Grand SvgNumber aNum; 138ddde725dSArmin Le Grand 139ddde725dSArmin Le Grand if(readSingleNumber(aContent, aNum)) 140ddde725dSArmin Le Grand { 141ddde725dSArmin Le Grand if(aNum.isPositive()) 142ddde725dSArmin Le Grand { 143ddde725dSArmin Le Grand setHeight(aNum); 144ddde725dSArmin Le Grand } 145ddde725dSArmin Le Grand } 146ddde725dSArmin Le Grand break; 147ddde725dSArmin Le Grand } 148ddde725dSArmin Le Grand case SVGTokenVersion: 149ddde725dSArmin Le Grand { 150ddde725dSArmin Le Grand SvgNumber aNum; 151ddde725dSArmin Le Grand 152ddde725dSArmin Le Grand if(readSingleNumber(aContent, aNum)) 153ddde725dSArmin Le Grand { 154ddde725dSArmin Le Grand setVersion(aNum); 155ddde725dSArmin Le Grand } 156ddde725dSArmin Le Grand break; 157e2bf1e9dSArmin Le Grand } 158e2bf1e9dSArmin Le Grand default: 159e2bf1e9dSArmin Le Grand { 160e2bf1e9dSArmin Le Grand break; 161ddde725dSArmin Le Grand } 162ddde725dSArmin Le Grand } 163ddde725dSArmin Le Grand } 164ddde725dSArmin Le Grand 165ddde725dSArmin Le Grand void SvgSvgNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool bReferenced) const 166ddde725dSArmin Le Grand { 167ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence aSequence; 168ddde725dSArmin Le Grand 169ddde725dSArmin Le Grand // decompose childs 170ddde725dSArmin Le Grand SvgNode::decomposeSvgNode(aSequence, bReferenced); 171ddde725dSArmin Le Grand 172ddde725dSArmin Le Grand if(aSequence.hasElements()) 173ddde725dSArmin Le Grand { 174ddde725dSArmin Le Grand if(getParent()) 175ddde725dSArmin Le Grand { 176ddde725dSArmin Le Grand if(getViewBox()) 177ddde725dSArmin Le Grand { 178ddde725dSArmin Le Grand // Svg defines that with no width or no height the viewBox content is empty, 179ddde725dSArmin Le Grand // so both need to exist 180ddde725dSArmin Le Grand if(!basegfx::fTools::equalZero(getViewBox()->getWidth()) && !basegfx::fTools::equalZero(getViewBox()->getHeight())) 181ddde725dSArmin Le Grand { 182ddde725dSArmin Le Grand // create target range homing x,y, width and height as given 183ddde725dSArmin Le Grand const double fX(getX().isSet() ? getX().solve(*this, xcoordinate) : 0.0); 184ddde725dSArmin Le Grand const double fY(getY().isSet() ? getY().solve(*this, ycoordinate) : 0.0); 185ddde725dSArmin Le Grand const double fW(getWidth().isSet() ? getWidth().solve(*this, xcoordinate) : getViewBox()->getWidth()); 186ddde725dSArmin Le Grand const double fH(getHeight().isSet() ? getHeight().solve(*this, ycoordinate) : getViewBox()->getHeight()); 187ddde725dSArmin Le Grand const basegfx::B2DRange aTarget(fX, fY, fX + fW, fY + fH); 188ddde725dSArmin Le Grand 189ddde725dSArmin Le Grand if(aTarget.equal(*getViewBox())) 190ddde725dSArmin Le Grand { 191ddde725dSArmin Le Grand // no mapping needed, append 192ddde725dSArmin Le Grand drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aSequence); 193ddde725dSArmin Le Grand } 194ddde725dSArmin Le Grand else 195ddde725dSArmin Le Grand { 196ddde725dSArmin Le Grand // create mapping 197ddde725dSArmin Le Grand const SvgAspectRatio& rRatio = getSvgAspectRatio(); 198ddde725dSArmin Le Grand 199ddde725dSArmin Le Grand if(rRatio.isSet()) 200ddde725dSArmin Le Grand { 201ddde725dSArmin Le Grand // let mapping be created from SvgAspectRatio 202ddde725dSArmin Le Grand const basegfx::B2DHomMatrix aEmbeddingTransform( 203ddde725dSArmin Le Grand rRatio.createMapping(aTarget, *getViewBox())); 204ddde725dSArmin Le Grand 205ddde725dSArmin Le Grand // prepare embedding in transformation 206ddde725dSArmin Le Grand const drawinglayer::primitive2d::Primitive2DReference xRef( 207ddde725dSArmin Le Grand new drawinglayer::primitive2d::TransformPrimitive2D( 208ddde725dSArmin Le Grand aEmbeddingTransform, 209ddde725dSArmin Le Grand aSequence)); 210ddde725dSArmin Le Grand 211ddde725dSArmin Le Grand if(rRatio.isMeetOrSlice()) 212ddde725dSArmin Le Grand { 213ddde725dSArmin Le Grand // embed in transformation 214ddde725dSArmin Le Grand drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(rTarget, xRef); 215ddde725dSArmin Le Grand } 216ddde725dSArmin Le Grand else 217ddde725dSArmin Le Grand { 218ddde725dSArmin Le Grand // need to embed in MaskPrimitive2D, too 219ddde725dSArmin Le Grand const drawinglayer::primitive2d::Primitive2DReference xMask( 220ddde725dSArmin Le Grand new drawinglayer::primitive2d::MaskPrimitive2D( 221ddde725dSArmin Le Grand basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(aTarget)), 222ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1))); 223ddde725dSArmin Le Grand 224ddde725dSArmin Le Grand drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(rTarget, xMask); 225ddde725dSArmin Le Grand } 226ddde725dSArmin Le Grand } 227ddde725dSArmin Le Grand else 228ddde725dSArmin Le Grand { 229ddde725dSArmin Le Grand // choose default mapping 230ddde725dSArmin Le Grand const basegfx::B2DHomMatrix aEmbeddingTransform( 231ddde725dSArmin Le Grand rRatio.createLinearMapping( 232ddde725dSArmin Le Grand aTarget, *getViewBox())); 233ddde725dSArmin Le Grand 234ddde725dSArmin Le Grand // embed in transformation 235ddde725dSArmin Le Grand const drawinglayer::primitive2d::Primitive2DReference xTransform( 236ddde725dSArmin Le Grand new drawinglayer::primitive2d::TransformPrimitive2D( 237ddde725dSArmin Le Grand aEmbeddingTransform, 238ddde725dSArmin Le Grand aSequence)); 239ddde725dSArmin Le Grand 240ddde725dSArmin Le Grand drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(rTarget, xTransform); 241ddde725dSArmin Le Grand } 242ddde725dSArmin Le Grand } 243ddde725dSArmin Le Grand } 244ddde725dSArmin Le Grand } 245ddde725dSArmin Le Grand else 246ddde725dSArmin Le Grand { 247ddde725dSArmin Le Grand // check if we have a size 248ddde725dSArmin Le Grand const double fW(getWidth().isSet() ? getWidth().solve(*this, xcoordinate) : 0.0); 249ddde725dSArmin Le Grand const double fH(getHeight().isSet() ? getHeight().solve(*this, ycoordinate) : 0.0); 250ddde725dSArmin Le Grand 251ddde725dSArmin Le Grand // Svg defines that a negative value is an error and that 0.0 disables rendering 252ddde725dSArmin Le Grand if(basegfx::fTools::more(fW, 0.0) && basegfx::fTools::more(fH, 0.0)) 253ddde725dSArmin Le Grand { 254ddde725dSArmin Le Grand // check if we have a x,y position 255ddde725dSArmin Le Grand const double fX(getX().isSet() ? getX().solve(*this, xcoordinate) : 0.0); 256ddde725dSArmin Le Grand const double fY(getY().isSet() ? getY().solve(*this, ycoordinate) : 0.0); 257ddde725dSArmin Le Grand 258ddde725dSArmin Le Grand if(!basegfx::fTools::equalZero(fX) || !basegfx::fTools::equalZero(fY)) 259ddde725dSArmin Le Grand { 260ddde725dSArmin Le Grand // embed in transform 261ddde725dSArmin Le Grand const drawinglayer::primitive2d::Primitive2DReference xRef( 262ddde725dSArmin Le Grand new drawinglayer::primitive2d::TransformPrimitive2D( 263ddde725dSArmin Le Grand basegfx::tools::createTranslateB2DHomMatrix(fX, fY), 264ddde725dSArmin Le Grand aSequence)); 265ddde725dSArmin Le Grand 266ddde725dSArmin Le Grand aSequence = drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1); 267ddde725dSArmin Le Grand } 268ddde725dSArmin Le Grand 269ddde725dSArmin Le Grand // embed in MaskPrimitive2D to clip 270ddde725dSArmin Le Grand const drawinglayer::primitive2d::Primitive2DReference xMask( 271ddde725dSArmin Le Grand new drawinglayer::primitive2d::MaskPrimitive2D( 272ddde725dSArmin Le Grand basegfx::B2DPolyPolygon( 273ddde725dSArmin Le Grand basegfx::tools::createPolygonFromRect( 274ddde725dSArmin Le Grand basegfx::B2DRange(fX, fY, fX + fW, fY + fH))), 275ddde725dSArmin Le Grand aSequence)); 276ddde725dSArmin Le Grand 277ddde725dSArmin Le Grand // append 278ddde725dSArmin Le Grand drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(rTarget, xMask); 279ddde725dSArmin Le Grand } 280ddde725dSArmin Le Grand } 281ddde725dSArmin Le Grand } 282ddde725dSArmin Le Grand else 283ddde725dSArmin Le Grand { 284ddde725dSArmin Le Grand // Outermost SVG element; create target range homing width and height as given. 285ddde725dSArmin Le Grand // SVG defines that x,y has no meanig for the outermost SVG element. Use a fallback 286ddde725dSArmin Le Grand // width and height of din A 4 (21 x 29,7 cm) 287ddde725dSArmin Le Grand double fW(getWidth().isSet() ? getWidth().solve(*this, xcoordinate) : (210.0 * 3.543307)); 288ddde725dSArmin Le Grand double fH(getHeight().isSet() ? getHeight().solve(*this, ycoordinate) : (297.0 * 3.543307)); 289ddde725dSArmin Le Grand 290ddde725dSArmin Le Grand // Svg defines that a negative value is an error and that 0.0 disables rendering 291ddde725dSArmin Le Grand if(basegfx::fTools::more(fW, 0.0) && basegfx::fTools::more(fH, 0.0)) 292ddde725dSArmin Le Grand { 293ddde725dSArmin Le Grand const basegfx::B2DRange aSvgCanvasRange(0.0, 0.0, fW, fH); 294ddde725dSArmin Le Grand 295ddde725dSArmin Le Grand if(getViewBox()) 296ddde725dSArmin Le Grand { 297ddde725dSArmin Le Grand if(!basegfx::fTools::equalZero(getViewBox()->getWidth()) && !basegfx::fTools::equalZero(getViewBox()->getHeight())) 298ddde725dSArmin Le Grand { 299ddde725dSArmin Le Grand // create mapping 300ddde725dSArmin Le Grand const SvgAspectRatio& rRatio = getSvgAspectRatio(); 301ddde725dSArmin Le Grand basegfx::B2DHomMatrix aViewBoxMapping; 302ddde725dSArmin Le Grand 303ddde725dSArmin Le Grand if(rRatio.isSet()) 304ddde725dSArmin Le Grand { 305ddde725dSArmin Le Grand // let mapping be created from SvgAspectRatio 306ddde725dSArmin Le Grand aViewBoxMapping = rRatio.createMapping(aSvgCanvasRange, *getViewBox()); 307ddde725dSArmin Le Grand 308ddde725dSArmin Le Grand // no need to check ratio here for slice, the outermost Svg will 309ddde725dSArmin Le Grand // be clipped anyways (see below) 310ddde725dSArmin Le Grand } 311ddde725dSArmin Le Grand else 312ddde725dSArmin Le Grand { 313ddde725dSArmin Le Grand // choose default mapping 314ddde725dSArmin Le Grand aViewBoxMapping = rRatio.createLinearMapping(aSvgCanvasRange, *getViewBox()); 315ddde725dSArmin Le Grand } 316ddde725dSArmin Le Grand 317ddde725dSArmin Le Grand // scale content to viewBox definitions 318ddde725dSArmin Le Grand const drawinglayer::primitive2d::Primitive2DReference xTransform( 319ddde725dSArmin Le Grand new drawinglayer::primitive2d::TransformPrimitive2D( 320ddde725dSArmin Le Grand aViewBoxMapping, 321ddde725dSArmin Le Grand aSequence)); 322ddde725dSArmin Le Grand 323ddde725dSArmin Le Grand aSequence = drawinglayer::primitive2d::Primitive2DSequence(&xTransform, 1); 324ddde725dSArmin Le Grand } 325ddde725dSArmin Le Grand } 326ddde725dSArmin Le Grand 327ddde725dSArmin Le Grand // to be completely correct in Svg sense it is necessary to clip 328ddde725dSArmin Le Grand // the whole content to the given canvas. I choose here to do this 329ddde725dSArmin Le Grand // initially despite I found various examples of Svg files out there 330ddde725dSArmin Le Grand // which have no correct values for this clipping. It's correct 331ddde725dSArmin Le Grand // due to the Svg spec. 332ddde725dSArmin Le Grand bool bDoCorrectCanvasClipping(true); 333ddde725dSArmin Le Grand 334ddde725dSArmin Le Grand if(bDoCorrectCanvasClipping) 335ddde725dSArmin Le Grand { 336ddde725dSArmin Le Grand // different from Svg we have the possibility with primitives to get 337*41923119SArmin Le Grand // a correct bounding box for the geometry. Get it for evtl. taking action 338ddde725dSArmin Le Grand const basegfx::B2DRange aContentRange( 339ddde725dSArmin Le Grand drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence( 340ddde725dSArmin Le Grand aSequence, 341ddde725dSArmin Le Grand drawinglayer::geometry::ViewInformation2D())); 342ddde725dSArmin Le Grand 343*41923119SArmin Le Grand if(aSvgCanvasRange.isInside(aContentRange)) 344ddde725dSArmin Le Grand { 345*41923119SArmin Le Grand // no clip needed, but an invisible HiddenGeometryPrimitive2D 346*41923119SArmin Le Grand // to allow getting the full Svg range using the primitive mechanisms. 347*41923119SArmin Le Grand // This is needed since e.g. an SdrObject using this as graphic will 348*41923119SArmin Le Grand // create a mapping transformation to exactly map the content to it's 349*41923119SArmin Le Grand // real life size 350*41923119SArmin Le Grand const drawinglayer::primitive2d::Primitive2DReference xLine( 351*41923119SArmin Le Grand new drawinglayer::primitive2d::PolygonHairlinePrimitive2D( 352*41923119SArmin Le Grand basegfx::tools::createPolygonFromRect( 353*41923119SArmin Le Grand aSvgCanvasRange), 354*41923119SArmin Le Grand basegfx::BColor(0.0, 0.0, 0.0))); 355*41923119SArmin Le Grand const drawinglayer::primitive2d::Primitive2DReference xHidden( 356*41923119SArmin Le Grand new drawinglayer::primitive2d::HiddenGeometryPrimitive2D( 357*41923119SArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence(&xLine, 1))); 358*41923119SArmin Le Grand 359*41923119SArmin Le Grand drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aSequence, xHidden); 360*41923119SArmin Le Grand } 361*41923119SArmin Le Grand else if(aSvgCanvasRange.overlaps(aContentRange)) 362*41923119SArmin Le Grand { 363*41923119SArmin Le Grand // Clip is necessary. This will make Svg images evtl. smaller 364*41923119SArmin Le Grand // than wanted from Svg (the free space which may be around it is 365*41923119SArmin Le Grand // conform to the Svg spec), but avoids an expensive and unneccessary 366*41923119SArmin Le Grand // clip. Keep the full Svg range here to get the correct mappings 367*41923119SArmin Le Grand // to objects using this. Optimizations can be done in the processors 368ddde725dSArmin Le Grand const drawinglayer::primitive2d::Primitive2DReference xMask( 369ddde725dSArmin Le Grand new drawinglayer::primitive2d::MaskPrimitive2D( 370ddde725dSArmin Le Grand basegfx::B2DPolyPolygon( 371ddde725dSArmin Le Grand basegfx::tools::createPolygonFromRect( 372ddde725dSArmin Le Grand aSvgCanvasRange)), 373ddde725dSArmin Le Grand aSequence)); 374ddde725dSArmin Le Grand 375ddde725dSArmin Le Grand aSequence = drawinglayer::primitive2d::Primitive2DSequence(&xMask, 1); 376ddde725dSArmin Le Grand } 377*41923119SArmin Le Grand else 378*41923119SArmin Le Grand { 379*41923119SArmin Le Grand // not inside, no overlap. Empty Svg 380*41923119SArmin Le Grand aSequence.realloc(0); 381*41923119SArmin Le Grand } 382ddde725dSArmin Le Grand } 383ddde725dSArmin Le Grand 384*41923119SArmin Le Grand if(aSequence.hasElements()) 385ddde725dSArmin Le Grand { 386ddde725dSArmin Le Grand // embed in transform primitive to scale to 1/100th mm 387ddde725dSArmin Le Grand // where 1 mm == 3.543307 px to get from Svg coordinates to 388ddde725dSArmin Le Grand // drawinglayer ones 389ddde725dSArmin Le Grand const double fScaleTo100thmm(100.0 / 3.543307); 390ddde725dSArmin Le Grand const basegfx::B2DHomMatrix aTransform( 391ddde725dSArmin Le Grand basegfx::tools::createScaleB2DHomMatrix( 392ddde725dSArmin Le Grand fScaleTo100thmm, 393ddde725dSArmin Le Grand fScaleTo100thmm)); 394ddde725dSArmin Le Grand 395ddde725dSArmin Le Grand const drawinglayer::primitive2d::Primitive2DReference xTransform( 396ddde725dSArmin Le Grand new drawinglayer::primitive2d::TransformPrimitive2D( 397ddde725dSArmin Le Grand aTransform, 398ddde725dSArmin Le Grand aSequence)); 399ddde725dSArmin Le Grand 400ddde725dSArmin Le Grand aSequence = drawinglayer::primitive2d::Primitive2DSequence(&xTransform, 1); 401ddde725dSArmin Le Grand 402*41923119SArmin Le Grand // append to result 403*41923119SArmin Le Grand drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aSequence); 404*41923119SArmin Le Grand } 405ddde725dSArmin Le Grand } 406ddde725dSArmin Le Grand } 407ddde725dSArmin Le Grand } 408ddde725dSArmin Le Grand } 409ddde725dSArmin Le Grand 410ddde725dSArmin Le Grand const basegfx::B2DRange* SvgSvgNode::getCurrentViewPort() const 411ddde725dSArmin Le Grand { 412ddde725dSArmin Le Grand if(getViewBox()) 413ddde725dSArmin Le Grand { 414ddde725dSArmin Le Grand return getViewBox(); 415ddde725dSArmin Le Grand } 416ddde725dSArmin Le Grand else 417ddde725dSArmin Le Grand { 418ddde725dSArmin Le Grand return SvgNode::getCurrentViewPort(); 419ddde725dSArmin Le Grand } 420ddde725dSArmin Le Grand } 421ddde725dSArmin Le Grand 422ddde725dSArmin Le Grand } // end of namespace svgreader 423ddde725dSArmin Le Grand } // end of namespace svgio 424ddde725dSArmin Le Grand 425ddde725dSArmin Le Grand ////////////////////////////////////////////////////////////////////////////// 426ddde725dSArmin Le Grand // eof 427