xref: /aoo41x/main/svx/source/xoutdev/_xpoly.cxx (revision f6e50924)
1*f6e50924SAndrew Rist /**************************************************************
2*f6e50924SAndrew Rist  *
3*f6e50924SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*f6e50924SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*f6e50924SAndrew Rist  * distributed with this work for additional information
6*f6e50924SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*f6e50924SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*f6e50924SAndrew Rist  * "License"); you may not use this file except in compliance
9*f6e50924SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*f6e50924SAndrew Rist  *
11*f6e50924SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*f6e50924SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*f6e50924SAndrew Rist  * software distributed under the License is distributed on an
15*f6e50924SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*f6e50924SAndrew Rist  * KIND, either express or implied.  See the License for the
17*f6e50924SAndrew Rist  * specific language governing permissions and limitations
18*f6e50924SAndrew Rist  * under the License.
19*f6e50924SAndrew Rist  *
20*f6e50924SAndrew Rist  *************************************************************/
21*f6e50924SAndrew Rist 
22*f6e50924SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svx.hxx"
26cdf0e10cSrcweir #include <osl/endian.h>
27cdf0e10cSrcweir #include <tools/stream.hxx>
28cdf0e10cSrcweir #include <tools/debug.hxx>
29cdf0e10cSrcweir #include <tools/poly.hxx>
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include <svx/xpoly.hxx>
32cdf0e10cSrcweir #include "xpolyimp.hxx"
33cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
34cdf0e10cSrcweir #include <basegfx/point/b2dpoint.hxx>
35cdf0e10cSrcweir #include <basegfx/vector/b2dvector.hxx>
36cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx>
37cdf0e10cSrcweir #include <vcl/salbtype.hxx>		// FRound
38cdf0e10cSrcweir #include <basegfx/range/b2drange.hxx>
39cdf0e10cSrcweir #include <basegfx/numeric/ftools.hxx>
40cdf0e10cSrcweir 
41cdf0e10cSrcweir #define GLOBALOVERFLOW
42cdf0e10cSrcweir 
43cdf0e10cSrcweir DBG_NAME(XPolygon);
44cdf0e10cSrcweir DBG_NAME(XPolyPolygon);
45cdf0e10cSrcweir 
46cdf0e10cSrcweir /*************************************************************************
47cdf0e10cSrcweir |*
48cdf0e10cSrcweir |*    ImpXPolygon::ImpXPolygon()
49cdf0e10cSrcweir |*
50cdf0e10cSrcweir |*    Beschreibung
51cdf0e10cSrcweir |*    Ersterstellung    08.11.94
52cdf0e10cSrcweir |*    Letzte Aenderung  12.01.95 ESO
53cdf0e10cSrcweir |*
54cdf0e10cSrcweir *************************************************************************/
55cdf0e10cSrcweir 
ImpXPolygon(sal_uInt16 nInitSize,sal_uInt16 _nResize)56cdf0e10cSrcweir ImpXPolygon::ImpXPolygon( sal_uInt16 nInitSize, sal_uInt16 _nResize )
57cdf0e10cSrcweir {
58cdf0e10cSrcweir 	pPointAry               = NULL;
59cdf0e10cSrcweir 	pFlagAry                = NULL;
60cdf0e10cSrcweir 	bDeleteOldPoints        = sal_False;
61cdf0e10cSrcweir 	nSize                   = 0;
62cdf0e10cSrcweir 	nResize					= _nResize;
63cdf0e10cSrcweir 	nPoints                 = 0;
64cdf0e10cSrcweir 	nRefCount               = 1;
65cdf0e10cSrcweir 
66cdf0e10cSrcweir 	Resize( nInitSize );
67cdf0e10cSrcweir }
68cdf0e10cSrcweir 
69cdf0e10cSrcweir /*************************************************************************
70cdf0e10cSrcweir |*
71cdf0e10cSrcweir |*    ImpXPolygon::ImpXPolygon()
72cdf0e10cSrcweir |*
73cdf0e10cSrcweir |*    Beschreibung
74cdf0e10cSrcweir |*    Ersterstellung    08.11.94
75cdf0e10cSrcweir |*    Letzte Aenderung  12.01.95 ESO
76cdf0e10cSrcweir |*
77cdf0e10cSrcweir *************************************************************************/
78cdf0e10cSrcweir 
ImpXPolygon(const ImpXPolygon & rImpXPoly)79cdf0e10cSrcweir ImpXPolygon::ImpXPolygon( const ImpXPolygon& rImpXPoly )
80cdf0e10cSrcweir {
81cdf0e10cSrcweir 	( (ImpXPolygon&) rImpXPoly ).CheckPointDelete();
82cdf0e10cSrcweir 
83cdf0e10cSrcweir 	pPointAry               = NULL;
84cdf0e10cSrcweir 	pFlagAry                = NULL;
85cdf0e10cSrcweir 	bDeleteOldPoints        = sal_False;
86cdf0e10cSrcweir 	nSize                   = 0;
87cdf0e10cSrcweir 	ImpXPolygon::nResize    = rImpXPoly.nResize;
88cdf0e10cSrcweir 	nPoints                 = 0;
89cdf0e10cSrcweir 	nRefCount               = 1;
90cdf0e10cSrcweir 
91cdf0e10cSrcweir 	Resize( rImpXPoly.nSize );
92cdf0e10cSrcweir 
93cdf0e10cSrcweir 	// Kopieren
94cdf0e10cSrcweir 	nPoints = rImpXPoly.nPoints;
95cdf0e10cSrcweir 	memcpy( pPointAry, rImpXPoly.pPointAry, nSize*sizeof( Point ) );
96cdf0e10cSrcweir 	memcpy( pFlagAry, rImpXPoly.pFlagAry, nSize );
97cdf0e10cSrcweir }
98cdf0e10cSrcweir 
99cdf0e10cSrcweir /*************************************************************************
100cdf0e10cSrcweir |*
101cdf0e10cSrcweir |*    ImpXPolygon::~ImpXPolygon()
102cdf0e10cSrcweir |*
103cdf0e10cSrcweir |*    Beschreibung
104cdf0e10cSrcweir |*    Ersterstellung    08.11.94
105cdf0e10cSrcweir |*    Letzte Aenderung  12.01.95 ESO
106cdf0e10cSrcweir |*
107cdf0e10cSrcweir *************************************************************************/
108cdf0e10cSrcweir 
~ImpXPolygon()109cdf0e10cSrcweir ImpXPolygon::~ImpXPolygon()
110cdf0e10cSrcweir {
111cdf0e10cSrcweir 	delete[] (char*) pPointAry;
112cdf0e10cSrcweir 	delete[] pFlagAry;
113cdf0e10cSrcweir 	if ( bDeleteOldPoints )
114cdf0e10cSrcweir 		delete[] (char*) pOldPointAry;
115cdf0e10cSrcweir }
116cdf0e10cSrcweir 
117cdf0e10cSrcweir /*************************************************************************
118cdf0e10cSrcweir |*
119cdf0e10cSrcweir |*    ImpXPolygon::operator==()
120cdf0e10cSrcweir |*
121cdf0e10cSrcweir |*    Ersterstellung    Joe 26-09-95
122cdf0e10cSrcweir |*    Letzte Aenderung
123cdf0e10cSrcweir |*
124cdf0e10cSrcweir *************************************************************************/
125cdf0e10cSrcweir 
126cdf0e10cSrcweir 
operator ==(const ImpXPolygon & rImpXPoly) const127cdf0e10cSrcweir bool ImpXPolygon::operator==(const ImpXPolygon& rImpXPoly) const
128cdf0e10cSrcweir {
129cdf0e10cSrcweir 	return nPoints==rImpXPoly.nPoints &&
130cdf0e10cSrcweir 		   (nPoints==0 ||
131cdf0e10cSrcweir 			(memcmp(pPointAry,rImpXPoly.pPointAry,nPoints*sizeof(Point))==0 &&
132cdf0e10cSrcweir 			 memcmp(pFlagAry,rImpXPoly.pFlagAry,nPoints)==0));
133cdf0e10cSrcweir }
134cdf0e10cSrcweir 
135cdf0e10cSrcweir /*************************************************************************
136cdf0e10cSrcweir |*
137cdf0e10cSrcweir |*    ImpXPolygon::Resize()
138cdf0e10cSrcweir |*
139cdf0e10cSrcweir |*    !!! Polygongroesse aendern - wenn bDeletePoints sal_False, dann den
140cdf0e10cSrcweir |*    Point-Array nicht loeschen, sondern in pOldPointAry sichern und
141cdf0e10cSrcweir |*    das Flag bDeleteOldPoints setzen. Beim naechsten Zugriff wird
142cdf0e10cSrcweir |*    das Array dann geloescht.
143cdf0e10cSrcweir |*    Damit wird verhindert, dass bei XPoly[n] = XPoly[0] durch ein
144cdf0e10cSrcweir |*    Resize der fuer den rechten Ausdruck verwendete Point-Array
145cdf0e10cSrcweir |*    vorzeitig geloescht wird.
146cdf0e10cSrcweir |*    Ersterstellung    08.11.94
147cdf0e10cSrcweir |*    Letzte Aenderung  12.01.95 ESO
148cdf0e10cSrcweir |*
149cdf0e10cSrcweir *************************************************************************/
150cdf0e10cSrcweir 
Resize(sal_uInt16 nNewSize,sal_Bool bDeletePoints)151cdf0e10cSrcweir void ImpXPolygon::Resize( sal_uInt16 nNewSize, sal_Bool bDeletePoints )
152cdf0e10cSrcweir {
153cdf0e10cSrcweir 	if( nNewSize == nSize )
154cdf0e10cSrcweir 		return;
155cdf0e10cSrcweir 
156cdf0e10cSrcweir 	sal_uInt8*   pOldFlagAry  = pFlagAry;
157cdf0e10cSrcweir 	sal_uInt16  nOldSize     = nSize;
158cdf0e10cSrcweir 
159cdf0e10cSrcweir 	CheckPointDelete();
160cdf0e10cSrcweir 	pOldPointAry = pPointAry;
161cdf0e10cSrcweir 
162cdf0e10cSrcweir 	// Neue Groesse auf vielfaches von nResize runden, sofern Objekt
163cdf0e10cSrcweir 	// nicht neu angelegt wurde (nSize != 0)
164cdf0e10cSrcweir 	if ( nSize != 0 && nNewSize > nSize )
165cdf0e10cSrcweir 	{
166cdf0e10cSrcweir 		DBG_ASSERT(nResize, "Resize-Versuch trotz nResize = 0 !");
167cdf0e10cSrcweir 		nNewSize = nSize + ((nNewSize-nSize-1) / nResize + 1) * nResize;
168cdf0e10cSrcweir 	}
169cdf0e10cSrcweir 	// Punkt Array erzeugen
170cdf0e10cSrcweir 	nSize     = nNewSize;
171cdf0e10cSrcweir 	pPointAry = (Point*)new char[ nSize*sizeof( Point ) ];
172cdf0e10cSrcweir 	memset( pPointAry, 0, nSize*sizeof( Point ) );
173cdf0e10cSrcweir 
174cdf0e10cSrcweir 	// Flag Array erzeugen
175cdf0e10cSrcweir 	pFlagAry = new sal_uInt8[ nSize ];
176cdf0e10cSrcweir 	memset( pFlagAry, 0, nSize );
177cdf0e10cSrcweir 
178cdf0e10cSrcweir 	// Eventuell umkopieren
179cdf0e10cSrcweir 	if( nOldSize )
180cdf0e10cSrcweir 	{
181cdf0e10cSrcweir 		if( nOldSize < nSize )
182cdf0e10cSrcweir 		{
183cdf0e10cSrcweir 			memcpy( pPointAry, pOldPointAry, nOldSize*sizeof( Point ) );
184cdf0e10cSrcweir 			memcpy( pFlagAry,  pOldFlagAry, nOldSize );
185cdf0e10cSrcweir 		}
186cdf0e10cSrcweir 		else
187cdf0e10cSrcweir 		{
188cdf0e10cSrcweir 			memcpy( pPointAry, pOldPointAry, nSize*sizeof( Point ) );
189cdf0e10cSrcweir 			memcpy( pFlagAry, pOldFlagAry, nSize );
190cdf0e10cSrcweir 
191cdf0e10cSrcweir 			// Anzahl der gueltigen Punkte anpassen
192cdf0e10cSrcweir 			if( nPoints > nSize )
193cdf0e10cSrcweir 				nPoints = nSize;
194cdf0e10cSrcweir 		}
195cdf0e10cSrcweir 		if ( bDeletePoints )    delete[] (char*) pOldPointAry;
196cdf0e10cSrcweir 		else                    bDeleteOldPoints = sal_True;
197cdf0e10cSrcweir 		delete[] pOldFlagAry;
198cdf0e10cSrcweir 	}
199cdf0e10cSrcweir }
200cdf0e10cSrcweir 
201cdf0e10cSrcweir 
202cdf0e10cSrcweir /*************************************************************************
203cdf0e10cSrcweir |*
204cdf0e10cSrcweir |*    ImpXPolygon::InsertSpace()
205cdf0e10cSrcweir |*
206cdf0e10cSrcweir |*    Beschreibung
207cdf0e10cSrcweir |*    Ersterstellung    08.11.94
208cdf0e10cSrcweir |*    Letzte Aenderung  29.03.95 ESO
209cdf0e10cSrcweir |*
210cdf0e10cSrcweir *************************************************************************/
211cdf0e10cSrcweir 
InsertSpace(sal_uInt16 nPos,sal_uInt16 nCount)212cdf0e10cSrcweir void ImpXPolygon::InsertSpace( sal_uInt16 nPos, sal_uInt16 nCount )
213cdf0e10cSrcweir {
214cdf0e10cSrcweir 	CheckPointDelete();
215cdf0e10cSrcweir 
216cdf0e10cSrcweir 	if ( nPos > nPoints )
217cdf0e10cSrcweir 		nPos = nPoints;
218cdf0e10cSrcweir 
219cdf0e10cSrcweir 	// Wenn Polygon zu klein dann groesser machen
220cdf0e10cSrcweir 	if( (nPoints + nCount) > nSize )
221cdf0e10cSrcweir 		Resize( nPoints + nCount );
222cdf0e10cSrcweir 
223cdf0e10cSrcweir 	// Wenn nicht hinter dem letzten Punkt eingefuegt wurde,
224cdf0e10cSrcweir 	// den Rest nach hinten schieben
225cdf0e10cSrcweir 	if( nPos < nPoints )
226cdf0e10cSrcweir 	{
227cdf0e10cSrcweir 		sal_uInt16 nMove = nPoints - nPos;
228cdf0e10cSrcweir 		memmove( &pPointAry[nPos+nCount], &pPointAry[nPos],
229cdf0e10cSrcweir 				 nMove * sizeof(Point) );
230cdf0e10cSrcweir 		memmove( &pFlagAry[nPos+nCount], &pFlagAry[nPos], nMove );
231cdf0e10cSrcweir 	}
232cdf0e10cSrcweir 	memset( &pPointAry[nPos], 0, nCount * sizeof( Point ) );
233cdf0e10cSrcweir 	memset( &pFlagAry [nPos], 0, nCount );
234cdf0e10cSrcweir 
235cdf0e10cSrcweir 	nPoints = nPoints + nCount;
236cdf0e10cSrcweir }
237cdf0e10cSrcweir 
238cdf0e10cSrcweir 
239cdf0e10cSrcweir /*************************************************************************
240cdf0e10cSrcweir |*
241cdf0e10cSrcweir |*    ImpXPolygon::Remove()
242cdf0e10cSrcweir |*
243cdf0e10cSrcweir |*    Beschreibung
244cdf0e10cSrcweir |*    Ersterstellung    08.11.94
245cdf0e10cSrcweir |*    Letzte Aenderung  12.01.94 ESO
246cdf0e10cSrcweir |*
247cdf0e10cSrcweir *************************************************************************/
248cdf0e10cSrcweir 
Remove(sal_uInt16 nPos,sal_uInt16 nCount)249cdf0e10cSrcweir void ImpXPolygon::Remove( sal_uInt16 nPos, sal_uInt16 nCount )
250cdf0e10cSrcweir {
251cdf0e10cSrcweir 	CheckPointDelete();
252cdf0e10cSrcweir 
253cdf0e10cSrcweir 	if( (nPos + nCount) <= nPoints )
254cdf0e10cSrcweir 	{
255cdf0e10cSrcweir 		sal_uInt16 nMove = nPoints - nPos - nCount;
256cdf0e10cSrcweir 
257cdf0e10cSrcweir 		if( nMove )
258cdf0e10cSrcweir 		{
259cdf0e10cSrcweir 			memmove( &pPointAry[nPos], &pPointAry[nPos+nCount],
260cdf0e10cSrcweir 					 nMove * sizeof(Point) );
261cdf0e10cSrcweir 			memmove( &pFlagAry[nPos], &pFlagAry[nPos+nCount], nMove );
262cdf0e10cSrcweir 		}
263cdf0e10cSrcweir 		memset( &pPointAry[nPoints - nCount], 0, nCount * sizeof( Point ) );
264cdf0e10cSrcweir 		memset( &pFlagAry [nPoints - nCount], 0, nCount );
265cdf0e10cSrcweir 		nPoints = nPoints - nCount;
266cdf0e10cSrcweir 	}
267cdf0e10cSrcweir }
268cdf0e10cSrcweir 
269cdf0e10cSrcweir 
270cdf0e10cSrcweir /*************************************************************************
271cdf0e10cSrcweir |*
272cdf0e10cSrcweir |*    XPolygon::XPolygon()
273cdf0e10cSrcweir |*
274cdf0e10cSrcweir |*    Beschreibung
275cdf0e10cSrcweir |*    Ersterstellung    08.11.94
276cdf0e10cSrcweir |*    Letzte Aenderung  08.11.94
277cdf0e10cSrcweir |*
278cdf0e10cSrcweir *************************************************************************/
279cdf0e10cSrcweir 
XPolygon(sal_uInt16 nSize,sal_uInt16 nResize)280cdf0e10cSrcweir XPolygon::XPolygon( sal_uInt16 nSize, sal_uInt16 nResize )
281cdf0e10cSrcweir {
282cdf0e10cSrcweir 	DBG_CTOR(XPolygon,NULL);
283cdf0e10cSrcweir 	pImpXPolygon = new ImpXPolygon( nSize, nResize );
284cdf0e10cSrcweir }
285cdf0e10cSrcweir 
286cdf0e10cSrcweir /*************************************************************************
287cdf0e10cSrcweir |*
288cdf0e10cSrcweir |*    XPolygon::XPolygon()
289cdf0e10cSrcweir |*
290cdf0e10cSrcweir |*    Beschreibung
291cdf0e10cSrcweir |*    Ersterstellung    08.11.94
292cdf0e10cSrcweir |*    Letzte Aenderung  08.11.94
293cdf0e10cSrcweir |*
294cdf0e10cSrcweir *************************************************************************/
295cdf0e10cSrcweir 
XPolygon(const XPolygon & rXPoly)296cdf0e10cSrcweir XPolygon::XPolygon( const XPolygon& rXPoly )
297cdf0e10cSrcweir {
298cdf0e10cSrcweir 	DBG_CTOR(XPolygon,NULL);
299cdf0e10cSrcweir 	pImpXPolygon = rXPoly.pImpXPolygon;
300cdf0e10cSrcweir 	pImpXPolygon->nRefCount++;
301cdf0e10cSrcweir }
302cdf0e10cSrcweir 
303cdf0e10cSrcweir /*************************************************************************
304cdf0e10cSrcweir |*
305cdf0e10cSrcweir |*    XPolygon::XPolygon()
306cdf0e10cSrcweir |*
307cdf0e10cSrcweir |*    XPolygon aus einem Standardpolygon erstellen
308cdf0e10cSrcweir |*    Ersterstellung    18.01.95 ESO
309cdf0e10cSrcweir |*    Letzte Aenderung  18.01.95 ESO
310cdf0e10cSrcweir |*
311cdf0e10cSrcweir *************************************************************************/
312cdf0e10cSrcweir 
XPolygon(const Polygon & rPoly)313cdf0e10cSrcweir XPolygon::XPolygon( const Polygon& rPoly )
314cdf0e10cSrcweir {
315cdf0e10cSrcweir 	DBG_CTOR(XPolygon,NULL);
316cdf0e10cSrcweir 
317cdf0e10cSrcweir 	sal_uInt16 nSize = rPoly.GetSize();
318cdf0e10cSrcweir 	pImpXPolygon = new ImpXPolygon( nSize );
319cdf0e10cSrcweir 	pImpXPolygon->nPoints = nSize;
320cdf0e10cSrcweir 
321cdf0e10cSrcweir 	for( sal_uInt16 i = 0; i < nSize;  i++ )
322cdf0e10cSrcweir 	{
323cdf0e10cSrcweir 		pImpXPolygon->pPointAry[i] = rPoly[i];
324cdf0e10cSrcweir 		pImpXPolygon->pFlagAry[i] = (sal_uInt8) rPoly.GetFlags( i );
325cdf0e10cSrcweir 	}
326cdf0e10cSrcweir }
327cdf0e10cSrcweir 
328cdf0e10cSrcweir /*************************************************************************
329cdf0e10cSrcweir |*
330cdf0e10cSrcweir |*    XPolygon::XPolygon()
331cdf0e10cSrcweir |*
332cdf0e10cSrcweir |*    Rechteck (auch mit abgerundeten Ecken) als Bezierpolygon erzeugen
333cdf0e10cSrcweir |*    Ersterstellung    09.01.95 ESO
334cdf0e10cSrcweir |*    Letzte Aenderung  09.01.95 ESO
335cdf0e10cSrcweir |*
336cdf0e10cSrcweir *************************************************************************/
337cdf0e10cSrcweir 
XPolygon(const Rectangle & rRect,long nRx,long nRy)338cdf0e10cSrcweir XPolygon::XPolygon(const Rectangle& rRect, long nRx, long nRy)
339cdf0e10cSrcweir {
340cdf0e10cSrcweir 	DBG_CTOR(XPolygon,NULL);
341cdf0e10cSrcweir 	pImpXPolygon = new ImpXPolygon(17);
342cdf0e10cSrcweir 	long nWh = (rRect.GetWidth()  - 1) / 2;
343cdf0e10cSrcweir 	long nHh = (rRect.GetHeight() - 1) / 2;
344cdf0e10cSrcweir 
345cdf0e10cSrcweir 	if ( nRx > nWh )    nRx = nWh;
346cdf0e10cSrcweir 	if ( nRy > nHh )    nRy = nHh;
347cdf0e10cSrcweir 
348cdf0e10cSrcweir 	// Rx negativ, damit Umlauf im Uhrzeigersinn erfolgt
349cdf0e10cSrcweir 	nRx = -nRx;
350cdf0e10cSrcweir 
351cdf0e10cSrcweir 	// Faktor fuer Kontrollpunkte der Bezierkurven: 8/3 * (sin(45g) - 0.5)
352cdf0e10cSrcweir 	long    nXHdl = (long)(0.552284749 * nRx);
353cdf0e10cSrcweir 	long    nYHdl = (long)(0.552284749 * nRy);
354cdf0e10cSrcweir 	sal_uInt16  nPos = 0;
355cdf0e10cSrcweir 
356cdf0e10cSrcweir 	if ( nRx && nRy )
357cdf0e10cSrcweir 	{
358cdf0e10cSrcweir 		Point aCenter;
359cdf0e10cSrcweir 
360cdf0e10cSrcweir 		for (sal_uInt16 nQuad = 0; nQuad < 4; nQuad++)
361cdf0e10cSrcweir 		{
362cdf0e10cSrcweir 			switch ( nQuad )
363cdf0e10cSrcweir 			{
364cdf0e10cSrcweir 				case 0:	aCenter = rRect.TopLeft();
365cdf0e10cSrcweir 						aCenter.X() -= nRx;
366cdf0e10cSrcweir 						aCenter.Y() += nRy;
367cdf0e10cSrcweir 						break;
368cdf0e10cSrcweir 				case 1:	aCenter = rRect.TopRight();
369cdf0e10cSrcweir 						aCenter.X() += nRx;
370cdf0e10cSrcweir 						aCenter.Y() += nRy;
371cdf0e10cSrcweir 						break;
372cdf0e10cSrcweir 				case 2:	aCenter = rRect.BottomRight();
373cdf0e10cSrcweir 						aCenter.X() += nRx;
374cdf0e10cSrcweir 						aCenter.Y() -= nRy;
375cdf0e10cSrcweir 						break;
376cdf0e10cSrcweir 				case 3:	aCenter = rRect.BottomLeft();
377cdf0e10cSrcweir 						aCenter.X() -= nRx;
378cdf0e10cSrcweir 						aCenter.Y() -= nRy;
379cdf0e10cSrcweir 						break;
380cdf0e10cSrcweir 			}
381cdf0e10cSrcweir 			GenBezArc(aCenter, nRx, nRy, nXHdl, nYHdl, 0, 900, nQuad, nPos);
382cdf0e10cSrcweir 			pImpXPolygon->pFlagAry[nPos  ] = (sal_uInt8) XPOLY_SMOOTH;
383cdf0e10cSrcweir 			pImpXPolygon->pFlagAry[nPos+3] = (sal_uInt8) XPOLY_SMOOTH;
384cdf0e10cSrcweir 			nPos += 4;
385cdf0e10cSrcweir 		}
386cdf0e10cSrcweir 	}
387cdf0e10cSrcweir 	else
388cdf0e10cSrcweir 	{
389cdf0e10cSrcweir 		pImpXPolygon->pPointAry[nPos++] = rRect.TopLeft();
390cdf0e10cSrcweir 		pImpXPolygon->pPointAry[nPos++] = rRect.TopRight();
391cdf0e10cSrcweir 		pImpXPolygon->pPointAry[nPos++] = rRect.BottomRight();
392cdf0e10cSrcweir 		pImpXPolygon->pPointAry[nPos++] = rRect.BottomLeft();
393cdf0e10cSrcweir 	}
394cdf0e10cSrcweir 	pImpXPolygon->pPointAry[nPos] = pImpXPolygon->pPointAry[0];
395cdf0e10cSrcweir 	pImpXPolygon->nPoints = nPos + 1;
396cdf0e10cSrcweir }
397cdf0e10cSrcweir 
398cdf0e10cSrcweir /*************************************************************************
399cdf0e10cSrcweir |*
400cdf0e10cSrcweir |*    XPolygon::XPolygon()
401cdf0e10cSrcweir |*
402cdf0e10cSrcweir |*    Ellipsen(bogen) als Bezierpolygon erzeugen
403cdf0e10cSrcweir |*    Ersterstellung    09.01.95
404cdf0e10cSrcweir |*    Letzte Aenderung  09.01.95
405cdf0e10cSrcweir |*
406cdf0e10cSrcweir *************************************************************************/
407cdf0e10cSrcweir 
XPolygon(const Point & rCenter,long nRx,long nRy,sal_uInt16 nStartAngle,sal_uInt16 nEndAngle,sal_Bool bClose)408cdf0e10cSrcweir XPolygon::XPolygon(const Point& rCenter, long nRx, long nRy,
409cdf0e10cSrcweir 				   sal_uInt16 nStartAngle, sal_uInt16 nEndAngle, sal_Bool bClose)
410cdf0e10cSrcweir {
411cdf0e10cSrcweir 	DBG_CTOR(XPolygon,NULL);
412cdf0e10cSrcweir 	pImpXPolygon = new ImpXPolygon(17);
413cdf0e10cSrcweir 
414cdf0e10cSrcweir 	nStartAngle %= 3600;
415cdf0e10cSrcweir 	if ( nEndAngle > 3600 ) nEndAngle %= 3600;
416cdf0e10cSrcweir 	sal_Bool bFull = (nStartAngle == 0 && nEndAngle == 3600);
417cdf0e10cSrcweir 
418cdf0e10cSrcweir 	// Faktor fuer Kontrollpunkte der Bezierkurven: 8/3 * (sin(45g) - 0.5)
419cdf0e10cSrcweir 	long    nXHdl = (long)(0.552284749 * nRx);
420cdf0e10cSrcweir 	long    nYHdl = (long)(0.552284749 * nRy);
421cdf0e10cSrcweir 	sal_uInt16  nPos = 0;
422cdf0e10cSrcweir 	sal_Bool    bLoopEnd = sal_False;
423cdf0e10cSrcweir 
424cdf0e10cSrcweir 	do
425cdf0e10cSrcweir 	{
426cdf0e10cSrcweir 		sal_uInt16 nA1, nA2;
427cdf0e10cSrcweir 		sal_uInt16 nQuad = nStartAngle / 900;
428cdf0e10cSrcweir 		if ( nQuad == 4 ) nQuad = 0;
429cdf0e10cSrcweir 		bLoopEnd = CheckAngles(nStartAngle, nEndAngle, nA1, nA2);
430cdf0e10cSrcweir 		GenBezArc(rCenter, nRx, nRy, nXHdl, nYHdl, nA1, nA2, nQuad, nPos);
431cdf0e10cSrcweir 		nPos += 3;
432cdf0e10cSrcweir 		if ( !bLoopEnd )
433cdf0e10cSrcweir 			pImpXPolygon->pFlagAry[nPos] = (sal_uInt8) XPOLY_SMOOTH;
434cdf0e10cSrcweir 
435cdf0e10cSrcweir 	} while ( !bLoopEnd );
436cdf0e10cSrcweir 
437cdf0e10cSrcweir 	// Wenn kein Vollkreis, dann ggf. Enden mit Mittelpunkt verbinden
438cdf0e10cSrcweir 	if ( !bFull && bClose )
439cdf0e10cSrcweir 		pImpXPolygon->pPointAry[++nPos] = rCenter;
440cdf0e10cSrcweir 
441cdf0e10cSrcweir 	if ( bFull )
442cdf0e10cSrcweir 	{
443cdf0e10cSrcweir 		pImpXPolygon->pFlagAry[0   ] = (sal_uInt8) XPOLY_SMOOTH;
444cdf0e10cSrcweir 		pImpXPolygon->pFlagAry[nPos] = (sal_uInt8) XPOLY_SMOOTH;
445cdf0e10cSrcweir 	}
446cdf0e10cSrcweir 	pImpXPolygon->nPoints = nPos + 1;
447cdf0e10cSrcweir }
448cdf0e10cSrcweir 
449cdf0e10cSrcweir /*************************************************************************
450cdf0e10cSrcweir |*
451cdf0e10cSrcweir |*    XPolygon::~XPolygon()
452cdf0e10cSrcweir |*
453cdf0e10cSrcweir |*    Beschreibung
454cdf0e10cSrcweir |*    Ersterstellung    08.11.94
455cdf0e10cSrcweir |*    Letzte Aenderung  08.11.94
456cdf0e10cSrcweir |*
457cdf0e10cSrcweir *************************************************************************/
458cdf0e10cSrcweir 
~XPolygon()459cdf0e10cSrcweir XPolygon::~XPolygon()
460cdf0e10cSrcweir {
461cdf0e10cSrcweir 	DBG_DTOR(XPolygon,NULL);
462cdf0e10cSrcweir 	if( pImpXPolygon->nRefCount > 1 )
463cdf0e10cSrcweir 		pImpXPolygon->nRefCount--;
464cdf0e10cSrcweir 	else
465cdf0e10cSrcweir 		delete pImpXPolygon;
466cdf0e10cSrcweir }
467cdf0e10cSrcweir 
468cdf0e10cSrcweir /*************************************************************************
469cdf0e10cSrcweir |*
470cdf0e10cSrcweir |*    XPolygon::CheckReference()
471cdf0e10cSrcweir |*
472cdf0e10cSrcweir |*    Referenzzaehler desImpXPoly pruefen und ggf. von diesem abkoppeln
473cdf0e10cSrcweir |*    Ersterstellung    17.01.95 ESO
474cdf0e10cSrcweir |*    Letzte Aenderung  17.01.95 ESO
475cdf0e10cSrcweir |*
476cdf0e10cSrcweir *************************************************************************/
477cdf0e10cSrcweir 
CheckReference()478cdf0e10cSrcweir void XPolygon::CheckReference()
479cdf0e10cSrcweir {
480cdf0e10cSrcweir 	if( pImpXPolygon->nRefCount > 1 )
481cdf0e10cSrcweir 	{
482cdf0e10cSrcweir 		pImpXPolygon->nRefCount--;
483cdf0e10cSrcweir 		pImpXPolygon = new ImpXPolygon( *pImpXPolygon );
484cdf0e10cSrcweir 	}
485cdf0e10cSrcweir }
486cdf0e10cSrcweir 
487cdf0e10cSrcweir /*************************************************************************
488cdf0e10cSrcweir |*
489cdf0e10cSrcweir |*    XPolygon::SetSize()
490cdf0e10cSrcweir |*
491cdf0e10cSrcweir |*    Beschreibung
492cdf0e10cSrcweir |*    Ersterstellung    08.11.94
493cdf0e10cSrcweir |*    Letzte Aenderung  08.11.94
494cdf0e10cSrcweir |*
495cdf0e10cSrcweir *************************************************************************/
496cdf0e10cSrcweir 
SetSize(sal_uInt16 nNewSize)497cdf0e10cSrcweir void XPolygon::SetSize( sal_uInt16 nNewSize )
498cdf0e10cSrcweir {
499cdf0e10cSrcweir 	CheckReference();
500cdf0e10cSrcweir 	pImpXPolygon->Resize( nNewSize );
501cdf0e10cSrcweir }
502cdf0e10cSrcweir 
503cdf0e10cSrcweir /*************************************************************************
504cdf0e10cSrcweir |*
505cdf0e10cSrcweir |*    XPolygon::GetSize()
506cdf0e10cSrcweir |*
507cdf0e10cSrcweir |*    Beschreibung
508cdf0e10cSrcweir |*    Ersterstellung    08.11.94
509cdf0e10cSrcweir |*    Letzte Aenderung  12.01.95 ESO
510cdf0e10cSrcweir |*
511cdf0e10cSrcweir *************************************************************************/
512cdf0e10cSrcweir 
GetSize() const513cdf0e10cSrcweir sal_uInt16 XPolygon::GetSize() const
514cdf0e10cSrcweir {
515cdf0e10cSrcweir 	pImpXPolygon->CheckPointDelete();
516cdf0e10cSrcweir 	return pImpXPolygon->nSize;
517cdf0e10cSrcweir }
518cdf0e10cSrcweir 
519cdf0e10cSrcweir /*************************************************************************
520cdf0e10cSrcweir |*
521cdf0e10cSrcweir |*    XPolygon::SetPointCount()
522cdf0e10cSrcweir |*
523cdf0e10cSrcweir |*    Beschreibung
524cdf0e10cSrcweir |*    Ersterstellung    08.11.94
525cdf0e10cSrcweir |*    Letzte Aenderung  12.01.95 ESO
526cdf0e10cSrcweir |*
527cdf0e10cSrcweir *************************************************************************/
528cdf0e10cSrcweir 
SetPointCount(sal_uInt16 nPoints)529cdf0e10cSrcweir void XPolygon::SetPointCount( sal_uInt16 nPoints )
530cdf0e10cSrcweir {
531cdf0e10cSrcweir 	pImpXPolygon->CheckPointDelete();
532cdf0e10cSrcweir 	CheckReference();
533cdf0e10cSrcweir 
534cdf0e10cSrcweir 	if( pImpXPolygon->nSize < nPoints )
535cdf0e10cSrcweir 		pImpXPolygon->Resize( nPoints );
536cdf0e10cSrcweir 
537cdf0e10cSrcweir 	if ( nPoints < pImpXPolygon->nPoints )
538cdf0e10cSrcweir 	{
539cdf0e10cSrcweir 		sal_uInt16 nSize = pImpXPolygon->nPoints - nPoints;
540cdf0e10cSrcweir 		memset( &pImpXPolygon->pPointAry[nPoints], 0, nSize * sizeof( Point ) );
541cdf0e10cSrcweir 		memset( &pImpXPolygon->pFlagAry [nPoints], 0, nSize );
542cdf0e10cSrcweir 	}
543cdf0e10cSrcweir 	pImpXPolygon->nPoints = nPoints;
544cdf0e10cSrcweir }
545cdf0e10cSrcweir 
546cdf0e10cSrcweir /*************************************************************************
547cdf0e10cSrcweir |*
548cdf0e10cSrcweir |*    XPolygon::GetPointCount()
549cdf0e10cSrcweir |*
550cdf0e10cSrcweir |*    Beschreibung
551cdf0e10cSrcweir |*    Ersterstellung    08.11.94
552cdf0e10cSrcweir |*    Letzte Aenderung  12.01.95 ESO
553cdf0e10cSrcweir |*
554cdf0e10cSrcweir *************************************************************************/
555cdf0e10cSrcweir 
GetPointCount() const556cdf0e10cSrcweir sal_uInt16 XPolygon::GetPointCount() const
557cdf0e10cSrcweir {
558cdf0e10cSrcweir 	pImpXPolygon->CheckPointDelete();
559cdf0e10cSrcweir 	return pImpXPolygon->nPoints;
560cdf0e10cSrcweir }
561cdf0e10cSrcweir 
562cdf0e10cSrcweir /*************************************************************************
563cdf0e10cSrcweir |*
564cdf0e10cSrcweir |*    XPolygon::Insert()
565cdf0e10cSrcweir |*
566cdf0e10cSrcweir |*    Beschreibung
567cdf0e10cSrcweir |*    Ersterstellung    08.11.94
568cdf0e10cSrcweir |*    Letzte Aenderung  08.11.94
569cdf0e10cSrcweir |*
570cdf0e10cSrcweir *************************************************************************/
571cdf0e10cSrcweir 
Insert(sal_uInt16 nPos,const Point & rPt,XPolyFlags eFlags)572cdf0e10cSrcweir void XPolygon::Insert( sal_uInt16 nPos, const Point& rPt, XPolyFlags eFlags )
573cdf0e10cSrcweir {
574cdf0e10cSrcweir 	CheckReference();
575cdf0e10cSrcweir 	if (nPos>pImpXPolygon->nPoints) nPos=pImpXPolygon->nPoints;
576cdf0e10cSrcweir 	pImpXPolygon->InsertSpace( nPos, 1 );
577cdf0e10cSrcweir 	pImpXPolygon->pPointAry[nPos] = rPt;
578cdf0e10cSrcweir 	pImpXPolygon->pFlagAry[nPos]  = (sal_uInt8)eFlags;
579cdf0e10cSrcweir }
580cdf0e10cSrcweir 
581cdf0e10cSrcweir /*************************************************************************
582cdf0e10cSrcweir |*
583cdf0e10cSrcweir |*    XPolygon::Insert()
584cdf0e10cSrcweir |*
585cdf0e10cSrcweir |*    Beschreibung
586cdf0e10cSrcweir |*    Ersterstellung    08.11.94
587cdf0e10cSrcweir |*    Letzte Aenderung  08.11.94
588cdf0e10cSrcweir |*
589cdf0e10cSrcweir *************************************************************************/
590cdf0e10cSrcweir 
Insert(sal_uInt16 nPos,const XPolygon & rXPoly)591cdf0e10cSrcweir void XPolygon::Insert( sal_uInt16 nPos, const XPolygon& rXPoly )
592cdf0e10cSrcweir {
593cdf0e10cSrcweir 	CheckReference();
594cdf0e10cSrcweir 	if (nPos>pImpXPolygon->nPoints) nPos=pImpXPolygon->nPoints;
595cdf0e10cSrcweir 
596cdf0e10cSrcweir 	sal_uInt16 nPoints = rXPoly.GetPointCount();
597cdf0e10cSrcweir 
598cdf0e10cSrcweir 	pImpXPolygon->InsertSpace( nPos, nPoints );
599cdf0e10cSrcweir 
600cdf0e10cSrcweir 	memcpy( &(pImpXPolygon->pPointAry[nPos]),
601cdf0e10cSrcweir 			rXPoly.pImpXPolygon->pPointAry,
602cdf0e10cSrcweir 			nPoints*sizeof( Point ) );
603cdf0e10cSrcweir 	memcpy( &(pImpXPolygon->pFlagAry[nPos]),
604cdf0e10cSrcweir 			rXPoly.pImpXPolygon->pFlagAry,
605cdf0e10cSrcweir 			nPoints );
606cdf0e10cSrcweir }
607cdf0e10cSrcweir 
608cdf0e10cSrcweir /*************************************************************************
609cdf0e10cSrcweir |*
610cdf0e10cSrcweir |*    XPolygon::Insert()
611cdf0e10cSrcweir |*
612cdf0e10cSrcweir |*    Beschreibung
613cdf0e10cSrcweir |*    Ersterstellung    08.11.94
614cdf0e10cSrcweir |*    Letzte Aenderung  08.11.94
615cdf0e10cSrcweir |*
616cdf0e10cSrcweir *************************************************************************/
617cdf0e10cSrcweir 
Insert(sal_uInt16 nPos,const Polygon & rPoly)618cdf0e10cSrcweir void XPolygon::Insert( sal_uInt16 nPos, const Polygon& rPoly )
619cdf0e10cSrcweir {
620cdf0e10cSrcweir 	CheckReference();
621cdf0e10cSrcweir 	if (nPos>pImpXPolygon->nPoints) nPos=pImpXPolygon->nPoints;
622cdf0e10cSrcweir 
623cdf0e10cSrcweir 	sal_uInt16 nPoints = rPoly.GetSize();
624cdf0e10cSrcweir 
625cdf0e10cSrcweir 	pImpXPolygon->InsertSpace( nPos, nPoints );
626cdf0e10cSrcweir 
627cdf0e10cSrcweir 	sal_uInt16 i;
628cdf0e10cSrcweir 	for( i=0; i < nPoints; i++ )
629cdf0e10cSrcweir 		pImpXPolygon->pPointAry[i] = rPoly[i];
630cdf0e10cSrcweir 
631cdf0e10cSrcweir 	// Die Flags sind durch das InsertSpace bereits auf 0 gesetzt
632cdf0e10cSrcweir }
633cdf0e10cSrcweir 
634cdf0e10cSrcweir /*************************************************************************
635cdf0e10cSrcweir |*
636cdf0e10cSrcweir |*    XPolygon::Remove()
637cdf0e10cSrcweir |*
638cdf0e10cSrcweir |*    Beschreibung
639cdf0e10cSrcweir |*    Ersterstellung    08.11.94
640cdf0e10cSrcweir |*    Letzte Aenderung  08.11.94
641cdf0e10cSrcweir |*
642cdf0e10cSrcweir *************************************************************************/
643cdf0e10cSrcweir 
Remove(sal_uInt16 nPos,sal_uInt16 nCount)644cdf0e10cSrcweir void XPolygon::Remove( sal_uInt16 nPos, sal_uInt16 nCount )
645cdf0e10cSrcweir {
646cdf0e10cSrcweir 	CheckReference();
647cdf0e10cSrcweir 	pImpXPolygon->Remove( nPos, nCount );
648cdf0e10cSrcweir }
649cdf0e10cSrcweir 
650cdf0e10cSrcweir /*************************************************************************
651cdf0e10cSrcweir |*
652cdf0e10cSrcweir |*    XPolygon::Move()
653cdf0e10cSrcweir |*
654cdf0e10cSrcweir |*    Beschreibung
655cdf0e10cSrcweir |*    Ersterstellung    09.11.94
656cdf0e10cSrcweir |*    Letzte Aenderung  09.11.94
657cdf0e10cSrcweir |*
658cdf0e10cSrcweir *************************************************************************/
659cdf0e10cSrcweir 
Move(long nHorzMove,long nVertMove)660cdf0e10cSrcweir void XPolygon::Move( long nHorzMove, long nVertMove )
661cdf0e10cSrcweir {
662cdf0e10cSrcweir 	if ( !nHorzMove && !nVertMove )
663cdf0e10cSrcweir 		return;
664cdf0e10cSrcweir 
665cdf0e10cSrcweir 	CheckReference();
666cdf0e10cSrcweir 
667cdf0e10cSrcweir 	// Punkte verschieben
668cdf0e10cSrcweir 	sal_uInt16 nCount = pImpXPolygon->nPoints;
669cdf0e10cSrcweir 	for ( sal_uInt16 i = 0; i < nCount; i++ )
670cdf0e10cSrcweir 	{
671cdf0e10cSrcweir 		Point* pPt = &(pImpXPolygon->pPointAry[i]);
672cdf0e10cSrcweir 		pPt->X() += nHorzMove;
673cdf0e10cSrcweir 		pPt->Y() += nVertMove;
674cdf0e10cSrcweir 	}
675cdf0e10cSrcweir }
676cdf0e10cSrcweir 
677cdf0e10cSrcweir /*************************************************************************
678cdf0e10cSrcweir |*
679cdf0e10cSrcweir |*    XPolygon::GetBoundRect()
680cdf0e10cSrcweir |*
681cdf0e10cSrcweir |*    Beschreibung
682cdf0e10cSrcweir |*    Ersterstellung    09.11.94
683cdf0e10cSrcweir |*    Letzte Aenderung  12.01.95 ESO
684cdf0e10cSrcweir |*
685cdf0e10cSrcweir *************************************************************************/
686cdf0e10cSrcweir 
GetBoundRect() const687cdf0e10cSrcweir Rectangle XPolygon::GetBoundRect() const
688cdf0e10cSrcweir {
689cdf0e10cSrcweir 	pImpXPolygon->CheckPointDelete();
690cdf0e10cSrcweir 	Rectangle aRetval;
691cdf0e10cSrcweir 
692cdf0e10cSrcweir 	if(pImpXPolygon->nPoints)
693cdf0e10cSrcweir 	{
694cdf0e10cSrcweir 		// #i37709#
695cdf0e10cSrcweir 		// For historical reasons the control points are not part of the
696cdf0e10cSrcweir 		// BoundRect. This makes it necessary to subdivide the polygon to
697cdf0e10cSrcweir 		// get a relatively correct BoundRect. Numerically, this is not
698cdf0e10cSrcweir 		// correct and never was.
699cdf0e10cSrcweir 
700cdf0e10cSrcweir 		const basegfx::B2DRange aPolygonRange(basegfx::tools::getRange(getB2DPolygon()));
701cdf0e10cSrcweir 		aRetval = Rectangle(
702cdf0e10cSrcweir 			FRound(aPolygonRange.getMinX()), FRound(aPolygonRange.getMinY()),
703cdf0e10cSrcweir 			FRound(aPolygonRange.getMaxX()), FRound(aPolygonRange.getMaxY()));
704cdf0e10cSrcweir 	}
705cdf0e10cSrcweir 
706cdf0e10cSrcweir 	return aRetval;
707cdf0e10cSrcweir }
708cdf0e10cSrcweir 
709cdf0e10cSrcweir /*************************************************************************
710cdf0e10cSrcweir |*
711cdf0e10cSrcweir |*    XPolygon::operator[]()
712cdf0e10cSrcweir |*
713cdf0e10cSrcweir |*    Beschreibung
714cdf0e10cSrcweir |*    Ersterstellung    08.11.94
715cdf0e10cSrcweir |*    Letzte Aenderung  12.01.95
716cdf0e10cSrcweir |*
717cdf0e10cSrcweir *************************************************************************/
718cdf0e10cSrcweir 
operator [](sal_uInt16 nPos) const719cdf0e10cSrcweir const Point& XPolygon::operator[]( sal_uInt16 nPos ) const
720cdf0e10cSrcweir {
721cdf0e10cSrcweir 	DBG_ASSERT(nPos < pImpXPolygon->nPoints, "Ungueltiger Index bei const-Arrayzugriff auf XPolygon");
722cdf0e10cSrcweir 
723cdf0e10cSrcweir 	pImpXPolygon->CheckPointDelete();
724cdf0e10cSrcweir 	return pImpXPolygon->pPointAry[nPos];
725cdf0e10cSrcweir }
726cdf0e10cSrcweir 
727cdf0e10cSrcweir /*************************************************************************
728cdf0e10cSrcweir |*
729cdf0e10cSrcweir |*    XPolygon::operator[]()
730cdf0e10cSrcweir |*
731cdf0e10cSrcweir |*    Beschreibung
732cdf0e10cSrcweir |*    Ersterstellung    08.11.94
733cdf0e10cSrcweir |*    Letzte Aenderung  12.01.95 ESO
734cdf0e10cSrcweir |*
735cdf0e10cSrcweir *************************************************************************/
736cdf0e10cSrcweir 
operator [](sal_uInt16 nPos)737cdf0e10cSrcweir Point& XPolygon::operator[]( sal_uInt16 nPos )
738cdf0e10cSrcweir {
739cdf0e10cSrcweir 	pImpXPolygon->CheckPointDelete();
740cdf0e10cSrcweir 	CheckReference();
741cdf0e10cSrcweir 
742cdf0e10cSrcweir 	if( nPos >= pImpXPolygon->nSize )
743cdf0e10cSrcweir 	{
744cdf0e10cSrcweir 		DBG_ASSERT(pImpXPolygon->nResize, "Ungueltiger Index bei Arrayzugriff auf XPolygon");
745cdf0e10cSrcweir 		pImpXPolygon->Resize(nPos + 1, sal_False);
746cdf0e10cSrcweir 	}
747cdf0e10cSrcweir 	if( nPos >= pImpXPolygon->nPoints )
748cdf0e10cSrcweir 		pImpXPolygon->nPoints = nPos + 1;
749cdf0e10cSrcweir 
750cdf0e10cSrcweir 	return pImpXPolygon->pPointAry[nPos];
751cdf0e10cSrcweir }
752cdf0e10cSrcweir 
753cdf0e10cSrcweir /*************************************************************************
754cdf0e10cSrcweir |*
755cdf0e10cSrcweir |*    XPolygon::operator=()
756cdf0e10cSrcweir |*
757cdf0e10cSrcweir |*    Beschreibung      Zuweisungsoperator
758cdf0e10cSrcweir |*    Ersterstellung    ESO 22.11.94
759cdf0e10cSrcweir |*    Letzte Aenderung  ESO 12.01.95
760cdf0e10cSrcweir |*
761cdf0e10cSrcweir *************************************************************************/
762cdf0e10cSrcweir 
operator =(const XPolygon & rXPoly)763cdf0e10cSrcweir XPolygon& XPolygon::operator=( const XPolygon& rXPoly )
764cdf0e10cSrcweir {
765cdf0e10cSrcweir 	pImpXPolygon->CheckPointDelete();
766cdf0e10cSrcweir 
767cdf0e10cSrcweir 	rXPoly.pImpXPolygon->nRefCount++;
768cdf0e10cSrcweir 
769cdf0e10cSrcweir 	if( pImpXPolygon->nRefCount > 1 )
770cdf0e10cSrcweir 		pImpXPolygon->nRefCount--;
771cdf0e10cSrcweir 	else
772cdf0e10cSrcweir 		delete pImpXPolygon;
773cdf0e10cSrcweir 
774cdf0e10cSrcweir 	pImpXPolygon = rXPoly.pImpXPolygon;
775cdf0e10cSrcweir 	return *this;
776cdf0e10cSrcweir }
777cdf0e10cSrcweir 
778cdf0e10cSrcweir /*************************************************************************
779cdf0e10cSrcweir |*
780cdf0e10cSrcweir |*    XPolygon::operator==()
781cdf0e10cSrcweir |*
782cdf0e10cSrcweir |*    Beschreibung      Gleichheitsoperator
783cdf0e10cSrcweir |*    Ersterstellung    ESO 22.11.94
784cdf0e10cSrcweir |*    Letzte Aenderung  Joe 26.09.95
785cdf0e10cSrcweir |*
786cdf0e10cSrcweir *************************************************************************/
787cdf0e10cSrcweir 
operator ==(const XPolygon & rXPoly) const788cdf0e10cSrcweir sal_Bool XPolygon::operator==( const XPolygon& rXPoly ) const
789cdf0e10cSrcweir {
790cdf0e10cSrcweir 	pImpXPolygon->CheckPointDelete();
791cdf0e10cSrcweir 	if (rXPoly.pImpXPolygon==pImpXPolygon) return sal_True;
792cdf0e10cSrcweir 	return *rXPoly.pImpXPolygon == *pImpXPolygon;
793cdf0e10cSrcweir }
794cdf0e10cSrcweir 
795cdf0e10cSrcweir /*************************************************************************
796cdf0e10cSrcweir |*
797cdf0e10cSrcweir |*    XPolygon::operator!=()
798cdf0e10cSrcweir |*
799cdf0e10cSrcweir |*    Beschreibung      Ungleichheitsoperator
800cdf0e10cSrcweir |*    Ersterstellung    ESO 22.11.94
801cdf0e10cSrcweir |*    Letzte Aenderung  Joe 26.09.95
802cdf0e10cSrcweir |*
803cdf0e10cSrcweir *************************************************************************/
804cdf0e10cSrcweir 
operator !=(const XPolygon & rXPoly) const805cdf0e10cSrcweir sal_Bool XPolygon::operator!=( const XPolygon& rXPoly ) const
806cdf0e10cSrcweir {
807cdf0e10cSrcweir 	pImpXPolygon->CheckPointDelete();
808cdf0e10cSrcweir 	if (rXPoly.pImpXPolygon==pImpXPolygon) return sal_False;
809cdf0e10cSrcweir 	return *rXPoly.pImpXPolygon != *pImpXPolygon;
810cdf0e10cSrcweir }
811cdf0e10cSrcweir 
812cdf0e10cSrcweir /*************************************************************************
813cdf0e10cSrcweir |*
814cdf0e10cSrcweir |*    XPolygon::GetFlags()
815cdf0e10cSrcweir |*
816cdf0e10cSrcweir |*    Flags fuer den Punkt an der Position nPos zurueckgeben
817cdf0e10cSrcweir |*    Ersterstellung    ESO 11.11.94
818cdf0e10cSrcweir |*    Letzte Aenderung  ESO 12.01.95
819cdf0e10cSrcweir |*
820cdf0e10cSrcweir *************************************************************************/
821cdf0e10cSrcweir 
GetFlags(sal_uInt16 nPos) const822cdf0e10cSrcweir XPolyFlags XPolygon::GetFlags( sal_uInt16 nPos ) const
823cdf0e10cSrcweir {
824cdf0e10cSrcweir 	pImpXPolygon->CheckPointDelete();
825cdf0e10cSrcweir 	return (XPolyFlags) pImpXPolygon->pFlagAry[nPos];
826cdf0e10cSrcweir }
827cdf0e10cSrcweir 
828cdf0e10cSrcweir /*************************************************************************
829cdf0e10cSrcweir |*
830cdf0e10cSrcweir |*    XPolygon::SetFlags()
831cdf0e10cSrcweir |*
832cdf0e10cSrcweir |*    Flags fuer den Punkt an der Position nPos setzen
833cdf0e10cSrcweir |*    Ersterstellung    ESO 11.11.94
834cdf0e10cSrcweir |*    Letzte Aenderung  ESO 12.01.95
835cdf0e10cSrcweir |*
836cdf0e10cSrcweir *************************************************************************/
837cdf0e10cSrcweir 
SetFlags(sal_uInt16 nPos,XPolyFlags eFlags)838cdf0e10cSrcweir void XPolygon::SetFlags( sal_uInt16 nPos, XPolyFlags eFlags )
839cdf0e10cSrcweir {
840cdf0e10cSrcweir 	pImpXPolygon->CheckPointDelete();
841cdf0e10cSrcweir 	CheckReference();
842cdf0e10cSrcweir 	pImpXPolygon->pFlagAry[nPos] = (sal_uInt8) eFlags;
843cdf0e10cSrcweir }
844cdf0e10cSrcweir 
845cdf0e10cSrcweir /*************************************************************************
846cdf0e10cSrcweir |*
847cdf0e10cSrcweir |*    XPolygon::IsControl()
848cdf0e10cSrcweir |*
849cdf0e10cSrcweir |*    Kurzform zur Abfrage des CONTROL-Flags
850cdf0e10cSrcweir |*    Ersterstellung    ESO 09.01.95
851cdf0e10cSrcweir |*    Letzte Aenderung  ESO 12.01.95
852cdf0e10cSrcweir |*
853cdf0e10cSrcweir *************************************************************************/
854cdf0e10cSrcweir 
IsControl(sal_uInt16 nPos) const855cdf0e10cSrcweir sal_Bool XPolygon::IsControl(sal_uInt16 nPos) const
856cdf0e10cSrcweir {
857cdf0e10cSrcweir 	return ( (XPolyFlags) pImpXPolygon->pFlagAry[nPos] == XPOLY_CONTROL );
858cdf0e10cSrcweir }
859cdf0e10cSrcweir 
860cdf0e10cSrcweir /*************************************************************************
861cdf0e10cSrcweir |*
862cdf0e10cSrcweir |*    XPolygon::IsSmooth()
863cdf0e10cSrcweir |*
864cdf0e10cSrcweir |*    Kurzform zur Abfrage von SMOOTH- und SYMMTR-Flag
865cdf0e10cSrcweir |*    Ersterstellung    ESO 18.04.95
866cdf0e10cSrcweir |*    Letzte Aenderung  ESO 18.04.95
867cdf0e10cSrcweir |*
868cdf0e10cSrcweir *************************************************************************/
869cdf0e10cSrcweir 
IsSmooth(sal_uInt16 nPos) const870cdf0e10cSrcweir sal_Bool XPolygon::IsSmooth(sal_uInt16 nPos) const
871cdf0e10cSrcweir {
872cdf0e10cSrcweir 	XPolyFlags eFlag = (XPolyFlags) pImpXPolygon->pFlagAry[nPos];
873cdf0e10cSrcweir 	return ( eFlag == XPOLY_SMOOTH || eFlag == XPOLY_SYMMTR );
874cdf0e10cSrcweir }
875cdf0e10cSrcweir 
876cdf0e10cSrcweir /*************************************************************************
877cdf0e10cSrcweir |*
878cdf0e10cSrcweir |*    XPolygon::CalcDistance()
879cdf0e10cSrcweir |*
880cdf0e10cSrcweir |*    Abstand zwischen zwei Punkten berechnen
881cdf0e10cSrcweir |*    Ersterstellung    ESO 09.01.95
882cdf0e10cSrcweir |*    Letzte Aenderung  ESO 09.01.95
883cdf0e10cSrcweir |*
884cdf0e10cSrcweir *************************************************************************/
885cdf0e10cSrcweir 
CalcDistance(sal_uInt16 nP1,sal_uInt16 nP2)886cdf0e10cSrcweir double XPolygon::CalcDistance(sal_uInt16 nP1, sal_uInt16 nP2)
887cdf0e10cSrcweir {
888cdf0e10cSrcweir 	const Point& rP1 = pImpXPolygon->pPointAry[nP1];
889cdf0e10cSrcweir 	const Point& rP2 = pImpXPolygon->pPointAry[nP2];
890cdf0e10cSrcweir 	double fDx = rP2.X() - rP1.X();
891cdf0e10cSrcweir 	double fDy = rP2.Y() - rP1.Y();
892cdf0e10cSrcweir 	return sqrt(fDx * fDx + fDy * fDy);
893cdf0e10cSrcweir }
894cdf0e10cSrcweir 
895cdf0e10cSrcweir /*************************************************************************
896cdf0e10cSrcweir |*
897cdf0e10cSrcweir |*    XPolygon::SubdivideBezier()
898cdf0e10cSrcweir |*
899cdf0e10cSrcweir |*    Bezierkurve unterteilen
900cdf0e10cSrcweir |*    Ersterstellung    ESO 09.01.95
901cdf0e10cSrcweir |*    Letzte Aenderung  ESO 09.01.95
902cdf0e10cSrcweir |*
903cdf0e10cSrcweir *************************************************************************/
904cdf0e10cSrcweir 
SubdivideBezier(sal_uInt16 nPos,sal_Bool bCalcFirst,double fT)905cdf0e10cSrcweir void XPolygon::SubdivideBezier(sal_uInt16 nPos, sal_Bool bCalcFirst, double fT)
906cdf0e10cSrcweir {
907cdf0e10cSrcweir 	Point*  pPoints = pImpXPolygon->pPointAry;
908cdf0e10cSrcweir 	double  fT2 = fT * fT;
909cdf0e10cSrcweir 	double  fT3 = fT * fT2;
910cdf0e10cSrcweir 	double  fU = 1.0 - fT;
911cdf0e10cSrcweir 	double  fU2 = fU * fU;
912cdf0e10cSrcweir 	double  fU3 = fU * fU2;
913cdf0e10cSrcweir 	sal_uInt16  nIdx = nPos;
914cdf0e10cSrcweir 	short   nPosInc, nIdxInc;
915cdf0e10cSrcweir 
916cdf0e10cSrcweir 	if ( bCalcFirst )
917cdf0e10cSrcweir 	{
918cdf0e10cSrcweir 		nPos += 3;
919cdf0e10cSrcweir 		nPosInc = -1;
920cdf0e10cSrcweir 		nIdxInc = 0;
921cdf0e10cSrcweir 	}
922cdf0e10cSrcweir 	else
923cdf0e10cSrcweir 	{
924cdf0e10cSrcweir 		nPosInc = 1;
925cdf0e10cSrcweir 		nIdxInc = 1;
926cdf0e10cSrcweir 	}
927cdf0e10cSrcweir 	pPoints[nPos].X() = (long) (fU3 *       pPoints[nIdx  ].X() +
928cdf0e10cSrcweir 								fT  * fU2 * pPoints[nIdx+1].X() * 3 +
929cdf0e10cSrcweir 								fT2 * fU  * pPoints[nIdx+2].X() * 3 +
930cdf0e10cSrcweir 								fT3 *       pPoints[nIdx+3].X());
931cdf0e10cSrcweir 	pPoints[nPos].Y() = (long) (fU3 *       pPoints[nIdx  ].Y() +
932cdf0e10cSrcweir 								fT  * fU2 * pPoints[nIdx+1].Y() * 3 +
933cdf0e10cSrcweir 								fT2 * fU  * pPoints[nIdx+2].Y() * 3 +
934cdf0e10cSrcweir 								fT3 *       pPoints[nIdx+3].Y());
935cdf0e10cSrcweir 	nPos = nPos + nPosInc;
936cdf0e10cSrcweir 	nIdx = nIdx + nIdxInc;
937cdf0e10cSrcweir 	pPoints[nPos].X() = (long) (fU2 *       pPoints[nIdx  ].X() +
938cdf0e10cSrcweir 								fT  * fU *  pPoints[nIdx+1].X() * 2 +
939cdf0e10cSrcweir 								fT2 *       pPoints[nIdx+2].X());
940cdf0e10cSrcweir 	pPoints[nPos].Y() = (long) (fU2 *       pPoints[nIdx  ].Y() +
941cdf0e10cSrcweir 								fT  * fU *  pPoints[nIdx+1].Y() * 2 +
942cdf0e10cSrcweir 								fT2 *       pPoints[nIdx+2].Y());
943cdf0e10cSrcweir 	nPos = nPos + nPosInc;
944cdf0e10cSrcweir 	nIdx = nIdx + nIdxInc;
945cdf0e10cSrcweir 	pPoints[nPos].X() = (long) (fU * pPoints[nIdx  ].X() +
946cdf0e10cSrcweir 								fT * pPoints[nIdx+1].X());
947cdf0e10cSrcweir 	pPoints[nPos].Y() = (long) (fU * pPoints[nIdx  ].Y() +
948cdf0e10cSrcweir 								fT * pPoints[nIdx+1].Y());
949cdf0e10cSrcweir }
950cdf0e10cSrcweir 
951cdf0e10cSrcweir /************************************************************************/
952cdf0e10cSrcweir 
GenBezArc(const Point & rCenter,long nRx,long nRy,long nXHdl,long nYHdl,sal_uInt16 nStart,sal_uInt16 nEnd,sal_uInt16 nQuad,sal_uInt16 nFirst)953cdf0e10cSrcweir void XPolygon::GenBezArc(const Point& rCenter, long nRx, long nRy,
954cdf0e10cSrcweir 						 long nXHdl, long nYHdl, sal_uInt16 nStart, sal_uInt16 nEnd,
955cdf0e10cSrcweir 						 sal_uInt16 nQuad, sal_uInt16 nFirst)
956cdf0e10cSrcweir {
957cdf0e10cSrcweir 	Point* pPoints = pImpXPolygon->pPointAry;
958cdf0e10cSrcweir 	pPoints[nFirst  ] = rCenter;
959cdf0e10cSrcweir 	pPoints[nFirst+3] = rCenter;
960cdf0e10cSrcweir 
961cdf0e10cSrcweir 	if ( nQuad == 1 || nQuad == 2 )
962cdf0e10cSrcweir 	{
963cdf0e10cSrcweir 		nRx   = -nRx; nXHdl = -nXHdl;
964cdf0e10cSrcweir 	}
965cdf0e10cSrcweir 	if ( nQuad == 0 || nQuad == 1 )
966cdf0e10cSrcweir 	{
967cdf0e10cSrcweir 		nRy   = -nRy; nYHdl = -nYHdl;
968cdf0e10cSrcweir 	}
969cdf0e10cSrcweir 
970cdf0e10cSrcweir 	if ( nQuad == 0 || nQuad == 2 )
971cdf0e10cSrcweir 	{
972cdf0e10cSrcweir 		pPoints[nFirst].X() += nRx; pPoints[nFirst+3].Y() += nRy;
973cdf0e10cSrcweir 	}
974cdf0e10cSrcweir 	else
975cdf0e10cSrcweir 	{
976cdf0e10cSrcweir 		pPoints[nFirst].Y() += nRy; pPoints[nFirst+3].X() += nRx;
977cdf0e10cSrcweir 	}
978cdf0e10cSrcweir 	pPoints[nFirst+1] = pPoints[nFirst];
979cdf0e10cSrcweir 	pPoints[nFirst+2] = pPoints[nFirst+3];
980cdf0e10cSrcweir 
981cdf0e10cSrcweir 	if ( nQuad == 0 || nQuad == 2 )
982cdf0e10cSrcweir 	{
983cdf0e10cSrcweir 		pPoints[nFirst+1].Y() += nYHdl; pPoints[nFirst+2].X() += nXHdl;
984cdf0e10cSrcweir 	}
985cdf0e10cSrcweir 	else
986cdf0e10cSrcweir 	{
987cdf0e10cSrcweir 		pPoints[nFirst+1].X() += nXHdl; pPoints[nFirst+2].Y() += nYHdl;
988cdf0e10cSrcweir 	}
989cdf0e10cSrcweir 	if ( nStart > 0 )
990cdf0e10cSrcweir 		SubdivideBezier(nFirst, sal_False, (double)nStart / 900);
991cdf0e10cSrcweir 	if ( nEnd < 900 )
992cdf0e10cSrcweir 		SubdivideBezier(nFirst, sal_True, (double)(nEnd-nStart) / (900-nStart));
993cdf0e10cSrcweir 	SetFlags(nFirst+1, XPOLY_CONTROL);
994cdf0e10cSrcweir 	SetFlags(nFirst+2, XPOLY_CONTROL);
995cdf0e10cSrcweir }
996cdf0e10cSrcweir 
997cdf0e10cSrcweir /************************************************************************/
998cdf0e10cSrcweir 
CheckAngles(sal_uInt16 & nStart,sal_uInt16 nEnd,sal_uInt16 & nA1,sal_uInt16 & nA2)999cdf0e10cSrcweir sal_Bool XPolygon::CheckAngles(sal_uInt16& nStart, sal_uInt16 nEnd, sal_uInt16& nA1, sal_uInt16& nA2)
1000cdf0e10cSrcweir {
1001cdf0e10cSrcweir 	if ( nStart == 3600 ) nStart = 0;
1002cdf0e10cSrcweir 	if ( nEnd == 0 ) nEnd = 3600;
1003cdf0e10cSrcweir 	sal_uInt16 nStPrev = nStart;
1004cdf0e10cSrcweir 	sal_uInt16 nMax = (nStart / 900 + 1) * 900;
1005cdf0e10cSrcweir 	sal_uInt16 nMin = nMax - 900;
1006cdf0e10cSrcweir 
1007cdf0e10cSrcweir 	if ( nEnd >= nMax || nEnd <= nStart )   nA2 = 900;
1008cdf0e10cSrcweir 	else                                    nA2 = nEnd - nMin;
1009cdf0e10cSrcweir 	nA1 = nStart - nMin;
1010cdf0e10cSrcweir 	nStart = nMax;
1011cdf0e10cSrcweir 
1012cdf0e10cSrcweir 	// sal_True zurueck, falls letztes Segment berechnet wurde
1013cdf0e10cSrcweir 	return (nStPrev < nEnd && nStart >= nEnd);
1014cdf0e10cSrcweir }
1015cdf0e10cSrcweir 
1016cdf0e10cSrcweir /*************************************************************************
1017cdf0e10cSrcweir |*
1018cdf0e10cSrcweir |*    XPolygon::CalcSmoothJoin()
1019cdf0e10cSrcweir |*
1020cdf0e10cSrcweir |*    glatten Uebergang zu einer Bezierkurve berechnen, indem der
1021cdf0e10cSrcweir |*    entsprechende Punkt auf die Verbindungslinie von zwei anderen
1022cdf0e10cSrcweir |*    Punkten projiziert wird
1023cdf0e10cSrcweir |*     Center = End- bzw. Anfangspunkt der Bezierkurve
1024cdf0e10cSrcweir |*     Drag   = der bewegte Punkt, der die Verschiebung von Pnt vorgibt
1025cdf0e10cSrcweir |*     Pnt    = der zu modifizierende Punkt
1026cdf0e10cSrcweir |*    Wenn Center am Anfang bzw. Ende des Polygons liegt, wird Pnt
1027cdf0e10cSrcweir |*    auf die entgegengesetzte Seite verlegt
1028cdf0e10cSrcweir |*    Ersterstellung    ESO 09.01.95
1029cdf0e10cSrcweir |*    Letzte Aenderung  ESO 18.04.95
1030cdf0e10cSrcweir |*
1031cdf0e10cSrcweir \************************************************************************/
1032cdf0e10cSrcweir 
CalcSmoothJoin(sal_uInt16 nCenter,sal_uInt16 nDrag,sal_uInt16 nPnt)1033cdf0e10cSrcweir void XPolygon::CalcSmoothJoin(sal_uInt16 nCenter, sal_uInt16 nDrag, sal_uInt16 nPnt)
1034cdf0e10cSrcweir {
1035cdf0e10cSrcweir 	CheckReference();
1036cdf0e10cSrcweir 
1037cdf0e10cSrcweir //	sal_uInt16  nMaxPnt = pImpXPolygon->nPoints - 1;
1038cdf0e10cSrcweir 
1039cdf0e10cSrcweir //  if ( nCenter == nMaxPnt )   nPnt = 1;
1040cdf0e10cSrcweir //  else if ( nCenter == 0 )    nPnt = nMaxPnt - 1;
1041cdf0e10cSrcweir 
1042cdf0e10cSrcweir 	// Wenn nPnt kein Control-Punkt, d.h. nicht verschiebbar, dann
1043cdf0e10cSrcweir 	// statt dessen nDrag auf der Achse nCenter-nPnt verschieben
1044cdf0e10cSrcweir 	if ( !IsControl(nPnt) )
1045cdf0e10cSrcweir 	{
1046cdf0e10cSrcweir 		sal_uInt16 nTmp = nDrag;
1047cdf0e10cSrcweir 		nDrag = nPnt;
1048cdf0e10cSrcweir 		nPnt = nTmp;
1049cdf0e10cSrcweir 	}
1050cdf0e10cSrcweir 	Point*  pPoints = pImpXPolygon->pPointAry;
1051cdf0e10cSrcweir 	Point   aDiff   = pPoints[nDrag] - pPoints[nCenter];
1052cdf0e10cSrcweir 	double  fDiv    = CalcDistance(nCenter, nDrag);
1053cdf0e10cSrcweir 
1054cdf0e10cSrcweir 	if ( fDiv )
1055cdf0e10cSrcweir 	{
1056cdf0e10cSrcweir 		double fRatio = CalcDistance(nCenter, nPnt) / fDiv;
1057cdf0e10cSrcweir 		// bei SMOOTH bisherige Laenge beibehalten
1058cdf0e10cSrcweir 		if ( GetFlags(nCenter) == XPOLY_SMOOTH || !IsControl(nDrag) )
1059cdf0e10cSrcweir 		{
1060cdf0e10cSrcweir 			aDiff.X() = (long) (fRatio * aDiff.X());
1061cdf0e10cSrcweir 			aDiff.Y() = (long) (fRatio * aDiff.Y());
1062cdf0e10cSrcweir 		}
1063cdf0e10cSrcweir 		pPoints[nPnt] = pPoints[nCenter] - aDiff;
1064cdf0e10cSrcweir 	}
1065cdf0e10cSrcweir }
1066cdf0e10cSrcweir 
1067cdf0e10cSrcweir /*************************************************************************
1068cdf0e10cSrcweir |*
1069cdf0e10cSrcweir |*    XPolygon::CalcTangent()
1070cdf0e10cSrcweir |*
1071cdf0e10cSrcweir |*    Tangente fuer den Uebergang zwischen zwei Bezierkurven berechnen
1072cdf0e10cSrcweir |*     Center = End- bzw. Anfangspunkt der Bezierkurven
1073cdf0e10cSrcweir |*     Prev   = vorheriger Zugpunkt
1074cdf0e10cSrcweir |*     Next   = naechster Zugpunkt
1075cdf0e10cSrcweir |*    Ersterstellung    ESO 09.01.95
1076cdf0e10cSrcweir |*    Letzte Aenderung  ESO 18.04.95
1077cdf0e10cSrcweir |*
1078cdf0e10cSrcweir \************************************************************************/
1079cdf0e10cSrcweir 
CalcTangent(sal_uInt16 nCenter,sal_uInt16 nPrev,sal_uInt16 nNext)1080cdf0e10cSrcweir void XPolygon::CalcTangent(sal_uInt16 nCenter, sal_uInt16 nPrev, sal_uInt16 nNext)
1081cdf0e10cSrcweir {
1082cdf0e10cSrcweir 	CheckReference();
1083cdf0e10cSrcweir 
1084cdf0e10cSrcweir 	double fAbsLen = CalcDistance(nNext, nPrev);
1085cdf0e10cSrcweir 
1086cdf0e10cSrcweir 	if ( fAbsLen )
1087cdf0e10cSrcweir 	{
1088cdf0e10cSrcweir 		const Point& rCenter = pImpXPolygon->pPointAry[nCenter];
1089cdf0e10cSrcweir 		Point&  rNext = pImpXPolygon->pPointAry[nNext];
1090cdf0e10cSrcweir 		Point&  rPrev = pImpXPolygon->pPointAry[nPrev];
1091cdf0e10cSrcweir 		Point   aDiff = rNext - rPrev;
1092cdf0e10cSrcweir 		double  fNextLen = CalcDistance(nCenter, nNext) / fAbsLen;
1093cdf0e10cSrcweir 		double  fPrevLen = CalcDistance(nCenter, nPrev) / fAbsLen;
1094cdf0e10cSrcweir 
1095cdf0e10cSrcweir 		// bei SYMMTR gleiche Laenge fuer beide Seiten
1096cdf0e10cSrcweir 		if ( GetFlags(nCenter) == XPOLY_SYMMTR )
1097cdf0e10cSrcweir 		{
1098cdf0e10cSrcweir 			fPrevLen = (fNextLen + fPrevLen) / 2;
1099cdf0e10cSrcweir 			fNextLen = fPrevLen;
1100cdf0e10cSrcweir 		}
1101cdf0e10cSrcweir 		rNext.X() = rCenter.X() + (long) (fNextLen * aDiff.X());
1102cdf0e10cSrcweir 		rNext.Y() = rCenter.Y() + (long) (fNextLen * aDiff.Y());
1103cdf0e10cSrcweir 		rPrev.X() = rCenter.X() - (long) (fPrevLen * aDiff.X());
1104cdf0e10cSrcweir 		rPrev.Y() = rCenter.Y() - (long) (fPrevLen * aDiff.Y());
1105cdf0e10cSrcweir 	}
1106cdf0e10cSrcweir }
1107cdf0e10cSrcweir 
1108cdf0e10cSrcweir /*************************************************************************
1109cdf0e10cSrcweir |*
1110cdf0e10cSrcweir |*    XPolygon::PointsToBezier()
1111cdf0e10cSrcweir |*
1112cdf0e10cSrcweir |*    wandelt vier Polygonpunkte in eine Bezierkurve durch diese Punkte um
1113cdf0e10cSrcweir |*    Ersterstellung    ESO 09.01.95
1114cdf0e10cSrcweir |*    Letzte Aenderung  ESO 09.01.95
1115cdf0e10cSrcweir |*
1116cdf0e10cSrcweir \************************************************************************/
1117cdf0e10cSrcweir 
PointsToBezier(sal_uInt16 nFirst)1118cdf0e10cSrcweir void XPolygon::PointsToBezier(sal_uInt16 nFirst)
1119cdf0e10cSrcweir {
1120cdf0e10cSrcweir 	double  nFullLength, nPart1Length, nPart2Length;
1121cdf0e10cSrcweir 	double  fX0, fY0, fX1, fY1, fX2, fY2, fX3, fY3;
1122cdf0e10cSrcweir 	double  fTx1, fTx2, fTy1, fTy2;
1123cdf0e10cSrcweir 	double  fT1, fU1, fT2, fU2, fV;
1124cdf0e10cSrcweir 	Point*  pPoints = pImpXPolygon->pPointAry;
1125cdf0e10cSrcweir 
1126cdf0e10cSrcweir 	if ( nFirst > pImpXPolygon->nPoints - 4 || IsControl(nFirst) ||
1127cdf0e10cSrcweir 		 IsControl(nFirst+1) || IsControl(nFirst+2) || IsControl(nFirst+3) )
1128cdf0e10cSrcweir 		return;
1129cdf0e10cSrcweir 
1130cdf0e10cSrcweir 	CheckReference();
1131cdf0e10cSrcweir 
1132cdf0e10cSrcweir 	fTx1 = pPoints[nFirst+1].X();
1133cdf0e10cSrcweir 	fTy1 = pPoints[nFirst+1].Y();
1134cdf0e10cSrcweir 	fTx2 = pPoints[nFirst+2].X();
1135cdf0e10cSrcweir 	fTy2 = pPoints[nFirst+2].Y();
1136cdf0e10cSrcweir 	fX0  = pPoints[nFirst  ].X();
1137cdf0e10cSrcweir 	fY0  = pPoints[nFirst  ].Y();
1138cdf0e10cSrcweir 	fX3  = pPoints[nFirst+3].X();
1139cdf0e10cSrcweir 	fY3  = pPoints[nFirst+3].Y();
1140cdf0e10cSrcweir 
1141cdf0e10cSrcweir 	nPart1Length = CalcDistance(nFirst, nFirst+1);
1142cdf0e10cSrcweir 	nPart2Length = nPart1Length + CalcDistance(nFirst+1, nFirst+2);
1143cdf0e10cSrcweir 	nFullLength  = nPart2Length + CalcDistance(nFirst+2, nFirst+3);
1144cdf0e10cSrcweir 	if ( nFullLength < 20 )
1145cdf0e10cSrcweir 		return;
1146cdf0e10cSrcweir 
1147cdf0e10cSrcweir 	if ( nPart2Length == nFullLength )
1148cdf0e10cSrcweir 		nPart2Length -= 1;
1149cdf0e10cSrcweir 	if ( nPart1Length == nFullLength )
1150cdf0e10cSrcweir 		nPart1Length = nPart2Length - 1;
1151cdf0e10cSrcweir 	if ( nPart1Length <= 0 )
1152cdf0e10cSrcweir 		nPart1Length = 1;
1153cdf0e10cSrcweir 	if ( nPart2Length <= 0 || nPart2Length == nPart1Length )
1154cdf0e10cSrcweir 		nPart2Length = nPart1Length + 1;
1155cdf0e10cSrcweir 
1156cdf0e10cSrcweir 	fT1 = nPart1Length / nFullLength;
1157cdf0e10cSrcweir 	fU1 = 1.0 - fT1;
1158cdf0e10cSrcweir 	fT2 = nPart2Length / nFullLength;
1159cdf0e10cSrcweir 	fU2 = 1.0 - fT2;
1160cdf0e10cSrcweir 	fV = 3 * (1.0 - (fT1 * fU2) / (fT2 * fU1));
1161cdf0e10cSrcweir 
1162cdf0e10cSrcweir 	fX1 = fTx1 / (fT1 * fU1 * fU1) - fTx2 * fT1 / (fT2 * fT2 * fU1 * fU2);
1163cdf0e10cSrcweir 	fX1 /= fV;
1164cdf0e10cSrcweir 	fX1 -= fX0 * ( fU1 / fT1 + fU2 / fT2) / 3;
1165cdf0e10cSrcweir 	fX1 += fX3 * ( fT1 * fT2 / (fU1 * fU2)) / 3;
1166cdf0e10cSrcweir 
1167cdf0e10cSrcweir 	fY1 = fTy1 / (fT1 * fU1 * fU1) - fTy2 * fT1 / (fT2 * fT2 * fU1 * fU2);
1168cdf0e10cSrcweir 	fY1 /= fV;
1169cdf0e10cSrcweir 	fY1 -= fY0 * ( fU1 / fT1 + fU2 / fT2) / 3;
1170cdf0e10cSrcweir 	fY1 += fY3 * ( fT1 * fT2 / (fU1 * fU2)) / 3;
1171cdf0e10cSrcweir 
1172cdf0e10cSrcweir 	fX2 = fTx2 / (fT2 * fT2 * fU2 * 3) - fX0 * fU2 * fU2 / ( fT2 * fT2 * 3);
1173cdf0e10cSrcweir 	fX2 -= fX1 * fU2 / fT2;
1174cdf0e10cSrcweir 	fX2 -= fX3 * fT2 / (fU2 * 3);
1175cdf0e10cSrcweir 
1176cdf0e10cSrcweir 	fY2 = fTy2 / (fT2 * fT2 * fU2 * 3) - fY0 * fU2 * fU2 / ( fT2 * fT2 * 3);
1177cdf0e10cSrcweir 	fY2 -= fY1 * fU2 / fT2;
1178cdf0e10cSrcweir 	fY2 -= fY3 * fT2 / (fU2 * 3);
1179cdf0e10cSrcweir 
1180cdf0e10cSrcweir 	pPoints[nFirst+1] = Point((long) fX1, (long) fY1);
1181cdf0e10cSrcweir 	pPoints[nFirst+2] = Point((long) fX2, (long) fY2);
1182cdf0e10cSrcweir 	SetFlags(nFirst+1, XPOLY_CONTROL);
1183cdf0e10cSrcweir 	SetFlags(nFirst+2, XPOLY_CONTROL);
1184cdf0e10cSrcweir }
1185cdf0e10cSrcweir 
1186cdf0e10cSrcweir /*************************************************************************
1187cdf0e10cSrcweir |*
1188cdf0e10cSrcweir |*    XPolygon::Translate()
1189cdf0e10cSrcweir |*
1190cdf0e10cSrcweir |*    Polygon auf den uebergebenen Punkt verschieben
1191cdf0e10cSrcweir |*    Ersterstellung    ESO 17.01.95
1192cdf0e10cSrcweir |*    Letzte Aenderung  ESO 17.01.95
1193cdf0e10cSrcweir |*
1194cdf0e10cSrcweir *************************************************************************/
1195cdf0e10cSrcweir 
Translate(const Point & rTrans)1196cdf0e10cSrcweir void XPolygon::Translate(const Point& rTrans)
1197cdf0e10cSrcweir {
1198cdf0e10cSrcweir 	pImpXPolygon->CheckPointDelete();
1199cdf0e10cSrcweir 	CheckReference();
1200cdf0e10cSrcweir 
1201cdf0e10cSrcweir 	sal_uInt16 nPntCnt = pImpXPolygon->nPoints;
1202cdf0e10cSrcweir 
1203cdf0e10cSrcweir 	for (sal_uInt16 i = 0; i < nPntCnt; i++)
1204cdf0e10cSrcweir 		pImpXPolygon->pPointAry[i] += rTrans;
1205cdf0e10cSrcweir }
1206cdf0e10cSrcweir 
1207cdf0e10cSrcweir /*************************************************************************
1208cdf0e10cSrcweir |*
1209cdf0e10cSrcweir |*    XPolygon::Rotate()
1210cdf0e10cSrcweir |*
1211cdf0e10cSrcweir |*    Alle Punkte um den Punkt rCenter drehen, Sinus und Cosinus
1212cdf0e10cSrcweir |*    muessen uebergeben werden
1213cdf0e10cSrcweir |*    Ersterstellung    ESO 09.01.95
1214cdf0e10cSrcweir |*    Letzte Aenderung  ESO 17.01.95
1215cdf0e10cSrcweir |*
1216cdf0e10cSrcweir *************************************************************************/
1217cdf0e10cSrcweir 
Rotate(const Point & rCenter,double fSin,double fCos)1218cdf0e10cSrcweir void XPolygon::Rotate(const Point& rCenter, double fSin, double fCos)
1219cdf0e10cSrcweir {
1220cdf0e10cSrcweir 	pImpXPolygon->CheckPointDelete();
1221cdf0e10cSrcweir 	CheckReference();
1222cdf0e10cSrcweir 
1223cdf0e10cSrcweir 	long nX;
1224cdf0e10cSrcweir 	long nY;
1225cdf0e10cSrcweir 	long nNewX;
1226cdf0e10cSrcweir 	long nNewY;
1227cdf0e10cSrcweir 	long nCenterX = rCenter.X();
1228cdf0e10cSrcweir 	long nCenterY = rCenter.Y();
1229cdf0e10cSrcweir 
1230cdf0e10cSrcweir 	sal_uInt16 nPntCnt = pImpXPolygon->nPoints;
1231cdf0e10cSrcweir 
1232cdf0e10cSrcweir 	for (sal_uInt16 i = 0; i < nPntCnt; i++)
1233cdf0e10cSrcweir 	{
1234cdf0e10cSrcweir 		Point *pPt = &(pImpXPolygon->pPointAry[i]);
1235cdf0e10cSrcweir 		nX = pPt->X()-nCenterX;
1236cdf0e10cSrcweir 		nY = pPt->Y()-nCenterY;
1237cdf0e10cSrcweir 		nNewX =  (long)floor(fCos * nX + fSin * nY + 0.5);
1238cdf0e10cSrcweir 		nNewY = -(long)floor(fSin * nX - fCos * nY + 0.5);
1239cdf0e10cSrcweir 		pPt->X() = nNewX + nCenterX;
1240cdf0e10cSrcweir 		pPt->Y() = nNewY + nCenterY;
1241cdf0e10cSrcweir 
1242cdf0e10cSrcweir 	/* und so stand das in einem anderen File auf T:
1243cdf0e10cSrcweir 	   dass ich am 29-11-1995 gegettet habe. Joe M.
1244cdf0e10cSrcweir 	sal_uInt16 nPntCnt = pImpXPolygon->nPoints;
1245cdf0e10cSrcweir 
1246cdf0e10cSrcweir 	for (sal_uInt16 i = 0; i < nPntCnt; i++)
1247cdf0e10cSrcweir 	{
1248cdf0e10cSrcweir 		Point P = pImpXPolygon->pPointAry[i] - rCenter;
1249cdf0e10cSrcweir 		long X = P.X();
1250cdf0e10cSrcweir 		long Y = P.Y();
1251cdf0e10cSrcweir 		P.X() =  (long)floor(fCos * X + fSin * Y + 0.5);
1252cdf0e10cSrcweir 		P.Y() = -(long)floor(fSin * X - fCos * Y + 0.5);
1253cdf0e10cSrcweir 		pImpXPolygon->pPointAry[i] = P + rCenter;
1254cdf0e10cSrcweir 	*/
1255cdf0e10cSrcweir 	}
1256cdf0e10cSrcweir }
1257cdf0e10cSrcweir 
1258cdf0e10cSrcweir /*************************************************************************
1259cdf0e10cSrcweir |*
1260cdf0e10cSrcweir |*    XPolygon::Rotate()
1261cdf0e10cSrcweir |*
1262cdf0e10cSrcweir |*    Alle Punkte um den Punkt rCenter mit dem Winkel nAngle drehen
1263cdf0e10cSrcweir |*    Winkel in 10tel Grad, Wertebereich 0 - 3600
1264cdf0e10cSrcweir |*    Ersterstellung    ESO 17.01.95
1265cdf0e10cSrcweir |*    Letzte Aenderung  ESO 17.01.95
1266cdf0e10cSrcweir |*
1267cdf0e10cSrcweir *************************************************************************/
1268cdf0e10cSrcweir 
Rotate(const Point & rCenter,sal_uInt16 nAngle)1269cdf0e10cSrcweir void XPolygon::Rotate(const Point& rCenter, sal_uInt16 nAngle)
1270cdf0e10cSrcweir {
1271cdf0e10cSrcweir 	nAngle %= 3600;
1272cdf0e10cSrcweir 
1273cdf0e10cSrcweir 	if ( nAngle != 0 )
1274cdf0e10cSrcweir 	{
1275cdf0e10cSrcweir 		double fAngle = F_PI * nAngle / 1800;
1276cdf0e10cSrcweir 		double fSin = sin(fAngle);
1277cdf0e10cSrcweir 		double fCos = cos(fAngle);
1278cdf0e10cSrcweir 		Rotate(rCenter, fSin, fCos);
1279cdf0e10cSrcweir 	}
1280cdf0e10cSrcweir }
1281cdf0e10cSrcweir 
1282cdf0e10cSrcweir /*************************************************************************
1283cdf0e10cSrcweir |*
1284cdf0e10cSrcweir |*    XPolygon::Scale()
1285cdf0e10cSrcweir |*
1286cdf0e10cSrcweir |*    XPolygon in X- und/oder Y-Richtung skalieren
1287cdf0e10cSrcweir |*    Ersterstellung    ESO 01.02.95
1288cdf0e10cSrcweir |*    Letzte Aenderung  ESO 01.02.95
1289cdf0e10cSrcweir |*
1290cdf0e10cSrcweir *************************************************************************/
1291cdf0e10cSrcweir 
Scale(double fSx,double fSy)1292cdf0e10cSrcweir void XPolygon::Scale(double fSx, double fSy)
1293cdf0e10cSrcweir {
1294cdf0e10cSrcweir 	pImpXPolygon->CheckPointDelete();
1295cdf0e10cSrcweir 	CheckReference();
1296cdf0e10cSrcweir 
1297cdf0e10cSrcweir 	sal_uInt16 nPntCnt = pImpXPolygon->nPoints;
1298cdf0e10cSrcweir 
1299cdf0e10cSrcweir 	for (sal_uInt16 i = 0; i < nPntCnt; i++)
1300cdf0e10cSrcweir 	{
1301cdf0e10cSrcweir 		Point& rPnt = pImpXPolygon->pPointAry[i];
1302cdf0e10cSrcweir 		rPnt.X() = (long)(fSx * rPnt.X());
1303cdf0e10cSrcweir 		rPnt.Y() = (long)(fSy * rPnt.Y());
1304cdf0e10cSrcweir 	}
1305cdf0e10cSrcweir }
1306cdf0e10cSrcweir 
1307cdf0e10cSrcweir /*************************************************************************
1308cdf0e10cSrcweir |*
1309cdf0e10cSrcweir |*    XPolygon::SlantX()
1310cdf0e10cSrcweir |*
1311cdf0e10cSrcweir |*    XPolygon in X-Richtung um einen beliebigen Winkel kippen,
1312cdf0e10cSrcweir |*    bezogen auf eine Referenz-Y-Koordinate
1313cdf0e10cSrcweir |*    Ersterstellung    ESO 01.02.95
1314cdf0e10cSrcweir |*    Letzte Aenderung  ESO 01.02.95
1315cdf0e10cSrcweir |*
1316cdf0e10cSrcweir *************************************************************************/
1317cdf0e10cSrcweir 
SlantX(long nYRef,double fSin,double fCos)1318cdf0e10cSrcweir void XPolygon::SlantX(long nYRef, double fSin, double fCos)
1319cdf0e10cSrcweir {
1320cdf0e10cSrcweir 	pImpXPolygon->CheckPointDelete();
1321cdf0e10cSrcweir 	CheckReference();
1322cdf0e10cSrcweir 
1323cdf0e10cSrcweir 	sal_uInt16 nPntCnt = pImpXPolygon->nPoints;
1324cdf0e10cSrcweir 
1325cdf0e10cSrcweir 	for (sal_uInt16 i = 0; i < nPntCnt; i++)
1326cdf0e10cSrcweir 	{
1327cdf0e10cSrcweir 		Point& rPnt = pImpXPolygon->pPointAry[i];
1328cdf0e10cSrcweir 		long nDy = rPnt.Y() - nYRef;
1329cdf0e10cSrcweir 		rPnt.X() += (long)(fSin * nDy);
1330cdf0e10cSrcweir 		rPnt.Y() = nYRef + (long)(fCos * nDy);
1331cdf0e10cSrcweir 	}
1332cdf0e10cSrcweir }
1333cdf0e10cSrcweir 
1334cdf0e10cSrcweir /*************************************************************************
1335cdf0e10cSrcweir |*
1336cdf0e10cSrcweir |*    XPolygon::SlantY()
1337cdf0e10cSrcweir |*
1338cdf0e10cSrcweir |*    XPolygon in Y-Richtung um einen beliebigen Winkel kippen,
1339cdf0e10cSrcweir |*    bezogen auf eine Referenz-X-Koordinate
1340cdf0e10cSrcweir |*    Ersterstellung    ESO 01.02.95
1341cdf0e10cSrcweir |*    Letzte Aenderung  ESO 01.02.95
1342cdf0e10cSrcweir |*
1343cdf0e10cSrcweir *************************************************************************/
1344cdf0e10cSrcweir 
SlantY(long nXRef,double fSin,double fCos)1345cdf0e10cSrcweir void XPolygon::SlantY(long nXRef, double fSin, double fCos)
1346cdf0e10cSrcweir {
1347cdf0e10cSrcweir 	pImpXPolygon->CheckPointDelete();
1348cdf0e10cSrcweir 	CheckReference();
1349cdf0e10cSrcweir 
1350cdf0e10cSrcweir 	sal_uInt16 nPntCnt = pImpXPolygon->nPoints;
1351cdf0e10cSrcweir 
1352cdf0e10cSrcweir 	for (sal_uInt16 i = 0; i < nPntCnt; i++)
1353cdf0e10cSrcweir 	{
1354cdf0e10cSrcweir 		Point& rPnt = pImpXPolygon->pPointAry[i];
1355cdf0e10cSrcweir 		long nDx = rPnt.X() - nXRef;
1356cdf0e10cSrcweir 		rPnt.X() = nXRef + (long)(fCos * nDx);
1357cdf0e10cSrcweir 		rPnt.Y() -= (long)(fSin * nDx);
1358cdf0e10cSrcweir 	}
1359cdf0e10cSrcweir }
1360cdf0e10cSrcweir 
1361cdf0e10cSrcweir /*************************************************************************
1362cdf0e10cSrcweir |*
1363cdf0e10cSrcweir |*    XPolygon::Distort()
1364cdf0e10cSrcweir |*
1365cdf0e10cSrcweir |*    XPolygon verzerren, indem die Koordinaten relativ zu einem
1366cdf0e10cSrcweir |*    Referenzrechteck in ein beliebiges Viereck skaliert werden
1367cdf0e10cSrcweir |*    Zuordnung der Viereck-Punkte im Polygon zum Referenzrechteck:
1368cdf0e10cSrcweir |*    0: links oben      0----1
1369cdf0e10cSrcweir |*    1: rechts oben     |    |
1370cdf0e10cSrcweir |*    2: rechts unten    3----2
1371cdf0e10cSrcweir |*    3: links unten
1372cdf0e10cSrcweir |*    Ersterstellung    ESO 07.07.95
1373cdf0e10cSrcweir |*    Letzte Aenderung  ESO 07.07.95
1374cdf0e10cSrcweir |*
1375cdf0e10cSrcweir *************************************************************************/
1376cdf0e10cSrcweir 
Distort(const Rectangle & rRefRect,const XPolygon & rDistortedRect)1377cdf0e10cSrcweir void XPolygon::Distort(const Rectangle& rRefRect,
1378cdf0e10cSrcweir 					   const XPolygon& rDistortedRect)
1379cdf0e10cSrcweir {
1380cdf0e10cSrcweir 	pImpXPolygon->CheckPointDelete();
1381cdf0e10cSrcweir 	CheckReference();
1382cdf0e10cSrcweir 
1383cdf0e10cSrcweir 	long    Xr, Wr, X1, X2, X3, X4;
1384cdf0e10cSrcweir 	long    Yr, Hr, Y1, Y2, Y3, Y4;
1385cdf0e10cSrcweir 	double  fTx, fTy, fUx, fUy;
1386cdf0e10cSrcweir 
1387cdf0e10cSrcweir 	Xr = rRefRect.Left();
1388cdf0e10cSrcweir 	Yr = rRefRect.Top();
1389cdf0e10cSrcweir 	Wr = rRefRect.GetWidth();
1390cdf0e10cSrcweir 	Hr = rRefRect.GetHeight();
1391cdf0e10cSrcweir 
1392cdf0e10cSrcweir 	if ( Wr && Hr )
1393cdf0e10cSrcweir 	{
1394cdf0e10cSrcweir 		DBG_ASSERT(rDistortedRect.pImpXPolygon->nPoints >= 4,
1395cdf0e10cSrcweir 				   "Distort-Rechteck zu klein");
1396cdf0e10cSrcweir 
1397cdf0e10cSrcweir 		X1 = rDistortedRect[0].X();
1398cdf0e10cSrcweir 		Y1 = rDistortedRect[0].Y();
1399cdf0e10cSrcweir 		X2 = rDistortedRect[1].X();
1400cdf0e10cSrcweir 		Y2 = rDistortedRect[1].Y();
1401cdf0e10cSrcweir 		X3 = rDistortedRect[3].X();
1402cdf0e10cSrcweir 		Y3 = rDistortedRect[3].Y();
1403cdf0e10cSrcweir 		X4 = rDistortedRect[2].X();
1404cdf0e10cSrcweir 		Y4 = rDistortedRect[2].Y();
1405cdf0e10cSrcweir 
1406cdf0e10cSrcweir 		sal_uInt16 nPntCnt = pImpXPolygon->nPoints;
1407cdf0e10cSrcweir 
1408cdf0e10cSrcweir 		for (sal_uInt16 i = 0; i < nPntCnt; i++)
1409cdf0e10cSrcweir 		{
1410cdf0e10cSrcweir 			Point& rPnt = pImpXPolygon->pPointAry[i];
1411cdf0e10cSrcweir 
1412cdf0e10cSrcweir 			fTx = (double)(rPnt.X() - Xr) / Wr;
1413cdf0e10cSrcweir 			fTy = (double)(rPnt.Y() - Yr) / Hr;
1414cdf0e10cSrcweir 			fUx = 1.0 - fTx;
1415cdf0e10cSrcweir 			fUy = 1.0 - fTy;
1416cdf0e10cSrcweir 
1417cdf0e10cSrcweir 			rPnt.X() = (long) ( fUy * (fUx * X1 + fTx * X2) +
1418cdf0e10cSrcweir 								fTy * (fUx * X3 + fTx * X4) );
1419cdf0e10cSrcweir 			rPnt.Y() = (long) ( fUx * (fUy * Y1 + fTy * Y3) +
1420cdf0e10cSrcweir 								fTx * (fUy * Y2 + fTy * Y4) );
1421cdf0e10cSrcweir 		}
1422cdf0e10cSrcweir 	}
1423cdf0e10cSrcweir }
1424cdf0e10cSrcweir 
1425cdf0e10cSrcweir /*************************************************************************
1426cdf0e10cSrcweir |*
1427cdf0e10cSrcweir |* Bestimme den linken, unteren Punkt des Polygons und richte das
1428cdf0e10cSrcweir |* Polygon so aus, dass dieser Punkt auf dem Index 0 liegt
1429cdf0e10cSrcweir |*
1430cdf0e10cSrcweir \************************************************************************/
1431cdf0e10cSrcweir 
Rotate20()1432cdf0e10cSrcweir void XPolygon::Rotate20()
1433cdf0e10cSrcweir {
1434cdf0e10cSrcweir 	pImpXPolygon->CheckPointDelete();
1435cdf0e10cSrcweir 	CheckReference();
1436cdf0e10cSrcweir 
1437cdf0e10cSrcweir 	double   fMinY   = pImpXPolygon->pPointAry->Y();
1438cdf0e10cSrcweir 	double   fMinX   = pImpXPolygon->pPointAry->X();
1439cdf0e10cSrcweir 	long     nPntCnt = pImpXPolygon->nPoints;
1440cdf0e10cSrcweir 	long     nIndex0 = 0;
1441cdf0e10cSrcweir 
1442cdf0e10cSrcweir 	for (long nPoints = 1;
1443cdf0e10cSrcweir 			  nPoints < nPntCnt;
1444cdf0e10cSrcweir 			  nPoints ++)
1445cdf0e10cSrcweir 	{
1446cdf0e10cSrcweir 		Point &rPnt = pImpXPolygon->pPointAry[nPoints];
1447cdf0e10cSrcweir 
1448cdf0e10cSrcweir 		if ((rPnt.X () < fMinX) || (fMinX == rPnt.X ()) &&
1449cdf0e10cSrcweir 								   (fMinY >= rPnt.Y ()))
1450cdf0e10cSrcweir 		{
1451cdf0e10cSrcweir 			fMinX   = rPnt.X ();
1452cdf0e10cSrcweir 			fMinY   = rPnt.Y ();
1453cdf0e10cSrcweir 			nIndex0 = nPoints;
1454cdf0e10cSrcweir 		}
1455cdf0e10cSrcweir 	}
1456cdf0e10cSrcweir 
1457cdf0e10cSrcweir 	if (nIndex0 < nPntCnt)
1458cdf0e10cSrcweir 	{
1459cdf0e10cSrcweir 		Point *pTemp = new Point [nIndex0];
1460cdf0e10cSrcweir 		memcpy (pTemp, pImpXPolygon->pPointAry, nIndex0 * sizeof (Point));
1461cdf0e10cSrcweir 		memcpy (pImpXPolygon->pPointAry, &pImpXPolygon->pPointAry [nIndex0], (nPntCnt - nIndex0) * sizeof (Point));
1462cdf0e10cSrcweir 		memcpy (&pImpXPolygon->pPointAry [nIndex0], pTemp, nIndex0 * sizeof (Point));
1463cdf0e10cSrcweir 		delete[] pTemp;
1464cdf0e10cSrcweir 	}
1465cdf0e10cSrcweir }
1466cdf0e10cSrcweir 
getB2DPolygon() const1467cdf0e10cSrcweir basegfx::B2DPolygon XPolygon::getB2DPolygon() const
1468cdf0e10cSrcweir {
1469cdf0e10cSrcweir 	// #i74631# use tools Polygon class for conversion to not have the code doubled
1470cdf0e10cSrcweir 	// here. This needs one more conversion but avoids different convertors in
1471cdf0e10cSrcweir 	// the long run
1472cdf0e10cSrcweir 	DBG_ASSERT(pImpXPolygon != 0, "XPolygon::getB2DPolygon(): XPolygon has no implementation incarnated (!)");
1473cdf0e10cSrcweir 	const Polygon aSource(GetPointCount(), pImpXPolygon->pPointAry, pImpXPolygon->pFlagAry);
1474cdf0e10cSrcweir 
1475cdf0e10cSrcweir 	return aSource.getB2DPolygon();
1476cdf0e10cSrcweir }
1477cdf0e10cSrcweir 
XPolygon(const basegfx::B2DPolygon & rPolygon)1478cdf0e10cSrcweir XPolygon::XPolygon(const basegfx::B2DPolygon& rPolygon)
1479cdf0e10cSrcweir {
1480cdf0e10cSrcweir 	// #i74631# use tools Polygon class for conversion to not have the code doubled
1481cdf0e10cSrcweir 	// here. This needs one more conversion but avoids different convertors in
1482cdf0e10cSrcweir 	// the long run
1483cdf0e10cSrcweir 	DBG_CTOR(XPolygon,NULL);
1484cdf0e10cSrcweir 
1485cdf0e10cSrcweir 	const Polygon aSource(rPolygon);
1486cdf0e10cSrcweir 	sal_uInt16 nSize = aSource.GetSize();
1487cdf0e10cSrcweir 	pImpXPolygon = new ImpXPolygon( nSize );
1488cdf0e10cSrcweir 	pImpXPolygon->nPoints = nSize;
1489cdf0e10cSrcweir 
1490cdf0e10cSrcweir 	for( sal_uInt16 i = 0; i < nSize;  i++ )
1491cdf0e10cSrcweir 	{
1492cdf0e10cSrcweir 		pImpXPolygon->pPointAry[i] = aSource[i];
1493cdf0e10cSrcweir 		pImpXPolygon->pFlagAry[i] = (sal_uInt8) aSource.GetFlags( i );
1494cdf0e10cSrcweir 	}
1495cdf0e10cSrcweir }
1496cdf0e10cSrcweir 
1497cdf0e10cSrcweir //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1498cdf0e10cSrcweir //+--------------- XPolyPolygon -----------------------------------------+
1499cdf0e10cSrcweir //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1500cdf0e10cSrcweir 
1501cdf0e10cSrcweir /*************************************************************************
1502cdf0e10cSrcweir |*
1503cdf0e10cSrcweir |*    ImpXPolyPolygon::ImpXPolyPolygon()
1504cdf0e10cSrcweir |*
1505cdf0e10cSrcweir |*    Beschreibung      Erzeugt das XPolygon-Array
1506cdf0e10cSrcweir |*    Ersterstellung    CL 09.11.94
1507cdf0e10cSrcweir |*    Letzte Aenderung  MM 09.11.94
1508cdf0e10cSrcweir |*
1509cdf0e10cSrcweir *************************************************************************/
1510cdf0e10cSrcweir 
ImpXPolyPolygon(const ImpXPolyPolygon & rImpXPolyPoly)1511cdf0e10cSrcweir ImpXPolyPolygon::ImpXPolyPolygon( const ImpXPolyPolygon& rImpXPolyPoly ) :
1512cdf0e10cSrcweir 					 aXPolyList( rImpXPolyPoly.aXPolyList )
1513cdf0e10cSrcweir {
1514cdf0e10cSrcweir 	nRefCount = 1;
1515cdf0e10cSrcweir 
1516cdf0e10cSrcweir 	// Einzelne Elemente duplizieren
1517cdf0e10cSrcweir 	XPolygon* pXPoly = aXPolyList.First();
1518cdf0e10cSrcweir 	while ( pXPoly )
1519cdf0e10cSrcweir 	{
1520cdf0e10cSrcweir 		aXPolyList.Replace( new XPolygon( *(aXPolyList.GetCurObject()) ) );
1521cdf0e10cSrcweir 		pXPoly = aXPolyList.Next();
1522cdf0e10cSrcweir 	}
1523cdf0e10cSrcweir }
1524cdf0e10cSrcweir 
1525cdf0e10cSrcweir 
1526cdf0e10cSrcweir /*************************************************************************
1527cdf0e10cSrcweir |*
1528cdf0e10cSrcweir |*    ImpXPolyPolygon::~ImpXPolyPolygon()
1529cdf0e10cSrcweir |*
1530cdf0e10cSrcweir |*    Beschreibung      Loescht das Polygon-Array
1531cdf0e10cSrcweir |*    Ersterstellung    CL 09.06.93
1532cdf0e10cSrcweir |*    Letzte Aenderung  CL 09.06.93
1533cdf0e10cSrcweir |*
1534cdf0e10cSrcweir *************************************************************************/
1535cdf0e10cSrcweir 
~ImpXPolyPolygon()1536cdf0e10cSrcweir ImpXPolyPolygon::~ImpXPolyPolygon()
1537cdf0e10cSrcweir {
1538cdf0e10cSrcweir 	XPolygon* pXPoly = aXPolyList.First();
1539cdf0e10cSrcweir 	while( pXPoly )
1540cdf0e10cSrcweir 	{
1541cdf0e10cSrcweir 		delete pXPoly;
1542cdf0e10cSrcweir 		pXPoly = aXPolyList.Next();
1543cdf0e10cSrcweir 	}
1544cdf0e10cSrcweir }
1545cdf0e10cSrcweir 
1546cdf0e10cSrcweir /*************************************************************************
1547cdf0e10cSrcweir |*
1548cdf0e10cSrcweir |*    ImpXPolyPolygon::operator==()
1549cdf0e10cSrcweir |*
1550cdf0e10cSrcweir |*    Ersterstellung    Joe 26-09-95
1551cdf0e10cSrcweir |*    Letzte Aenderung
1552cdf0e10cSrcweir |*
1553cdf0e10cSrcweir *************************************************************************/
1554cdf0e10cSrcweir 
1555cdf0e10cSrcweir 
operator ==(const ImpXPolyPolygon & rImpXPolyPoly) const1556cdf0e10cSrcweir bool ImpXPolyPolygon::operator==(const ImpXPolyPolygon& rImpXPolyPoly) const
1557cdf0e10cSrcweir {
1558cdf0e10cSrcweir 	sal_uInt16 nAnz=(sal_uInt16)aXPolyList.Count();
1559cdf0e10cSrcweir 	const XPolygonList& rCmpList=rImpXPolyPoly.aXPolyList;
1560cdf0e10cSrcweir 	if (nAnz!=(sal_uInt16)rCmpList.Count()) return sal_False;
1561cdf0e10cSrcweir 	bool bEq=true;
1562cdf0e10cSrcweir 	for (sal_uInt16 i=nAnz; i>0 && bEq;) {
1563cdf0e10cSrcweir 		i--;
1564cdf0e10cSrcweir 		bEq= *aXPolyList.GetObject(i) == *rCmpList.GetObject(i);
1565cdf0e10cSrcweir 	}
1566cdf0e10cSrcweir 	return bEq;
1567cdf0e10cSrcweir }
1568cdf0e10cSrcweir 
1569cdf0e10cSrcweir /*************************************************************************
1570cdf0e10cSrcweir |*
1571cdf0e10cSrcweir |*    XPolyPolygon::XPolyPolygon()
1572cdf0e10cSrcweir |*
1573cdf0e10cSrcweir |*    Beschreibung      POLY.SDW
1574cdf0e10cSrcweir |*    Ersterstellung    CL 27.01.93
1575cdf0e10cSrcweir |*    Letzte Aenderung  CL 27.01.93
1576cdf0e10cSrcweir |*
1577cdf0e10cSrcweir *************************************************************************/
1578cdf0e10cSrcweir 
XPolyPolygon(sal_uInt16 nInitSize,sal_uInt16 nResize)1579cdf0e10cSrcweir XPolyPolygon::XPolyPolygon( sal_uInt16 nInitSize, sal_uInt16 nResize )
1580cdf0e10cSrcweir {
1581cdf0e10cSrcweir 	DBG_CTOR(XPolyPolygon,NULL);
1582cdf0e10cSrcweir 	pImpXPolyPolygon = new ImpXPolyPolygon( nInitSize, nResize );
1583cdf0e10cSrcweir }
1584cdf0e10cSrcweir 
1585cdf0e10cSrcweir 
1586cdf0e10cSrcweir /*************************************************************************
1587cdf0e10cSrcweir |*
1588cdf0e10cSrcweir |*    XPolyPolygon::XPolyPolygon()
1589cdf0e10cSrcweir |*
1590cdf0e10cSrcweir |*    Beschreibung      POLY.SDW
1591cdf0e10cSrcweir |*    Ersterstellung    CL 27.01.93
1592cdf0e10cSrcweir |*    Letzte Aenderung  CL 27.01.93
1593cdf0e10cSrcweir |*
1594cdf0e10cSrcweir *************************************************************************/
1595cdf0e10cSrcweir 
XPolyPolygon(const XPolygon & rXPoly)1596cdf0e10cSrcweir XPolyPolygon::XPolyPolygon( const XPolygon& rXPoly )
1597cdf0e10cSrcweir {
1598cdf0e10cSrcweir 	DBG_CTOR(XPolyPolygon,NULL);
1599cdf0e10cSrcweir 	pImpXPolyPolygon = new ImpXPolyPolygon;
1600cdf0e10cSrcweir 	pImpXPolyPolygon->aXPolyList.Insert( new XPolygon( rXPoly ) );
1601cdf0e10cSrcweir }
1602cdf0e10cSrcweir 
1603cdf0e10cSrcweir /*************************************************************************
1604cdf0e10cSrcweir |*
1605cdf0e10cSrcweir |*    XPolyPolygon::XPolyPolygon()
1606cdf0e10cSrcweir |*
1607cdf0e10cSrcweir |*    Beschreibung      POLY.SDW
1608cdf0e10cSrcweir |*    Ersterstellung    CL 27.01.93
1609cdf0e10cSrcweir |*    Letzte Aenderung  CL 27.01.93
1610cdf0e10cSrcweir |*
1611cdf0e10cSrcweir *************************************************************************/
1612cdf0e10cSrcweir 
XPolyPolygon(const XPolyPolygon & rXPolyPoly)1613cdf0e10cSrcweir XPolyPolygon::XPolyPolygon( const XPolyPolygon& rXPolyPoly )
1614cdf0e10cSrcweir {
1615cdf0e10cSrcweir 	DBG_CTOR(XPolyPolygon,NULL);
1616cdf0e10cSrcweir 	pImpXPolyPolygon = rXPolyPoly.pImpXPolyPolygon;
1617cdf0e10cSrcweir 	pImpXPolyPolygon->nRefCount++;
1618cdf0e10cSrcweir }
1619cdf0e10cSrcweir 
1620cdf0e10cSrcweir /*************************************************************************
1621cdf0e10cSrcweir |*
1622cdf0e10cSrcweir |*    XPolyPolygon::XPolyPolygon()
1623cdf0e10cSrcweir |*
1624cdf0e10cSrcweir |*    XPolyPolygon aus einen Standard-PolyPolygon erzeugen
1625cdf0e10cSrcweir |*    Ersterstellung    18.01.95 ESO
1626cdf0e10cSrcweir |*    Letzte Aenderung  18.01.95 ESO
1627cdf0e10cSrcweir |*
1628cdf0e10cSrcweir *************************************************************************/
1629cdf0e10cSrcweir 
XPolyPolygon(const PolyPolygon & rPolyPoly)1630cdf0e10cSrcweir XPolyPolygon::XPolyPolygon( const PolyPolygon& rPolyPoly )
1631cdf0e10cSrcweir {
1632cdf0e10cSrcweir 	DBG_CTOR(XPolyPolygon,NULL);
1633cdf0e10cSrcweir 	pImpXPolyPolygon = new ImpXPolyPolygon;
1634cdf0e10cSrcweir 
1635cdf0e10cSrcweir 	for (sal_uInt16 i = 0; i < rPolyPoly.Count(); i++)
1636cdf0e10cSrcweir 		pImpXPolyPolygon->aXPolyList.Insert(
1637cdf0e10cSrcweir 									new XPolygon(rPolyPoly.GetObject(i)) );
1638cdf0e10cSrcweir }
1639cdf0e10cSrcweir 
1640cdf0e10cSrcweir /*************************************************************************
1641cdf0e10cSrcweir |*
1642cdf0e10cSrcweir |*    XPolyPolygon::~XPolyPolygon()
1643cdf0e10cSrcweir |*
1644cdf0e10cSrcweir |*    Beschreibung      POLY.SDW
1645cdf0e10cSrcweir |*    Ersterstellung    CL 27.01.93
1646cdf0e10cSrcweir |*    Letzte Aenderung  CL 27.01.93
1647cdf0e10cSrcweir |*
1648cdf0e10cSrcweir *************************************************************************/
1649cdf0e10cSrcweir 
~XPolyPolygon()1650cdf0e10cSrcweir XPolyPolygon::~XPolyPolygon()
1651cdf0e10cSrcweir {
1652cdf0e10cSrcweir 	DBG_DTOR(XPolyPolygon,NULL);
1653cdf0e10cSrcweir 	if( pImpXPolyPolygon->nRefCount > 1 )
1654cdf0e10cSrcweir 		pImpXPolyPolygon->nRefCount--;
1655cdf0e10cSrcweir 	else
1656cdf0e10cSrcweir 		delete pImpXPolyPolygon;
1657cdf0e10cSrcweir }
1658cdf0e10cSrcweir 
1659cdf0e10cSrcweir /*************************************************************************
1660cdf0e10cSrcweir |*
1661cdf0e10cSrcweir |*    XPolygon::CheckReference()
1662cdf0e10cSrcweir |*
1663cdf0e10cSrcweir |*    Referenzzaehler desImpXPolyPoly pruefen und ggf. von diesem abkoppeln
1664cdf0e10cSrcweir |*    Ersterstellung    18.01.95 ESO
1665cdf0e10cSrcweir |*    Letzte Aenderung  18.01.95 ESO
1666cdf0e10cSrcweir |*
1667cdf0e10cSrcweir *************************************************************************/
1668cdf0e10cSrcweir 
CheckReference()1669cdf0e10cSrcweir void XPolyPolygon::CheckReference()
1670cdf0e10cSrcweir {
1671cdf0e10cSrcweir 	if( pImpXPolyPolygon->nRefCount > 1 )
1672cdf0e10cSrcweir 	{
1673cdf0e10cSrcweir 		pImpXPolyPolygon->nRefCount--;
1674cdf0e10cSrcweir 		pImpXPolyPolygon = new ImpXPolyPolygon( *pImpXPolyPolygon );
1675cdf0e10cSrcweir 	}
1676cdf0e10cSrcweir }
1677cdf0e10cSrcweir 
1678cdf0e10cSrcweir /*************************************************************************
1679cdf0e10cSrcweir |*
1680cdf0e10cSrcweir |*    XPolyPolygon::Insert()
1681cdf0e10cSrcweir |*
1682cdf0e10cSrcweir |*    Beschreibung      POLY.SDW
1683cdf0e10cSrcweir |*    Ersterstellung    CL 27.01.93
1684cdf0e10cSrcweir |*    Letzte Aenderung  CL 27.01.93
1685cdf0e10cSrcweir |*
1686cdf0e10cSrcweir *************************************************************************/
1687cdf0e10cSrcweir 
Insert(const XPolygon & rXPoly,sal_uInt16 nPos)1688cdf0e10cSrcweir void XPolyPolygon::Insert( const XPolygon& rXPoly, sal_uInt16 nPos )
1689cdf0e10cSrcweir {
1690cdf0e10cSrcweir 	CheckReference();
1691cdf0e10cSrcweir 	XPolygon* pXPoly = new XPolygon( rXPoly );
1692cdf0e10cSrcweir 	pImpXPolyPolygon->aXPolyList.Insert( pXPoly, nPos );
1693cdf0e10cSrcweir }
1694cdf0e10cSrcweir 
1695cdf0e10cSrcweir /*************************************************************************
1696cdf0e10cSrcweir |*
1697cdf0e10cSrcweir |*    XPolyPolygon::Insert()
1698cdf0e10cSrcweir |*
1699cdf0e10cSrcweir |*    saemtliche XPolygone aus einem XPolyPolygon einfuegen
1700cdf0e10cSrcweir |*    Ersterstellung    18.01.95 ESO
1701cdf0e10cSrcweir |*    Letzte Aenderung  18.01.95 ESO
1702cdf0e10cSrcweir |*
1703cdf0e10cSrcweir *************************************************************************/
1704cdf0e10cSrcweir 
Insert(const XPolyPolygon & rXPolyPoly,sal_uInt16 nPos)1705cdf0e10cSrcweir void XPolyPolygon::Insert( const XPolyPolygon& rXPolyPoly, sal_uInt16 nPos )
1706cdf0e10cSrcweir {
1707cdf0e10cSrcweir 	CheckReference();
1708cdf0e10cSrcweir 
1709cdf0e10cSrcweir 	for (sal_uInt16 i = 0; i < rXPolyPoly.Count(); i++)
1710cdf0e10cSrcweir 	{
1711cdf0e10cSrcweir 		XPolygon* pXPoly = new XPolygon(rXPolyPoly[i]);
1712cdf0e10cSrcweir 		pImpXPolyPolygon->aXPolyList.Insert(pXPoly, nPos);
1713cdf0e10cSrcweir 		if ( nPos != XPOLYPOLY_APPEND )
1714cdf0e10cSrcweir 			nPos++;
1715cdf0e10cSrcweir 	}
1716cdf0e10cSrcweir }
1717cdf0e10cSrcweir 
1718cdf0e10cSrcweir /*************************************************************************
1719cdf0e10cSrcweir |*
1720cdf0e10cSrcweir |*    XPolyPolygon::Remove()
1721cdf0e10cSrcweir |*
1722cdf0e10cSrcweir |*    Beschreibung      POLY.SDW
1723cdf0e10cSrcweir |*    Ersterstellung    CL 27.01.93
1724cdf0e10cSrcweir |*    Letzte Aenderung  CL 27.01.93
1725cdf0e10cSrcweir |*
1726cdf0e10cSrcweir *************************************************************************/
1727cdf0e10cSrcweir 
Remove(sal_uInt16 nPos)1728cdf0e10cSrcweir XPolygon XPolyPolygon::Remove( sal_uInt16 nPos )
1729cdf0e10cSrcweir {
1730cdf0e10cSrcweir 	CheckReference();
1731cdf0e10cSrcweir 	XPolygon* pTmpXPoly = pImpXPolyPolygon->aXPolyList.Remove( nPos );
1732cdf0e10cSrcweir 	XPolygon  aXPoly( *pTmpXPoly );
1733cdf0e10cSrcweir 	delete pTmpXPoly;
1734cdf0e10cSrcweir 	return aXPoly;
1735cdf0e10cSrcweir }
1736cdf0e10cSrcweir 
1737cdf0e10cSrcweir 
1738cdf0e10cSrcweir /*************************************************************************
1739cdf0e10cSrcweir |*
1740cdf0e10cSrcweir |*    XPolyPolygon::Replace()
1741cdf0e10cSrcweir |*
1742cdf0e10cSrcweir |*    Beschreibung      POLY.SDW
1743cdf0e10cSrcweir |*    Ersterstellung    CL 27.01.93
1744cdf0e10cSrcweir |*    Letzte Aenderung  CL 27.01.93
1745cdf0e10cSrcweir |*
1746cdf0e10cSrcweir *************************************************************************/
1747cdf0e10cSrcweir 
Replace(const XPolygon & rXPoly,sal_uInt16 nPos)1748cdf0e10cSrcweir XPolygon XPolyPolygon::Replace( const XPolygon& rXPoly, sal_uInt16 nPos )
1749cdf0e10cSrcweir {
1750cdf0e10cSrcweir 	CheckReference();
1751cdf0e10cSrcweir 	XPolygon* pXPoly = new XPolygon( rXPoly );
1752cdf0e10cSrcweir 	XPolygon* pTmpXPoly = pImpXPolyPolygon->aXPolyList.Replace( pXPoly, nPos );
1753cdf0e10cSrcweir 	XPolygon  aXPoly( *pTmpXPoly );
1754cdf0e10cSrcweir 	delete pTmpXPoly;
1755cdf0e10cSrcweir 	return aXPoly;
1756cdf0e10cSrcweir }
1757cdf0e10cSrcweir 
1758cdf0e10cSrcweir 
1759cdf0e10cSrcweir /*************************************************************************
1760cdf0e10cSrcweir |*
1761cdf0e10cSrcweir |*    XPolyPolygon::GetObject()
1762cdf0e10cSrcweir |*
1763cdf0e10cSrcweir |*    Beschreibung      POLY.SDW
1764cdf0e10cSrcweir |*    Ersterstellung    CL 27.01.93
1765cdf0e10cSrcweir |*    Letzte Aenderung  CL 27.01.93
1766cdf0e10cSrcweir |*
1767cdf0e10cSrcweir *************************************************************************/
1768cdf0e10cSrcweir 
GetObject(sal_uInt16 nPos) const1769cdf0e10cSrcweir const XPolygon& XPolyPolygon::GetObject( sal_uInt16 nPos ) const
1770cdf0e10cSrcweir {
1771cdf0e10cSrcweir 	return *(pImpXPolyPolygon->aXPolyList.GetObject( nPos ));
1772cdf0e10cSrcweir }
1773cdf0e10cSrcweir 
1774cdf0e10cSrcweir 
1775cdf0e10cSrcweir /*************************************************************************
1776cdf0e10cSrcweir |*
1777cdf0e10cSrcweir |*    XPolyPolygon::Clear()
1778cdf0e10cSrcweir |*
1779cdf0e10cSrcweir |*    Beschreibung      POLY.SDW
1780cdf0e10cSrcweir |*    Ersterstellung    CL 27.01.93
1781cdf0e10cSrcweir |*    Letzte Aenderung  TH 17.10.94
1782cdf0e10cSrcweir |*
1783cdf0e10cSrcweir *************************************************************************/
1784cdf0e10cSrcweir 
Clear()1785cdf0e10cSrcweir void XPolyPolygon::Clear()
1786cdf0e10cSrcweir {
1787cdf0e10cSrcweir 	if ( pImpXPolyPolygon->nRefCount > 1 )
1788cdf0e10cSrcweir 	{
1789cdf0e10cSrcweir 		pImpXPolyPolygon->nRefCount--;
1790cdf0e10cSrcweir 		pImpXPolyPolygon = new ImpXPolyPolygon();
1791cdf0e10cSrcweir 	}
1792cdf0e10cSrcweir 	else
1793cdf0e10cSrcweir 	{
1794cdf0e10cSrcweir 		XPolygon* pXPoly = pImpXPolyPolygon->aXPolyList.First();
1795cdf0e10cSrcweir 		while( pXPoly )
1796cdf0e10cSrcweir 		{
1797cdf0e10cSrcweir 			delete pXPoly;
1798cdf0e10cSrcweir 			pXPoly = pImpXPolyPolygon->aXPolyList.Next();
1799cdf0e10cSrcweir 		}
1800cdf0e10cSrcweir 		pImpXPolyPolygon->aXPolyList.Clear();
1801cdf0e10cSrcweir 	}
1802cdf0e10cSrcweir }
1803cdf0e10cSrcweir 
1804cdf0e10cSrcweir 
1805cdf0e10cSrcweir /*************************************************************************
1806cdf0e10cSrcweir |*
1807cdf0e10cSrcweir |*    XPolyPolygon::Count()
1808cdf0e10cSrcweir |*
1809cdf0e10cSrcweir |*    Beschreibung
1810cdf0e10cSrcweir |*    Ersterstellung    CL 27.01.93
1811cdf0e10cSrcweir |*    Letzte Aenderung  CL 27.01.93
1812cdf0e10cSrcweir |*
1813cdf0e10cSrcweir *************************************************************************/
1814cdf0e10cSrcweir 
Count() const1815cdf0e10cSrcweir sal_uInt16 XPolyPolygon::Count() const
1816cdf0e10cSrcweir {
1817cdf0e10cSrcweir 	return (sal_uInt16)(pImpXPolyPolygon->aXPolyList.Count());
1818cdf0e10cSrcweir }
1819cdf0e10cSrcweir 
1820cdf0e10cSrcweir 
1821cdf0e10cSrcweir /*************************************************************************
1822cdf0e10cSrcweir |*
1823cdf0e10cSrcweir |*    XPolyPolygon::Move()
1824cdf0e10cSrcweir |*
1825cdf0e10cSrcweir |*    Beschreibung      POLY.SDW
1826cdf0e10cSrcweir |*    Ersterstellung    TH 04.10.94
1827cdf0e10cSrcweir |*    Letzte Aenderung  TH 04.10.94
1828cdf0e10cSrcweir |*
1829cdf0e10cSrcweir *************************************************************************/
1830cdf0e10cSrcweir 
Move(long nHorzMove,long nVertMove)1831cdf0e10cSrcweir void XPolyPolygon::Move( long nHorzMove, long nVertMove )
1832cdf0e10cSrcweir {
1833cdf0e10cSrcweir 	// Diese Abfrage sollte man fuer die DrawEngine durchfuehren
1834cdf0e10cSrcweir 	if ( !nHorzMove && !nVertMove )
1835cdf0e10cSrcweir 		return;
1836cdf0e10cSrcweir 
1837cdf0e10cSrcweir 	// Referenzcounter beruecksichtigen
1838cdf0e10cSrcweir 	CheckReference();
1839cdf0e10cSrcweir 
1840cdf0e10cSrcweir 	// Punkte verschieben
1841cdf0e10cSrcweir 	XPolygon* pXPoly = pImpXPolyPolygon->aXPolyList.First();
1842cdf0e10cSrcweir 	while( pXPoly )
1843cdf0e10cSrcweir 	{
1844cdf0e10cSrcweir 		pXPoly->Move( nHorzMove, nVertMove );
1845cdf0e10cSrcweir 		pXPoly = pImpXPolyPolygon->aXPolyList.Next();
1846cdf0e10cSrcweir 	}
1847cdf0e10cSrcweir }
1848cdf0e10cSrcweir 
1849cdf0e10cSrcweir /*************************************************************************
1850cdf0e10cSrcweir |*
1851cdf0e10cSrcweir |*    XPolyPolygon::GetBoundRect()
1852cdf0e10cSrcweir |*
1853cdf0e10cSrcweir |*    Beschreibung      POLY.SDW
1854cdf0e10cSrcweir |*    Ersterstellung    TH 04.10.94
1855cdf0e10cSrcweir |*    Letzte Aenderung  TH 04.10.94
1856cdf0e10cSrcweir |*
1857cdf0e10cSrcweir *************************************************************************/
1858cdf0e10cSrcweir 
GetBoundRect() const1859cdf0e10cSrcweir Rectangle XPolyPolygon::GetBoundRect() const
1860cdf0e10cSrcweir {
1861cdf0e10cSrcweir 	sal_uInt16    nXPoly = (sal_uInt16)pImpXPolyPolygon->aXPolyList.Count();
1862cdf0e10cSrcweir 	Rectangle aRect;
1863cdf0e10cSrcweir 
1864cdf0e10cSrcweir 	for ( sal_uInt16 n = 0; n < nXPoly; n++ )
1865cdf0e10cSrcweir 	{
1866cdf0e10cSrcweir 		const XPolygon* pXPoly = pImpXPolyPolygon->aXPolyList.GetObject( n );
1867cdf0e10cSrcweir 		aRect.Union( pXPoly->GetBoundRect() );
1868cdf0e10cSrcweir 	}
1869cdf0e10cSrcweir 
1870cdf0e10cSrcweir 	return aRect;
1871cdf0e10cSrcweir }
1872cdf0e10cSrcweir 
1873cdf0e10cSrcweir 
1874cdf0e10cSrcweir /*************************************************************************
1875cdf0e10cSrcweir |*
1876cdf0e10cSrcweir |*    XPolyPolygon::operator[]()
1877cdf0e10cSrcweir |*
1878cdf0e10cSrcweir |*    Beschreibung      POLY.SDW
1879cdf0e10cSrcweir |*    Ersterstellung    TH 28.10.94
1880cdf0e10cSrcweir |*    Letzte Aenderung  TH 28.10.94
1881cdf0e10cSrcweir |*
1882cdf0e10cSrcweir *************************************************************************/
1883cdf0e10cSrcweir 
operator [](sal_uInt16 nPos)1884cdf0e10cSrcweir XPolygon& XPolyPolygon::operator[]( sal_uInt16 nPos )
1885cdf0e10cSrcweir {
1886cdf0e10cSrcweir 	CheckReference();
1887cdf0e10cSrcweir 	return *(pImpXPolyPolygon->aXPolyList.GetObject( nPos ));
1888cdf0e10cSrcweir }
1889cdf0e10cSrcweir 
1890cdf0e10cSrcweir /*************************************************************************
1891cdf0e10cSrcweir |*
1892cdf0e10cSrcweir |*    XPolyPolygon::operator=()
1893cdf0e10cSrcweir |*
1894cdf0e10cSrcweir |*    Beschreibung      POLY.SDW
1895cdf0e10cSrcweir |*    Ersterstellung    CL 27.01.93
1896cdf0e10cSrcweir |*    Letzte Aenderung  CL 27.01.93
1897cdf0e10cSrcweir |*
1898cdf0e10cSrcweir *************************************************************************/
1899cdf0e10cSrcweir 
operator =(const XPolyPolygon & rXPolyPoly)1900cdf0e10cSrcweir XPolyPolygon& XPolyPolygon::operator=( const XPolyPolygon& rXPolyPoly )
1901cdf0e10cSrcweir {
1902cdf0e10cSrcweir 	rXPolyPoly.pImpXPolyPolygon->nRefCount++;
1903cdf0e10cSrcweir 
1904cdf0e10cSrcweir 	if( pImpXPolyPolygon->nRefCount > 1 )
1905cdf0e10cSrcweir 		pImpXPolyPolygon->nRefCount--;
1906cdf0e10cSrcweir 	else
1907cdf0e10cSrcweir 		delete pImpXPolyPolygon;
1908cdf0e10cSrcweir 
1909cdf0e10cSrcweir 	pImpXPolyPolygon = rXPolyPoly.pImpXPolyPolygon;
1910cdf0e10cSrcweir 	return *this;
1911cdf0e10cSrcweir }
1912cdf0e10cSrcweir 
1913cdf0e10cSrcweir 
1914cdf0e10cSrcweir /*************************************************************************
1915cdf0e10cSrcweir |*
1916cdf0e10cSrcweir |*    XPolyPolygon::operator==()
1917cdf0e10cSrcweir |*
1918cdf0e10cSrcweir |*    Beschreibung      POLY.SDW
1919cdf0e10cSrcweir |*    Ersterstellung    CL  27.01.93
1920cdf0e10cSrcweir |*    Letzte Aenderung  Joe 27.01.93
1921cdf0e10cSrcweir |*
1922cdf0e10cSrcweir *************************************************************************/
1923cdf0e10cSrcweir 
operator ==(const XPolyPolygon & rXPolyPoly) const1924cdf0e10cSrcweir sal_Bool XPolyPolygon::operator==( const XPolyPolygon& rXPolyPoly ) const
1925cdf0e10cSrcweir {
1926cdf0e10cSrcweir 	if (pImpXPolyPolygon==rXPolyPoly.pImpXPolyPolygon) return sal_True;
1927cdf0e10cSrcweir 	return *pImpXPolyPolygon == *rXPolyPoly.pImpXPolyPolygon;
1928cdf0e10cSrcweir }
1929cdf0e10cSrcweir 
1930cdf0e10cSrcweir 
1931cdf0e10cSrcweir /*************************************************************************
1932cdf0e10cSrcweir |*
1933cdf0e10cSrcweir |*    XPolyPolygon::operator!=()
1934cdf0e10cSrcweir |*
1935cdf0e10cSrcweir |*    Beschreibung      POLY.SDW
1936cdf0e10cSrcweir |*    Ersterstellung    CL  27.01.93
1937cdf0e10cSrcweir |*    Letzte Aenderung  Joe 27.01.93
1938cdf0e10cSrcweir |*
1939cdf0e10cSrcweir *************************************************************************/
1940cdf0e10cSrcweir 
operator !=(const XPolyPolygon & rXPolyPoly) const1941cdf0e10cSrcweir sal_Bool XPolyPolygon::operator!=( const XPolyPolygon& rXPolyPoly ) const
1942cdf0e10cSrcweir {
1943cdf0e10cSrcweir 	if (pImpXPolyPolygon==rXPolyPoly.pImpXPolyPolygon) return sal_False;
1944cdf0e10cSrcweir 	return *pImpXPolyPolygon != *rXPolyPoly.pImpXPolyPolygon;
1945cdf0e10cSrcweir }
1946cdf0e10cSrcweir 
1947cdf0e10cSrcweir /*************************************************************************
1948cdf0e10cSrcweir |*
1949cdf0e10cSrcweir |*    XPolyPolygon::Translate()
1950cdf0e10cSrcweir |*
1951cdf0e10cSrcweir |*    Alle Polygone auf den uebergebenen Punkt verschieben
1952cdf0e10cSrcweir |*    Ersterstellung    ESO 25.01.95
1953cdf0e10cSrcweir |*    Letzte Aenderung  ESO 25.01.95
1954cdf0e10cSrcweir |*
1955cdf0e10cSrcweir *************************************************************************/
1956cdf0e10cSrcweir 
Translate(const Point & rTrans)1957cdf0e10cSrcweir void XPolyPolygon::Translate(const Point& rTrans)
1958cdf0e10cSrcweir {
1959cdf0e10cSrcweir 	CheckReference();
1960cdf0e10cSrcweir 
1961cdf0e10cSrcweir 	for (sal_uInt16 i = 0; i < Count(); i++)
1962cdf0e10cSrcweir 		pImpXPolyPolygon->aXPolyList.GetObject(i)->Translate(rTrans);
1963cdf0e10cSrcweir }
1964cdf0e10cSrcweir 
1965cdf0e10cSrcweir /*************************************************************************
1966cdf0e10cSrcweir |*
1967cdf0e10cSrcweir |*    XPolyPolygon::Rotate()
1968cdf0e10cSrcweir |*
1969cdf0e10cSrcweir |*    Alle Polygone um den Punkt rCenter drehen, Sinus und Cosinus
1970cdf0e10cSrcweir |*    muessen uebergeben werden
1971cdf0e10cSrcweir |*    Ersterstellung    ESO 25.01.95
1972cdf0e10cSrcweir |*    Letzte Aenderung  ESO 25.01.95
1973cdf0e10cSrcweir |*
1974cdf0e10cSrcweir *************************************************************************/
1975cdf0e10cSrcweir 
Rotate(const Point & rCenter,double fSin,double fCos)1976cdf0e10cSrcweir void XPolyPolygon::Rotate(const Point& rCenter, double fSin, double fCos)
1977cdf0e10cSrcweir {
1978cdf0e10cSrcweir 	CheckReference();
1979cdf0e10cSrcweir 
1980cdf0e10cSrcweir 	for (sal_uInt16 i = 0; i < Count(); i++)
1981cdf0e10cSrcweir 		pImpXPolyPolygon->aXPolyList.GetObject(i)->Rotate(rCenter, fSin, fCos);
1982cdf0e10cSrcweir }
1983cdf0e10cSrcweir 
1984cdf0e10cSrcweir /*************************************************************************
1985cdf0e10cSrcweir |*
1986cdf0e10cSrcweir |* Bestimme den linken, unteren Punkt des Polygons und richte das
1987cdf0e10cSrcweir |* Polygon so aus, dass dieser Punkt auf dem Index 0 liegt
1988cdf0e10cSrcweir |*
1989cdf0e10cSrcweir \************************************************************************/
1990cdf0e10cSrcweir 
Rotate20()1991cdf0e10cSrcweir void XPolyPolygon::Rotate20()
1992cdf0e10cSrcweir {
1993cdf0e10cSrcweir 	CheckReference();
1994cdf0e10cSrcweir 
1995cdf0e10cSrcweir 	for (sal_uInt16 i = 0; i < Count(); i++)
1996cdf0e10cSrcweir 		pImpXPolyPolygon->aXPolyList.GetObject(i)->Rotate20();
1997cdf0e10cSrcweir }
1998cdf0e10cSrcweir 
1999cdf0e10cSrcweir /*************************************************************************
2000cdf0e10cSrcweir |*
2001cdf0e10cSrcweir |*    XPolyPolygon::Rotate()
2002cdf0e10cSrcweir |*
2003cdf0e10cSrcweir |*    Alle Poylgone um den Punkt rCenter mit dem Winkel nAngle drehen
2004cdf0e10cSrcweir |*    Winkel in 10tel Grad, Wertebereich 0 - 3600
2005cdf0e10cSrcweir |*    Ersterstellung    ESO 25.01.95
2006cdf0e10cSrcweir |*    Letzte Aenderung  ESO 25.01.95
2007cdf0e10cSrcweir |*
2008cdf0e10cSrcweir *************************************************************************/
2009cdf0e10cSrcweir 
Rotate(const Point & rCenter,sal_uInt16 nAngle)2010cdf0e10cSrcweir void XPolyPolygon::Rotate(const Point& rCenter, sal_uInt16 nAngle)
2011cdf0e10cSrcweir {
2012cdf0e10cSrcweir 	nAngle %= 3600;
2013cdf0e10cSrcweir 
2014cdf0e10cSrcweir 	if ( nAngle != 0 )
2015cdf0e10cSrcweir 	{
2016cdf0e10cSrcweir 		double fAngle = F_PI * nAngle / 1800;
2017cdf0e10cSrcweir 		double fSin = sin(fAngle);
2018cdf0e10cSrcweir 		double fCos = cos(fAngle);
2019cdf0e10cSrcweir 		Rotate(rCenter, fSin, fCos);
2020cdf0e10cSrcweir 	}
2021cdf0e10cSrcweir }
2022cdf0e10cSrcweir 
2023cdf0e10cSrcweir /*************************************************************************
2024cdf0e10cSrcweir |*
2025cdf0e10cSrcweir |*    XPolyPolygon::Scale()
2026cdf0e10cSrcweir |*
2027cdf0e10cSrcweir |*    Alle Polygone in X- und/oder Y-Richtung skalieren
2028cdf0e10cSrcweir |*    Ersterstellung    ESO 01.02.95
2029cdf0e10cSrcweir |*    Letzte Aenderung  ESO 01.02.95
2030cdf0e10cSrcweir |*
2031cdf0e10cSrcweir *************************************************************************/
2032cdf0e10cSrcweir 
Scale(double fSx,double fSy)2033cdf0e10cSrcweir void XPolyPolygon::Scale(double fSx, double fSy)
2034cdf0e10cSrcweir {
2035cdf0e10cSrcweir 	CheckReference();
2036cdf0e10cSrcweir 
2037cdf0e10cSrcweir 	for (sal_uInt16 i = 0; i < Count(); i++)
2038cdf0e10cSrcweir 		pImpXPolyPolygon->aXPolyList.GetObject(i)->Scale(fSx, fSy);
2039cdf0e10cSrcweir }
2040cdf0e10cSrcweir 
2041cdf0e10cSrcweir /*************************************************************************
2042cdf0e10cSrcweir |*
2043cdf0e10cSrcweir |*    XPolyPolygon::SlantX()
2044cdf0e10cSrcweir |*
2045cdf0e10cSrcweir |*    Alle Polygone in X-Richtung um einen beliebigen Winkel kippen,
2046cdf0e10cSrcweir |*    bezogen auf eine Referenz-Y-Koordinate
2047cdf0e10cSrcweir |*    Ersterstellung    ESO 01.02.95
2048cdf0e10cSrcweir |*    Letzte Aenderung  ESO 01.02.95
2049cdf0e10cSrcweir |*
2050cdf0e10cSrcweir *************************************************************************/
2051cdf0e10cSrcweir 
SlantX(long nYRef,double fSin,double fCos)2052cdf0e10cSrcweir void XPolyPolygon::SlantX(long nYRef, double fSin, double fCos)
2053cdf0e10cSrcweir {
2054cdf0e10cSrcweir 	CheckReference();
2055cdf0e10cSrcweir 
2056cdf0e10cSrcweir 	for (sal_uInt16 i = 0; i < Count(); i++)
2057cdf0e10cSrcweir 		pImpXPolyPolygon->aXPolyList.GetObject(i)->SlantX(nYRef, fSin, fCos);
2058cdf0e10cSrcweir }
2059cdf0e10cSrcweir 
2060cdf0e10cSrcweir /*************************************************************************
2061cdf0e10cSrcweir |*
2062cdf0e10cSrcweir |*    XPolyPolygon::SlantY()
2063cdf0e10cSrcweir |*
2064cdf0e10cSrcweir |*    Alle Polygone in Y-Richtung um einen beliebigen Winkel kippen,
2065cdf0e10cSrcweir |*    bezogen auf eine Referenz-X-Koordinate
2066cdf0e10cSrcweir |*    Ersterstellung    ESO 01.02.95
2067cdf0e10cSrcweir |*    Letzte Aenderung  ESO 01.02.95
2068cdf0e10cSrcweir |*
2069cdf0e10cSrcweir *************************************************************************/
2070cdf0e10cSrcweir 
SlantY(long nXRef,double fSin,double fCos)2071cdf0e10cSrcweir void XPolyPolygon::SlantY(long nXRef, double fSin, double fCos)
2072cdf0e10cSrcweir {
2073cdf0e10cSrcweir 	CheckReference();
2074cdf0e10cSrcweir 
2075cdf0e10cSrcweir 	for (sal_uInt16 i = 0; i < Count(); i++)
2076cdf0e10cSrcweir 		pImpXPolyPolygon->aXPolyList.GetObject(i)->SlantY(nXRef, fSin, fCos);
2077cdf0e10cSrcweir }
2078cdf0e10cSrcweir 
2079cdf0e10cSrcweir /*************************************************************************
2080cdf0e10cSrcweir |*
2081cdf0e10cSrcweir |*    XPolygon::Distort()
2082cdf0e10cSrcweir |*
2083cdf0e10cSrcweir |*    XPolygon verzerren, indem die Koordinaten relativ zu einem
2084cdf0e10cSrcweir |*    Referenzrechteck in ein beliebiges Viereck skaliert werden
2085cdf0e10cSrcweir |*    Zuordnung der Viereck-Punkte im Polygon zum Referenzrechteck:
2086cdf0e10cSrcweir |*    0: links oben      0----1
2087cdf0e10cSrcweir |*    1: rechts oben     |    |
2088cdf0e10cSrcweir |*    2: rechts unten    3----2
2089cdf0e10cSrcweir |*    3: links unten
2090cdf0e10cSrcweir |*    Ersterstellung    ESO 07.07.95
2091cdf0e10cSrcweir |*    Letzte Aenderung  ESO 07.07.95
2092cdf0e10cSrcweir |*
2093cdf0e10cSrcweir *************************************************************************/
2094cdf0e10cSrcweir 
Distort(const Rectangle & rRefRect,const XPolygon & rDistortedRect)2095cdf0e10cSrcweir void XPolyPolygon::Distort(const Rectangle& rRefRect,
2096cdf0e10cSrcweir 						   const XPolygon& rDistortedRect)
2097cdf0e10cSrcweir {
2098cdf0e10cSrcweir 	CheckReference();
2099cdf0e10cSrcweir 
2100cdf0e10cSrcweir 	for (sal_uInt16 i = 0; i < Count(); i++)
2101cdf0e10cSrcweir 		pImpXPolyPolygon->aXPolyList.GetObject(i)->Distort(rRefRect,
2102cdf0e10cSrcweir 														   rDistortedRect);
2103cdf0e10cSrcweir }
2104cdf0e10cSrcweir 
getB2DPolyPolygon() const2105cdf0e10cSrcweir basegfx::B2DPolyPolygon XPolyPolygon::getB2DPolyPolygon() const
2106cdf0e10cSrcweir {
2107cdf0e10cSrcweir 	basegfx::B2DPolyPolygon aRetval;
2108cdf0e10cSrcweir 
2109cdf0e10cSrcweir 	for(sal_uInt16 a(0L); a < Count(); a++)
2110cdf0e10cSrcweir 	{
2111cdf0e10cSrcweir 		const XPolygon& rPoly = (*this)[a];
2112cdf0e10cSrcweir 		aRetval.append(rPoly.getB2DPolygon());
2113cdf0e10cSrcweir 	}
2114cdf0e10cSrcweir 
2115cdf0e10cSrcweir 	return aRetval;
2116cdf0e10cSrcweir }
2117cdf0e10cSrcweir 
XPolyPolygon(const basegfx::B2DPolyPolygon & rPolyPolygon)2118cdf0e10cSrcweir XPolyPolygon::XPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPolygon)
2119cdf0e10cSrcweir {
2120cdf0e10cSrcweir 	DBG_CTOR(XPolyPolygon,NULL);
2121cdf0e10cSrcweir 	pImpXPolyPolygon = new ImpXPolyPolygon( 16, 16 );
2122cdf0e10cSrcweir 
2123cdf0e10cSrcweir 	for(sal_uInt32 a(0L); a < rPolyPolygon.count(); a++)
2124cdf0e10cSrcweir 	{
2125cdf0e10cSrcweir 		basegfx::B2DPolygon aCandidate = rPolyPolygon.getB2DPolygon(a);
2126cdf0e10cSrcweir 		XPolygon aNewPoly(aCandidate);
2127cdf0e10cSrcweir 		Insert(aNewPoly);
2128cdf0e10cSrcweir 	}
2129cdf0e10cSrcweir }
2130cdf0e10cSrcweir 
2131cdf0e10cSrcweir // eof
2132