1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
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
)
44 mpPolyAry
= new SVPPOLYGON
[ nInitSize
];
47 ImplPolyPolygon::ImplPolyPolygon( const ImplPolyPolygon
& rImplPolyPoly
)
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
] );
64 ImplPolyPolygon::~ImplPolyPolygon()
68 for ( sal_uInt16 i
= 0; i
< mnCount
; i
++ )
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
)
82 if ( nResize
> MAX_POLYGONS
)
83 nResize
= MAX_POLYGONS
;
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
);
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
--;
119 delete mpImplPolyPolygon
;
122 void PolyPolygon::Insert( const Polygon
& rPoly
, sal_uInt16 nPos
)
124 DBG_CHKTHIS( PolyPolygon
, NULL
);
126 if ( mpImplPolyPolygon
->mnCount
>= MAX_POLYGONS
)
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
;
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
;
212 bIsRect
= mpImplPolyPolygon
->mpPolyAry
[ 0 ]->IsRect();
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
);
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
);
247 const sal_Bool bEdges
= ( nOptimizeFlags
& POLY_OPTIMIZE_EDGES
) == POLY_OPTIMIZE_EDGES
;
248 sal_uInt16 nPercent
= 0;
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
);
267 for( sal_uInt16 i
= 0, nPolyCount
= mpImplPolyPolygon
->mnCount
; i
< nPolyCount
; i
++ )
271 mpImplPolyPolygon
->mpPolyAry
[ i
]->Optimize( POLY_OPTIMIZE_NO_SAME
);
272 Polygon::ImplReduceEdges( *( mpImplPolyPolygon
->mpPolyAry
[ i
] ), fArea
, nPercent
);
276 mpImplPolyPolygon
->mpPolyAry
[ i
]->Optimize( nOptimizeFlags
, pData
);
281 void PolyPolygon::AdaptiveSubdivide( PolyPolygon
& rResult
, const double d
) const
283 DBG_CHKTHIS( PolyPolygon
, NULL
);
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
316 aMergePolyPolygonA
= basegfx::tools::prepareForPolygonOperation( aMergePolyPolygonA
);
317 aMergePolyPolygonB
= basegfx::tools::prepareForPolygonOperation( aMergePolyPolygonB
);
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
);
332 // substract B from A (DIFF)
333 aMergePolyPolygonA
= basegfx::tools::solvePolygonOperationDiff(aMergePolyPolygonA
, aMergePolyPolygonB
);
339 // compute XOR between poly A and B
340 aMergePolyPolygonA
= basegfx::tools::solvePolygonOperationXor(aMergePolyPolygonA
, aMergePolyPolygonB
);
347 // cut poly 1 against polys 2..n (AND)
348 aMergePolyPolygonA
= basegfx::tools::solvePolygonOperationAnd(aMergePolyPolygonA
, aMergePolyPolygonB
);
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
);
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
);
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
);
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
);
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
);
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
;
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
);
458 if ( GetObject( nPolyCount
-1 ).GetSize() <= 2 )
459 Remove( nPolyCount
-1 );
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
];
484 nXMin
= nXMax
= pPt
->X();
485 nYMin
= nYMax
= pPt
->Y();
490 if ( pPt
->X() < nXMin
)
492 if ( pPt
->X() > nXMax
)
494 if ( pPt
->Y() < nYMin
)
496 if ( pPt
->Y() > nYMax
)
503 return Rectangle( nXMin
, nYMin
, nXMax
, nYMax
);
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
--;
533 delete mpImplPolyPolygon
;
535 mpImplPolyPolygon
= rPolyPoly
.mpImplPolyPolygon
;
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
)
550 sal_Bool
PolyPolygon::IsEqual( const PolyPolygon
& rPolyPoly
) const
552 sal_Bool bIsEqual
= sal_True
;
553 if ( Count() != rPolyPoly
.Count() )
554 bIsEqual
= sal_False
;
558 for ( i
= 0; i
< Count(); i
++ )
560 if (!GetObject( i
).IsEqual( rPolyPoly
.GetObject( i
) ) )
562 bIsEqual
= sal_False
;
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" );
576 sal_uInt16 nPolyCount
;
578 // read number of polygons
579 rIStream
>> nPolyCount
;
583 if ( rPolyPoly
.mpImplPolyPolygon
->mnRefCount
> 1 )
584 rPolyPoly
.mpImplPolyPolygon
->mnRefCount
--;
586 delete rPolyPoly
.mpImplPolyPolygon
;
588 rPolyPoly
.mpImplPolyPolygon
= new ImplPolyPolygon( nPolyCount
);
590 for ( sal_uInt16 i
= 0; i
< nPolyCount
; i
++ )
594 rPolyPoly
.mpImplPolyPolygon
->mpPolyAry
[i
] = pPoly
;
598 rPolyPoly
= PolyPolygon();
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
;
613 for ( sal_uInt16 i
= 0; i
< nPolyCount
; i
++ )
614 rOStream
<< *(rPolyPoly
.mpImplPolyPolygon
->mpPolyAry
[i
]);
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" );
627 sal_uInt16 nPolyCount
;
629 // Read number of polygons
630 rIStream
>> nPolyCount
;
634 if ( mpImplPolyPolygon
->mnRefCount
> 1 )
635 mpImplPolyPolygon
->mnRefCount
--;
637 delete mpImplPolyPolygon
;
639 mpImplPolyPolygon
= new ImplPolyPolygon( nPolyCount
);
641 for ( sal_uInt16 i
= 0; i
< nPolyCount
; i
++ )
644 pPoly
->ImplRead( rIStream
);
645 mpImplPolyPolygon
->mpPolyAry
[i
] = pPoly
;
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
;
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());
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 (!)");
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
);
702 mpImplPolyPolygon
= new ImplPolyPolygon( 16, 16 );
706 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */