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