fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / svx / source / xoutdev / _xpoly.cxx
blob2573ba3367ec281731df0876afee85135987eca6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <osl/endian.h>
21 #include <tools/stream.hxx>
22 #include <tools/debug.hxx>
23 #include <tools/poly.hxx>
24 #include <tools/helpers.hxx>
25 #include <tools/gen.hxx>
27 #include <svx/xpoly.hxx>
28 #include "xpolyimp.hxx"
29 #include <basegfx/polygon/b2dpolygon.hxx>
30 #include <basegfx/point/b2dpoint.hxx>
31 #include <basegfx/vector/b2dvector.hxx>
32 #include <basegfx/polygon/b2dpolygontools.hxx>
33 #include <basegfx/range/b2drange.hxx>
34 #include <basegfx/numeric/ftools.hxx>
36 DBG_NAME(XPolygon);
37 DBG_NAME(XPolyPolygon);
39 /*************************************************************************
41 |* ImpXPolygon::ImpXPolygon()
43 *************************************************************************/
45 ImpXPolygon::ImpXPolygon( sal_uInt16 nInitSize, sal_uInt16 _nResize )
47 pPointAry = NULL;
48 pFlagAry = NULL;
49 bDeleteOldPoints = sal_False;
50 nSize = 0;
51 nResize = _nResize;
52 nPoints = 0;
53 nRefCount = 1;
55 Resize( nInitSize );
58 /*************************************************************************
60 |* ImpXPolygon::ImpXPolygon()
62 *************************************************************************/
64 ImpXPolygon::ImpXPolygon( const ImpXPolygon& rImpXPoly )
66 ( (ImpXPolygon&) rImpXPoly ).CheckPointDelete();
68 pPointAry = NULL;
69 pFlagAry = NULL;
70 bDeleteOldPoints = sal_False;
71 nSize = 0;
72 ImpXPolygon::nResize = rImpXPoly.nResize;
73 nPoints = 0;
74 nRefCount = 1;
76 Resize( rImpXPoly.nSize );
78 // Kopieren
79 nPoints = rImpXPoly.nPoints;
80 memcpy( pPointAry, rImpXPoly.pPointAry, nSize*sizeof( Point ) );
81 memcpy( pFlagAry, rImpXPoly.pFlagAry, nSize );
84 /*************************************************************************
86 |* ImpXPolygon::~ImpXPolygon()
88 *************************************************************************/
90 ImpXPolygon::~ImpXPolygon()
92 delete[] (char*) pPointAry;
93 delete[] pFlagAry;
94 if ( bDeleteOldPoints )
95 delete[] (char*) pOldPointAry;
98 /*************************************************************************
100 |* ImpXPolygon::operator==()
102 *************************************************************************/
105 bool ImpXPolygon::operator==(const ImpXPolygon& rImpXPoly) const
107 return nPoints==rImpXPoly.nPoints &&
108 (nPoints==0 ||
109 (memcmp(pPointAry,rImpXPoly.pPointAry,nPoints*sizeof(Point))==0 &&
110 memcmp(pFlagAry,rImpXPoly.pFlagAry,nPoints)==0));
113 /*************************************************************************
115 |* ImpXPolygon::Resize()
117 |* !!! Polygongroesse aendern - wenn bDeletePoints sal_False, dann den
118 |* Point-Array nicht loeschen, sondern in pOldPointAry sichern und
119 |* das Flag bDeleteOldPoints setzen. Beim naechsten Zugriff wird
120 |* das Array dann geloescht.
121 |* Damit wird verhindert, dass bei XPoly[n] = XPoly[0] durch ein
122 |* Resize der fuer den rechten Ausdruck verwendete Point-Array
123 |* vorzeitig geloescht wird.
125 *************************************************************************/
127 void ImpXPolygon::Resize( sal_uInt16 nNewSize, sal_Bool bDeletePoints )
129 if( nNewSize == nSize )
130 return;
132 sal_uInt8* pOldFlagAry = pFlagAry;
133 sal_uInt16 nOldSize = nSize;
135 CheckPointDelete();
136 pOldPointAry = pPointAry;
138 // Neue Groesse auf vielfaches von nResize runden, sofern Objekt
139 // nicht neu angelegt wurde (nSize != 0)
140 if ( nSize != 0 && nNewSize > nSize )
142 DBG_ASSERT(nResize, "Resize-Versuch trotz nResize = 0 !");
143 nNewSize = nSize + ((nNewSize-nSize-1) / nResize + 1) * nResize;
145 // Punkt Array erzeugen
146 nSize = nNewSize;
147 pPointAry = (Point*)new char[ nSize*sizeof( Point ) ];
148 memset( pPointAry, 0, nSize*sizeof( Point ) );
150 // Flag Array erzeugen
151 pFlagAry = new sal_uInt8[ nSize ];
152 memset( pFlagAry, 0, nSize );
154 // Eventuell umkopieren
155 if( nOldSize )
157 if( nOldSize < nSize )
159 memcpy( pPointAry, pOldPointAry, nOldSize*sizeof( Point ) );
160 memcpy( pFlagAry, pOldFlagAry, nOldSize );
162 else
164 memcpy( pPointAry, pOldPointAry, nSize*sizeof( Point ) );
165 memcpy( pFlagAry, pOldFlagAry, nSize );
167 // Anzahl der gueltigen Punkte anpassen
168 if( nPoints > nSize )
169 nPoints = nSize;
171 if ( bDeletePoints ) delete[] (char*) pOldPointAry;
172 else bDeleteOldPoints = sal_True;
173 delete[] pOldFlagAry;
178 /*************************************************************************
180 |* ImpXPolygon::InsertSpace()
182 *************************************************************************/
184 void ImpXPolygon::InsertSpace( sal_uInt16 nPos, sal_uInt16 nCount )
186 CheckPointDelete();
188 if ( nPos > nPoints )
189 nPos = nPoints;
191 // Wenn Polygon zu klein dann groesser machen
192 if( (nPoints + nCount) > nSize )
193 Resize( nPoints + nCount );
195 // Wenn nicht hinter dem letzten Punkt eingefuegt wurde,
196 // den Rest nach hinten schieben
197 if( nPos < nPoints )
199 sal_uInt16 nMove = nPoints - nPos;
200 memmove( &pPointAry[nPos+nCount], &pPointAry[nPos],
201 nMove * sizeof(Point) );
202 memmove( &pFlagAry[nPos+nCount], &pFlagAry[nPos], nMove );
204 memset( &pPointAry[nPos], 0, nCount * sizeof( Point ) );
205 memset( &pFlagAry [nPos], 0, nCount );
207 nPoints = nPoints + nCount;
211 /*************************************************************************
213 |* ImpXPolygon::Remove()
215 *************************************************************************/
217 void ImpXPolygon::Remove( sal_uInt16 nPos, sal_uInt16 nCount )
219 CheckPointDelete();
221 if( (nPos + nCount) <= nPoints )
223 sal_uInt16 nMove = nPoints - nPos - nCount;
225 if( nMove )
227 memmove( &pPointAry[nPos], &pPointAry[nPos+nCount],
228 nMove * sizeof(Point) );
229 memmove( &pFlagAry[nPos], &pFlagAry[nPos+nCount], nMove );
231 memset( &pPointAry[nPoints - nCount], 0, nCount * sizeof( Point ) );
232 memset( &pFlagAry [nPoints - nCount], 0, nCount );
233 nPoints = nPoints - nCount;
238 /*************************************************************************
240 |* XPolygon::XPolygon()
242 *************************************************************************/
244 XPolygon::XPolygon( sal_uInt16 nSize, sal_uInt16 nResize )
246 DBG_CTOR(XPolygon,NULL);
247 pImpXPolygon = new ImpXPolygon( nSize, nResize );
250 /*************************************************************************
252 |* XPolygon::XPolygon()
254 *************************************************************************/
256 XPolygon::XPolygon( const XPolygon& rXPoly )
258 DBG_CTOR(XPolygon,NULL);
259 pImpXPolygon = rXPoly.pImpXPolygon;
260 pImpXPolygon->nRefCount++;
263 /*************************************************************************
265 |* XPolygon::XPolygon()
267 |* Rechteck (auch mit abgerundeten Ecken) als Bezierpolygon erzeugen
269 *************************************************************************/
271 XPolygon::XPolygon(const Rectangle& rRect, long nRx, long nRy)
273 DBG_CTOR(XPolygon,NULL);
274 pImpXPolygon = new ImpXPolygon(17);
275 long nWh = (rRect.GetWidth() - 1) / 2;
276 long nHh = (rRect.GetHeight() - 1) / 2;
278 if ( nRx > nWh ) nRx = nWh;
279 if ( nRy > nHh ) nRy = nHh;
281 // Rx negativ, damit Umlauf im Uhrzeigersinn erfolgt
282 nRx = -nRx;
284 // Faktor fuer Kontrollpunkte der Bezierkurven: 8/3 * (sin(45g) - 0.5)
285 long nXHdl = (long)(0.552284749 * nRx);
286 long nYHdl = (long)(0.552284749 * nRy);
287 sal_uInt16 nPos = 0;
289 if ( nRx && nRy )
291 Point aCenter;
293 for (sal_uInt16 nQuad = 0; nQuad < 4; nQuad++)
295 switch ( nQuad )
297 case 0: aCenter = rRect.TopLeft();
298 aCenter.X() -= nRx;
299 aCenter.Y() += nRy;
300 break;
301 case 1: aCenter = rRect.TopRight();
302 aCenter.X() += nRx;
303 aCenter.Y() += nRy;
304 break;
305 case 2: aCenter = rRect.BottomRight();
306 aCenter.X() += nRx;
307 aCenter.Y() -= nRy;
308 break;
309 case 3: aCenter = rRect.BottomLeft();
310 aCenter.X() -= nRx;
311 aCenter.Y() -= nRy;
312 break;
314 GenBezArc(aCenter, nRx, nRy, nXHdl, nYHdl, 0, 900, nQuad, nPos);
315 pImpXPolygon->pFlagAry[nPos ] = (sal_uInt8) XPOLY_SMOOTH;
316 pImpXPolygon->pFlagAry[nPos+3] = (sal_uInt8) XPOLY_SMOOTH;
317 nPos += 4;
320 else
322 pImpXPolygon->pPointAry[nPos++] = rRect.TopLeft();
323 pImpXPolygon->pPointAry[nPos++] = rRect.TopRight();
324 pImpXPolygon->pPointAry[nPos++] = rRect.BottomRight();
325 pImpXPolygon->pPointAry[nPos++] = rRect.BottomLeft();
327 pImpXPolygon->pPointAry[nPos] = pImpXPolygon->pPointAry[0];
328 pImpXPolygon->nPoints = nPos + 1;
331 /*************************************************************************
333 |* XPolygon::XPolygon()
335 |* Ellipsen(bogen) als Bezierpolygon erzeugen
337 *************************************************************************/
339 XPolygon::XPolygon(const Point& rCenter, long nRx, long nRy,
340 sal_uInt16 nStartAngle, sal_uInt16 nEndAngle, sal_Bool bClose)
342 DBG_CTOR(XPolygon,NULL);
343 pImpXPolygon = new ImpXPolygon(17);
345 nStartAngle %= 3600;
346 if ( nEndAngle > 3600 ) nEndAngle %= 3600;
347 bool bFull = (nStartAngle == 0 && nEndAngle == 3600);
349 // Faktor fuer Kontrollpunkte der Bezierkurven: 8/3 * (sin(45g) - 0.5)
350 long nXHdl = (long)(0.552284749 * nRx);
351 long nYHdl = (long)(0.552284749 * nRy);
352 sal_uInt16 nPos = 0;
353 sal_Bool bLoopEnd = sal_False;
357 sal_uInt16 nA1, nA2;
358 sal_uInt16 nQuad = nStartAngle / 900;
359 if ( nQuad == 4 ) nQuad = 0;
360 bLoopEnd = CheckAngles(nStartAngle, nEndAngle, nA1, nA2);
361 GenBezArc(rCenter, nRx, nRy, nXHdl, nYHdl, nA1, nA2, nQuad, nPos);
362 nPos += 3;
363 if ( !bLoopEnd )
364 pImpXPolygon->pFlagAry[nPos] = (sal_uInt8) XPOLY_SMOOTH;
366 } while ( !bLoopEnd );
368 // Wenn kein Vollkreis, dann ggf. Enden mit Mittelpunkt verbinden
369 if ( !bFull && bClose )
370 pImpXPolygon->pPointAry[++nPos] = rCenter;
372 if ( bFull )
374 pImpXPolygon->pFlagAry[0 ] = (sal_uInt8) XPOLY_SMOOTH;
375 pImpXPolygon->pFlagAry[nPos] = (sal_uInt8) XPOLY_SMOOTH;
377 pImpXPolygon->nPoints = nPos + 1;
380 /*************************************************************************
382 |* XPolygon::~XPolygon()
384 *************************************************************************/
386 XPolygon::~XPolygon()
388 DBG_DTOR(XPolygon,NULL);
389 if( pImpXPolygon->nRefCount > 1 )
390 pImpXPolygon->nRefCount--;
391 else
392 delete pImpXPolygon;
395 /*************************************************************************
397 |* XPolygon::CheckReference()
399 |* Referenzzaehler desImpXPoly pruefen und ggf. von diesem abkoppeln
401 *************************************************************************/
403 void XPolygon::CheckReference()
405 if( pImpXPolygon->nRefCount > 1 )
407 pImpXPolygon->nRefCount--;
408 pImpXPolygon = new ImpXPolygon( *pImpXPolygon );
412 /*************************************************************************
414 |* XPolygon::SetPointCount()
416 *************************************************************************/
418 void XPolygon::SetPointCount( sal_uInt16 nPoints )
420 pImpXPolygon->CheckPointDelete();
421 CheckReference();
423 if( pImpXPolygon->nSize < nPoints )
424 pImpXPolygon->Resize( nPoints );
426 if ( nPoints < pImpXPolygon->nPoints )
428 sal_uInt16 nSize = pImpXPolygon->nPoints - nPoints;
429 memset( &pImpXPolygon->pPointAry[nPoints], 0, nSize * sizeof( Point ) );
430 memset( &pImpXPolygon->pFlagAry [nPoints], 0, nSize );
432 pImpXPolygon->nPoints = nPoints;
435 /*************************************************************************
437 |* XPolygon::GetPointCount()
439 *************************************************************************/
441 sal_uInt16 XPolygon::GetPointCount() const
443 pImpXPolygon->CheckPointDelete();
444 return pImpXPolygon->nPoints;
447 /*************************************************************************
449 |* XPolygon::Insert()
451 *************************************************************************/
453 void XPolygon::Insert( sal_uInt16 nPos, const Point& rPt, XPolyFlags eFlags )
455 CheckReference();
456 if (nPos>pImpXPolygon->nPoints) nPos=pImpXPolygon->nPoints;
457 pImpXPolygon->InsertSpace( nPos, 1 );
458 pImpXPolygon->pPointAry[nPos] = rPt;
459 pImpXPolygon->pFlagAry[nPos] = (sal_uInt8)eFlags;
462 /*************************************************************************
464 |* XPolygon::Insert()
466 *************************************************************************/
468 void XPolygon::Insert( sal_uInt16 nPos, const XPolygon& rXPoly )
470 CheckReference();
471 if (nPos>pImpXPolygon->nPoints) nPos=pImpXPolygon->nPoints;
473 sal_uInt16 nPoints = rXPoly.GetPointCount();
475 pImpXPolygon->InsertSpace( nPos, nPoints );
477 memcpy( &(pImpXPolygon->pPointAry[nPos]),
478 rXPoly.pImpXPolygon->pPointAry,
479 nPoints*sizeof( Point ) );
480 memcpy( &(pImpXPolygon->pFlagAry[nPos]),
481 rXPoly.pImpXPolygon->pFlagAry,
482 nPoints );
485 /*************************************************************************
487 |* XPolygon::Remove()
489 *************************************************************************/
491 void XPolygon::Remove( sal_uInt16 nPos, sal_uInt16 nCount )
493 CheckReference();
494 pImpXPolygon->Remove( nPos, nCount );
497 /*************************************************************************
499 |* XPolygon::Move()
501 *************************************************************************/
503 void XPolygon::Move( long nHorzMove, long nVertMove )
505 if ( !nHorzMove && !nVertMove )
506 return;
508 CheckReference();
510 // Punkte verschieben
511 sal_uInt16 nCount = pImpXPolygon->nPoints;
512 for ( sal_uInt16 i = 0; i < nCount; i++ )
514 Point* pPt = &(pImpXPolygon->pPointAry[i]);
515 pPt->X() += nHorzMove;
516 pPt->Y() += nVertMove;
520 /*************************************************************************
522 |* XPolygon::GetBoundRect()
524 *************************************************************************/
526 Rectangle XPolygon::GetBoundRect() const
528 pImpXPolygon->CheckPointDelete();
529 Rectangle aRetval;
531 if(pImpXPolygon->nPoints)
533 // #i37709#
534 // For historical reasons the control points are not part of the
535 // BoundRect. This makes it necessary to subdivide the polygon to
536 // get a relatively correct BoundRect. Numerically, this is not
537 // correct and never was.
539 const basegfx::B2DRange aPolygonRange(basegfx::tools::getRange(getB2DPolygon()));
540 aRetval = Rectangle(
541 FRound(aPolygonRange.getMinX()), FRound(aPolygonRange.getMinY()),
542 FRound(aPolygonRange.getMaxX()), FRound(aPolygonRange.getMaxY()));
545 return aRetval;
548 /*************************************************************************
550 |* XPolygon::operator[]()
552 *************************************************************************/
554 const Point& XPolygon::operator[]( sal_uInt16 nPos ) const
556 DBG_ASSERT(nPos < pImpXPolygon->nPoints, "Ungueltiger Index bei const-Arrayzugriff auf XPolygon");
558 pImpXPolygon->CheckPointDelete();
559 return pImpXPolygon->pPointAry[nPos];
562 /*************************************************************************
564 |* XPolygon::operator[]()
566 *************************************************************************/
568 Point& XPolygon::operator[]( sal_uInt16 nPos )
570 pImpXPolygon->CheckPointDelete();
571 CheckReference();
573 if( nPos >= pImpXPolygon->nSize )
575 DBG_ASSERT(pImpXPolygon->nResize, "Ungueltiger Index bei Arrayzugriff auf XPolygon");
576 pImpXPolygon->Resize(nPos + 1, sal_False);
578 if( nPos >= pImpXPolygon->nPoints )
579 pImpXPolygon->nPoints = nPos + 1;
581 return pImpXPolygon->pPointAry[nPos];
584 /*************************************************************************
586 |* XPolygon::operator=()
588 |* Beschreibung Zuweisungsoperator
590 *************************************************************************/
592 XPolygon& XPolygon::operator=( const XPolygon& rXPoly )
594 pImpXPolygon->CheckPointDelete();
596 rXPoly.pImpXPolygon->nRefCount++;
598 if( pImpXPolygon->nRefCount > 1 )
599 pImpXPolygon->nRefCount--;
600 else
601 delete pImpXPolygon;
603 pImpXPolygon = rXPoly.pImpXPolygon;
604 return *this;
607 /*************************************************************************
609 |* XPolygon::operator==()
611 |* Beschreibung Gleichheitsoperator
613 *************************************************************************/
615 sal_Bool XPolygon::operator==( const XPolygon& rXPoly ) const
617 pImpXPolygon->CheckPointDelete();
618 if (rXPoly.pImpXPolygon==pImpXPolygon) return sal_True;
619 return *rXPoly.pImpXPolygon == *pImpXPolygon;
622 /*************************************************************************
624 |* XPolygon::operator!=()
626 |* Beschreibung Ungleichheitsoperator
628 *************************************************************************/
630 sal_Bool XPolygon::operator!=( const XPolygon& rXPoly ) const
632 pImpXPolygon->CheckPointDelete();
633 if (rXPoly.pImpXPolygon==pImpXPolygon) return sal_False;
634 return *rXPoly.pImpXPolygon != *pImpXPolygon;
637 /*************************************************************************
639 |* XPolygon::GetFlags()
641 |* Flags fuer den Punkt an der Position nPos zurueckgeben
643 *************************************************************************/
645 XPolyFlags XPolygon::GetFlags( sal_uInt16 nPos ) const
647 pImpXPolygon->CheckPointDelete();
648 return (XPolyFlags) pImpXPolygon->pFlagAry[nPos];
651 /*************************************************************************
653 |* XPolygon::SetFlags()
655 |* Flags fuer den Punkt an der Position nPos setzen
657 *************************************************************************/
659 void XPolygon::SetFlags( sal_uInt16 nPos, XPolyFlags eFlags )
661 pImpXPolygon->CheckPointDelete();
662 CheckReference();
663 pImpXPolygon->pFlagAry[nPos] = (sal_uInt8) eFlags;
666 /*************************************************************************
668 |* XPolygon::IsControl()
670 |* Kurzform zur Abfrage des CONTROL-Flags
672 *************************************************************************/
674 sal_Bool XPolygon::IsControl(sal_uInt16 nPos) const
676 return ( (XPolyFlags) pImpXPolygon->pFlagAry[nPos] == XPOLY_CONTROL );
679 /*************************************************************************
681 |* XPolygon::IsSmooth()
683 |* Kurzform zur Abfrage von SMOOTH- und SYMMTR-Flag
685 *************************************************************************/
687 sal_Bool XPolygon::IsSmooth(sal_uInt16 nPos) const
689 XPolyFlags eFlag = (XPolyFlags) pImpXPolygon->pFlagAry[nPos];
690 return ( eFlag == XPOLY_SMOOTH || eFlag == XPOLY_SYMMTR );
693 /*************************************************************************
695 |* XPolygon::CalcDistance()
697 |* Abstand zwischen zwei Punkten berechnen
699 *************************************************************************/
701 double XPolygon::CalcDistance(sal_uInt16 nP1, sal_uInt16 nP2)
703 const Point& rP1 = pImpXPolygon->pPointAry[nP1];
704 const Point& rP2 = pImpXPolygon->pPointAry[nP2];
705 double fDx = rP2.X() - rP1.X();
706 double fDy = rP2.Y() - rP1.Y();
707 return sqrt(fDx * fDx + fDy * fDy);
710 /*************************************************************************
712 |* XPolygon::SubdivideBezier()
714 |* Bezierkurve unterteilen
716 *************************************************************************/
718 void XPolygon::SubdivideBezier(sal_uInt16 nPos, sal_Bool bCalcFirst, double fT)
720 Point* pPoints = pImpXPolygon->pPointAry;
721 double fT2 = fT * fT;
722 double fT3 = fT * fT2;
723 double fU = 1.0 - fT;
724 double fU2 = fU * fU;
725 double fU3 = fU * fU2;
726 sal_uInt16 nIdx = nPos;
727 short nPosInc, nIdxInc;
729 if ( bCalcFirst )
731 nPos += 3;
732 nPosInc = -1;
733 nIdxInc = 0;
735 else
737 nPosInc = 1;
738 nIdxInc = 1;
740 pPoints[nPos].X() = (long) (fU3 * pPoints[nIdx ].X() +
741 fT * fU2 * pPoints[nIdx+1].X() * 3 +
742 fT2 * fU * pPoints[nIdx+2].X() * 3 +
743 fT3 * pPoints[nIdx+3].X());
744 pPoints[nPos].Y() = (long) (fU3 * pPoints[nIdx ].Y() +
745 fT * fU2 * pPoints[nIdx+1].Y() * 3 +
746 fT2 * fU * pPoints[nIdx+2].Y() * 3 +
747 fT3 * pPoints[nIdx+3].Y());
748 nPos = nPos + nPosInc;
749 nIdx = nIdx + nIdxInc;
750 pPoints[nPos].X() = (long) (fU2 * pPoints[nIdx ].X() +
751 fT * fU * pPoints[nIdx+1].X() * 2 +
752 fT2 * pPoints[nIdx+2].X());
753 pPoints[nPos].Y() = (long) (fU2 * pPoints[nIdx ].Y() +
754 fT * fU * pPoints[nIdx+1].Y() * 2 +
755 fT2 * pPoints[nIdx+2].Y());
756 nPos = nPos + nPosInc;
757 nIdx = nIdx + nIdxInc;
758 pPoints[nPos].X() = (long) (fU * pPoints[nIdx ].X() +
759 fT * pPoints[nIdx+1].X());
760 pPoints[nPos].Y() = (long) (fU * pPoints[nIdx ].Y() +
761 fT * pPoints[nIdx+1].Y());
764 /************************************************************************/
766 void XPolygon::GenBezArc(const Point& rCenter, long nRx, long nRy,
767 long nXHdl, long nYHdl, sal_uInt16 nStart, sal_uInt16 nEnd,
768 sal_uInt16 nQuad, sal_uInt16 nFirst)
770 Point* pPoints = pImpXPolygon->pPointAry;
771 pPoints[nFirst ] = rCenter;
772 pPoints[nFirst+3] = rCenter;
774 if ( nQuad == 1 || nQuad == 2 )
776 nRx = -nRx; nXHdl = -nXHdl;
778 if ( nQuad == 0 || nQuad == 1 )
780 nRy = -nRy; nYHdl = -nYHdl;
783 if ( nQuad == 0 || nQuad == 2 )
785 pPoints[nFirst].X() += nRx; pPoints[nFirst+3].Y() += nRy;
787 else
789 pPoints[nFirst].Y() += nRy; pPoints[nFirst+3].X() += nRx;
791 pPoints[nFirst+1] = pPoints[nFirst];
792 pPoints[nFirst+2] = pPoints[nFirst+3];
794 if ( nQuad == 0 || nQuad == 2 )
796 pPoints[nFirst+1].Y() += nYHdl; pPoints[nFirst+2].X() += nXHdl;
798 else
800 pPoints[nFirst+1].X() += nXHdl; pPoints[nFirst+2].Y() += nYHdl;
802 if ( nStart > 0 )
803 SubdivideBezier(nFirst, sal_False, (double)nStart / 900);
804 if ( nEnd < 900 )
805 SubdivideBezier(nFirst, sal_True, (double)(nEnd-nStart) / (900-nStart));
806 SetFlags(nFirst+1, XPOLY_CONTROL);
807 SetFlags(nFirst+2, XPOLY_CONTROL);
810 /************************************************************************/
812 sal_Bool XPolygon::CheckAngles(sal_uInt16& nStart, sal_uInt16 nEnd, sal_uInt16& nA1, sal_uInt16& nA2)
814 if ( nStart == 3600 ) nStart = 0;
815 if ( nEnd == 0 ) nEnd = 3600;
816 sal_uInt16 nStPrev = nStart;
817 sal_uInt16 nMax = (nStart / 900 + 1) * 900;
818 sal_uInt16 nMin = nMax - 900;
820 if ( nEnd >= nMax || nEnd <= nStart ) nA2 = 900;
821 else nA2 = nEnd - nMin;
822 nA1 = nStart - nMin;
823 nStart = nMax;
825 // sal_True zurueck, falls letztes Segment berechnet wurde
826 return (nStPrev < nEnd && nStart >= nEnd);
829 /*************************************************************************
831 |* XPolygon::CalcSmoothJoin()
833 |* glatten Uebergang zu einer Bezierkurve berechnen, indem der
834 |* entsprechende Punkt auf die Verbindungslinie von zwei anderen
835 |* Punkten projiziert wird
836 |* Center = End- bzw. Anfangspunkt der Bezierkurve
837 |* Drag = der bewegte Punkt, der die Verschiebung von Pnt vorgibt
838 |* Pnt = der zu modifizierende Punkt
839 |* Wenn Center am Anfang bzw. Ende des Polygons liegt, wird Pnt
840 |* auf die entgegengesetzte Seite verlegt
842 \************************************************************************/
844 void XPolygon::CalcSmoothJoin(sal_uInt16 nCenter, sal_uInt16 nDrag, sal_uInt16 nPnt)
846 CheckReference();
848 // sal_uInt16 nMaxPnt = pImpXPolygon->nPoints - 1;
850 // if ( nCenter == nMaxPnt ) nPnt = 1;
851 // else if ( nCenter == 0 ) nPnt = nMaxPnt - 1;
853 // Wenn nPnt kein Control-Punkt, d.h. nicht verschiebbar, dann
854 // statt dessen nDrag auf der Achse nCenter-nPnt verschieben
855 if ( !IsControl(nPnt) )
857 sal_uInt16 nTmp = nDrag;
858 nDrag = nPnt;
859 nPnt = nTmp;
861 Point* pPoints = pImpXPolygon->pPointAry;
862 Point aDiff = pPoints[nDrag] - pPoints[nCenter];
863 double fDiv = CalcDistance(nCenter, nDrag);
865 if ( fDiv )
867 double fRatio = CalcDistance(nCenter, nPnt) / fDiv;
868 // bei SMOOTH bisherige Laenge beibehalten
869 if ( GetFlags(nCenter) == XPOLY_SMOOTH || !IsControl(nDrag) )
871 aDiff.X() = (long) (fRatio * aDiff.X());
872 aDiff.Y() = (long) (fRatio * aDiff.Y());
874 pPoints[nPnt] = pPoints[nCenter] - aDiff;
878 /*************************************************************************
880 |* XPolygon::CalcTangent()
882 |* Tangente fuer den Uebergang zwischen zwei Bezierkurven berechnen
883 |* Center = End- bzw. Anfangspunkt der Bezierkurven
884 |* Prev = vorheriger Zugpunkt
885 |* Next = naechster Zugpunkt
887 \************************************************************************/
889 void XPolygon::CalcTangent(sal_uInt16 nCenter, sal_uInt16 nPrev, sal_uInt16 nNext)
891 CheckReference();
893 double fAbsLen = CalcDistance(nNext, nPrev);
895 if ( fAbsLen )
897 const Point& rCenter = pImpXPolygon->pPointAry[nCenter];
898 Point& rNext = pImpXPolygon->pPointAry[nNext];
899 Point& rPrev = pImpXPolygon->pPointAry[nPrev];
900 Point aDiff = rNext - rPrev;
901 double fNextLen = CalcDistance(nCenter, nNext) / fAbsLen;
902 double fPrevLen = CalcDistance(nCenter, nPrev) / fAbsLen;
904 // bei SYMMTR gleiche Laenge fuer beide Seiten
905 if ( GetFlags(nCenter) == XPOLY_SYMMTR )
907 fPrevLen = (fNextLen + fPrevLen) / 2;
908 fNextLen = fPrevLen;
910 rNext.X() = rCenter.X() + (long) (fNextLen * aDiff.X());
911 rNext.Y() = rCenter.Y() + (long) (fNextLen * aDiff.Y());
912 rPrev.X() = rCenter.X() - (long) (fPrevLen * aDiff.X());
913 rPrev.Y() = rCenter.Y() - (long) (fPrevLen * aDiff.Y());
917 /*************************************************************************
919 |* XPolygon::PointsToBezier()
921 |* wandelt vier Polygonpunkte in eine Bezierkurve durch diese Punkte um
923 \************************************************************************/
925 void XPolygon::PointsToBezier(sal_uInt16 nFirst)
927 double nFullLength, nPart1Length, nPart2Length;
928 double fX0, fY0, fX1, fY1, fX2, fY2, fX3, fY3;
929 double fTx1, fTx2, fTy1, fTy2;
930 double fT1, fU1, fT2, fU2, fV;
931 Point* pPoints = pImpXPolygon->pPointAry;
933 if ( nFirst > pImpXPolygon->nPoints - 4 || IsControl(nFirst) ||
934 IsControl(nFirst+1) || IsControl(nFirst+2) || IsControl(nFirst+3) )
935 return;
937 CheckReference();
939 fTx1 = pPoints[nFirst+1].X();
940 fTy1 = pPoints[nFirst+1].Y();
941 fTx2 = pPoints[nFirst+2].X();
942 fTy2 = pPoints[nFirst+2].Y();
943 fX0 = pPoints[nFirst ].X();
944 fY0 = pPoints[nFirst ].Y();
945 fX3 = pPoints[nFirst+3].X();
946 fY3 = pPoints[nFirst+3].Y();
948 nPart1Length = CalcDistance(nFirst, nFirst+1);
949 nPart2Length = nPart1Length + CalcDistance(nFirst+1, nFirst+2);
950 nFullLength = nPart2Length + CalcDistance(nFirst+2, nFirst+3);
951 if ( nFullLength < 20 )
952 return;
954 if ( nPart2Length == nFullLength )
955 nPart2Length -= 1;
956 if ( nPart1Length == nFullLength )
957 nPart1Length = nPart2Length - 1;
958 if ( nPart1Length <= 0 )
959 nPart1Length = 1;
960 if ( nPart2Length <= 0 || nPart2Length == nPart1Length )
961 nPart2Length = nPart1Length + 1;
963 fT1 = nPart1Length / nFullLength;
964 fU1 = 1.0 - fT1;
965 fT2 = nPart2Length / nFullLength;
966 fU2 = 1.0 - fT2;
967 fV = 3 * (1.0 - (fT1 * fU2) / (fT2 * fU1));
969 fX1 = fTx1 / (fT1 * fU1 * fU1) - fTx2 * fT1 / (fT2 * fT2 * fU1 * fU2);
970 fX1 /= fV;
971 fX1 -= fX0 * ( fU1 / fT1 + fU2 / fT2) / 3;
972 fX1 += fX3 * ( fT1 * fT2 / (fU1 * fU2)) / 3;
974 fY1 = fTy1 / (fT1 * fU1 * fU1) - fTy2 * fT1 / (fT2 * fT2 * fU1 * fU2);
975 fY1 /= fV;
976 fY1 -= fY0 * ( fU1 / fT1 + fU2 / fT2) / 3;
977 fY1 += fY3 * ( fT1 * fT2 / (fU1 * fU2)) / 3;
979 fX2 = fTx2 / (fT2 * fT2 * fU2 * 3) - fX0 * fU2 * fU2 / ( fT2 * fT2 * 3);
980 fX2 -= fX1 * fU2 / fT2;
981 fX2 -= fX3 * fT2 / (fU2 * 3);
983 fY2 = fTy2 / (fT2 * fT2 * fU2 * 3) - fY0 * fU2 * fU2 / ( fT2 * fT2 * 3);
984 fY2 -= fY1 * fU2 / fT2;
985 fY2 -= fY3 * fT2 / (fU2 * 3);
987 pPoints[nFirst+1] = Point((long) fX1, (long) fY1);
988 pPoints[nFirst+2] = Point((long) fX2, (long) fY2);
989 SetFlags(nFirst+1, XPOLY_CONTROL);
990 SetFlags(nFirst+2, XPOLY_CONTROL);
993 /*************************************************************************
995 |* XPolygon::Scale()
997 |* XPolygon in X- und/oder Y-Richtung skalieren
999 *************************************************************************/
1001 void XPolygon::Scale(double fSx, double fSy)
1003 pImpXPolygon->CheckPointDelete();
1004 CheckReference();
1006 sal_uInt16 nPntCnt = pImpXPolygon->nPoints;
1008 for (sal_uInt16 i = 0; i < nPntCnt; i++)
1010 Point& rPnt = pImpXPolygon->pPointAry[i];
1011 rPnt.X() = (long)(fSx * rPnt.X());
1012 rPnt.Y() = (long)(fSy * rPnt.Y());
1016 /*************************************************************************
1018 |* XPolygon::Distort()
1020 |* XPolygon verzerren, indem die Koordinaten relativ zu einem
1021 |* Referenzrechteck in ein beliebiges Viereck skaliert werden
1022 |* Zuordnung der Viereck-Punkte im Polygon zum Referenzrechteck:
1023 |* 0: links oben 0----1
1024 |* 1: rechts oben | |
1025 |* 2: rechts unten 3----2
1026 |* 3: links unten
1028 *************************************************************************/
1030 void XPolygon::Distort(const Rectangle& rRefRect,
1031 const XPolygon& rDistortedRect)
1033 pImpXPolygon->CheckPointDelete();
1034 CheckReference();
1036 long Xr, Wr;
1037 long Yr, Hr;
1039 Xr = rRefRect.Left();
1040 Yr = rRefRect.Top();
1041 Wr = rRefRect.GetWidth();
1042 Hr = rRefRect.GetHeight();
1044 if ( Wr && Hr )
1046 long X1, X2, X3, X4;
1047 long Y1, Y2, Y3, Y4;
1048 DBG_ASSERT(rDistortedRect.pImpXPolygon->nPoints >= 4,
1049 "Distort-Rechteck zu klein");
1051 X1 = rDistortedRect[0].X();
1052 Y1 = rDistortedRect[0].Y();
1053 X2 = rDistortedRect[1].X();
1054 Y2 = rDistortedRect[1].Y();
1055 X3 = rDistortedRect[3].X();
1056 Y3 = rDistortedRect[3].Y();
1057 X4 = rDistortedRect[2].X();
1058 Y4 = rDistortedRect[2].Y();
1060 sal_uInt16 nPntCnt = pImpXPolygon->nPoints;
1062 for (sal_uInt16 i = 0; i < nPntCnt; i++)
1064 double fTx, fTy, fUx, fUy;
1065 Point& rPnt = pImpXPolygon->pPointAry[i];
1067 fTx = (double)(rPnt.X() - Xr) / Wr;
1068 fTy = (double)(rPnt.Y() - Yr) / Hr;
1069 fUx = 1.0 - fTx;
1070 fUy = 1.0 - fTy;
1072 rPnt.X() = (long) ( fUy * (fUx * X1 + fTx * X2) +
1073 fTy * (fUx * X3 + fTx * X4) );
1074 rPnt.Y() = (long) ( fUx * (fUy * Y1 + fTy * Y3) +
1075 fTx * (fUy * Y2 + fTy * Y4) );
1080 basegfx::B2DPolygon XPolygon::getB2DPolygon() const
1082 // #i74631# use tools Polygon class for conversion to not have the code doubled
1083 // here. This needs one more conversion but avoids different convertors in
1084 // the long run
1085 DBG_ASSERT(pImpXPolygon != 0, "XPolygon::getB2DPolygon(): XPolygon has no implementation incarnated (!)");
1086 const Polygon aSource(GetPointCount(), pImpXPolygon->pPointAry, pImpXPolygon->pFlagAry);
1088 return aSource.getB2DPolygon();
1091 XPolygon::XPolygon(const basegfx::B2DPolygon& rPolygon)
1093 // #i74631# use tools Polygon class for conversion to not have the code doubled
1094 // here. This needs one more conversion but avoids different convertors in
1095 // the long run
1096 DBG_CTOR(XPolygon,NULL);
1098 const Polygon aSource(rPolygon);
1099 sal_uInt16 nSize = aSource.GetSize();
1100 pImpXPolygon = new ImpXPolygon( nSize );
1101 pImpXPolygon->nPoints = nSize;
1103 for( sal_uInt16 i = 0; i < nSize; i++ )
1105 pImpXPolygon->pPointAry[i] = aSource[i];
1106 pImpXPolygon->pFlagAry[i] = (sal_uInt8) aSource.GetFlags( i );
1110 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1111 //+--------------- XPolyPolygon -----------------------------------------+
1112 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1114 /*************************************************************************
1116 |* ImpXPolyPolygon::ImpXPolyPolygon()
1118 |* Beschreibung Erzeugt das XPolygon-Array
1120 *************************************************************************/
1122 ImpXPolyPolygon::ImpXPolyPolygon( const ImpXPolyPolygon& rImpXPolyPoly ) :
1123 aXPolyList( rImpXPolyPoly.aXPolyList )
1125 nRefCount = 1;
1127 // Einzelne Elemente duplizieren
1128 for ( size_t i = 0, n = aXPolyList.size(); i < n; ++i )
1129 aXPolyList[ i ] = new XPolygon( *aXPolyList[ i ] );
1133 /*************************************************************************
1135 |* ImpXPolyPolygon::~ImpXPolyPolygon()
1137 |* Beschreibung Loescht das Polygon-Array
1139 *************************************************************************/
1141 ImpXPolyPolygon::~ImpXPolyPolygon()
1143 for ( size_t i = 0, n = aXPolyList.size(); i < n; ++i )
1144 delete aXPolyList[ i ];
1145 aXPolyList.clear();
1148 /*************************************************************************
1150 |* ImpXPolyPolygon::operator==()
1152 *************************************************************************/
1154 bool ImpXPolyPolygon::operator==(const ImpXPolyPolygon& rImpXPolyPoly) const
1156 size_t nAnz = aXPolyList.size();
1157 const XPolygonList& rCmpList = rImpXPolyPoly.aXPolyList;
1158 if ( nAnz != rCmpList.size() ) return false;
1159 bool bEq=true;
1160 for ( size_t i = nAnz; i > 0 && bEq; )
1162 i--;
1163 bEq = ( *aXPolyList[ i ] == *rCmpList[ i ] );
1165 return bEq;
1168 /*************************************************************************
1170 |* XPolyPolygon::XPolyPolygon()
1172 *************************************************************************/
1174 XPolyPolygon::XPolyPolygon( sal_uInt16 /*nInitSize*/, sal_uInt16 /*nResize*/ )
1176 DBG_CTOR(XPolyPolygon,NULL);
1177 pImpXPolyPolygon = new ImpXPolyPolygon();
1180 /*************************************************************************
1182 |* XPolyPolygon::XPolyPolygon()
1184 *************************************************************************/
1186 XPolyPolygon::XPolyPolygon( const XPolyPolygon& rXPolyPoly )
1188 DBG_CTOR(XPolyPolygon,NULL);
1189 pImpXPolyPolygon = rXPolyPoly.pImpXPolyPolygon;
1190 pImpXPolyPolygon->nRefCount++;
1193 /*************************************************************************
1195 |* XPolyPolygon::~XPolyPolygon()
1197 *************************************************************************/
1199 XPolyPolygon::~XPolyPolygon()
1201 DBG_DTOR(XPolyPolygon,NULL);
1202 if( pImpXPolyPolygon->nRefCount > 1 )
1203 pImpXPolyPolygon->nRefCount--;
1204 else
1205 delete pImpXPolyPolygon;
1208 /*************************************************************************
1210 |* XPolygon::CheckReference()
1212 |* Referenzzaehler desImpXPolyPoly pruefen und ggf. von diesem abkoppeln
1214 *************************************************************************/
1216 void XPolyPolygon::CheckReference()
1218 if( pImpXPolyPolygon->nRefCount > 1 )
1220 pImpXPolyPolygon->nRefCount--;
1221 pImpXPolyPolygon = new ImpXPolyPolygon( *pImpXPolyPolygon );
1225 /*************************************************************************
1227 |* XPolyPolygon::Insert()
1229 *************************************************************************/
1231 void XPolyPolygon::Insert( const XPolygon& rXPoly, sal_uInt16 nPos )
1233 CheckReference();
1234 XPolygon* pXPoly = new XPolygon( rXPoly );
1235 if ( nPos < pImpXPolyPolygon->aXPolyList.size() )
1237 XPolygonList::iterator it = pImpXPolyPolygon->aXPolyList.begin();
1238 ::std::advance( it, nPos );
1239 pImpXPolyPolygon->aXPolyList.insert( it, pXPoly );
1241 else
1242 pImpXPolyPolygon->aXPolyList.push_back( pXPoly );
1245 /*************************************************************************
1247 |* XPolyPolygon::Insert()
1249 |* saemtliche XPolygone aus einem XPolyPolygon einfuegen
1251 *************************************************************************/
1253 void XPolyPolygon::Insert( const XPolyPolygon& rXPolyPoly, sal_uInt16 nPos )
1255 CheckReference();
1257 for ( size_t i = 0; i < rXPolyPoly.Count(); i++)
1259 XPolygon* pXPoly = new XPolygon( rXPolyPoly[i] );
1261 if ( nPos < pImpXPolyPolygon->aXPolyList.size() )
1263 XPolygonList::iterator it = pImpXPolyPolygon->aXPolyList.begin();
1264 ::std::advance( it, nPos );
1265 pImpXPolyPolygon->aXPolyList.insert( it, pXPoly );
1266 nPos++;
1268 else
1269 pImpXPolyPolygon->aXPolyList.push_back( pXPoly );
1273 /*************************************************************************
1275 |* XPolyPolygon::Remove()
1277 *************************************************************************/
1279 XPolygon XPolyPolygon::Remove( sal_uInt16 nPos )
1281 CheckReference();
1282 XPolygonList::iterator it = pImpXPolyPolygon->aXPolyList.begin();
1283 ::std::advance( it, nPos );
1284 XPolygon* pTmpXPoly = *it;
1285 pImpXPolyPolygon->aXPolyList.erase( it );
1286 XPolygon aXPoly( *pTmpXPoly );
1287 delete pTmpXPoly;
1288 return aXPoly;
1292 /*************************************************************************
1294 |* XPolyPolygon::GetObject()
1296 *************************************************************************/
1298 const XPolygon& XPolyPolygon::GetObject( sal_uInt16 nPos ) const
1300 return *(pImpXPolyPolygon->aXPolyList[ nPos ]);
1304 /*************************************************************************
1306 |* XPolyPolygon::Clear()
1308 *************************************************************************/
1310 void XPolyPolygon::Clear()
1312 if ( pImpXPolyPolygon->nRefCount > 1 )
1314 pImpXPolyPolygon->nRefCount--;
1315 pImpXPolyPolygon = new ImpXPolyPolygon();
1317 else
1319 for( size_t i = 0, n = pImpXPolyPolygon->aXPolyList.size(); i < n; ++i )
1320 delete pImpXPolyPolygon->aXPolyList[ i ];
1321 pImpXPolyPolygon->aXPolyList.clear();
1326 /*************************************************************************
1328 |* XPolyPolygon::Count()
1330 *************************************************************************/
1332 sal_uInt16 XPolyPolygon::Count() const
1334 return (sal_uInt16)(pImpXPolyPolygon->aXPolyList.size());
1337 /*************************************************************************
1339 |* XPolyPolygon::GetBoundRect()
1341 *************************************************************************/
1343 Rectangle XPolyPolygon::GetBoundRect() const
1345 size_t nXPoly = pImpXPolyPolygon->aXPolyList.size();
1346 Rectangle aRect;
1348 for ( size_t n = 0; n < nXPoly; n++ )
1350 const XPolygon* pXPoly = pImpXPolyPolygon->aXPolyList[ n ];
1351 aRect.Union( pXPoly->GetBoundRect() );
1354 return aRect;
1358 /*************************************************************************
1360 |* XPolyPolygon::operator[]()
1362 *************************************************************************/
1364 XPolygon& XPolyPolygon::operator[]( sal_uInt16 nPos )
1366 CheckReference();
1367 return *( pImpXPolyPolygon->aXPolyList[ nPos ] );
1370 /*************************************************************************
1372 |* XPolyPolygon::operator=()
1374 *************************************************************************/
1376 XPolyPolygon& XPolyPolygon::operator=( const XPolyPolygon& rXPolyPoly )
1378 rXPolyPoly.pImpXPolyPolygon->nRefCount++;
1380 if( pImpXPolyPolygon->nRefCount > 1 )
1381 pImpXPolyPolygon->nRefCount--;
1382 else
1383 delete pImpXPolyPolygon;
1385 pImpXPolyPolygon = rXPolyPoly.pImpXPolyPolygon;
1386 return *this;
1390 /*************************************************************************
1392 |* XPolyPolygon::operator==()
1394 *************************************************************************/
1396 sal_Bool XPolyPolygon::operator==( const XPolyPolygon& rXPolyPoly ) const
1398 if (pImpXPolyPolygon==rXPolyPoly.pImpXPolyPolygon) return sal_True;
1399 return *pImpXPolyPolygon == *rXPolyPoly.pImpXPolyPolygon;
1403 /*************************************************************************
1405 |* XPolyPolygon::operator!=()
1407 *************************************************************************/
1409 sal_Bool XPolyPolygon::operator!=( const XPolyPolygon& rXPolyPoly ) const
1411 if (pImpXPolyPolygon==rXPolyPoly.pImpXPolyPolygon) return sal_False;
1412 return *pImpXPolyPolygon != *rXPolyPoly.pImpXPolyPolygon;
1415 /*************************************************************************
1417 |* XPolygon::Distort()
1419 |* XPolygon verzerren, indem die Koordinaten relativ zu einem
1420 |* Referenzrechteck in ein beliebiges Viereck skaliert werden
1421 |* Zuordnung der Viereck-Punkte im Polygon zum Referenzrechteck:
1422 |* 0: links oben 0----1
1423 |* 1: rechts oben | |
1424 |* 2: rechts unten 3----2
1425 |* 3: links unten
1427 *************************************************************************/
1429 void XPolyPolygon::Distort(const Rectangle& rRefRect,
1430 const XPolygon& rDistortedRect)
1432 CheckReference();
1434 for (size_t i = 0; i < Count(); i++)
1435 pImpXPolyPolygon->aXPolyList[ i ]->Distort(rRefRect, rDistortedRect);
1438 basegfx::B2DPolyPolygon XPolyPolygon::getB2DPolyPolygon() const
1440 basegfx::B2DPolyPolygon aRetval;
1442 for(sal_uInt16 a(0L); a < Count(); a++)
1444 const XPolygon& rPoly = (*this)[a];
1445 aRetval.append(rPoly.getB2DPolygon());
1448 return aRetval;
1451 XPolyPolygon::XPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPolygon)
1453 DBG_CTOR(XPolyPolygon,NULL);
1454 pImpXPolyPolygon = new ImpXPolyPolygon();
1456 for(sal_uInt32 a(0L); a < rPolyPolygon.count(); a++)
1458 basegfx::B2DPolygon aCandidate = rPolyPolygon.getB2DPolygon(a);
1459 XPolygon aNewPoly(aCandidate);
1460 Insert(aNewPoly);
1464 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */