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
DBG_NAME(PolyPolygon)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
ImplPolyPolygon(const ImplPolyPolygon & rImplPolyPoly)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
~ImplPolyPolygon()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
PolyPolygon(sal_uInt16 nInitSize,sal_uInt16 nResize)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
PolyPolygon(const Polygon & rPoly)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
PolyPolygon(const PolyPolygon & rPolyPoly)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
~PolyPolygon()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
Insert(const Polygon & rPoly,sal_uInt16 nPos)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
Remove(sal_uInt16 nPos)197cdf0e10cSrcweir void PolyPolygon::Remove( sal_uInt16 nPos )
198cdf0e10cSrcweir {
199cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
200cdf0e10cSrcweir DBG_ASSERT( nPos < Count(), "PolyPolygon::Remove(): nPos >= nSize" );
201*7566a17cSkschenk if ( nPos >= Count() ) return; // not removable
202cdf0e10cSrcweir
203cdf0e10cSrcweir if ( mpImplPolyPolygon->mnRefCount > 1 )
204cdf0e10cSrcweir {
205cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--;
206cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
207cdf0e10cSrcweir }
208cdf0e10cSrcweir
209cdf0e10cSrcweir delete mpImplPolyPolygon->mpPolyAry[nPos];
210cdf0e10cSrcweir mpImplPolyPolygon->mnCount--;
211cdf0e10cSrcweir memmove( mpImplPolyPolygon->mpPolyAry+nPos,
212cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry+nPos+1,
213cdf0e10cSrcweir (mpImplPolyPolygon->mnCount-nPos)*sizeof(SVPPOLYGON) );
214cdf0e10cSrcweir }
215cdf0e10cSrcweir
216cdf0e10cSrcweir // -----------------------------------------------------------------------
217cdf0e10cSrcweir
Replace(const Polygon & rPoly,sal_uInt16 nPos)218cdf0e10cSrcweir void PolyPolygon::Replace( const Polygon& rPoly, sal_uInt16 nPos )
219cdf0e10cSrcweir {
220cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
221cdf0e10cSrcweir DBG_ASSERT( nPos < Count(), "PolyPolygon::Replace(): nPos >= nSize" );
222*7566a17cSkschenk if ( nPos >= Count() ) return; // not replaceable
223cdf0e10cSrcweir
224cdf0e10cSrcweir if ( mpImplPolyPolygon->mnRefCount > 1 )
225cdf0e10cSrcweir {
226cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--;
227cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
228cdf0e10cSrcweir }
229cdf0e10cSrcweir
230cdf0e10cSrcweir delete mpImplPolyPolygon->mpPolyAry[nPos];
231cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[nPos] = new Polygon( rPoly );
232cdf0e10cSrcweir }
233cdf0e10cSrcweir
234cdf0e10cSrcweir // -----------------------------------------------------------------------
235cdf0e10cSrcweir
GetObject(sal_uInt16 nPos) const236cdf0e10cSrcweir const Polygon& PolyPolygon::GetObject( sal_uInt16 nPos ) const
237cdf0e10cSrcweir {
238cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
239cdf0e10cSrcweir DBG_ASSERT( nPos < Count(), "PolyPolygon::GetObject(): nPos >= nSize" );
240cdf0e10cSrcweir
241cdf0e10cSrcweir return *(mpImplPolyPolygon->mpPolyAry[nPos]);
242cdf0e10cSrcweir }
243cdf0e10cSrcweir
244cdf0e10cSrcweir // -----------------------------------------------------------------------
245cdf0e10cSrcweir
IsRect() const246cdf0e10cSrcweir sal_Bool PolyPolygon::IsRect() const
247cdf0e10cSrcweir {
248cdf0e10cSrcweir sal_Bool bIsRect = sal_False;
249cdf0e10cSrcweir if ( Count() == 1 )
250cdf0e10cSrcweir bIsRect = mpImplPolyPolygon->mpPolyAry[ 0 ]->IsRect();
251cdf0e10cSrcweir return bIsRect;
252cdf0e10cSrcweir }
253cdf0e10cSrcweir
254cdf0e10cSrcweir // -----------------------------------------------------------------------
255cdf0e10cSrcweir
Clear()256cdf0e10cSrcweir void PolyPolygon::Clear()
257cdf0e10cSrcweir {
258cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
259cdf0e10cSrcweir
260cdf0e10cSrcweir if ( mpImplPolyPolygon->mnRefCount > 1 )
261cdf0e10cSrcweir {
262cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--;
263cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( mpImplPolyPolygon->mnResize,
264cdf0e10cSrcweir mpImplPolyPolygon->mnResize );
265cdf0e10cSrcweir }
266cdf0e10cSrcweir else
267cdf0e10cSrcweir {
268cdf0e10cSrcweir if ( mpImplPolyPolygon->mpPolyAry )
269cdf0e10cSrcweir {
270cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < mpImplPolyPolygon->mnCount; i++ )
271cdf0e10cSrcweir delete mpImplPolyPolygon->mpPolyAry[i];
272cdf0e10cSrcweir delete[] mpImplPolyPolygon->mpPolyAry;
273cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry = NULL;
274cdf0e10cSrcweir mpImplPolyPolygon->mnCount = 0;
275cdf0e10cSrcweir mpImplPolyPolygon->mnSize = mpImplPolyPolygon->mnResize;
276cdf0e10cSrcweir }
277cdf0e10cSrcweir }
278cdf0e10cSrcweir }
279cdf0e10cSrcweir
280cdf0e10cSrcweir // -----------------------------------------------------------------------
281cdf0e10cSrcweir
Optimize(sal_uIntPtr nOptimizeFlags,const PolyOptimizeData * pData)282cdf0e10cSrcweir void PolyPolygon::Optimize( sal_uIntPtr nOptimizeFlags, const PolyOptimizeData* pData )
283cdf0e10cSrcweir {
284cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
285cdf0e10cSrcweir
2866b7345f3SArmin Le Grand if(nOptimizeFlags && Count())
2876b7345f3SArmin Le Grand {
2886b7345f3SArmin Le Grand // #115630# ImplDrawHatch does not work with beziers included in the polypolygon, take care of that
2896b7345f3SArmin Le Grand bool bIsCurve(false);
2906b7345f3SArmin Le Grand
2916b7345f3SArmin Le Grand for(sal_uInt16 a(0); !bIsCurve && a < Count(); a++)
2926b7345f3SArmin Le Grand {
2936b7345f3SArmin Le Grand if((*this)[a].HasFlags())
2946b7345f3SArmin Le Grand {
2956b7345f3SArmin Le Grand bIsCurve = true;
2966b7345f3SArmin Le Grand }
2976b7345f3SArmin Le Grand }
2986b7345f3SArmin Le Grand
2996b7345f3SArmin Le Grand if(bIsCurve)
3006b7345f3SArmin Le Grand {
3016b7345f3SArmin Le Grand OSL_ENSURE(false, "Optimize does *not* support curves, falling back to AdaptiveSubdivide()...");
3026b7345f3SArmin Le Grand PolyPolygon aPolyPoly;
3036b7345f3SArmin Le Grand
3046b7345f3SArmin Le Grand AdaptiveSubdivide(aPolyPoly);
3056b7345f3SArmin Le Grand aPolyPoly.Optimize(nOptimizeFlags, pData);
3066b7345f3SArmin Le Grand *this = aPolyPoly;
3076b7345f3SArmin Le Grand }
3086b7345f3SArmin Le Grand else
309cdf0e10cSrcweir {
310cdf0e10cSrcweir double fArea;
311cdf0e10cSrcweir const sal_Bool bEdges = ( nOptimizeFlags & POLY_OPTIMIZE_EDGES ) == POLY_OPTIMIZE_EDGES;
312cdf0e10cSrcweir sal_uInt16 nPercent = 0;
313cdf0e10cSrcweir
314cdf0e10cSrcweir if( bEdges )
315cdf0e10cSrcweir {
316cdf0e10cSrcweir const Rectangle aBound( GetBoundRect() );
317cdf0e10cSrcweir
318cdf0e10cSrcweir fArea = ( aBound.GetWidth() + aBound.GetHeight() ) * 0.5;
319cdf0e10cSrcweir nPercent = pData ? pData->GetPercentValue() : 50;
320cdf0e10cSrcweir nOptimizeFlags &= ~POLY_OPTIMIZE_EDGES;
321cdf0e10cSrcweir }
322cdf0e10cSrcweir
323cdf0e10cSrcweir // watch for ref counter
324cdf0e10cSrcweir if( mpImplPolyPolygon->mnRefCount > 1 )
325cdf0e10cSrcweir {
326cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--;
327cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
328cdf0e10cSrcweir }
329cdf0e10cSrcweir
330cdf0e10cSrcweir // Optimize polygons
331cdf0e10cSrcweir for( sal_uInt16 i = 0, nPolyCount = mpImplPolyPolygon->mnCount; i < nPolyCount; i++ )
332cdf0e10cSrcweir {
333cdf0e10cSrcweir if( bEdges )
334cdf0e10cSrcweir {
335cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[ i ]->Optimize( POLY_OPTIMIZE_NO_SAME );
336cdf0e10cSrcweir Polygon::ImplReduceEdges( *( mpImplPolyPolygon->mpPolyAry[ i ] ), fArea, nPercent );
337cdf0e10cSrcweir }
338cdf0e10cSrcweir
339cdf0e10cSrcweir if( nOptimizeFlags )
340cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[ i ]->Optimize( nOptimizeFlags, pData );
341cdf0e10cSrcweir }
342cdf0e10cSrcweir }
343cdf0e10cSrcweir }
3446b7345f3SArmin Le Grand }
345cdf0e10cSrcweir
346cdf0e10cSrcweir // -----------------------------------------------------------------------
347cdf0e10cSrcweir
AdaptiveSubdivide(PolyPolygon & rResult,const double d) const348cdf0e10cSrcweir void PolyPolygon::AdaptiveSubdivide( PolyPolygon& rResult, const double d ) const
349cdf0e10cSrcweir {
350cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
351cdf0e10cSrcweir
352cdf0e10cSrcweir rResult.Clear();
353cdf0e10cSrcweir
354cdf0e10cSrcweir Polygon aPolygon;
355cdf0e10cSrcweir
356cdf0e10cSrcweir for( sal_uInt16 i = 0; i < mpImplPolyPolygon->mnCount; i++ )
357cdf0e10cSrcweir {
358cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[ i ]->AdaptiveSubdivide( aPolygon, d );
359cdf0e10cSrcweir rResult.Insert( aPolygon );
360cdf0e10cSrcweir }
361cdf0e10cSrcweir }
362cdf0e10cSrcweir
363cdf0e10cSrcweir // -----------------------------------------------------------------------
364cdf0e10cSrcweir
GetIntersection(const PolyPolygon & rPolyPoly,PolyPolygon & rResult) const365cdf0e10cSrcweir void PolyPolygon::GetIntersection( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const
366cdf0e10cSrcweir {
367cdf0e10cSrcweir ImplDoOperation( rPolyPoly, rResult, POLY_CLIP_INT );
368cdf0e10cSrcweir }
369cdf0e10cSrcweir
370cdf0e10cSrcweir // -----------------------------------------------------------------------
371cdf0e10cSrcweir
GetUnion(const PolyPolygon & rPolyPoly,PolyPolygon & rResult) const372cdf0e10cSrcweir void PolyPolygon::GetUnion( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const
373cdf0e10cSrcweir {
374cdf0e10cSrcweir ImplDoOperation( rPolyPoly, rResult, POLY_CLIP_UNION );
375cdf0e10cSrcweir }
376cdf0e10cSrcweir
377cdf0e10cSrcweir // -----------------------------------------------------------------------
378cdf0e10cSrcweir
GetDifference(const PolyPolygon & rPolyPoly,PolyPolygon & rResult) const379cdf0e10cSrcweir void PolyPolygon::GetDifference( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const
380cdf0e10cSrcweir {
381cdf0e10cSrcweir ImplDoOperation( rPolyPoly, rResult, POLY_CLIP_DIFF );
382cdf0e10cSrcweir }
383cdf0e10cSrcweir
384cdf0e10cSrcweir // -----------------------------------------------------------------------
385cdf0e10cSrcweir
GetXOR(const PolyPolygon & rPolyPoly,PolyPolygon & rResult) const386cdf0e10cSrcweir void PolyPolygon::GetXOR( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const
387cdf0e10cSrcweir {
388cdf0e10cSrcweir ImplDoOperation( rPolyPoly, rResult, POLY_CLIP_XOR );
389cdf0e10cSrcweir }
390cdf0e10cSrcweir
391cdf0e10cSrcweir // -----------------------------------------------------------------------
392cdf0e10cSrcweir
ImplDoOperation(const PolyPolygon & rPolyPoly,PolyPolygon & rResult,sal_uIntPtr nOperation) const393cdf0e10cSrcweir void PolyPolygon::ImplDoOperation( const PolyPolygon& rPolyPoly, PolyPolygon& rResult, sal_uIntPtr nOperation ) const
394cdf0e10cSrcweir {
395cdf0e10cSrcweir // Convert to B2DPolyPolygon, temporarily. It might be
396cdf0e10cSrcweir // advantageous in the future, to have a PolyPolygon adaptor that
397cdf0e10cSrcweir // just simulates a B2DPolyPolygon here...
398cdf0e10cSrcweir basegfx::B2DPolyPolygon aMergePolyPolygonA( getB2DPolyPolygon() );
399cdf0e10cSrcweir basegfx::B2DPolyPolygon aMergePolyPolygonB( rPolyPoly.getB2DPolyPolygon() );
400cdf0e10cSrcweir
401cdf0e10cSrcweir // normalize the two polypolygons before. Force properly oriented
402cdf0e10cSrcweir // polygons.
403cdf0e10cSrcweir aMergePolyPolygonA = basegfx::tools::prepareForPolygonOperation( aMergePolyPolygonA );
404cdf0e10cSrcweir aMergePolyPolygonB = basegfx::tools::prepareForPolygonOperation( aMergePolyPolygonB );
405cdf0e10cSrcweir
406cdf0e10cSrcweir switch( nOperation )
407cdf0e10cSrcweir {
408cdf0e10cSrcweir // All code extracted from svx/source/svdraw/svedtv2.cxx
409cdf0e10cSrcweir // -----------------------------------------------------
410cdf0e10cSrcweir
411cdf0e10cSrcweir case POLY_CLIP_UNION:
412cdf0e10cSrcweir {
413cdf0e10cSrcweir // merge A and B (OR)
414cdf0e10cSrcweir aMergePolyPolygonA = basegfx::tools::solvePolygonOperationOr(aMergePolyPolygonA, aMergePolyPolygonB);
415cdf0e10cSrcweir break;
416cdf0e10cSrcweir }
417cdf0e10cSrcweir
418cdf0e10cSrcweir case POLY_CLIP_DIFF:
419cdf0e10cSrcweir {
420cdf0e10cSrcweir // substract B from A (DIFF)
421cdf0e10cSrcweir aMergePolyPolygonA = basegfx::tools::solvePolygonOperationDiff(aMergePolyPolygonA, aMergePolyPolygonB);
422cdf0e10cSrcweir break;
423cdf0e10cSrcweir }
424cdf0e10cSrcweir
425cdf0e10cSrcweir case POLY_CLIP_XOR:
426cdf0e10cSrcweir {
427cdf0e10cSrcweir // compute XOR between poly A and B
428cdf0e10cSrcweir aMergePolyPolygonA = basegfx::tools::solvePolygonOperationXor(aMergePolyPolygonA, aMergePolyPolygonB);
429cdf0e10cSrcweir break;
430cdf0e10cSrcweir }
431cdf0e10cSrcweir
432cdf0e10cSrcweir default:
433cdf0e10cSrcweir case POLY_CLIP_INT:
434cdf0e10cSrcweir {
435cdf0e10cSrcweir // cut poly 1 against polys 2..n (AND)
436cdf0e10cSrcweir aMergePolyPolygonA = basegfx::tools::solvePolygonOperationAnd(aMergePolyPolygonA, aMergePolyPolygonB);
437cdf0e10cSrcweir break;
438cdf0e10cSrcweir }
439cdf0e10cSrcweir }
440cdf0e10cSrcweir
441cdf0e10cSrcweir rResult = PolyPolygon( aMergePolyPolygonA );
442cdf0e10cSrcweir }
443cdf0e10cSrcweir
444cdf0e10cSrcweir // -----------------------------------------------------------------------
445cdf0e10cSrcweir
Count() const446cdf0e10cSrcweir sal_uInt16 PolyPolygon::Count() const
447cdf0e10cSrcweir {
448cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
449cdf0e10cSrcweir return mpImplPolyPolygon->mnCount;
450cdf0e10cSrcweir }
451cdf0e10cSrcweir
452cdf0e10cSrcweir // -----------------------------------------------------------------------
453cdf0e10cSrcweir
Move(long nHorzMove,long nVertMove)454cdf0e10cSrcweir void PolyPolygon::Move( long nHorzMove, long nVertMove )
455cdf0e10cSrcweir {
456cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
457cdf0e10cSrcweir
458cdf0e10cSrcweir // Diese Abfrage sollte man fuer die DrawEngine durchfuehren
459cdf0e10cSrcweir if( nHorzMove || nVertMove )
460cdf0e10cSrcweir {
461cdf0e10cSrcweir // Referenzcounter beruecksichtigen
462cdf0e10cSrcweir if ( mpImplPolyPolygon->mnRefCount > 1 )
463cdf0e10cSrcweir {
464cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--;
465cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
466cdf0e10cSrcweir }
467cdf0e10cSrcweir
468cdf0e10cSrcweir // Punkte verschieben
469cdf0e10cSrcweir sal_uInt16 nPolyCount = mpImplPolyPolygon->mnCount;
470cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
471cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[i]->Move( nHorzMove, nVertMove );
472cdf0e10cSrcweir }
473cdf0e10cSrcweir }
474cdf0e10cSrcweir
475cdf0e10cSrcweir // -----------------------------------------------------------------------
476cdf0e10cSrcweir
Translate(const Point & rTrans)477cdf0e10cSrcweir void PolyPolygon::Translate( const Point& rTrans )
478cdf0e10cSrcweir {
479cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
480cdf0e10cSrcweir
481cdf0e10cSrcweir // Referenzcounter beruecksichtigen
482cdf0e10cSrcweir if( mpImplPolyPolygon->mnRefCount > 1 )
483cdf0e10cSrcweir {
484cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--;
485cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
486cdf0e10cSrcweir }
487cdf0e10cSrcweir
488cdf0e10cSrcweir // Punkte verschieben
489cdf0e10cSrcweir for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ )
490cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[ i ]->Translate( rTrans );
491cdf0e10cSrcweir }
492cdf0e10cSrcweir
493cdf0e10cSrcweir // -----------------------------------------------------------------------
494cdf0e10cSrcweir
Scale(double fScaleX,double fScaleY)495cdf0e10cSrcweir void PolyPolygon::Scale( double fScaleX, double fScaleY )
496cdf0e10cSrcweir {
497cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
498cdf0e10cSrcweir
499cdf0e10cSrcweir // Referenzcounter beruecksichtigen
500cdf0e10cSrcweir if( mpImplPolyPolygon->mnRefCount > 1 )
501cdf0e10cSrcweir {
502cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--;
503cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
504cdf0e10cSrcweir }
505cdf0e10cSrcweir
506cdf0e10cSrcweir // Punkte verschieben
507cdf0e10cSrcweir for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ )
508cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[ i ]->Scale( fScaleX, fScaleY );
509cdf0e10cSrcweir }
510cdf0e10cSrcweir
511cdf0e10cSrcweir // -----------------------------------------------------------------------
512cdf0e10cSrcweir
Rotate(const Point & rCenter,sal_uInt16 nAngle10)513cdf0e10cSrcweir void PolyPolygon::Rotate( const Point& rCenter, sal_uInt16 nAngle10 )
514cdf0e10cSrcweir {
515cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
516cdf0e10cSrcweir nAngle10 %= 3600;
517cdf0e10cSrcweir
518cdf0e10cSrcweir if( nAngle10 )
519cdf0e10cSrcweir {
520cdf0e10cSrcweir const double fAngle = F_PI1800 * nAngle10;
521cdf0e10cSrcweir Rotate( rCenter, sin( fAngle ), cos( fAngle ) );
522cdf0e10cSrcweir }
523cdf0e10cSrcweir }
524cdf0e10cSrcweir
525cdf0e10cSrcweir // -----------------------------------------------------------------------
526cdf0e10cSrcweir
Rotate(const Point & rCenter,double fSin,double fCos)527cdf0e10cSrcweir void PolyPolygon::Rotate( const Point& rCenter, double fSin, double fCos )
528cdf0e10cSrcweir {
529cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
530cdf0e10cSrcweir
531cdf0e10cSrcweir // Referenzcounter beruecksichtigen
532cdf0e10cSrcweir if( mpImplPolyPolygon->mnRefCount > 1 )
533cdf0e10cSrcweir {
534cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--;
535cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
536cdf0e10cSrcweir }
537cdf0e10cSrcweir
538cdf0e10cSrcweir // Punkte verschieben
539cdf0e10cSrcweir for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ )
540cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[ i ]->Rotate( rCenter, fSin, fCos );
541cdf0e10cSrcweir }
542cdf0e10cSrcweir
543cdf0e10cSrcweir // -----------------------------------------------------------------------
544cdf0e10cSrcweir
SlantX(long nYRef,double fSin,double fCos)545cdf0e10cSrcweir void PolyPolygon::SlantX( long nYRef, double fSin, double fCos )
546cdf0e10cSrcweir {
547cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
548cdf0e10cSrcweir
549cdf0e10cSrcweir // Referenzcounter beruecksichtigen
550cdf0e10cSrcweir if( mpImplPolyPolygon->mnRefCount > 1 )
551cdf0e10cSrcweir {
552cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--;
553cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
554cdf0e10cSrcweir }
555cdf0e10cSrcweir
556cdf0e10cSrcweir // Punkte verschieben
557cdf0e10cSrcweir for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ )
558cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[ i ]->SlantX( nYRef, fSin, fCos );
559cdf0e10cSrcweir }
560cdf0e10cSrcweir
561cdf0e10cSrcweir // -----------------------------------------------------------------------
562cdf0e10cSrcweir
SlantY(long nXRef,double fSin,double fCos)563cdf0e10cSrcweir void PolyPolygon::SlantY( long nXRef, double fSin, double fCos )
564cdf0e10cSrcweir {
565cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
566cdf0e10cSrcweir
567cdf0e10cSrcweir // Referenzcounter beruecksichtigen
568cdf0e10cSrcweir if( mpImplPolyPolygon->mnRefCount > 1 )
569cdf0e10cSrcweir {
570cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--;
571cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
572cdf0e10cSrcweir }
573cdf0e10cSrcweir
574cdf0e10cSrcweir // Punkte verschieben
575cdf0e10cSrcweir for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ )
576cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[ i ]->SlantY( nXRef, fSin, fCos );
577cdf0e10cSrcweir }
578cdf0e10cSrcweir
579cdf0e10cSrcweir // -----------------------------------------------------------------------
580cdf0e10cSrcweir
Distort(const Rectangle & rRefRect,const Polygon & rDistortedRect)581cdf0e10cSrcweir void PolyPolygon::Distort( const Rectangle& rRefRect, const Polygon& rDistortedRect )
582cdf0e10cSrcweir {
583cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
584cdf0e10cSrcweir
585cdf0e10cSrcweir // Referenzcounter beruecksichtigen
586cdf0e10cSrcweir if( mpImplPolyPolygon->mnRefCount > 1 )
587cdf0e10cSrcweir {
588cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--;
589cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
590cdf0e10cSrcweir }
591cdf0e10cSrcweir
592cdf0e10cSrcweir // Punkte verschieben
593cdf0e10cSrcweir for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ )
594cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[ i ]->Distort( rRefRect, rDistortedRect );
595cdf0e10cSrcweir }
596cdf0e10cSrcweir
597cdf0e10cSrcweir
598cdf0e10cSrcweir // -----------------------------------------------------------------------
599cdf0e10cSrcweir
Clip(const Rectangle & rRect)600cdf0e10cSrcweir void PolyPolygon::Clip( const Rectangle& rRect )
601cdf0e10cSrcweir {
602cdf0e10cSrcweir // Polygon-Clippen
603cdf0e10cSrcweir sal_uInt16 nPolyCount = mpImplPolyPolygon->mnCount;
604cdf0e10cSrcweir sal_uInt16 i;
605cdf0e10cSrcweir
606cdf0e10cSrcweir if ( !nPolyCount )
607cdf0e10cSrcweir return;
608cdf0e10cSrcweir
609cdf0e10cSrcweir // Referenzcounter beruecksichtigen
610cdf0e10cSrcweir if ( mpImplPolyPolygon->mnRefCount > 1 )
611cdf0e10cSrcweir {
612cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--;
613cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
614cdf0e10cSrcweir }
615cdf0e10cSrcweir
616cdf0e10cSrcweir // Erst jedes Polygon Clippen und dann die leeren entfernen
617cdf0e10cSrcweir for ( i = 0; i < nPolyCount; i++ )
618cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[i]->Clip( rRect );
619cdf0e10cSrcweir while ( nPolyCount )
620cdf0e10cSrcweir {
621cdf0e10cSrcweir if ( GetObject( nPolyCount-1 ).GetSize() <= 2 )
622cdf0e10cSrcweir Remove( nPolyCount-1 );
623cdf0e10cSrcweir nPolyCount--;
624cdf0e10cSrcweir }
625cdf0e10cSrcweir }
626cdf0e10cSrcweir
627cdf0e10cSrcweir // -----------------------------------------------------------------------
628cdf0e10cSrcweir
GetBoundRect() const629cdf0e10cSrcweir Rectangle PolyPolygon::GetBoundRect() const
630cdf0e10cSrcweir {
631cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
632cdf0e10cSrcweir
633cdf0e10cSrcweir long nXMin=0, nXMax=0, nYMin=0, nYMax=0;
634cdf0e10cSrcweir sal_Bool bFirst = sal_True;
635cdf0e10cSrcweir sal_uInt16 nPolyCount = mpImplPolyPolygon->mnCount;
636cdf0e10cSrcweir
637cdf0e10cSrcweir for ( sal_uInt16 n = 0; n < nPolyCount; n++ )
638cdf0e10cSrcweir {
639cdf0e10cSrcweir const Polygon* pPoly = mpImplPolyPolygon->mpPolyAry[n];
640cdf0e10cSrcweir const Point* pAry = pPoly->GetConstPointAry();
641cdf0e10cSrcweir sal_uInt16 nPointCount = pPoly->GetSize();
642cdf0e10cSrcweir
643cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < nPointCount; i++ )
644cdf0e10cSrcweir {
645cdf0e10cSrcweir const Point* pPt = &pAry[ i ];
646cdf0e10cSrcweir
647cdf0e10cSrcweir if ( bFirst )
648cdf0e10cSrcweir {
649cdf0e10cSrcweir nXMin = nXMax = pPt->X();
650cdf0e10cSrcweir nYMin = nYMax = pPt->Y();
651cdf0e10cSrcweir bFirst = sal_False;
652cdf0e10cSrcweir }
653cdf0e10cSrcweir else
654cdf0e10cSrcweir {
655cdf0e10cSrcweir if ( pPt->X() < nXMin )
656cdf0e10cSrcweir nXMin = pPt->X();
657cdf0e10cSrcweir if ( pPt->X() > nXMax )
658cdf0e10cSrcweir nXMax = pPt->X();
659cdf0e10cSrcweir if ( pPt->Y() < nYMin )
660cdf0e10cSrcweir nYMin = pPt->Y();
661cdf0e10cSrcweir if ( pPt->Y() > nYMax )
662cdf0e10cSrcweir nYMax = pPt->Y();
663cdf0e10cSrcweir }
664cdf0e10cSrcweir }
665cdf0e10cSrcweir }
666cdf0e10cSrcweir
667cdf0e10cSrcweir if ( !bFirst )
668cdf0e10cSrcweir return Rectangle( nXMin, nYMin, nXMax, nYMax );
669cdf0e10cSrcweir else
670cdf0e10cSrcweir return Rectangle();
671cdf0e10cSrcweir }
672cdf0e10cSrcweir
673cdf0e10cSrcweir // -----------------------------------------------------------------------
674cdf0e10cSrcweir
operator [](sal_uInt16 nPos)675cdf0e10cSrcweir Polygon& PolyPolygon::operator[]( sal_uInt16 nPos )
676cdf0e10cSrcweir {
677cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
678cdf0e10cSrcweir DBG_ASSERT( nPos < Count(), "PolyPolygon::[](): nPos >= nSize" );
679cdf0e10cSrcweir
680cdf0e10cSrcweir if ( mpImplPolyPolygon->mnRefCount > 1 )
681cdf0e10cSrcweir {
682cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--;
683cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
684cdf0e10cSrcweir }
685cdf0e10cSrcweir
686cdf0e10cSrcweir return *(mpImplPolyPolygon->mpPolyAry[nPos]);
687cdf0e10cSrcweir }
688cdf0e10cSrcweir
689cdf0e10cSrcweir // -----------------------------------------------------------------------
690cdf0e10cSrcweir
operator =(const PolyPolygon & rPolyPoly)691cdf0e10cSrcweir PolyPolygon& PolyPolygon::operator=( const PolyPolygon& rPolyPoly )
692cdf0e10cSrcweir {
693cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
694cdf0e10cSrcweir DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
695cdf0e10cSrcweir DBG_ASSERT( rPolyPoly.mpImplPolyPolygon->mnRefCount < 0xFFFFFFFE, "PolyPolygon: RefCount overflow" );
696cdf0e10cSrcweir
697cdf0e10cSrcweir rPolyPoly.mpImplPolyPolygon->mnRefCount++;
698cdf0e10cSrcweir
699cdf0e10cSrcweir if ( mpImplPolyPolygon->mnRefCount > 1 )
700cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--;
701cdf0e10cSrcweir else
702cdf0e10cSrcweir delete mpImplPolyPolygon;
703cdf0e10cSrcweir
704cdf0e10cSrcweir mpImplPolyPolygon = rPolyPoly.mpImplPolyPolygon;
705cdf0e10cSrcweir return *this;
706cdf0e10cSrcweir }
707cdf0e10cSrcweir
708cdf0e10cSrcweir // -----------------------------------------------------------------------
709cdf0e10cSrcweir
operator ==(const PolyPolygon & rPolyPoly) const710cdf0e10cSrcweir sal_Bool PolyPolygon::operator==( const PolyPolygon& rPolyPoly ) const
711cdf0e10cSrcweir {
712cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
713cdf0e10cSrcweir DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
714cdf0e10cSrcweir
715cdf0e10cSrcweir if ( rPolyPoly.mpImplPolyPolygon == mpImplPolyPolygon )
716cdf0e10cSrcweir return sal_True;
717cdf0e10cSrcweir else
718cdf0e10cSrcweir return sal_False;
719cdf0e10cSrcweir }
720cdf0e10cSrcweir
721cdf0e10cSrcweir // -----------------------------------------------------------------------
722cdf0e10cSrcweir
IsEqual(const PolyPolygon & rPolyPoly) const723cdf0e10cSrcweir sal_Bool PolyPolygon::IsEqual( const PolyPolygon& rPolyPoly ) const
724cdf0e10cSrcweir {
725cdf0e10cSrcweir sal_Bool bIsEqual = sal_True;
726cdf0e10cSrcweir if ( Count() != rPolyPoly.Count() )
727cdf0e10cSrcweir bIsEqual = sal_False;
728cdf0e10cSrcweir else
729cdf0e10cSrcweir {
730cdf0e10cSrcweir sal_uInt16 i;
731cdf0e10cSrcweir for ( i = 0; i < Count(); i++ )
732cdf0e10cSrcweir {
733cdf0e10cSrcweir if (!GetObject( i ).IsEqual( rPolyPoly.GetObject( i ) ) )
734cdf0e10cSrcweir {
735cdf0e10cSrcweir bIsEqual = sal_False;
736cdf0e10cSrcweir break;
737cdf0e10cSrcweir }
738cdf0e10cSrcweir }
739cdf0e10cSrcweir }
740cdf0e10cSrcweir return bIsEqual;
741cdf0e10cSrcweir }
742cdf0e10cSrcweir
743cdf0e10cSrcweir // -----------------------------------------------------------------------
744cdf0e10cSrcweir
operator >>(SvStream & rIStream,PolyPolygon & rPolyPoly)745cdf0e10cSrcweir SvStream& operator>>( SvStream& rIStream, PolyPolygon& rPolyPoly )
746cdf0e10cSrcweir {
747cdf0e10cSrcweir DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
748cdf0e10cSrcweir DBG_ASSERTWARNING( rIStream.GetVersion(), "PolyPolygon::>> - Solar-Version not set on rIStream" );
749cdf0e10cSrcweir
750cdf0e10cSrcweir Polygon* pPoly;
751cdf0e10cSrcweir sal_uInt16 nPolyCount;
752cdf0e10cSrcweir
753cdf0e10cSrcweir // Anzahl der Polygone einlesen
754cdf0e10cSrcweir rIStream >> nPolyCount;
755cdf0e10cSrcweir
756cdf0e10cSrcweir // Daten anlegen
757cdf0e10cSrcweir if( nPolyCount )
758cdf0e10cSrcweir {
759cdf0e10cSrcweir // Referenzcounter beruecksichtigen
760cdf0e10cSrcweir if ( rPolyPoly.mpImplPolyPolygon->mnRefCount > 1 )
761cdf0e10cSrcweir rPolyPoly.mpImplPolyPolygon->mnRefCount--;
762cdf0e10cSrcweir else
763cdf0e10cSrcweir delete rPolyPoly.mpImplPolyPolygon;
764cdf0e10cSrcweir
765cdf0e10cSrcweir rPolyPoly.mpImplPolyPolygon = new ImplPolyPolygon( nPolyCount );
766cdf0e10cSrcweir
767cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
768cdf0e10cSrcweir {
769cdf0e10cSrcweir pPoly = new Polygon;
770cdf0e10cSrcweir rIStream >> *pPoly;
771cdf0e10cSrcweir rPolyPoly.mpImplPolyPolygon->mpPolyAry[i] = pPoly;
772cdf0e10cSrcweir }
773cdf0e10cSrcweir }
774cdf0e10cSrcweir else
775cdf0e10cSrcweir rPolyPoly = PolyPolygon();
776cdf0e10cSrcweir
777cdf0e10cSrcweir return rIStream;
778cdf0e10cSrcweir }
779cdf0e10cSrcweir
780cdf0e10cSrcweir // -----------------------------------------------------------------------
781cdf0e10cSrcweir
operator <<(SvStream & rOStream,const PolyPolygon & rPolyPoly)782cdf0e10cSrcweir SvStream& operator<<( SvStream& rOStream, const PolyPolygon& rPolyPoly )
783cdf0e10cSrcweir {
784cdf0e10cSrcweir DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
785cdf0e10cSrcweir DBG_ASSERTWARNING( rOStream.GetVersion(), "PolyPolygon::<< - Solar-Version not set on rOStream" );
786cdf0e10cSrcweir
787cdf0e10cSrcweir // Anzahl der Polygone rausschreiben
788cdf0e10cSrcweir sal_uInt16 nPolyCount = rPolyPoly.mpImplPolyPolygon->mnCount;
789cdf0e10cSrcweir rOStream << nPolyCount;
790cdf0e10cSrcweir
791cdf0e10cSrcweir // Die einzelnen Polygone ausgeben
792cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
793cdf0e10cSrcweir rOStream << *(rPolyPoly.mpImplPolyPolygon->mpPolyAry[i]);
794cdf0e10cSrcweir
795cdf0e10cSrcweir return rOStream;
796cdf0e10cSrcweir }
797cdf0e10cSrcweir
798cdf0e10cSrcweir // -----------------------------------------------------------------------
799cdf0e10cSrcweir
Read(SvStream & rIStream)800cdf0e10cSrcweir void PolyPolygon::Read( SvStream& rIStream )
801cdf0e10cSrcweir {
802cdf0e10cSrcweir VersionCompat aCompat( rIStream, STREAM_READ );
803cdf0e10cSrcweir
804cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
805cdf0e10cSrcweir DBG_ASSERTWARNING( rIStream.GetVersion(), "PolyPolygon::>> - Solar-Version not set on rIStream" );
806cdf0e10cSrcweir
807cdf0e10cSrcweir Polygon* pPoly;
808cdf0e10cSrcweir sal_uInt16 nPolyCount;
809cdf0e10cSrcweir
810cdf0e10cSrcweir // Anzahl der Polygone einlesen
811cdf0e10cSrcweir rIStream >> nPolyCount;
812cdf0e10cSrcweir
813cdf0e10cSrcweir // Daten anlegen
814cdf0e10cSrcweir if( nPolyCount )
815cdf0e10cSrcweir {
816cdf0e10cSrcweir // Referenzcounter beruecksichtigen
817cdf0e10cSrcweir if ( mpImplPolyPolygon->mnRefCount > 1 )
818cdf0e10cSrcweir mpImplPolyPolygon->mnRefCount--;
819cdf0e10cSrcweir else
820cdf0e10cSrcweir delete mpImplPolyPolygon;
821cdf0e10cSrcweir
822cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( nPolyCount );
823cdf0e10cSrcweir
824cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
825cdf0e10cSrcweir {
826cdf0e10cSrcweir pPoly = new Polygon;
827cdf0e10cSrcweir pPoly->ImplRead( rIStream );
828cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[i] = pPoly;
829cdf0e10cSrcweir }
830cdf0e10cSrcweir }
831cdf0e10cSrcweir else
832cdf0e10cSrcweir *this = PolyPolygon();
833cdf0e10cSrcweir }
834cdf0e10cSrcweir
835cdf0e10cSrcweir // -----------------------------------------------------------------------
836cdf0e10cSrcweir
Write(SvStream & rOStream) const837cdf0e10cSrcweir void PolyPolygon::Write( SvStream& rOStream ) const
838cdf0e10cSrcweir {
839cdf0e10cSrcweir VersionCompat aCompat( rOStream, STREAM_WRITE, 1 );
840cdf0e10cSrcweir
841cdf0e10cSrcweir DBG_CHKTHIS( PolyPolygon, NULL );
842cdf0e10cSrcweir DBG_ASSERTWARNING( rOStream.GetVersion(), "PolyPolygon::<< - Solar-Version not set on rOStream" );
843cdf0e10cSrcweir
844cdf0e10cSrcweir // Anzahl der Polygone rausschreiben
845cdf0e10cSrcweir sal_uInt16 nPolyCount = mpImplPolyPolygon->mnCount;
846cdf0e10cSrcweir rOStream << nPolyCount;
847cdf0e10cSrcweir
848cdf0e10cSrcweir // Die einzelnen Polygone ausgeben
849cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
850cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[i]->ImplWrite( rOStream );;
851cdf0e10cSrcweir }
852cdf0e10cSrcweir
853cdf0e10cSrcweir // -----------------------------------------------------------------------
854cdf0e10cSrcweir // convert to basegfx::B2DPolyPolygon and return
getB2DPolyPolygon() const855cdf0e10cSrcweir basegfx::B2DPolyPolygon PolyPolygon::getB2DPolyPolygon() const
856cdf0e10cSrcweir {
857cdf0e10cSrcweir basegfx::B2DPolyPolygon aRetval;
858cdf0e10cSrcweir
859cdf0e10cSrcweir for(sal_uInt16 a(0); a < mpImplPolyPolygon->mnCount; a++)
860cdf0e10cSrcweir {
861cdf0e10cSrcweir Polygon* pCandidate = mpImplPolyPolygon->mpPolyAry[a];
862cdf0e10cSrcweir aRetval.append(pCandidate->getB2DPolygon());
863cdf0e10cSrcweir }
864cdf0e10cSrcweir
865cdf0e10cSrcweir return aRetval;
866cdf0e10cSrcweir }
867cdf0e10cSrcweir
868cdf0e10cSrcweir // -----------------------------------------------------------------------
869cdf0e10cSrcweir // constructor to convert from basegfx::B2DPolyPolygon
PolyPolygon(const basegfx::B2DPolyPolygon & rPolyPolygon)870cdf0e10cSrcweir PolyPolygon::PolyPolygon(const basegfx::B2DPolyPolygon& rPolyPolygon)
871cdf0e10cSrcweir {
872cdf0e10cSrcweir DBG_CTOR( PolyPolygon, NULL );
873cdf0e10cSrcweir const sal_uInt16 nCount(sal_uInt16(rPolyPolygon.count()));
874cdf0e10cSrcweir DBG_ASSERT(sal_uInt32(nCount) == rPolyPolygon.count(),
875cdf0e10cSrcweir "PolyPolygon::PolyPolygon: Too many sub-polygons in given basegfx::B2DPolyPolygon (!)");
876cdf0e10cSrcweir
877cdf0e10cSrcweir if ( nCount )
878cdf0e10cSrcweir {
879cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( nCount );
880cdf0e10cSrcweir
881cdf0e10cSrcweir for(sal_uInt16 a(0); a < nCount; a++)
882cdf0e10cSrcweir {
883cdf0e10cSrcweir basegfx::B2DPolygon aCandidate(rPolyPolygon.getB2DPolygon(sal_uInt32(a)));
884cdf0e10cSrcweir mpImplPolyPolygon->mpPolyAry[a] = new Polygon( aCandidate );
885cdf0e10cSrcweir }
886cdf0e10cSrcweir }
887cdf0e10cSrcweir else
888cdf0e10cSrcweir {
889cdf0e10cSrcweir mpImplPolyPolygon = new ImplPolyPolygon( 16, 16 );
890cdf0e10cSrcweir }
891cdf0e10cSrcweir }
892cdf0e10cSrcweir
893cdf0e10cSrcweir // eof
894