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/svgstyleattributes.hxx> 26ddde725dSArmin Le Grand #include <drawinglayer/primitive2d/transformprimitive2d.hxx> 27ddde725dSArmin Le Grand #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> 28ddde725dSArmin Le Grand #include <svgio/svgreader/svgnode.hxx> 29ddde725dSArmin Le Grand #include <svgio/svgreader/svgdocument.hxx> 30ddde725dSArmin Le Grand #include <drawinglayer/primitive2d/svggradientprimitive2d.hxx> 31ddde725dSArmin Le Grand #include <svgio/svgreader/svggradientnode.hxx> 32ddde725dSArmin Le Grand #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> 33ddde725dSArmin Le Grand #include <basegfx/vector/b2enums.hxx> 34ddde725dSArmin Le Grand #include <drawinglayer/processor2d/linegeometryextractor2d.hxx> 35ddde725dSArmin Le Grand #include <drawinglayer/processor2d/textaspolygonextractor2d.hxx> 36ddde725dSArmin Le Grand #include <basegfx/polygon/b2dpolypolygoncutter.hxx> 37ddde725dSArmin Le Grand #include <svgio/svgreader/svgclippathnode.hxx> 38ddde725dSArmin Le Grand #include <svgio/svgreader/svgmasknode.hxx> 39ddde725dSArmin Le Grand #include <basegfx/polygon/b2dpolypolygoncutter.hxx> 40ddde725dSArmin Le Grand #include <basegfx/polygon/b2dpolypolygontools.hxx> 41ddde725dSArmin Le Grand #include <svgio/svgreader/svgmarkernode.hxx> 42ddde725dSArmin Le Grand #include <basegfx/curve/b2dcubicbezier.hxx> 43ddde725dSArmin Le Grand #include <svgio/svgreader/svgpatternnode.hxx> 44ddde725dSArmin Le Grand #include <drawinglayer/primitive2d/patternfillprimitive2d.hxx> 45ddde725dSArmin Le Grand 46ddde725dSArmin Le Grand ////////////////////////////////////////////////////////////////////////////// 47ddde725dSArmin Le Grand 48ddde725dSArmin Le Grand namespace svgio 49ddde725dSArmin Le Grand { 50ddde725dSArmin Le Grand namespace svgreader 51ddde725dSArmin Le Grand { 52ddde725dSArmin Le Grand basegfx::B2DLineJoin StrokeLinejoinToB2DLineJoin(StrokeLinejoin aStrokeLinejoin) 53ddde725dSArmin Le Grand { 54ddde725dSArmin Le Grand if(StrokeLinejoin_round == aStrokeLinejoin) 55ddde725dSArmin Le Grand { 56ddde725dSArmin Le Grand return basegfx::B2DLINEJOIN_ROUND; 57ddde725dSArmin Le Grand } 58ddde725dSArmin Le Grand else if(StrokeLinejoin_bevel == aStrokeLinejoin) 59ddde725dSArmin Le Grand { 60ddde725dSArmin Le Grand return basegfx::B2DLINEJOIN_BEVEL; 61ddde725dSArmin Le Grand } 62ddde725dSArmin Le Grand 63ddde725dSArmin Le Grand return basegfx::B2DLINEJOIN_MITER; 64ddde725dSArmin Le Grand } 65ddde725dSArmin Le Grand 66ddde725dSArmin Le Grand FontStretch getWider(FontStretch aSource) 67ddde725dSArmin Le Grand { 68ddde725dSArmin Le Grand switch(aSource) 69ddde725dSArmin Le Grand { 70ddde725dSArmin Le Grand case FontStretch_ultra_condensed: aSource = FontStretch_extra_condensed; break; 71ddde725dSArmin Le Grand case FontStretch_extra_condensed: aSource = FontStretch_condensed; break; 72ddde725dSArmin Le Grand case FontStretch_condensed: aSource = FontStretch_semi_condensed; break; 73ddde725dSArmin Le Grand case FontStretch_semi_condensed: aSource = FontStretch_normal; break; 74ddde725dSArmin Le Grand case FontStretch_normal: aSource = FontStretch_semi_expanded; break; 75ddde725dSArmin Le Grand case FontStretch_semi_expanded: aSource = FontStretch_expanded; break; 76ddde725dSArmin Le Grand case FontStretch_expanded: aSource = FontStretch_extra_expanded; break; 77ddde725dSArmin Le Grand case FontStretch_extra_expanded: aSource = FontStretch_ultra_expanded; break; 78e2bf1e9dSArmin Le Grand default: break; 79ddde725dSArmin Le Grand } 80ddde725dSArmin Le Grand 81ddde725dSArmin Le Grand return aSource; 82ddde725dSArmin Le Grand } 83ddde725dSArmin Le Grand 84ddde725dSArmin Le Grand FontStretch getNarrower(FontStretch aSource) 85ddde725dSArmin Le Grand { 86ddde725dSArmin Le Grand switch(aSource) 87ddde725dSArmin Le Grand { 88ddde725dSArmin Le Grand case FontStretch_extra_condensed: aSource = FontStretch_ultra_condensed; break; 89ddde725dSArmin Le Grand case FontStretch_condensed: aSource = FontStretch_extra_condensed; break; 90ddde725dSArmin Le Grand case FontStretch_semi_condensed: aSource = FontStretch_condensed; break; 91ddde725dSArmin Le Grand case FontStretch_normal: aSource = FontStretch_semi_condensed; break; 92ddde725dSArmin Le Grand case FontStretch_semi_expanded: aSource = FontStretch_normal; break; 93ddde725dSArmin Le Grand case FontStretch_expanded: aSource = FontStretch_semi_expanded; break; 94ddde725dSArmin Le Grand case FontStretch_extra_expanded: aSource = FontStretch_expanded; break; 95ddde725dSArmin Le Grand case FontStretch_ultra_expanded: aSource = FontStretch_extra_expanded; break; 96e2bf1e9dSArmin Le Grand default: break; 97ddde725dSArmin Le Grand } 98ddde725dSArmin Le Grand 99ddde725dSArmin Le Grand return aSource; 100ddde725dSArmin Le Grand } 101ddde725dSArmin Le Grand 102ddde725dSArmin Le Grand FontWeight getBolder(FontWeight aSource) 103ddde725dSArmin Le Grand { 104ddde725dSArmin Le Grand switch(aSource) 105ddde725dSArmin Le Grand { 106ddde725dSArmin Le Grand case FontWeight_100: aSource = FontWeight_200; break; 107ddde725dSArmin Le Grand case FontWeight_200: aSource = FontWeight_300; break; 108ddde725dSArmin Le Grand case FontWeight_300: aSource = FontWeight_400; break; 109ddde725dSArmin Le Grand case FontWeight_400: aSource = FontWeight_500; break; 110ddde725dSArmin Le Grand case FontWeight_500: aSource = FontWeight_600; break; 111ddde725dSArmin Le Grand case FontWeight_600: aSource = FontWeight_700; break; 112ddde725dSArmin Le Grand case FontWeight_700: aSource = FontWeight_800; break; 113ddde725dSArmin Le Grand case FontWeight_800: aSource = FontWeight_900; break; 114e2bf1e9dSArmin Le Grand default: break; 115ddde725dSArmin Le Grand } 116ddde725dSArmin Le Grand 117ddde725dSArmin Le Grand return aSource; 118ddde725dSArmin Le Grand } 119ddde725dSArmin Le Grand 120ddde725dSArmin Le Grand FontWeight getLighter(FontWeight aSource) 121ddde725dSArmin Le Grand { 122ddde725dSArmin Le Grand switch(aSource) 123ddde725dSArmin Le Grand { 124ddde725dSArmin Le Grand case FontWeight_200: aSource = FontWeight_100; break; 125ddde725dSArmin Le Grand case FontWeight_300: aSource = FontWeight_200; break; 126ddde725dSArmin Le Grand case FontWeight_400: aSource = FontWeight_300; break; 127ddde725dSArmin Le Grand case FontWeight_500: aSource = FontWeight_400; break; 128ddde725dSArmin Le Grand case FontWeight_600: aSource = FontWeight_500; break; 129ddde725dSArmin Le Grand case FontWeight_700: aSource = FontWeight_600; break; 130ddde725dSArmin Le Grand case FontWeight_800: aSource = FontWeight_700; break; 131ddde725dSArmin Le Grand case FontWeight_900: aSource = FontWeight_800; break; 132e2bf1e9dSArmin Le Grand default: break; 133ddde725dSArmin Le Grand } 134ddde725dSArmin Le Grand 135ddde725dSArmin Le Grand return aSource; 136ddde725dSArmin Le Grand } 137ddde725dSArmin Le Grand 138ddde725dSArmin Le Grand ::FontWeight getVclFontWeight(FontWeight aSource) 139ddde725dSArmin Le Grand { 140ddde725dSArmin Le Grand ::FontWeight nRetval(WEIGHT_NORMAL); 141ddde725dSArmin Le Grand 142ddde725dSArmin Le Grand switch(aSource) 143ddde725dSArmin Le Grand { 144ddde725dSArmin Le Grand case FontWeight_100: nRetval = WEIGHT_ULTRALIGHT; break; 145ddde725dSArmin Le Grand case FontWeight_200: nRetval = WEIGHT_LIGHT; break; 146ddde725dSArmin Le Grand case FontWeight_300: nRetval = WEIGHT_SEMILIGHT; break; 147ddde725dSArmin Le Grand case FontWeight_400: nRetval = WEIGHT_NORMAL; break; 148ddde725dSArmin Le Grand case FontWeight_500: nRetval = WEIGHT_MEDIUM; break; 149ddde725dSArmin Le Grand case FontWeight_600: nRetval = WEIGHT_SEMIBOLD; break; 150ddde725dSArmin Le Grand case FontWeight_700: nRetval = WEIGHT_BOLD; break; 151ddde725dSArmin Le Grand case FontWeight_800: nRetval = WEIGHT_ULTRABOLD; break; 152ddde725dSArmin Le Grand case FontWeight_900: nRetval = WEIGHT_BLACK; break; 153e2bf1e9dSArmin Le Grand default: break; 154ddde725dSArmin Le Grand } 155ddde725dSArmin Le Grand 156ddde725dSArmin Le Grand return nRetval; 157ddde725dSArmin Le Grand } 158ddde725dSArmin Le Grand 159ddde725dSArmin Le Grand void SvgStyleAttributes::readStyle(const rtl::OUString& rCandidate) 160ddde725dSArmin Le Grand { 161ddde725dSArmin Le Grand const sal_Int32 nLen(rCandidate.getLength()); 162ddde725dSArmin Le Grand sal_Int32 nPos(0); 163ddde725dSArmin Le Grand 164ddde725dSArmin Le Grand while(nPos < nLen) 165ddde725dSArmin Le Grand { 166ddde725dSArmin Le Grand const sal_Int32 nInitPos(nPos); 167ddde725dSArmin Le Grand skip_char(rCandidate, sal_Unicode(' '), nPos, nLen); 168ddde725dSArmin Le Grand rtl::OUStringBuffer aTokenName; 169ddde725dSArmin Le Grand copyString(rCandidate, nPos, aTokenName, nLen); 170ddde725dSArmin Le Grand 171ddde725dSArmin Le Grand if(aTokenName.getLength()) 172ddde725dSArmin Le Grand { 173ddde725dSArmin Le Grand skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(':'), nPos, nLen); 174ddde725dSArmin Le Grand rtl::OUStringBuffer aTokenValue; 175ddde725dSArmin Le Grand copyToLimiter(rCandidate, sal_Unicode(';'), nPos, aTokenValue, nLen); 176ddde725dSArmin Le Grand skip_char(rCandidate, sal_Unicode(' '), sal_Unicode(';'), nPos, nLen); 177ddde725dSArmin Le Grand const rtl::OUString aOUTokenName(aTokenName.makeStringAndClear()); 178ddde725dSArmin Le Grand const rtl::OUString aOUTokenValue(aTokenValue.makeStringAndClear()); 179ddde725dSArmin Le Grand 180ddde725dSArmin Le Grand parseStyleAttribute(aOUTokenName, StrToSVGToken(aOUTokenName), aOUTokenValue); 181ddde725dSArmin Le Grand } 182ddde725dSArmin Le Grand 183ddde725dSArmin Le Grand if(nInitPos == nPos) 184ddde725dSArmin Le Grand { 185ddde725dSArmin Le Grand OSL_ENSURE(false, "Could not interpret on current position (!)"); 186ddde725dSArmin Le Grand nPos++; 187ddde725dSArmin Le Grand } 188ddde725dSArmin Le Grand } 189ddde725dSArmin Le Grand } 190ddde725dSArmin Le Grand 191ddde725dSArmin Le Grand void SvgStyleAttributes::checkForCssStyle(const rtl::OUString& rClassStr) const 192ddde725dSArmin Le Grand { 193ddde725dSArmin Le Grand if(!mpCssStyleParent) 194ddde725dSArmin Le Grand { 195ddde725dSArmin Le Grand const SvgDocument& rDocument = mrOwner.getDocument(); 196ddde725dSArmin Le Grand const SvgStyleAttributes* pNew = 0; 197ddde725dSArmin Le Grand 198ddde725dSArmin Le Grand if(rDocument.hasSvgStyleAttributesById()) 199ddde725dSArmin Le Grand { 200ddde725dSArmin Le Grand if(mrOwner.getClass()) 201ddde725dSArmin Le Grand { 202ddde725dSArmin Le Grand rtl::OUString aId(rtl::OUString::createFromAscii(".")); 203ddde725dSArmin Le Grand aId = aId + *mrOwner.getClass(); 204ddde725dSArmin Le Grand pNew = rDocument.findSvgStyleAttributesById(aId); 205ddde725dSArmin Le Grand 206*3aaca8a3SArmin Le Grand if(!pNew && rClassStr.getLength()) 207ddde725dSArmin Le Grand { 208ddde725dSArmin Le Grand aId = rClassStr + aId; 209ddde725dSArmin Le Grand 210ddde725dSArmin Le Grand pNew = rDocument.findSvgStyleAttributesById(aId); 211ddde725dSArmin Le Grand } 212ddde725dSArmin Le Grand } 213ddde725dSArmin Le Grand else if(mrOwner.getId()) 214ddde725dSArmin Le Grand { 215ddde725dSArmin Le Grand pNew = rDocument.findSvgStyleAttributesById(*mrOwner.getId()); 216ddde725dSArmin Le Grand } 217*3aaca8a3SArmin Le Grand else if(rClassStr.getLength()) 218*3aaca8a3SArmin Le Grand { 219*3aaca8a3SArmin Le Grand pNew = rDocument.findSvgStyleAttributesById(rClassStr); 220*3aaca8a3SArmin Le Grand } 221ddde725dSArmin Le Grand 222ddde725dSArmin Le Grand if(pNew) 223ddde725dSArmin Le Grand { 224ddde725dSArmin Le Grand // found css style, set as parent 225ddde725dSArmin Le Grand const_cast< SvgStyleAttributes* >(this)->mpCssStyleParent = pNew; 226ddde725dSArmin Le Grand } 227ddde725dSArmin Le Grand } 228ddde725dSArmin Le Grand } 229ddde725dSArmin Le Grand } 230ddde725dSArmin Le Grand 231ddde725dSArmin Le Grand const SvgStyleAttributes* SvgStyleAttributes::getParentStyle() const 232ddde725dSArmin Le Grand { 233ddde725dSArmin Le Grand if(mpCssStyleParent) 234ddde725dSArmin Le Grand { 235ddde725dSArmin Le Grand return mpCssStyleParent; 236ddde725dSArmin Le Grand } 237ddde725dSArmin Le Grand 238ddde725dSArmin Le Grand if(mrOwner.getParent()) 239ddde725dSArmin Le Grand { 240ddde725dSArmin Le Grand return mrOwner.getParent()->getSvgStyleAttributes(); 241ddde725dSArmin Le Grand } 242ddde725dSArmin Le Grand 243ddde725dSArmin Le Grand return 0; 244ddde725dSArmin Le Grand } 245ddde725dSArmin Le Grand 246ddde725dSArmin Le Grand void SvgStyleAttributes::add_text( 247ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence& rTarget, 248ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence& rSource) const 249ddde725dSArmin Le Grand { 250ddde725dSArmin Le Grand if(rSource.hasElements()) 251ddde725dSArmin Le Grand { 252ddde725dSArmin Le Grand // at this point the primitives in rSource are of type TextSimplePortionPrimitive2D 253ddde725dSArmin Le Grand // or TextDecoratedPortionPrimitive2D and have the Fill Color (pAttributes->getFill()) 254ddde725dSArmin Le Grand // set. When another fill is used and also evtl. stroke is set it gets necessary to 255ddde725dSArmin Le Grand // dismantle to geometry and add needed primitives 256ddde725dSArmin Le Grand const basegfx::BColor* pFill = getFill(); 257ddde725dSArmin Le Grand const SvgGradientNode* pFillGradient = getSvgGradientNodeFill(); 258ddde725dSArmin Le Grand const SvgPatternNode* pFillPattern = getSvgPatternNodeFill(); 259ddde725dSArmin Le Grand const basegfx::BColor* pStroke = getStroke(); 260ddde725dSArmin Le Grand const SvgGradientNode* pStrokeGradient = getSvgGradientNodeStroke(); 261ddde725dSArmin Le Grand const SvgPatternNode* pStrokePattern = getSvgPatternNodeStroke(); 262ddde725dSArmin Le Grand basegfx::B2DPolyPolygon aMergedArea; 263ddde725dSArmin Le Grand 264ddde725dSArmin Le Grand if(pFillGradient || pFillPattern || pStroke || pStrokeGradient || pStrokePattern) 265ddde725dSArmin Le Grand { 266ddde725dSArmin Le Grand // text geometry is needed, create 267ddde725dSArmin Le Grand // use neutral ViewInformation and create LineGeometryExtractor2D 268ddde725dSArmin Le Grand const drawinglayer::geometry::ViewInformation2D aViewInformation2D; 269ddde725dSArmin Le Grand drawinglayer::processor2d::TextAsPolygonExtractor2D aExtractor(aViewInformation2D); 270ddde725dSArmin Le Grand 271ddde725dSArmin Le Grand // proccess 272ddde725dSArmin Le Grand aExtractor.process(rSource); 273ddde725dSArmin Le Grand 274ddde725dSArmin Le Grand // get results 275ddde725dSArmin Le Grand const drawinglayer::processor2d::TextAsPolygonDataNodeVector& rResult = aExtractor.getTarget(); 276ddde725dSArmin Le Grand const sal_uInt32 nResultCount(rResult.size()); 277ddde725dSArmin Le Grand basegfx::B2DPolyPolygonVector aTextFillVector; 278ddde725dSArmin Le Grand aTextFillVector.reserve(nResultCount); 279ddde725dSArmin Le Grand 280ddde725dSArmin Le Grand for(sal_uInt32 a(0); a < nResultCount; a++) 281ddde725dSArmin Le Grand { 282ddde725dSArmin Le Grand const drawinglayer::processor2d::TextAsPolygonDataNode& rCandidate = rResult[a]; 283ddde725dSArmin Le Grand 284ddde725dSArmin Le Grand if(rCandidate.getIsFilled()) 285ddde725dSArmin Le Grand { 286ddde725dSArmin Le Grand aTextFillVector.push_back(rCandidate.getB2DPolyPolygon()); 287ddde725dSArmin Le Grand } 288ddde725dSArmin Le Grand } 289ddde725dSArmin Le Grand 290ddde725dSArmin Le Grand if(!aTextFillVector.empty()) 291ddde725dSArmin Le Grand { 292ddde725dSArmin Le Grand aMergedArea = basegfx::tools::mergeToSinglePolyPolygon(aTextFillVector); 293ddde725dSArmin Le Grand } 294ddde725dSArmin Le Grand } 295ddde725dSArmin Le Grand 296ddde725dSArmin Le Grand const bool bStrokeUsed(pStroke || pStrokeGradient || pStrokePattern); 297ddde725dSArmin Le Grand 298ddde725dSArmin Le Grand // add fill. Use geometry even for simple color fill when stroke 299ddde725dSArmin Le Grand // is used, else text rendering and the geometry-based stroke will 300ddde725dSArmin Le Grand // normally not really match optically due to divrese system text 301ddde725dSArmin Le Grand // renderers 302ddde725dSArmin Le Grand if(aMergedArea.count() && (pFillGradient || pFillPattern || bStrokeUsed)) 303ddde725dSArmin Le Grand { 304ddde725dSArmin Le Grand // create text fill content based on geometry 305ddde725dSArmin Le Grand add_fill(aMergedArea, rTarget, aMergedArea.getB2DRange()); 306ddde725dSArmin Le Grand } 307ddde725dSArmin Le Grand else if(pFill) 308ddde725dSArmin Le Grand { 309ddde725dSArmin Le Grand // add the already prepared primitives for single color fill 310ddde725dSArmin Le Grand drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, rSource); 311ddde725dSArmin Le Grand } 312ddde725dSArmin Le Grand 313ddde725dSArmin Le Grand // add stroke 314ddde725dSArmin Le Grand if(aMergedArea.count() && bStrokeUsed) 315ddde725dSArmin Le Grand { 316ddde725dSArmin Le Grand // create text stroke content 317ddde725dSArmin Le Grand add_stroke(aMergedArea, rTarget, aMergedArea.getB2DRange()); 318ddde725dSArmin Le Grand } 319ddde725dSArmin Le Grand } 320ddde725dSArmin Le Grand } 321ddde725dSArmin Le Grand 322ddde725dSArmin Le Grand void SvgStyleAttributes::add_fillGradient( 323ddde725dSArmin Le Grand const basegfx::B2DPolyPolygon& rPath, 324ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence& rTarget, 325ddde725dSArmin Le Grand const SvgGradientNode& rFillGradient, 326ddde725dSArmin Le Grand const basegfx::B2DRange& rGeoRange) const 327ddde725dSArmin Le Grand { 328ddde725dSArmin Le Grand // create fill content 329ddde725dSArmin Le Grand drawinglayer::primitive2d::SvgGradientEntryVector aSvgGradientEntryVector; 330ddde725dSArmin Le Grand 331ddde725dSArmin Le Grand // get the color stops 332ddde725dSArmin Le Grand rFillGradient.collectGradientEntries(aSvgGradientEntryVector); 333ddde725dSArmin Le Grand 334ddde725dSArmin Le Grand if(!aSvgGradientEntryVector.empty()) 335ddde725dSArmin Le Grand { 336ddde725dSArmin Le Grand basegfx::B2DHomMatrix aGeoToUnit; 337ddde725dSArmin Le Grand 338ddde725dSArmin Le Grand if(rFillGradient.getGradientTransform()) 339ddde725dSArmin Le Grand { 340ddde725dSArmin Le Grand aGeoToUnit = *rFillGradient.getGradientTransform(); 341ddde725dSArmin Le Grand } 342ddde725dSArmin Le Grand 343ddde725dSArmin Le Grand if(userSpaceOnUse == rFillGradient.getGradientUnits()) 344ddde725dSArmin Le Grand { 345ddde725dSArmin Le Grand aGeoToUnit.translate(-rGeoRange.getMinX(), -rGeoRange.getMinY()); 346ddde725dSArmin Le Grand aGeoToUnit.scale(1.0 / rGeoRange.getWidth(), 1.0 / rGeoRange.getHeight()); 347ddde725dSArmin Le Grand } 348ddde725dSArmin Le Grand 349ddde725dSArmin Le Grand if(SVGTokenLinearGradient == rFillGradient.getType()) 350ddde725dSArmin Le Grand { 351ddde725dSArmin Le Grand basegfx::B2DPoint aStart(0.0, 0.0); 352ddde725dSArmin Le Grand basegfx::B2DPoint aEnd(1.0, 0.0); 353ddde725dSArmin Le Grand 354ddde725dSArmin Le Grand if(userSpaceOnUse == rFillGradient.getGradientUnits()) 355ddde725dSArmin Le Grand { 356ddde725dSArmin Le Grand // all possible units 357ddde725dSArmin Le Grand aStart.setX(rFillGradient.getX1().solve(mrOwner, xcoordinate)); 358ddde725dSArmin Le Grand aStart.setY(rFillGradient.getY1().solve(mrOwner, ycoordinate)); 359ddde725dSArmin Le Grand aEnd.setX(rFillGradient.getX2().solve(mrOwner, xcoordinate)); 360ddde725dSArmin Le Grand aEnd.setY(rFillGradient.getY2().solve(mrOwner, ycoordinate)); 361ddde725dSArmin Le Grand } 362ddde725dSArmin Le Grand else 363ddde725dSArmin Le Grand { 364ddde725dSArmin Le Grand // fractions or percent relative to object bounds 365ddde725dSArmin Le Grand const SvgNumber X1(rFillGradient.getX1()); 366ddde725dSArmin Le Grand const SvgNumber Y1(rFillGradient.getY1()); 367ddde725dSArmin Le Grand const SvgNumber X2(rFillGradient.getX2()); 368ddde725dSArmin Le Grand const SvgNumber Y2(rFillGradient.getY2()); 369ddde725dSArmin Le Grand 370ddde725dSArmin Le Grand aStart.setX(Unit_percent == X1.getUnit() ? X1.getNumber() * 0.01 : X1.getNumber()); 371ddde725dSArmin Le Grand aStart.setY(Unit_percent == Y1.getUnit() ? Y1.getNumber() * 0.01 : Y1.getNumber()); 372ddde725dSArmin Le Grand aEnd.setX(Unit_percent == X2.getUnit() ? X2.getNumber() * 0.01 : X2.getNumber()); 373ddde725dSArmin Le Grand aEnd.setY(Unit_percent == Y2.getUnit() ? Y2.getNumber() * 0.01 : Y2.getNumber()); 374ddde725dSArmin Le Grand } 375ddde725dSArmin Le Grand 376ddde725dSArmin Le Grand if(!aGeoToUnit.isIdentity()) 377ddde725dSArmin Le Grand { 378ddde725dSArmin Le Grand aStart *= aGeoToUnit; 379ddde725dSArmin Le Grand aEnd *= aGeoToUnit; 380ddde725dSArmin Le Grand } 381ddde725dSArmin Le Grand 382ddde725dSArmin Le Grand drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence( 383ddde725dSArmin Le Grand rTarget, 384ddde725dSArmin Le Grand new drawinglayer::primitive2d::SvgLinearGradientPrimitive2D( 385ddde725dSArmin Le Grand rPath, 386ddde725dSArmin Le Grand aSvgGradientEntryVector, 387ddde725dSArmin Le Grand aStart, 388ddde725dSArmin Le Grand aEnd, 389ddde725dSArmin Le Grand rFillGradient.getSpreadMethod())); 390ddde725dSArmin Le Grand } 391ddde725dSArmin Le Grand else 392ddde725dSArmin Le Grand { 393ddde725dSArmin Le Grand basegfx::B2DPoint aStart(0.5, 0.5); 394ddde725dSArmin Le Grand basegfx::B2DPoint aFocal; 395ddde725dSArmin Le Grand double fRadius(0.5); 396ddde725dSArmin Le Grand const SvgNumber* pFx = rFillGradient.getFx(); 397ddde725dSArmin Le Grand const SvgNumber* pFy = rFillGradient.getFy(); 398ddde725dSArmin Le Grand const bool bFocal(pFx || pFy); 399ddde725dSArmin Le Grand 400ddde725dSArmin Le Grand if(userSpaceOnUse == rFillGradient.getGradientUnits()) 401ddde725dSArmin Le Grand { 402ddde725dSArmin Le Grand // all possible units 403ddde725dSArmin Le Grand aStart.setX(rFillGradient.getCx().solve(mrOwner, xcoordinate)); 404ddde725dSArmin Le Grand aStart.setY(rFillGradient.getCy().solve(mrOwner, ycoordinate)); 405ddde725dSArmin Le Grand fRadius = rFillGradient.getR().solve(mrOwner, length); 406ddde725dSArmin Le Grand 407ddde725dSArmin Le Grand if(bFocal) 408ddde725dSArmin Le Grand { 409ddde725dSArmin Le Grand aFocal.setX(pFx ? pFx->solve(mrOwner, xcoordinate) : aStart.getX()); 410ddde725dSArmin Le Grand aFocal.setY(pFy ? pFy->solve(mrOwner, ycoordinate) : aStart.getY()); 411ddde725dSArmin Le Grand } 412ddde725dSArmin Le Grand } 413ddde725dSArmin Le Grand else 414ddde725dSArmin Le Grand { 415ddde725dSArmin Le Grand // fractions or percent relative to object bounds 416ddde725dSArmin Le Grand const SvgNumber Cx(rFillGradient.getCx()); 417ddde725dSArmin Le Grand const SvgNumber Cy(rFillGradient.getCy()); 418ddde725dSArmin Le Grand const SvgNumber R(rFillGradient.getR()); 419ddde725dSArmin Le Grand 420ddde725dSArmin Le Grand aStart.setX(Unit_percent == Cx.getUnit() ? Cx.getNumber() * 0.01 : Cx.getNumber()); 421ddde725dSArmin Le Grand aStart.setY(Unit_percent == Cy.getUnit() ? Cy.getNumber() * 0.01 : Cy.getNumber()); 422ddde725dSArmin Le Grand fRadius = (Unit_percent == R.getUnit()) ? R.getNumber() * 0.01 : R.getNumber(); 423ddde725dSArmin Le Grand 424ddde725dSArmin Le Grand if(bFocal) 425ddde725dSArmin Le Grand { 426ddde725dSArmin Le Grand aFocal.setX(pFx ? (Unit_percent == pFx->getUnit() ? pFx->getNumber() * 0.01 : pFx->getNumber()) : aStart.getX()); 427ddde725dSArmin Le Grand aFocal.setY(pFy ? (Unit_percent == pFy->getUnit() ? pFy->getNumber() * 0.01 : pFy->getNumber()) : aStart.getY()); 428ddde725dSArmin Le Grand } 429ddde725dSArmin Le Grand } 430ddde725dSArmin Le Grand 431ddde725dSArmin Le Grand if(!aGeoToUnit.isIdentity()) 432ddde725dSArmin Le Grand { 433ddde725dSArmin Le Grand aStart *= aGeoToUnit; 434ddde725dSArmin Le Grand fRadius = (aGeoToUnit * basegfx::B2DVector(fRadius, 0.0)).getLength(); 435ddde725dSArmin Le Grand 436ddde725dSArmin Le Grand if(bFocal) 437ddde725dSArmin Le Grand { 438ddde725dSArmin Le Grand aFocal *= aGeoToUnit; 439ddde725dSArmin Le Grand } 440ddde725dSArmin Le Grand } 441ddde725dSArmin Le Grand 442ddde725dSArmin Le Grand drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence( 443ddde725dSArmin Le Grand rTarget, 444ddde725dSArmin Le Grand new drawinglayer::primitive2d::SvgRadialGradientPrimitive2D( 445ddde725dSArmin Le Grand rPath, 446ddde725dSArmin Le Grand aSvgGradientEntryVector, 447ddde725dSArmin Le Grand aStart, 448ddde725dSArmin Le Grand fRadius, 449ddde725dSArmin Le Grand rFillGradient.getSpreadMethod(), 450ddde725dSArmin Le Grand bFocal ? &aFocal : 0)); 451ddde725dSArmin Le Grand } 452ddde725dSArmin Le Grand } 453ddde725dSArmin Le Grand } 454ddde725dSArmin Le Grand 455ddde725dSArmin Le Grand void SvgStyleAttributes::add_fillPatternTransform( 456ddde725dSArmin Le Grand const basegfx::B2DPolyPolygon& rPath, 457ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence& rTarget, 458ddde725dSArmin Le Grand const SvgPatternNode& rFillPattern, 459ddde725dSArmin Le Grand const basegfx::B2DRange& rGeoRange) const 460ddde725dSArmin Le Grand { 461ddde725dSArmin Le Grand // prepare fill polyPolygon with given pattern, check for patternTransform 462ddde725dSArmin Le Grand if(rFillPattern.getPatternTransform() && !rFillPattern.getPatternTransform()->isIdentity()) 463ddde725dSArmin Le Grand { 464ddde725dSArmin Le Grand // PatternTransform is active; Handle by filling the inverse transformed 465ddde725dSArmin Le Grand // path and back-transforming the result 466ddde725dSArmin Le Grand basegfx::B2DPolyPolygon aPath(rPath); 467ddde725dSArmin Le Grand basegfx::B2DHomMatrix aInv(*rFillPattern.getPatternTransform()); 468ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence aNewTarget; 469ddde725dSArmin Le Grand 470ddde725dSArmin Le Grand aInv.invert(); 471ddde725dSArmin Le Grand aPath.transform(aInv); 472ddde725dSArmin Le Grand add_fillPattern(aPath, aNewTarget, rFillPattern, aPath.getB2DRange()); 473ddde725dSArmin Le Grand 474ddde725dSArmin Le Grand if(aNewTarget.hasElements()) 475ddde725dSArmin Le Grand { 476ddde725dSArmin Le Grand drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence( 477ddde725dSArmin Le Grand rTarget, 478ddde725dSArmin Le Grand new drawinglayer::primitive2d::TransformPrimitive2D( 479ddde725dSArmin Le Grand *rFillPattern.getPatternTransform(), 480ddde725dSArmin Le Grand aNewTarget)); 481ddde725dSArmin Le Grand } 482ddde725dSArmin Le Grand } 483ddde725dSArmin Le Grand else 484ddde725dSArmin Le Grand { 485ddde725dSArmin Le Grand // no patternTransform, create fillPattern directly 486ddde725dSArmin Le Grand add_fillPattern(rPath, rTarget, rFillPattern, rGeoRange); 487ddde725dSArmin Le Grand } 488ddde725dSArmin Le Grand } 489ddde725dSArmin Le Grand 490ddde725dSArmin Le Grand void SvgStyleAttributes::add_fillPattern( 491ddde725dSArmin Le Grand const basegfx::B2DPolyPolygon& rPath, 492ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence& rTarget, 493ddde725dSArmin Le Grand const SvgPatternNode& rFillPattern, 494ddde725dSArmin Le Grand const basegfx::B2DRange& rGeoRange) const 495ddde725dSArmin Le Grand { 496ddde725dSArmin Le Grand // fill polyPolygon with given pattern 497ddde725dSArmin Le Grand const drawinglayer::primitive2d::Primitive2DSequence& rPrimitives = rFillPattern.getPatternPrimitives(); 498ddde725dSArmin Le Grand 499ddde725dSArmin Le Grand if(rPrimitives.hasElements()) 500ddde725dSArmin Le Grand { 501ddde725dSArmin Le Grand double fTargetWidth(rGeoRange.getWidth()); 502ddde725dSArmin Le Grand double fTargetHeight(rGeoRange.getHeight()); 503ddde725dSArmin Le Grand 504ddde725dSArmin Le Grand if(fTargetWidth > 0.0 && fTargetHeight > 0.0) 505ddde725dSArmin Le Grand { 506ddde725dSArmin Le Grand // get relative values from pattern 507ddde725dSArmin Le Grand double fX(0.0); 508ddde725dSArmin Le Grand double fY(0.0); 509ddde725dSArmin Le Grand double fW(0.0); 510ddde725dSArmin Le Grand double fH(0.0); 511ddde725dSArmin Le Grand 512ddde725dSArmin Le Grand rFillPattern.getValuesRelative(fX, fY, fW, fH, rGeoRange, mrOwner); 513ddde725dSArmin Le Grand 514ddde725dSArmin Le Grand if(fW > 0.0 && fH > 0.0) 515ddde725dSArmin Le Grand { 516ddde725dSArmin Le Grand // build the reference range relative to the rGeoRange 517ddde725dSArmin Le Grand const basegfx::B2DRange aReferenceRange(fX, fY, fX + fW, fY + fH); 518ddde725dSArmin Le Grand 519ddde725dSArmin Le Grand // find out how the content is mapped to the reference range 520ddde725dSArmin Le Grand basegfx::B2DHomMatrix aMapPrimitivesToUnitRange; 521ddde725dSArmin Le Grand const basegfx::B2DRange* pViewBox = rFillPattern.getViewBox(); 522ddde725dSArmin Le Grand 523ddde725dSArmin Le Grand if(pViewBox) 524ddde725dSArmin Le Grand { 525ddde725dSArmin Le Grand // use viewBox/preserveAspectRatio 526ddde725dSArmin Le Grand const SvgAspectRatio& rRatio = rFillPattern.getSvgAspectRatio(); 527ddde725dSArmin Le Grand const basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0); 528ddde725dSArmin Le Grand 529ddde725dSArmin Le Grand if(rRatio.isSet()) 530ddde725dSArmin Le Grand { 531ddde725dSArmin Le Grand // let mapping be created from SvgAspectRatio 532ddde725dSArmin Le Grand aMapPrimitivesToUnitRange = rRatio.createMapping(aUnitRange, *pViewBox); 533ddde725dSArmin Le Grand } 534ddde725dSArmin Le Grand else 535ddde725dSArmin Le Grand { 536ddde725dSArmin Le Grand // choose default mapping 537ddde725dSArmin Le Grand aMapPrimitivesToUnitRange = rRatio.createLinearMapping(aUnitRange, *pViewBox); 538ddde725dSArmin Le Grand } 539ddde725dSArmin Le Grand } 540ddde725dSArmin Le Grand else 541ddde725dSArmin Le Grand { 542ddde725dSArmin Le Grand // use patternContentUnits 543ddde725dSArmin Le Grand const SvgUnits aPatternContentUnits(rFillPattern.getPatternContentUnits() ? *rFillPattern.getPatternContentUnits() : userSpaceOnUse); 544ddde725dSArmin Le Grand 545ddde725dSArmin Le Grand if(userSpaceOnUse == aPatternContentUnits) 546ddde725dSArmin Le Grand { 547ddde725dSArmin Le Grand // create relative mapping to unit coordinates 548ddde725dSArmin Le Grand aMapPrimitivesToUnitRange.scale(1.0 / (fW * fTargetWidth), 1.0 / (fH * fTargetHeight)); 549ddde725dSArmin Le Grand } 550ddde725dSArmin Le Grand else 551ddde725dSArmin Le Grand { 552ddde725dSArmin Le Grand aMapPrimitivesToUnitRange.scale(1.0 / fW, 1.0 / fH); 553ddde725dSArmin Le Grand } 554ddde725dSArmin Le Grand } 555ddde725dSArmin Le Grand 556ddde725dSArmin Le Grand // apply aMapPrimitivesToUnitRange to content when used 557ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence aPrimitives(rPrimitives); 558ddde725dSArmin Le Grand 559ddde725dSArmin Le Grand if(!aMapPrimitivesToUnitRange.isIdentity()) 560ddde725dSArmin Le Grand { 561ddde725dSArmin Le Grand const drawinglayer::primitive2d::Primitive2DReference xRef( 562ddde725dSArmin Le Grand new drawinglayer::primitive2d::TransformPrimitive2D( 563ddde725dSArmin Le Grand aMapPrimitivesToUnitRange, 564ddde725dSArmin Le Grand aPrimitives)); 565ddde725dSArmin Le Grand 566ddde725dSArmin Le Grand aPrimitives = drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1); 567ddde725dSArmin Le Grand } 568ddde725dSArmin Le Grand 569ddde725dSArmin Le Grand // embed in PatternFillPrimitive2D 570ddde725dSArmin Le Grand drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence( 571ddde725dSArmin Le Grand rTarget, 572ddde725dSArmin Le Grand new drawinglayer::primitive2d::PatternFillPrimitive2D( 573ddde725dSArmin Le Grand rPath, 574ddde725dSArmin Le Grand aPrimitives, 575ddde725dSArmin Le Grand aReferenceRange)); 576ddde725dSArmin Le Grand } 577ddde725dSArmin Le Grand } 578ddde725dSArmin Le Grand } 579ddde725dSArmin Le Grand } 580ddde725dSArmin Le Grand 581ddde725dSArmin Le Grand void SvgStyleAttributes::add_fill( 582ddde725dSArmin Le Grand const basegfx::B2DPolyPolygon& rPath, 583ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence& rTarget, 584ddde725dSArmin Le Grand const basegfx::B2DRange& rGeoRange) const 585ddde725dSArmin Le Grand { 586ddde725dSArmin Le Grand const basegfx::BColor* pFill = getFill(); 587ddde725dSArmin Le Grand const SvgGradientNode* pFillGradient = getSvgGradientNodeFill(); 588ddde725dSArmin Le Grand const SvgPatternNode* pFillPattern = getSvgPatternNodeFill(); 589ddde725dSArmin Le Grand 590ddde725dSArmin Le Grand if(pFill || pFillGradient || pFillPattern) 591ddde725dSArmin Le Grand { 592ddde725dSArmin Le Grand const double fFillOpacity(getFillOpacity().solve(mrOwner, length)); 593ddde725dSArmin Le Grand 594ddde725dSArmin Le Grand if(basegfx::fTools::more(fFillOpacity, 0.0)) 595ddde725dSArmin Le Grand { 596ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence aNewFill; 597ddde725dSArmin Le Grand 598ddde725dSArmin Le Grand if(pFillGradient) 599ddde725dSArmin Le Grand { 600ddde725dSArmin Le Grand // create fill content with SVG gradient primitive 601ddde725dSArmin Le Grand add_fillGradient(rPath, aNewFill, *pFillGradient, rGeoRange); 602ddde725dSArmin Le Grand } 603ddde725dSArmin Le Grand else if(pFillPattern) 604ddde725dSArmin Le Grand { 605ddde725dSArmin Le Grand // create fill content with SVG pattern primitive 606ddde725dSArmin Le Grand add_fillPatternTransform(rPath, aNewFill, *pFillPattern, rGeoRange); 607ddde725dSArmin Le Grand } 608ddde725dSArmin Le Grand else // if(pFill) 609ddde725dSArmin Le Grand { 610ddde725dSArmin Le Grand // create fill content 611ddde725dSArmin Le Grand aNewFill.realloc(1); 612ddde725dSArmin Le Grand aNewFill[0] = new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( 613ddde725dSArmin Le Grand rPath, 614ddde725dSArmin Le Grand *pFill); 615ddde725dSArmin Le Grand } 616ddde725dSArmin Le Grand 617ddde725dSArmin Le Grand if(aNewFill.hasElements()) 618ddde725dSArmin Le Grand { 619ddde725dSArmin Le Grand if(basegfx::fTools::less(fFillOpacity, 1.0)) 620ddde725dSArmin Le Grand { 621ddde725dSArmin Le Grand // embed in UnifiedTransparencePrimitive2D 622ddde725dSArmin Le Grand drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence( 623ddde725dSArmin Le Grand rTarget, 624ddde725dSArmin Le Grand new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D( 625ddde725dSArmin Le Grand aNewFill, 626ddde725dSArmin Le Grand 1.0 - fFillOpacity)); 627ddde725dSArmin Le Grand } 628ddde725dSArmin Le Grand else 629ddde725dSArmin Le Grand { 630ddde725dSArmin Le Grand // append 631ddde725dSArmin Le Grand drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aNewFill); 632ddde725dSArmin Le Grand } 633ddde725dSArmin Le Grand } 634ddde725dSArmin Le Grand } 635ddde725dSArmin Le Grand } 636ddde725dSArmin Le Grand } 637ddde725dSArmin Le Grand 638ddde725dSArmin Le Grand void SvgStyleAttributes::add_stroke( 639ddde725dSArmin Le Grand const basegfx::B2DPolyPolygon& rPath, 640ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence& rTarget, 641ddde725dSArmin Le Grand const basegfx::B2DRange& rGeoRange) const 642ddde725dSArmin Le Grand { 643ddde725dSArmin Le Grand const basegfx::BColor* pStroke = getStroke(); 644ddde725dSArmin Le Grand const SvgGradientNode* pStrokeGradient = getSvgGradientNodeStroke(); 645ddde725dSArmin Le Grand const SvgPatternNode* pStrokePattern = getSvgPatternNodeStroke(); 646ddde725dSArmin Le Grand 647ddde725dSArmin Le Grand if(pStroke || pStrokeGradient || pStrokePattern) 648ddde725dSArmin Le Grand { 649ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence aNewStroke; 650ddde725dSArmin Le Grand const double fStrokeOpacity(getStrokeOpacity().solve(mrOwner, length)); 651ddde725dSArmin Le Grand 652ddde725dSArmin Le Grand if(basegfx::fTools::more(fStrokeOpacity, 0.0)) 653ddde725dSArmin Le Grand { 654ddde725dSArmin Le Grand // get stroke width; SVG does not use 0.0 == hairline, so 0.0 is no line at all 655ddde725dSArmin Le Grand const double fStrokeWidth(getStrokeWidth().isSet() ? getStrokeWidth().solve(mrOwner, length) : 1.0); 656ddde725dSArmin Le Grand 657ddde725dSArmin Le Grand if(basegfx::fTools::more(fStrokeWidth, 0.0)) 658ddde725dSArmin Le Grand { 659ddde725dSArmin Le Grand // get LineJoin and stroke array 660ddde725dSArmin Le Grand const basegfx::B2DLineJoin aB2DLineJoin(StrokeLinejoinToB2DLineJoin(getStrokeLinejoin())); 661ddde725dSArmin Le Grand ::std::vector< double > aDashArray; 662ddde725dSArmin Le Grand 663ddde725dSArmin Le Grand if(!getStrokeDasharray().empty()) 664ddde725dSArmin Le Grand { 665ddde725dSArmin Le Grand aDashArray = solveSvgNumberVector(getStrokeDasharray(), mrOwner, length); 666ddde725dSArmin Le Grand } 667ddde725dSArmin Le Grand 668ddde725dSArmin Le Grand // todo: Handle getStrokeDashOffset() 669ddde725dSArmin Le Grand // todo: Handle getStrokeLinecap() 670ddde725dSArmin Le Grand 671ddde725dSArmin Le Grand // prepare line attribute 672ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DReference aNewLinePrimitive; 673ddde725dSArmin Le Grand const drawinglayer::attribute::LineAttribute aLineAttribute( 674ddde725dSArmin Le Grand pStroke ? *pStroke : basegfx::BColor(0.0, 0.0, 0.0), 675ddde725dSArmin Le Grand fStrokeWidth, 676ddde725dSArmin Le Grand aB2DLineJoin); 677ddde725dSArmin Le Grand 678ddde725dSArmin Le Grand if(aDashArray.empty()) 679ddde725dSArmin Le Grand { 680ddde725dSArmin Le Grand aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D( 681ddde725dSArmin Le Grand rPath, 682ddde725dSArmin Le Grand aLineAttribute); 683ddde725dSArmin Le Grand } 684ddde725dSArmin Le Grand else 685ddde725dSArmin Le Grand { 686ddde725dSArmin Le Grand const drawinglayer::attribute::StrokeAttribute aStrokeAttribute(aDashArray); 687ddde725dSArmin Le Grand 688ddde725dSArmin Le Grand aNewLinePrimitive = new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D( 689ddde725dSArmin Le Grand rPath, 690ddde725dSArmin Le Grand aLineAttribute, 691ddde725dSArmin Le Grand aDashArray); 692ddde725dSArmin Le Grand } 693ddde725dSArmin Le Grand 694ddde725dSArmin Le Grand if(pStrokeGradient || pStrokePattern) 695ddde725dSArmin Le Grand { 696ddde725dSArmin Le Grand // put primitive into Primitive2DReference and Primitive2DSequence 697ddde725dSArmin Le Grand const drawinglayer::primitive2d::Primitive2DSequence aSeq(&aNewLinePrimitive, 1); 698ddde725dSArmin Le Grand 699ddde725dSArmin Le Grand // use neutral ViewInformation and create LineGeometryExtractor2D 700ddde725dSArmin Le Grand const drawinglayer::geometry::ViewInformation2D aViewInformation2D; 701ddde725dSArmin Le Grand drawinglayer::processor2d::LineGeometryExtractor2D aExtractor(aViewInformation2D); 702ddde725dSArmin Le Grand 703ddde725dSArmin Le Grand // proccess 704ddde725dSArmin Le Grand aExtractor.process(aSeq); 705ddde725dSArmin Le Grand 706ddde725dSArmin Le Grand // check for fill rsults 707ddde725dSArmin Le Grand const basegfx::B2DPolyPolygonVector& rLineFillVector(aExtractor.getExtractedLineFills()); 708ddde725dSArmin Le Grand 709e2bf1e9dSArmin Le Grand if(!rLineFillVector.empty()) 710ddde725dSArmin Le Grand { 711ddde725dSArmin Le Grand const basegfx::B2DPolyPolygon aMergedArea( 712ddde725dSArmin Le Grand basegfx::tools::mergeToSinglePolyPolygon( 713e2bf1e9dSArmin Le Grand rLineFillVector)); 714ddde725dSArmin Le Grand 715ddde725dSArmin Le Grand if(aMergedArea.count()) 716ddde725dSArmin Le Grand { 717ddde725dSArmin Le Grand if(pStrokeGradient) 718ddde725dSArmin Le Grand { 719ddde725dSArmin Le Grand // create fill content with SVG gradient primitive. Use original GeoRange, 720ddde725dSArmin Le Grand // e.g. from circle without LineWidth 721ddde725dSArmin Le Grand add_fillGradient(aMergedArea, aNewStroke, *pStrokeGradient, rGeoRange); 722ddde725dSArmin Le Grand } 723ddde725dSArmin Le Grand else // if(pStrokePattern) 724ddde725dSArmin Le Grand { 725ddde725dSArmin Le Grand // create fill content with SVG pattern primitive. Use GeoRange 726ddde725dSArmin Le Grand // from the expanded data, e.g. circle with extended geo by half linewidth 727ddde725dSArmin Le Grand add_fillPatternTransform(aMergedArea, aNewStroke, *pStrokePattern, aMergedArea.getB2DRange()); 728ddde725dSArmin Le Grand } 729ddde725dSArmin Le Grand } 730ddde725dSArmin Le Grand } 731ddde725dSArmin Le Grand } 732ddde725dSArmin Le Grand else // if(pStroke) 733ddde725dSArmin Le Grand { 734ddde725dSArmin Le Grand drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aNewStroke, aNewLinePrimitive); 735ddde725dSArmin Le Grand } 736ddde725dSArmin Le Grand 737ddde725dSArmin Le Grand if(aNewStroke.hasElements()) 738ddde725dSArmin Le Grand { 739ddde725dSArmin Le Grand if(basegfx::fTools::less(fStrokeOpacity, 1.0)) 740ddde725dSArmin Le Grand { 741ddde725dSArmin Le Grand // embed in UnifiedTransparencePrimitive2D 742ddde725dSArmin Le Grand drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence( 743ddde725dSArmin Le Grand rTarget, 744ddde725dSArmin Le Grand new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D( 745ddde725dSArmin Le Grand aNewStroke, 746ddde725dSArmin Le Grand 1.0 - fStrokeOpacity)); 747ddde725dSArmin Le Grand } 748ddde725dSArmin Le Grand else 749ddde725dSArmin Le Grand { 750ddde725dSArmin Le Grand // append 751ddde725dSArmin Le Grand drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aNewStroke); 752ddde725dSArmin Le Grand } 753ddde725dSArmin Le Grand } 754ddde725dSArmin Le Grand } 755ddde725dSArmin Le Grand } 756ddde725dSArmin Le Grand } 757ddde725dSArmin Le Grand } 758ddde725dSArmin Le Grand 759ddde725dSArmin Le Grand double get_markerRotation( 760ddde725dSArmin Le Grand const SvgMarkerNode& rMarker, 761ddde725dSArmin Le Grand const basegfx::B2DPolygon& rPolygon, 762ddde725dSArmin Le Grand const sal_uInt32 nIndex) 763ddde725dSArmin Le Grand { 764ddde725dSArmin Le Grand double fAngle(0.0); 765ddde725dSArmin Le Grand const sal_uInt32 nPointCount(rPolygon.count()); 766ddde725dSArmin Le Grand 767ddde725dSArmin Le Grand if(nPointCount) 768ddde725dSArmin Le Grand { 769ddde725dSArmin Le Grand if(rMarker.getOrientAuto()) 770ddde725dSArmin Le Grand { 771ddde725dSArmin Le Grand const bool bPrev(rPolygon.isClosed() || nIndex > 0); 772ddde725dSArmin Le Grand basegfx::B2DCubicBezier aSegment; 773ddde725dSArmin Le Grand basegfx::B2DVector aPrev; 774ddde725dSArmin Le Grand basegfx::B2DVector aNext; 775ddde725dSArmin Le Grand 776ddde725dSArmin Le Grand if(bPrev) 777ddde725dSArmin Le Grand { 778ddde725dSArmin Le Grand rPolygon.getBezierSegment((nIndex - 1) % nPointCount, aSegment); 779ddde725dSArmin Le Grand aPrev = aSegment.getTangent(1.0); 780ddde725dSArmin Le Grand } 781ddde725dSArmin Le Grand 782ddde725dSArmin Le Grand const bool bNext(rPolygon.isClosed() || nIndex + 1 < nPointCount); 783ddde725dSArmin Le Grand 784ddde725dSArmin Le Grand if(bNext) 785ddde725dSArmin Le Grand { 786ddde725dSArmin Le Grand rPolygon.getBezierSegment(nIndex % nPointCount, aSegment); 787ddde725dSArmin Le Grand aNext = aSegment.getTangent(0.0); 788ddde725dSArmin Le Grand } 789ddde725dSArmin Le Grand 790ddde725dSArmin Le Grand if(bPrev && bNext) 791ddde725dSArmin Le Grand { 792ddde725dSArmin Le Grand fAngle = atan2(aPrev.getY() + aNext.getY(), aPrev.getX() + aNext.getX()); 793ddde725dSArmin Le Grand } 794ddde725dSArmin Le Grand else if(bPrev) 795ddde725dSArmin Le Grand { 796ddde725dSArmin Le Grand fAngle = atan2(aPrev.getY(), aPrev.getX()); 797ddde725dSArmin Le Grand } 798ddde725dSArmin Le Grand else if(bNext) 799ddde725dSArmin Le Grand { 800ddde725dSArmin Le Grand fAngle = atan2(aNext.getY(), aNext.getX()); 801ddde725dSArmin Le Grand } 802ddde725dSArmin Le Grand } 803ddde725dSArmin Le Grand else 804ddde725dSArmin Le Grand { 805ddde725dSArmin Le Grand fAngle = rMarker.getAngle(); 806ddde725dSArmin Le Grand } 807ddde725dSArmin Le Grand } 808ddde725dSArmin Le Grand 809ddde725dSArmin Le Grand return fAngle; 810ddde725dSArmin Le Grand } 811ddde725dSArmin Le Grand 812ddde725dSArmin Le Grand bool SvgStyleAttributes::prepare_singleMarker( 813ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence& rMarkerPrimitives, 814ddde725dSArmin Le Grand basegfx::B2DHomMatrix& rMarkerTransform, 815ddde725dSArmin Le Grand basegfx::B2DRange& rClipRange, 816ddde725dSArmin Le Grand const SvgMarkerNode& rMarker) const 817ddde725dSArmin Le Grand { 818ddde725dSArmin Le Grand // reset return values 819ddde725dSArmin Le Grand rMarkerTransform.identity(); 820ddde725dSArmin Le Grand rClipRange.reset(); 821ddde725dSArmin Le Grand 822ddde725dSArmin Le Grand // get marker primitive representation 823ddde725dSArmin Le Grand rMarkerPrimitives = rMarker.getMarkerPrimitives(); 824ddde725dSArmin Le Grand 825ddde725dSArmin Le Grand if(rMarkerPrimitives.hasElements()) 826ddde725dSArmin Le Grand { 827ddde725dSArmin Le Grand basegfx::B2DRange aPrimitiveRange; 828ddde725dSArmin Le Grand 829ddde725dSArmin Le Grand if(rMarker.getViewBox()) 830ddde725dSArmin Le Grand { 831ddde725dSArmin Le Grand aPrimitiveRange = *rMarker.getViewBox(); 832ddde725dSArmin Le Grand } 833ddde725dSArmin Le Grand else 834ddde725dSArmin Le Grand { 835ddde725dSArmin Le Grand aPrimitiveRange = drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence( 836ddde725dSArmin Le Grand rMarkerPrimitives, 837ddde725dSArmin Le Grand drawinglayer::geometry::ViewInformation2D()); 838ddde725dSArmin Le Grand } 839ddde725dSArmin Le Grand 840ddde725dSArmin Le Grand if(aPrimitiveRange.getWidth() > 0.0 && aPrimitiveRange.getHeight() > 0.0) 841ddde725dSArmin Le Grand { 842ddde725dSArmin Le Grand double fTargetWidth(rMarker.getMarkerWidth().isSet() ? rMarker.getMarkerWidth().solve(mrOwner, xcoordinate) : 0.0); 843ddde725dSArmin Le Grand double fTargetHeight(rMarker.getMarkerHeight().isSet() ? rMarker.getMarkerHeight().solve(mrOwner, xcoordinate) : 0.0); 844ddde725dSArmin Le Grand 845ddde725dSArmin Le Grand if(SvgMarkerNode::strokeWidth == rMarker.getMarkerUnits()) 846ddde725dSArmin Le Grand { 847ddde725dSArmin Le Grand // relative to strokeWidth 848ddde725dSArmin Le Grand const double fStrokeWidth(getStrokeWidth().isSet() ? getStrokeWidth().solve(mrOwner, length) : 1.0); 849ddde725dSArmin Le Grand 850ddde725dSArmin Le Grand fTargetWidth *= fStrokeWidth; 851ddde725dSArmin Le Grand fTargetHeight *= fStrokeWidth; 852ddde725dSArmin Le Grand } 853ddde725dSArmin Le Grand 854ddde725dSArmin Le Grand if(fTargetWidth > 0.0 && fTargetHeight > 0.0) 855ddde725dSArmin Le Grand { 856ddde725dSArmin Le Grand const basegfx::B2DRange aTargetRange(0.0, 0.0, fTargetWidth, fTargetHeight); 857ddde725dSArmin Le Grand 858ddde725dSArmin Le Grand // subbstract refX, refY first, it's in marker local coordinates 859ddde725dSArmin Le Grand rMarkerTransform.translate( 860ddde725dSArmin Le Grand rMarker.getRefX().isSet() ? -rMarker.getRefX().solve(mrOwner, xcoordinate) : 0.0, 861ddde725dSArmin Le Grand rMarker.getRefY().isSet() ? -rMarker.getRefY().solve(mrOwner, ycoordinate) : 0.0); 862ddde725dSArmin Le Grand 863ddde725dSArmin Le Grand // create mapping 864ddde725dSArmin Le Grand const SvgAspectRatio& rRatio = rMarker.getSvgAspectRatio(); 865ddde725dSArmin Le Grand 866ddde725dSArmin Le Grand if(rRatio.isSet()) 867ddde725dSArmin Le Grand { 868ddde725dSArmin Le Grand // let mapping be created from SvgAspectRatio 869ddde725dSArmin Le Grand rMarkerTransform = rRatio.createMapping(aTargetRange, aPrimitiveRange) * rMarkerTransform; 870ddde725dSArmin Le Grand 871ddde725dSArmin Le Grand if(rRatio.isMeetOrSlice()) 872ddde725dSArmin Le Grand { 873ddde725dSArmin Le Grand // need to clip 874ddde725dSArmin Le Grand rClipRange = basegfx::B2DRange(0.0, 0.0, 1.0, 1.0); 875ddde725dSArmin Le Grand } 876ddde725dSArmin Le Grand } 877ddde725dSArmin Le Grand else 878ddde725dSArmin Le Grand { 879ddde725dSArmin Le Grand // choose default mapping 880ddde725dSArmin Le Grand rMarkerTransform = rRatio.createLinearMapping(aTargetRange, aPrimitiveRange) * rMarkerTransform; 881ddde725dSArmin Le Grand } 882ddde725dSArmin Le Grand 883ddde725dSArmin Le Grand return true; 884ddde725dSArmin Le Grand } 885ddde725dSArmin Le Grand } 886ddde725dSArmin Le Grand } 887ddde725dSArmin Le Grand 888ddde725dSArmin Le Grand return false; 889ddde725dSArmin Le Grand } 890ddde725dSArmin Le Grand 891ddde725dSArmin Le Grand void SvgStyleAttributes::add_singleMarker( 892ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence& rTarget, 893ddde725dSArmin Le Grand const drawinglayer::primitive2d::Primitive2DSequence& rMarkerPrimitives, 894ddde725dSArmin Le Grand const basegfx::B2DHomMatrix& rMarkerTransform, 895e2bf1e9dSArmin Le Grand const basegfx::B2DRange& /*rClipRange*/, 896ddde725dSArmin Le Grand const SvgMarkerNode& rMarker, 897ddde725dSArmin Le Grand const basegfx::B2DPolygon& rCandidate, 898ddde725dSArmin Le Grand const sal_uInt32 nIndex) const 899ddde725dSArmin Le Grand { 900ddde725dSArmin Le Grand const sal_uInt32 nPointCount(rCandidate.count()); 901ddde725dSArmin Le Grand 902ddde725dSArmin Le Grand if(nPointCount) 903ddde725dSArmin Le Grand { 904ddde725dSArmin Le Grand // get and apply rotation 905ddde725dSArmin Le Grand basegfx::B2DHomMatrix aCombinedTransform(rMarkerTransform); 906ddde725dSArmin Le Grand aCombinedTransform.rotate(get_markerRotation(rMarker, rCandidate, nIndex)); 907ddde725dSArmin Le Grand 908ddde725dSArmin Le Grand // get and apply target position 909ddde725dSArmin Le Grand const basegfx::B2DPoint aPoint(rCandidate.getB2DPoint(nIndex % nPointCount)); 910ddde725dSArmin Le Grand aCombinedTransform.translate(aPoint.getX(), aPoint.getY()); 911ddde725dSArmin Le Grand 912ddde725dSArmin Le Grand // add marker 913ddde725dSArmin Le Grand drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence( 914ddde725dSArmin Le Grand rTarget, 915ddde725dSArmin Le Grand new drawinglayer::primitive2d::TransformPrimitive2D( 916ddde725dSArmin Le Grand aCombinedTransform, 917ddde725dSArmin Le Grand rMarkerPrimitives)); 918ddde725dSArmin Le Grand } 919ddde725dSArmin Le Grand } 920ddde725dSArmin Le Grand 921ddde725dSArmin Le Grand void SvgStyleAttributes::add_markers( 922ddde725dSArmin Le Grand const basegfx::B2DPolyPolygon& rPath, 923ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence& rTarget) const 924ddde725dSArmin Le Grand { 925ddde725dSArmin Le Grand // try to access linked markers 926ddde725dSArmin Le Grand const SvgMarkerNode* pStart = accessMarkerStartXLink(); 927ddde725dSArmin Le Grand const SvgMarkerNode* pMid = accessMarkerMidXLink(); 928ddde725dSArmin Le Grand const SvgMarkerNode* pEnd = accessMarkerEndXLink(); 929ddde725dSArmin Le Grand 930ddde725dSArmin Le Grand if(pStart || pMid || pEnd) 931ddde725dSArmin Le Grand { 932ddde725dSArmin Le Grand const sal_uInt32 nCount(rPath.count()); 933ddde725dSArmin Le Grand 934ddde725dSArmin Le Grand for (sal_uInt32 a(0); a < nCount; a++) 935ddde725dSArmin Le Grand { 936ddde725dSArmin Le Grand const basegfx::B2DPolygon aCandidate(rPath.getB2DPolygon(a)); 937ddde725dSArmin Le Grand const sal_uInt32 nPointCount(aCandidate.count()); 938ddde725dSArmin Le Grand 939ddde725dSArmin Le Grand if(nPointCount) 940ddde725dSArmin Le Grand { 941ddde725dSArmin Le Grand const sal_uInt32 nMarkerCount(aCandidate.isClosed() ? nPointCount + 1 : nPointCount); 942ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence aMarkerPrimitives; 943ddde725dSArmin Le Grand basegfx::B2DHomMatrix aMarkerTransform; 944ddde725dSArmin Le Grand basegfx::B2DRange aClipRange; 945ddde725dSArmin Le Grand const SvgMarkerNode* pPrepared = 0; 946ddde725dSArmin Le Grand 947ddde725dSArmin Le Grand if(pStart) 948ddde725dSArmin Le Grand { 949ddde725dSArmin Le Grand if(prepare_singleMarker(aMarkerPrimitives, aMarkerTransform, aClipRange, *pStart)) 950ddde725dSArmin Le Grand { 951ddde725dSArmin Le Grand pPrepared = pStart; 952ddde725dSArmin Le Grand add_singleMarker(rTarget, aMarkerPrimitives, aMarkerTransform, aClipRange, *pPrepared, aCandidate, 0); 953ddde725dSArmin Le Grand } 954ddde725dSArmin Le Grand } 955ddde725dSArmin Le Grand 956ddde725dSArmin Le Grand if(pMid && nMarkerCount > 2) 957ddde725dSArmin Le Grand { 958ddde725dSArmin Le Grand if(pMid == pPrepared || prepare_singleMarker(aMarkerPrimitives, aMarkerTransform, aClipRange, *pMid)) 959ddde725dSArmin Le Grand { 960ddde725dSArmin Le Grand pPrepared = pMid; 961ddde725dSArmin Le Grand 962e2bf1e9dSArmin Le Grand for(sal_uInt32 b(1); b < nMarkerCount - 1; b++) 963ddde725dSArmin Le Grand { 964e2bf1e9dSArmin Le Grand add_singleMarker(rTarget, aMarkerPrimitives, aMarkerTransform, aClipRange, *pPrepared, aCandidate, b); 965ddde725dSArmin Le Grand } 966ddde725dSArmin Le Grand } 967ddde725dSArmin Le Grand } 968ddde725dSArmin Le Grand 969ddde725dSArmin Le Grand if(pEnd) 970ddde725dSArmin Le Grand { 971ddde725dSArmin Le Grand if(pEnd == pPrepared || prepare_singleMarker(aMarkerPrimitives, aMarkerTransform, aClipRange, *pEnd)) 972ddde725dSArmin Le Grand { 973ddde725dSArmin Le Grand pPrepared = pEnd; 974ddde725dSArmin Le Grand add_singleMarker(rTarget, aMarkerPrimitives, aMarkerTransform, aClipRange, *pPrepared, aCandidate, nMarkerCount - 1); 975ddde725dSArmin Le Grand } 976ddde725dSArmin Le Grand } 977ddde725dSArmin Le Grand } 978ddde725dSArmin Le Grand } 979ddde725dSArmin Le Grand } 980ddde725dSArmin Le Grand } 981ddde725dSArmin Le Grand 982ddde725dSArmin Le Grand void SvgStyleAttributes::add_path( 983ddde725dSArmin Le Grand const basegfx::B2DPolyPolygon& rPath, 984ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence& rTarget) const 985ddde725dSArmin Le Grand { 986ddde725dSArmin Le Grand const bool bIsLine(1 == rPath.count() 987ddde725dSArmin Le Grand && !rPath.areControlPointsUsed() 988ddde725dSArmin Le Grand && 2 == rPath.getB2DPolygon(0).count()); 989ddde725dSArmin Le Grand 990ddde725dSArmin Le Grand if(!rPath.count()) 991ddde725dSArmin Le Grand { 992ddde725dSArmin Le Grand return; 993ddde725dSArmin Le Grand } 994ddde725dSArmin Le Grand 995ddde725dSArmin Le Grand const basegfx::B2DRange aGeoRange(rPath.getB2DRange()); 996ddde725dSArmin Le Grand 997ddde725dSArmin Le Grand if(aGeoRange.isEmpty()) 998ddde725dSArmin Le Grand { 999ddde725dSArmin Le Grand return; 1000ddde725dSArmin Le Grand } 1001ddde725dSArmin Le Grand 1002ddde725dSArmin Le Grand if(!bIsLine && // not for lines 1003ddde725dSArmin Le Grand (basegfx::fTools::equalZero(aGeoRange.getWidth()) 1004ddde725dSArmin Le Grand || basegfx::fTools::equalZero(aGeoRange.getHeight()))) 1005ddde725dSArmin Le Grand { 1006ddde725dSArmin Le Grand return; 1007ddde725dSArmin Le Grand } 1008ddde725dSArmin Le Grand 1009ddde725dSArmin Le Grand const double fOpacity(getOpacity().getNumber()); 1010ddde725dSArmin Le Grand 1011ddde725dSArmin Le Grand if(basegfx::fTools::equalZero(fOpacity)) 1012ddde725dSArmin Le Grand { 1013ddde725dSArmin Le Grand return; 1014ddde725dSArmin Le Grand } 1015ddde725dSArmin Le Grand 1016ddde725dSArmin Le Grand if(!bIsLine) 1017ddde725dSArmin Le Grand { 1018ddde725dSArmin Le Grand basegfx::B2DPolyPolygon aPath(rPath); 1019ddde725dSArmin Le Grand const bool bNeedToCheckClipRule(SVGTokenPath == mrOwner.getType() || SVGTokenPolygon == mrOwner.getType()); 1020ddde725dSArmin Le Grand const bool bClipPathIsNonzero(!bIsLine && bNeedToCheckClipRule && mbIsClipPathContent && mbClipRule); 1021ddde725dSArmin Le Grand const bool bFillRuleIsNonzero(!bIsLine && bNeedToCheckClipRule && !mbIsClipPathContent && getFillRule()); 1022ddde725dSArmin Le Grand 1023ddde725dSArmin Le Grand if(bClipPathIsNonzero || bFillRuleIsNonzero) 1024ddde725dSArmin Le Grand { 1025ddde725dSArmin Le Grand // nonzero is wanted, solve geometrically (see description on basegfx) 1026ddde725dSArmin Le Grand aPath = basegfx::tools::createNonzeroConform(aPath); 1027ddde725dSArmin Le Grand } 1028ddde725dSArmin Le Grand 1029ddde725dSArmin Le Grand add_fill(aPath, rTarget, aGeoRange); 1030ddde725dSArmin Le Grand } 1031ddde725dSArmin Le Grand 1032ddde725dSArmin Le Grand add_stroke(rPath, rTarget, aGeoRange); 1033ddde725dSArmin Le Grand 1034ddde725dSArmin Le Grand // Svg supports markers for path, polygon, polyline and line 1035ddde725dSArmin Le Grand if(SVGTokenPath == mrOwner.getType() || // path 1036ddde725dSArmin Le Grand SVGTokenPolygon == mrOwner.getType() || // polygon, polyline 1037ddde725dSArmin Le Grand SVGTokenLine == mrOwner.getType()) // line 1038ddde725dSArmin Le Grand { 1039ddde725dSArmin Le Grand // try to add markers 1040ddde725dSArmin Le Grand add_markers(rPath, rTarget); 1041ddde725dSArmin Le Grand } 1042ddde725dSArmin Le Grand } 1043ddde725dSArmin Le Grand 1044ddde725dSArmin Le Grand void SvgStyleAttributes::add_postProcess( 1045ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence& rTarget, 1046ddde725dSArmin Le Grand const drawinglayer::primitive2d::Primitive2DSequence& rSource, 1047ddde725dSArmin Le Grand const basegfx::B2DHomMatrix* pTransform) const 1048ddde725dSArmin Le Grand { 1049ddde725dSArmin Le Grand if(rSource.hasElements()) 1050ddde725dSArmin Le Grand { 1051ddde725dSArmin Le Grand const double fOpacity(getOpacity().getNumber()); 1052ddde725dSArmin Le Grand 1053ddde725dSArmin Le Grand if(basegfx::fTools::equalZero(fOpacity)) 1054ddde725dSArmin Le Grand { 1055ddde725dSArmin Le Grand return; 1056ddde725dSArmin Le Grand } 1057ddde725dSArmin Le Grand 1058ddde725dSArmin Le Grand drawinglayer::primitive2d::Primitive2DSequence aSource(rSource); 1059ddde725dSArmin Le Grand 1060ddde725dSArmin Le Grand if(basegfx::fTools::less(fOpacity, 1.0)) 1061ddde725dSArmin Le Grand { 1062ddde725dSArmin Le Grand // embed in UnifiedTransparencePrimitive2D 1063ddde725dSArmin Le Grand const drawinglayer::primitive2d::Primitive2DReference xRef( 1064ddde725dSArmin Le Grand new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D( 1065ddde725dSArmin Le Grand aSource, 1066ddde725dSArmin Le Grand 1.0 - fOpacity)); 1067ddde725dSArmin Le Grand 1068ddde725dSArmin Le Grand aSource = drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1); 1069ddde725dSArmin Le Grand } 1070ddde725dSArmin Le Grand 1071ddde725dSArmin Le Grand if(getClipPathXLink().getLength()) 1072ddde725dSArmin Le Grand { 1073ddde725dSArmin Le Grand // try to access linked ClipPath 1074ddde725dSArmin Le Grand const SvgClipPathNode* mpClip = dynamic_cast< const SvgClipPathNode* >(mrOwner.getDocument().findSvgNodeById(getClipPathXLink())); 1075ddde725dSArmin Le Grand 1076ddde725dSArmin Le Grand if(mpClip) 1077ddde725dSArmin Le Grand { 1078ddde725dSArmin Le Grand mpClip->apply(aSource); 1079ddde725dSArmin Le Grand } 1080ddde725dSArmin Le Grand } 1081ddde725dSArmin Le Grand 1082ddde725dSArmin Le Grand if(aSource.hasElements()) // test again, applied clipPath may have lead to empty geometry 1083ddde725dSArmin Le Grand { 1084ddde725dSArmin Le Grand if(getMaskXLink().getLength()) 1085ddde725dSArmin Le Grand { 1086ddde725dSArmin Le Grand // try to access linked Mask 1087ddde725dSArmin Le Grand const SvgMaskNode* mpMask = dynamic_cast< const SvgMaskNode* >(mrOwner.getDocument().findSvgNodeById(getMaskXLink())); 1088ddde725dSArmin Le Grand 1089ddde725dSArmin Le Grand if(mpMask) 1090ddde725dSArmin Le Grand { 1091ddde725dSArmin Le Grand mpMask->apply(aSource); 1092ddde725dSArmin Le Grand } 1093ddde725dSArmin Le Grand } 1094ddde725dSArmin Le Grand 1095ddde725dSArmin Le Grand if(aSource.hasElements()) // test again, applied mask may have lead to empty geometry 1096ddde725dSArmin Le Grand { 1097ddde725dSArmin Le Grand if(pTransform) 1098ddde725dSArmin Le Grand { 1099ddde725dSArmin Le Grand // create embedding group element with transformation 1100ddde725dSArmin Le Grand const drawinglayer::primitive2d::Primitive2DReference xRef( 1101ddde725dSArmin Le Grand new drawinglayer::primitive2d::TransformPrimitive2D( 1102ddde725dSArmin Le Grand *pTransform, 1103ddde725dSArmin Le Grand aSource)); 1104ddde725dSArmin Le Grand 1105ddde725dSArmin Le Grand aSource = drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1); 1106ddde725dSArmin Le Grand } 1107ddde725dSArmin Le Grand 1108ddde725dSArmin Le Grand // append to current target 1109ddde725dSArmin Le Grand drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aSource); 1110ddde725dSArmin Le Grand } 1111ddde725dSArmin Le Grand } 1112ddde725dSArmin Le Grand } 1113ddde725dSArmin Le Grand } 1114ddde725dSArmin Le Grand 1115ddde725dSArmin Le Grand SvgStyleAttributes::SvgStyleAttributes(SvgNode& rOwner) 1116ddde725dSArmin Le Grand : mrOwner(rOwner), 1117ddde725dSArmin Le Grand mpCssStyleParent(0), 1118ddde725dSArmin Le Grand maFill(), 1119ddde725dSArmin Le Grand maStroke(), 1120ddde725dSArmin Le Grand maStopColor(basegfx::BColor(0.0, 0.0, 0.0), true), 1121ddde725dSArmin Le Grand maStrokeWidth(), 1122ddde725dSArmin Le Grand maStopOpacity(), 1123ddde725dSArmin Le Grand mpSvgGradientNodeFill(0), 1124ddde725dSArmin Le Grand mpSvgGradientNodeStroke(0), 1125ddde725dSArmin Le Grand mpSvgPatternNodeFill(0), 1126ddde725dSArmin Le Grand mpSvgPatternNodeStroke(0), 1127ddde725dSArmin Le Grand maFillOpacity(), 1128ddde725dSArmin Le Grand maStrokeDasharray(), 1129ddde725dSArmin Le Grand maStrokeDashOffset(), 1130ddde725dSArmin Le Grand maStrokeLinecap(StrokeLinecap_notset), 1131ddde725dSArmin Le Grand maStrokeLinejoin(StrokeLinejoin_notset), 1132ddde725dSArmin Le Grand maStrokeMiterLimit(), 1133ddde725dSArmin Le Grand maStrokeOpacity(), 1134ddde725dSArmin Le Grand maFontFamily(), 1135ddde725dSArmin Le Grand maFontSize(), 1136ddde725dSArmin Le Grand maFontStretch(FontStretch_notset), 1137ddde725dSArmin Le Grand maFontStyle(FontStyle_notset), 1138ddde725dSArmin Le Grand maFontVariant(FontVariant_notset), 1139ddde725dSArmin Le Grand maFontWeight(FontWeight_notset), 1140ddde725dSArmin Le Grand maTextAlign(TextAlign_notset), 1141ddde725dSArmin Le Grand maTextDecoration(TextDecoration_notset), 1142ddde725dSArmin Le Grand maTextAnchor(TextAnchor_notset), 1143ddde725dSArmin Le Grand maColor(), 1144ddde725dSArmin Le Grand maOpacity(1.0), 1145ddde725dSArmin Le Grand maClipPathXLink(), 1146ddde725dSArmin Le Grand maMaskXLink(), 1147ddde725dSArmin Le Grand maMarkerStartXLink(), 1148ddde725dSArmin Le Grand mpMarkerStartXLink(0), 1149ddde725dSArmin Le Grand maMarkerMidXLink(), 1150ddde725dSArmin Le Grand mpMarkerMidXLink(0), 1151ddde725dSArmin Le Grand maMarkerEndXLink(), 1152ddde725dSArmin Le Grand mpMarkerEndXLink(0), 1153ddde725dSArmin Le Grand maFillRule(true), 1154ddde725dSArmin Le Grand maFillRuleSet(false), 1155ddde725dSArmin Le Grand mbIsClipPathContent(SVGTokenClipPathNode == mrOwner.getType()), 1156ddde725dSArmin Le Grand mbClipRule(true) 1157ddde725dSArmin Le Grand { 1158ddde725dSArmin Le Grand if(!mbIsClipPathContent) 1159ddde725dSArmin Le Grand { 1160ddde725dSArmin Le Grand const SvgStyleAttributes* pParentStyle = getParentStyle(); 1161ddde725dSArmin Le Grand 1162ddde725dSArmin Le Grand if(pParentStyle) 1163ddde725dSArmin Le Grand { 1164ddde725dSArmin Le Grand mbIsClipPathContent = pParentStyle->mbIsClipPathContent; 1165ddde725dSArmin Le Grand } 1166ddde725dSArmin Le Grand } 1167ddde725dSArmin Le Grand } 1168ddde725dSArmin Le Grand 1169ddde725dSArmin Le Grand SvgStyleAttributes::~SvgStyleAttributes() 1170ddde725dSArmin Le Grand { 1171ddde725dSArmin Le Grand } 1172ddde725dSArmin Le Grand 1173e2bf1e9dSArmin Le Grand void SvgStyleAttributes::parseStyleAttribute(const rtl::OUString& /*rTokenName*/, SVGToken aSVGToken, const rtl::OUString& aContent) 1174ddde725dSArmin Le Grand { 1175ddde725dSArmin Le Grand switch(aSVGToken) 1176ddde725dSArmin Le Grand { 1177ddde725dSArmin Le Grand case SVGTokenFill: 1178ddde725dSArmin Le Grand { 1179ddde725dSArmin Le Grand SvgPaint aSvgPaint; 1180ddde725dSArmin Le Grand rtl::OUString aURL; 1181ddde725dSArmin Le Grand 1182ddde725dSArmin Le Grand if(readSvgPaint(aContent, aSvgPaint, aURL)) 1183ddde725dSArmin Le Grand { 1184ddde725dSArmin Le Grand setFill(aSvgPaint); 1185ddde725dSArmin Le Grand } 1186ddde725dSArmin Le Grand else if(aURL.getLength()) 1187ddde725dSArmin Le Grand { 1188ddde725dSArmin Le Grand const SvgNode* pNode = mrOwner.getDocument().findSvgNodeById(aURL); 1189ddde725dSArmin Le Grand 1190ddde725dSArmin Le Grand if(pNode) 1191ddde725dSArmin Le Grand { 1192ddde725dSArmin Le Grand if(SVGTokenLinearGradient == pNode->getType() || SVGTokenRadialGradient == pNode->getType()) 1193ddde725dSArmin Le Grand { 1194ddde725dSArmin Le Grand setSvgGradientNodeFill(static_cast< const SvgGradientNode* >(pNode)); 1195ddde725dSArmin Le Grand } 1196ddde725dSArmin Le Grand else if(SVGTokenPattern == pNode->getType()) 1197ddde725dSArmin Le Grand { 1198ddde725dSArmin Le Grand setSvgPatternNodeFill(static_cast< const SvgPatternNode* >(pNode)); 1199ddde725dSArmin Le Grand } 1200ddde725dSArmin Le Grand } 1201ddde725dSArmin Le Grand } 1202ddde725dSArmin Le Grand break; 1203ddde725dSArmin Le Grand } 1204ddde725dSArmin Le Grand case SVGTokenFillOpacity: 1205ddde725dSArmin Le Grand { 1206ddde725dSArmin Le Grand SvgNumber aNum; 1207ddde725dSArmin Le Grand 1208ddde725dSArmin Le Grand if(readSingleNumber(aContent, aNum)) 1209ddde725dSArmin Le Grand { 1210ddde725dSArmin Le Grand if(aNum.isPositive()) 1211ddde725dSArmin Le Grand { 1212ddde725dSArmin Le Grand setFillOpacity(aNum); 1213ddde725dSArmin Le Grand } 1214ddde725dSArmin Le Grand } 1215ddde725dSArmin Le Grand break; 1216ddde725dSArmin Le Grand } 1217ddde725dSArmin Le Grand case SVGTokenFillRule: 1218ddde725dSArmin Le Grand { 1219ddde725dSArmin Le Grand if(aContent.getLength()) 1220ddde725dSArmin Le Grand { 1221ddde725dSArmin Le Grand if(aContent.match(commonStrings::aStrNonzero)) 1222ddde725dSArmin Le Grand { 1223ddde725dSArmin Le Grand maFillRule = true; 1224ddde725dSArmin Le Grand maFillRuleSet = true; 1225ddde725dSArmin Le Grand } 1226ddde725dSArmin Le Grand else if(aContent.match(commonStrings::aStrEvenOdd)) 1227ddde725dSArmin Le Grand { 1228ddde725dSArmin Le Grand maFillRule = false; 1229ddde725dSArmin Le Grand maFillRuleSet = true; 1230ddde725dSArmin Le Grand } 1231ddde725dSArmin Le Grand } 1232ddde725dSArmin Le Grand break; 1233ddde725dSArmin Le Grand } 1234ddde725dSArmin Le Grand case SVGTokenStroke: 1235ddde725dSArmin Le Grand { 1236ddde725dSArmin Le Grand SvgPaint aSvgPaint; 1237ddde725dSArmin Le Grand rtl::OUString aURL; 1238ddde725dSArmin Le Grand 1239ddde725dSArmin Le Grand if(readSvgPaint(aContent, aSvgPaint, aURL)) 1240ddde725dSArmin Le Grand { 1241ddde725dSArmin Le Grand setStroke(aSvgPaint); 1242ddde725dSArmin Le Grand } 1243ddde725dSArmin Le Grand else if(aURL.getLength()) 1244ddde725dSArmin Le Grand { 1245ddde725dSArmin Le Grand const SvgNode* pNode = mrOwner.getDocument().findSvgNodeById(aURL); 1246ddde725dSArmin Le Grand 1247ddde725dSArmin Le Grand if(pNode) 1248ddde725dSArmin Le Grand { 1249ddde725dSArmin Le Grand if(SVGTokenLinearGradient == pNode->getType() || SVGTokenRadialGradient == pNode->getType()) 1250ddde725dSArmin Le Grand { 1251ddde725dSArmin Le Grand setSvgGradientNodeStroke(static_cast< const SvgGradientNode* >(pNode)); 1252ddde725dSArmin Le Grand } 1253ddde725dSArmin Le Grand else if(SVGTokenPattern == pNode->getType()) 1254ddde725dSArmin Le Grand { 1255ddde725dSArmin Le Grand setSvgPatternNodeStroke(static_cast< const SvgPatternNode* >(pNode)); 1256ddde725dSArmin Le Grand } 1257ddde725dSArmin Le Grand } 1258ddde725dSArmin Le Grand } 1259ddde725dSArmin Le Grand break; 1260ddde725dSArmin Le Grand } 1261ddde725dSArmin Le Grand case SVGTokenStrokeDasharray: 1262ddde725dSArmin Le Grand { 1263ddde725dSArmin Le Grand if(aContent.getLength()) 1264ddde725dSArmin Le Grand { 1265ddde725dSArmin Le Grand SvgNumberVector aVector; 1266ddde725dSArmin Le Grand 1267ddde725dSArmin Le Grand if(readSvgNumberVector(aContent, aVector)) 1268ddde725dSArmin Le Grand { 1269ddde725dSArmin Le Grand setStrokeDasharray(aVector); 1270ddde725dSArmin Le Grand } 1271ddde725dSArmin Le Grand } 1272ddde725dSArmin Le Grand break; 1273ddde725dSArmin Le Grand } 1274ddde725dSArmin Le Grand case SVGTokenStrokeDashoffset: 1275ddde725dSArmin Le Grand { 1276ddde725dSArmin Le Grand SvgNumber aNum; 1277ddde725dSArmin Le Grand 1278ddde725dSArmin Le Grand if(readSingleNumber(aContent, aNum)) 1279ddde725dSArmin Le Grand { 1280ddde725dSArmin Le Grand if(aNum.isPositive()) 1281ddde725dSArmin Le Grand { 1282ddde725dSArmin Le Grand setStrokeDashOffset(aNum); 1283ddde725dSArmin Le Grand } 1284ddde725dSArmin Le Grand } 1285ddde725dSArmin Le Grand break; 1286ddde725dSArmin Le Grand } 1287ddde725dSArmin Le Grand case SVGTokenStrokeLinecap: 1288ddde725dSArmin Le Grand { 1289ddde725dSArmin Le Grand if(aContent.getLength()) 1290ddde725dSArmin Le Grand { 1291ddde725dSArmin Le Grand static rtl::OUString aStrButt(rtl::OUString::createFromAscii("butt")); 1292ddde725dSArmin Le Grand static rtl::OUString aStrRound(rtl::OUString::createFromAscii("round")); 1293ddde725dSArmin Le Grand static rtl::OUString aStrSquare(rtl::OUString::createFromAscii("square")); 1294ddde725dSArmin Le Grand 1295ddde725dSArmin Le Grand if(aContent.match(aStrButt)) 1296ddde725dSArmin Le Grand { 1297ddde725dSArmin Le Grand setStrokeLinecap(StrokeLinecap_butt); 1298ddde725dSArmin Le Grand } 1299ddde725dSArmin Le Grand else if(aContent.match(aStrRound)) 1300ddde725dSArmin Le Grand { 1301ddde725dSArmin Le Grand setStrokeLinecap(StrokeLinecap_round); 1302ddde725dSArmin Le Grand } 1303ddde725dSArmin Le Grand else if(aContent.match(aStrSquare)) 1304ddde725dSArmin Le Grand { 1305ddde725dSArmin Le Grand setStrokeLinecap(StrokeLinecap_square); 1306ddde725dSArmin Le Grand } 1307ddde725dSArmin Le Grand } 1308ddde725dSArmin Le Grand break; 1309ddde725dSArmin Le Grand } 1310ddde725dSArmin Le Grand case SVGTokenStrokeLinejoin: 1311ddde725dSArmin Le Grand { 1312ddde725dSArmin Le Grand if(aContent.getLength()) 1313ddde725dSArmin Le Grand { 1314ddde725dSArmin Le Grand static rtl::OUString aStrMiter(rtl::OUString::createFromAscii("miter")); 1315ddde725dSArmin Le Grand static rtl::OUString aStrRound(rtl::OUString::createFromAscii("round")); 1316ddde725dSArmin Le Grand static rtl::OUString aStrBevel(rtl::OUString::createFromAscii("bevel")); 1317ddde725dSArmin Le Grand 1318ddde725dSArmin Le Grand if(aContent.match(aStrMiter)) 1319ddde725dSArmin Le Grand { 1320ddde725dSArmin Le Grand setStrokeLinejoin(StrokeLinejoin_miter); 1321ddde725dSArmin Le Grand } 1322ddde725dSArmin Le Grand else if(aContent.match(aStrRound)) 1323ddde725dSArmin Le Grand { 1324ddde725dSArmin Le Grand setStrokeLinejoin(StrokeLinejoin_round); 1325ddde725dSArmin Le Grand } 1326ddde725dSArmin Le Grand else if(aContent.match(aStrBevel)) 1327ddde725dSArmin Le Grand { 1328ddde725dSArmin Le Grand setStrokeLinejoin(StrokeLinejoin_bevel); 1329ddde725dSArmin Le Grand } 1330ddde725dSArmin Le Grand } 1331ddde725dSArmin Le Grand break; 1332ddde725dSArmin Le Grand } 1333ddde725dSArmin Le Grand case SVGTokenStrokeMiterlimit: 1334ddde725dSArmin Le Grand { 1335ddde725dSArmin Le Grand SvgNumber aNum; 1336ddde725dSArmin Le Grand 1337ddde725dSArmin Le Grand if(readSingleNumber(aContent, aNum)) 1338ddde725dSArmin Le Grand { 1339ddde725dSArmin Le Grand if(aNum.isPositive()) 1340ddde725dSArmin Le Grand { 1341ddde725dSArmin Le Grand setStrokeMiterLimit(aNum); 1342ddde725dSArmin Le Grand } 1343ddde725dSArmin Le Grand } 1344ddde725dSArmin Le Grand break; 1345ddde725dSArmin Le Grand } 1346ddde725dSArmin Le Grand case SVGTokenStrokeOpacity: 1347ddde725dSArmin Le Grand { 1348ddde725dSArmin Le Grand SvgNumber aNum; 1349ddde725dSArmin Le Grand 1350ddde725dSArmin Le Grand if(readSingleNumber(aContent, aNum)) 1351ddde725dSArmin Le Grand { 1352ddde725dSArmin Le Grand if(aNum.isPositive()) 1353ddde725dSArmin Le Grand { 1354ddde725dSArmin Le Grand setStrokeOpacity(aNum); 1355ddde725dSArmin Le Grand } 1356ddde725dSArmin Le Grand } 1357ddde725dSArmin Le Grand break; 1358ddde725dSArmin Le Grand } 1359ddde725dSArmin Le Grand case SVGTokenStrokeWidth: 1360ddde725dSArmin Le Grand { 1361ddde725dSArmin Le Grand SvgNumber aNum; 1362ddde725dSArmin Le Grand 1363ddde725dSArmin Le Grand if(readSingleNumber(aContent, aNum)) 1364ddde725dSArmin Le Grand { 1365ddde725dSArmin Le Grand if(aNum.isPositive()) 1366ddde725dSArmin Le Grand { 1367ddde725dSArmin Le Grand setStrokeWidth(aNum); 1368ddde725dSArmin Le Grand } 1369ddde725dSArmin Le Grand } 1370ddde725dSArmin Le Grand break; 1371ddde725dSArmin Le Grand } 1372ddde725dSArmin Le Grand case SVGTokenStopColor: 1373ddde725dSArmin Le Grand { 1374ddde725dSArmin Le Grand SvgPaint aSvgPaint; 1375ddde725dSArmin Le Grand rtl::OUString aURL; 1376ddde725dSArmin Le Grand 1377ddde725dSArmin Le Grand if(readSvgPaint(aContent, aSvgPaint, aURL)) 1378ddde725dSArmin Le Grand { 1379ddde725dSArmin Le Grand setStopColor(aSvgPaint); 1380ddde725dSArmin Le Grand } 1381ddde725dSArmin Le Grand break; 1382ddde725dSArmin Le Grand } 1383ddde725dSArmin Le Grand case SVGTokenStopOpacity: 1384ddde725dSArmin Le Grand { 1385ddde725dSArmin Le Grand SvgNumber aNum; 1386ddde725dSArmin Le Grand 1387ddde725dSArmin Le Grand if(readSingleNumber(aContent, aNum)) 1388ddde725dSArmin Le Grand { 1389ddde725dSArmin Le Grand if(aNum.isPositive()) 1390ddde725dSArmin Le Grand { 1391ddde725dSArmin Le Grand setStopOpacity(aNum); 1392ddde725dSArmin Le Grand } 1393ddde725dSArmin Le Grand } 1394ddde725dSArmin Le Grand break; 1395ddde725dSArmin Le Grand } 1396ddde725dSArmin Le Grand case SVGTokenFont: 1397ddde725dSArmin Le Grand { 1398ddde725dSArmin Le Grand break; 1399ddde725dSArmin Le Grand } 1400ddde725dSArmin Le Grand case SVGTokenFontFamily: 1401ddde725dSArmin Le Grand { 1402ddde725dSArmin Le Grand SvgStringVector aSvgStringVector; 1403ddde725dSArmin Le Grand 1404ddde725dSArmin Le Grand if(readSvgStringVector(aContent, aSvgStringVector)) 1405ddde725dSArmin Le Grand { 1406ddde725dSArmin Le Grand setFontFamily(aSvgStringVector); 1407ddde725dSArmin Le Grand } 1408ddde725dSArmin Le Grand break; 1409ddde725dSArmin Le Grand } 1410ddde725dSArmin Le Grand case SVGTokenFontSize: 1411ddde725dSArmin Le Grand { 1412ddde725dSArmin Le Grand SvgNumber aNum; 1413ddde725dSArmin Le Grand 1414ddde725dSArmin Le Grand if(readSingleNumber(aContent, aNum)) 1415ddde725dSArmin Le Grand { 1416ddde725dSArmin Le Grand setFontSize(aNum); 1417ddde725dSArmin Le Grand } 1418ddde725dSArmin Le Grand break; 1419ddde725dSArmin Le Grand } 1420ddde725dSArmin Le Grand case SVGTokenFontSizeAdjust: 1421ddde725dSArmin Le Grand { 1422ddde725dSArmin Le Grand break; 1423ddde725dSArmin Le Grand } 1424ddde725dSArmin Le Grand case SVGTokenFontStretch: 1425ddde725dSArmin Le Grand { 1426ddde725dSArmin Le Grand if(aContent.getLength()) 1427ddde725dSArmin Le Grand { 1428ddde725dSArmin Le Grand static rtl::OUString aStrNormal(rtl::OUString::createFromAscii("normal")); 1429ddde725dSArmin Le Grand static rtl::OUString aStrWider(rtl::OUString::createFromAscii("wider")); 1430ddde725dSArmin Le Grand static rtl::OUString aStrNarrower(rtl::OUString::createFromAscii("narrower")); 1431ddde725dSArmin Le Grand static rtl::OUString aStrUltra_condensed(rtl::OUString::createFromAscii("ultra-condensed")); 1432ddde725dSArmin Le Grand static rtl::OUString aStrExtra_condensed(rtl::OUString::createFromAscii("extra-condensed")); 1433ddde725dSArmin Le Grand static rtl::OUString aStrCondensed(rtl::OUString::createFromAscii("condensed")); 1434ddde725dSArmin Le Grand static rtl::OUString aStrSemi_condensed(rtl::OUString::createFromAscii("semi-condensed")); 1435ddde725dSArmin Le Grand static rtl::OUString aStrSemi_expanded(rtl::OUString::createFromAscii("semi-expanded")); 1436ddde725dSArmin Le Grand static rtl::OUString aStrExpanded(rtl::OUString::createFromAscii("expanded")); 1437ddde725dSArmin Le Grand static rtl::OUString aStrExtra_expanded(rtl::OUString::createFromAscii("extra-expanded")); 1438ddde725dSArmin Le Grand static rtl::OUString aStrUltra_expanded(rtl::OUString::createFromAscii("ultra-expanded")); 1439ddde725dSArmin Le Grand 1440ddde725dSArmin Le Grand if(aContent.match(aStrNormal)) 1441ddde725dSArmin Le Grand { 1442ddde725dSArmin Le Grand setFontStretch(FontStretch_normal); 1443ddde725dSArmin Le Grand } 1444ddde725dSArmin Le Grand else if(aContent.match(aStrWider)) 1445ddde725dSArmin Le Grand { 1446ddde725dSArmin Le Grand setFontStretch(FontStretch_wider); 1447ddde725dSArmin Le Grand } 1448ddde725dSArmin Le Grand else if(aContent.match(aStrNarrower)) 1449ddde725dSArmin Le Grand { 1450ddde725dSArmin Le Grand setFontStretch(FontStretch_narrower); 1451ddde725dSArmin Le Grand } 1452ddde725dSArmin Le Grand else if(aContent.match(aStrUltra_condensed)) 1453ddde725dSArmin Le Grand { 1454ddde725dSArmin Le Grand setFontStretch(FontStretch_ultra_condensed); 1455ddde725dSArmin Le Grand } 1456ddde725dSArmin Le Grand else if(aContent.match(aStrExtra_condensed)) 1457ddde725dSArmin Le Grand { 1458ddde725dSArmin Le Grand setFontStretch(FontStretch_extra_condensed); 1459ddde725dSArmin Le Grand } 1460ddde725dSArmin Le Grand else if(aContent.match(aStrCondensed)) 1461ddde725dSArmin Le Grand { 1462ddde725dSArmin Le Grand setFontStretch(FontStretch_condensed); 1463ddde725dSArmin Le Grand } 1464ddde725dSArmin Le Grand else if(aContent.match(aStrSemi_condensed)) 1465ddde725dSArmin Le Grand { 1466ddde725dSArmin Le Grand setFontStretch(FontStretch_semi_condensed); 1467ddde725dSArmin Le Grand } 1468ddde725dSArmin Le Grand else if(aContent.match(aStrSemi_expanded)) 1469ddde725dSArmin Le Grand { 1470ddde725dSArmin Le Grand setFontStretch(FontStretch_semi_expanded); 1471ddde725dSArmin Le Grand } 1472ddde725dSArmin Le Grand else if(aContent.match(aStrExpanded)) 1473ddde725dSArmin Le Grand { 1474ddde725dSArmin Le Grand setFontStretch(FontStretch_expanded); 1475ddde725dSArmin Le Grand } 1476ddde725dSArmin Le Grand else if(aContent.match(aStrExtra_expanded)) 1477ddde725dSArmin Le Grand { 1478ddde725dSArmin Le Grand setFontStretch(FontStretch_extra_expanded); 1479ddde725dSArmin Le Grand } 1480ddde725dSArmin Le Grand else if(aContent.match(aStrUltra_expanded)) 1481ddde725dSArmin Le Grand { 1482ddde725dSArmin Le Grand setFontStretch(FontStretch_ultra_expanded); 1483ddde725dSArmin Le Grand } 1484ddde725dSArmin Le Grand } 1485ddde725dSArmin Le Grand break; 1486ddde725dSArmin Le Grand } 1487ddde725dSArmin Le Grand case SVGTokenFontStyle: 1488ddde725dSArmin Le Grand { 1489ddde725dSArmin Le Grand if(aContent.getLength()) 1490ddde725dSArmin Le Grand { 1491ddde725dSArmin Le Grand static rtl::OUString aStrNormal(rtl::OUString::createFromAscii("normal")); 1492ddde725dSArmin Le Grand static rtl::OUString aStrItalic(rtl::OUString::createFromAscii("italic")); 1493ddde725dSArmin Le Grand static rtl::OUString aStrOblique(rtl::OUString::createFromAscii("oblique")); 1494ddde725dSArmin Le Grand 1495ddde725dSArmin Le Grand if(aContent.match(aStrNormal)) 1496ddde725dSArmin Le Grand { 1497ddde725dSArmin Le Grand setFontStyle(FontStyle_normal); 1498ddde725dSArmin Le Grand } 1499ddde725dSArmin Le Grand else if(aContent.match(aStrItalic)) 1500ddde725dSArmin Le Grand { 1501ddde725dSArmin Le Grand setFontStyle(FontStyle_italic); 1502ddde725dSArmin Le Grand } 1503ddde725dSArmin Le Grand else if(aContent.match(aStrOblique)) 1504ddde725dSArmin Le Grand { 1505ddde725dSArmin Le Grand setFontStyle(FontStyle_oblique); 1506ddde725dSArmin Le Grand } 1507ddde725dSArmin Le Grand } 1508ddde725dSArmin Le Grand break; 1509ddde725dSArmin Le Grand } 1510ddde725dSArmin Le Grand case SVGTokenFontVariant: 1511ddde725dSArmin Le Grand { 1512ddde725dSArmin Le Grand if(aContent.getLength()) 1513ddde725dSArmin Le Grand { 1514ddde725dSArmin Le Grand static rtl::OUString aStrNormal(rtl::OUString::createFromAscii("normal")); 1515ddde725dSArmin Le Grand static rtl::OUString aStrSmallCaps(rtl::OUString::createFromAscii("small-caps")); 1516ddde725dSArmin Le Grand 1517ddde725dSArmin Le Grand if(aContent.match(aStrNormal)) 1518ddde725dSArmin Le Grand { 1519ddde725dSArmin Le Grand setFontVariant(FontVariant_normal); 1520ddde725dSArmin Le Grand } 1521ddde725dSArmin Le Grand else if(aContent.match(aStrSmallCaps)) 1522ddde725dSArmin Le Grand { 1523ddde725dSArmin Le Grand setFontVariant(FontVariant_small_caps); 1524ddde725dSArmin Le Grand } 1525ddde725dSArmin Le Grand } 1526ddde725dSArmin Le Grand break; 1527ddde725dSArmin Le Grand } 1528ddde725dSArmin Le Grand case SVGTokenFontWeight: 1529ddde725dSArmin Le Grand { 1530ddde725dSArmin Le Grand if(aContent.getLength()) 1531ddde725dSArmin Le Grand { 1532ddde725dSArmin Le Grand static rtl::OUString aStrNormal(rtl::OUString::createFromAscii("normal")); 1533ddde725dSArmin Le Grand static rtl::OUString aStrBold(rtl::OUString::createFromAscii("bold")); 1534ddde725dSArmin Le Grand static rtl::OUString aStrBolder(rtl::OUString::createFromAscii("bolder")); 1535ddde725dSArmin Le Grand static rtl::OUString aStrLighter(rtl::OUString::createFromAscii("lighter")); 1536ddde725dSArmin Le Grand static rtl::OUString aStr100(rtl::OUString::createFromAscii("100")); 1537ddde725dSArmin Le Grand static rtl::OUString aStr200(rtl::OUString::createFromAscii("200")); 1538ddde725dSArmin Le Grand static rtl::OUString aStr300(rtl::OUString::createFromAscii("300")); 1539ddde725dSArmin Le Grand static rtl::OUString aStr400(rtl::OUString::createFromAscii("400")); 1540ddde725dSArmin Le Grand static rtl::OUString aStr500(rtl::OUString::createFromAscii("500")); 1541ddde725dSArmin Le Grand static rtl::OUString aStr600(rtl::OUString::createFromAscii("600")); 1542ddde725dSArmin Le Grand static rtl::OUString aStr700(rtl::OUString::createFromAscii("700")); 1543ddde725dSArmin Le Grand static rtl::OUString aStr800(rtl::OUString::createFromAscii("800")); 1544ddde725dSArmin Le Grand static rtl::OUString aStr900(rtl::OUString::createFromAscii("900")); 1545ddde725dSArmin Le Grand 1546ddde725dSArmin Le Grand if(aContent.match(aStr100)) 1547ddde725dSArmin Le Grand { 1548ddde725dSArmin Le Grand setFontWeight(FontWeight_100); 1549ddde725dSArmin Le Grand } 1550ddde725dSArmin Le Grand else if(aContent.match(aStr200)) 1551ddde725dSArmin Le Grand { 1552ddde725dSArmin Le Grand setFontWeight(FontWeight_200); 1553ddde725dSArmin Le Grand } 1554ddde725dSArmin Le Grand else if(aContent.match(aStr300)) 1555ddde725dSArmin Le Grand { 1556ddde725dSArmin Le Grand setFontWeight(FontWeight_300); 1557ddde725dSArmin Le Grand } 1558ddde725dSArmin Le Grand else if(aContent.match(aStr400) || aContent.match(aStrNormal)) 1559ddde725dSArmin Le Grand { 1560ddde725dSArmin Le Grand setFontWeight(FontWeight_400); 1561ddde725dSArmin Le Grand } 1562ddde725dSArmin Le Grand else if(aContent.match(aStr500)) 1563ddde725dSArmin Le Grand { 1564ddde725dSArmin Le Grand setFontWeight(FontWeight_500); 1565ddde725dSArmin Le Grand } 1566ddde725dSArmin Le Grand else if(aContent.match(aStr600)) 1567ddde725dSArmin Le Grand { 1568ddde725dSArmin Le Grand setFontWeight(FontWeight_600); 1569ddde725dSArmin Le Grand } 1570ddde725dSArmin Le Grand else if(aContent.match(aStr700) || aContent.match(aStrBold)) 1571ddde725dSArmin Le Grand { 1572ddde725dSArmin Le Grand setFontWeight(FontWeight_700); 1573ddde725dSArmin Le Grand } 1574ddde725dSArmin Le Grand else if(aContent.match(aStr800)) 1575ddde725dSArmin Le Grand { 1576ddde725dSArmin Le Grand setFontWeight(FontWeight_800); 1577ddde725dSArmin Le Grand } 1578ddde725dSArmin Le Grand else if(aContent.match(aStr900)) 1579ddde725dSArmin Le Grand { 1580ddde725dSArmin Le Grand setFontWeight(FontWeight_900); 1581ddde725dSArmin Le Grand } 1582ddde725dSArmin Le Grand else if(aContent.match(aStrBolder)) 1583ddde725dSArmin Le Grand { 1584ddde725dSArmin Le Grand setFontWeight(FontWeight_bolder); 1585ddde725dSArmin Le Grand } 1586ddde725dSArmin Le Grand else if(aContent.match(aStrLighter)) 1587ddde725dSArmin Le Grand { 1588ddde725dSArmin Le Grand setFontWeight(FontWeight_lighter); 1589ddde725dSArmin Le Grand } 1590ddde725dSArmin Le Grand } 1591ddde725dSArmin Le Grand break; 1592ddde725dSArmin Le Grand } 1593ddde725dSArmin Le Grand case SVGTokenDirection: 1594ddde725dSArmin Le Grand { 1595ddde725dSArmin Le Grand break; 1596ddde725dSArmin Le Grand } 1597ddde725dSArmin Le Grand case SVGTokenLetterSpacing: 1598ddde725dSArmin Le Grand { 1599ddde725dSArmin Le Grand break; 1600ddde725dSArmin Le Grand } 1601ddde725dSArmin Le Grand case SVGTokenTextDecoration: 1602ddde725dSArmin Le Grand { 1603ddde725dSArmin Le Grand if(aContent.getLength()) 1604ddde725dSArmin Le Grand { 1605ddde725dSArmin Le Grand static rtl::OUString aStrNone(rtl::OUString::createFromAscii("none")); 1606ddde725dSArmin Le Grand static rtl::OUString aStrUnderline(rtl::OUString::createFromAscii("underline")); 1607ddde725dSArmin Le Grand static rtl::OUString aStrOverline(rtl::OUString::createFromAscii("overline")); 1608ddde725dSArmin Le Grand static rtl::OUString aStrLineThrough(rtl::OUString::createFromAscii("line-through")); 1609ddde725dSArmin Le Grand static rtl::OUString aStrBlink(rtl::OUString::createFromAscii("blink")); 1610ddde725dSArmin Le Grand 1611ddde725dSArmin Le Grand if(aContent.match(aStrNone)) 1612ddde725dSArmin Le Grand { 1613ddde725dSArmin Le Grand setTextDecoration(TextDecoration_none); 1614ddde725dSArmin Le Grand } 1615ddde725dSArmin Le Grand else if(aContent.match(aStrUnderline)) 1616ddde725dSArmin Le Grand { 1617ddde725dSArmin Le Grand setTextDecoration(TextDecoration_underline); 1618ddde725dSArmin Le Grand } 1619ddde725dSArmin Le Grand else if(aContent.match(aStrOverline)) 1620ddde725dSArmin Le Grand { 1621ddde725dSArmin Le Grand setTextDecoration(TextDecoration_overline); 1622ddde725dSArmin Le Grand } 1623ddde725dSArmin Le Grand else if(aContent.match(aStrLineThrough)) 1624ddde725dSArmin Le Grand { 1625ddde725dSArmin Le Grand setTextDecoration(TextDecoration_line_through); 1626ddde725dSArmin Le Grand } 1627ddde725dSArmin Le Grand else if(aContent.match(aStrBlink)) 1628ddde725dSArmin Le Grand { 1629ddde725dSArmin Le Grand setTextDecoration(TextDecoration_blink); 1630ddde725dSArmin Le Grand } 1631ddde725dSArmin Le Grand } 1632ddde725dSArmin Le Grand break; 1633ddde725dSArmin Le Grand } 1634ddde725dSArmin Le Grand case SVGTokenUnicodeBidi: 1635ddde725dSArmin Le Grand { 1636ddde725dSArmin Le Grand break; 1637ddde725dSArmin Le Grand } 1638ddde725dSArmin Le Grand case SVGTokenWordSpacing: 1639ddde725dSArmin Le Grand { 1640ddde725dSArmin Le Grand break; 1641ddde725dSArmin Le Grand } 1642ddde725dSArmin Le Grand case SVGTokenTextAnchor: 1643ddde725dSArmin Le Grand { 1644ddde725dSArmin Le Grand if(aContent.getLength()) 1645ddde725dSArmin Le Grand { 1646ddde725dSArmin Le Grand static rtl::OUString aStrStart(rtl::OUString::createFromAscii("start")); 1647ddde725dSArmin Le Grand static rtl::OUString aStrMiddle(rtl::OUString::createFromAscii("middle")); 1648ddde725dSArmin Le Grand static rtl::OUString aStrEnd(rtl::OUString::createFromAscii("end")); 1649ddde725dSArmin Le Grand 1650ddde725dSArmin Le Grand if(aContent.match(aStrStart)) 1651ddde725dSArmin Le Grand { 1652ddde725dSArmin Le Grand setTextAnchor(TextAnchor_start); 1653ddde725dSArmin Le Grand } 1654ddde725dSArmin Le Grand else if(aContent.match(aStrMiddle)) 1655ddde725dSArmin Le Grand { 1656ddde725dSArmin Le Grand setTextAnchor(TextAnchor_middle); 1657ddde725dSArmin Le Grand } 1658ddde725dSArmin Le Grand else if(aContent.match(aStrEnd)) 1659ddde725dSArmin Le Grand { 1660ddde725dSArmin Le Grand setTextAnchor(TextAnchor_end); 1661ddde725dSArmin Le Grand } 1662ddde725dSArmin Le Grand } 1663ddde725dSArmin Le Grand break; 1664ddde725dSArmin Le Grand } 1665ddde725dSArmin Le Grand case SVGTokenTextAlign: 1666ddde725dSArmin Le Grand { 1667ddde725dSArmin Le Grand if(aContent.getLength()) 1668ddde725dSArmin Le Grand { 1669ddde725dSArmin Le Grand static rtl::OUString aStrLeft(rtl::OUString::createFromAscii("left")); 1670ddde725dSArmin Le Grand static rtl::OUString aStrRight(rtl::OUString::createFromAscii("right")); 1671ddde725dSArmin Le Grand static rtl::OUString aStrCenter(rtl::OUString::createFromAscii("center")); 1672ddde725dSArmin Le Grand static rtl::OUString aStrJustify(rtl::OUString::createFromAscii("justify")); 1673ddde725dSArmin Le Grand 1674ddde725dSArmin Le Grand if(aContent.match(aStrLeft)) 1675ddde725dSArmin Le Grand { 1676ddde725dSArmin Le Grand setTextAlign(TextAlign_left); 1677ddde725dSArmin Le Grand } 1678ddde725dSArmin Le Grand else if(aContent.match(aStrRight)) 1679ddde725dSArmin Le Grand { 1680ddde725dSArmin Le Grand setTextAlign(TextAlign_right); 1681ddde725dSArmin Le Grand } 1682ddde725dSArmin Le Grand else if(aContent.match(aStrCenter)) 1683ddde725dSArmin Le Grand { 1684ddde725dSArmin Le Grand setTextAlign(TextAlign_center); 1685ddde725dSArmin Le Grand } 1686ddde725dSArmin Le Grand else if(aContent.match(aStrJustify)) 1687ddde725dSArmin Le Grand { 1688ddde725dSArmin Le Grand setTextAlign(TextAlign_justify); 1689ddde725dSArmin Le Grand } 1690ddde725dSArmin Le Grand } 1691ddde725dSArmin Le Grand break; 1692ddde725dSArmin Le Grand } 1693ddde725dSArmin Le Grand case SVGTokenColor: 1694ddde725dSArmin Le Grand { 1695ddde725dSArmin Le Grand SvgPaint aSvgPaint; 1696ddde725dSArmin Le Grand rtl::OUString aURL; 1697ddde725dSArmin Le Grand 1698ddde725dSArmin Le Grand if(readSvgPaint(aContent, aSvgPaint, aURL)) 1699ddde725dSArmin Le Grand { 1700ddde725dSArmin Le Grand setColor(aSvgPaint); 1701ddde725dSArmin Le Grand } 1702ddde725dSArmin Le Grand break; 1703ddde725dSArmin Le Grand } 1704ddde725dSArmin Le Grand case SVGTokenOpacity: 1705ddde725dSArmin Le Grand { 1706ddde725dSArmin Le Grand SvgNumber aNum; 1707ddde725dSArmin Le Grand 1708ddde725dSArmin Le Grand if(readSingleNumber(aContent, aNum)) 1709ddde725dSArmin Le Grand { 1710ddde725dSArmin Le Grand setOpacity(SvgNumber(basegfx::clamp(aNum.getNumber(), 0.0, 1.0), aNum.getUnit(), aNum.isSet())); 1711ddde725dSArmin Le Grand } 1712ddde725dSArmin Le Grand break; 1713ddde725dSArmin Le Grand } 1714ddde725dSArmin Le Grand case SVGTokenClipPathProperty: 1715ddde725dSArmin Le Grand { 1716ddde725dSArmin Le Grand readLocalUrl(aContent, maClipPathXLink); 1717ddde725dSArmin Le Grand break; 1718ddde725dSArmin Le Grand } 1719ddde725dSArmin Le Grand case SVGTokenMask: 1720ddde725dSArmin Le Grand { 1721ddde725dSArmin Le Grand readLocalUrl(aContent, maMaskXLink); 1722ddde725dSArmin Le Grand break; 1723ddde725dSArmin Le Grand } 1724ddde725dSArmin Le Grand case SVGTokenClipRule: 1725ddde725dSArmin Le Grand { 1726ddde725dSArmin Le Grand if(aContent.getLength()) 1727ddde725dSArmin Le Grand { 1728ddde725dSArmin Le Grand if(aContent.match(commonStrings::aStrNonzero)) 1729ddde725dSArmin Le Grand { 1730ddde725dSArmin Le Grand mbClipRule = true; 1731ddde725dSArmin Le Grand } 1732ddde725dSArmin Le Grand else if(aContent.match(commonStrings::aStrEvenOdd)) 1733ddde725dSArmin Le Grand { 1734ddde725dSArmin Le Grand mbClipRule = false; 1735ddde725dSArmin Le Grand } 1736ddde725dSArmin Le Grand } 1737ddde725dSArmin Le Grand break; 1738ddde725dSArmin Le Grand } 1739ddde725dSArmin Le Grand case SVGTokenMarker: 1740ddde725dSArmin Le Grand { 1741ddde725dSArmin Le Grand readLocalUrl(aContent, maMarkerEndXLink); 1742ddde725dSArmin Le Grand maMarkerStartXLink = maMarkerMidXLink = maMarkerEndXLink; 1743ddde725dSArmin Le Grand break; 1744ddde725dSArmin Le Grand } 1745ddde725dSArmin Le Grand case SVGTokenMarkerStart: 1746ddde725dSArmin Le Grand { 1747ddde725dSArmin Le Grand readLocalUrl(aContent, maMarkerStartXLink); 1748ddde725dSArmin Le Grand break; 1749ddde725dSArmin Le Grand } 1750ddde725dSArmin Le Grand case SVGTokenMarkerMid: 1751ddde725dSArmin Le Grand { 1752ddde725dSArmin Le Grand readLocalUrl(aContent, maMarkerMidXLink); 1753ddde725dSArmin Le Grand break; 1754ddde725dSArmin Le Grand } 1755ddde725dSArmin Le Grand case SVGTokenMarkerEnd: 1756ddde725dSArmin Le Grand { 1757ddde725dSArmin Le Grand readLocalUrl(aContent, maMarkerEndXLink); 1758ddde725dSArmin Le Grand break; 1759ddde725dSArmin Le Grand } 1760e2bf1e9dSArmin Le Grand default: 1761e2bf1e9dSArmin Le Grand { 1762e2bf1e9dSArmin Le Grand break; 1763e2bf1e9dSArmin Le Grand } 1764ddde725dSArmin Le Grand } 1765ddde725dSArmin Le Grand } 1766ddde725dSArmin Le Grand 1767ddde725dSArmin Le Grand const basegfx::BColor* SvgStyleAttributes::getFill() const 1768ddde725dSArmin Le Grand { 1769ddde725dSArmin Le Grand if(mbIsClipPathContent) 1770ddde725dSArmin Le Grand { 1771ddde725dSArmin Le Grand static basegfx::BColor aBlack(0.0, 0.0, 0.0); 1772ddde725dSArmin Le Grand 1773ddde725dSArmin Le Grand return &aBlack; 1774ddde725dSArmin Le Grand } 1775ddde725dSArmin Le Grand else if(maFill.isSet()) 1776ddde725dSArmin Le Grand { 1777ddde725dSArmin Le Grand if(maFill.isCurrent()) 1778ddde725dSArmin Le Grand { 1779ddde725dSArmin Le Grand return getColor(); 1780ddde725dSArmin Le Grand } 1781ddde725dSArmin Le Grand else if(maFill.isOn()) 1782ddde725dSArmin Le Grand { 1783ddde725dSArmin Le Grand return &maFill.getBColor(); 1784ddde725dSArmin Le Grand } 1785ddde725dSArmin Le Grand } 1786ddde725dSArmin Le Grand else 1787ddde725dSArmin Le Grand { 1788ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 1789ddde725dSArmin Le Grand 1790ddde725dSArmin Le Grand if(pSvgStyleAttributes) 1791ddde725dSArmin Le Grand { 1792ddde725dSArmin Le Grand return pSvgStyleAttributes->getFill(); 1793ddde725dSArmin Le Grand } 1794ddde725dSArmin Le Grand } 1795ddde725dSArmin Le Grand 1796ddde725dSArmin Le Grand return 0; 1797ddde725dSArmin Le Grand } 1798ddde725dSArmin Le Grand 1799ddde725dSArmin Le Grand const basegfx::BColor* SvgStyleAttributes::getStroke() const 1800ddde725dSArmin Le Grand { 1801ddde725dSArmin Le Grand if(mbIsClipPathContent) 1802ddde725dSArmin Le Grand { 1803ddde725dSArmin Le Grand return 0; 1804ddde725dSArmin Le Grand } 1805ddde725dSArmin Le Grand else if(maStroke.isSet()) 1806ddde725dSArmin Le Grand { 1807ddde725dSArmin Le Grand if(maStroke.isCurrent()) 1808ddde725dSArmin Le Grand { 1809ddde725dSArmin Le Grand return getColor(); 1810ddde725dSArmin Le Grand } 1811ddde725dSArmin Le Grand else if(maStroke.isOn()) 1812ddde725dSArmin Le Grand { 1813ddde725dSArmin Le Grand return &maStroke.getBColor(); 1814ddde725dSArmin Le Grand } 1815ddde725dSArmin Le Grand } 1816ddde725dSArmin Le Grand else 1817ddde725dSArmin Le Grand { 1818ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 1819ddde725dSArmin Le Grand 1820ddde725dSArmin Le Grand if(pSvgStyleAttributes) 1821ddde725dSArmin Le Grand { 1822ddde725dSArmin Le Grand return pSvgStyleAttributes->getStroke(); 1823ddde725dSArmin Le Grand } 1824ddde725dSArmin Le Grand } 1825ddde725dSArmin Le Grand 1826ddde725dSArmin Le Grand return 0; 1827ddde725dSArmin Le Grand } 1828ddde725dSArmin Le Grand 1829ddde725dSArmin Le Grand const basegfx::BColor& SvgStyleAttributes::getStopColor() const 1830ddde725dSArmin Le Grand { 1831ddde725dSArmin Le Grand if(maStopColor.isCurrent()) 1832ddde725dSArmin Le Grand { 1833ddde725dSArmin Le Grand return *getColor(); 1834ddde725dSArmin Le Grand } 1835ddde725dSArmin Le Grand else 1836ddde725dSArmin Le Grand { 1837ddde725dSArmin Le Grand return maStopColor.getBColor(); 1838ddde725dSArmin Le Grand } 1839ddde725dSArmin Le Grand } 1840ddde725dSArmin Le Grand 1841ddde725dSArmin Le Grand const SvgGradientNode* SvgStyleAttributes::getSvgGradientNodeFill() const 1842ddde725dSArmin Le Grand { 1843ddde725dSArmin Le Grand if(mbIsClipPathContent) 1844ddde725dSArmin Le Grand { 1845ddde725dSArmin Le Grand return 0; 1846ddde725dSArmin Le Grand } 1847ddde725dSArmin Le Grand else if(mpSvgGradientNodeFill) 1848ddde725dSArmin Le Grand { 1849ddde725dSArmin Le Grand return mpSvgGradientNodeFill; 1850ddde725dSArmin Le Grand } 1851ddde725dSArmin Le Grand else 1852ddde725dSArmin Le Grand { 1853ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 1854ddde725dSArmin Le Grand 1855ddde725dSArmin Le Grand if(pSvgStyleAttributes) 1856ddde725dSArmin Le Grand { 1857ddde725dSArmin Le Grand return pSvgStyleAttributes->getSvgGradientNodeFill(); 1858ddde725dSArmin Le Grand } 1859ddde725dSArmin Le Grand } 1860ddde725dSArmin Le Grand 1861ddde725dSArmin Le Grand return 0; 1862ddde725dSArmin Le Grand } 1863ddde725dSArmin Le Grand 1864ddde725dSArmin Le Grand const SvgGradientNode* SvgStyleAttributes::getSvgGradientNodeStroke() const 1865ddde725dSArmin Le Grand { 1866ddde725dSArmin Le Grand if(mbIsClipPathContent) 1867ddde725dSArmin Le Grand { 1868ddde725dSArmin Le Grand return 0; 1869ddde725dSArmin Le Grand } 1870ddde725dSArmin Le Grand else if(mpSvgGradientNodeStroke) 1871ddde725dSArmin Le Grand { 1872ddde725dSArmin Le Grand return mpSvgGradientNodeStroke; 1873ddde725dSArmin Le Grand } 1874ddde725dSArmin Le Grand else 1875ddde725dSArmin Le Grand { 1876ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 1877ddde725dSArmin Le Grand 1878ddde725dSArmin Le Grand if(pSvgStyleAttributes) 1879ddde725dSArmin Le Grand { 1880ddde725dSArmin Le Grand return pSvgStyleAttributes->getSvgGradientNodeStroke(); 1881ddde725dSArmin Le Grand } 1882ddde725dSArmin Le Grand } 1883ddde725dSArmin Le Grand 1884ddde725dSArmin Le Grand return 0; 1885ddde725dSArmin Le Grand } 1886ddde725dSArmin Le Grand 1887ddde725dSArmin Le Grand const SvgPatternNode* SvgStyleAttributes::getSvgPatternNodeFill() const 1888ddde725dSArmin Le Grand { 1889ddde725dSArmin Le Grand if(mbIsClipPathContent) 1890ddde725dSArmin Le Grand { 1891ddde725dSArmin Le Grand return 0; 1892ddde725dSArmin Le Grand } 1893ddde725dSArmin Le Grand else if(mpSvgPatternNodeFill) 1894ddde725dSArmin Le Grand { 1895ddde725dSArmin Le Grand return mpSvgPatternNodeFill; 1896ddde725dSArmin Le Grand } 1897ddde725dSArmin Le Grand else 1898ddde725dSArmin Le Grand { 1899ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 1900ddde725dSArmin Le Grand 1901ddde725dSArmin Le Grand if(pSvgStyleAttributes) 1902ddde725dSArmin Le Grand { 1903ddde725dSArmin Le Grand return pSvgStyleAttributes->getSvgPatternNodeFill(); 1904ddde725dSArmin Le Grand } 1905ddde725dSArmin Le Grand } 1906ddde725dSArmin Le Grand 1907ddde725dSArmin Le Grand return 0; 1908ddde725dSArmin Le Grand } 1909ddde725dSArmin Le Grand 1910ddde725dSArmin Le Grand const SvgPatternNode* SvgStyleAttributes::getSvgPatternNodeStroke() const 1911ddde725dSArmin Le Grand { 1912ddde725dSArmin Le Grand if(mbIsClipPathContent) 1913ddde725dSArmin Le Grand { 1914ddde725dSArmin Le Grand return 0; 1915ddde725dSArmin Le Grand } 1916ddde725dSArmin Le Grand else if(mpSvgPatternNodeStroke) 1917ddde725dSArmin Le Grand { 1918ddde725dSArmin Le Grand return mpSvgPatternNodeStroke; 1919ddde725dSArmin Le Grand } 1920ddde725dSArmin Le Grand else 1921ddde725dSArmin Le Grand { 1922ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 1923ddde725dSArmin Le Grand 1924ddde725dSArmin Le Grand if(pSvgStyleAttributes) 1925ddde725dSArmin Le Grand { 1926ddde725dSArmin Le Grand return pSvgStyleAttributes->getSvgPatternNodeStroke(); 1927ddde725dSArmin Le Grand } 1928ddde725dSArmin Le Grand } 1929ddde725dSArmin Le Grand 1930ddde725dSArmin Le Grand return 0; 1931ddde725dSArmin Le Grand } 1932ddde725dSArmin Le Grand 1933ddde725dSArmin Le Grand const SvgNumber SvgStyleAttributes::getStrokeWidth() const 1934ddde725dSArmin Le Grand { 1935ddde725dSArmin Le Grand if(mbIsClipPathContent) 1936ddde725dSArmin Le Grand { 1937ddde725dSArmin Le Grand return SvgNumber(0.0); 1938ddde725dSArmin Le Grand } 1939ddde725dSArmin Le Grand else if(maStrokeWidth.isSet()) 1940ddde725dSArmin Le Grand { 1941ddde725dSArmin Le Grand return maStrokeWidth; 1942ddde725dSArmin Le Grand } 1943ddde725dSArmin Le Grand 1944ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 1945ddde725dSArmin Le Grand 1946ddde725dSArmin Le Grand if(pSvgStyleAttributes) 1947ddde725dSArmin Le Grand { 1948ddde725dSArmin Le Grand return pSvgStyleAttributes->getStrokeWidth(); 1949ddde725dSArmin Le Grand } 1950ddde725dSArmin Le Grand 1951ddde725dSArmin Le Grand // default is 1 1952ddde725dSArmin Le Grand return SvgNumber(1.0); 1953ddde725dSArmin Le Grand } 1954ddde725dSArmin Le Grand 1955ddde725dSArmin Le Grand const SvgNumber SvgStyleAttributes::getStopOpacity() const 1956ddde725dSArmin Le Grand { 1957ddde725dSArmin Le Grand if(maStopOpacity.isSet()) 1958ddde725dSArmin Le Grand { 1959ddde725dSArmin Le Grand return maStopOpacity; 1960ddde725dSArmin Le Grand } 1961ddde725dSArmin Le Grand 1962ddde725dSArmin Le Grand // default is 1 1963ddde725dSArmin Le Grand return SvgNumber(1.0); 1964ddde725dSArmin Le Grand } 1965ddde725dSArmin Le Grand 1966ddde725dSArmin Le Grand const SvgNumber SvgStyleAttributes::getFillOpacity() const 1967ddde725dSArmin Le Grand { 1968ddde725dSArmin Le Grand if(mbIsClipPathContent) 1969ddde725dSArmin Le Grand { 1970ddde725dSArmin Le Grand return SvgNumber(1.0); 1971ddde725dSArmin Le Grand } 1972ddde725dSArmin Le Grand else if(maFillOpacity.isSet()) 1973ddde725dSArmin Le Grand { 1974ddde725dSArmin Le Grand return maFillOpacity; 1975ddde725dSArmin Le Grand } 1976ddde725dSArmin Le Grand 1977ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 1978ddde725dSArmin Le Grand 1979ddde725dSArmin Le Grand if(pSvgStyleAttributes) 1980ddde725dSArmin Le Grand { 1981ddde725dSArmin Le Grand return pSvgStyleAttributes->getFillOpacity(); 1982ddde725dSArmin Le Grand } 1983ddde725dSArmin Le Grand 1984ddde725dSArmin Le Grand // default is 1 1985ddde725dSArmin Le Grand return SvgNumber(1.0); 1986ddde725dSArmin Le Grand } 1987ddde725dSArmin Le Grand 1988ddde725dSArmin Le Grand bool SvgStyleAttributes::getFillRule() const 1989ddde725dSArmin Le Grand { 1990ddde725dSArmin Le Grand if(maFillRuleSet) 1991ddde725dSArmin Le Grand { 1992ddde725dSArmin Le Grand return maFillRule; 1993ddde725dSArmin Le Grand } 1994ddde725dSArmin Le Grand 1995ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 1996ddde725dSArmin Le Grand 1997ddde725dSArmin Le Grand if(pSvgStyleAttributes) 1998ddde725dSArmin Le Grand { 1999ddde725dSArmin Le Grand return pSvgStyleAttributes->getFillRule(); 2000ddde725dSArmin Le Grand } 2001ddde725dSArmin Le Grand 2002ddde725dSArmin Le Grand // default is NonZero 2003ddde725dSArmin Le Grand return true; 2004ddde725dSArmin Le Grand } 2005ddde725dSArmin Le Grand 2006ddde725dSArmin Le Grand void SvgStyleAttributes::setFillRule(const bool* pFillRule) 2007ddde725dSArmin Le Grand { 2008ddde725dSArmin Le Grand if(pFillRule) 2009ddde725dSArmin Le Grand { 2010ddde725dSArmin Le Grand maFillRuleSet = true; 2011ddde725dSArmin Le Grand maFillRule = *pFillRule; 2012ddde725dSArmin Le Grand } 2013ddde725dSArmin Le Grand else 2014ddde725dSArmin Le Grand { 2015ddde725dSArmin Le Grand maFillRuleSet = false; 2016ddde725dSArmin Le Grand } 2017ddde725dSArmin Le Grand } 2018ddde725dSArmin Le Grand 2019ddde725dSArmin Le Grand const SvgNumberVector& SvgStyleAttributes::getStrokeDasharray() const 2020ddde725dSArmin Le Grand { 2021ddde725dSArmin Le Grand if(!maStrokeDasharray.empty()) 2022ddde725dSArmin Le Grand { 2023ddde725dSArmin Le Grand return maStrokeDasharray; 2024ddde725dSArmin Le Grand } 2025ddde725dSArmin Le Grand 2026ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 2027ddde725dSArmin Le Grand 2028ddde725dSArmin Le Grand if(pSvgStyleAttributes) 2029ddde725dSArmin Le Grand { 2030ddde725dSArmin Le Grand return pSvgStyleAttributes->getStrokeDasharray(); 2031ddde725dSArmin Le Grand } 2032ddde725dSArmin Le Grand 2033ddde725dSArmin Le Grand // default empty 2034ddde725dSArmin Le Grand return maStrokeDasharray; 2035ddde725dSArmin Le Grand } 2036ddde725dSArmin Le Grand 2037ddde725dSArmin Le Grand const SvgNumber SvgStyleAttributes::getStrokeDashOffset() const 2038ddde725dSArmin Le Grand { 2039ddde725dSArmin Le Grand if(maStrokeDashOffset.isSet()) 2040ddde725dSArmin Le Grand { 2041ddde725dSArmin Le Grand return maStrokeDashOffset; 2042ddde725dSArmin Le Grand } 2043ddde725dSArmin Le Grand 2044ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 2045ddde725dSArmin Le Grand 2046ddde725dSArmin Le Grand if(pSvgStyleAttributes) 2047ddde725dSArmin Le Grand { 2048ddde725dSArmin Le Grand return pSvgStyleAttributes->getStrokeDashOffset(); 2049ddde725dSArmin Le Grand } 2050ddde725dSArmin Le Grand 2051ddde725dSArmin Le Grand // default is 0 2052ddde725dSArmin Le Grand return SvgNumber(0.0); 2053ddde725dSArmin Le Grand } 2054ddde725dSArmin Le Grand 2055e2bf1e9dSArmin Le Grand StrokeLinecap SvgStyleAttributes::getStrokeLinecap() const 2056ddde725dSArmin Le Grand { 2057ddde725dSArmin Le Grand if(maStrokeLinecap != StrokeLinecap_notset) 2058ddde725dSArmin Le Grand { 2059ddde725dSArmin Le Grand return maStrokeLinecap; 2060ddde725dSArmin Le Grand } 2061ddde725dSArmin Le Grand 2062ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 2063ddde725dSArmin Le Grand 2064ddde725dSArmin Le Grand if(pSvgStyleAttributes) 2065ddde725dSArmin Le Grand { 2066ddde725dSArmin Le Grand return pSvgStyleAttributes->getStrokeLinecap(); 2067ddde725dSArmin Le Grand } 2068ddde725dSArmin Le Grand 2069ddde725dSArmin Le Grand // default is StrokeLinecap_butt 2070ddde725dSArmin Le Grand return StrokeLinecap_butt; 2071ddde725dSArmin Le Grand } 2072ddde725dSArmin Le Grand 2073e2bf1e9dSArmin Le Grand StrokeLinejoin SvgStyleAttributes::getStrokeLinejoin() const 2074ddde725dSArmin Le Grand { 2075ddde725dSArmin Le Grand if(maStrokeLinejoin != StrokeLinejoin_notset) 2076ddde725dSArmin Le Grand { 2077ddde725dSArmin Le Grand return maStrokeLinejoin; 2078ddde725dSArmin Le Grand } 2079ddde725dSArmin Le Grand 2080ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 2081ddde725dSArmin Le Grand 2082ddde725dSArmin Le Grand if(pSvgStyleAttributes) 2083ddde725dSArmin Le Grand { 2084ddde725dSArmin Le Grand return pSvgStyleAttributes->getStrokeLinejoin(); 2085ddde725dSArmin Le Grand } 2086ddde725dSArmin Le Grand 2087ddde725dSArmin Le Grand // default is StrokeLinejoin_butt 2088ddde725dSArmin Le Grand return StrokeLinejoin_miter; 2089ddde725dSArmin Le Grand } 2090ddde725dSArmin Le Grand 2091ddde725dSArmin Le Grand const SvgNumber SvgStyleAttributes::getStrokeMiterLimit() const 2092ddde725dSArmin Le Grand { 2093ddde725dSArmin Le Grand if(maStrokeMiterLimit.isSet()) 2094ddde725dSArmin Le Grand { 2095ddde725dSArmin Le Grand return maStrokeMiterLimit; 2096ddde725dSArmin Le Grand } 2097ddde725dSArmin Le Grand 2098ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 2099ddde725dSArmin Le Grand 2100ddde725dSArmin Le Grand if(pSvgStyleAttributes) 2101ddde725dSArmin Le Grand { 2102ddde725dSArmin Le Grand return pSvgStyleAttributes->getStrokeMiterLimit(); 2103ddde725dSArmin Le Grand } 2104ddde725dSArmin Le Grand 2105ddde725dSArmin Le Grand // default is 4 2106ddde725dSArmin Le Grand return SvgNumber(4.0); 2107ddde725dSArmin Le Grand } 2108ddde725dSArmin Le Grand 2109ddde725dSArmin Le Grand const SvgNumber SvgStyleAttributes::getStrokeOpacity() const 2110ddde725dSArmin Le Grand { 2111ddde725dSArmin Le Grand if(maStrokeOpacity.isSet()) 2112ddde725dSArmin Le Grand { 2113ddde725dSArmin Le Grand return maStrokeOpacity; 2114ddde725dSArmin Le Grand } 2115ddde725dSArmin Le Grand 2116ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 2117ddde725dSArmin Le Grand 2118ddde725dSArmin Le Grand if(pSvgStyleAttributes) 2119ddde725dSArmin Le Grand { 2120ddde725dSArmin Le Grand return pSvgStyleAttributes->getStrokeOpacity(); 2121ddde725dSArmin Le Grand } 2122ddde725dSArmin Le Grand 2123ddde725dSArmin Le Grand // default is 1 2124ddde725dSArmin Le Grand return SvgNumber(1.0); 2125ddde725dSArmin Le Grand } 2126ddde725dSArmin Le Grand 2127ddde725dSArmin Le Grand const SvgStringVector& SvgStyleAttributes::getFontFamily() const 2128ddde725dSArmin Le Grand { 2129ddde725dSArmin Le Grand if(!maFontFamily.empty()) 2130ddde725dSArmin Le Grand { 2131ddde725dSArmin Le Grand return maFontFamily; 2132ddde725dSArmin Le Grand } 2133ddde725dSArmin Le Grand 2134ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 2135ddde725dSArmin Le Grand 2136ddde725dSArmin Le Grand if(pSvgStyleAttributes) 2137ddde725dSArmin Le Grand { 2138ddde725dSArmin Le Grand return pSvgStyleAttributes->getFontFamily(); 2139ddde725dSArmin Le Grand } 2140ddde725dSArmin Le Grand 2141ddde725dSArmin Le Grand // default is empty 2142ddde725dSArmin Le Grand return maFontFamily; 2143ddde725dSArmin Le Grand } 2144ddde725dSArmin Le Grand 2145ddde725dSArmin Le Grand const SvgNumber SvgStyleAttributes::getFontSize() const 2146ddde725dSArmin Le Grand { 2147ddde725dSArmin Le Grand if(maFontSize.isSet()) 2148ddde725dSArmin Le Grand { 2149ddde725dSArmin Le Grand return maFontSize; 2150ddde725dSArmin Le Grand } 2151ddde725dSArmin Le Grand 2152ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 2153ddde725dSArmin Le Grand 2154ddde725dSArmin Le Grand if(pSvgStyleAttributes) 2155ddde725dSArmin Le Grand { 2156ddde725dSArmin Le Grand return pSvgStyleAttributes->getFontSize(); 2157ddde725dSArmin Le Grand } 2158ddde725dSArmin Le Grand 2159ddde725dSArmin Le Grand // default is 'medium' 2160ddde725dSArmin Le Grand return SvgNumber(12.0); 2161ddde725dSArmin Le Grand } 2162ddde725dSArmin Le Grand 2163e2bf1e9dSArmin Le Grand FontStretch SvgStyleAttributes::getFontStretch() const 2164ddde725dSArmin Le Grand { 2165ddde725dSArmin Le Grand if(maFontStretch != FontStretch_notset) 2166ddde725dSArmin Le Grand { 2167ddde725dSArmin Le Grand if(FontStretch_wider != maFontStretch && FontStretch_narrower != maFontStretch) 2168ddde725dSArmin Le Grand { 2169ddde725dSArmin Le Grand return maFontStretch; 2170ddde725dSArmin Le Grand } 2171ddde725dSArmin Le Grand } 2172ddde725dSArmin Le Grand 2173ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 2174ddde725dSArmin Le Grand 2175ddde725dSArmin Le Grand if(pSvgStyleAttributes) 2176ddde725dSArmin Le Grand { 2177ddde725dSArmin Le Grand FontStretch aInherited = pSvgStyleAttributes->getFontStretch(); 2178ddde725dSArmin Le Grand 2179ddde725dSArmin Le Grand if(FontStretch_wider == maFontStretch) 2180ddde725dSArmin Le Grand { 2181ddde725dSArmin Le Grand aInherited = getWider(aInherited); 2182ddde725dSArmin Le Grand } 2183ddde725dSArmin Le Grand else if(FontStretch_narrower == maFontStretch) 2184ddde725dSArmin Le Grand { 2185ddde725dSArmin Le Grand aInherited = getNarrower(aInherited); 2186ddde725dSArmin Le Grand } 2187ddde725dSArmin Le Grand 2188ddde725dSArmin Le Grand return aInherited; 2189ddde725dSArmin Le Grand } 2190ddde725dSArmin Le Grand 2191ddde725dSArmin Le Grand // default is FontStretch_normal 2192ddde725dSArmin Le Grand return FontStretch_normal; 2193ddde725dSArmin Le Grand } 2194ddde725dSArmin Le Grand 2195e2bf1e9dSArmin Le Grand FontStyle SvgStyleAttributes::getFontStyle() const 2196ddde725dSArmin Le Grand { 2197ddde725dSArmin Le Grand if(maFontStyle != FontStyle_notset) 2198ddde725dSArmin Le Grand { 2199ddde725dSArmin Le Grand return maFontStyle; 2200ddde725dSArmin Le Grand } 2201ddde725dSArmin Le Grand 2202ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 2203ddde725dSArmin Le Grand 2204ddde725dSArmin Le Grand if(pSvgStyleAttributes) 2205ddde725dSArmin Le Grand { 2206ddde725dSArmin Le Grand return pSvgStyleAttributes->getFontStyle(); 2207ddde725dSArmin Le Grand } 2208ddde725dSArmin Le Grand 2209ddde725dSArmin Le Grand // default is FontStyle_normal 2210ddde725dSArmin Le Grand return FontStyle_normal; 2211ddde725dSArmin Le Grand } 2212ddde725dSArmin Le Grand 2213e2bf1e9dSArmin Le Grand FontWeight SvgStyleAttributes::getFontWeight() const 2214ddde725dSArmin Le Grand { 2215ddde725dSArmin Le Grand if(maFontWeight != FontWeight_notset) 2216ddde725dSArmin Le Grand { 2217ddde725dSArmin Le Grand if(FontWeight_bolder != maFontWeight && FontWeight_lighter != maFontWeight) 2218ddde725dSArmin Le Grand { 2219ddde725dSArmin Le Grand return maFontWeight; 2220ddde725dSArmin Le Grand } 2221ddde725dSArmin Le Grand } 2222ddde725dSArmin Le Grand 2223ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 2224ddde725dSArmin Le Grand 2225ddde725dSArmin Le Grand if(pSvgStyleAttributes) 2226ddde725dSArmin Le Grand { 2227ddde725dSArmin Le Grand FontWeight aInherited = pSvgStyleAttributes->getFontWeight(); 2228ddde725dSArmin Le Grand 2229ddde725dSArmin Le Grand if(FontWeight_bolder == maFontWeight) 2230ddde725dSArmin Le Grand { 2231ddde725dSArmin Le Grand aInherited = getBolder(aInherited); 2232ddde725dSArmin Le Grand } 2233ddde725dSArmin Le Grand else if(FontWeight_lighter == maFontWeight) 2234ddde725dSArmin Le Grand { 2235ddde725dSArmin Le Grand aInherited = getLighter(aInherited); 2236ddde725dSArmin Le Grand } 2237ddde725dSArmin Le Grand 2238ddde725dSArmin Le Grand return aInherited; 2239ddde725dSArmin Le Grand } 2240ddde725dSArmin Le Grand 2241ddde725dSArmin Le Grand // default is FontWeight_400 (FontWeight_normal) 2242ddde725dSArmin Le Grand return FontWeight_400; 2243ddde725dSArmin Le Grand } 2244ddde725dSArmin Le Grand 2245e2bf1e9dSArmin Le Grand TextAlign SvgStyleAttributes::getTextAlign() const 2246ddde725dSArmin Le Grand { 2247ddde725dSArmin Le Grand if(maTextAlign != TextAlign_notset) 2248ddde725dSArmin Le Grand { 2249ddde725dSArmin Le Grand return maTextAlign; 2250ddde725dSArmin Le Grand } 2251ddde725dSArmin Le Grand 2252ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 2253ddde725dSArmin Le Grand 2254ddde725dSArmin Le Grand if(pSvgStyleAttributes) 2255ddde725dSArmin Le Grand { 2256ddde725dSArmin Le Grand return pSvgStyleAttributes->getTextAlign(); 2257ddde725dSArmin Le Grand } 2258ddde725dSArmin Le Grand 2259ddde725dSArmin Le Grand // default is TextAlign_left 2260ddde725dSArmin Le Grand return TextAlign_left; 2261ddde725dSArmin Le Grand } 2262ddde725dSArmin Le Grand 2263ddde725dSArmin Le Grand const SvgStyleAttributes* SvgStyleAttributes::getTextDecorationDefiningSvgStyleAttributes() const 2264ddde725dSArmin Le Grand { 2265ddde725dSArmin Le Grand if(maTextDecoration != TextDecoration_notset) 2266ddde725dSArmin Le Grand { 2267ddde725dSArmin Le Grand return this; 2268ddde725dSArmin Le Grand } 2269ddde725dSArmin Le Grand 2270ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 2271ddde725dSArmin Le Grand 2272ddde725dSArmin Le Grand if(pSvgStyleAttributes) 2273ddde725dSArmin Le Grand { 2274ddde725dSArmin Le Grand return pSvgStyleAttributes->getTextDecorationDefiningSvgStyleAttributes(); 2275ddde725dSArmin Le Grand } 2276ddde725dSArmin Le Grand 2277ddde725dSArmin Le Grand // default is 0 2278ddde725dSArmin Le Grand return 0; 2279ddde725dSArmin Le Grand } 2280ddde725dSArmin Le Grand 2281e2bf1e9dSArmin Le Grand TextDecoration SvgStyleAttributes::getTextDecoration() const 2282ddde725dSArmin Le Grand { 2283ddde725dSArmin Le Grand const SvgStyleAttributes* pDefining = getTextDecorationDefiningSvgStyleAttributes(); 2284ddde725dSArmin Le Grand 2285ddde725dSArmin Le Grand if(pDefining) 2286ddde725dSArmin Le Grand { 2287ddde725dSArmin Le Grand return pDefining->maTextDecoration; 2288ddde725dSArmin Le Grand } 2289ddde725dSArmin Le Grand else 2290ddde725dSArmin Le Grand { 2291ddde725dSArmin Le Grand // default is TextDecoration_none 2292ddde725dSArmin Le Grand return TextDecoration_none; 2293ddde725dSArmin Le Grand } 2294ddde725dSArmin Le Grand } 2295ddde725dSArmin Le Grand 2296e2bf1e9dSArmin Le Grand TextAnchor SvgStyleAttributes::getTextAnchor() const 2297ddde725dSArmin Le Grand { 2298ddde725dSArmin Le Grand if(maTextAnchor != TextAnchor_notset) 2299ddde725dSArmin Le Grand { 2300ddde725dSArmin Le Grand return maTextAnchor; 2301ddde725dSArmin Le Grand } 2302ddde725dSArmin Le Grand 2303ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 2304ddde725dSArmin Le Grand 2305ddde725dSArmin Le Grand if(pSvgStyleAttributes) 2306ddde725dSArmin Le Grand { 2307ddde725dSArmin Le Grand return pSvgStyleAttributes->getTextAnchor(); 2308ddde725dSArmin Le Grand } 2309ddde725dSArmin Le Grand 2310ddde725dSArmin Le Grand // default is TextAnchor_start 2311ddde725dSArmin Le Grand return TextAnchor_start; 2312ddde725dSArmin Le Grand } 2313ddde725dSArmin Le Grand 2314ddde725dSArmin Le Grand const basegfx::BColor* SvgStyleAttributes::getColor() const 2315ddde725dSArmin Le Grand { 2316ddde725dSArmin Le Grand if(maColor.isSet()) 2317ddde725dSArmin Le Grand { 2318ddde725dSArmin Le Grand if(maColor.isCurrent()) 2319ddde725dSArmin Le Grand { 2320ddde725dSArmin Le Grand OSL_ENSURE(false, "Svg error: current color uses current color (!)"); 2321ddde725dSArmin Le Grand return 0; 2322ddde725dSArmin Le Grand } 2323ddde725dSArmin Le Grand else if(maColor.isOn()) 2324ddde725dSArmin Le Grand { 2325ddde725dSArmin Le Grand return &maColor.getBColor(); 2326ddde725dSArmin Le Grand } 2327ddde725dSArmin Le Grand } 2328ddde725dSArmin Le Grand else 2329ddde725dSArmin Le Grand { 2330ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 2331ddde725dSArmin Le Grand 2332ddde725dSArmin Le Grand if(pSvgStyleAttributes) 2333ddde725dSArmin Le Grand { 2334ddde725dSArmin Le Grand return pSvgStyleAttributes->getColor(); 2335ddde725dSArmin Le Grand } 2336ddde725dSArmin Le Grand } 2337ddde725dSArmin Le Grand 2338ddde725dSArmin Le Grand return 0; 2339ddde725dSArmin Le Grand } 2340ddde725dSArmin Le Grand 2341ddde725dSArmin Le Grand const rtl::OUString SvgStyleAttributes::getMarkerStartXLink() const 2342ddde725dSArmin Le Grand { 2343ddde725dSArmin Le Grand if(maMarkerStartXLink.getLength()) 2344ddde725dSArmin Le Grand { 2345ddde725dSArmin Le Grand return maMarkerStartXLink; 2346ddde725dSArmin Le Grand } 2347ddde725dSArmin Le Grand 2348ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 2349ddde725dSArmin Le Grand 2350ddde725dSArmin Le Grand if(pSvgStyleAttributes) 2351ddde725dSArmin Le Grand { 2352ddde725dSArmin Le Grand return pSvgStyleAttributes->getMarkerStartXLink(); 2353ddde725dSArmin Le Grand } 2354ddde725dSArmin Le Grand 2355ddde725dSArmin Le Grand return rtl::OUString(); 2356ddde725dSArmin Le Grand } 2357ddde725dSArmin Le Grand 2358ddde725dSArmin Le Grand const SvgMarkerNode* SvgStyleAttributes::accessMarkerStartXLink() const 2359ddde725dSArmin Le Grand { 2360ddde725dSArmin Le Grand if(!mpMarkerStartXLink) 2361ddde725dSArmin Le Grand { 2362ddde725dSArmin Le Grand const rtl::OUString aMarker(getMarkerStartXLink()); 2363ddde725dSArmin Le Grand 2364ddde725dSArmin Le Grand if(aMarker.getLength()) 2365ddde725dSArmin Le Grand { 2366ddde725dSArmin Le Grand const_cast< SvgStyleAttributes* >(this)->mpMarkerStartXLink = dynamic_cast< const SvgMarkerNode* >(mrOwner.getDocument().findSvgNodeById(getMarkerStartXLink())); 2367ddde725dSArmin Le Grand } 2368ddde725dSArmin Le Grand } 2369ddde725dSArmin Le Grand 2370ddde725dSArmin Le Grand return mpMarkerStartXLink; 2371ddde725dSArmin Le Grand } 2372ddde725dSArmin Le Grand 2373ddde725dSArmin Le Grand const rtl::OUString SvgStyleAttributes::getMarkerMidXLink() const 2374ddde725dSArmin Le Grand { 2375ddde725dSArmin Le Grand if(maMarkerMidXLink.getLength()) 2376ddde725dSArmin Le Grand { 2377ddde725dSArmin Le Grand return maMarkerMidXLink; 2378ddde725dSArmin Le Grand } 2379ddde725dSArmin Le Grand 2380ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 2381ddde725dSArmin Le Grand 2382ddde725dSArmin Le Grand if(pSvgStyleAttributes) 2383ddde725dSArmin Le Grand { 2384ddde725dSArmin Le Grand return pSvgStyleAttributes->getMarkerMidXLink(); 2385ddde725dSArmin Le Grand } 2386ddde725dSArmin Le Grand 2387ddde725dSArmin Le Grand return rtl::OUString(); 2388ddde725dSArmin Le Grand } 2389ddde725dSArmin Le Grand 2390ddde725dSArmin Le Grand const SvgMarkerNode* SvgStyleAttributes::accessMarkerMidXLink() const 2391ddde725dSArmin Le Grand { 2392ddde725dSArmin Le Grand if(!mpMarkerMidXLink) 2393ddde725dSArmin Le Grand { 2394ddde725dSArmin Le Grand const rtl::OUString aMarker(getMarkerMidXLink()); 2395ddde725dSArmin Le Grand 2396ddde725dSArmin Le Grand if(aMarker.getLength()) 2397ddde725dSArmin Le Grand { 2398ddde725dSArmin Le Grand const_cast< SvgStyleAttributes* >(this)->mpMarkerMidXLink = dynamic_cast< const SvgMarkerNode* >(mrOwner.getDocument().findSvgNodeById(getMarkerMidXLink())); 2399ddde725dSArmin Le Grand } 2400ddde725dSArmin Le Grand } 2401ddde725dSArmin Le Grand 2402ddde725dSArmin Le Grand return mpMarkerMidXLink; 2403ddde725dSArmin Le Grand } 2404ddde725dSArmin Le Grand 2405ddde725dSArmin Le Grand const rtl::OUString SvgStyleAttributes::getMarkerEndXLink() const 2406ddde725dSArmin Le Grand { 2407ddde725dSArmin Le Grand if(maMarkerEndXLink.getLength()) 2408ddde725dSArmin Le Grand { 2409ddde725dSArmin Le Grand return maMarkerEndXLink; 2410ddde725dSArmin Le Grand } 2411ddde725dSArmin Le Grand 2412ddde725dSArmin Le Grand const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); 2413ddde725dSArmin Le Grand 2414ddde725dSArmin Le Grand if(pSvgStyleAttributes) 2415ddde725dSArmin Le Grand { 2416ddde725dSArmin Le Grand return pSvgStyleAttributes->getMarkerEndXLink(); 2417ddde725dSArmin Le Grand } 2418ddde725dSArmin Le Grand 2419ddde725dSArmin Le Grand return rtl::OUString(); 2420ddde725dSArmin Le Grand } 2421ddde725dSArmin Le Grand 2422ddde725dSArmin Le Grand const SvgMarkerNode* SvgStyleAttributes::accessMarkerEndXLink() const 2423ddde725dSArmin Le Grand { 2424ddde725dSArmin Le Grand if(!mpMarkerEndXLink) 2425ddde725dSArmin Le Grand { 2426ddde725dSArmin Le Grand const rtl::OUString aMarker(getMarkerEndXLink()); 2427ddde725dSArmin Le Grand 2428ddde725dSArmin Le Grand if(aMarker.getLength()) 2429ddde725dSArmin Le Grand { 2430ddde725dSArmin Le Grand const_cast< SvgStyleAttributes* >(this)->mpMarkerEndXLink = dynamic_cast< const SvgMarkerNode* >(mrOwner.getDocument().findSvgNodeById(getMarkerEndXLink())); 2431ddde725dSArmin Le Grand } 2432ddde725dSArmin Le Grand } 2433ddde725dSArmin Le Grand 2434ddde725dSArmin Le Grand return mpMarkerEndXLink; 2435ddde725dSArmin Le Grand } 2436ddde725dSArmin Le Grand 2437ddde725dSArmin Le Grand } // end of namespace svgreader 2438ddde725dSArmin Le Grand } // end of namespace svgio 2439ddde725dSArmin Le Grand 2440ddde725dSArmin Le Grand ////////////////////////////////////////////////////////////////////////////// 2441ddde725dSArmin Le Grand // eof 2442