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