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