xref: /AOO41X/main/tools/source/generic/poly2.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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