1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: poly2.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_tools.hxx"
36 #define POLY_CLIP_INT 0
37 #define POLY_CLIP_UNION 1
38 #define POLY_CLIP_DIFF 2
39 #define POLY_CLIP_XOR 3
41 #include <rtl/math.hxx>
43 #include <tools/poly.hxx>
44 #include <tools/debug.hxx>
45 #include <tools/stream.hxx>
46 #include <tools/vcompat.hxx>
47 #include <basegfx/polygon/b2dpolypolygon.hxx>
48 #include <basegfx/polygon/b2dpolygon.hxx>
49 #include <basegfx/polygon/b2dpolypolygoncutter.hxx>
55 DBG_NAME( PolyPolygon
)
57 // -----------------------------------------------------------------------
59 ImplPolyPolygon::ImplPolyPolygon( USHORT nInitSize
)
65 mpPolyAry
= new SVPPOLYGON
[ nInitSize
];
68 // -----------------------------------------------------------------------
70 ImplPolyPolygon::ImplPolyPolygon( const ImplPolyPolygon
& rImplPolyPoly
)
73 mnCount
= rImplPolyPoly
.mnCount
;
74 mnSize
= rImplPolyPoly
.mnSize
;
75 mnResize
= rImplPolyPoly
.mnResize
;
77 if ( rImplPolyPoly
.mpPolyAry
)
79 mpPolyAry
= new SVPPOLYGON
[mnSize
];
80 for ( USHORT i
= 0; i
< mnCount
; i
++ )
81 mpPolyAry
[i
] = new Polygon( *rImplPolyPoly
.mpPolyAry
[i
] );
87 // -----------------------------------------------------------------------
89 ImplPolyPolygon::~ImplPolyPolygon()
93 for ( USHORT i
= 0; i
< mnCount
; i
++ )
99 // =======================================================================
101 PolyPolygon::PolyPolygon( USHORT nInitSize
, USHORT nResize
)
103 DBG_CTOR( PolyPolygon
, NULL
);
105 if ( nInitSize
> MAX_POLYGONS
)
106 nInitSize
= MAX_POLYGONS
;
107 else if ( !nInitSize
)
109 if ( nResize
> MAX_POLYGONS
)
110 nResize
= MAX_POLYGONS
;
113 mpImplPolyPolygon
= new ImplPolyPolygon( nInitSize
, nResize
);
116 // -----------------------------------------------------------------------
118 PolyPolygon::PolyPolygon( const Polygon
& rPoly
)
120 DBG_CTOR( PolyPolygon
, NULL
);
122 if ( rPoly
.GetSize() )
124 mpImplPolyPolygon
= new ImplPolyPolygon( 1 );
125 mpImplPolyPolygon
->mpPolyAry
[0] = new Polygon( rPoly
);
128 mpImplPolyPolygon
= new ImplPolyPolygon( 16, 16 );
131 // -----------------------------------------------------------------------
133 PolyPolygon::PolyPolygon( USHORT nPoly
, const USHORT
* pPointCountAry
,
134 const Point
* pPtAry
)
136 DBG_CTOR( PolyPolygon
, NULL
);
138 if ( nPoly
> MAX_POLYGONS
)
139 nPoly
= MAX_POLYGONS
;
141 mpImplPolyPolygon
= new ImplPolyPolygon( nPoly
);
142 for ( USHORT i
= 0; i
< nPoly
; i
++ )
144 mpImplPolyPolygon
->mpPolyAry
[i
] = new Polygon( *pPointCountAry
, pPtAry
);
145 pPtAry
+= *pPointCountAry
;
150 // -----------------------------------------------------------------------
152 PolyPolygon::PolyPolygon( const PolyPolygon
& rPolyPoly
)
154 DBG_CTOR( PolyPolygon
, NULL
);
155 DBG_CHKOBJ( &rPolyPoly
, PolyPolygon
, NULL
);
156 DBG_ASSERT( rPolyPoly
.mpImplPolyPolygon
->mnRefCount
< 0xFFFFFFFE, "PolyPolygon: RefCount overflow" );
158 mpImplPolyPolygon
= rPolyPoly
.mpImplPolyPolygon
;
159 mpImplPolyPolygon
->mnRefCount
++;
162 // -----------------------------------------------------------------------
164 PolyPolygon::~PolyPolygon()
166 DBG_DTOR( PolyPolygon
, NULL
);
168 if ( mpImplPolyPolygon
->mnRefCount
> 1 )
169 mpImplPolyPolygon
->mnRefCount
--;
171 delete mpImplPolyPolygon
;
174 // -----------------------------------------------------------------------
176 void PolyPolygon::Insert( const Polygon
& rPoly
, USHORT nPos
)
178 DBG_CHKTHIS( PolyPolygon
, NULL
);
180 if ( mpImplPolyPolygon
->mnCount
>= MAX_POLYGONS
)
183 if ( mpImplPolyPolygon
->mnRefCount
> 1 )
185 mpImplPolyPolygon
->mnRefCount
--;
186 mpImplPolyPolygon
= new ImplPolyPolygon( *mpImplPolyPolygon
);
189 if ( nPos
> mpImplPolyPolygon
->mnCount
)
190 nPos
= mpImplPolyPolygon
->mnCount
;
192 if ( !mpImplPolyPolygon
->mpPolyAry
)
193 mpImplPolyPolygon
->mpPolyAry
= new SVPPOLYGON
[mpImplPolyPolygon
->mnSize
];
194 else if ( mpImplPolyPolygon
->mnCount
== mpImplPolyPolygon
->mnSize
)
196 USHORT nOldSize
= mpImplPolyPolygon
->mnSize
;
197 USHORT nNewSize
= nOldSize
+ mpImplPolyPolygon
->mnResize
;
200 if ( nNewSize
>= MAX_POLYGONS
)
201 nNewSize
= MAX_POLYGONS
;
202 pNewAry
= new SVPPOLYGON
[nNewSize
];
203 memcpy( pNewAry
, mpImplPolyPolygon
->mpPolyAry
, nPos
*sizeof(SVPPOLYGON
) );
204 memcpy( pNewAry
+nPos
+1, mpImplPolyPolygon
->mpPolyAry
+nPos
,
205 (nOldSize
-nPos
)*sizeof(SVPPOLYGON
) );
206 delete[] mpImplPolyPolygon
->mpPolyAry
;
207 mpImplPolyPolygon
->mpPolyAry
= pNewAry
;
208 mpImplPolyPolygon
->mnSize
= nNewSize
;
210 else if ( nPos
< mpImplPolyPolygon
->mnCount
)
212 memmove( mpImplPolyPolygon
->mpPolyAry
+nPos
+1,
213 mpImplPolyPolygon
->mpPolyAry
+nPos
,
214 (mpImplPolyPolygon
->mnCount
-nPos
)*sizeof(SVPPOLYGON
) );
217 mpImplPolyPolygon
->mpPolyAry
[nPos
] = new Polygon( rPoly
);
218 mpImplPolyPolygon
->mnCount
++;
221 // -----------------------------------------------------------------------
223 void PolyPolygon::Remove( USHORT nPos
)
225 DBG_CHKTHIS( PolyPolygon
, NULL
);
226 DBG_ASSERT( nPos
< Count(), "PolyPolygon::Remove(): nPos >= nSize" );
228 if ( mpImplPolyPolygon
->mnRefCount
> 1 )
230 mpImplPolyPolygon
->mnRefCount
--;
231 mpImplPolyPolygon
= new ImplPolyPolygon( *mpImplPolyPolygon
);
234 delete mpImplPolyPolygon
->mpPolyAry
[nPos
];
235 mpImplPolyPolygon
->mnCount
--;
236 memmove( mpImplPolyPolygon
->mpPolyAry
+nPos
,
237 mpImplPolyPolygon
->mpPolyAry
+nPos
+1,
238 (mpImplPolyPolygon
->mnCount
-nPos
)*sizeof(SVPPOLYGON
) );
241 // -----------------------------------------------------------------------
243 void PolyPolygon::Replace( const Polygon
& rPoly
, USHORT nPos
)
245 DBG_CHKTHIS( PolyPolygon
, NULL
);
246 DBG_ASSERT( nPos
< Count(), "PolyPolygon::Replace(): nPos >= nSize" );
248 if ( mpImplPolyPolygon
->mnRefCount
> 1 )
250 mpImplPolyPolygon
->mnRefCount
--;
251 mpImplPolyPolygon
= new ImplPolyPolygon( *mpImplPolyPolygon
);
254 delete mpImplPolyPolygon
->mpPolyAry
[nPos
];
255 mpImplPolyPolygon
->mpPolyAry
[nPos
] = new Polygon( rPoly
);
258 // -----------------------------------------------------------------------
260 const Polygon
& PolyPolygon::GetObject( USHORT nPos
) const
262 DBG_CHKTHIS( PolyPolygon
, NULL
);
263 DBG_ASSERT( nPos
< Count(), "PolyPolygon::GetObject(): nPos >= nSize" );
265 return *(mpImplPolyPolygon
->mpPolyAry
[nPos
]);
268 // -----------------------------------------------------------------------
270 BOOL
PolyPolygon::IsRect() const
272 BOOL bIsRect
= FALSE
;
274 bIsRect
= mpImplPolyPolygon
->mpPolyAry
[ 0 ]->IsRect();
278 // -----------------------------------------------------------------------
280 void PolyPolygon::Clear()
282 DBG_CHKTHIS( PolyPolygon
, NULL
);
284 if ( mpImplPolyPolygon
->mnRefCount
> 1 )
286 mpImplPolyPolygon
->mnRefCount
--;
287 mpImplPolyPolygon
= new ImplPolyPolygon( mpImplPolyPolygon
->mnResize
,
288 mpImplPolyPolygon
->mnResize
);
292 if ( mpImplPolyPolygon
->mpPolyAry
)
294 for ( USHORT i
= 0; i
< mpImplPolyPolygon
->mnCount
; i
++ )
295 delete mpImplPolyPolygon
->mpPolyAry
[i
];
296 delete[] mpImplPolyPolygon
->mpPolyAry
;
297 mpImplPolyPolygon
->mpPolyAry
= NULL
;
298 mpImplPolyPolygon
->mnCount
= 0;
299 mpImplPolyPolygon
->mnSize
= mpImplPolyPolygon
->mnResize
;
304 // -----------------------------------------------------------------------
306 void PolyPolygon::Optimize( ULONG nOptimizeFlags
, const PolyOptimizeData
* pData
)
308 DBG_CHKTHIS( PolyPolygon
, NULL
);
313 const BOOL bEdges
= ( nOptimizeFlags
& POLY_OPTIMIZE_EDGES
) == POLY_OPTIMIZE_EDGES
;
318 const Rectangle
aBound( GetBoundRect() );
320 fArea
= ( aBound
.GetWidth() + aBound
.GetHeight() ) * 0.5;
321 nPercent
= pData
? pData
->GetPercentValue() : 50;
322 nOptimizeFlags
&= ~POLY_OPTIMIZE_EDGES
;
325 // watch for ref counter
326 if( mpImplPolyPolygon
->mnRefCount
> 1 )
328 mpImplPolyPolygon
->mnRefCount
--;
329 mpImplPolyPolygon
= new ImplPolyPolygon( *mpImplPolyPolygon
);
333 for( USHORT i
= 0, nPolyCount
= mpImplPolyPolygon
->mnCount
; i
< nPolyCount
; i
++ )
337 mpImplPolyPolygon
->mpPolyAry
[ i
]->Optimize( POLY_OPTIMIZE_NO_SAME
);
338 Polygon::ImplReduceEdges( *( mpImplPolyPolygon
->mpPolyAry
[ i
] ), fArea
, nPercent
);
342 mpImplPolyPolygon
->mpPolyAry
[ i
]->Optimize( nOptimizeFlags
, pData
);
347 // -----------------------------------------------------------------------
349 void PolyPolygon::GetSimple( PolyPolygon
& rResult
) const
351 DBG_CHKTHIS( PolyPolygon
, NULL
);
357 for( USHORT i
= 0; i
< mpImplPolyPolygon
->mnCount
; i
++ )
359 mpImplPolyPolygon
->mpPolyAry
[ i
]->GetSimple( aPolygon
);
360 rResult
.Insert( aPolygon
);
364 // -----------------------------------------------------------------------
366 void PolyPolygon::AdaptiveSubdivide( PolyPolygon
& rResult
, const double d
) const
368 DBG_CHKTHIS( PolyPolygon
, NULL
);
374 for( USHORT i
= 0; i
< mpImplPolyPolygon
->mnCount
; i
++ )
376 mpImplPolyPolygon
->mpPolyAry
[ i
]->AdaptiveSubdivide( aPolygon
, d
);
377 rResult
.Insert( aPolygon
);
381 // -----------------------------------------------------------------------
383 void PolyPolygon::GetIntersection( const PolyPolygon
& rPolyPoly
, PolyPolygon
& rResult
) const
385 ImplDoOperation( rPolyPoly
, rResult
, POLY_CLIP_INT
);
388 // -----------------------------------------------------------------------
390 void PolyPolygon::GetUnion( const PolyPolygon
& rPolyPoly
, PolyPolygon
& rResult
) const
392 ImplDoOperation( rPolyPoly
, rResult
, POLY_CLIP_UNION
);
395 // -----------------------------------------------------------------------
397 void PolyPolygon::GetDifference( const PolyPolygon
& rPolyPoly
, PolyPolygon
& rResult
) const
399 ImplDoOperation( rPolyPoly
, rResult
, POLY_CLIP_DIFF
);
402 // -----------------------------------------------------------------------
404 void PolyPolygon::GetXOR( const PolyPolygon
& rPolyPoly
, PolyPolygon
& rResult
) const
406 ImplDoOperation( rPolyPoly
, rResult
, POLY_CLIP_XOR
);
409 // -----------------------------------------------------------------------
411 void PolyPolygon::ImplDoOperation( const PolyPolygon
& rPolyPoly
, PolyPolygon
& rResult
, ULONG nOperation
) const
413 // Convert to B2DPolyPolygon, temporarily. It might be
414 // advantageous in the future, to have a PolyPolygon adaptor that
415 // just simulates a B2DPolyPolygon here...
416 basegfx::B2DPolyPolygon
aMergePolyPolygonA( getB2DPolyPolygon() );
417 basegfx::B2DPolyPolygon
aMergePolyPolygonB( rPolyPoly
.getB2DPolyPolygon() );
419 // normalize the two polypolygons before. Force properly oriented
421 aMergePolyPolygonA
= basegfx::tools::prepareForPolygonOperation( aMergePolyPolygonA
);
422 aMergePolyPolygonB
= basegfx::tools::prepareForPolygonOperation( aMergePolyPolygonB
);
426 // All code extracted from svx/source/svdraw/svedtv2.cxx
427 // -----------------------------------------------------
429 case POLY_CLIP_UNION
:
431 // merge A and B (OR)
432 aMergePolyPolygonA
= basegfx::tools::solvePolygonOperationOr(aMergePolyPolygonA
, aMergePolyPolygonB
);
438 // substract B from A (DIFF)
439 aMergePolyPolygonA
= basegfx::tools::solvePolygonOperationDiff(aMergePolyPolygonA
, aMergePolyPolygonB
);
445 // compute XOR between poly A and B
446 aMergePolyPolygonA
= basegfx::tools::solvePolygonOperationXor(aMergePolyPolygonA
, aMergePolyPolygonB
);
453 // cut poly 1 against polys 2..n (AND)
454 aMergePolyPolygonA
= basegfx::tools::solvePolygonOperationAnd(aMergePolyPolygonA
, aMergePolyPolygonB
);
459 rResult
= PolyPolygon( aMergePolyPolygonA
);
462 // -----------------------------------------------------------------------
464 USHORT
PolyPolygon::Count() const
466 DBG_CHKTHIS( PolyPolygon
, NULL
);
467 return mpImplPolyPolygon
->mnCount
;
470 // -----------------------------------------------------------------------
472 void PolyPolygon::Move( long nHorzMove
, long nVertMove
)
474 DBG_CHKTHIS( PolyPolygon
, NULL
);
476 // Diese Abfrage sollte man fuer die DrawEngine durchfuehren
477 if( nHorzMove
|| nVertMove
)
479 // Referenzcounter beruecksichtigen
480 if ( mpImplPolyPolygon
->mnRefCount
> 1 )
482 mpImplPolyPolygon
->mnRefCount
--;
483 mpImplPolyPolygon
= new ImplPolyPolygon( *mpImplPolyPolygon
);
486 // Punkte verschieben
487 USHORT nPolyCount
= mpImplPolyPolygon
->mnCount
;
488 for ( USHORT i
= 0; i
< nPolyCount
; i
++ )
489 mpImplPolyPolygon
->mpPolyAry
[i
]->Move( nHorzMove
, nVertMove
);
493 // -----------------------------------------------------------------------
495 void PolyPolygon::Translate( const Point
& rTrans
)
497 DBG_CHKTHIS( PolyPolygon
, NULL
);
499 // Referenzcounter beruecksichtigen
500 if( mpImplPolyPolygon
->mnRefCount
> 1 )
502 mpImplPolyPolygon
->mnRefCount
--;
503 mpImplPolyPolygon
= new ImplPolyPolygon( *mpImplPolyPolygon
);
506 // Punkte verschieben
507 for ( USHORT i
= 0, nCount
= mpImplPolyPolygon
->mnCount
; i
< nCount
; i
++ )
508 mpImplPolyPolygon
->mpPolyAry
[ i
]->Translate( rTrans
);
511 // -----------------------------------------------------------------------
513 void PolyPolygon::Scale( double fScaleX
, double fScaleY
)
515 DBG_CHKTHIS( PolyPolygon
, NULL
);
517 // Referenzcounter beruecksichtigen
518 if( mpImplPolyPolygon
->mnRefCount
> 1 )
520 mpImplPolyPolygon
->mnRefCount
--;
521 mpImplPolyPolygon
= new ImplPolyPolygon( *mpImplPolyPolygon
);
524 // Punkte verschieben
525 for ( USHORT i
= 0, nCount
= mpImplPolyPolygon
->mnCount
; i
< nCount
; i
++ )
526 mpImplPolyPolygon
->mpPolyAry
[ i
]->Scale( fScaleX
, fScaleY
);
529 // -----------------------------------------------------------------------
531 void PolyPolygon::Rotate( const Point
& rCenter
, USHORT nAngle10
)
533 DBG_CHKTHIS( PolyPolygon
, NULL
);
538 const double fAngle
= F_PI1800
* nAngle10
;
539 Rotate( rCenter
, sin( fAngle
), cos( fAngle
) );
543 // -----------------------------------------------------------------------
545 void PolyPolygon::Rotate( const Point
& rCenter
, double fSin
, double fCos
)
547 DBG_CHKTHIS( PolyPolygon
, NULL
);
549 // Referenzcounter beruecksichtigen
550 if( mpImplPolyPolygon
->mnRefCount
> 1 )
552 mpImplPolyPolygon
->mnRefCount
--;
553 mpImplPolyPolygon
= new ImplPolyPolygon( *mpImplPolyPolygon
);
556 // Punkte verschieben
557 for ( USHORT i
= 0, nCount
= mpImplPolyPolygon
->mnCount
; i
< nCount
; i
++ )
558 mpImplPolyPolygon
->mpPolyAry
[ i
]->Rotate( rCenter
, fSin
, fCos
);
561 // -----------------------------------------------------------------------
563 void PolyPolygon::SlantX( long nYRef
, double fSin
, double fCos
)
565 DBG_CHKTHIS( PolyPolygon
, NULL
);
567 // Referenzcounter beruecksichtigen
568 if( mpImplPolyPolygon
->mnRefCount
> 1 )
570 mpImplPolyPolygon
->mnRefCount
--;
571 mpImplPolyPolygon
= new ImplPolyPolygon( *mpImplPolyPolygon
);
574 // Punkte verschieben
575 for ( USHORT i
= 0, nCount
= mpImplPolyPolygon
->mnCount
; i
< nCount
; i
++ )
576 mpImplPolyPolygon
->mpPolyAry
[ i
]->SlantX( nYRef
, fSin
, fCos
);
579 // -----------------------------------------------------------------------
581 void PolyPolygon::SlantY( long nXRef
, double fSin
, double fCos
)
583 DBG_CHKTHIS( PolyPolygon
, NULL
);
585 // Referenzcounter beruecksichtigen
586 if( mpImplPolyPolygon
->mnRefCount
> 1 )
588 mpImplPolyPolygon
->mnRefCount
--;
589 mpImplPolyPolygon
= new ImplPolyPolygon( *mpImplPolyPolygon
);
592 // Punkte verschieben
593 for ( USHORT i
= 0, nCount
= mpImplPolyPolygon
->mnCount
; i
< nCount
; i
++ )
594 mpImplPolyPolygon
->mpPolyAry
[ i
]->SlantY( nXRef
, fSin
, fCos
);
597 // -----------------------------------------------------------------------
599 void PolyPolygon::Distort( const Rectangle
& rRefRect
, const Polygon
& rDistortedRect
)
601 DBG_CHKTHIS( PolyPolygon
, NULL
);
603 // Referenzcounter beruecksichtigen
604 if( mpImplPolyPolygon
->mnRefCount
> 1 )
606 mpImplPolyPolygon
->mnRefCount
--;
607 mpImplPolyPolygon
= new ImplPolyPolygon( *mpImplPolyPolygon
);
610 // Punkte verschieben
611 for ( USHORT i
= 0, nCount
= mpImplPolyPolygon
->mnCount
; i
< nCount
; i
++ )
612 mpImplPolyPolygon
->mpPolyAry
[ i
]->Distort( rRefRect
, rDistortedRect
);
616 // -----------------------------------------------------------------------
618 void PolyPolygon::Clip( const Rectangle
& rRect
)
621 USHORT nPolyCount
= mpImplPolyPolygon
->mnCount
;
627 // Referenzcounter beruecksichtigen
628 if ( mpImplPolyPolygon
->mnRefCount
> 1 )
630 mpImplPolyPolygon
->mnRefCount
--;
631 mpImplPolyPolygon
= new ImplPolyPolygon( *mpImplPolyPolygon
);
634 // Erst jedes Polygon Clippen und dann die leeren entfernen
635 for ( i
= 0; i
< nPolyCount
; i
++ )
636 mpImplPolyPolygon
->mpPolyAry
[i
]->Clip( rRect
);
639 if ( GetObject( nPolyCount
-1 ).GetSize() <= 2 )
640 Remove( nPolyCount
-1 );
645 // -----------------------------------------------------------------------
647 Rectangle
PolyPolygon::GetBoundRect() const
649 DBG_CHKTHIS( PolyPolygon
, NULL
);
651 long nXMin
=0, nXMax
=0, nYMin
=0, nYMax
=0;
653 USHORT nPolyCount
= mpImplPolyPolygon
->mnCount
;
655 for ( USHORT n
= 0; n
< nPolyCount
; n
++ )
657 const Polygon
* pPoly
= mpImplPolyPolygon
->mpPolyAry
[n
];
658 const Point
* pAry
= pPoly
->GetConstPointAry();
659 USHORT nPointCount
= pPoly
->GetSize();
661 for ( USHORT i
= 0; i
< nPointCount
; i
++ )
663 const Point
* pPt
= &pAry
[ i
];
667 nXMin
= nXMax
= pPt
->X();
668 nYMin
= nYMax
= pPt
->Y();
673 if ( pPt
->X() < nXMin
)
675 if ( pPt
->X() > nXMax
)
677 if ( pPt
->Y() < nYMin
)
679 if ( pPt
->Y() > nYMax
)
686 return Rectangle( nXMin
, nYMin
, nXMax
, nYMax
);
691 // -----------------------------------------------------------------------
693 Polygon
& PolyPolygon::operator[]( USHORT nPos
)
695 DBG_CHKTHIS( PolyPolygon
, NULL
);
696 DBG_ASSERT( nPos
< Count(), "PolyPolygon::[](): nPos >= nSize" );
698 if ( mpImplPolyPolygon
->mnRefCount
> 1 )
700 mpImplPolyPolygon
->mnRefCount
--;
701 mpImplPolyPolygon
= new ImplPolyPolygon( *mpImplPolyPolygon
);
704 return *(mpImplPolyPolygon
->mpPolyAry
[nPos
]);
707 // -----------------------------------------------------------------------
709 PolyPolygon
& PolyPolygon::operator=( const PolyPolygon
& rPolyPoly
)
711 DBG_CHKTHIS( PolyPolygon
, NULL
);
712 DBG_CHKOBJ( &rPolyPoly
, PolyPolygon
, NULL
);
713 DBG_ASSERT( rPolyPoly
.mpImplPolyPolygon
->mnRefCount
< 0xFFFFFFFE, "PolyPolygon: RefCount overflow" );
715 rPolyPoly
.mpImplPolyPolygon
->mnRefCount
++;
717 if ( mpImplPolyPolygon
->mnRefCount
> 1 )
718 mpImplPolyPolygon
->mnRefCount
--;
720 delete mpImplPolyPolygon
;
722 mpImplPolyPolygon
= rPolyPoly
.mpImplPolyPolygon
;
726 // -----------------------------------------------------------------------
728 BOOL
PolyPolygon::operator==( const PolyPolygon
& rPolyPoly
) const
730 DBG_CHKTHIS( PolyPolygon
, NULL
);
731 DBG_CHKOBJ( &rPolyPoly
, PolyPolygon
, NULL
);
733 if ( rPolyPoly
.mpImplPolyPolygon
== mpImplPolyPolygon
)
739 // -----------------------------------------------------------------------
741 sal_Bool
PolyPolygon::IsEqual( const PolyPolygon
& rPolyPoly
) const
743 sal_Bool bIsEqual
= sal_True
;
744 if ( Count() != rPolyPoly
.Count() )
745 bIsEqual
= sal_False
;
749 for ( i
= 0; i
< Count(); i
++ )
751 if (!GetObject( i
).IsEqual( rPolyPoly
.GetObject( i
) ) )
753 bIsEqual
= sal_False
;
761 // -----------------------------------------------------------------------
763 SvStream
& operator>>( SvStream
& rIStream
, PolyPolygon
& rPolyPoly
)
765 DBG_CHKOBJ( &rPolyPoly
, PolyPolygon
, NULL
);
766 DBG_ASSERTWARNING( rIStream
.GetVersion(), "PolyPolygon::>> - Solar-Version not set on rIStream" );
771 // Anzahl der Polygone einlesen
772 rIStream
>> nPolyCount
;
777 // Referenzcounter beruecksichtigen
778 if ( rPolyPoly
.mpImplPolyPolygon
->mnRefCount
> 1 )
779 rPolyPoly
.mpImplPolyPolygon
->mnRefCount
--;
781 delete rPolyPoly
.mpImplPolyPolygon
;
783 rPolyPoly
.mpImplPolyPolygon
= new ImplPolyPolygon( nPolyCount
);
785 for ( USHORT i
= 0; i
< nPolyCount
; i
++ )
789 rPolyPoly
.mpImplPolyPolygon
->mpPolyAry
[i
] = pPoly
;
793 rPolyPoly
= PolyPolygon();
798 // -----------------------------------------------------------------------
800 SvStream
& operator<<( SvStream
& rOStream
, const PolyPolygon
& rPolyPoly
)
802 DBG_CHKOBJ( &rPolyPoly
, PolyPolygon
, NULL
);
803 DBG_ASSERTWARNING( rOStream
.GetVersion(), "PolyPolygon::<< - Solar-Version not set on rOStream" );
805 // Anzahl der Polygone rausschreiben
806 USHORT nPolyCount
= rPolyPoly
.mpImplPolyPolygon
->mnCount
;
807 rOStream
<< nPolyCount
;
809 // Die einzelnen Polygone ausgeben
810 for ( USHORT i
= 0; i
< nPolyCount
; i
++ )
811 rOStream
<< *(rPolyPoly
.mpImplPolyPolygon
->mpPolyAry
[i
]);
816 // -----------------------------------------------------------------------
818 void PolyPolygon::Read( SvStream
& rIStream
)
820 VersionCompat
aCompat( rIStream
, STREAM_READ
);
822 DBG_CHKTHIS( PolyPolygon
, NULL
);
823 DBG_ASSERTWARNING( rIStream
.GetVersion(), "PolyPolygon::>> - Solar-Version not set on rIStream" );
828 // Anzahl der Polygone einlesen
829 rIStream
>> nPolyCount
;
834 // Referenzcounter beruecksichtigen
835 if ( mpImplPolyPolygon
->mnRefCount
> 1 )
836 mpImplPolyPolygon
->mnRefCount
--;
838 delete mpImplPolyPolygon
;
840 mpImplPolyPolygon
= new ImplPolyPolygon( nPolyCount
);
842 for ( USHORT i
= 0; i
< nPolyCount
; i
++ )
845 pPoly
->ImplRead( rIStream
);
846 mpImplPolyPolygon
->mpPolyAry
[i
] = pPoly
;
850 *this = PolyPolygon();
853 // -----------------------------------------------------------------------
855 void PolyPolygon::Write( SvStream
& rOStream
) const
857 VersionCompat
aCompat( rOStream
, STREAM_WRITE
, 1 );
859 DBG_CHKTHIS( PolyPolygon
, NULL
);
860 DBG_ASSERTWARNING( rOStream
.GetVersion(), "PolyPolygon::<< - Solar-Version not set on rOStream" );
862 // Anzahl der Polygone rausschreiben
863 USHORT nPolyCount
= mpImplPolyPolygon
->mnCount
;
864 rOStream
<< nPolyCount
;
866 // Die einzelnen Polygone ausgeben
867 for ( USHORT i
= 0; i
< nPolyCount
; i
++ )
868 mpImplPolyPolygon
->mpPolyAry
[i
]->ImplWrite( rOStream
);;
871 // -----------------------------------------------------------------------
872 // convert to basegfx::B2DPolyPolygon and return
873 basegfx::B2DPolyPolygon
PolyPolygon::getB2DPolyPolygon() const
875 basegfx::B2DPolyPolygon aRetval
;
877 for(sal_uInt16
a(0); a
< mpImplPolyPolygon
->mnCount
; a
++)
879 Polygon
* pCandidate
= mpImplPolyPolygon
->mpPolyAry
[a
];
880 aRetval
.append(pCandidate
->getB2DPolygon());
886 // -----------------------------------------------------------------------
887 // constructor to convert from basegfx::B2DPolyPolygon
888 PolyPolygon::PolyPolygon(const basegfx::B2DPolyPolygon
& rPolyPolygon
)
890 DBG_CTOR( PolyPolygon
, NULL
);
891 const sal_uInt16
nCount(sal_uInt16(rPolyPolygon
.count()));
892 DBG_ASSERT(sal_uInt32(nCount
) == rPolyPolygon
.count(),
893 "PolyPolygon::PolyPolygon: Too many sub-polygons in given basegfx::B2DPolyPolygon (!)");
897 mpImplPolyPolygon
= new ImplPolyPolygon( nCount
);
899 for(sal_uInt16
a(0); a
< nCount
; a
++)
901 basegfx::B2DPolygon
aCandidate(rPolyPolygon
.getB2DPolygon(sal_uInt32(a
)));
902 mpImplPolyPolygon
->mpPolyAry
[a
] = new Polygon( aCandidate
);
907 mpImplPolyPolygon
= new ImplPolyPolygon( 16, 16 );