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 23*b1cdbd2cSJim Jagielski 24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove 25*b1cdbd2cSJim Jagielski #include "precompiled_drawinglayer.hxx" 26*b1cdbd2cSJim Jagielski 27*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> 28*b1cdbd2cSJim Jagielski #include <basegfx/tools/canvastools.hxx> 29*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dpolygontools.hxx> 30*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dpolypolygontools.hxx> 31*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> 32*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> 33*b1cdbd2cSJim Jagielski #include <drawinglayer/geometry/viewinformation2d.hxx> 34*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dlinegeometry.hxx> 35*b1cdbd2cSJim Jagielski #include <com/sun/star/drawing/LineCap.hpp> 36*b1cdbd2cSJim Jagielski 37*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 38*b1cdbd2cSJim Jagielski 39*b1cdbd2cSJim Jagielski using namespace com::sun::star; 40*b1cdbd2cSJim Jagielski 41*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 42*b1cdbd2cSJim Jagielski 43*b1cdbd2cSJim Jagielski namespace drawinglayer 44*b1cdbd2cSJim Jagielski { 45*b1cdbd2cSJim Jagielski namespace primitive2d 46*b1cdbd2cSJim Jagielski { PolygonHairlinePrimitive2D(const basegfx::B2DPolygon & rPolygon,const basegfx::BColor & rBColor)47*b1cdbd2cSJim Jagielski PolygonHairlinePrimitive2D::PolygonHairlinePrimitive2D( 48*b1cdbd2cSJim Jagielski const basegfx::B2DPolygon& rPolygon, 49*b1cdbd2cSJim Jagielski const basegfx::BColor& rBColor) 50*b1cdbd2cSJim Jagielski : BasePrimitive2D(), 51*b1cdbd2cSJim Jagielski maPolygon(rPolygon), 52*b1cdbd2cSJim Jagielski maBColor(rBColor) 53*b1cdbd2cSJim Jagielski { 54*b1cdbd2cSJim Jagielski } 55*b1cdbd2cSJim Jagielski operator ==(const BasePrimitive2D & rPrimitive) const56*b1cdbd2cSJim Jagielski bool PolygonHairlinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 57*b1cdbd2cSJim Jagielski { 58*b1cdbd2cSJim Jagielski if(BasePrimitive2D::operator==(rPrimitive)) 59*b1cdbd2cSJim Jagielski { 60*b1cdbd2cSJim Jagielski const PolygonHairlinePrimitive2D& rCompare = (PolygonHairlinePrimitive2D&)rPrimitive; 61*b1cdbd2cSJim Jagielski 62*b1cdbd2cSJim Jagielski return (getB2DPolygon() == rCompare.getB2DPolygon() 63*b1cdbd2cSJim Jagielski && getBColor() == rCompare.getBColor()); 64*b1cdbd2cSJim Jagielski } 65*b1cdbd2cSJim Jagielski 66*b1cdbd2cSJim Jagielski return false; 67*b1cdbd2cSJim Jagielski } 68*b1cdbd2cSJim Jagielski getB2DRange(const geometry::ViewInformation2D & rViewInformation) const69*b1cdbd2cSJim Jagielski basegfx::B2DRange PolygonHairlinePrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const 70*b1cdbd2cSJim Jagielski { 71*b1cdbd2cSJim Jagielski // this is a hairline, thus the line width is view-dependent. Get range of polygon 72*b1cdbd2cSJim Jagielski // as base size 73*b1cdbd2cSJim Jagielski basegfx::B2DRange aRetval(getB2DPolygon().getB2DRange()); 74*b1cdbd2cSJim Jagielski 75*b1cdbd2cSJim Jagielski if(!aRetval.isEmpty()) 76*b1cdbd2cSJim Jagielski { 77*b1cdbd2cSJim Jagielski // Calculate view-dependent hairline width 78*b1cdbd2cSJim Jagielski const basegfx::B2DVector aDiscreteSize(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0)); 79*b1cdbd2cSJim Jagielski const double fDiscreteHalfLineWidth(aDiscreteSize.getLength() * 0.5); 80*b1cdbd2cSJim Jagielski 81*b1cdbd2cSJim Jagielski if(basegfx::fTools::more(fDiscreteHalfLineWidth, 0.0)) 82*b1cdbd2cSJim Jagielski { 83*b1cdbd2cSJim Jagielski aRetval.grow(fDiscreteHalfLineWidth); 84*b1cdbd2cSJim Jagielski } 85*b1cdbd2cSJim Jagielski } 86*b1cdbd2cSJim Jagielski 87*b1cdbd2cSJim Jagielski // return range 88*b1cdbd2cSJim Jagielski return aRetval; 89*b1cdbd2cSJim Jagielski } 90*b1cdbd2cSJim Jagielski 91*b1cdbd2cSJim Jagielski // provide unique ID 92*b1cdbd2cSJim Jagielski ImplPrimitrive2DIDBlock(PolygonHairlinePrimitive2D, PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D) 93*b1cdbd2cSJim Jagielski 94*b1cdbd2cSJim Jagielski } // end of namespace primitive2d 95*b1cdbd2cSJim Jagielski } // end of namespace drawinglayer 96*b1cdbd2cSJim Jagielski 97*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 98*b1cdbd2cSJim Jagielski 99*b1cdbd2cSJim Jagielski namespace drawinglayer 100*b1cdbd2cSJim Jagielski { 101*b1cdbd2cSJim Jagielski namespace primitive2d 102*b1cdbd2cSJim Jagielski { create2DDecomposition(const geometry::ViewInformation2D & rViewInformation) const103*b1cdbd2cSJim Jagielski Primitive2DSequence PolygonMarkerPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const 104*b1cdbd2cSJim Jagielski { 105*b1cdbd2cSJim Jagielski // calculate logic DashLength 106*b1cdbd2cSJim Jagielski const basegfx::B2DVector aDashVector(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(getDiscreteDashLength(), 0.0)); 107*b1cdbd2cSJim Jagielski const double fLogicDashLength(aDashVector.getX()); 108*b1cdbd2cSJim Jagielski 109*b1cdbd2cSJim Jagielski if(fLogicDashLength > 0.0 && !getRGBColorA().equal(getRGBColorB())) 110*b1cdbd2cSJim Jagielski { 111*b1cdbd2cSJim Jagielski // apply dashing; get line and gap snippets 112*b1cdbd2cSJim Jagielski ::std::vector< double > aDash; 113*b1cdbd2cSJim Jagielski basegfx::B2DPolyPolygon aDashedPolyPolyA; 114*b1cdbd2cSJim Jagielski basegfx::B2DPolyPolygon aDashedPolyPolyB; 115*b1cdbd2cSJim Jagielski 116*b1cdbd2cSJim Jagielski aDash.push_back(fLogicDashLength); 117*b1cdbd2cSJim Jagielski aDash.push_back(fLogicDashLength); 118*b1cdbd2cSJim Jagielski basegfx::tools::applyLineDashing(getB2DPolygon(), aDash, &aDashedPolyPolyA, &aDashedPolyPolyB, 2.0 * fLogicDashLength); 119*b1cdbd2cSJim Jagielski 120*b1cdbd2cSJim Jagielski // prepare return value 121*b1cdbd2cSJim Jagielski Primitive2DSequence aRetval(2); 122*b1cdbd2cSJim Jagielski 123*b1cdbd2cSJim Jagielski aRetval[0] = Primitive2DReference(new PolyPolygonHairlinePrimitive2D(aDashedPolyPolyA, getRGBColorA())); 124*b1cdbd2cSJim Jagielski aRetval[1] = Primitive2DReference(new PolyPolygonHairlinePrimitive2D(aDashedPolyPolyB, getRGBColorB())); 125*b1cdbd2cSJim Jagielski 126*b1cdbd2cSJim Jagielski return aRetval; 127*b1cdbd2cSJim Jagielski } 128*b1cdbd2cSJim Jagielski else 129*b1cdbd2cSJim Jagielski { 130*b1cdbd2cSJim Jagielski const Primitive2DReference xRef(new PolygonHairlinePrimitive2D(getB2DPolygon(), getRGBColorA())); 131*b1cdbd2cSJim Jagielski return Primitive2DSequence(&xRef, 1L); 132*b1cdbd2cSJim Jagielski } 133*b1cdbd2cSJim Jagielski } 134*b1cdbd2cSJim Jagielski PolygonMarkerPrimitive2D(const basegfx::B2DPolygon & rPolygon,const basegfx::BColor & rRGBColorA,const basegfx::BColor & rRGBColorB,double fDiscreteDashLength)135*b1cdbd2cSJim Jagielski PolygonMarkerPrimitive2D::PolygonMarkerPrimitive2D( 136*b1cdbd2cSJim Jagielski const basegfx::B2DPolygon& rPolygon, 137*b1cdbd2cSJim Jagielski const basegfx::BColor& rRGBColorA, 138*b1cdbd2cSJim Jagielski const basegfx::BColor& rRGBColorB, 139*b1cdbd2cSJim Jagielski double fDiscreteDashLength) 140*b1cdbd2cSJim Jagielski : BufferedDecompositionPrimitive2D(), 141*b1cdbd2cSJim Jagielski maPolygon(rPolygon), 142*b1cdbd2cSJim Jagielski maRGBColorA(rRGBColorA), 143*b1cdbd2cSJim Jagielski maRGBColorB(rRGBColorB), 144*b1cdbd2cSJim Jagielski mfDiscreteDashLength(fDiscreteDashLength), 145*b1cdbd2cSJim Jagielski maLastInverseObjectToViewTransformation() 146*b1cdbd2cSJim Jagielski { 147*b1cdbd2cSJim Jagielski } 148*b1cdbd2cSJim Jagielski operator ==(const BasePrimitive2D & rPrimitive) const149*b1cdbd2cSJim Jagielski bool PolygonMarkerPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 150*b1cdbd2cSJim Jagielski { 151*b1cdbd2cSJim Jagielski if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 152*b1cdbd2cSJim Jagielski { 153*b1cdbd2cSJim Jagielski const PolygonMarkerPrimitive2D& rCompare = (PolygonMarkerPrimitive2D&)rPrimitive; 154*b1cdbd2cSJim Jagielski 155*b1cdbd2cSJim Jagielski return (getB2DPolygon() == rCompare.getB2DPolygon() 156*b1cdbd2cSJim Jagielski && getRGBColorA() == rCompare.getRGBColorA() 157*b1cdbd2cSJim Jagielski && getRGBColorB() == rCompare.getRGBColorB() 158*b1cdbd2cSJim Jagielski && getDiscreteDashLength() == rCompare.getDiscreteDashLength()); 159*b1cdbd2cSJim Jagielski } 160*b1cdbd2cSJim Jagielski 161*b1cdbd2cSJim Jagielski return false; 162*b1cdbd2cSJim Jagielski } 163*b1cdbd2cSJim Jagielski getB2DRange(const geometry::ViewInformation2D & rViewInformation) const164*b1cdbd2cSJim Jagielski basegfx::B2DRange PolygonMarkerPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const 165*b1cdbd2cSJim Jagielski { 166*b1cdbd2cSJim Jagielski // this is a hairline, thus the line width is view-dependent. Get range of polygon 167*b1cdbd2cSJim Jagielski // as base size 168*b1cdbd2cSJim Jagielski basegfx::B2DRange aRetval(getB2DPolygon().getB2DRange()); 169*b1cdbd2cSJim Jagielski 170*b1cdbd2cSJim Jagielski if(!aRetval.isEmpty()) 171*b1cdbd2cSJim Jagielski { 172*b1cdbd2cSJim Jagielski // Calculate view-dependent hairline width 173*b1cdbd2cSJim Jagielski const basegfx::B2DVector aDiscreteSize(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0)); 174*b1cdbd2cSJim Jagielski const double fDiscreteHalfLineWidth(aDiscreteSize.getLength() * 0.5); 175*b1cdbd2cSJim Jagielski 176*b1cdbd2cSJim Jagielski if(basegfx::fTools::more(fDiscreteHalfLineWidth, 0.0)) 177*b1cdbd2cSJim Jagielski { 178*b1cdbd2cSJim Jagielski aRetval.grow(fDiscreteHalfLineWidth); 179*b1cdbd2cSJim Jagielski } 180*b1cdbd2cSJim Jagielski } 181*b1cdbd2cSJim Jagielski 182*b1cdbd2cSJim Jagielski // return range 183*b1cdbd2cSJim Jagielski return aRetval; 184*b1cdbd2cSJim Jagielski } 185*b1cdbd2cSJim Jagielski get2DDecomposition(const geometry::ViewInformation2D & rViewInformation) const186*b1cdbd2cSJim Jagielski Primitive2DSequence PolygonMarkerPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const 187*b1cdbd2cSJim Jagielski { 188*b1cdbd2cSJim Jagielski ::osl::MutexGuard aGuard( m_aMutex ); 189*b1cdbd2cSJim Jagielski bool bNeedNewDecomposition(false); 190*b1cdbd2cSJim Jagielski 191*b1cdbd2cSJim Jagielski if(getBuffered2DDecomposition().hasElements()) 192*b1cdbd2cSJim Jagielski { 193*b1cdbd2cSJim Jagielski if(rViewInformation.getInverseObjectToViewTransformation() != maLastInverseObjectToViewTransformation) 194*b1cdbd2cSJim Jagielski { 195*b1cdbd2cSJim Jagielski bNeedNewDecomposition = true; 196*b1cdbd2cSJim Jagielski } 197*b1cdbd2cSJim Jagielski } 198*b1cdbd2cSJim Jagielski 199*b1cdbd2cSJim Jagielski if(bNeedNewDecomposition) 200*b1cdbd2cSJim Jagielski { 201*b1cdbd2cSJim Jagielski // conditions of last local decomposition have changed, delete 202*b1cdbd2cSJim Jagielski const_cast< PolygonMarkerPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence()); 203*b1cdbd2cSJim Jagielski } 204*b1cdbd2cSJim Jagielski 205*b1cdbd2cSJim Jagielski if(!getBuffered2DDecomposition().hasElements()) 206*b1cdbd2cSJim Jagielski { 207*b1cdbd2cSJim Jagielski // remember last used InverseObjectToViewTransformation 208*b1cdbd2cSJim Jagielski PolygonMarkerPrimitive2D* pThat = const_cast< PolygonMarkerPrimitive2D* >(this); 209*b1cdbd2cSJim Jagielski pThat->maLastInverseObjectToViewTransformation = rViewInformation.getInverseObjectToViewTransformation(); 210*b1cdbd2cSJim Jagielski } 211*b1cdbd2cSJim Jagielski 212*b1cdbd2cSJim Jagielski // use parent implementation 213*b1cdbd2cSJim Jagielski return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation); 214*b1cdbd2cSJim Jagielski } 215*b1cdbd2cSJim Jagielski 216*b1cdbd2cSJim Jagielski // provide unique ID 217*b1cdbd2cSJim Jagielski ImplPrimitrive2DIDBlock(PolygonMarkerPrimitive2D, PRIMITIVE2D_ID_POLYGONMARKERPRIMITIVE2D) 218*b1cdbd2cSJim Jagielski 219*b1cdbd2cSJim Jagielski } // end of namespace primitive2d 220*b1cdbd2cSJim Jagielski } // end of namespace drawinglayer 221*b1cdbd2cSJim Jagielski 222*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 223*b1cdbd2cSJim Jagielski 224*b1cdbd2cSJim Jagielski namespace drawinglayer 225*b1cdbd2cSJim Jagielski { 226*b1cdbd2cSJim Jagielski namespace primitive2d 227*b1cdbd2cSJim Jagielski { create2DDecomposition(const geometry::ViewInformation2D &) const228*b1cdbd2cSJim Jagielski Primitive2DSequence PolygonStrokePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const 229*b1cdbd2cSJim Jagielski { 230*b1cdbd2cSJim Jagielski if(getB2DPolygon().count()) 231*b1cdbd2cSJim Jagielski { 232*b1cdbd2cSJim Jagielski // #i102241# try to simplify before usage 233*b1cdbd2cSJim Jagielski const basegfx::B2DPolygon aB2DPolygon(basegfx::tools::simplifyCurveSegments(getB2DPolygon())); 234*b1cdbd2cSJim Jagielski basegfx::B2DPolyPolygon aHairLinePolyPolygon; 235*b1cdbd2cSJim Jagielski 236*b1cdbd2cSJim Jagielski if(getStrokeAttribute().isDefault() || 0.0 == getStrokeAttribute().getFullDotDashLen()) 237*b1cdbd2cSJim Jagielski { 238*b1cdbd2cSJim Jagielski // no line dashing, just copy 239*b1cdbd2cSJim Jagielski aHairLinePolyPolygon.append(aB2DPolygon); 240*b1cdbd2cSJim Jagielski } 241*b1cdbd2cSJim Jagielski else 242*b1cdbd2cSJim Jagielski { 243*b1cdbd2cSJim Jagielski // apply LineStyle 244*b1cdbd2cSJim Jagielski basegfx::tools::applyLineDashing( 245*b1cdbd2cSJim Jagielski aB2DPolygon, getStrokeAttribute().getDotDashArray(), 246*b1cdbd2cSJim Jagielski &aHairLinePolyPolygon, 0, getStrokeAttribute().getFullDotDashLen()); 247*b1cdbd2cSJim Jagielski } 248*b1cdbd2cSJim Jagielski 249*b1cdbd2cSJim Jagielski const sal_uInt32 nCount(aHairLinePolyPolygon.count()); 250*b1cdbd2cSJim Jagielski 251*b1cdbd2cSJim Jagielski if(!getLineAttribute().isDefault() && getLineAttribute().getWidth()) 252*b1cdbd2cSJim Jagielski { 253*b1cdbd2cSJim Jagielski // create fat line data 254*b1cdbd2cSJim Jagielski const double fHalfLineWidth(getLineAttribute().getWidth() / 2.0); 255*b1cdbd2cSJim Jagielski const basegfx::B2DLineJoin aLineJoin(getLineAttribute().getLineJoin()); 256*b1cdbd2cSJim Jagielski const com::sun::star::drawing::LineCap aLineCap(getLineAttribute().getLineCap()); 257*b1cdbd2cSJim Jagielski basegfx::B2DPolyPolygon aAreaPolyPolygon; 258*b1cdbd2cSJim Jagielski 259*b1cdbd2cSJim Jagielski for(sal_uInt32 a(0L); a < nCount; a++) 260*b1cdbd2cSJim Jagielski { 261*b1cdbd2cSJim Jagielski // New version of createAreaGeometry; now creates bezier polygons 262*b1cdbd2cSJim Jagielski aAreaPolyPolygon.append(basegfx::tools::createAreaGeometry( 263*b1cdbd2cSJim Jagielski aHairLinePolyPolygon.getB2DPolygon(a), 264*b1cdbd2cSJim Jagielski fHalfLineWidth, 265*b1cdbd2cSJim Jagielski aLineJoin, 266*b1cdbd2cSJim Jagielski aLineCap)); 267*b1cdbd2cSJim Jagielski } 268*b1cdbd2cSJim Jagielski 269*b1cdbd2cSJim Jagielski // prepare return value 270*b1cdbd2cSJim Jagielski Primitive2DSequence aRetval(aAreaPolyPolygon.count()); 271*b1cdbd2cSJim Jagielski 272*b1cdbd2cSJim Jagielski // create primitive 273*b1cdbd2cSJim Jagielski for(sal_uInt32 b(0L); b < aAreaPolyPolygon.count(); b++) 274*b1cdbd2cSJim Jagielski { 275*b1cdbd2cSJim Jagielski // put into single polyPolygon primitives to make clear that this is NOT meant 276*b1cdbd2cSJim Jagielski // to be painted as a single PolyPolygon (XORed as fill rule). Alternatively, a 277*b1cdbd2cSJim Jagielski // melting process may be used here one day. 278*b1cdbd2cSJim Jagielski const basegfx::B2DPolyPolygon aNewPolyPolygon(aAreaPolyPolygon.getB2DPolygon(b)); 279*b1cdbd2cSJim Jagielski static bool bTestByUsingRandomColor(false); 280*b1cdbd2cSJim Jagielski const basegfx::BColor aColor(bTestByUsingRandomColor 281*b1cdbd2cSJim Jagielski ? basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0) 282*b1cdbd2cSJim Jagielski : getLineAttribute().getColor()); 283*b1cdbd2cSJim Jagielski const Primitive2DReference xRef(new PolyPolygonColorPrimitive2D(aNewPolyPolygon, aColor)); 284*b1cdbd2cSJim Jagielski aRetval[b] = xRef; 285*b1cdbd2cSJim Jagielski } 286*b1cdbd2cSJim Jagielski 287*b1cdbd2cSJim Jagielski return aRetval; 288*b1cdbd2cSJim Jagielski } 289*b1cdbd2cSJim Jagielski else 290*b1cdbd2cSJim Jagielski { 291*b1cdbd2cSJim Jagielski // prepare return value 292*b1cdbd2cSJim Jagielski const Primitive2DReference xRef( 293*b1cdbd2cSJim Jagielski new PolyPolygonHairlinePrimitive2D( 294*b1cdbd2cSJim Jagielski aHairLinePolyPolygon, 295*b1cdbd2cSJim Jagielski getLineAttribute().getColor())); 296*b1cdbd2cSJim Jagielski 297*b1cdbd2cSJim Jagielski return Primitive2DSequence(&xRef, 1); 298*b1cdbd2cSJim Jagielski } 299*b1cdbd2cSJim Jagielski } 300*b1cdbd2cSJim Jagielski else 301*b1cdbd2cSJim Jagielski { 302*b1cdbd2cSJim Jagielski return Primitive2DSequence(); 303*b1cdbd2cSJim Jagielski } 304*b1cdbd2cSJim Jagielski } 305*b1cdbd2cSJim Jagielski PolygonStrokePrimitive2D(const basegfx::B2DPolygon & rPolygon,const attribute::LineAttribute & rLineAttribute,const attribute::StrokeAttribute & rStrokeAttribute)306*b1cdbd2cSJim Jagielski PolygonStrokePrimitive2D::PolygonStrokePrimitive2D( 307*b1cdbd2cSJim Jagielski const basegfx::B2DPolygon& rPolygon, 308*b1cdbd2cSJim Jagielski const attribute::LineAttribute& rLineAttribute, 309*b1cdbd2cSJim Jagielski const attribute::StrokeAttribute& rStrokeAttribute) 310*b1cdbd2cSJim Jagielski : BufferedDecompositionPrimitive2D(), 311*b1cdbd2cSJim Jagielski maPolygon(rPolygon), 312*b1cdbd2cSJim Jagielski maLineAttribute(rLineAttribute), 313*b1cdbd2cSJim Jagielski maStrokeAttribute(rStrokeAttribute) 314*b1cdbd2cSJim Jagielski { 315*b1cdbd2cSJim Jagielski } 316*b1cdbd2cSJim Jagielski PolygonStrokePrimitive2D(const basegfx::B2DPolygon & rPolygon,const attribute::LineAttribute & rLineAttribute)317*b1cdbd2cSJim Jagielski PolygonStrokePrimitive2D::PolygonStrokePrimitive2D( 318*b1cdbd2cSJim Jagielski const basegfx::B2DPolygon& rPolygon, 319*b1cdbd2cSJim Jagielski const attribute::LineAttribute& rLineAttribute) 320*b1cdbd2cSJim Jagielski : BufferedDecompositionPrimitive2D(), 321*b1cdbd2cSJim Jagielski maPolygon(rPolygon), 322*b1cdbd2cSJim Jagielski maLineAttribute(rLineAttribute), 323*b1cdbd2cSJim Jagielski maStrokeAttribute() 324*b1cdbd2cSJim Jagielski { 325*b1cdbd2cSJim Jagielski } 326*b1cdbd2cSJim Jagielski operator ==(const BasePrimitive2D & rPrimitive) const327*b1cdbd2cSJim Jagielski bool PolygonStrokePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 328*b1cdbd2cSJim Jagielski { 329*b1cdbd2cSJim Jagielski if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 330*b1cdbd2cSJim Jagielski { 331*b1cdbd2cSJim Jagielski const PolygonStrokePrimitive2D& rCompare = (PolygonStrokePrimitive2D&)rPrimitive; 332*b1cdbd2cSJim Jagielski 333*b1cdbd2cSJim Jagielski return (getB2DPolygon() == rCompare.getB2DPolygon() 334*b1cdbd2cSJim Jagielski && getLineAttribute() == rCompare.getLineAttribute() 335*b1cdbd2cSJim Jagielski && getStrokeAttribute() == rCompare.getStrokeAttribute()); 336*b1cdbd2cSJim Jagielski } 337*b1cdbd2cSJim Jagielski 338*b1cdbd2cSJim Jagielski return false; 339*b1cdbd2cSJim Jagielski } 340*b1cdbd2cSJim Jagielski getB2DRange(const geometry::ViewInformation2D & rViewInformation) const341*b1cdbd2cSJim Jagielski basegfx::B2DRange PolygonStrokePrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const 342*b1cdbd2cSJim Jagielski { 343*b1cdbd2cSJim Jagielski basegfx::B2DRange aRetval; 344*b1cdbd2cSJim Jagielski 345*b1cdbd2cSJim Jagielski if(getLineAttribute().getWidth()) 346*b1cdbd2cSJim Jagielski { 347*b1cdbd2cSJim Jagielski bool bUseDecomposition(false); 348*b1cdbd2cSJim Jagielski 349*b1cdbd2cSJim Jagielski if(basegfx::B2DLINEJOIN_MITER == getLineAttribute().getLineJoin()) 350*b1cdbd2cSJim Jagielski { 351*b1cdbd2cSJim Jagielski // if line is mitered, use parent call since mitered line 352*b1cdbd2cSJim Jagielski // geometry may use more space than the geometry grown by half line width 353*b1cdbd2cSJim Jagielski bUseDecomposition = true; 354*b1cdbd2cSJim Jagielski } 355*b1cdbd2cSJim Jagielski 356*b1cdbd2cSJim Jagielski if(!bUseDecomposition && com::sun::star::drawing::LineCap_SQUARE == getLineAttribute().getLineCap()) 357*b1cdbd2cSJim Jagielski { 358*b1cdbd2cSJim Jagielski // when drawing::LineCap_SQUARE is used the below method to grow the polygon 359*b1cdbd2cSJim Jagielski // range by half line width will not work, so use decomposition. Interestingly, 360*b1cdbd2cSJim Jagielski // the grow method below works perfectly for LineCap_ROUND since the grow is in 361*b1cdbd2cSJim Jagielski // all directions and the rounded cap needs the same grow in all directions independent 362*b1cdbd2cSJim Jagielski // from it's orientation. Unfortunately this is not the case for drawing::LineCap_SQUARE 363*b1cdbd2cSJim Jagielski bUseDecomposition = true; 364*b1cdbd2cSJim Jagielski } 365*b1cdbd2cSJim Jagielski 366*b1cdbd2cSJim Jagielski if(bUseDecomposition) 367*b1cdbd2cSJim Jagielski { 368*b1cdbd2cSJim Jagielski // get correct range by using the decomposition fallback, reasons see above cases 369*b1cdbd2cSJim Jagielski aRetval = BufferedDecompositionPrimitive2D::getB2DRange(rViewInformation); 370*b1cdbd2cSJim Jagielski } 371*b1cdbd2cSJim Jagielski else 372*b1cdbd2cSJim Jagielski { 373*b1cdbd2cSJim Jagielski // for all other B2DLINEJOIN_* get the range from the base geometry 374*b1cdbd2cSJim Jagielski // and expand by half the line width 375*b1cdbd2cSJim Jagielski aRetval = getB2DPolygon().getB2DRange(); 376*b1cdbd2cSJim Jagielski aRetval.grow(getLineAttribute().getWidth() * 0.5); 377*b1cdbd2cSJim Jagielski } 378*b1cdbd2cSJim Jagielski } 379*b1cdbd2cSJim Jagielski else 380*b1cdbd2cSJim Jagielski { 381*b1cdbd2cSJim Jagielski // this is a hairline, thus the line width is view-dependent. Get range of polygon 382*b1cdbd2cSJim Jagielski // as base size 383*b1cdbd2cSJim Jagielski aRetval = getB2DPolygon().getB2DRange(); 384*b1cdbd2cSJim Jagielski 385*b1cdbd2cSJim Jagielski if(!aRetval.isEmpty()) 386*b1cdbd2cSJim Jagielski { 387*b1cdbd2cSJim Jagielski // Calculate view-dependent hairline width 388*b1cdbd2cSJim Jagielski const basegfx::B2DVector aDiscreteSize(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0)); 389*b1cdbd2cSJim Jagielski const double fDiscreteHalfLineWidth(aDiscreteSize.getLength() * 0.5); 390*b1cdbd2cSJim Jagielski 391*b1cdbd2cSJim Jagielski if(basegfx::fTools::more(fDiscreteHalfLineWidth, 0.0)) 392*b1cdbd2cSJim Jagielski { 393*b1cdbd2cSJim Jagielski aRetval.grow(fDiscreteHalfLineWidth); 394*b1cdbd2cSJim Jagielski } 395*b1cdbd2cSJim Jagielski } 396*b1cdbd2cSJim Jagielski } 397*b1cdbd2cSJim Jagielski 398*b1cdbd2cSJim Jagielski return aRetval; 399*b1cdbd2cSJim Jagielski } 400*b1cdbd2cSJim Jagielski 401*b1cdbd2cSJim Jagielski // provide unique ID 402*b1cdbd2cSJim Jagielski ImplPrimitrive2DIDBlock(PolygonStrokePrimitive2D, PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D) 403*b1cdbd2cSJim Jagielski 404*b1cdbd2cSJim Jagielski } // end of namespace primitive2d 405*b1cdbd2cSJim Jagielski } // end of namespace drawinglayer 406*b1cdbd2cSJim Jagielski 407*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 408*b1cdbd2cSJim Jagielski 409*b1cdbd2cSJim Jagielski namespace drawinglayer 410*b1cdbd2cSJim Jagielski { 411*b1cdbd2cSJim Jagielski namespace primitive2d 412*b1cdbd2cSJim Jagielski { create2DDecomposition(const geometry::ViewInformation2D &) const413*b1cdbd2cSJim Jagielski Primitive2DSequence PolygonWavePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const 414*b1cdbd2cSJim Jagielski { 415*b1cdbd2cSJim Jagielski Primitive2DSequence aRetval; 416*b1cdbd2cSJim Jagielski 417*b1cdbd2cSJim Jagielski if(getB2DPolygon().count()) 418*b1cdbd2cSJim Jagielski { 419*b1cdbd2cSJim Jagielski const bool bHasWidth(!basegfx::fTools::equalZero(getWaveWidth())); 420*b1cdbd2cSJim Jagielski const bool bHasHeight(!basegfx::fTools::equalZero(getWaveHeight())); 421*b1cdbd2cSJim Jagielski 422*b1cdbd2cSJim Jagielski if(bHasWidth && bHasHeight) 423*b1cdbd2cSJim Jagielski { 424*b1cdbd2cSJim Jagielski // create waveline curve 425*b1cdbd2cSJim Jagielski const basegfx::B2DPolygon aWaveline(basegfx::tools::createWaveline(getB2DPolygon(), getWaveWidth(), getWaveHeight())); 426*b1cdbd2cSJim Jagielski const Primitive2DReference xRef(new PolygonStrokePrimitive2D(aWaveline, getLineAttribute(), getStrokeAttribute())); 427*b1cdbd2cSJim Jagielski aRetval = Primitive2DSequence(&xRef, 1); 428*b1cdbd2cSJim Jagielski } 429*b1cdbd2cSJim Jagielski else 430*b1cdbd2cSJim Jagielski { 431*b1cdbd2cSJim Jagielski // flat waveline, decompose to simple line primitive 432*b1cdbd2cSJim Jagielski const Primitive2DReference xRef(new PolygonStrokePrimitive2D(getB2DPolygon(), getLineAttribute(), getStrokeAttribute())); 433*b1cdbd2cSJim Jagielski aRetval = Primitive2DSequence(&xRef, 1); 434*b1cdbd2cSJim Jagielski } 435*b1cdbd2cSJim Jagielski } 436*b1cdbd2cSJim Jagielski 437*b1cdbd2cSJim Jagielski return aRetval; 438*b1cdbd2cSJim Jagielski } 439*b1cdbd2cSJim Jagielski PolygonWavePrimitive2D(const basegfx::B2DPolygon & rPolygon,const attribute::LineAttribute & rLineAttribute,const attribute::StrokeAttribute & rStrokeAttribute,double fWaveWidth,double fWaveHeight)440*b1cdbd2cSJim Jagielski PolygonWavePrimitive2D::PolygonWavePrimitive2D( 441*b1cdbd2cSJim Jagielski const basegfx::B2DPolygon& rPolygon, 442*b1cdbd2cSJim Jagielski const attribute::LineAttribute& rLineAttribute, 443*b1cdbd2cSJim Jagielski const attribute::StrokeAttribute& rStrokeAttribute, 444*b1cdbd2cSJim Jagielski double fWaveWidth, 445*b1cdbd2cSJim Jagielski double fWaveHeight) 446*b1cdbd2cSJim Jagielski : PolygonStrokePrimitive2D(rPolygon, rLineAttribute, rStrokeAttribute), 447*b1cdbd2cSJim Jagielski mfWaveWidth(fWaveWidth), 448*b1cdbd2cSJim Jagielski mfWaveHeight(fWaveHeight) 449*b1cdbd2cSJim Jagielski { 450*b1cdbd2cSJim Jagielski if(mfWaveWidth < 0.0) 451*b1cdbd2cSJim Jagielski { 452*b1cdbd2cSJim Jagielski mfWaveWidth = 0.0; 453*b1cdbd2cSJim Jagielski } 454*b1cdbd2cSJim Jagielski 455*b1cdbd2cSJim Jagielski if(mfWaveHeight < 0.0) 456*b1cdbd2cSJim Jagielski { 457*b1cdbd2cSJim Jagielski mfWaveHeight = 0.0; 458*b1cdbd2cSJim Jagielski } 459*b1cdbd2cSJim Jagielski } 460*b1cdbd2cSJim Jagielski PolygonWavePrimitive2D(const basegfx::B2DPolygon & rPolygon,const attribute::LineAttribute & rLineAttribute,double fWaveWidth,double fWaveHeight)461*b1cdbd2cSJim Jagielski PolygonWavePrimitive2D::PolygonWavePrimitive2D( 462*b1cdbd2cSJim Jagielski const basegfx::B2DPolygon& rPolygon, 463*b1cdbd2cSJim Jagielski const attribute::LineAttribute& rLineAttribute, 464*b1cdbd2cSJim Jagielski double fWaveWidth, 465*b1cdbd2cSJim Jagielski double fWaveHeight) 466*b1cdbd2cSJim Jagielski : PolygonStrokePrimitive2D(rPolygon, rLineAttribute), 467*b1cdbd2cSJim Jagielski mfWaveWidth(fWaveWidth), 468*b1cdbd2cSJim Jagielski mfWaveHeight(fWaveHeight) 469*b1cdbd2cSJim Jagielski { 470*b1cdbd2cSJim Jagielski if(mfWaveWidth < 0.0) 471*b1cdbd2cSJim Jagielski { 472*b1cdbd2cSJim Jagielski mfWaveWidth = 0.0; 473*b1cdbd2cSJim Jagielski } 474*b1cdbd2cSJim Jagielski 475*b1cdbd2cSJim Jagielski if(mfWaveHeight < 0.0) 476*b1cdbd2cSJim Jagielski { 477*b1cdbd2cSJim Jagielski mfWaveHeight = 0.0; 478*b1cdbd2cSJim Jagielski } 479*b1cdbd2cSJim Jagielski } 480*b1cdbd2cSJim Jagielski operator ==(const BasePrimitive2D & rPrimitive) const481*b1cdbd2cSJim Jagielski bool PolygonWavePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 482*b1cdbd2cSJim Jagielski { 483*b1cdbd2cSJim Jagielski if(PolygonStrokePrimitive2D::operator==(rPrimitive)) 484*b1cdbd2cSJim Jagielski { 485*b1cdbd2cSJim Jagielski const PolygonWavePrimitive2D& rCompare = (PolygonWavePrimitive2D&)rPrimitive; 486*b1cdbd2cSJim Jagielski 487*b1cdbd2cSJim Jagielski return (getWaveWidth() == rCompare.getWaveWidth() 488*b1cdbd2cSJim Jagielski && getWaveHeight() == rCompare.getWaveHeight()); 489*b1cdbd2cSJim Jagielski } 490*b1cdbd2cSJim Jagielski 491*b1cdbd2cSJim Jagielski return false; 492*b1cdbd2cSJim Jagielski } 493*b1cdbd2cSJim Jagielski getB2DRange(const geometry::ViewInformation2D & rViewInformation) const494*b1cdbd2cSJim Jagielski basegfx::B2DRange PolygonWavePrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const 495*b1cdbd2cSJim Jagielski { 496*b1cdbd2cSJim Jagielski // get range of parent 497*b1cdbd2cSJim Jagielski basegfx::B2DRange aRetval(PolygonStrokePrimitive2D::getB2DRange(rViewInformation)); 498*b1cdbd2cSJim Jagielski 499*b1cdbd2cSJim Jagielski // if WaveHeight, grow by it 500*b1cdbd2cSJim Jagielski if(basegfx::fTools::more(getWaveHeight(), 0.0)) 501*b1cdbd2cSJim Jagielski { 502*b1cdbd2cSJim Jagielski aRetval.grow(getWaveHeight()); 503*b1cdbd2cSJim Jagielski } 504*b1cdbd2cSJim Jagielski 505*b1cdbd2cSJim Jagielski // if line width, grow by it 506*b1cdbd2cSJim Jagielski if(basegfx::fTools::more(getLineAttribute().getWidth(), 0.0)) 507*b1cdbd2cSJim Jagielski { 508*b1cdbd2cSJim Jagielski aRetval.grow(getLineAttribute().getWidth() * 0.5); 509*b1cdbd2cSJim Jagielski } 510*b1cdbd2cSJim Jagielski 511*b1cdbd2cSJim Jagielski return aRetval; 512*b1cdbd2cSJim Jagielski } 513*b1cdbd2cSJim Jagielski 514*b1cdbd2cSJim Jagielski // provide unique ID 515*b1cdbd2cSJim Jagielski ImplPrimitrive2DIDBlock(PolygonWavePrimitive2D, PRIMITIVE2D_ID_POLYGONWAVEPRIMITIVE2D) 516*b1cdbd2cSJim Jagielski 517*b1cdbd2cSJim Jagielski } // end of namespace primitive2d 518*b1cdbd2cSJim Jagielski } // end of namespace drawinglayer 519*b1cdbd2cSJim Jagielski 520*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 521*b1cdbd2cSJim Jagielski 522*b1cdbd2cSJim Jagielski namespace drawinglayer 523*b1cdbd2cSJim Jagielski { 524*b1cdbd2cSJim Jagielski namespace primitive2d 525*b1cdbd2cSJim Jagielski { create2DDecomposition(const geometry::ViewInformation2D &) const526*b1cdbd2cSJim Jagielski Primitive2DSequence PolygonStrokeArrowPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const 527*b1cdbd2cSJim Jagielski { 528*b1cdbd2cSJim Jagielski // copy local polygon, it may be changed 529*b1cdbd2cSJim Jagielski basegfx::B2DPolygon aLocalPolygon(getB2DPolygon()); 530*b1cdbd2cSJim Jagielski basegfx::B2DPolyPolygon aArrowA; 531*b1cdbd2cSJim Jagielski basegfx::B2DPolyPolygon aArrowB; 532*b1cdbd2cSJim Jagielski 533*b1cdbd2cSJim Jagielski if(!aLocalPolygon.isClosed()) 534*b1cdbd2cSJim Jagielski { 535*b1cdbd2cSJim Jagielski // apply arrows 536*b1cdbd2cSJim Jagielski const double fPolyLength(basegfx::tools::getLength(aLocalPolygon)); 537*b1cdbd2cSJim Jagielski double fStart(0.0); 538*b1cdbd2cSJim Jagielski double fEnd(0.0); 539*b1cdbd2cSJim Jagielski double fStartOverlap(0.0); 540*b1cdbd2cSJim Jagielski double fEndOverlap(0.0); 541*b1cdbd2cSJim Jagielski 542*b1cdbd2cSJim Jagielski if(!getStart().isDefault() && getStart().isActive()) 543*b1cdbd2cSJim Jagielski { 544*b1cdbd2cSJim Jagielski // create start arrow primitive and consume 545*b1cdbd2cSJim Jagielski aArrowA = basegfx::tools::createAreaGeometryForLineStartEnd( 546*b1cdbd2cSJim Jagielski aLocalPolygon, getStart().getB2DPolyPolygon(), true, getStart().getWidth(), 547*b1cdbd2cSJim Jagielski fPolyLength, getStart().isCentered() ? 0.5 : 0.0, &fStart); 548*b1cdbd2cSJim Jagielski 549*b1cdbd2cSJim Jagielski // create some overlapping, compromise between straight and peaked markers 550*b1cdbd2cSJim Jagielski // best for marker width 0.3cm and marker line width 0.02cm 551*b1cdbd2cSJim Jagielski fStartOverlap = getStart().getWidth() / 15.0; 552*b1cdbd2cSJim Jagielski } 553*b1cdbd2cSJim Jagielski 554*b1cdbd2cSJim Jagielski if(!getEnd().isDefault() && getEnd().isActive()) 555*b1cdbd2cSJim Jagielski { 556*b1cdbd2cSJim Jagielski // create end arrow primitive and consume 557*b1cdbd2cSJim Jagielski aArrowB = basegfx::tools::createAreaGeometryForLineStartEnd( 558*b1cdbd2cSJim Jagielski aLocalPolygon, getEnd().getB2DPolyPolygon(), false, getEnd().getWidth(), 559*b1cdbd2cSJim Jagielski fPolyLength, getEnd().isCentered() ? 0.5 : 0.0, &fEnd); 560*b1cdbd2cSJim Jagielski 561*b1cdbd2cSJim Jagielski // create some overlapping 562*b1cdbd2cSJim Jagielski fEndOverlap = getEnd().getWidth() / 15.0; 563*b1cdbd2cSJim Jagielski } 564*b1cdbd2cSJim Jagielski 565*b1cdbd2cSJim Jagielski if(0.0 != fStart || 0.0 != fEnd) 566*b1cdbd2cSJim Jagielski { 567*b1cdbd2cSJim Jagielski // build new poly, consume something from old poly 568*b1cdbd2cSJim Jagielski aLocalPolygon = basegfx::tools::getSnippetAbsolute(aLocalPolygon, fStart-fStartOverlap, fPolyLength - fEnd + fEndOverlap, fPolyLength); 569*b1cdbd2cSJim Jagielski } 570*b1cdbd2cSJim Jagielski } 571*b1cdbd2cSJim Jagielski 572*b1cdbd2cSJim Jagielski // prepare return value 573*b1cdbd2cSJim Jagielski Primitive2DSequence aRetval(1L + (aArrowA.count() ? 1L : 0L) + (aArrowB.count() ? 1L : 0L)); 574*b1cdbd2cSJim Jagielski sal_uInt32 nInd(0L); 575*b1cdbd2cSJim Jagielski 576*b1cdbd2cSJim Jagielski // add shaft 577*b1cdbd2cSJim Jagielski const Primitive2DReference xRefShaft(new 578*b1cdbd2cSJim Jagielski PolygonStrokePrimitive2D( 579*b1cdbd2cSJim Jagielski aLocalPolygon, getLineAttribute(), getStrokeAttribute())); 580*b1cdbd2cSJim Jagielski aRetval[nInd++] = xRefShaft; 581*b1cdbd2cSJim Jagielski 582*b1cdbd2cSJim Jagielski if(aArrowA.count()) 583*b1cdbd2cSJim Jagielski { 584*b1cdbd2cSJim Jagielski const Primitive2DReference xRefA( 585*b1cdbd2cSJim Jagielski new PolyPolygonColorPrimitive2D( 586*b1cdbd2cSJim Jagielski aArrowA, getLineAttribute().getColor())); 587*b1cdbd2cSJim Jagielski aRetval[nInd++] = xRefA; 588*b1cdbd2cSJim Jagielski } 589*b1cdbd2cSJim Jagielski 590*b1cdbd2cSJim Jagielski if(aArrowB.count()) 591*b1cdbd2cSJim Jagielski { 592*b1cdbd2cSJim Jagielski const Primitive2DReference xRefB( 593*b1cdbd2cSJim Jagielski new PolyPolygonColorPrimitive2D( 594*b1cdbd2cSJim Jagielski aArrowB, getLineAttribute().getColor())); 595*b1cdbd2cSJim Jagielski aRetval[nInd++] = xRefB; 596*b1cdbd2cSJim Jagielski } 597*b1cdbd2cSJim Jagielski 598*b1cdbd2cSJim Jagielski return aRetval; 599*b1cdbd2cSJim Jagielski } 600*b1cdbd2cSJim Jagielski PolygonStrokeArrowPrimitive2D(const basegfx::B2DPolygon & rPolygon,const attribute::LineAttribute & rLineAttribute,const attribute::StrokeAttribute & rStrokeAttribute,const attribute::LineStartEndAttribute & rStart,const attribute::LineStartEndAttribute & rEnd)601*b1cdbd2cSJim Jagielski PolygonStrokeArrowPrimitive2D::PolygonStrokeArrowPrimitive2D( 602*b1cdbd2cSJim Jagielski const basegfx::B2DPolygon& rPolygon, 603*b1cdbd2cSJim Jagielski const attribute::LineAttribute& rLineAttribute, 604*b1cdbd2cSJim Jagielski const attribute::StrokeAttribute& rStrokeAttribute, 605*b1cdbd2cSJim Jagielski const attribute::LineStartEndAttribute& rStart, 606*b1cdbd2cSJim Jagielski const attribute::LineStartEndAttribute& rEnd) 607*b1cdbd2cSJim Jagielski : PolygonStrokePrimitive2D(rPolygon, rLineAttribute, rStrokeAttribute), 608*b1cdbd2cSJim Jagielski maStart(rStart), 609*b1cdbd2cSJim Jagielski maEnd(rEnd) 610*b1cdbd2cSJim Jagielski { 611*b1cdbd2cSJim Jagielski } 612*b1cdbd2cSJim Jagielski PolygonStrokeArrowPrimitive2D(const basegfx::B2DPolygon & rPolygon,const attribute::LineAttribute & rLineAttribute,const attribute::LineStartEndAttribute & rStart,const attribute::LineStartEndAttribute & rEnd)613*b1cdbd2cSJim Jagielski PolygonStrokeArrowPrimitive2D::PolygonStrokeArrowPrimitive2D( 614*b1cdbd2cSJim Jagielski const basegfx::B2DPolygon& rPolygon, 615*b1cdbd2cSJim Jagielski const attribute::LineAttribute& rLineAttribute, 616*b1cdbd2cSJim Jagielski const attribute::LineStartEndAttribute& rStart, 617*b1cdbd2cSJim Jagielski const attribute::LineStartEndAttribute& rEnd) 618*b1cdbd2cSJim Jagielski : PolygonStrokePrimitive2D(rPolygon, rLineAttribute), 619*b1cdbd2cSJim Jagielski maStart(rStart), 620*b1cdbd2cSJim Jagielski maEnd(rEnd) 621*b1cdbd2cSJim Jagielski { 622*b1cdbd2cSJim Jagielski } 623*b1cdbd2cSJim Jagielski operator ==(const BasePrimitive2D & rPrimitive) const624*b1cdbd2cSJim Jagielski bool PolygonStrokeArrowPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 625*b1cdbd2cSJim Jagielski { 626*b1cdbd2cSJim Jagielski if(PolygonStrokePrimitive2D::operator==(rPrimitive)) 627*b1cdbd2cSJim Jagielski { 628*b1cdbd2cSJim Jagielski const PolygonStrokeArrowPrimitive2D& rCompare = (PolygonStrokeArrowPrimitive2D&)rPrimitive; 629*b1cdbd2cSJim Jagielski 630*b1cdbd2cSJim Jagielski return (getStart() == rCompare.getStart() 631*b1cdbd2cSJim Jagielski && getEnd() == rCompare.getEnd()); 632*b1cdbd2cSJim Jagielski } 633*b1cdbd2cSJim Jagielski 634*b1cdbd2cSJim Jagielski return false; 635*b1cdbd2cSJim Jagielski } 636*b1cdbd2cSJim Jagielski getB2DRange(const geometry::ViewInformation2D & rViewInformation) const637*b1cdbd2cSJim Jagielski basegfx::B2DRange PolygonStrokeArrowPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const 638*b1cdbd2cSJim Jagielski { 639*b1cdbd2cSJim Jagielski basegfx::B2DRange aRetval; 640*b1cdbd2cSJim Jagielski 641*b1cdbd2cSJim Jagielski if(getStart().isActive() || getEnd().isActive()) 642*b1cdbd2cSJim Jagielski { 643*b1cdbd2cSJim Jagielski // use decomposition when line start/end is used 644*b1cdbd2cSJim Jagielski return BufferedDecompositionPrimitive2D::getB2DRange(rViewInformation); 645*b1cdbd2cSJim Jagielski } 646*b1cdbd2cSJim Jagielski else 647*b1cdbd2cSJim Jagielski { 648*b1cdbd2cSJim Jagielski // get range from parent 649*b1cdbd2cSJim Jagielski return PolygonStrokePrimitive2D::getB2DRange(rViewInformation); 650*b1cdbd2cSJim Jagielski } 651*b1cdbd2cSJim Jagielski } 652*b1cdbd2cSJim Jagielski 653*b1cdbd2cSJim Jagielski // provide unique ID 654*b1cdbd2cSJim Jagielski ImplPrimitrive2DIDBlock(PolygonStrokeArrowPrimitive2D, PRIMITIVE2D_ID_POLYGONSTROKEARROWPRIMITIVE2D) 655*b1cdbd2cSJim Jagielski 656*b1cdbd2cSJim Jagielski } // end of namespace primitive2d 657*b1cdbd2cSJim Jagielski } // end of namespace drawinglayer 658*b1cdbd2cSJim Jagielski 659*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 660*b1cdbd2cSJim Jagielski // eof 661