1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_basegfx.hxx" 30*cdf0e10cSrcweir #include <osl/diagnose.h> 31*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx> 32*cdf0e10cSrcweir #include <basegfx/point/b2dpoint.hxx> 33*cdf0e10cSrcweir #include <basegfx/vector/b2dvector.hxx> 34*cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx> 35*cdf0e10cSrcweir #include <basegfx/curve/b2dcubicbezier.hxx> 36*cdf0e10cSrcweir #include <rtl/instance.hxx> 37*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx> 38*cdf0e10cSrcweir #include <boost/scoped_ptr.hpp> 39*cdf0e10cSrcweir #include <vector> 40*cdf0e10cSrcweir #include <algorithm> 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir struct CoordinateData2D : public basegfx::B2DPoint 45*cdf0e10cSrcweir { 46*cdf0e10cSrcweir public: 47*cdf0e10cSrcweir CoordinateData2D() {} 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir explicit CoordinateData2D(const basegfx::B2DPoint& rData) 50*cdf0e10cSrcweir : B2DPoint(rData) 51*cdf0e10cSrcweir {} 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir CoordinateData2D& operator=(const basegfx::B2DPoint& rData) 54*cdf0e10cSrcweir { 55*cdf0e10cSrcweir B2DPoint::operator=(rData); 56*cdf0e10cSrcweir return *this; 57*cdf0e10cSrcweir } 58*cdf0e10cSrcweir 59*cdf0e10cSrcweir void transform(const basegfx::B2DHomMatrix& rMatrix) 60*cdf0e10cSrcweir { 61*cdf0e10cSrcweir *this *= rMatrix; 62*cdf0e10cSrcweir } 63*cdf0e10cSrcweir }; 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir class CoordinateDataArray2D 68*cdf0e10cSrcweir { 69*cdf0e10cSrcweir typedef ::std::vector< CoordinateData2D > CoordinateData2DVector; 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir CoordinateData2DVector maVector; 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir public: 74*cdf0e10cSrcweir explicit CoordinateDataArray2D(sal_uInt32 nCount) 75*cdf0e10cSrcweir : maVector(nCount) 76*cdf0e10cSrcweir { 77*cdf0e10cSrcweir } 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir explicit CoordinateDataArray2D(const CoordinateDataArray2D& rOriginal) 80*cdf0e10cSrcweir : maVector(rOriginal.maVector) 81*cdf0e10cSrcweir { 82*cdf0e10cSrcweir } 83*cdf0e10cSrcweir 84*cdf0e10cSrcweir CoordinateDataArray2D(const CoordinateDataArray2D& rOriginal, sal_uInt32 nIndex, sal_uInt32 nCount) 85*cdf0e10cSrcweir : maVector(rOriginal.maVector.begin() + nIndex, rOriginal.maVector.begin() + (nIndex + nCount)) 86*cdf0e10cSrcweir { 87*cdf0e10cSrcweir } 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir sal_uInt32 count() const 90*cdf0e10cSrcweir { 91*cdf0e10cSrcweir return maVector.size(); 92*cdf0e10cSrcweir } 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir bool operator==(const CoordinateDataArray2D& rCandidate) const 95*cdf0e10cSrcweir { 96*cdf0e10cSrcweir return (maVector == rCandidate.maVector); 97*cdf0e10cSrcweir } 98*cdf0e10cSrcweir 99*cdf0e10cSrcweir const basegfx::B2DPoint& getCoordinate(sal_uInt32 nIndex) const 100*cdf0e10cSrcweir { 101*cdf0e10cSrcweir return maVector[nIndex]; 102*cdf0e10cSrcweir } 103*cdf0e10cSrcweir 104*cdf0e10cSrcweir void setCoordinate(sal_uInt32 nIndex, const basegfx::B2DPoint& rValue) 105*cdf0e10cSrcweir { 106*cdf0e10cSrcweir maVector[nIndex] = rValue; 107*cdf0e10cSrcweir } 108*cdf0e10cSrcweir 109*cdf0e10cSrcweir void reserve(sal_uInt32 nCount) 110*cdf0e10cSrcweir { 111*cdf0e10cSrcweir maVector.reserve(nCount); 112*cdf0e10cSrcweir } 113*cdf0e10cSrcweir 114*cdf0e10cSrcweir void append(const CoordinateData2D& rValue) 115*cdf0e10cSrcweir { 116*cdf0e10cSrcweir maVector.push_back(rValue); 117*cdf0e10cSrcweir } 118*cdf0e10cSrcweir 119*cdf0e10cSrcweir void insert(sal_uInt32 nIndex, const CoordinateData2D& rValue, sal_uInt32 nCount) 120*cdf0e10cSrcweir { 121*cdf0e10cSrcweir if(nCount) 122*cdf0e10cSrcweir { 123*cdf0e10cSrcweir // add nCount copies of rValue 124*cdf0e10cSrcweir CoordinateData2DVector::iterator aIndex(maVector.begin()); 125*cdf0e10cSrcweir aIndex += nIndex; 126*cdf0e10cSrcweir maVector.insert(aIndex, nCount, rValue); 127*cdf0e10cSrcweir } 128*cdf0e10cSrcweir } 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir void insert(sal_uInt32 nIndex, const CoordinateDataArray2D& rSource) 131*cdf0e10cSrcweir { 132*cdf0e10cSrcweir const sal_uInt32 nCount(rSource.maVector.size()); 133*cdf0e10cSrcweir 134*cdf0e10cSrcweir if(nCount) 135*cdf0e10cSrcweir { 136*cdf0e10cSrcweir // insert data 137*cdf0e10cSrcweir CoordinateData2DVector::iterator aIndex(maVector.begin()); 138*cdf0e10cSrcweir aIndex += nIndex; 139*cdf0e10cSrcweir CoordinateData2DVector::const_iterator aStart(rSource.maVector.begin()); 140*cdf0e10cSrcweir CoordinateData2DVector::const_iterator aEnd(rSource.maVector.end()); 141*cdf0e10cSrcweir maVector.insert(aIndex, aStart, aEnd); 142*cdf0e10cSrcweir } 143*cdf0e10cSrcweir } 144*cdf0e10cSrcweir 145*cdf0e10cSrcweir void remove(sal_uInt32 nIndex, sal_uInt32 nCount) 146*cdf0e10cSrcweir { 147*cdf0e10cSrcweir if(nCount) 148*cdf0e10cSrcweir { 149*cdf0e10cSrcweir // remove point data 150*cdf0e10cSrcweir CoordinateData2DVector::iterator aStart(maVector.begin()); 151*cdf0e10cSrcweir aStart += nIndex; 152*cdf0e10cSrcweir const CoordinateData2DVector::iterator aEnd(aStart + nCount); 153*cdf0e10cSrcweir maVector.erase(aStart, aEnd); 154*cdf0e10cSrcweir } 155*cdf0e10cSrcweir } 156*cdf0e10cSrcweir 157*cdf0e10cSrcweir void flip(bool bIsClosed) 158*cdf0e10cSrcweir { 159*cdf0e10cSrcweir if(maVector.size() > 1) 160*cdf0e10cSrcweir { 161*cdf0e10cSrcweir // to keep the same point at index 0, just flip all points except the 162*cdf0e10cSrcweir // first one when closed 163*cdf0e10cSrcweir const sal_uInt32 nHalfSize(bIsClosed ? (maVector.size() - 1) >> 1 : maVector.size() >> 1); 164*cdf0e10cSrcweir CoordinateData2DVector::iterator aStart(bIsClosed ? maVector.begin() + 1 : maVector.begin()); 165*cdf0e10cSrcweir CoordinateData2DVector::iterator aEnd(maVector.end() - 1); 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir for(sal_uInt32 a(0); a < nHalfSize; a++) 168*cdf0e10cSrcweir { 169*cdf0e10cSrcweir ::std::swap(*aStart, *aEnd); 170*cdf0e10cSrcweir aStart++; 171*cdf0e10cSrcweir aEnd--; 172*cdf0e10cSrcweir } 173*cdf0e10cSrcweir } 174*cdf0e10cSrcweir } 175*cdf0e10cSrcweir 176*cdf0e10cSrcweir void removeDoublePointsAtBeginEnd() 177*cdf0e10cSrcweir { 178*cdf0e10cSrcweir // remove from end as long as there are at least two points 179*cdf0e10cSrcweir // and begin/end are equal 180*cdf0e10cSrcweir while((maVector.size() > 1) && (maVector[0] == maVector[maVector.size() - 1])) 181*cdf0e10cSrcweir { 182*cdf0e10cSrcweir maVector.pop_back(); 183*cdf0e10cSrcweir } 184*cdf0e10cSrcweir } 185*cdf0e10cSrcweir 186*cdf0e10cSrcweir void removeDoublePointsWholeTrack() 187*cdf0e10cSrcweir { 188*cdf0e10cSrcweir sal_uInt32 nIndex(0); 189*cdf0e10cSrcweir 190*cdf0e10cSrcweir // test as long as there are at least two points and as long as the index 191*cdf0e10cSrcweir // is smaller or equal second last point 192*cdf0e10cSrcweir while((maVector.size() > 1) && (nIndex <= maVector.size() - 2)) 193*cdf0e10cSrcweir { 194*cdf0e10cSrcweir if(maVector[nIndex] == maVector[nIndex + 1]) 195*cdf0e10cSrcweir { 196*cdf0e10cSrcweir // if next is same as index, delete next 197*cdf0e10cSrcweir maVector.erase(maVector.begin() + (nIndex + 1)); 198*cdf0e10cSrcweir } 199*cdf0e10cSrcweir else 200*cdf0e10cSrcweir { 201*cdf0e10cSrcweir // if different, step forward 202*cdf0e10cSrcweir nIndex++; 203*cdf0e10cSrcweir } 204*cdf0e10cSrcweir } 205*cdf0e10cSrcweir } 206*cdf0e10cSrcweir 207*cdf0e10cSrcweir void transform(const basegfx::B2DHomMatrix& rMatrix) 208*cdf0e10cSrcweir { 209*cdf0e10cSrcweir CoordinateData2DVector::iterator aStart(maVector.begin()); 210*cdf0e10cSrcweir CoordinateData2DVector::iterator aEnd(maVector.end()); 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir for(; aStart != aEnd; aStart++) 213*cdf0e10cSrcweir { 214*cdf0e10cSrcweir aStart->transform(rMatrix); 215*cdf0e10cSrcweir } 216*cdf0e10cSrcweir } 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir const basegfx::B2DPoint* begin() const 219*cdf0e10cSrcweir { 220*cdf0e10cSrcweir if(maVector.empty()) 221*cdf0e10cSrcweir return 0; 222*cdf0e10cSrcweir else 223*cdf0e10cSrcweir return &maVector.front(); 224*cdf0e10cSrcweir } 225*cdf0e10cSrcweir 226*cdf0e10cSrcweir const basegfx::B2DPoint* end() const 227*cdf0e10cSrcweir { 228*cdf0e10cSrcweir if(maVector.empty()) 229*cdf0e10cSrcweir return 0; 230*cdf0e10cSrcweir else 231*cdf0e10cSrcweir return (&maVector.back())+1; 232*cdf0e10cSrcweir } 233*cdf0e10cSrcweir 234*cdf0e10cSrcweir basegfx::B2DPoint* begin() 235*cdf0e10cSrcweir { 236*cdf0e10cSrcweir if(maVector.empty()) 237*cdf0e10cSrcweir return 0; 238*cdf0e10cSrcweir else 239*cdf0e10cSrcweir return &maVector.front(); 240*cdf0e10cSrcweir } 241*cdf0e10cSrcweir 242*cdf0e10cSrcweir basegfx::B2DPoint* end() 243*cdf0e10cSrcweir { 244*cdf0e10cSrcweir if(maVector.empty()) 245*cdf0e10cSrcweir return 0; 246*cdf0e10cSrcweir else 247*cdf0e10cSrcweir return (&maVector.back())+1; 248*cdf0e10cSrcweir } 249*cdf0e10cSrcweir }; 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 252*cdf0e10cSrcweir 253*cdf0e10cSrcweir class ControlVectorPair2D 254*cdf0e10cSrcweir { 255*cdf0e10cSrcweir basegfx::B2DVector maPrevVector; 256*cdf0e10cSrcweir basegfx::B2DVector maNextVector; 257*cdf0e10cSrcweir 258*cdf0e10cSrcweir public: 259*cdf0e10cSrcweir const basegfx::B2DVector& getPrevVector() const 260*cdf0e10cSrcweir { 261*cdf0e10cSrcweir return maPrevVector; 262*cdf0e10cSrcweir } 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir void setPrevVector(const basegfx::B2DVector& rValue) 265*cdf0e10cSrcweir { 266*cdf0e10cSrcweir if(rValue != maPrevVector) 267*cdf0e10cSrcweir maPrevVector = rValue; 268*cdf0e10cSrcweir } 269*cdf0e10cSrcweir 270*cdf0e10cSrcweir const basegfx::B2DVector& getNextVector() const 271*cdf0e10cSrcweir { 272*cdf0e10cSrcweir return maNextVector; 273*cdf0e10cSrcweir } 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir void setNextVector(const basegfx::B2DVector& rValue) 276*cdf0e10cSrcweir { 277*cdf0e10cSrcweir if(rValue != maNextVector) 278*cdf0e10cSrcweir maNextVector = rValue; 279*cdf0e10cSrcweir } 280*cdf0e10cSrcweir 281*cdf0e10cSrcweir bool operator==(const ControlVectorPair2D& rData) const 282*cdf0e10cSrcweir { 283*cdf0e10cSrcweir return (maPrevVector == rData.getPrevVector() && maNextVector == rData.getNextVector()); 284*cdf0e10cSrcweir } 285*cdf0e10cSrcweir 286*cdf0e10cSrcweir void flip() 287*cdf0e10cSrcweir { 288*cdf0e10cSrcweir ::std::swap(maPrevVector, maNextVector); 289*cdf0e10cSrcweir } 290*cdf0e10cSrcweir }; 291*cdf0e10cSrcweir 292*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 293*cdf0e10cSrcweir 294*cdf0e10cSrcweir class ControlVectorArray2D 295*cdf0e10cSrcweir { 296*cdf0e10cSrcweir typedef ::std::vector< ControlVectorPair2D > ControlVectorPair2DVector; 297*cdf0e10cSrcweir 298*cdf0e10cSrcweir ControlVectorPair2DVector maVector; 299*cdf0e10cSrcweir sal_uInt32 mnUsedVectors; 300*cdf0e10cSrcweir 301*cdf0e10cSrcweir public: 302*cdf0e10cSrcweir explicit ControlVectorArray2D(sal_uInt32 nCount) 303*cdf0e10cSrcweir : maVector(nCount), 304*cdf0e10cSrcweir mnUsedVectors(0) 305*cdf0e10cSrcweir {} 306*cdf0e10cSrcweir 307*cdf0e10cSrcweir ControlVectorArray2D(const ControlVectorArray2D& rOriginal, sal_uInt32 nIndex, sal_uInt32 nCount) 308*cdf0e10cSrcweir : maVector(), 309*cdf0e10cSrcweir mnUsedVectors(0) 310*cdf0e10cSrcweir { 311*cdf0e10cSrcweir ControlVectorPair2DVector::const_iterator aStart(rOriginal.maVector.begin()); 312*cdf0e10cSrcweir aStart += nIndex; 313*cdf0e10cSrcweir ControlVectorPair2DVector::const_iterator aEnd(aStart); 314*cdf0e10cSrcweir aEnd += nCount; 315*cdf0e10cSrcweir maVector.reserve(nCount); 316*cdf0e10cSrcweir 317*cdf0e10cSrcweir for(; aStart != aEnd; aStart++) 318*cdf0e10cSrcweir { 319*cdf0e10cSrcweir if(!aStart->getPrevVector().equalZero()) 320*cdf0e10cSrcweir mnUsedVectors++; 321*cdf0e10cSrcweir 322*cdf0e10cSrcweir if(!aStart->getNextVector().equalZero()) 323*cdf0e10cSrcweir mnUsedVectors++; 324*cdf0e10cSrcweir 325*cdf0e10cSrcweir maVector.push_back(*aStart); 326*cdf0e10cSrcweir } 327*cdf0e10cSrcweir } 328*cdf0e10cSrcweir 329*cdf0e10cSrcweir sal_uInt32 count() const 330*cdf0e10cSrcweir { 331*cdf0e10cSrcweir return maVector.size(); 332*cdf0e10cSrcweir } 333*cdf0e10cSrcweir 334*cdf0e10cSrcweir bool operator==(const ControlVectorArray2D& rCandidate) const 335*cdf0e10cSrcweir { 336*cdf0e10cSrcweir return (maVector == rCandidate.maVector); 337*cdf0e10cSrcweir } 338*cdf0e10cSrcweir 339*cdf0e10cSrcweir bool isUsed() const 340*cdf0e10cSrcweir { 341*cdf0e10cSrcweir return (0 != mnUsedVectors); 342*cdf0e10cSrcweir } 343*cdf0e10cSrcweir 344*cdf0e10cSrcweir const basegfx::B2DVector& getPrevVector(sal_uInt32 nIndex) const 345*cdf0e10cSrcweir { 346*cdf0e10cSrcweir return maVector[nIndex].getPrevVector(); 347*cdf0e10cSrcweir } 348*cdf0e10cSrcweir 349*cdf0e10cSrcweir void setPrevVector(sal_uInt32 nIndex, const basegfx::B2DVector& rValue) 350*cdf0e10cSrcweir { 351*cdf0e10cSrcweir bool bWasUsed(mnUsedVectors && !maVector[nIndex].getPrevVector().equalZero()); 352*cdf0e10cSrcweir bool bIsUsed(!rValue.equalZero()); 353*cdf0e10cSrcweir 354*cdf0e10cSrcweir if(bWasUsed) 355*cdf0e10cSrcweir { 356*cdf0e10cSrcweir if(bIsUsed) 357*cdf0e10cSrcweir { 358*cdf0e10cSrcweir maVector[nIndex].setPrevVector(rValue); 359*cdf0e10cSrcweir } 360*cdf0e10cSrcweir else 361*cdf0e10cSrcweir { 362*cdf0e10cSrcweir maVector[nIndex].setPrevVector(basegfx::B2DVector::getEmptyVector()); 363*cdf0e10cSrcweir mnUsedVectors--; 364*cdf0e10cSrcweir } 365*cdf0e10cSrcweir } 366*cdf0e10cSrcweir else 367*cdf0e10cSrcweir { 368*cdf0e10cSrcweir if(bIsUsed) 369*cdf0e10cSrcweir { 370*cdf0e10cSrcweir maVector[nIndex].setPrevVector(rValue); 371*cdf0e10cSrcweir mnUsedVectors++; 372*cdf0e10cSrcweir } 373*cdf0e10cSrcweir } 374*cdf0e10cSrcweir } 375*cdf0e10cSrcweir 376*cdf0e10cSrcweir const basegfx::B2DVector& getNextVector(sal_uInt32 nIndex) const 377*cdf0e10cSrcweir { 378*cdf0e10cSrcweir return maVector[nIndex].getNextVector(); 379*cdf0e10cSrcweir } 380*cdf0e10cSrcweir 381*cdf0e10cSrcweir void setNextVector(sal_uInt32 nIndex, const basegfx::B2DVector& rValue) 382*cdf0e10cSrcweir { 383*cdf0e10cSrcweir bool bWasUsed(mnUsedVectors && !maVector[nIndex].getNextVector().equalZero()); 384*cdf0e10cSrcweir bool bIsUsed(!rValue.equalZero()); 385*cdf0e10cSrcweir 386*cdf0e10cSrcweir if(bWasUsed) 387*cdf0e10cSrcweir { 388*cdf0e10cSrcweir if(bIsUsed) 389*cdf0e10cSrcweir { 390*cdf0e10cSrcweir maVector[nIndex].setNextVector(rValue); 391*cdf0e10cSrcweir } 392*cdf0e10cSrcweir else 393*cdf0e10cSrcweir { 394*cdf0e10cSrcweir maVector[nIndex].setNextVector(basegfx::B2DVector::getEmptyVector()); 395*cdf0e10cSrcweir mnUsedVectors--; 396*cdf0e10cSrcweir } 397*cdf0e10cSrcweir } 398*cdf0e10cSrcweir else 399*cdf0e10cSrcweir { 400*cdf0e10cSrcweir if(bIsUsed) 401*cdf0e10cSrcweir { 402*cdf0e10cSrcweir maVector[nIndex].setNextVector(rValue); 403*cdf0e10cSrcweir mnUsedVectors++; 404*cdf0e10cSrcweir } 405*cdf0e10cSrcweir } 406*cdf0e10cSrcweir } 407*cdf0e10cSrcweir 408*cdf0e10cSrcweir void append(const ControlVectorPair2D& rValue) 409*cdf0e10cSrcweir { 410*cdf0e10cSrcweir maVector.push_back(rValue); 411*cdf0e10cSrcweir 412*cdf0e10cSrcweir if(!rValue.getPrevVector().equalZero()) 413*cdf0e10cSrcweir mnUsedVectors += 1; 414*cdf0e10cSrcweir 415*cdf0e10cSrcweir if(!rValue.getNextVector().equalZero()) 416*cdf0e10cSrcweir mnUsedVectors += 1; 417*cdf0e10cSrcweir } 418*cdf0e10cSrcweir 419*cdf0e10cSrcweir void insert(sal_uInt32 nIndex, const ControlVectorPair2D& rValue, sal_uInt32 nCount) 420*cdf0e10cSrcweir { 421*cdf0e10cSrcweir if(nCount) 422*cdf0e10cSrcweir { 423*cdf0e10cSrcweir // add nCount copies of rValue 424*cdf0e10cSrcweir ControlVectorPair2DVector::iterator aIndex(maVector.begin()); 425*cdf0e10cSrcweir aIndex += nIndex; 426*cdf0e10cSrcweir maVector.insert(aIndex, nCount, rValue); 427*cdf0e10cSrcweir 428*cdf0e10cSrcweir if(!rValue.getPrevVector().equalZero()) 429*cdf0e10cSrcweir mnUsedVectors += nCount; 430*cdf0e10cSrcweir 431*cdf0e10cSrcweir if(!rValue.getNextVector().equalZero()) 432*cdf0e10cSrcweir mnUsedVectors += nCount; 433*cdf0e10cSrcweir } 434*cdf0e10cSrcweir } 435*cdf0e10cSrcweir 436*cdf0e10cSrcweir void insert(sal_uInt32 nIndex, const ControlVectorArray2D& rSource) 437*cdf0e10cSrcweir { 438*cdf0e10cSrcweir const sal_uInt32 nCount(rSource.maVector.size()); 439*cdf0e10cSrcweir 440*cdf0e10cSrcweir if(nCount) 441*cdf0e10cSrcweir { 442*cdf0e10cSrcweir // insert data 443*cdf0e10cSrcweir ControlVectorPair2DVector::iterator aIndex(maVector.begin()); 444*cdf0e10cSrcweir aIndex += nIndex; 445*cdf0e10cSrcweir ControlVectorPair2DVector::const_iterator aStart(rSource.maVector.begin()); 446*cdf0e10cSrcweir ControlVectorPair2DVector::const_iterator aEnd(rSource.maVector.end()); 447*cdf0e10cSrcweir maVector.insert(aIndex, aStart, aEnd); 448*cdf0e10cSrcweir 449*cdf0e10cSrcweir for(; aStart != aEnd; aStart++) 450*cdf0e10cSrcweir { 451*cdf0e10cSrcweir if(!aStart->getPrevVector().equalZero()) 452*cdf0e10cSrcweir mnUsedVectors++; 453*cdf0e10cSrcweir 454*cdf0e10cSrcweir if(!aStart->getNextVector().equalZero()) 455*cdf0e10cSrcweir mnUsedVectors++; 456*cdf0e10cSrcweir } 457*cdf0e10cSrcweir } 458*cdf0e10cSrcweir } 459*cdf0e10cSrcweir 460*cdf0e10cSrcweir void remove(sal_uInt32 nIndex, sal_uInt32 nCount) 461*cdf0e10cSrcweir { 462*cdf0e10cSrcweir if(nCount) 463*cdf0e10cSrcweir { 464*cdf0e10cSrcweir const ControlVectorPair2DVector::iterator aDeleteStart(maVector.begin() + nIndex); 465*cdf0e10cSrcweir const ControlVectorPair2DVector::iterator aDeleteEnd(aDeleteStart + nCount); 466*cdf0e10cSrcweir ControlVectorPair2DVector::const_iterator aStart(aDeleteStart); 467*cdf0e10cSrcweir 468*cdf0e10cSrcweir for(; mnUsedVectors && aStart != aDeleteEnd; aStart++) 469*cdf0e10cSrcweir { 470*cdf0e10cSrcweir if(!aStart->getPrevVector().equalZero()) 471*cdf0e10cSrcweir mnUsedVectors--; 472*cdf0e10cSrcweir 473*cdf0e10cSrcweir if(mnUsedVectors && !aStart->getNextVector().equalZero()) 474*cdf0e10cSrcweir mnUsedVectors--; 475*cdf0e10cSrcweir } 476*cdf0e10cSrcweir 477*cdf0e10cSrcweir // remove point data 478*cdf0e10cSrcweir maVector.erase(aDeleteStart, aDeleteEnd); 479*cdf0e10cSrcweir } 480*cdf0e10cSrcweir } 481*cdf0e10cSrcweir 482*cdf0e10cSrcweir void flip(bool bIsClosed) 483*cdf0e10cSrcweir { 484*cdf0e10cSrcweir if(maVector.size() > 1) 485*cdf0e10cSrcweir { 486*cdf0e10cSrcweir // to keep the same point at index 0, just flip all points except the 487*cdf0e10cSrcweir // first one when closed 488*cdf0e10cSrcweir const sal_uInt32 nHalfSize(bIsClosed ? (maVector.size() - 1) >> 1 : maVector.size() >> 1); 489*cdf0e10cSrcweir ControlVectorPair2DVector::iterator aStart(bIsClosed ? maVector.begin() + 1 : maVector.begin()); 490*cdf0e10cSrcweir ControlVectorPair2DVector::iterator aEnd(maVector.end() - 1); 491*cdf0e10cSrcweir 492*cdf0e10cSrcweir for(sal_uInt32 a(0); a < nHalfSize; a++) 493*cdf0e10cSrcweir { 494*cdf0e10cSrcweir // swap Prev and Next 495*cdf0e10cSrcweir aStart->flip(); 496*cdf0e10cSrcweir aEnd->flip(); 497*cdf0e10cSrcweir 498*cdf0e10cSrcweir // swap entries 499*cdf0e10cSrcweir ::std::swap(*aStart, *aEnd); 500*cdf0e10cSrcweir 501*cdf0e10cSrcweir aStart++; 502*cdf0e10cSrcweir aEnd--; 503*cdf0e10cSrcweir } 504*cdf0e10cSrcweir 505*cdf0e10cSrcweir if(aStart == aEnd) 506*cdf0e10cSrcweir { 507*cdf0e10cSrcweir // swap Prev and Next at middle element (if exists) 508*cdf0e10cSrcweir aStart->flip(); 509*cdf0e10cSrcweir } 510*cdf0e10cSrcweir 511*cdf0e10cSrcweir if(bIsClosed) 512*cdf0e10cSrcweir { 513*cdf0e10cSrcweir // swap Prev and Next at start element 514*cdf0e10cSrcweir maVector.begin()->flip(); 515*cdf0e10cSrcweir } 516*cdf0e10cSrcweir } 517*cdf0e10cSrcweir } 518*cdf0e10cSrcweir }; 519*cdf0e10cSrcweir 520*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 521*cdf0e10cSrcweir 522*cdf0e10cSrcweir class ImplBufferedData 523*cdf0e10cSrcweir { 524*cdf0e10cSrcweir private: 525*cdf0e10cSrcweir // Possibility to hold the last subdivision 526*cdf0e10cSrcweir boost::scoped_ptr< basegfx::B2DPolygon > mpDefaultSubdivision; 527*cdf0e10cSrcweir 528*cdf0e10cSrcweir // Possibility to hold the last B2DRange calculation 529*cdf0e10cSrcweir boost::scoped_ptr< basegfx::B2DRange > mpB2DRange; 530*cdf0e10cSrcweir 531*cdf0e10cSrcweir public: 532*cdf0e10cSrcweir ImplBufferedData() 533*cdf0e10cSrcweir : mpDefaultSubdivision(), 534*cdf0e10cSrcweir mpB2DRange() 535*cdf0e10cSrcweir {} 536*cdf0e10cSrcweir 537*cdf0e10cSrcweir const basegfx::B2DPolygon& getDefaultAdaptiveSubdivision(const basegfx::B2DPolygon& rSource) const 538*cdf0e10cSrcweir { 539*cdf0e10cSrcweir if(!mpDefaultSubdivision) 540*cdf0e10cSrcweir { 541*cdf0e10cSrcweir const_cast< ImplBufferedData* >(this)->mpDefaultSubdivision.reset(new basegfx::B2DPolygon(basegfx::tools::adaptiveSubdivideByCount(rSource, 9))); 542*cdf0e10cSrcweir } 543*cdf0e10cSrcweir 544*cdf0e10cSrcweir return *mpDefaultSubdivision; 545*cdf0e10cSrcweir } 546*cdf0e10cSrcweir 547*cdf0e10cSrcweir const basegfx::B2DRange& getB2DRange(const basegfx::B2DPolygon& rSource) const 548*cdf0e10cSrcweir { 549*cdf0e10cSrcweir if(!mpB2DRange) 550*cdf0e10cSrcweir { 551*cdf0e10cSrcweir basegfx::B2DRange aNewRange; 552*cdf0e10cSrcweir const sal_uInt32 nPointCount(rSource.count()); 553*cdf0e10cSrcweir 554*cdf0e10cSrcweir if(nPointCount) 555*cdf0e10cSrcweir { 556*cdf0e10cSrcweir for(sal_uInt32 a(0); a < nPointCount; a++) 557*cdf0e10cSrcweir { 558*cdf0e10cSrcweir aNewRange.expand(rSource.getB2DPoint(a)); 559*cdf0e10cSrcweir } 560*cdf0e10cSrcweir 561*cdf0e10cSrcweir if(rSource.areControlPointsUsed()) 562*cdf0e10cSrcweir { 563*cdf0e10cSrcweir const sal_uInt32 nEdgeCount(rSource.isClosed() ? nPointCount : nPointCount - 1); 564*cdf0e10cSrcweir 565*cdf0e10cSrcweir if(nEdgeCount) 566*cdf0e10cSrcweir { 567*cdf0e10cSrcweir basegfx::B2DCubicBezier aEdge; 568*cdf0e10cSrcweir aEdge.setStartPoint(rSource.getB2DPoint(0)); 569*cdf0e10cSrcweir 570*cdf0e10cSrcweir for(sal_uInt32 b(0); b < nEdgeCount; b++) 571*cdf0e10cSrcweir { 572*cdf0e10cSrcweir const sal_uInt32 nNextIndex((b + 1) % nPointCount); 573*cdf0e10cSrcweir aEdge.setControlPointA(rSource.getNextControlPoint(b)); 574*cdf0e10cSrcweir aEdge.setControlPointB(rSource.getPrevControlPoint(nNextIndex)); 575*cdf0e10cSrcweir aEdge.setEndPoint(rSource.getB2DPoint(nNextIndex)); 576*cdf0e10cSrcweir 577*cdf0e10cSrcweir if(aEdge.isBezier()) 578*cdf0e10cSrcweir { 579*cdf0e10cSrcweir const basegfx::B2DRange aBezierRangeWithControlPoints(aEdge.getRange()); 580*cdf0e10cSrcweir 581*cdf0e10cSrcweir if(!aNewRange.isInside(aBezierRangeWithControlPoints)) 582*cdf0e10cSrcweir { 583*cdf0e10cSrcweir // the range with control points of the current edge is not completely 584*cdf0e10cSrcweir // inside the current range without control points. Expand current range by 585*cdf0e10cSrcweir // subdividing the bezier segment. 586*cdf0e10cSrcweir // Ideal here is a subdivision at the extreme values, so use 587*cdf0e10cSrcweir // getAllExtremumPositions to get all extremas in one run 588*cdf0e10cSrcweir ::std::vector< double > aExtremas; 589*cdf0e10cSrcweir 590*cdf0e10cSrcweir aExtremas.reserve(4); 591*cdf0e10cSrcweir aEdge.getAllExtremumPositions(aExtremas); 592*cdf0e10cSrcweir 593*cdf0e10cSrcweir const sal_uInt32 nExtremaCount(aExtremas.size()); 594*cdf0e10cSrcweir 595*cdf0e10cSrcweir for(sal_uInt32 c(0); c < nExtremaCount; c++) 596*cdf0e10cSrcweir { 597*cdf0e10cSrcweir aNewRange.expand(aEdge.interpolatePoint(aExtremas[c])); 598*cdf0e10cSrcweir } 599*cdf0e10cSrcweir } 600*cdf0e10cSrcweir } 601*cdf0e10cSrcweir 602*cdf0e10cSrcweir // prepare next edge 603*cdf0e10cSrcweir aEdge.setStartPoint(aEdge.getEndPoint()); 604*cdf0e10cSrcweir } 605*cdf0e10cSrcweir } 606*cdf0e10cSrcweir } 607*cdf0e10cSrcweir } 608*cdf0e10cSrcweir 609*cdf0e10cSrcweir const_cast< ImplBufferedData* >(this)->mpB2DRange.reset(new basegfx::B2DRange(aNewRange)); 610*cdf0e10cSrcweir } 611*cdf0e10cSrcweir 612*cdf0e10cSrcweir return *mpB2DRange; 613*cdf0e10cSrcweir } 614*cdf0e10cSrcweir }; 615*cdf0e10cSrcweir 616*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 617*cdf0e10cSrcweir 618*cdf0e10cSrcweir class ImplB2DPolygon 619*cdf0e10cSrcweir { 620*cdf0e10cSrcweir private: 621*cdf0e10cSrcweir // The point vector. This vector exists always and defines the 622*cdf0e10cSrcweir // count of members. 623*cdf0e10cSrcweir CoordinateDataArray2D maPoints; 624*cdf0e10cSrcweir 625*cdf0e10cSrcweir // The control point vectors. This vectors are created on demand 626*cdf0e10cSrcweir // and may be zero. 627*cdf0e10cSrcweir boost::scoped_ptr< ControlVectorArray2D > mpControlVector; 628*cdf0e10cSrcweir 629*cdf0e10cSrcweir // buffered data for e.g. default subdivision and range 630*cdf0e10cSrcweir boost::scoped_ptr< ImplBufferedData > mpBufferedData; 631*cdf0e10cSrcweir 632*cdf0e10cSrcweir // flag which decides if this polygon is opened or closed 633*cdf0e10cSrcweir bool mbIsClosed; 634*cdf0e10cSrcweir 635*cdf0e10cSrcweir public: 636*cdf0e10cSrcweir const basegfx::B2DPolygon& getDefaultAdaptiveSubdivision(const basegfx::B2DPolygon& rSource) const 637*cdf0e10cSrcweir { 638*cdf0e10cSrcweir if(!mpControlVector || !mpControlVector->isUsed()) 639*cdf0e10cSrcweir { 640*cdf0e10cSrcweir return rSource; 641*cdf0e10cSrcweir } 642*cdf0e10cSrcweir 643*cdf0e10cSrcweir if(!mpBufferedData) 644*cdf0e10cSrcweir { 645*cdf0e10cSrcweir const_cast< ImplB2DPolygon* >(this)->mpBufferedData.reset(new ImplBufferedData); 646*cdf0e10cSrcweir } 647*cdf0e10cSrcweir 648*cdf0e10cSrcweir return mpBufferedData->getDefaultAdaptiveSubdivision(rSource); 649*cdf0e10cSrcweir } 650*cdf0e10cSrcweir 651*cdf0e10cSrcweir const basegfx::B2DRange& getB2DRange(const basegfx::B2DPolygon& rSource) const 652*cdf0e10cSrcweir { 653*cdf0e10cSrcweir if(!mpBufferedData) 654*cdf0e10cSrcweir { 655*cdf0e10cSrcweir const_cast< ImplB2DPolygon* >(this)->mpBufferedData.reset(new ImplBufferedData); 656*cdf0e10cSrcweir } 657*cdf0e10cSrcweir 658*cdf0e10cSrcweir return mpBufferedData->getB2DRange(rSource); 659*cdf0e10cSrcweir } 660*cdf0e10cSrcweir 661*cdf0e10cSrcweir ImplB2DPolygon() 662*cdf0e10cSrcweir : maPoints(0), 663*cdf0e10cSrcweir mpControlVector(), 664*cdf0e10cSrcweir mpBufferedData(), 665*cdf0e10cSrcweir mbIsClosed(false) 666*cdf0e10cSrcweir {} 667*cdf0e10cSrcweir 668*cdf0e10cSrcweir ImplB2DPolygon(const ImplB2DPolygon& rToBeCopied) 669*cdf0e10cSrcweir : maPoints(rToBeCopied.maPoints), 670*cdf0e10cSrcweir mpControlVector(), 671*cdf0e10cSrcweir mpBufferedData(), 672*cdf0e10cSrcweir mbIsClosed(rToBeCopied.mbIsClosed) 673*cdf0e10cSrcweir { 674*cdf0e10cSrcweir // complete initialization using copy 675*cdf0e10cSrcweir if(rToBeCopied.mpControlVector && rToBeCopied.mpControlVector->isUsed()) 676*cdf0e10cSrcweir { 677*cdf0e10cSrcweir mpControlVector.reset( new ControlVectorArray2D(*rToBeCopied.mpControlVector) ); 678*cdf0e10cSrcweir } 679*cdf0e10cSrcweir } 680*cdf0e10cSrcweir 681*cdf0e10cSrcweir ImplB2DPolygon(const ImplB2DPolygon& rToBeCopied, sal_uInt32 nIndex, sal_uInt32 nCount) 682*cdf0e10cSrcweir : maPoints(rToBeCopied.maPoints, nIndex, nCount), 683*cdf0e10cSrcweir mpControlVector(), 684*cdf0e10cSrcweir mpBufferedData(), 685*cdf0e10cSrcweir mbIsClosed(rToBeCopied.mbIsClosed) 686*cdf0e10cSrcweir { 687*cdf0e10cSrcweir // complete initialization using partly copy 688*cdf0e10cSrcweir if(rToBeCopied.mpControlVector && rToBeCopied.mpControlVector->isUsed()) 689*cdf0e10cSrcweir { 690*cdf0e10cSrcweir mpControlVector.reset( new ControlVectorArray2D(*rToBeCopied.mpControlVector, nIndex, nCount) ); 691*cdf0e10cSrcweir 692*cdf0e10cSrcweir if(!mpControlVector->isUsed()) 693*cdf0e10cSrcweir mpControlVector.reset(); 694*cdf0e10cSrcweir } 695*cdf0e10cSrcweir } 696*cdf0e10cSrcweir 697*cdf0e10cSrcweir ImplB2DPolygon& operator=( const ImplB2DPolygon& rToBeCopied ) 698*cdf0e10cSrcweir { 699*cdf0e10cSrcweir maPoints = rToBeCopied.maPoints; 700*cdf0e10cSrcweir mpControlVector.reset(); 701*cdf0e10cSrcweir mpBufferedData.reset(); 702*cdf0e10cSrcweir mbIsClosed = rToBeCopied.mbIsClosed; 703*cdf0e10cSrcweir 704*cdf0e10cSrcweir // complete initialization using copy 705*cdf0e10cSrcweir if(rToBeCopied.mpControlVector && rToBeCopied.mpControlVector->isUsed()) 706*cdf0e10cSrcweir mpControlVector.reset( new ControlVectorArray2D(*rToBeCopied.mpControlVector) ); 707*cdf0e10cSrcweir 708*cdf0e10cSrcweir return *this; 709*cdf0e10cSrcweir } 710*cdf0e10cSrcweir 711*cdf0e10cSrcweir sal_uInt32 count() const 712*cdf0e10cSrcweir { 713*cdf0e10cSrcweir return maPoints.count(); 714*cdf0e10cSrcweir } 715*cdf0e10cSrcweir 716*cdf0e10cSrcweir bool isClosed() const 717*cdf0e10cSrcweir { 718*cdf0e10cSrcweir return mbIsClosed; 719*cdf0e10cSrcweir } 720*cdf0e10cSrcweir 721*cdf0e10cSrcweir void setClosed(bool bNew) 722*cdf0e10cSrcweir { 723*cdf0e10cSrcweir if(bNew != mbIsClosed) 724*cdf0e10cSrcweir { 725*cdf0e10cSrcweir mpBufferedData.reset(); 726*cdf0e10cSrcweir mbIsClosed = bNew; 727*cdf0e10cSrcweir } 728*cdf0e10cSrcweir } 729*cdf0e10cSrcweir 730*cdf0e10cSrcweir bool operator==(const ImplB2DPolygon& rCandidate) const 731*cdf0e10cSrcweir { 732*cdf0e10cSrcweir if(mbIsClosed == rCandidate.mbIsClosed) 733*cdf0e10cSrcweir { 734*cdf0e10cSrcweir if(maPoints == rCandidate.maPoints) 735*cdf0e10cSrcweir { 736*cdf0e10cSrcweir bool bControlVectorsAreEqual(true); 737*cdf0e10cSrcweir 738*cdf0e10cSrcweir if(mpControlVector) 739*cdf0e10cSrcweir { 740*cdf0e10cSrcweir if(rCandidate.mpControlVector) 741*cdf0e10cSrcweir { 742*cdf0e10cSrcweir bControlVectorsAreEqual = ((*mpControlVector) == (*rCandidate.mpControlVector)); 743*cdf0e10cSrcweir } 744*cdf0e10cSrcweir else 745*cdf0e10cSrcweir { 746*cdf0e10cSrcweir // candidate has no control vector, so it's assumed all unused. 747*cdf0e10cSrcweir bControlVectorsAreEqual = !mpControlVector->isUsed(); 748*cdf0e10cSrcweir } 749*cdf0e10cSrcweir } 750*cdf0e10cSrcweir else 751*cdf0e10cSrcweir { 752*cdf0e10cSrcweir if(rCandidate.mpControlVector) 753*cdf0e10cSrcweir { 754*cdf0e10cSrcweir // we have no control vector, so it's assumed all unused. 755*cdf0e10cSrcweir bControlVectorsAreEqual = !rCandidate.mpControlVector->isUsed(); 756*cdf0e10cSrcweir } 757*cdf0e10cSrcweir } 758*cdf0e10cSrcweir 759*cdf0e10cSrcweir if(bControlVectorsAreEqual) 760*cdf0e10cSrcweir { 761*cdf0e10cSrcweir return true; 762*cdf0e10cSrcweir } 763*cdf0e10cSrcweir } 764*cdf0e10cSrcweir } 765*cdf0e10cSrcweir 766*cdf0e10cSrcweir return false; 767*cdf0e10cSrcweir } 768*cdf0e10cSrcweir 769*cdf0e10cSrcweir const basegfx::B2DPoint& getPoint(sal_uInt32 nIndex) const 770*cdf0e10cSrcweir { 771*cdf0e10cSrcweir return maPoints.getCoordinate(nIndex); 772*cdf0e10cSrcweir } 773*cdf0e10cSrcweir 774*cdf0e10cSrcweir void setPoint(sal_uInt32 nIndex, const basegfx::B2DPoint& rValue) 775*cdf0e10cSrcweir { 776*cdf0e10cSrcweir mpBufferedData.reset(); 777*cdf0e10cSrcweir maPoints.setCoordinate(nIndex, rValue); 778*cdf0e10cSrcweir } 779*cdf0e10cSrcweir 780*cdf0e10cSrcweir void reserve(sal_uInt32 nCount) 781*cdf0e10cSrcweir { 782*cdf0e10cSrcweir maPoints.reserve(nCount); 783*cdf0e10cSrcweir } 784*cdf0e10cSrcweir 785*cdf0e10cSrcweir void append(const basegfx::B2DPoint& rPoint) 786*cdf0e10cSrcweir { 787*cdf0e10cSrcweir mpBufferedData.reset(); // TODO: is this needed? 788*cdf0e10cSrcweir const CoordinateData2D aCoordinate(rPoint); 789*cdf0e10cSrcweir maPoints.append(aCoordinate); 790*cdf0e10cSrcweir 791*cdf0e10cSrcweir if(mpControlVector) 792*cdf0e10cSrcweir { 793*cdf0e10cSrcweir const ControlVectorPair2D aVectorPair; 794*cdf0e10cSrcweir mpControlVector->append(aVectorPair); 795*cdf0e10cSrcweir } 796*cdf0e10cSrcweir } 797*cdf0e10cSrcweir 798*cdf0e10cSrcweir void insert(sal_uInt32 nIndex, const basegfx::B2DPoint& rPoint, sal_uInt32 nCount) 799*cdf0e10cSrcweir { 800*cdf0e10cSrcweir if(nCount) 801*cdf0e10cSrcweir { 802*cdf0e10cSrcweir mpBufferedData.reset(); 803*cdf0e10cSrcweir CoordinateData2D aCoordinate(rPoint); 804*cdf0e10cSrcweir maPoints.insert(nIndex, aCoordinate, nCount); 805*cdf0e10cSrcweir 806*cdf0e10cSrcweir if(mpControlVector) 807*cdf0e10cSrcweir { 808*cdf0e10cSrcweir ControlVectorPair2D aVectorPair; 809*cdf0e10cSrcweir mpControlVector->insert(nIndex, aVectorPair, nCount); 810*cdf0e10cSrcweir } 811*cdf0e10cSrcweir } 812*cdf0e10cSrcweir } 813*cdf0e10cSrcweir 814*cdf0e10cSrcweir const basegfx::B2DVector& getPrevControlVector(sal_uInt32 nIndex) const 815*cdf0e10cSrcweir { 816*cdf0e10cSrcweir if(mpControlVector) 817*cdf0e10cSrcweir { 818*cdf0e10cSrcweir return mpControlVector->getPrevVector(nIndex); 819*cdf0e10cSrcweir } 820*cdf0e10cSrcweir else 821*cdf0e10cSrcweir { 822*cdf0e10cSrcweir return basegfx::B2DVector::getEmptyVector(); 823*cdf0e10cSrcweir } 824*cdf0e10cSrcweir } 825*cdf0e10cSrcweir 826*cdf0e10cSrcweir void setPrevControlVector(sal_uInt32 nIndex, const basegfx::B2DVector& rValue) 827*cdf0e10cSrcweir { 828*cdf0e10cSrcweir if(!mpControlVector) 829*cdf0e10cSrcweir { 830*cdf0e10cSrcweir if(!rValue.equalZero()) 831*cdf0e10cSrcweir { 832*cdf0e10cSrcweir mpBufferedData.reset(); 833*cdf0e10cSrcweir mpControlVector.reset( new ControlVectorArray2D(maPoints.count()) ); 834*cdf0e10cSrcweir mpControlVector->setPrevVector(nIndex, rValue); 835*cdf0e10cSrcweir } 836*cdf0e10cSrcweir } 837*cdf0e10cSrcweir else 838*cdf0e10cSrcweir { 839*cdf0e10cSrcweir mpBufferedData.reset(); 840*cdf0e10cSrcweir mpControlVector->setPrevVector(nIndex, rValue); 841*cdf0e10cSrcweir 842*cdf0e10cSrcweir if(!mpControlVector->isUsed()) 843*cdf0e10cSrcweir mpControlVector.reset(); 844*cdf0e10cSrcweir } 845*cdf0e10cSrcweir } 846*cdf0e10cSrcweir 847*cdf0e10cSrcweir const basegfx::B2DVector& getNextControlVector(sal_uInt32 nIndex) const 848*cdf0e10cSrcweir { 849*cdf0e10cSrcweir if(mpControlVector) 850*cdf0e10cSrcweir { 851*cdf0e10cSrcweir return mpControlVector->getNextVector(nIndex); 852*cdf0e10cSrcweir } 853*cdf0e10cSrcweir else 854*cdf0e10cSrcweir { 855*cdf0e10cSrcweir return basegfx::B2DVector::getEmptyVector(); 856*cdf0e10cSrcweir } 857*cdf0e10cSrcweir } 858*cdf0e10cSrcweir 859*cdf0e10cSrcweir void setNextControlVector(sal_uInt32 nIndex, const basegfx::B2DVector& rValue) 860*cdf0e10cSrcweir { 861*cdf0e10cSrcweir if(!mpControlVector) 862*cdf0e10cSrcweir { 863*cdf0e10cSrcweir if(!rValue.equalZero()) 864*cdf0e10cSrcweir { 865*cdf0e10cSrcweir mpBufferedData.reset(); 866*cdf0e10cSrcweir mpControlVector.reset( new ControlVectorArray2D(maPoints.count()) ); 867*cdf0e10cSrcweir mpControlVector->setNextVector(nIndex, rValue); 868*cdf0e10cSrcweir } 869*cdf0e10cSrcweir } 870*cdf0e10cSrcweir else 871*cdf0e10cSrcweir { 872*cdf0e10cSrcweir mpBufferedData.reset(); 873*cdf0e10cSrcweir mpControlVector->setNextVector(nIndex, rValue); 874*cdf0e10cSrcweir 875*cdf0e10cSrcweir if(!mpControlVector->isUsed()) 876*cdf0e10cSrcweir mpControlVector.reset(); 877*cdf0e10cSrcweir } 878*cdf0e10cSrcweir } 879*cdf0e10cSrcweir 880*cdf0e10cSrcweir bool areControlPointsUsed() const 881*cdf0e10cSrcweir { 882*cdf0e10cSrcweir return (mpControlVector && mpControlVector->isUsed()); 883*cdf0e10cSrcweir } 884*cdf0e10cSrcweir 885*cdf0e10cSrcweir void resetControlVectors(sal_uInt32 nIndex) 886*cdf0e10cSrcweir { 887*cdf0e10cSrcweir setPrevControlVector(nIndex, basegfx::B2DVector::getEmptyVector()); 888*cdf0e10cSrcweir setNextControlVector(nIndex, basegfx::B2DVector::getEmptyVector()); 889*cdf0e10cSrcweir } 890*cdf0e10cSrcweir 891*cdf0e10cSrcweir void resetControlVectors() 892*cdf0e10cSrcweir { 893*cdf0e10cSrcweir mpBufferedData.reset(); 894*cdf0e10cSrcweir mpControlVector.reset(); 895*cdf0e10cSrcweir } 896*cdf0e10cSrcweir 897*cdf0e10cSrcweir void setControlVectors(sal_uInt32 nIndex, const basegfx::B2DVector& rPrev, const basegfx::B2DVector& rNext) 898*cdf0e10cSrcweir { 899*cdf0e10cSrcweir setPrevControlVector(nIndex, rPrev); 900*cdf0e10cSrcweir setNextControlVector(nIndex, rNext); 901*cdf0e10cSrcweir } 902*cdf0e10cSrcweir 903*cdf0e10cSrcweir void appendBezierSegment(const basegfx::B2DVector& rNext, const basegfx::B2DVector& rPrev, const basegfx::B2DPoint& rPoint) 904*cdf0e10cSrcweir { 905*cdf0e10cSrcweir mpBufferedData.reset(); 906*cdf0e10cSrcweir const sal_uInt32 nCount(maPoints.count()); 907*cdf0e10cSrcweir 908*cdf0e10cSrcweir if(nCount) 909*cdf0e10cSrcweir { 910*cdf0e10cSrcweir setNextControlVector(nCount - 1, rNext); 911*cdf0e10cSrcweir } 912*cdf0e10cSrcweir 913*cdf0e10cSrcweir insert(nCount, rPoint, 1); 914*cdf0e10cSrcweir setPrevControlVector(nCount, rPrev); 915*cdf0e10cSrcweir } 916*cdf0e10cSrcweir 917*cdf0e10cSrcweir void insert(sal_uInt32 nIndex, const ImplB2DPolygon& rSource) 918*cdf0e10cSrcweir { 919*cdf0e10cSrcweir const sal_uInt32 nCount(rSource.maPoints.count()); 920*cdf0e10cSrcweir 921*cdf0e10cSrcweir if(nCount) 922*cdf0e10cSrcweir { 923*cdf0e10cSrcweir mpBufferedData.reset(); 924*cdf0e10cSrcweir 925*cdf0e10cSrcweir if(rSource.mpControlVector && rSource.mpControlVector->isUsed() && !mpControlVector) 926*cdf0e10cSrcweir { 927*cdf0e10cSrcweir mpControlVector.reset( new ControlVectorArray2D(maPoints.count()) ); 928*cdf0e10cSrcweir } 929*cdf0e10cSrcweir 930*cdf0e10cSrcweir maPoints.insert(nIndex, rSource.maPoints); 931*cdf0e10cSrcweir 932*cdf0e10cSrcweir if(rSource.mpControlVector) 933*cdf0e10cSrcweir { 934*cdf0e10cSrcweir mpControlVector->insert(nIndex, *rSource.mpControlVector); 935*cdf0e10cSrcweir 936*cdf0e10cSrcweir if(!mpControlVector->isUsed()) 937*cdf0e10cSrcweir mpControlVector.reset(); 938*cdf0e10cSrcweir } 939*cdf0e10cSrcweir else if(mpControlVector) 940*cdf0e10cSrcweir { 941*cdf0e10cSrcweir ControlVectorPair2D aVectorPair; 942*cdf0e10cSrcweir mpControlVector->insert(nIndex, aVectorPair, nCount); 943*cdf0e10cSrcweir } 944*cdf0e10cSrcweir } 945*cdf0e10cSrcweir } 946*cdf0e10cSrcweir 947*cdf0e10cSrcweir void remove(sal_uInt32 nIndex, sal_uInt32 nCount) 948*cdf0e10cSrcweir { 949*cdf0e10cSrcweir if(nCount) 950*cdf0e10cSrcweir { 951*cdf0e10cSrcweir mpBufferedData.reset(); 952*cdf0e10cSrcweir maPoints.remove(nIndex, nCount); 953*cdf0e10cSrcweir 954*cdf0e10cSrcweir if(mpControlVector) 955*cdf0e10cSrcweir { 956*cdf0e10cSrcweir mpControlVector->remove(nIndex, nCount); 957*cdf0e10cSrcweir 958*cdf0e10cSrcweir if(!mpControlVector->isUsed()) 959*cdf0e10cSrcweir mpControlVector.reset(); 960*cdf0e10cSrcweir } 961*cdf0e10cSrcweir } 962*cdf0e10cSrcweir } 963*cdf0e10cSrcweir 964*cdf0e10cSrcweir void flip() 965*cdf0e10cSrcweir { 966*cdf0e10cSrcweir if(maPoints.count() > 1) 967*cdf0e10cSrcweir { 968*cdf0e10cSrcweir mpBufferedData.reset(); 969*cdf0e10cSrcweir 970*cdf0e10cSrcweir // flip points 971*cdf0e10cSrcweir maPoints.flip(mbIsClosed); 972*cdf0e10cSrcweir 973*cdf0e10cSrcweir if(mpControlVector) 974*cdf0e10cSrcweir { 975*cdf0e10cSrcweir // flip control vector 976*cdf0e10cSrcweir mpControlVector->flip(mbIsClosed); 977*cdf0e10cSrcweir } 978*cdf0e10cSrcweir } 979*cdf0e10cSrcweir } 980*cdf0e10cSrcweir 981*cdf0e10cSrcweir bool hasDoublePoints() const 982*cdf0e10cSrcweir { 983*cdf0e10cSrcweir if(mbIsClosed) 984*cdf0e10cSrcweir { 985*cdf0e10cSrcweir // check for same start and end point 986*cdf0e10cSrcweir const sal_uInt32 nIndex(maPoints.count() - 1); 987*cdf0e10cSrcweir 988*cdf0e10cSrcweir if(maPoints.getCoordinate(0) == maPoints.getCoordinate(nIndex)) 989*cdf0e10cSrcweir { 990*cdf0e10cSrcweir if(mpControlVector) 991*cdf0e10cSrcweir { 992*cdf0e10cSrcweir if(mpControlVector->getNextVector(nIndex).equalZero() && mpControlVector->getPrevVector(0).equalZero()) 993*cdf0e10cSrcweir { 994*cdf0e10cSrcweir return true; 995*cdf0e10cSrcweir } 996*cdf0e10cSrcweir } 997*cdf0e10cSrcweir else 998*cdf0e10cSrcweir { 999*cdf0e10cSrcweir return true; 1000*cdf0e10cSrcweir } 1001*cdf0e10cSrcweir } 1002*cdf0e10cSrcweir } 1003*cdf0e10cSrcweir 1004*cdf0e10cSrcweir // test for range 1005*cdf0e10cSrcweir for(sal_uInt32 a(0); a < maPoints.count() - 1; a++) 1006*cdf0e10cSrcweir { 1007*cdf0e10cSrcweir if(maPoints.getCoordinate(a) == maPoints.getCoordinate(a + 1)) 1008*cdf0e10cSrcweir { 1009*cdf0e10cSrcweir if(mpControlVector) 1010*cdf0e10cSrcweir { 1011*cdf0e10cSrcweir if(mpControlVector->getNextVector(a).equalZero() && mpControlVector->getPrevVector(a + 1).equalZero()) 1012*cdf0e10cSrcweir { 1013*cdf0e10cSrcweir return true; 1014*cdf0e10cSrcweir } 1015*cdf0e10cSrcweir } 1016*cdf0e10cSrcweir else 1017*cdf0e10cSrcweir { 1018*cdf0e10cSrcweir return true; 1019*cdf0e10cSrcweir } 1020*cdf0e10cSrcweir } 1021*cdf0e10cSrcweir } 1022*cdf0e10cSrcweir 1023*cdf0e10cSrcweir return false; 1024*cdf0e10cSrcweir } 1025*cdf0e10cSrcweir 1026*cdf0e10cSrcweir void removeDoublePointsAtBeginEnd() 1027*cdf0e10cSrcweir { 1028*cdf0e10cSrcweir // Only remove DoublePoints at Begin and End when poly is closed 1029*cdf0e10cSrcweir if(mbIsClosed) 1030*cdf0e10cSrcweir { 1031*cdf0e10cSrcweir mpBufferedData.reset(); 1032*cdf0e10cSrcweir 1033*cdf0e10cSrcweir if(mpControlVector) 1034*cdf0e10cSrcweir { 1035*cdf0e10cSrcweir bool bRemove; 1036*cdf0e10cSrcweir 1037*cdf0e10cSrcweir do 1038*cdf0e10cSrcweir { 1039*cdf0e10cSrcweir bRemove = false; 1040*cdf0e10cSrcweir 1041*cdf0e10cSrcweir if(maPoints.count() > 1) 1042*cdf0e10cSrcweir { 1043*cdf0e10cSrcweir const sal_uInt32 nIndex(maPoints.count() - 1); 1044*cdf0e10cSrcweir 1045*cdf0e10cSrcweir if(maPoints.getCoordinate(0) == maPoints.getCoordinate(nIndex)) 1046*cdf0e10cSrcweir { 1047*cdf0e10cSrcweir if(mpControlVector) 1048*cdf0e10cSrcweir { 1049*cdf0e10cSrcweir if(mpControlVector->getNextVector(nIndex).equalZero() && mpControlVector->getPrevVector(0).equalZero()) 1050*cdf0e10cSrcweir { 1051*cdf0e10cSrcweir bRemove = true; 1052*cdf0e10cSrcweir } 1053*cdf0e10cSrcweir } 1054*cdf0e10cSrcweir else 1055*cdf0e10cSrcweir { 1056*cdf0e10cSrcweir bRemove = true; 1057*cdf0e10cSrcweir } 1058*cdf0e10cSrcweir } 1059*cdf0e10cSrcweir } 1060*cdf0e10cSrcweir 1061*cdf0e10cSrcweir if(bRemove) 1062*cdf0e10cSrcweir { 1063*cdf0e10cSrcweir const sal_uInt32 nIndex(maPoints.count() - 1); 1064*cdf0e10cSrcweir 1065*cdf0e10cSrcweir if(mpControlVector && !mpControlVector->getPrevVector(nIndex).equalZero()) 1066*cdf0e10cSrcweir { 1067*cdf0e10cSrcweir mpControlVector->setPrevVector(0, mpControlVector->getPrevVector(nIndex)); 1068*cdf0e10cSrcweir } 1069*cdf0e10cSrcweir 1070*cdf0e10cSrcweir remove(nIndex, 1); 1071*cdf0e10cSrcweir } 1072*cdf0e10cSrcweir } 1073*cdf0e10cSrcweir while(bRemove); 1074*cdf0e10cSrcweir } 1075*cdf0e10cSrcweir else 1076*cdf0e10cSrcweir { 1077*cdf0e10cSrcweir maPoints.removeDoublePointsAtBeginEnd(); 1078*cdf0e10cSrcweir } 1079*cdf0e10cSrcweir } 1080*cdf0e10cSrcweir } 1081*cdf0e10cSrcweir 1082*cdf0e10cSrcweir void removeDoublePointsWholeTrack() 1083*cdf0e10cSrcweir { 1084*cdf0e10cSrcweir mpBufferedData.reset(); 1085*cdf0e10cSrcweir 1086*cdf0e10cSrcweir if(mpControlVector) 1087*cdf0e10cSrcweir { 1088*cdf0e10cSrcweir sal_uInt32 nIndex(0); 1089*cdf0e10cSrcweir 1090*cdf0e10cSrcweir // test as long as there are at least two points and as long as the index 1091*cdf0e10cSrcweir // is smaller or equal second last point 1092*cdf0e10cSrcweir while((maPoints.count() > 1) && (nIndex <= maPoints.count() - 2)) 1093*cdf0e10cSrcweir { 1094*cdf0e10cSrcweir bool bRemove(maPoints.getCoordinate(nIndex) == maPoints.getCoordinate(nIndex + 1)); 1095*cdf0e10cSrcweir 1096*cdf0e10cSrcweir if(bRemove) 1097*cdf0e10cSrcweir { 1098*cdf0e10cSrcweir if(mpControlVector) 1099*cdf0e10cSrcweir { 1100*cdf0e10cSrcweir if(!mpControlVector->getNextVector(nIndex).equalZero() || !mpControlVector->getPrevVector(nIndex + 1).equalZero()) 1101*cdf0e10cSrcweir { 1102*cdf0e10cSrcweir bRemove = false; 1103*cdf0e10cSrcweir } 1104*cdf0e10cSrcweir } 1105*cdf0e10cSrcweir } 1106*cdf0e10cSrcweir 1107*cdf0e10cSrcweir if(bRemove) 1108*cdf0e10cSrcweir { 1109*cdf0e10cSrcweir if(mpControlVector && !mpControlVector->getPrevVector(nIndex).equalZero()) 1110*cdf0e10cSrcweir { 1111*cdf0e10cSrcweir mpControlVector->setPrevVector(nIndex + 1, mpControlVector->getPrevVector(nIndex)); 1112*cdf0e10cSrcweir } 1113*cdf0e10cSrcweir 1114*cdf0e10cSrcweir // if next is same as index and the control vectors are unused, delete index 1115*cdf0e10cSrcweir remove(nIndex, 1); 1116*cdf0e10cSrcweir } 1117*cdf0e10cSrcweir else 1118*cdf0e10cSrcweir { 1119*cdf0e10cSrcweir // if different, step forward 1120*cdf0e10cSrcweir nIndex++; 1121*cdf0e10cSrcweir } 1122*cdf0e10cSrcweir } 1123*cdf0e10cSrcweir } 1124*cdf0e10cSrcweir else 1125*cdf0e10cSrcweir { 1126*cdf0e10cSrcweir maPoints.removeDoublePointsWholeTrack(); 1127*cdf0e10cSrcweir } 1128*cdf0e10cSrcweir } 1129*cdf0e10cSrcweir 1130*cdf0e10cSrcweir void transform(const basegfx::B2DHomMatrix& rMatrix) 1131*cdf0e10cSrcweir { 1132*cdf0e10cSrcweir mpBufferedData.reset(); 1133*cdf0e10cSrcweir 1134*cdf0e10cSrcweir if(mpControlVector) 1135*cdf0e10cSrcweir { 1136*cdf0e10cSrcweir for(sal_uInt32 a(0); a < maPoints.count(); a++) 1137*cdf0e10cSrcweir { 1138*cdf0e10cSrcweir basegfx::B2DPoint aCandidate = maPoints.getCoordinate(a); 1139*cdf0e10cSrcweir 1140*cdf0e10cSrcweir if(mpControlVector->isUsed()) 1141*cdf0e10cSrcweir { 1142*cdf0e10cSrcweir const basegfx::B2DVector& rPrevVector(mpControlVector->getPrevVector(a)); 1143*cdf0e10cSrcweir const basegfx::B2DVector& rNextVector(mpControlVector->getNextVector(a)); 1144*cdf0e10cSrcweir 1145*cdf0e10cSrcweir if(!rPrevVector.equalZero()) 1146*cdf0e10cSrcweir { 1147*cdf0e10cSrcweir basegfx::B2DVector aPrevVector(rMatrix * rPrevVector); 1148*cdf0e10cSrcweir mpControlVector->setPrevVector(a, aPrevVector); 1149*cdf0e10cSrcweir } 1150*cdf0e10cSrcweir 1151*cdf0e10cSrcweir if(!rNextVector.equalZero()) 1152*cdf0e10cSrcweir { 1153*cdf0e10cSrcweir basegfx::B2DVector aNextVector(rMatrix * rNextVector); 1154*cdf0e10cSrcweir mpControlVector->setNextVector(a, aNextVector); 1155*cdf0e10cSrcweir } 1156*cdf0e10cSrcweir } 1157*cdf0e10cSrcweir 1158*cdf0e10cSrcweir aCandidate *= rMatrix; 1159*cdf0e10cSrcweir maPoints.setCoordinate(a, aCandidate); 1160*cdf0e10cSrcweir } 1161*cdf0e10cSrcweir 1162*cdf0e10cSrcweir if(!mpControlVector->isUsed()) 1163*cdf0e10cSrcweir mpControlVector.reset(); 1164*cdf0e10cSrcweir } 1165*cdf0e10cSrcweir else 1166*cdf0e10cSrcweir { 1167*cdf0e10cSrcweir maPoints.transform(rMatrix); 1168*cdf0e10cSrcweir } 1169*cdf0e10cSrcweir } 1170*cdf0e10cSrcweir 1171*cdf0e10cSrcweir const basegfx::B2DPoint* begin() const 1172*cdf0e10cSrcweir { 1173*cdf0e10cSrcweir return maPoints.begin(); 1174*cdf0e10cSrcweir } 1175*cdf0e10cSrcweir 1176*cdf0e10cSrcweir const basegfx::B2DPoint* end() const 1177*cdf0e10cSrcweir { 1178*cdf0e10cSrcweir return maPoints.end(); 1179*cdf0e10cSrcweir } 1180*cdf0e10cSrcweir 1181*cdf0e10cSrcweir basegfx::B2DPoint* begin() 1182*cdf0e10cSrcweir { 1183*cdf0e10cSrcweir mpBufferedData.reset(); 1184*cdf0e10cSrcweir return maPoints.begin(); 1185*cdf0e10cSrcweir } 1186*cdf0e10cSrcweir 1187*cdf0e10cSrcweir basegfx::B2DPoint* end() 1188*cdf0e10cSrcweir { 1189*cdf0e10cSrcweir mpBufferedData.reset(); 1190*cdf0e10cSrcweir return maPoints.end(); 1191*cdf0e10cSrcweir } 1192*cdf0e10cSrcweir }; 1193*cdf0e10cSrcweir 1194*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 1195*cdf0e10cSrcweir 1196*cdf0e10cSrcweir namespace basegfx 1197*cdf0e10cSrcweir { 1198*cdf0e10cSrcweir namespace 1199*cdf0e10cSrcweir { 1200*cdf0e10cSrcweir struct DefaultPolygon: public rtl::Static<B2DPolygon::ImplType, DefaultPolygon> {}; 1201*cdf0e10cSrcweir } 1202*cdf0e10cSrcweir 1203*cdf0e10cSrcweir B2DPolygon::B2DPolygon() 1204*cdf0e10cSrcweir : mpPolygon(DefaultPolygon::get()) 1205*cdf0e10cSrcweir {} 1206*cdf0e10cSrcweir 1207*cdf0e10cSrcweir B2DPolygon::B2DPolygon(const B2DPolygon& rPolygon) 1208*cdf0e10cSrcweir : mpPolygon(rPolygon.mpPolygon) 1209*cdf0e10cSrcweir {} 1210*cdf0e10cSrcweir 1211*cdf0e10cSrcweir B2DPolygon::B2DPolygon(const B2DPolygon& rPolygon, sal_uInt32 nIndex, sal_uInt32 nCount) 1212*cdf0e10cSrcweir : mpPolygon(ImplB2DPolygon(*rPolygon.mpPolygon, nIndex, nCount)) 1213*cdf0e10cSrcweir { 1214*cdf0e10cSrcweir // TODO(P2): one extra temporary here (cow_wrapper copies 1215*cdf0e10cSrcweir // given ImplB2DPolygon into its internal impl_t wrapper type) 1216*cdf0e10cSrcweir OSL_ENSURE(nIndex + nCount <= rPolygon.mpPolygon->count(), "B2DPolygon constructor outside range (!)"); 1217*cdf0e10cSrcweir } 1218*cdf0e10cSrcweir 1219*cdf0e10cSrcweir B2DPolygon::~B2DPolygon() 1220*cdf0e10cSrcweir { 1221*cdf0e10cSrcweir } 1222*cdf0e10cSrcweir 1223*cdf0e10cSrcweir B2DPolygon& B2DPolygon::operator=(const B2DPolygon& rPolygon) 1224*cdf0e10cSrcweir { 1225*cdf0e10cSrcweir mpPolygon = rPolygon.mpPolygon; 1226*cdf0e10cSrcweir return *this; 1227*cdf0e10cSrcweir } 1228*cdf0e10cSrcweir 1229*cdf0e10cSrcweir void B2DPolygon::makeUnique() 1230*cdf0e10cSrcweir { 1231*cdf0e10cSrcweir mpPolygon.make_unique(); 1232*cdf0e10cSrcweir } 1233*cdf0e10cSrcweir 1234*cdf0e10cSrcweir bool B2DPolygon::operator==(const B2DPolygon& rPolygon) const 1235*cdf0e10cSrcweir { 1236*cdf0e10cSrcweir if(mpPolygon.same_object(rPolygon.mpPolygon)) 1237*cdf0e10cSrcweir return true; 1238*cdf0e10cSrcweir 1239*cdf0e10cSrcweir return ((*mpPolygon) == (*rPolygon.mpPolygon)); 1240*cdf0e10cSrcweir } 1241*cdf0e10cSrcweir 1242*cdf0e10cSrcweir bool B2DPolygon::operator!=(const B2DPolygon& rPolygon) const 1243*cdf0e10cSrcweir { 1244*cdf0e10cSrcweir return !(*this == rPolygon); 1245*cdf0e10cSrcweir } 1246*cdf0e10cSrcweir 1247*cdf0e10cSrcweir sal_uInt32 B2DPolygon::count() const 1248*cdf0e10cSrcweir { 1249*cdf0e10cSrcweir return mpPolygon->count(); 1250*cdf0e10cSrcweir } 1251*cdf0e10cSrcweir 1252*cdf0e10cSrcweir B2DPoint B2DPolygon::getB2DPoint(sal_uInt32 nIndex) const 1253*cdf0e10cSrcweir { 1254*cdf0e10cSrcweir OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)"); 1255*cdf0e10cSrcweir 1256*cdf0e10cSrcweir return mpPolygon->getPoint(nIndex); 1257*cdf0e10cSrcweir } 1258*cdf0e10cSrcweir 1259*cdf0e10cSrcweir void B2DPolygon::setB2DPoint(sal_uInt32 nIndex, const B2DPoint& rValue) 1260*cdf0e10cSrcweir { 1261*cdf0e10cSrcweir OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)"); 1262*cdf0e10cSrcweir 1263*cdf0e10cSrcweir if(getB2DPoint(nIndex) != rValue) 1264*cdf0e10cSrcweir { 1265*cdf0e10cSrcweir mpPolygon->setPoint(nIndex, rValue); 1266*cdf0e10cSrcweir } 1267*cdf0e10cSrcweir } 1268*cdf0e10cSrcweir 1269*cdf0e10cSrcweir void B2DPolygon::reserve(sal_uInt32 nCount) 1270*cdf0e10cSrcweir { 1271*cdf0e10cSrcweir mpPolygon->reserve(nCount); 1272*cdf0e10cSrcweir } 1273*cdf0e10cSrcweir 1274*cdf0e10cSrcweir void B2DPolygon::insert(sal_uInt32 nIndex, const B2DPoint& rPoint, sal_uInt32 nCount) 1275*cdf0e10cSrcweir { 1276*cdf0e10cSrcweir OSL_ENSURE(nIndex <= mpPolygon->count(), "B2DPolygon Insert outside range (!)"); 1277*cdf0e10cSrcweir 1278*cdf0e10cSrcweir if(nCount) 1279*cdf0e10cSrcweir { 1280*cdf0e10cSrcweir mpPolygon->insert(nIndex, rPoint, nCount); 1281*cdf0e10cSrcweir } 1282*cdf0e10cSrcweir } 1283*cdf0e10cSrcweir 1284*cdf0e10cSrcweir void B2DPolygon::append(const B2DPoint& rPoint, sal_uInt32 nCount) 1285*cdf0e10cSrcweir { 1286*cdf0e10cSrcweir if(nCount) 1287*cdf0e10cSrcweir { 1288*cdf0e10cSrcweir mpPolygon->insert(mpPolygon->count(), rPoint, nCount); 1289*cdf0e10cSrcweir } 1290*cdf0e10cSrcweir } 1291*cdf0e10cSrcweir 1292*cdf0e10cSrcweir void B2DPolygon::append(const B2DPoint& rPoint) 1293*cdf0e10cSrcweir { 1294*cdf0e10cSrcweir mpPolygon->append(rPoint); 1295*cdf0e10cSrcweir } 1296*cdf0e10cSrcweir 1297*cdf0e10cSrcweir B2DPoint B2DPolygon::getPrevControlPoint(sal_uInt32 nIndex) const 1298*cdf0e10cSrcweir { 1299*cdf0e10cSrcweir OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)"); 1300*cdf0e10cSrcweir 1301*cdf0e10cSrcweir if(mpPolygon->areControlPointsUsed()) 1302*cdf0e10cSrcweir { 1303*cdf0e10cSrcweir return mpPolygon->getPoint(nIndex) + mpPolygon->getPrevControlVector(nIndex); 1304*cdf0e10cSrcweir } 1305*cdf0e10cSrcweir else 1306*cdf0e10cSrcweir { 1307*cdf0e10cSrcweir return mpPolygon->getPoint(nIndex); 1308*cdf0e10cSrcweir } 1309*cdf0e10cSrcweir } 1310*cdf0e10cSrcweir 1311*cdf0e10cSrcweir B2DPoint B2DPolygon::getNextControlPoint(sal_uInt32 nIndex) const 1312*cdf0e10cSrcweir { 1313*cdf0e10cSrcweir OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)"); 1314*cdf0e10cSrcweir 1315*cdf0e10cSrcweir if(mpPolygon->areControlPointsUsed()) 1316*cdf0e10cSrcweir { 1317*cdf0e10cSrcweir return mpPolygon->getPoint(nIndex) + mpPolygon->getNextControlVector(nIndex); 1318*cdf0e10cSrcweir } 1319*cdf0e10cSrcweir else 1320*cdf0e10cSrcweir { 1321*cdf0e10cSrcweir return mpPolygon->getPoint(nIndex); 1322*cdf0e10cSrcweir } 1323*cdf0e10cSrcweir } 1324*cdf0e10cSrcweir 1325*cdf0e10cSrcweir void B2DPolygon::setPrevControlPoint(sal_uInt32 nIndex, const B2DPoint& rValue) 1326*cdf0e10cSrcweir { 1327*cdf0e10cSrcweir OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)"); 1328*cdf0e10cSrcweir const basegfx::B2DVector aNewVector(rValue - mpPolygon->getPoint(nIndex)); 1329*cdf0e10cSrcweir 1330*cdf0e10cSrcweir if(mpPolygon->getPrevControlVector(nIndex) != aNewVector) 1331*cdf0e10cSrcweir { 1332*cdf0e10cSrcweir mpPolygon->setPrevControlVector(nIndex, aNewVector); 1333*cdf0e10cSrcweir } 1334*cdf0e10cSrcweir } 1335*cdf0e10cSrcweir 1336*cdf0e10cSrcweir void B2DPolygon::setNextControlPoint(sal_uInt32 nIndex, const B2DPoint& rValue) 1337*cdf0e10cSrcweir { 1338*cdf0e10cSrcweir OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)"); 1339*cdf0e10cSrcweir const basegfx::B2DVector aNewVector(rValue - mpPolygon->getPoint(nIndex)); 1340*cdf0e10cSrcweir 1341*cdf0e10cSrcweir if(mpPolygon->getNextControlVector(nIndex) != aNewVector) 1342*cdf0e10cSrcweir { 1343*cdf0e10cSrcweir mpPolygon->setNextControlVector(nIndex, aNewVector); 1344*cdf0e10cSrcweir } 1345*cdf0e10cSrcweir } 1346*cdf0e10cSrcweir 1347*cdf0e10cSrcweir void B2DPolygon::setControlPoints(sal_uInt32 nIndex, const basegfx::B2DPoint& rPrev, const basegfx::B2DPoint& rNext) 1348*cdf0e10cSrcweir { 1349*cdf0e10cSrcweir OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)"); 1350*cdf0e10cSrcweir const B2DPoint aPoint(mpPolygon->getPoint(nIndex)); 1351*cdf0e10cSrcweir const basegfx::B2DVector aNewPrev(rPrev - aPoint); 1352*cdf0e10cSrcweir const basegfx::B2DVector aNewNext(rNext - aPoint); 1353*cdf0e10cSrcweir 1354*cdf0e10cSrcweir if(mpPolygon->getPrevControlVector(nIndex) != aNewPrev || mpPolygon->getNextControlVector(nIndex) != aNewNext) 1355*cdf0e10cSrcweir { 1356*cdf0e10cSrcweir mpPolygon->setControlVectors(nIndex, aNewPrev, aNewNext); 1357*cdf0e10cSrcweir } 1358*cdf0e10cSrcweir } 1359*cdf0e10cSrcweir 1360*cdf0e10cSrcweir void B2DPolygon::resetPrevControlPoint(sal_uInt32 nIndex) 1361*cdf0e10cSrcweir { 1362*cdf0e10cSrcweir OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)"); 1363*cdf0e10cSrcweir 1364*cdf0e10cSrcweir if(mpPolygon->areControlPointsUsed() && !mpPolygon->getPrevControlVector(nIndex).equalZero()) 1365*cdf0e10cSrcweir { 1366*cdf0e10cSrcweir mpPolygon->setPrevControlVector(nIndex, B2DVector::getEmptyVector()); 1367*cdf0e10cSrcweir } 1368*cdf0e10cSrcweir } 1369*cdf0e10cSrcweir 1370*cdf0e10cSrcweir void B2DPolygon::resetNextControlPoint(sal_uInt32 nIndex) 1371*cdf0e10cSrcweir { 1372*cdf0e10cSrcweir OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)"); 1373*cdf0e10cSrcweir 1374*cdf0e10cSrcweir if(mpPolygon->areControlPointsUsed() && !mpPolygon->getNextControlVector(nIndex).equalZero()) 1375*cdf0e10cSrcweir { 1376*cdf0e10cSrcweir mpPolygon->setNextControlVector(nIndex, B2DVector::getEmptyVector()); 1377*cdf0e10cSrcweir } 1378*cdf0e10cSrcweir } 1379*cdf0e10cSrcweir 1380*cdf0e10cSrcweir void B2DPolygon::resetControlPoints(sal_uInt32 nIndex) 1381*cdf0e10cSrcweir { 1382*cdf0e10cSrcweir OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)"); 1383*cdf0e10cSrcweir 1384*cdf0e10cSrcweir if(mpPolygon->areControlPointsUsed() && 1385*cdf0e10cSrcweir (!mpPolygon->getPrevControlVector(nIndex).equalZero() || !mpPolygon->getNextControlVector(nIndex).equalZero())) 1386*cdf0e10cSrcweir { 1387*cdf0e10cSrcweir mpPolygon->resetControlVectors(nIndex); 1388*cdf0e10cSrcweir } 1389*cdf0e10cSrcweir } 1390*cdf0e10cSrcweir 1391*cdf0e10cSrcweir void B2DPolygon::resetControlPoints() 1392*cdf0e10cSrcweir { 1393*cdf0e10cSrcweir if(mpPolygon->areControlPointsUsed()) 1394*cdf0e10cSrcweir { 1395*cdf0e10cSrcweir mpPolygon->resetControlVectors(); 1396*cdf0e10cSrcweir } 1397*cdf0e10cSrcweir } 1398*cdf0e10cSrcweir 1399*cdf0e10cSrcweir void B2DPolygon::appendBezierSegment( 1400*cdf0e10cSrcweir const B2DPoint& rNextControlPoint, 1401*cdf0e10cSrcweir const B2DPoint& rPrevControlPoint, 1402*cdf0e10cSrcweir const B2DPoint& rPoint) 1403*cdf0e10cSrcweir { 1404*cdf0e10cSrcweir const B2DVector aNewNextVector(mpPolygon->count() ? B2DVector(rNextControlPoint - mpPolygon->getPoint(mpPolygon->count() - 1)) : B2DVector::getEmptyVector()); 1405*cdf0e10cSrcweir const B2DVector aNewPrevVector(rPrevControlPoint - rPoint); 1406*cdf0e10cSrcweir 1407*cdf0e10cSrcweir if(aNewNextVector.equalZero() && aNewPrevVector.equalZero()) 1408*cdf0e10cSrcweir { 1409*cdf0e10cSrcweir mpPolygon->insert(mpPolygon->count(), rPoint, 1); 1410*cdf0e10cSrcweir } 1411*cdf0e10cSrcweir else 1412*cdf0e10cSrcweir { 1413*cdf0e10cSrcweir mpPolygon->appendBezierSegment(aNewNextVector, aNewPrevVector, rPoint); 1414*cdf0e10cSrcweir } 1415*cdf0e10cSrcweir } 1416*cdf0e10cSrcweir 1417*cdf0e10cSrcweir bool B2DPolygon::areControlPointsUsed() const 1418*cdf0e10cSrcweir { 1419*cdf0e10cSrcweir return mpPolygon->areControlPointsUsed(); 1420*cdf0e10cSrcweir } 1421*cdf0e10cSrcweir 1422*cdf0e10cSrcweir bool B2DPolygon::isPrevControlPointUsed(sal_uInt32 nIndex) const 1423*cdf0e10cSrcweir { 1424*cdf0e10cSrcweir OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)"); 1425*cdf0e10cSrcweir 1426*cdf0e10cSrcweir return (mpPolygon->areControlPointsUsed() && !mpPolygon->getPrevControlVector(nIndex).equalZero()); 1427*cdf0e10cSrcweir } 1428*cdf0e10cSrcweir 1429*cdf0e10cSrcweir bool B2DPolygon::isNextControlPointUsed(sal_uInt32 nIndex) const 1430*cdf0e10cSrcweir { 1431*cdf0e10cSrcweir OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)"); 1432*cdf0e10cSrcweir 1433*cdf0e10cSrcweir return (mpPolygon->areControlPointsUsed() && !mpPolygon->getNextControlVector(nIndex).equalZero()); 1434*cdf0e10cSrcweir } 1435*cdf0e10cSrcweir 1436*cdf0e10cSrcweir B2VectorContinuity B2DPolygon::getContinuityInPoint(sal_uInt32 nIndex) const 1437*cdf0e10cSrcweir { 1438*cdf0e10cSrcweir OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)"); 1439*cdf0e10cSrcweir 1440*cdf0e10cSrcweir if(mpPolygon->areControlPointsUsed()) 1441*cdf0e10cSrcweir { 1442*cdf0e10cSrcweir const B2DVector& rPrev(mpPolygon->getPrevControlVector(nIndex)); 1443*cdf0e10cSrcweir const B2DVector& rNext(mpPolygon->getNextControlVector(nIndex)); 1444*cdf0e10cSrcweir 1445*cdf0e10cSrcweir return getContinuity(rPrev, rNext); 1446*cdf0e10cSrcweir } 1447*cdf0e10cSrcweir else 1448*cdf0e10cSrcweir { 1449*cdf0e10cSrcweir return CONTINUITY_NONE; 1450*cdf0e10cSrcweir } 1451*cdf0e10cSrcweir } 1452*cdf0e10cSrcweir 1453*cdf0e10cSrcweir bool B2DPolygon::isBezierSegment(sal_uInt32 nIndex) const 1454*cdf0e10cSrcweir { 1455*cdf0e10cSrcweir OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)"); 1456*cdf0e10cSrcweir 1457*cdf0e10cSrcweir if(mpPolygon->areControlPointsUsed()) 1458*cdf0e10cSrcweir { 1459*cdf0e10cSrcweir // Check if the edge exists 1460*cdf0e10cSrcweir const bool bNextIndexValidWithoutClose(nIndex + 1 < mpPolygon->count()); 1461*cdf0e10cSrcweir 1462*cdf0e10cSrcweir if(bNextIndexValidWithoutClose || mpPolygon->isClosed()) 1463*cdf0e10cSrcweir { 1464*cdf0e10cSrcweir const sal_uInt32 nNextIndex(bNextIndexValidWithoutClose ? nIndex + 1 : 0); 1465*cdf0e10cSrcweir return (!mpPolygon->getPrevControlVector(nNextIndex).equalZero() 1466*cdf0e10cSrcweir || !mpPolygon->getNextControlVector(nIndex).equalZero()); 1467*cdf0e10cSrcweir } 1468*cdf0e10cSrcweir else 1469*cdf0e10cSrcweir { 1470*cdf0e10cSrcweir // no valid edge -> no bezier segment, even when local next 1471*cdf0e10cSrcweir // vector may be used 1472*cdf0e10cSrcweir return false; 1473*cdf0e10cSrcweir } 1474*cdf0e10cSrcweir } 1475*cdf0e10cSrcweir else 1476*cdf0e10cSrcweir { 1477*cdf0e10cSrcweir // no control points -> no bezier segment 1478*cdf0e10cSrcweir return false; 1479*cdf0e10cSrcweir } 1480*cdf0e10cSrcweir } 1481*cdf0e10cSrcweir 1482*cdf0e10cSrcweir void B2DPolygon::getBezierSegment(sal_uInt32 nIndex, B2DCubicBezier& rTarget) const 1483*cdf0e10cSrcweir { 1484*cdf0e10cSrcweir OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)"); 1485*cdf0e10cSrcweir const bool bNextIndexValidWithoutClose(nIndex + 1 < mpPolygon->count()); 1486*cdf0e10cSrcweir 1487*cdf0e10cSrcweir if(bNextIndexValidWithoutClose || mpPolygon->isClosed()) 1488*cdf0e10cSrcweir { 1489*cdf0e10cSrcweir const sal_uInt32 nNextIndex(bNextIndexValidWithoutClose ? nIndex + 1 : 0); 1490*cdf0e10cSrcweir rTarget.setStartPoint(mpPolygon->getPoint(nIndex)); 1491*cdf0e10cSrcweir rTarget.setEndPoint(mpPolygon->getPoint(nNextIndex)); 1492*cdf0e10cSrcweir 1493*cdf0e10cSrcweir if(mpPolygon->areControlPointsUsed()) 1494*cdf0e10cSrcweir { 1495*cdf0e10cSrcweir rTarget.setControlPointA(rTarget.getStartPoint() + mpPolygon->getNextControlVector(nIndex)); 1496*cdf0e10cSrcweir rTarget.setControlPointB(rTarget.getEndPoint() + mpPolygon->getPrevControlVector(nNextIndex)); 1497*cdf0e10cSrcweir } 1498*cdf0e10cSrcweir else 1499*cdf0e10cSrcweir { 1500*cdf0e10cSrcweir // no bezier, reset control poins at rTarget 1501*cdf0e10cSrcweir rTarget.setControlPointA(rTarget.getStartPoint()); 1502*cdf0e10cSrcweir rTarget.setControlPointB(rTarget.getEndPoint()); 1503*cdf0e10cSrcweir } 1504*cdf0e10cSrcweir } 1505*cdf0e10cSrcweir else 1506*cdf0e10cSrcweir { 1507*cdf0e10cSrcweir // no valid edge at all, reset rTarget to current point 1508*cdf0e10cSrcweir const B2DPoint aPoint(mpPolygon->getPoint(nIndex)); 1509*cdf0e10cSrcweir rTarget.setStartPoint(aPoint); 1510*cdf0e10cSrcweir rTarget.setEndPoint(aPoint); 1511*cdf0e10cSrcweir rTarget.setControlPointA(aPoint); 1512*cdf0e10cSrcweir rTarget.setControlPointB(aPoint); 1513*cdf0e10cSrcweir } 1514*cdf0e10cSrcweir } 1515*cdf0e10cSrcweir 1516*cdf0e10cSrcweir B2DPolygon B2DPolygon::getDefaultAdaptiveSubdivision() const 1517*cdf0e10cSrcweir { 1518*cdf0e10cSrcweir return mpPolygon->getDefaultAdaptiveSubdivision(*this); 1519*cdf0e10cSrcweir } 1520*cdf0e10cSrcweir 1521*cdf0e10cSrcweir B2DRange B2DPolygon::getB2DRange() const 1522*cdf0e10cSrcweir { 1523*cdf0e10cSrcweir return mpPolygon->getB2DRange(*this); 1524*cdf0e10cSrcweir } 1525*cdf0e10cSrcweir 1526*cdf0e10cSrcweir void B2DPolygon::insert(sal_uInt32 nIndex, const B2DPolygon& rPoly, sal_uInt32 nIndex2, sal_uInt32 nCount) 1527*cdf0e10cSrcweir { 1528*cdf0e10cSrcweir OSL_ENSURE(nIndex <= mpPolygon->count(), "B2DPolygon Insert outside range (!)"); 1529*cdf0e10cSrcweir 1530*cdf0e10cSrcweir if(rPoly.count()) 1531*cdf0e10cSrcweir { 1532*cdf0e10cSrcweir if(!nCount) 1533*cdf0e10cSrcweir { 1534*cdf0e10cSrcweir nCount = rPoly.count(); 1535*cdf0e10cSrcweir } 1536*cdf0e10cSrcweir 1537*cdf0e10cSrcweir if(0 == nIndex2 && nCount == rPoly.count()) 1538*cdf0e10cSrcweir { 1539*cdf0e10cSrcweir mpPolygon->insert(nIndex, *rPoly.mpPolygon); 1540*cdf0e10cSrcweir } 1541*cdf0e10cSrcweir else 1542*cdf0e10cSrcweir { 1543*cdf0e10cSrcweir OSL_ENSURE(nIndex2 + nCount <= rPoly.mpPolygon->count(), "B2DPolygon Insert outside range (!)"); 1544*cdf0e10cSrcweir ImplB2DPolygon aTempPoly(*rPoly.mpPolygon, nIndex2, nCount); 1545*cdf0e10cSrcweir mpPolygon->insert(nIndex, aTempPoly); 1546*cdf0e10cSrcweir } 1547*cdf0e10cSrcweir } 1548*cdf0e10cSrcweir } 1549*cdf0e10cSrcweir 1550*cdf0e10cSrcweir void B2DPolygon::append(const B2DPolygon& rPoly, sal_uInt32 nIndex, sal_uInt32 nCount) 1551*cdf0e10cSrcweir { 1552*cdf0e10cSrcweir if(rPoly.count()) 1553*cdf0e10cSrcweir { 1554*cdf0e10cSrcweir if(!nCount) 1555*cdf0e10cSrcweir { 1556*cdf0e10cSrcweir nCount = rPoly.count(); 1557*cdf0e10cSrcweir } 1558*cdf0e10cSrcweir 1559*cdf0e10cSrcweir if(0 == nIndex && nCount == rPoly.count()) 1560*cdf0e10cSrcweir { 1561*cdf0e10cSrcweir mpPolygon->insert(mpPolygon->count(), *rPoly.mpPolygon); 1562*cdf0e10cSrcweir } 1563*cdf0e10cSrcweir else 1564*cdf0e10cSrcweir { 1565*cdf0e10cSrcweir OSL_ENSURE(nIndex + nCount <= rPoly.mpPolygon->count(), "B2DPolygon Append outside range (!)"); 1566*cdf0e10cSrcweir ImplB2DPolygon aTempPoly(*rPoly.mpPolygon, nIndex, nCount); 1567*cdf0e10cSrcweir mpPolygon->insert(mpPolygon->count(), aTempPoly); 1568*cdf0e10cSrcweir } 1569*cdf0e10cSrcweir } 1570*cdf0e10cSrcweir } 1571*cdf0e10cSrcweir 1572*cdf0e10cSrcweir void B2DPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount) 1573*cdf0e10cSrcweir { 1574*cdf0e10cSrcweir OSL_ENSURE(nIndex + nCount <= mpPolygon->count(), "B2DPolygon Remove outside range (!)"); 1575*cdf0e10cSrcweir 1576*cdf0e10cSrcweir if(nCount) 1577*cdf0e10cSrcweir { 1578*cdf0e10cSrcweir mpPolygon->remove(nIndex, nCount); 1579*cdf0e10cSrcweir } 1580*cdf0e10cSrcweir } 1581*cdf0e10cSrcweir 1582*cdf0e10cSrcweir void B2DPolygon::clear() 1583*cdf0e10cSrcweir { 1584*cdf0e10cSrcweir mpPolygon = DefaultPolygon::get(); 1585*cdf0e10cSrcweir } 1586*cdf0e10cSrcweir 1587*cdf0e10cSrcweir bool B2DPolygon::isClosed() const 1588*cdf0e10cSrcweir { 1589*cdf0e10cSrcweir return mpPolygon->isClosed(); 1590*cdf0e10cSrcweir } 1591*cdf0e10cSrcweir 1592*cdf0e10cSrcweir void B2DPolygon::setClosed(bool bNew) 1593*cdf0e10cSrcweir { 1594*cdf0e10cSrcweir if(isClosed() != bNew) 1595*cdf0e10cSrcweir { 1596*cdf0e10cSrcweir mpPolygon->setClosed(bNew); 1597*cdf0e10cSrcweir } 1598*cdf0e10cSrcweir } 1599*cdf0e10cSrcweir 1600*cdf0e10cSrcweir void B2DPolygon::flip() 1601*cdf0e10cSrcweir { 1602*cdf0e10cSrcweir if(count() > 1) 1603*cdf0e10cSrcweir { 1604*cdf0e10cSrcweir mpPolygon->flip(); 1605*cdf0e10cSrcweir } 1606*cdf0e10cSrcweir } 1607*cdf0e10cSrcweir 1608*cdf0e10cSrcweir bool B2DPolygon::hasDoublePoints() const 1609*cdf0e10cSrcweir { 1610*cdf0e10cSrcweir return (mpPolygon->count() > 1 && mpPolygon->hasDoublePoints()); 1611*cdf0e10cSrcweir } 1612*cdf0e10cSrcweir 1613*cdf0e10cSrcweir void B2DPolygon::removeDoublePoints() 1614*cdf0e10cSrcweir { 1615*cdf0e10cSrcweir if(hasDoublePoints()) 1616*cdf0e10cSrcweir { 1617*cdf0e10cSrcweir mpPolygon->removeDoublePointsAtBeginEnd(); 1618*cdf0e10cSrcweir mpPolygon->removeDoublePointsWholeTrack(); 1619*cdf0e10cSrcweir } 1620*cdf0e10cSrcweir } 1621*cdf0e10cSrcweir 1622*cdf0e10cSrcweir void B2DPolygon::transform(const B2DHomMatrix& rMatrix) 1623*cdf0e10cSrcweir { 1624*cdf0e10cSrcweir if(mpPolygon->count() && !rMatrix.isIdentity()) 1625*cdf0e10cSrcweir { 1626*cdf0e10cSrcweir mpPolygon->transform(rMatrix); 1627*cdf0e10cSrcweir } 1628*cdf0e10cSrcweir } 1629*cdf0e10cSrcweir 1630*cdf0e10cSrcweir const B2DPoint* B2DPolygon::begin() const 1631*cdf0e10cSrcweir { 1632*cdf0e10cSrcweir return mpPolygon->begin(); 1633*cdf0e10cSrcweir } 1634*cdf0e10cSrcweir 1635*cdf0e10cSrcweir const B2DPoint* B2DPolygon::end() const 1636*cdf0e10cSrcweir { 1637*cdf0e10cSrcweir return mpPolygon->end(); 1638*cdf0e10cSrcweir } 1639*cdf0e10cSrcweir 1640*cdf0e10cSrcweir B2DPoint* B2DPolygon::begin() 1641*cdf0e10cSrcweir { 1642*cdf0e10cSrcweir return mpPolygon->begin(); 1643*cdf0e10cSrcweir } 1644*cdf0e10cSrcweir 1645*cdf0e10cSrcweir B2DPoint* B2DPolygon::end() 1646*cdf0e10cSrcweir { 1647*cdf0e10cSrcweir return mpPolygon->end(); 1648*cdf0e10cSrcweir } 1649*cdf0e10cSrcweir } // end of namespace basegfx 1650*cdf0e10cSrcweir 1651*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 1652*cdf0e10cSrcweir // eof 1653