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