bump product version to 4.1.6.2
[LibreOffice.git] / tools / source / generic / poly2.cxx
blob535ff9ac1c019eb19abe4246dbb7b430cb0a930e
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 #define POLY_CLIP_INT 0
21 #define POLY_CLIP_UNION 1
22 #define POLY_CLIP_DIFF 2
23 #define POLY_CLIP_XOR 3
25 #include <rtl/math.hxx>
26 #include <poly.h>
27 #include <tools/poly.hxx>
28 #include <tools/debug.hxx>
29 #include <tools/stream.hxx>
30 #include <tools/vcompat.hxx>
31 #include <tools/gen.hxx>
32 #include <basegfx/polygon/b2dpolypolygon.hxx>
33 #include <basegfx/polygon/b2dpolygon.hxx>
34 #include <basegfx/polygon/b2dpolypolygoncutter.hxx>
36 DBG_NAME( PolyPolygon )
38 ImplPolyPolygon::ImplPolyPolygon( sal_uInt16 nInitSize )
40 mnRefCount = 1;
41 mnCount = nInitSize;
42 mnSize = nInitSize;
43 mnResize = 16;
44 mpPolyAry = new SVPPOLYGON[ nInitSize ];
47 ImplPolyPolygon::ImplPolyPolygon( const ImplPolyPolygon& rImplPolyPoly )
49 mnRefCount = 1;
50 mnCount = rImplPolyPoly.mnCount;
51 mnSize = rImplPolyPoly.mnSize;
52 mnResize = rImplPolyPoly.mnResize;
54 if ( rImplPolyPoly.mpPolyAry )
56 mpPolyAry = new SVPPOLYGON[mnSize];
57 for ( sal_uInt16 i = 0; i < mnCount; i++ )
58 mpPolyAry[i] = new Polygon( *rImplPolyPoly.mpPolyAry[i] );
60 else
61 mpPolyAry = NULL;
64 ImplPolyPolygon::~ImplPolyPolygon()
66 if ( mpPolyAry )
68 for ( sal_uInt16 i = 0; i < mnCount; i++ )
69 delete mpPolyAry[i];
70 delete[] mpPolyAry;
74 PolyPolygon::PolyPolygon( sal_uInt16 nInitSize, sal_uInt16 nResize )
76 DBG_CTOR( PolyPolygon, NULL );
78 if ( nInitSize > MAX_POLYGONS )
79 nInitSize = MAX_POLYGONS;
80 else if ( !nInitSize )
81 nInitSize = 1;
82 if ( nResize > MAX_POLYGONS )
83 nResize = MAX_POLYGONS;
84 else if ( !nResize )
85 nResize = 1;
86 mpImplPolyPolygon = new ImplPolyPolygon( nInitSize, nResize );
89 PolyPolygon::PolyPolygon( const Polygon& rPoly )
91 DBG_CTOR( PolyPolygon, NULL );
93 if ( rPoly.GetSize() )
95 mpImplPolyPolygon = new ImplPolyPolygon( 1 );
96 mpImplPolyPolygon->mpPolyAry[0] = new Polygon( rPoly );
98 else
99 mpImplPolyPolygon = new ImplPolyPolygon( 16, 16 );
102 PolyPolygon::PolyPolygon( const PolyPolygon& rPolyPoly )
104 DBG_CTOR( PolyPolygon, NULL );
105 DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
106 DBG_ASSERT( rPolyPoly.mpImplPolyPolygon->mnRefCount < 0xFFFFFFFE, "PolyPolygon: RefCount overflow" );
108 mpImplPolyPolygon = rPolyPoly.mpImplPolyPolygon;
109 mpImplPolyPolygon->mnRefCount++;
112 PolyPolygon::~PolyPolygon()
114 DBG_DTOR( PolyPolygon, NULL );
116 if ( mpImplPolyPolygon->mnRefCount > 1 )
117 mpImplPolyPolygon->mnRefCount--;
118 else
119 delete mpImplPolyPolygon;
122 void PolyPolygon::Insert( const Polygon& rPoly, sal_uInt16 nPos )
124 DBG_CHKTHIS( PolyPolygon, NULL );
126 if ( mpImplPolyPolygon->mnCount >= MAX_POLYGONS )
127 return;
129 if ( mpImplPolyPolygon->mnRefCount > 1 )
131 mpImplPolyPolygon->mnRefCount--;
132 mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
135 if ( nPos > mpImplPolyPolygon->mnCount )
136 nPos = mpImplPolyPolygon->mnCount;
138 if ( !mpImplPolyPolygon->mpPolyAry )
139 mpImplPolyPolygon->mpPolyAry = new SVPPOLYGON[mpImplPolyPolygon->mnSize];
140 else if ( mpImplPolyPolygon->mnCount == mpImplPolyPolygon->mnSize )
142 sal_uInt16 nOldSize = mpImplPolyPolygon->mnSize;
143 sal_uInt16 nNewSize = nOldSize + mpImplPolyPolygon->mnResize;
144 SVPPOLYGON* pNewAry;
146 if ( nNewSize >= MAX_POLYGONS )
147 nNewSize = MAX_POLYGONS;
148 pNewAry = new SVPPOLYGON[nNewSize];
149 memcpy( pNewAry, mpImplPolyPolygon->mpPolyAry, nPos*sizeof(SVPPOLYGON) );
150 memcpy( pNewAry+nPos+1, mpImplPolyPolygon->mpPolyAry+nPos,
151 (nOldSize-nPos)*sizeof(SVPPOLYGON) );
152 delete[] mpImplPolyPolygon->mpPolyAry;
153 mpImplPolyPolygon->mpPolyAry = pNewAry;
154 mpImplPolyPolygon->mnSize = nNewSize;
156 else if ( nPos < mpImplPolyPolygon->mnCount )
158 memmove( mpImplPolyPolygon->mpPolyAry+nPos+1,
159 mpImplPolyPolygon->mpPolyAry+nPos,
160 (mpImplPolyPolygon->mnCount-nPos)*sizeof(SVPPOLYGON) );
163 mpImplPolyPolygon->mpPolyAry[nPos] = new Polygon( rPoly );
164 mpImplPolyPolygon->mnCount++;
167 void PolyPolygon::Remove( sal_uInt16 nPos )
169 DBG_CHKTHIS( PolyPolygon, NULL );
170 DBG_ASSERT( nPos < Count(), "PolyPolygon::Remove(): nPos >= nSize" );
172 if ( mpImplPolyPolygon->mnRefCount > 1 )
174 mpImplPolyPolygon->mnRefCount--;
175 mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
178 delete mpImplPolyPolygon->mpPolyAry[nPos];
179 mpImplPolyPolygon->mnCount--;
180 memmove( mpImplPolyPolygon->mpPolyAry+nPos,
181 mpImplPolyPolygon->mpPolyAry+nPos+1,
182 (mpImplPolyPolygon->mnCount-nPos)*sizeof(SVPPOLYGON) );
185 void PolyPolygon::Replace( const Polygon& rPoly, sal_uInt16 nPos )
187 DBG_CHKTHIS( PolyPolygon, NULL );
188 DBG_ASSERT( nPos < Count(), "PolyPolygon::Replace(): nPos >= nSize" );
190 if ( mpImplPolyPolygon->mnRefCount > 1 )
192 mpImplPolyPolygon->mnRefCount--;
193 mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
196 delete mpImplPolyPolygon->mpPolyAry[nPos];
197 mpImplPolyPolygon->mpPolyAry[nPos] = new Polygon( rPoly );
200 const Polygon& PolyPolygon::GetObject( sal_uInt16 nPos ) const
202 DBG_CHKTHIS( PolyPolygon, NULL );
203 DBG_ASSERT( nPos < Count(), "PolyPolygon::GetObject(): nPos >= nSize" );
205 return *(mpImplPolyPolygon->mpPolyAry[nPos]);
208 sal_Bool PolyPolygon::IsRect() const
210 sal_Bool bIsRect = sal_False;
211 if ( Count() == 1 )
212 bIsRect = mpImplPolyPolygon->mpPolyAry[ 0 ]->IsRect();
213 return bIsRect;
216 void PolyPolygon::Clear()
218 DBG_CHKTHIS( PolyPolygon, NULL );
220 if ( mpImplPolyPolygon->mnRefCount > 1 )
222 mpImplPolyPolygon->mnRefCount--;
223 mpImplPolyPolygon = new ImplPolyPolygon( mpImplPolyPolygon->mnResize,
224 mpImplPolyPolygon->mnResize );
226 else
228 if ( mpImplPolyPolygon->mpPolyAry )
230 for ( sal_uInt16 i = 0; i < mpImplPolyPolygon->mnCount; i++ )
231 delete mpImplPolyPolygon->mpPolyAry[i];
232 delete[] mpImplPolyPolygon->mpPolyAry;
233 mpImplPolyPolygon->mpPolyAry = NULL;
234 mpImplPolyPolygon->mnCount = 0;
235 mpImplPolyPolygon->mnSize = mpImplPolyPolygon->mnResize;
240 void PolyPolygon::Optimize( sal_uIntPtr nOptimizeFlags, const PolyOptimizeData* pData )
242 DBG_CHKTHIS( PolyPolygon, NULL );
244 if( nOptimizeFlags )
246 double fArea;
247 const sal_Bool bEdges = ( nOptimizeFlags & POLY_OPTIMIZE_EDGES ) == POLY_OPTIMIZE_EDGES;
248 sal_uInt16 nPercent = 0;
250 if( bEdges )
252 const Rectangle aBound( GetBoundRect() );
254 fArea = ( aBound.GetWidth() + aBound.GetHeight() ) * 0.5;
255 nPercent = pData ? pData->GetPercentValue() : 50;
256 nOptimizeFlags &= ~POLY_OPTIMIZE_EDGES;
259 // watch for ref counter
260 if( mpImplPolyPolygon->mnRefCount > 1 )
262 mpImplPolyPolygon->mnRefCount--;
263 mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
266 // Optimize polygons
267 for( sal_uInt16 i = 0, nPolyCount = mpImplPolyPolygon->mnCount; i < nPolyCount; i++ )
269 if( bEdges )
271 mpImplPolyPolygon->mpPolyAry[ i ]->Optimize( POLY_OPTIMIZE_NO_SAME );
272 Polygon::ImplReduceEdges( *( mpImplPolyPolygon->mpPolyAry[ i ] ), fArea, nPercent );
275 if( nOptimizeFlags )
276 mpImplPolyPolygon->mpPolyAry[ i ]->Optimize( nOptimizeFlags, pData );
281 void PolyPolygon::AdaptiveSubdivide( PolyPolygon& rResult, const double d ) const
283 DBG_CHKTHIS( PolyPolygon, NULL );
285 rResult.Clear();
287 Polygon aPolygon;
289 for( sal_uInt16 i = 0; i < mpImplPolyPolygon->mnCount; i++ )
291 mpImplPolyPolygon->mpPolyAry[ i ]->AdaptiveSubdivide( aPolygon, d );
292 rResult.Insert( aPolygon );
296 void PolyPolygon::GetIntersection( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const
298 ImplDoOperation( rPolyPoly, rResult, POLY_CLIP_INT );
301 void PolyPolygon::GetUnion( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const
303 ImplDoOperation( rPolyPoly, rResult, POLY_CLIP_UNION );
306 void PolyPolygon::ImplDoOperation( const PolyPolygon& rPolyPoly, PolyPolygon& rResult, sal_uIntPtr nOperation ) const
308 // Convert to B2DPolyPolygon, temporarily. It might be
309 // advantageous in the future, to have a PolyPolygon adaptor that
310 // just simulates a B2DPolyPolygon here...
311 basegfx::B2DPolyPolygon aMergePolyPolygonA( getB2DPolyPolygon() );
312 basegfx::B2DPolyPolygon aMergePolyPolygonB( rPolyPoly.getB2DPolyPolygon() );
314 // normalize the two polypolygons before. Force properly oriented
315 // polygons.
316 aMergePolyPolygonA = basegfx::tools::prepareForPolygonOperation( aMergePolyPolygonA );
317 aMergePolyPolygonB = basegfx::tools::prepareForPolygonOperation( aMergePolyPolygonB );
319 switch( nOperation )
321 // All code extracted from svx/source/svdraw/svedtv2.cxx
323 case POLY_CLIP_UNION:
325 // merge A and B (OR)
326 aMergePolyPolygonA = basegfx::tools::solvePolygonOperationOr(aMergePolyPolygonA, aMergePolyPolygonB);
327 break;
330 case POLY_CLIP_DIFF:
332 // substract B from A (DIFF)
333 aMergePolyPolygonA = basegfx::tools::solvePolygonOperationDiff(aMergePolyPolygonA, aMergePolyPolygonB);
334 break;
337 case POLY_CLIP_XOR:
339 // compute XOR between poly A and B
340 aMergePolyPolygonA = basegfx::tools::solvePolygonOperationXor(aMergePolyPolygonA, aMergePolyPolygonB);
341 break;
344 default:
345 case POLY_CLIP_INT:
347 // cut poly 1 against polys 2..n (AND)
348 aMergePolyPolygonA = basegfx::tools::solvePolygonOperationAnd(aMergePolyPolygonA, aMergePolyPolygonB);
349 break;
353 rResult = PolyPolygon( aMergePolyPolygonA );
356 sal_uInt16 PolyPolygon::Count() const
358 DBG_CHKTHIS( PolyPolygon, NULL );
359 return mpImplPolyPolygon->mnCount;
362 void PolyPolygon::Move( long nHorzMove, long nVertMove )
364 DBG_CHKTHIS( PolyPolygon, NULL );
366 // Required for DrawEngine
367 if( nHorzMove || nVertMove )
369 if ( mpImplPolyPolygon->mnRefCount > 1 )
371 mpImplPolyPolygon->mnRefCount--;
372 mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
375 // move points
376 sal_uInt16 nPolyCount = mpImplPolyPolygon->mnCount;
377 for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
378 mpImplPolyPolygon->mpPolyAry[i]->Move( nHorzMove, nVertMove );
382 void PolyPolygon::Translate( const Point& rTrans )
384 DBG_CHKTHIS( PolyPolygon, NULL );
386 if( mpImplPolyPolygon->mnRefCount > 1 )
388 mpImplPolyPolygon->mnRefCount--;
389 mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
392 // move points
393 for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ )
394 mpImplPolyPolygon->mpPolyAry[ i ]->Translate( rTrans );
397 void PolyPolygon::Scale( double fScaleX, double fScaleY )
399 DBG_CHKTHIS( PolyPolygon, NULL );
401 if( mpImplPolyPolygon->mnRefCount > 1 )
403 mpImplPolyPolygon->mnRefCount--;
404 mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
407 // Move points
408 for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ )
409 mpImplPolyPolygon->mpPolyAry[ i ]->Scale( fScaleX, fScaleY );
412 void PolyPolygon::Rotate( const Point& rCenter, sal_uInt16 nAngle10 )
414 DBG_CHKTHIS( PolyPolygon, NULL );
415 nAngle10 %= 3600;
417 if( nAngle10 )
419 const double fAngle = F_PI1800 * nAngle10;
420 Rotate( rCenter, sin( fAngle ), cos( fAngle ) );
424 void PolyPolygon::Rotate( const Point& rCenter, double fSin, double fCos )
426 DBG_CHKTHIS( PolyPolygon, NULL );
428 if( mpImplPolyPolygon->mnRefCount > 1 )
430 mpImplPolyPolygon->mnRefCount--;
431 mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
434 // move points
435 for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ )
436 mpImplPolyPolygon->mpPolyAry[ i ]->Rotate( rCenter, fSin, fCos );
439 void PolyPolygon::Clip( const Rectangle& rRect )
441 sal_uInt16 nPolyCount = mpImplPolyPolygon->mnCount;
442 sal_uInt16 i;
444 if ( !nPolyCount )
445 return;
447 if ( mpImplPolyPolygon->mnRefCount > 1 )
449 mpImplPolyPolygon->mnRefCount--;
450 mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
453 // Clip every polygon, deleting the empty ones
454 for ( i = 0; i < nPolyCount; i++ )
455 mpImplPolyPolygon->mpPolyAry[i]->Clip( rRect );
456 while ( nPolyCount )
458 if ( GetObject( nPolyCount-1 ).GetSize() <= 2 )
459 Remove( nPolyCount-1 );
460 nPolyCount--;
464 Rectangle PolyPolygon::GetBoundRect() const
466 DBG_CHKTHIS( PolyPolygon, NULL );
468 long nXMin=0, nXMax=0, nYMin=0, nYMax=0;
469 sal_Bool bFirst = sal_True;
470 sal_uInt16 nPolyCount = mpImplPolyPolygon->mnCount;
472 for ( sal_uInt16 n = 0; n < nPolyCount; n++ )
474 const Polygon* pPoly = mpImplPolyPolygon->mpPolyAry[n];
475 const Point* pAry = pPoly->GetConstPointAry();
476 sal_uInt16 nPointCount = pPoly->GetSize();
478 for ( sal_uInt16 i = 0; i < nPointCount; i++ )
480 const Point* pPt = &pAry[ i ];
482 if ( bFirst )
484 nXMin = nXMax = pPt->X();
485 nYMin = nYMax = pPt->Y();
486 bFirst = sal_False;
488 else
490 if ( pPt->X() < nXMin )
491 nXMin = pPt->X();
492 if ( pPt->X() > nXMax )
493 nXMax = pPt->X();
494 if ( pPt->Y() < nYMin )
495 nYMin = pPt->Y();
496 if ( pPt->Y() > nYMax )
497 nYMax = pPt->Y();
502 if ( !bFirst )
503 return Rectangle( nXMin, nYMin, nXMax, nYMax );
504 else
505 return Rectangle();
508 Polygon& PolyPolygon::operator[]( sal_uInt16 nPos )
510 DBG_CHKTHIS( PolyPolygon, NULL );
511 DBG_ASSERT( nPos < Count(), "PolyPolygon::[](): nPos >= nSize" );
513 if ( mpImplPolyPolygon->mnRefCount > 1 )
515 mpImplPolyPolygon->mnRefCount--;
516 mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
519 return *(mpImplPolyPolygon->mpPolyAry[nPos]);
522 PolyPolygon& PolyPolygon::operator=( const PolyPolygon& rPolyPoly )
524 DBG_CHKTHIS( PolyPolygon, NULL );
525 DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
526 DBG_ASSERT( rPolyPoly.mpImplPolyPolygon->mnRefCount < 0xFFFFFFFE, "PolyPolygon: RefCount overflow" );
528 rPolyPoly.mpImplPolyPolygon->mnRefCount++;
530 if ( mpImplPolyPolygon->mnRefCount > 1 )
531 mpImplPolyPolygon->mnRefCount--;
532 else
533 delete mpImplPolyPolygon;
535 mpImplPolyPolygon = rPolyPoly.mpImplPolyPolygon;
536 return *this;
539 sal_Bool PolyPolygon::operator==( const PolyPolygon& rPolyPoly ) const
541 DBG_CHKTHIS( PolyPolygon, NULL );
542 DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
544 if ( rPolyPoly.mpImplPolyPolygon == mpImplPolyPolygon )
545 return sal_True;
546 else
547 return sal_False;
550 sal_Bool PolyPolygon::IsEqual( const PolyPolygon& rPolyPoly ) const
552 sal_Bool bIsEqual = sal_True;
553 if ( Count() != rPolyPoly.Count() )
554 bIsEqual = sal_False;
555 else
557 sal_uInt16 i;
558 for ( i = 0; i < Count(); i++ )
560 if (!GetObject( i ).IsEqual( rPolyPoly.GetObject( i ) ) )
562 bIsEqual = sal_False;
563 break;
567 return bIsEqual;
570 SvStream& operator>>( SvStream& rIStream, PolyPolygon& rPolyPoly )
572 DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
573 DBG_ASSERTWARNING( rIStream.GetVersion(), "PolyPolygon::>> - Solar-Version not set on rIStream" );
575 Polygon* pPoly;
576 sal_uInt16 nPolyCount;
578 // read number of polygons
579 rIStream >> nPolyCount;
581 if( nPolyCount )
583 if ( rPolyPoly.mpImplPolyPolygon->mnRefCount > 1 )
584 rPolyPoly.mpImplPolyPolygon->mnRefCount--;
585 else
586 delete rPolyPoly.mpImplPolyPolygon;
588 rPolyPoly.mpImplPolyPolygon = new ImplPolyPolygon( nPolyCount );
590 for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
592 pPoly = new Polygon;
593 rIStream >> *pPoly;
594 rPolyPoly.mpImplPolyPolygon->mpPolyAry[i] = pPoly;
597 else
598 rPolyPoly = PolyPolygon();
600 return rIStream;
603 SvStream& operator<<( SvStream& rOStream, const PolyPolygon& rPolyPoly )
605 DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
606 DBG_ASSERTWARNING( rOStream.GetVersion(), "PolyPolygon::<< - Solar-Version not set on rOStream" );
608 // Write number of polygons
609 sal_uInt16 nPolyCount = rPolyPoly.mpImplPolyPolygon->mnCount;
610 rOStream << nPolyCount;
612 // output polygons
613 for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
614 rOStream << *(rPolyPoly.mpImplPolyPolygon->mpPolyAry[i]);
616 return rOStream;
619 void PolyPolygon::Read( SvStream& rIStream )
621 VersionCompat aCompat( rIStream, STREAM_READ );
623 DBG_CHKTHIS( PolyPolygon, NULL );
624 DBG_ASSERTWARNING( rIStream.GetVersion(), "PolyPolygon::>> - Solar-Version not set on rIStream" );
626 Polygon* pPoly;
627 sal_uInt16 nPolyCount;
629 // Read number of polygons
630 rIStream >> nPolyCount;
632 if( nPolyCount )
634 if ( mpImplPolyPolygon->mnRefCount > 1 )
635 mpImplPolyPolygon->mnRefCount--;
636 else
637 delete mpImplPolyPolygon;
639 mpImplPolyPolygon = new ImplPolyPolygon( nPolyCount );
641 for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
643 pPoly = new Polygon;
644 pPoly->ImplRead( rIStream );
645 mpImplPolyPolygon->mpPolyAry[i] = pPoly;
648 else
649 *this = PolyPolygon();
652 void PolyPolygon::Write( SvStream& rOStream ) const
654 VersionCompat aCompat( rOStream, STREAM_WRITE, 1 );
656 DBG_CHKTHIS( PolyPolygon, NULL );
657 DBG_ASSERTWARNING( rOStream.GetVersion(), "PolyPolygon::<< - Solar-Version not set on rOStream" );
659 // Write number of polygons
660 sal_uInt16 nPolyCount = mpImplPolyPolygon->mnCount;
661 rOStream << nPolyCount;
663 // Output polygons
664 for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
665 mpImplPolyPolygon->mpPolyAry[i]->ImplWrite( rOStream );
668 // convert to basegfx::B2DPolyPolygon and return
669 basegfx::B2DPolyPolygon PolyPolygon::getB2DPolyPolygon() const
671 basegfx::B2DPolyPolygon aRetval;
673 for(sal_uInt16 a(0); a < mpImplPolyPolygon->mnCount; a++)
675 Polygon* pCandidate = mpImplPolyPolygon->mpPolyAry[a];
676 aRetval.append(pCandidate->getB2DPolygon());
679 return aRetval;
682 // constructor to convert from basegfx::B2DPolyPolygon
683 PolyPolygon::PolyPolygon(const basegfx::B2DPolyPolygon& rPolyPolygon)
685 DBG_CTOR( PolyPolygon, NULL );
686 const sal_uInt16 nCount(sal_uInt16(rPolyPolygon.count()));
687 DBG_ASSERT(sal_uInt32(nCount) == rPolyPolygon.count(),
688 "PolyPolygon::PolyPolygon: Too many sub-polygons in given basegfx::B2DPolyPolygon (!)");
690 if ( nCount )
692 mpImplPolyPolygon = new ImplPolyPolygon( nCount );
694 for(sal_uInt16 a(0); a < nCount; a++)
696 basegfx::B2DPolygon aCandidate(rPolyPolygon.getB2DPolygon(sal_uInt32(a)));
697 mpImplPolyPolygon->mpPolyAry[a] = new Polygon( aCandidate );
700 else
702 mpImplPolyPolygon = new ImplPolyPolygon( 16, 16 );
706 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */