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_tools.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #define _SV_POLY2_CXX 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir #define POLY_CLIP_INT 0 34*cdf0e10cSrcweir #define POLY_CLIP_UNION 1 35*cdf0e10cSrcweir #define POLY_CLIP_DIFF 2 36*cdf0e10cSrcweir #define POLY_CLIP_XOR 3 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir #include <rtl/math.hxx> 39*cdf0e10cSrcweir #include <poly.h> 40*cdf0e10cSrcweir #include <tools/poly.hxx> 41*cdf0e10cSrcweir #include <tools/debug.hxx> 42*cdf0e10cSrcweir #include <tools/stream.hxx> 43*cdf0e10cSrcweir #include <tools/vcompat.hxx> 44*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygon.hxx> 45*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx> 46*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygoncutter.hxx> 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir // --------------- 49*cdf0e10cSrcweir // - PolyPolygon - 50*cdf0e10cSrcweir // --------------- 51*cdf0e10cSrcweir 52*cdf0e10cSrcweir DBG_NAME( PolyPolygon ) 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir // ----------------------------------------------------------------------- 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir ImplPolyPolygon::ImplPolyPolygon( sal_uInt16 nInitSize ) 57*cdf0e10cSrcweir { 58*cdf0e10cSrcweir mnRefCount = 1; 59*cdf0e10cSrcweir mnCount = nInitSize; 60*cdf0e10cSrcweir mnSize = nInitSize; 61*cdf0e10cSrcweir mnResize = 16; 62*cdf0e10cSrcweir mpPolyAry = new SVPPOLYGON[ nInitSize ]; 63*cdf0e10cSrcweir } 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir // ----------------------------------------------------------------------- 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir ImplPolyPolygon::ImplPolyPolygon( const ImplPolyPolygon& rImplPolyPoly ) 68*cdf0e10cSrcweir { 69*cdf0e10cSrcweir mnRefCount = 1; 70*cdf0e10cSrcweir mnCount = rImplPolyPoly.mnCount; 71*cdf0e10cSrcweir mnSize = rImplPolyPoly.mnSize; 72*cdf0e10cSrcweir mnResize = rImplPolyPoly.mnResize; 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir if ( rImplPolyPoly.mpPolyAry ) 75*cdf0e10cSrcweir { 76*cdf0e10cSrcweir mpPolyAry = new SVPPOLYGON[mnSize]; 77*cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < mnCount; i++ ) 78*cdf0e10cSrcweir mpPolyAry[i] = new Polygon( *rImplPolyPoly.mpPolyAry[i] ); 79*cdf0e10cSrcweir } 80*cdf0e10cSrcweir else 81*cdf0e10cSrcweir mpPolyAry = NULL; 82*cdf0e10cSrcweir } 83*cdf0e10cSrcweir 84*cdf0e10cSrcweir // ----------------------------------------------------------------------- 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir ImplPolyPolygon::~ImplPolyPolygon() 87*cdf0e10cSrcweir { 88*cdf0e10cSrcweir if ( mpPolyAry ) 89*cdf0e10cSrcweir { 90*cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < mnCount; i++ ) 91*cdf0e10cSrcweir delete mpPolyAry[i]; 92*cdf0e10cSrcweir delete[] mpPolyAry; 93*cdf0e10cSrcweir } 94*cdf0e10cSrcweir } 95*cdf0e10cSrcweir 96*cdf0e10cSrcweir // ======================================================================= 97*cdf0e10cSrcweir 98*cdf0e10cSrcweir PolyPolygon::PolyPolygon( sal_uInt16 nInitSize, sal_uInt16 nResize ) 99*cdf0e10cSrcweir { 100*cdf0e10cSrcweir DBG_CTOR( PolyPolygon, NULL ); 101*cdf0e10cSrcweir 102*cdf0e10cSrcweir if ( nInitSize > MAX_POLYGONS ) 103*cdf0e10cSrcweir nInitSize = MAX_POLYGONS; 104*cdf0e10cSrcweir else if ( !nInitSize ) 105*cdf0e10cSrcweir nInitSize = 1; 106*cdf0e10cSrcweir if ( nResize > MAX_POLYGONS ) 107*cdf0e10cSrcweir nResize = MAX_POLYGONS; 108*cdf0e10cSrcweir else if ( !nResize ) 109*cdf0e10cSrcweir nResize = 1; 110*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( nInitSize, nResize ); 111*cdf0e10cSrcweir } 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir // ----------------------------------------------------------------------- 114*cdf0e10cSrcweir 115*cdf0e10cSrcweir PolyPolygon::PolyPolygon( const Polygon& rPoly ) 116*cdf0e10cSrcweir { 117*cdf0e10cSrcweir DBG_CTOR( PolyPolygon, NULL ); 118*cdf0e10cSrcweir 119*cdf0e10cSrcweir if ( rPoly.GetSize() ) 120*cdf0e10cSrcweir { 121*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( 1 ); 122*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[0] = new Polygon( rPoly ); 123*cdf0e10cSrcweir } 124*cdf0e10cSrcweir else 125*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( 16, 16 ); 126*cdf0e10cSrcweir } 127*cdf0e10cSrcweir 128*cdf0e10cSrcweir // ----------------------------------------------------------------------- 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir PolyPolygon::PolyPolygon( sal_uInt16 nPoly, const sal_uInt16* pPointCountAry, 131*cdf0e10cSrcweir const Point* pPtAry ) 132*cdf0e10cSrcweir { 133*cdf0e10cSrcweir DBG_CTOR( PolyPolygon, NULL ); 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir if ( nPoly > MAX_POLYGONS ) 136*cdf0e10cSrcweir nPoly = MAX_POLYGONS; 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( nPoly ); 139*cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < nPoly; i++ ) 140*cdf0e10cSrcweir { 141*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[i] = new Polygon( *pPointCountAry, pPtAry ); 142*cdf0e10cSrcweir pPtAry += *pPointCountAry; 143*cdf0e10cSrcweir pPointCountAry++; 144*cdf0e10cSrcweir } 145*cdf0e10cSrcweir } 146*cdf0e10cSrcweir 147*cdf0e10cSrcweir // ----------------------------------------------------------------------- 148*cdf0e10cSrcweir 149*cdf0e10cSrcweir PolyPolygon::PolyPolygon( const PolyPolygon& rPolyPoly ) 150*cdf0e10cSrcweir { 151*cdf0e10cSrcweir DBG_CTOR( PolyPolygon, NULL ); 152*cdf0e10cSrcweir DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL ); 153*cdf0e10cSrcweir DBG_ASSERT( rPolyPoly.mpImplPolyPolygon->mnRefCount < 0xFFFFFFFE, "PolyPolygon: RefCount overflow" ); 154*cdf0e10cSrcweir 155*cdf0e10cSrcweir mpImplPolyPolygon = rPolyPoly.mpImplPolyPolygon; 156*cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount++; 157*cdf0e10cSrcweir } 158*cdf0e10cSrcweir 159*cdf0e10cSrcweir // ----------------------------------------------------------------------- 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir PolyPolygon::~PolyPolygon() 162*cdf0e10cSrcweir { 163*cdf0e10cSrcweir DBG_DTOR( PolyPolygon, NULL ); 164*cdf0e10cSrcweir 165*cdf0e10cSrcweir if ( mpImplPolyPolygon->mnRefCount > 1 ) 166*cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--; 167*cdf0e10cSrcweir else 168*cdf0e10cSrcweir delete mpImplPolyPolygon; 169*cdf0e10cSrcweir } 170*cdf0e10cSrcweir 171*cdf0e10cSrcweir // ----------------------------------------------------------------------- 172*cdf0e10cSrcweir 173*cdf0e10cSrcweir void PolyPolygon::Insert( const Polygon& rPoly, sal_uInt16 nPos ) 174*cdf0e10cSrcweir { 175*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 176*cdf0e10cSrcweir 177*cdf0e10cSrcweir if ( mpImplPolyPolygon->mnCount >= MAX_POLYGONS ) 178*cdf0e10cSrcweir return; 179*cdf0e10cSrcweir 180*cdf0e10cSrcweir if ( mpImplPolyPolygon->mnRefCount > 1 ) 181*cdf0e10cSrcweir { 182*cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--; 183*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon ); 184*cdf0e10cSrcweir } 185*cdf0e10cSrcweir 186*cdf0e10cSrcweir if ( nPos > mpImplPolyPolygon->mnCount ) 187*cdf0e10cSrcweir nPos = mpImplPolyPolygon->mnCount; 188*cdf0e10cSrcweir 189*cdf0e10cSrcweir if ( !mpImplPolyPolygon->mpPolyAry ) 190*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry = new SVPPOLYGON[mpImplPolyPolygon->mnSize]; 191*cdf0e10cSrcweir else if ( mpImplPolyPolygon->mnCount == mpImplPolyPolygon->mnSize ) 192*cdf0e10cSrcweir { 193*cdf0e10cSrcweir sal_uInt16 nOldSize = mpImplPolyPolygon->mnSize; 194*cdf0e10cSrcweir sal_uInt16 nNewSize = nOldSize + mpImplPolyPolygon->mnResize; 195*cdf0e10cSrcweir SVPPOLYGON* pNewAry; 196*cdf0e10cSrcweir 197*cdf0e10cSrcweir if ( nNewSize >= MAX_POLYGONS ) 198*cdf0e10cSrcweir nNewSize = MAX_POLYGONS; 199*cdf0e10cSrcweir pNewAry = new SVPPOLYGON[nNewSize]; 200*cdf0e10cSrcweir memcpy( pNewAry, mpImplPolyPolygon->mpPolyAry, nPos*sizeof(SVPPOLYGON) ); 201*cdf0e10cSrcweir memcpy( pNewAry+nPos+1, mpImplPolyPolygon->mpPolyAry+nPos, 202*cdf0e10cSrcweir (nOldSize-nPos)*sizeof(SVPPOLYGON) ); 203*cdf0e10cSrcweir delete[] mpImplPolyPolygon->mpPolyAry; 204*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry = pNewAry; 205*cdf0e10cSrcweir mpImplPolyPolygon->mnSize = nNewSize; 206*cdf0e10cSrcweir } 207*cdf0e10cSrcweir else if ( nPos < mpImplPolyPolygon->mnCount ) 208*cdf0e10cSrcweir { 209*cdf0e10cSrcweir memmove( mpImplPolyPolygon->mpPolyAry+nPos+1, 210*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry+nPos, 211*cdf0e10cSrcweir (mpImplPolyPolygon->mnCount-nPos)*sizeof(SVPPOLYGON) ); 212*cdf0e10cSrcweir } 213*cdf0e10cSrcweir 214*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[nPos] = new Polygon( rPoly ); 215*cdf0e10cSrcweir mpImplPolyPolygon->mnCount++; 216*cdf0e10cSrcweir } 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir // ----------------------------------------------------------------------- 219*cdf0e10cSrcweir 220*cdf0e10cSrcweir void PolyPolygon::Remove( sal_uInt16 nPos ) 221*cdf0e10cSrcweir { 222*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 223*cdf0e10cSrcweir DBG_ASSERT( nPos < Count(), "PolyPolygon::Remove(): nPos >= nSize" ); 224*cdf0e10cSrcweir 225*cdf0e10cSrcweir if ( mpImplPolyPolygon->mnRefCount > 1 ) 226*cdf0e10cSrcweir { 227*cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--; 228*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon ); 229*cdf0e10cSrcweir } 230*cdf0e10cSrcweir 231*cdf0e10cSrcweir delete mpImplPolyPolygon->mpPolyAry[nPos]; 232*cdf0e10cSrcweir mpImplPolyPolygon->mnCount--; 233*cdf0e10cSrcweir memmove( mpImplPolyPolygon->mpPolyAry+nPos, 234*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry+nPos+1, 235*cdf0e10cSrcweir (mpImplPolyPolygon->mnCount-nPos)*sizeof(SVPPOLYGON) ); 236*cdf0e10cSrcweir } 237*cdf0e10cSrcweir 238*cdf0e10cSrcweir // ----------------------------------------------------------------------- 239*cdf0e10cSrcweir 240*cdf0e10cSrcweir void PolyPolygon::Replace( const Polygon& rPoly, sal_uInt16 nPos ) 241*cdf0e10cSrcweir { 242*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 243*cdf0e10cSrcweir DBG_ASSERT( nPos < Count(), "PolyPolygon::Replace(): nPos >= nSize" ); 244*cdf0e10cSrcweir 245*cdf0e10cSrcweir if ( mpImplPolyPolygon->mnRefCount > 1 ) 246*cdf0e10cSrcweir { 247*cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--; 248*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon ); 249*cdf0e10cSrcweir } 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir delete mpImplPolyPolygon->mpPolyAry[nPos]; 252*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[nPos] = new Polygon( rPoly ); 253*cdf0e10cSrcweir } 254*cdf0e10cSrcweir 255*cdf0e10cSrcweir // ----------------------------------------------------------------------- 256*cdf0e10cSrcweir 257*cdf0e10cSrcweir const Polygon& PolyPolygon::GetObject( sal_uInt16 nPos ) const 258*cdf0e10cSrcweir { 259*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 260*cdf0e10cSrcweir DBG_ASSERT( nPos < Count(), "PolyPolygon::GetObject(): nPos >= nSize" ); 261*cdf0e10cSrcweir 262*cdf0e10cSrcweir return *(mpImplPolyPolygon->mpPolyAry[nPos]); 263*cdf0e10cSrcweir } 264*cdf0e10cSrcweir 265*cdf0e10cSrcweir // ----------------------------------------------------------------------- 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir sal_Bool PolyPolygon::IsRect() const 268*cdf0e10cSrcweir { 269*cdf0e10cSrcweir sal_Bool bIsRect = sal_False; 270*cdf0e10cSrcweir if ( Count() == 1 ) 271*cdf0e10cSrcweir bIsRect = mpImplPolyPolygon->mpPolyAry[ 0 ]->IsRect(); 272*cdf0e10cSrcweir return bIsRect; 273*cdf0e10cSrcweir } 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir // ----------------------------------------------------------------------- 276*cdf0e10cSrcweir 277*cdf0e10cSrcweir void PolyPolygon::Clear() 278*cdf0e10cSrcweir { 279*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 280*cdf0e10cSrcweir 281*cdf0e10cSrcweir if ( mpImplPolyPolygon->mnRefCount > 1 ) 282*cdf0e10cSrcweir { 283*cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--; 284*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( mpImplPolyPolygon->mnResize, 285*cdf0e10cSrcweir mpImplPolyPolygon->mnResize ); 286*cdf0e10cSrcweir } 287*cdf0e10cSrcweir else 288*cdf0e10cSrcweir { 289*cdf0e10cSrcweir if ( mpImplPolyPolygon->mpPolyAry ) 290*cdf0e10cSrcweir { 291*cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < mpImplPolyPolygon->mnCount; i++ ) 292*cdf0e10cSrcweir delete mpImplPolyPolygon->mpPolyAry[i]; 293*cdf0e10cSrcweir delete[] mpImplPolyPolygon->mpPolyAry; 294*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry = NULL; 295*cdf0e10cSrcweir mpImplPolyPolygon->mnCount = 0; 296*cdf0e10cSrcweir mpImplPolyPolygon->mnSize = mpImplPolyPolygon->mnResize; 297*cdf0e10cSrcweir } 298*cdf0e10cSrcweir } 299*cdf0e10cSrcweir } 300*cdf0e10cSrcweir 301*cdf0e10cSrcweir // ----------------------------------------------------------------------- 302*cdf0e10cSrcweir 303*cdf0e10cSrcweir void PolyPolygon::Optimize( sal_uIntPtr nOptimizeFlags, const PolyOptimizeData* pData ) 304*cdf0e10cSrcweir { 305*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 306*cdf0e10cSrcweir 307*cdf0e10cSrcweir if( nOptimizeFlags ) 308*cdf0e10cSrcweir { 309*cdf0e10cSrcweir double fArea; 310*cdf0e10cSrcweir const sal_Bool bEdges = ( nOptimizeFlags & POLY_OPTIMIZE_EDGES ) == POLY_OPTIMIZE_EDGES; 311*cdf0e10cSrcweir sal_uInt16 nPercent = 0; 312*cdf0e10cSrcweir 313*cdf0e10cSrcweir if( bEdges ) 314*cdf0e10cSrcweir { 315*cdf0e10cSrcweir const Rectangle aBound( GetBoundRect() ); 316*cdf0e10cSrcweir 317*cdf0e10cSrcweir fArea = ( aBound.GetWidth() + aBound.GetHeight() ) * 0.5; 318*cdf0e10cSrcweir nPercent = pData ? pData->GetPercentValue() : 50; 319*cdf0e10cSrcweir nOptimizeFlags &= ~POLY_OPTIMIZE_EDGES; 320*cdf0e10cSrcweir } 321*cdf0e10cSrcweir 322*cdf0e10cSrcweir // watch for ref counter 323*cdf0e10cSrcweir if( mpImplPolyPolygon->mnRefCount > 1 ) 324*cdf0e10cSrcweir { 325*cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--; 326*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon ); 327*cdf0e10cSrcweir } 328*cdf0e10cSrcweir 329*cdf0e10cSrcweir // Optimize polygons 330*cdf0e10cSrcweir for( sal_uInt16 i = 0, nPolyCount = mpImplPolyPolygon->mnCount; i < nPolyCount; i++ ) 331*cdf0e10cSrcweir { 332*cdf0e10cSrcweir if( bEdges ) 333*cdf0e10cSrcweir { 334*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[ i ]->Optimize( POLY_OPTIMIZE_NO_SAME ); 335*cdf0e10cSrcweir Polygon::ImplReduceEdges( *( mpImplPolyPolygon->mpPolyAry[ i ] ), fArea, nPercent ); 336*cdf0e10cSrcweir } 337*cdf0e10cSrcweir 338*cdf0e10cSrcweir if( nOptimizeFlags ) 339*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[ i ]->Optimize( nOptimizeFlags, pData ); 340*cdf0e10cSrcweir } 341*cdf0e10cSrcweir } 342*cdf0e10cSrcweir } 343*cdf0e10cSrcweir 344*cdf0e10cSrcweir // ----------------------------------------------------------------------- 345*cdf0e10cSrcweir 346*cdf0e10cSrcweir void PolyPolygon::AdaptiveSubdivide( PolyPolygon& rResult, const double d ) const 347*cdf0e10cSrcweir { 348*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 349*cdf0e10cSrcweir 350*cdf0e10cSrcweir rResult.Clear(); 351*cdf0e10cSrcweir 352*cdf0e10cSrcweir Polygon aPolygon; 353*cdf0e10cSrcweir 354*cdf0e10cSrcweir for( sal_uInt16 i = 0; i < mpImplPolyPolygon->mnCount; i++ ) 355*cdf0e10cSrcweir { 356*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[ i ]->AdaptiveSubdivide( aPolygon, d ); 357*cdf0e10cSrcweir rResult.Insert( aPolygon ); 358*cdf0e10cSrcweir } 359*cdf0e10cSrcweir } 360*cdf0e10cSrcweir 361*cdf0e10cSrcweir // ----------------------------------------------------------------------- 362*cdf0e10cSrcweir 363*cdf0e10cSrcweir void PolyPolygon::GetIntersection( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const 364*cdf0e10cSrcweir { 365*cdf0e10cSrcweir ImplDoOperation( rPolyPoly, rResult, POLY_CLIP_INT ); 366*cdf0e10cSrcweir } 367*cdf0e10cSrcweir 368*cdf0e10cSrcweir // ----------------------------------------------------------------------- 369*cdf0e10cSrcweir 370*cdf0e10cSrcweir void PolyPolygon::GetUnion( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const 371*cdf0e10cSrcweir { 372*cdf0e10cSrcweir ImplDoOperation( rPolyPoly, rResult, POLY_CLIP_UNION ); 373*cdf0e10cSrcweir } 374*cdf0e10cSrcweir 375*cdf0e10cSrcweir // ----------------------------------------------------------------------- 376*cdf0e10cSrcweir 377*cdf0e10cSrcweir void PolyPolygon::GetDifference( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const 378*cdf0e10cSrcweir { 379*cdf0e10cSrcweir ImplDoOperation( rPolyPoly, rResult, POLY_CLIP_DIFF ); 380*cdf0e10cSrcweir } 381*cdf0e10cSrcweir 382*cdf0e10cSrcweir // ----------------------------------------------------------------------- 383*cdf0e10cSrcweir 384*cdf0e10cSrcweir void PolyPolygon::GetXOR( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const 385*cdf0e10cSrcweir { 386*cdf0e10cSrcweir ImplDoOperation( rPolyPoly, rResult, POLY_CLIP_XOR ); 387*cdf0e10cSrcweir } 388*cdf0e10cSrcweir 389*cdf0e10cSrcweir // ----------------------------------------------------------------------- 390*cdf0e10cSrcweir 391*cdf0e10cSrcweir void PolyPolygon::ImplDoOperation( const PolyPolygon& rPolyPoly, PolyPolygon& rResult, sal_uIntPtr nOperation ) const 392*cdf0e10cSrcweir { 393*cdf0e10cSrcweir // Convert to B2DPolyPolygon, temporarily. It might be 394*cdf0e10cSrcweir // advantageous in the future, to have a PolyPolygon adaptor that 395*cdf0e10cSrcweir // just simulates a B2DPolyPolygon here... 396*cdf0e10cSrcweir basegfx::B2DPolyPolygon aMergePolyPolygonA( getB2DPolyPolygon() ); 397*cdf0e10cSrcweir basegfx::B2DPolyPolygon aMergePolyPolygonB( rPolyPoly.getB2DPolyPolygon() ); 398*cdf0e10cSrcweir 399*cdf0e10cSrcweir // normalize the two polypolygons before. Force properly oriented 400*cdf0e10cSrcweir // polygons. 401*cdf0e10cSrcweir aMergePolyPolygonA = basegfx::tools::prepareForPolygonOperation( aMergePolyPolygonA ); 402*cdf0e10cSrcweir aMergePolyPolygonB = basegfx::tools::prepareForPolygonOperation( aMergePolyPolygonB ); 403*cdf0e10cSrcweir 404*cdf0e10cSrcweir switch( nOperation ) 405*cdf0e10cSrcweir { 406*cdf0e10cSrcweir // All code extracted from svx/source/svdraw/svedtv2.cxx 407*cdf0e10cSrcweir // ----------------------------------------------------- 408*cdf0e10cSrcweir 409*cdf0e10cSrcweir case POLY_CLIP_UNION: 410*cdf0e10cSrcweir { 411*cdf0e10cSrcweir // merge A and B (OR) 412*cdf0e10cSrcweir aMergePolyPolygonA = basegfx::tools::solvePolygonOperationOr(aMergePolyPolygonA, aMergePolyPolygonB); 413*cdf0e10cSrcweir break; 414*cdf0e10cSrcweir } 415*cdf0e10cSrcweir 416*cdf0e10cSrcweir case POLY_CLIP_DIFF: 417*cdf0e10cSrcweir { 418*cdf0e10cSrcweir // substract B from A (DIFF) 419*cdf0e10cSrcweir aMergePolyPolygonA = basegfx::tools::solvePolygonOperationDiff(aMergePolyPolygonA, aMergePolyPolygonB); 420*cdf0e10cSrcweir break; 421*cdf0e10cSrcweir } 422*cdf0e10cSrcweir 423*cdf0e10cSrcweir case POLY_CLIP_XOR: 424*cdf0e10cSrcweir { 425*cdf0e10cSrcweir // compute XOR between poly A and B 426*cdf0e10cSrcweir aMergePolyPolygonA = basegfx::tools::solvePolygonOperationXor(aMergePolyPolygonA, aMergePolyPolygonB); 427*cdf0e10cSrcweir break; 428*cdf0e10cSrcweir } 429*cdf0e10cSrcweir 430*cdf0e10cSrcweir default: 431*cdf0e10cSrcweir case POLY_CLIP_INT: 432*cdf0e10cSrcweir { 433*cdf0e10cSrcweir // cut poly 1 against polys 2..n (AND) 434*cdf0e10cSrcweir aMergePolyPolygonA = basegfx::tools::solvePolygonOperationAnd(aMergePolyPolygonA, aMergePolyPolygonB); 435*cdf0e10cSrcweir break; 436*cdf0e10cSrcweir } 437*cdf0e10cSrcweir } 438*cdf0e10cSrcweir 439*cdf0e10cSrcweir rResult = PolyPolygon( aMergePolyPolygonA ); 440*cdf0e10cSrcweir } 441*cdf0e10cSrcweir 442*cdf0e10cSrcweir // ----------------------------------------------------------------------- 443*cdf0e10cSrcweir 444*cdf0e10cSrcweir sal_uInt16 PolyPolygon::Count() const 445*cdf0e10cSrcweir { 446*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 447*cdf0e10cSrcweir return mpImplPolyPolygon->mnCount; 448*cdf0e10cSrcweir } 449*cdf0e10cSrcweir 450*cdf0e10cSrcweir // ----------------------------------------------------------------------- 451*cdf0e10cSrcweir 452*cdf0e10cSrcweir void PolyPolygon::Move( long nHorzMove, long nVertMove ) 453*cdf0e10cSrcweir { 454*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 455*cdf0e10cSrcweir 456*cdf0e10cSrcweir // Diese Abfrage sollte man fuer die DrawEngine durchfuehren 457*cdf0e10cSrcweir if( nHorzMove || nVertMove ) 458*cdf0e10cSrcweir { 459*cdf0e10cSrcweir // Referenzcounter beruecksichtigen 460*cdf0e10cSrcweir if ( mpImplPolyPolygon->mnRefCount > 1 ) 461*cdf0e10cSrcweir { 462*cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--; 463*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon ); 464*cdf0e10cSrcweir } 465*cdf0e10cSrcweir 466*cdf0e10cSrcweir // Punkte verschieben 467*cdf0e10cSrcweir sal_uInt16 nPolyCount = mpImplPolyPolygon->mnCount; 468*cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < nPolyCount; i++ ) 469*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[i]->Move( nHorzMove, nVertMove ); 470*cdf0e10cSrcweir } 471*cdf0e10cSrcweir } 472*cdf0e10cSrcweir 473*cdf0e10cSrcweir // ----------------------------------------------------------------------- 474*cdf0e10cSrcweir 475*cdf0e10cSrcweir void PolyPolygon::Translate( const Point& rTrans ) 476*cdf0e10cSrcweir { 477*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 478*cdf0e10cSrcweir 479*cdf0e10cSrcweir // Referenzcounter beruecksichtigen 480*cdf0e10cSrcweir if( mpImplPolyPolygon->mnRefCount > 1 ) 481*cdf0e10cSrcweir { 482*cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--; 483*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon ); 484*cdf0e10cSrcweir } 485*cdf0e10cSrcweir 486*cdf0e10cSrcweir // Punkte verschieben 487*cdf0e10cSrcweir for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ ) 488*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[ i ]->Translate( rTrans ); 489*cdf0e10cSrcweir } 490*cdf0e10cSrcweir 491*cdf0e10cSrcweir // ----------------------------------------------------------------------- 492*cdf0e10cSrcweir 493*cdf0e10cSrcweir void PolyPolygon::Scale( double fScaleX, double fScaleY ) 494*cdf0e10cSrcweir { 495*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 496*cdf0e10cSrcweir 497*cdf0e10cSrcweir // Referenzcounter beruecksichtigen 498*cdf0e10cSrcweir if( mpImplPolyPolygon->mnRefCount > 1 ) 499*cdf0e10cSrcweir { 500*cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--; 501*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon ); 502*cdf0e10cSrcweir } 503*cdf0e10cSrcweir 504*cdf0e10cSrcweir // Punkte verschieben 505*cdf0e10cSrcweir for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ ) 506*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[ i ]->Scale( fScaleX, fScaleY ); 507*cdf0e10cSrcweir } 508*cdf0e10cSrcweir 509*cdf0e10cSrcweir // ----------------------------------------------------------------------- 510*cdf0e10cSrcweir 511*cdf0e10cSrcweir void PolyPolygon::Rotate( const Point& rCenter, sal_uInt16 nAngle10 ) 512*cdf0e10cSrcweir { 513*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 514*cdf0e10cSrcweir nAngle10 %= 3600; 515*cdf0e10cSrcweir 516*cdf0e10cSrcweir if( nAngle10 ) 517*cdf0e10cSrcweir { 518*cdf0e10cSrcweir const double fAngle = F_PI1800 * nAngle10; 519*cdf0e10cSrcweir Rotate( rCenter, sin( fAngle ), cos( fAngle ) ); 520*cdf0e10cSrcweir } 521*cdf0e10cSrcweir } 522*cdf0e10cSrcweir 523*cdf0e10cSrcweir // ----------------------------------------------------------------------- 524*cdf0e10cSrcweir 525*cdf0e10cSrcweir void PolyPolygon::Rotate( const Point& rCenter, double fSin, double fCos ) 526*cdf0e10cSrcweir { 527*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 528*cdf0e10cSrcweir 529*cdf0e10cSrcweir // Referenzcounter beruecksichtigen 530*cdf0e10cSrcweir if( mpImplPolyPolygon->mnRefCount > 1 ) 531*cdf0e10cSrcweir { 532*cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--; 533*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon ); 534*cdf0e10cSrcweir } 535*cdf0e10cSrcweir 536*cdf0e10cSrcweir // Punkte verschieben 537*cdf0e10cSrcweir for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ ) 538*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[ i ]->Rotate( rCenter, fSin, fCos ); 539*cdf0e10cSrcweir } 540*cdf0e10cSrcweir 541*cdf0e10cSrcweir // ----------------------------------------------------------------------- 542*cdf0e10cSrcweir 543*cdf0e10cSrcweir void PolyPolygon::SlantX( long nYRef, double fSin, double fCos ) 544*cdf0e10cSrcweir { 545*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 546*cdf0e10cSrcweir 547*cdf0e10cSrcweir // Referenzcounter beruecksichtigen 548*cdf0e10cSrcweir if( mpImplPolyPolygon->mnRefCount > 1 ) 549*cdf0e10cSrcweir { 550*cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--; 551*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon ); 552*cdf0e10cSrcweir } 553*cdf0e10cSrcweir 554*cdf0e10cSrcweir // Punkte verschieben 555*cdf0e10cSrcweir for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ ) 556*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[ i ]->SlantX( nYRef, fSin, fCos ); 557*cdf0e10cSrcweir } 558*cdf0e10cSrcweir 559*cdf0e10cSrcweir // ----------------------------------------------------------------------- 560*cdf0e10cSrcweir 561*cdf0e10cSrcweir void PolyPolygon::SlantY( long nXRef, double fSin, double fCos ) 562*cdf0e10cSrcweir { 563*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 564*cdf0e10cSrcweir 565*cdf0e10cSrcweir // Referenzcounter beruecksichtigen 566*cdf0e10cSrcweir if( mpImplPolyPolygon->mnRefCount > 1 ) 567*cdf0e10cSrcweir { 568*cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--; 569*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon ); 570*cdf0e10cSrcweir } 571*cdf0e10cSrcweir 572*cdf0e10cSrcweir // Punkte verschieben 573*cdf0e10cSrcweir for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ ) 574*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[ i ]->SlantY( nXRef, fSin, fCos ); 575*cdf0e10cSrcweir } 576*cdf0e10cSrcweir 577*cdf0e10cSrcweir // ----------------------------------------------------------------------- 578*cdf0e10cSrcweir 579*cdf0e10cSrcweir void PolyPolygon::Distort( const Rectangle& rRefRect, const Polygon& rDistortedRect ) 580*cdf0e10cSrcweir { 581*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 582*cdf0e10cSrcweir 583*cdf0e10cSrcweir // Referenzcounter beruecksichtigen 584*cdf0e10cSrcweir if( mpImplPolyPolygon->mnRefCount > 1 ) 585*cdf0e10cSrcweir { 586*cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--; 587*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon ); 588*cdf0e10cSrcweir } 589*cdf0e10cSrcweir 590*cdf0e10cSrcweir // Punkte verschieben 591*cdf0e10cSrcweir for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ ) 592*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[ i ]->Distort( rRefRect, rDistortedRect ); 593*cdf0e10cSrcweir } 594*cdf0e10cSrcweir 595*cdf0e10cSrcweir 596*cdf0e10cSrcweir // ----------------------------------------------------------------------- 597*cdf0e10cSrcweir 598*cdf0e10cSrcweir void PolyPolygon::Clip( const Rectangle& rRect ) 599*cdf0e10cSrcweir { 600*cdf0e10cSrcweir // Polygon-Clippen 601*cdf0e10cSrcweir sal_uInt16 nPolyCount = mpImplPolyPolygon->mnCount; 602*cdf0e10cSrcweir sal_uInt16 i; 603*cdf0e10cSrcweir 604*cdf0e10cSrcweir if ( !nPolyCount ) 605*cdf0e10cSrcweir return; 606*cdf0e10cSrcweir 607*cdf0e10cSrcweir // Referenzcounter beruecksichtigen 608*cdf0e10cSrcweir if ( mpImplPolyPolygon->mnRefCount > 1 ) 609*cdf0e10cSrcweir { 610*cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--; 611*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon ); 612*cdf0e10cSrcweir } 613*cdf0e10cSrcweir 614*cdf0e10cSrcweir // Erst jedes Polygon Clippen und dann die leeren entfernen 615*cdf0e10cSrcweir for ( i = 0; i < nPolyCount; i++ ) 616*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[i]->Clip( rRect ); 617*cdf0e10cSrcweir while ( nPolyCount ) 618*cdf0e10cSrcweir { 619*cdf0e10cSrcweir if ( GetObject( nPolyCount-1 ).GetSize() <= 2 ) 620*cdf0e10cSrcweir Remove( nPolyCount-1 ); 621*cdf0e10cSrcweir nPolyCount--; 622*cdf0e10cSrcweir } 623*cdf0e10cSrcweir } 624*cdf0e10cSrcweir 625*cdf0e10cSrcweir // ----------------------------------------------------------------------- 626*cdf0e10cSrcweir 627*cdf0e10cSrcweir Rectangle PolyPolygon::GetBoundRect() const 628*cdf0e10cSrcweir { 629*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 630*cdf0e10cSrcweir 631*cdf0e10cSrcweir long nXMin=0, nXMax=0, nYMin=0, nYMax=0; 632*cdf0e10cSrcweir sal_Bool bFirst = sal_True; 633*cdf0e10cSrcweir sal_uInt16 nPolyCount = mpImplPolyPolygon->mnCount; 634*cdf0e10cSrcweir 635*cdf0e10cSrcweir for ( sal_uInt16 n = 0; n < nPolyCount; n++ ) 636*cdf0e10cSrcweir { 637*cdf0e10cSrcweir const Polygon* pPoly = mpImplPolyPolygon->mpPolyAry[n]; 638*cdf0e10cSrcweir const Point* pAry = pPoly->GetConstPointAry(); 639*cdf0e10cSrcweir sal_uInt16 nPointCount = pPoly->GetSize(); 640*cdf0e10cSrcweir 641*cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < nPointCount; i++ ) 642*cdf0e10cSrcweir { 643*cdf0e10cSrcweir const Point* pPt = &pAry[ i ]; 644*cdf0e10cSrcweir 645*cdf0e10cSrcweir if ( bFirst ) 646*cdf0e10cSrcweir { 647*cdf0e10cSrcweir nXMin = nXMax = pPt->X(); 648*cdf0e10cSrcweir nYMin = nYMax = pPt->Y(); 649*cdf0e10cSrcweir bFirst = sal_False; 650*cdf0e10cSrcweir } 651*cdf0e10cSrcweir else 652*cdf0e10cSrcweir { 653*cdf0e10cSrcweir if ( pPt->X() < nXMin ) 654*cdf0e10cSrcweir nXMin = pPt->X(); 655*cdf0e10cSrcweir if ( pPt->X() > nXMax ) 656*cdf0e10cSrcweir nXMax = pPt->X(); 657*cdf0e10cSrcweir if ( pPt->Y() < nYMin ) 658*cdf0e10cSrcweir nYMin = pPt->Y(); 659*cdf0e10cSrcweir if ( pPt->Y() > nYMax ) 660*cdf0e10cSrcweir nYMax = pPt->Y(); 661*cdf0e10cSrcweir } 662*cdf0e10cSrcweir } 663*cdf0e10cSrcweir } 664*cdf0e10cSrcweir 665*cdf0e10cSrcweir if ( !bFirst ) 666*cdf0e10cSrcweir return Rectangle( nXMin, nYMin, nXMax, nYMax ); 667*cdf0e10cSrcweir else 668*cdf0e10cSrcweir return Rectangle(); 669*cdf0e10cSrcweir } 670*cdf0e10cSrcweir 671*cdf0e10cSrcweir // ----------------------------------------------------------------------- 672*cdf0e10cSrcweir 673*cdf0e10cSrcweir Polygon& PolyPolygon::operator[]( sal_uInt16 nPos ) 674*cdf0e10cSrcweir { 675*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 676*cdf0e10cSrcweir DBG_ASSERT( nPos < Count(), "PolyPolygon::[](): nPos >= nSize" ); 677*cdf0e10cSrcweir 678*cdf0e10cSrcweir if ( mpImplPolyPolygon->mnRefCount > 1 ) 679*cdf0e10cSrcweir { 680*cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--; 681*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon ); 682*cdf0e10cSrcweir } 683*cdf0e10cSrcweir 684*cdf0e10cSrcweir return *(mpImplPolyPolygon->mpPolyAry[nPos]); 685*cdf0e10cSrcweir } 686*cdf0e10cSrcweir 687*cdf0e10cSrcweir // ----------------------------------------------------------------------- 688*cdf0e10cSrcweir 689*cdf0e10cSrcweir PolyPolygon& PolyPolygon::operator=( const PolyPolygon& rPolyPoly ) 690*cdf0e10cSrcweir { 691*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 692*cdf0e10cSrcweir DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL ); 693*cdf0e10cSrcweir DBG_ASSERT( rPolyPoly.mpImplPolyPolygon->mnRefCount < 0xFFFFFFFE, "PolyPolygon: RefCount overflow" ); 694*cdf0e10cSrcweir 695*cdf0e10cSrcweir rPolyPoly.mpImplPolyPolygon->mnRefCount++; 696*cdf0e10cSrcweir 697*cdf0e10cSrcweir if ( mpImplPolyPolygon->mnRefCount > 1 ) 698*cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--; 699*cdf0e10cSrcweir else 700*cdf0e10cSrcweir delete mpImplPolyPolygon; 701*cdf0e10cSrcweir 702*cdf0e10cSrcweir mpImplPolyPolygon = rPolyPoly.mpImplPolyPolygon; 703*cdf0e10cSrcweir return *this; 704*cdf0e10cSrcweir } 705*cdf0e10cSrcweir 706*cdf0e10cSrcweir // ----------------------------------------------------------------------- 707*cdf0e10cSrcweir 708*cdf0e10cSrcweir sal_Bool PolyPolygon::operator==( const PolyPolygon& rPolyPoly ) const 709*cdf0e10cSrcweir { 710*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 711*cdf0e10cSrcweir DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL ); 712*cdf0e10cSrcweir 713*cdf0e10cSrcweir if ( rPolyPoly.mpImplPolyPolygon == mpImplPolyPolygon ) 714*cdf0e10cSrcweir return sal_True; 715*cdf0e10cSrcweir else 716*cdf0e10cSrcweir return sal_False; 717*cdf0e10cSrcweir } 718*cdf0e10cSrcweir 719*cdf0e10cSrcweir // ----------------------------------------------------------------------- 720*cdf0e10cSrcweir 721*cdf0e10cSrcweir sal_Bool PolyPolygon::IsEqual( const PolyPolygon& rPolyPoly ) const 722*cdf0e10cSrcweir { 723*cdf0e10cSrcweir sal_Bool bIsEqual = sal_True; 724*cdf0e10cSrcweir if ( Count() != rPolyPoly.Count() ) 725*cdf0e10cSrcweir bIsEqual = sal_False; 726*cdf0e10cSrcweir else 727*cdf0e10cSrcweir { 728*cdf0e10cSrcweir sal_uInt16 i; 729*cdf0e10cSrcweir for ( i = 0; i < Count(); i++ ) 730*cdf0e10cSrcweir { 731*cdf0e10cSrcweir if (!GetObject( i ).IsEqual( rPolyPoly.GetObject( i ) ) ) 732*cdf0e10cSrcweir { 733*cdf0e10cSrcweir bIsEqual = sal_False; 734*cdf0e10cSrcweir break; 735*cdf0e10cSrcweir } 736*cdf0e10cSrcweir } 737*cdf0e10cSrcweir } 738*cdf0e10cSrcweir return bIsEqual; 739*cdf0e10cSrcweir } 740*cdf0e10cSrcweir 741*cdf0e10cSrcweir // ----------------------------------------------------------------------- 742*cdf0e10cSrcweir 743*cdf0e10cSrcweir SvStream& operator>>( SvStream& rIStream, PolyPolygon& rPolyPoly ) 744*cdf0e10cSrcweir { 745*cdf0e10cSrcweir DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL ); 746*cdf0e10cSrcweir DBG_ASSERTWARNING( rIStream.GetVersion(), "PolyPolygon::>> - Solar-Version not set on rIStream" ); 747*cdf0e10cSrcweir 748*cdf0e10cSrcweir Polygon* pPoly; 749*cdf0e10cSrcweir sal_uInt16 nPolyCount; 750*cdf0e10cSrcweir 751*cdf0e10cSrcweir // Anzahl der Polygone einlesen 752*cdf0e10cSrcweir rIStream >> nPolyCount; 753*cdf0e10cSrcweir 754*cdf0e10cSrcweir // Daten anlegen 755*cdf0e10cSrcweir if( nPolyCount ) 756*cdf0e10cSrcweir { 757*cdf0e10cSrcweir // Referenzcounter beruecksichtigen 758*cdf0e10cSrcweir if ( rPolyPoly.mpImplPolyPolygon->mnRefCount > 1 ) 759*cdf0e10cSrcweir rPolyPoly.mpImplPolyPolygon->mnRefCount--; 760*cdf0e10cSrcweir else 761*cdf0e10cSrcweir delete rPolyPoly.mpImplPolyPolygon; 762*cdf0e10cSrcweir 763*cdf0e10cSrcweir rPolyPoly.mpImplPolyPolygon = new ImplPolyPolygon( nPolyCount ); 764*cdf0e10cSrcweir 765*cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < nPolyCount; i++ ) 766*cdf0e10cSrcweir { 767*cdf0e10cSrcweir pPoly = new Polygon; 768*cdf0e10cSrcweir rIStream >> *pPoly; 769*cdf0e10cSrcweir rPolyPoly.mpImplPolyPolygon->mpPolyAry[i] = pPoly; 770*cdf0e10cSrcweir } 771*cdf0e10cSrcweir } 772*cdf0e10cSrcweir else 773*cdf0e10cSrcweir rPolyPoly = PolyPolygon(); 774*cdf0e10cSrcweir 775*cdf0e10cSrcweir return rIStream; 776*cdf0e10cSrcweir } 777*cdf0e10cSrcweir 778*cdf0e10cSrcweir // ----------------------------------------------------------------------- 779*cdf0e10cSrcweir 780*cdf0e10cSrcweir SvStream& operator<<( SvStream& rOStream, const PolyPolygon& rPolyPoly ) 781*cdf0e10cSrcweir { 782*cdf0e10cSrcweir DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL ); 783*cdf0e10cSrcweir DBG_ASSERTWARNING( rOStream.GetVersion(), "PolyPolygon::<< - Solar-Version not set on rOStream" ); 784*cdf0e10cSrcweir 785*cdf0e10cSrcweir // Anzahl der Polygone rausschreiben 786*cdf0e10cSrcweir sal_uInt16 nPolyCount = rPolyPoly.mpImplPolyPolygon->mnCount; 787*cdf0e10cSrcweir rOStream << nPolyCount; 788*cdf0e10cSrcweir 789*cdf0e10cSrcweir // Die einzelnen Polygone ausgeben 790*cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < nPolyCount; i++ ) 791*cdf0e10cSrcweir rOStream << *(rPolyPoly.mpImplPolyPolygon->mpPolyAry[i]); 792*cdf0e10cSrcweir 793*cdf0e10cSrcweir return rOStream; 794*cdf0e10cSrcweir } 795*cdf0e10cSrcweir 796*cdf0e10cSrcweir // ----------------------------------------------------------------------- 797*cdf0e10cSrcweir 798*cdf0e10cSrcweir void PolyPolygon::Read( SvStream& rIStream ) 799*cdf0e10cSrcweir { 800*cdf0e10cSrcweir VersionCompat aCompat( rIStream, STREAM_READ ); 801*cdf0e10cSrcweir 802*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 803*cdf0e10cSrcweir DBG_ASSERTWARNING( rIStream.GetVersion(), "PolyPolygon::>> - Solar-Version not set on rIStream" ); 804*cdf0e10cSrcweir 805*cdf0e10cSrcweir Polygon* pPoly; 806*cdf0e10cSrcweir sal_uInt16 nPolyCount; 807*cdf0e10cSrcweir 808*cdf0e10cSrcweir // Anzahl der Polygone einlesen 809*cdf0e10cSrcweir rIStream >> nPolyCount; 810*cdf0e10cSrcweir 811*cdf0e10cSrcweir // Daten anlegen 812*cdf0e10cSrcweir if( nPolyCount ) 813*cdf0e10cSrcweir { 814*cdf0e10cSrcweir // Referenzcounter beruecksichtigen 815*cdf0e10cSrcweir if ( mpImplPolyPolygon->mnRefCount > 1 ) 816*cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--; 817*cdf0e10cSrcweir else 818*cdf0e10cSrcweir delete mpImplPolyPolygon; 819*cdf0e10cSrcweir 820*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( nPolyCount ); 821*cdf0e10cSrcweir 822*cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < nPolyCount; i++ ) 823*cdf0e10cSrcweir { 824*cdf0e10cSrcweir pPoly = new Polygon; 825*cdf0e10cSrcweir pPoly->ImplRead( rIStream ); 826*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[i] = pPoly; 827*cdf0e10cSrcweir } 828*cdf0e10cSrcweir } 829*cdf0e10cSrcweir else 830*cdf0e10cSrcweir *this = PolyPolygon(); 831*cdf0e10cSrcweir } 832*cdf0e10cSrcweir 833*cdf0e10cSrcweir // ----------------------------------------------------------------------- 834*cdf0e10cSrcweir 835*cdf0e10cSrcweir void PolyPolygon::Write( SvStream& rOStream ) const 836*cdf0e10cSrcweir { 837*cdf0e10cSrcweir VersionCompat aCompat( rOStream, STREAM_WRITE, 1 ); 838*cdf0e10cSrcweir 839*cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL ); 840*cdf0e10cSrcweir DBG_ASSERTWARNING( rOStream.GetVersion(), "PolyPolygon::<< - Solar-Version not set on rOStream" ); 841*cdf0e10cSrcweir 842*cdf0e10cSrcweir // Anzahl der Polygone rausschreiben 843*cdf0e10cSrcweir sal_uInt16 nPolyCount = mpImplPolyPolygon->mnCount; 844*cdf0e10cSrcweir rOStream << nPolyCount; 845*cdf0e10cSrcweir 846*cdf0e10cSrcweir // Die einzelnen Polygone ausgeben 847*cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < nPolyCount; i++ ) 848*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[i]->ImplWrite( rOStream );; 849*cdf0e10cSrcweir } 850*cdf0e10cSrcweir 851*cdf0e10cSrcweir // ----------------------------------------------------------------------- 852*cdf0e10cSrcweir // convert to basegfx::B2DPolyPolygon and return 853*cdf0e10cSrcweir basegfx::B2DPolyPolygon PolyPolygon::getB2DPolyPolygon() const 854*cdf0e10cSrcweir { 855*cdf0e10cSrcweir basegfx::B2DPolyPolygon aRetval; 856*cdf0e10cSrcweir 857*cdf0e10cSrcweir for(sal_uInt16 a(0); a < mpImplPolyPolygon->mnCount; a++) 858*cdf0e10cSrcweir { 859*cdf0e10cSrcweir Polygon* pCandidate = mpImplPolyPolygon->mpPolyAry[a]; 860*cdf0e10cSrcweir aRetval.append(pCandidate->getB2DPolygon()); 861*cdf0e10cSrcweir } 862*cdf0e10cSrcweir 863*cdf0e10cSrcweir return aRetval; 864*cdf0e10cSrcweir } 865*cdf0e10cSrcweir 866*cdf0e10cSrcweir // ----------------------------------------------------------------------- 867*cdf0e10cSrcweir // constructor to convert from basegfx::B2DPolyPolygon 868*cdf0e10cSrcweir PolyPolygon::PolyPolygon(const basegfx::B2DPolyPolygon& rPolyPolygon) 869*cdf0e10cSrcweir { 870*cdf0e10cSrcweir DBG_CTOR( PolyPolygon, NULL ); 871*cdf0e10cSrcweir const sal_uInt16 nCount(sal_uInt16(rPolyPolygon.count())); 872*cdf0e10cSrcweir DBG_ASSERT(sal_uInt32(nCount) == rPolyPolygon.count(), 873*cdf0e10cSrcweir "PolyPolygon::PolyPolygon: Too many sub-polygons in given basegfx::B2DPolyPolygon (!)"); 874*cdf0e10cSrcweir 875*cdf0e10cSrcweir if ( nCount ) 876*cdf0e10cSrcweir { 877*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( nCount ); 878*cdf0e10cSrcweir 879*cdf0e10cSrcweir for(sal_uInt16 a(0); a < nCount; a++) 880*cdf0e10cSrcweir { 881*cdf0e10cSrcweir basegfx::B2DPolygon aCandidate(rPolyPolygon.getB2DPolygon(sal_uInt32(a))); 882*cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[a] = new Polygon( aCandidate ); 883*cdf0e10cSrcweir } 884*cdf0e10cSrcweir } 885*cdf0e10cSrcweir else 886*cdf0e10cSrcweir { 887*cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( 16, 16 ); 888*cdf0e10cSrcweir } 889*cdf0e10cSrcweir } 890*cdf0e10cSrcweir 891*cdf0e10cSrcweir // eof 892