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