LCOV - code coverage report
Current view: top level - libreoffice/tools/source/generic - poly2.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 161 328 49.1 %
Date: 2012-12-27 Functions: 20 37 54.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #define POLY_CLIP_INT   0
      21             : #define POLY_CLIP_UNION 1
      22             : #define POLY_CLIP_DIFF  2
      23             : #define POLY_CLIP_XOR   3
      24             : 
      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 <basegfx/polygon/b2dpolypolygon.hxx>
      32             : #include <basegfx/polygon/b2dpolygon.hxx>
      33             : #include <basegfx/polygon/b2dpolypolygoncutter.hxx>
      34             : 
      35             : DBG_NAME( PolyPolygon )
      36             : 
      37         470 : ImplPolyPolygon::ImplPolyPolygon( sal_uInt16 nInitSize )
      38             : {
      39         470 :     mnRefCount  = 1;
      40         470 :     mnCount     = nInitSize;
      41         470 :     mnSize      = nInitSize;
      42         470 :     mnResize    = 16;
      43         470 :     mpPolyAry   = new SVPPOLYGON[ nInitSize ];
      44         470 : }
      45             : 
      46         164 : ImplPolyPolygon::ImplPolyPolygon( const ImplPolyPolygon& rImplPolyPoly )
      47             : {
      48         164 :     mnRefCount  = 1;
      49         164 :     mnCount     = rImplPolyPoly.mnCount;
      50         164 :     mnSize      = rImplPolyPoly.mnSize;
      51         164 :     mnResize    = rImplPolyPoly.mnResize;
      52             : 
      53         164 :     if ( rImplPolyPoly.mpPolyAry )
      54             :     {
      55         164 :         mpPolyAry = new SVPPOLYGON[mnSize];
      56         720 :         for ( sal_uInt16 i = 0; i < mnCount; i++ )
      57         556 :             mpPolyAry[i] = new Polygon( *rImplPolyPoly.mpPolyAry[i] );
      58             :     }
      59             :     else
      60           0 :         mpPolyAry = NULL;
      61         164 : }
      62             : 
      63        1216 : ImplPolyPolygon::~ImplPolyPolygon()
      64             : {
      65        1216 :     if ( mpPolyAry )
      66             :     {
      67        2230 :         for ( sal_uInt16 i = 0; i < mnCount; i++ )
      68        1519 :             delete mpPolyAry[i];
      69         711 :         delete[] mpPolyAry;
      70             :     }
      71        1216 : }
      72             : 
      73         572 : PolyPolygon::PolyPolygon( sal_uInt16 nInitSize, sal_uInt16 nResize )
      74             : {
      75             :     DBG_CTOR( PolyPolygon, NULL );
      76             : 
      77         572 :     if ( nInitSize > MAX_POLYGONS )
      78           0 :         nInitSize = MAX_POLYGONS;
      79         572 :     else if ( !nInitSize )
      80           0 :         nInitSize = 1;
      81         572 :     if ( nResize > MAX_POLYGONS )
      82           0 :         nResize = MAX_POLYGONS;
      83         572 :     else if ( !nResize )
      84           0 :         nResize = 1;
      85         572 :     mpImplPolyPolygon = new ImplPolyPolygon( nInitSize, nResize );
      86         572 : }
      87             : 
      88          10 : PolyPolygon::PolyPolygon( const Polygon& rPoly )
      89             : {
      90             :     DBG_CTOR( PolyPolygon, NULL );
      91             : 
      92          10 :     if ( rPoly.GetSize() )
      93             :     {
      94          10 :         mpImplPolyPolygon = new ImplPolyPolygon( 1 );
      95          10 :         mpImplPolyPolygon->mpPolyAry[0] = new Polygon( rPoly );
      96             :     }
      97             :     else
      98           0 :         mpImplPolyPolygon = new ImplPolyPolygon( 16, 16 );
      99          10 : }
     100             : 
     101           6 : PolyPolygon::PolyPolygon( sal_uInt16 nPoly, const sal_uInt16* pPointCountAry,
     102             :                           const Point* pPtAry )
     103             : {
     104             :     DBG_CTOR( PolyPolygon, NULL );
     105             : 
     106           6 :     if ( nPoly > MAX_POLYGONS )
     107           0 :         nPoly = MAX_POLYGONS;
     108             : 
     109           6 :     mpImplPolyPolygon = new ImplPolyPolygon( nPoly );
     110          12 :     for ( sal_uInt16 i = 0; i < nPoly; i++ )
     111             :     {
     112           6 :         mpImplPolyPolygon->mpPolyAry[i] = new Polygon( *pPointCountAry, pPtAry );
     113           6 :         pPtAry += *pPointCountAry;
     114           6 :         pPointCountAry++;
     115             :     }
     116           6 : }
     117             : 
     118         643 : PolyPolygon::PolyPolygon( const PolyPolygon& rPolyPoly )
     119             : {
     120             :     DBG_CTOR( PolyPolygon, NULL );
     121             :     DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
     122             :     DBG_ASSERT( rPolyPoly.mpImplPolyPolygon->mnRefCount < 0xFFFFFFFE, "PolyPolygon: RefCount overflow" );
     123             : 
     124         643 :     mpImplPolyPolygon = rPolyPoly.mpImplPolyPolygon;
     125         643 :     mpImplPolyPolygon->mnRefCount++;
     126         643 : }
     127             : 
     128        1685 : PolyPolygon::~PolyPolygon()
     129             : {
     130             :     DBG_DTOR( PolyPolygon, NULL );
     131             : 
     132        1685 :     if ( mpImplPolyPolygon->mnRefCount > 1 )
     133         566 :         mpImplPolyPolygon->mnRefCount--;
     134             :     else
     135        1119 :         delete mpImplPolyPolygon;
     136        1685 : }
     137             : 
     138         302 : void PolyPolygon::Insert( const Polygon& rPoly, sal_uInt16 nPos )
     139             : {
     140             :     DBG_CHKTHIS( PolyPolygon, NULL );
     141             : 
     142         302 :     if ( mpImplPolyPolygon->mnCount >= MAX_POLYGONS )
     143         302 :         return;
     144             : 
     145         302 :     if ( mpImplPolyPolygon->mnRefCount > 1 )
     146             :     {
     147           0 :         mpImplPolyPolygon->mnRefCount--;
     148           0 :         mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
     149             :     }
     150             : 
     151         302 :     if ( nPos > mpImplPolyPolygon->mnCount )
     152         302 :         nPos = mpImplPolyPolygon->mnCount;
     153             : 
     154         302 :     if ( !mpImplPolyPolygon->mpPolyAry )
     155          94 :         mpImplPolyPolygon->mpPolyAry = new SVPPOLYGON[mpImplPolyPolygon->mnSize];
     156         208 :     else if ( mpImplPolyPolygon->mnCount == mpImplPolyPolygon->mnSize )
     157             :     {
     158           0 :         sal_uInt16      nOldSize = mpImplPolyPolygon->mnSize;
     159           0 :         sal_uInt16      nNewSize = nOldSize + mpImplPolyPolygon->mnResize;
     160             :         SVPPOLYGON* pNewAry;
     161             : 
     162           0 :         if ( nNewSize >= MAX_POLYGONS )
     163           0 :             nNewSize = MAX_POLYGONS;
     164           0 :         pNewAry = new SVPPOLYGON[nNewSize];
     165           0 :         memcpy( pNewAry, mpImplPolyPolygon->mpPolyAry, nPos*sizeof(SVPPOLYGON) );
     166           0 :         memcpy( pNewAry+nPos+1, mpImplPolyPolygon->mpPolyAry+nPos,
     167           0 :                 (nOldSize-nPos)*sizeof(SVPPOLYGON) );
     168           0 :         delete[] mpImplPolyPolygon->mpPolyAry;
     169           0 :         mpImplPolyPolygon->mpPolyAry = pNewAry;
     170           0 :         mpImplPolyPolygon->mnSize = nNewSize;
     171             :     }
     172         208 :     else if ( nPos < mpImplPolyPolygon->mnCount )
     173             :     {
     174           0 :         memmove( mpImplPolyPolygon->mpPolyAry+nPos+1,
     175             :                  mpImplPolyPolygon->mpPolyAry+nPos,
     176           0 :                  (mpImplPolyPolygon->mnCount-nPos)*sizeof(SVPPOLYGON) );
     177             :     }
     178             : 
     179         302 :     mpImplPolyPolygon->mpPolyAry[nPos] = new Polygon( rPoly );
     180         302 :     mpImplPolyPolygon->mnCount++;
     181             : }
     182             : 
     183           0 : void PolyPolygon::Remove( sal_uInt16 nPos )
     184             : {
     185             :     DBG_CHKTHIS( PolyPolygon, NULL );
     186             :     DBG_ASSERT( nPos < Count(), "PolyPolygon::Remove(): nPos >= nSize" );
     187             : 
     188           0 :     if ( mpImplPolyPolygon->mnRefCount > 1 )
     189             :     {
     190           0 :         mpImplPolyPolygon->mnRefCount--;
     191           0 :         mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
     192             :     }
     193             : 
     194           0 :     delete mpImplPolyPolygon->mpPolyAry[nPos];
     195           0 :     mpImplPolyPolygon->mnCount--;
     196           0 :     memmove( mpImplPolyPolygon->mpPolyAry+nPos,
     197           0 :              mpImplPolyPolygon->mpPolyAry+nPos+1,
     198           0 :              (mpImplPolyPolygon->mnCount-nPos)*sizeof(SVPPOLYGON) );
     199           0 : }
     200             : 
     201           0 : void PolyPolygon::Replace( const Polygon& rPoly, sal_uInt16 nPos )
     202             : {
     203             :     DBG_CHKTHIS( PolyPolygon, NULL );
     204             :     DBG_ASSERT( nPos < Count(), "PolyPolygon::Replace(): nPos >= nSize" );
     205             : 
     206           0 :     if ( mpImplPolyPolygon->mnRefCount > 1 )
     207             :     {
     208           0 :         mpImplPolyPolygon->mnRefCount--;
     209           0 :         mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
     210             :     }
     211             : 
     212           0 :     delete mpImplPolyPolygon->mpPolyAry[nPos];
     213           0 :     mpImplPolyPolygon->mpPolyAry[nPos] = new Polygon( rPoly );
     214           0 : }
     215             : 
     216        1015 : const Polygon& PolyPolygon::GetObject( sal_uInt16 nPos ) const
     217             : {
     218             :     DBG_CHKTHIS( PolyPolygon, NULL );
     219             :     DBG_ASSERT( nPos < Count(), "PolyPolygon::GetObject(): nPos >= nSize" );
     220             : 
     221        1015 :     return *(mpImplPolyPolygon->mpPolyAry[nPos]);
     222             : }
     223             : 
     224           0 : sal_Bool PolyPolygon::IsRect() const
     225             : {
     226           0 :     sal_Bool bIsRect = sal_False;
     227           0 :     if ( Count() == 1 )
     228           0 :         bIsRect = mpImplPolyPolygon->mpPolyAry[ 0 ]->IsRect();
     229           0 :     return bIsRect;
     230             : }
     231             : 
     232          62 : void PolyPolygon::Clear()
     233             : {
     234             :     DBG_CHKTHIS( PolyPolygon, NULL );
     235             : 
     236          62 :     if ( mpImplPolyPolygon->mnRefCount > 1 )
     237             :     {
     238          10 :         mpImplPolyPolygon->mnRefCount--;
     239             :         mpImplPolyPolygon = new ImplPolyPolygon( mpImplPolyPolygon->mnResize,
     240          10 :                                                  mpImplPolyPolygon->mnResize );
     241             :     }
     242             :     else
     243             :     {
     244          52 :         if ( mpImplPolyPolygon->mpPolyAry )
     245             :         {
     246          12 :             for ( sal_uInt16 i = 0; i < mpImplPolyPolygon->mnCount; i++ )
     247           6 :                 delete mpImplPolyPolygon->mpPolyAry[i];
     248           6 :             delete[] mpImplPolyPolygon->mpPolyAry;
     249           6 :             mpImplPolyPolygon->mpPolyAry = NULL;
     250           6 :             mpImplPolyPolygon->mnCount   = 0;
     251           6 :             mpImplPolyPolygon->mnSize    = mpImplPolyPolygon->mnResize;
     252             :         }
     253             :     }
     254          62 : }
     255             : 
     256          35 : void PolyPolygon::Optimize( sal_uIntPtr nOptimizeFlags, const PolyOptimizeData* pData )
     257             : {
     258             :     DBG_CHKTHIS( PolyPolygon, NULL );
     259             : 
     260          35 :     if( nOptimizeFlags )
     261             :     {
     262             :         double      fArea;
     263          35 :         const sal_Bool  bEdges = ( nOptimizeFlags & POLY_OPTIMIZE_EDGES ) == POLY_OPTIMIZE_EDGES;
     264          35 :         sal_uInt16      nPercent = 0;
     265             : 
     266          35 :         if( bEdges )
     267             :         {
     268          35 :             const Rectangle aBound( GetBoundRect() );
     269             : 
     270          35 :             fArea = ( aBound.GetWidth() + aBound.GetHeight() ) * 0.5;
     271          35 :             nPercent = pData ? pData->GetPercentValue() : 50;
     272          35 :             nOptimizeFlags &= ~POLY_OPTIMIZE_EDGES;
     273             :         }
     274             : 
     275             :         // watch for ref counter
     276          35 :         if( mpImplPolyPolygon->mnRefCount > 1 )
     277             :         {
     278           0 :             mpImplPolyPolygon->mnRefCount--;
     279           0 :             mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
     280             :         }
     281             : 
     282             :         // Optimize polygons
     283          35 :         for( sal_uInt16 i = 0, nPolyCount = mpImplPolyPolygon->mnCount; i < nPolyCount; i++ )
     284             :         {
     285           0 :             if( bEdges )
     286             :             {
     287           0 :                 mpImplPolyPolygon->mpPolyAry[ i ]->Optimize( POLY_OPTIMIZE_NO_SAME );
     288           0 :                 Polygon::ImplReduceEdges( *( mpImplPolyPolygon->mpPolyAry[ i ] ), fArea, nPercent );
     289             :             }
     290             : 
     291           0 :             if( nOptimizeFlags )
     292           0 :                 mpImplPolyPolygon->mpPolyAry[ i ]->Optimize( nOptimizeFlags, pData );
     293             :         }
     294             :     }
     295          35 : }
     296             : 
     297           0 : void PolyPolygon::AdaptiveSubdivide( PolyPolygon& rResult, const double d ) const
     298             : {
     299             :     DBG_CHKTHIS( PolyPolygon, NULL );
     300             : 
     301           0 :     rResult.Clear();
     302             : 
     303           0 :     Polygon aPolygon;
     304             : 
     305           0 :     for( sal_uInt16 i = 0; i < mpImplPolyPolygon->mnCount; i++ )
     306             :     {
     307           0 :         mpImplPolyPolygon->mpPolyAry[ i ]->AdaptiveSubdivide( aPolygon, d );
     308           0 :         rResult.Insert( aPolygon );
     309           0 :     }
     310           0 : }
     311             : 
     312           0 : void PolyPolygon::GetIntersection( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const
     313             : {
     314           0 :     ImplDoOperation( rPolyPoly, rResult, POLY_CLIP_INT );
     315           0 : }
     316             : 
     317           0 : void PolyPolygon::GetUnion( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const
     318             : {
     319           0 :     ImplDoOperation( rPolyPoly, rResult, POLY_CLIP_UNION );
     320           0 : }
     321             : 
     322           0 : void PolyPolygon::ImplDoOperation( const PolyPolygon& rPolyPoly, PolyPolygon& rResult, sal_uIntPtr nOperation ) const
     323             : {
     324             :     // Convert to B2DPolyPolygon, temporarily. It might be
     325             :     // advantageous in the future, to have a PolyPolygon adaptor that
     326             :     // just simulates a B2DPolyPolygon here...
     327           0 :     basegfx::B2DPolyPolygon aMergePolyPolygonA( getB2DPolyPolygon() );
     328           0 :     basegfx::B2DPolyPolygon aMergePolyPolygonB( rPolyPoly.getB2DPolyPolygon() );
     329             : 
     330             :     // normalize the two polypolygons before. Force properly oriented
     331             :     // polygons.
     332           0 :     aMergePolyPolygonA = basegfx::tools::prepareForPolygonOperation( aMergePolyPolygonA );
     333           0 :     aMergePolyPolygonB = basegfx::tools::prepareForPolygonOperation( aMergePolyPolygonB );
     334             : 
     335           0 :     switch( nOperation )
     336             :     {
     337             :         // All code extracted from svx/source/svdraw/svedtv2.cxx
     338             : 
     339             :         case POLY_CLIP_UNION:
     340             :         {
     341             :             // merge A and B (OR)
     342           0 :             aMergePolyPolygonA = basegfx::tools::solvePolygonOperationOr(aMergePolyPolygonA, aMergePolyPolygonB);
     343           0 :             break;
     344             :         }
     345             : 
     346             :         case POLY_CLIP_DIFF:
     347             :         {
     348             :             // substract B from A (DIFF)
     349           0 :             aMergePolyPolygonA = basegfx::tools::solvePolygonOperationDiff(aMergePolyPolygonA, aMergePolyPolygonB);
     350           0 :             break;
     351             :         }
     352             : 
     353             :         case POLY_CLIP_XOR:
     354             :         {
     355             :             // compute XOR between poly A and B
     356           0 :             aMergePolyPolygonA = basegfx::tools::solvePolygonOperationXor(aMergePolyPolygonA, aMergePolyPolygonB);
     357           0 :             break;
     358             :         }
     359             : 
     360             :         default:
     361             :         case POLY_CLIP_INT:
     362             :         {
     363             :             // cut poly 1 against polys 2..n (AND)
     364           0 :             aMergePolyPolygonA = basegfx::tools::solvePolygonOperationAnd(aMergePolyPolygonA, aMergePolyPolygonB);
     365           0 :             break;
     366             :         }
     367             :     }
     368             : 
     369           0 :     rResult = PolyPolygon( aMergePolyPolygonA );
     370           0 : }
     371             : 
     372         820 : sal_uInt16 PolyPolygon::Count() const
     373             : {
     374             :     DBG_CHKTHIS( PolyPolygon, NULL );
     375         820 :     return mpImplPolyPolygon->mnCount;
     376             : }
     377             : 
     378          73 : void PolyPolygon::Move( long nHorzMove, long nVertMove )
     379             : {
     380             :     DBG_CHKTHIS( PolyPolygon, NULL );
     381             : 
     382             :     // Required for DrawEngine
     383          73 :     if( nHorzMove || nVertMove )
     384             :     {
     385          73 :         if ( mpImplPolyPolygon->mnRefCount > 1 )
     386             :         {
     387          73 :             mpImplPolyPolygon->mnRefCount--;
     388          73 :             mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
     389             :         }
     390             : 
     391             :         // move points
     392          73 :         sal_uInt16 nPolyCount = mpImplPolyPolygon->mnCount;
     393         338 :         for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
     394         265 :             mpImplPolyPolygon->mpPolyAry[i]->Move( nHorzMove, nVertMove );
     395             :     }
     396          73 : }
     397             : 
     398           0 : void PolyPolygon::Translate( const Point& rTrans )
     399             : {
     400             :     DBG_CHKTHIS( PolyPolygon, NULL );
     401             : 
     402           0 :     if( mpImplPolyPolygon->mnRefCount > 1 )
     403             :     {
     404           0 :         mpImplPolyPolygon->mnRefCount--;
     405           0 :         mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
     406             :     }
     407             : 
     408             :     // move points
     409           0 :     for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ )
     410           0 :         mpImplPolyPolygon->mpPolyAry[ i ]->Translate( rTrans );
     411           0 : }
     412             : 
     413           0 : void PolyPolygon::Scale( double fScaleX, double fScaleY )
     414             : {
     415             :     DBG_CHKTHIS( PolyPolygon, NULL );
     416             : 
     417           0 :     if( mpImplPolyPolygon->mnRefCount > 1 )
     418             :     {
     419           0 :         mpImplPolyPolygon->mnRefCount--;
     420           0 :         mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
     421             :     }
     422             : 
     423             :     // Move points
     424           0 :     for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ )
     425           0 :         mpImplPolyPolygon->mpPolyAry[ i ]->Scale( fScaleX, fScaleY );
     426           0 : }
     427             : 
     428           0 : void PolyPolygon::Rotate( const Point& rCenter, sal_uInt16 nAngle10 )
     429             : {
     430             :     DBG_CHKTHIS( PolyPolygon, NULL );
     431           0 :     nAngle10 %= 3600;
     432             : 
     433           0 :     if( nAngle10 )
     434             :     {
     435           0 :         const double fAngle = F_PI1800 * nAngle10;
     436           0 :         Rotate( rCenter, sin( fAngle ), cos( fAngle ) );
     437             :     }
     438           0 : }
     439             : 
     440           0 : void PolyPolygon::Rotate( const Point& rCenter, double fSin, double fCos )
     441             : {
     442             :     DBG_CHKTHIS( PolyPolygon, NULL );
     443             : 
     444           0 :     if( mpImplPolyPolygon->mnRefCount > 1 )
     445             :     {
     446           0 :         mpImplPolyPolygon->mnRefCount--;
     447           0 :         mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
     448             :     }
     449             : 
     450             :     // move points
     451           0 :     for ( sal_uInt16 i = 0, nCount = mpImplPolyPolygon->mnCount; i < nCount; i++ )
     452           0 :         mpImplPolyPolygon->mpPolyAry[ i ]->Rotate( rCenter, fSin, fCos );
     453           0 : }
     454             : 
     455           0 : void PolyPolygon::Clip( const Rectangle& rRect )
     456             : {
     457           0 :     sal_uInt16 nPolyCount = mpImplPolyPolygon->mnCount;
     458             :     sal_uInt16 i;
     459             : 
     460           0 :     if ( !nPolyCount )
     461           0 :         return;
     462             : 
     463           0 :     if ( mpImplPolyPolygon->mnRefCount > 1 )
     464             :     {
     465           0 :         mpImplPolyPolygon->mnRefCount--;
     466           0 :         mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
     467             :     }
     468             : 
     469             :     // Clip every polygon, deleting the empty ones
     470           0 :     for ( i = 0; i < nPolyCount; i++ )
     471           0 :         mpImplPolyPolygon->mpPolyAry[i]->Clip( rRect );
     472           0 :     while ( nPolyCount )
     473             :     {
     474           0 :         if ( GetObject( nPolyCount-1 ).GetSize() <= 2 )
     475           0 :             Remove( nPolyCount-1 );
     476           0 :         nPolyCount--;
     477             :     }
     478             : }
     479             : 
     480          46 : Rectangle PolyPolygon::GetBoundRect() const
     481             : {
     482             :     DBG_CHKTHIS( PolyPolygon, NULL );
     483             : 
     484          46 :     long    nXMin=0, nXMax=0, nYMin=0, nYMax=0;
     485          46 :     sal_Bool    bFirst = sal_True;
     486          46 :     sal_uInt16  nPolyCount = mpImplPolyPolygon->mnCount;
     487             : 
     488          65 :     for ( sal_uInt16 n = 0; n < nPolyCount; n++ )
     489             :     {
     490          19 :         const Polygon*  pPoly = mpImplPolyPolygon->mpPolyAry[n];
     491          19 :         const Point*    pAry = pPoly->GetConstPointAry();
     492          19 :         sal_uInt16          nPointCount = pPoly->GetSize();
     493             : 
     494         315 :         for ( sal_uInt16 i = 0; i < nPointCount; i++ )
     495             :         {
     496         296 :             const Point* pPt = &pAry[ i ];
     497             : 
     498         296 :             if ( bFirst )
     499             :             {
     500          11 :                 nXMin = nXMax = pPt->X();
     501          11 :                 nYMin = nYMax = pPt->Y();
     502          11 :                 bFirst = sal_False;
     503             :             }
     504             :             else
     505             :             {
     506         285 :                 if ( pPt->X() < nXMin )
     507          39 :                     nXMin = pPt->X();
     508         285 :                 if ( pPt->X() > nXMax )
     509          23 :                     nXMax = pPt->X();
     510         285 :                 if ( pPt->Y() < nYMin )
     511          29 :                     nYMin = pPt->Y();
     512         285 :                 if ( pPt->Y() > nYMax )
     513          40 :                     nYMax = pPt->Y();
     514             :             }
     515             :         }
     516             :     }
     517             : 
     518          46 :     if ( !bFirst )
     519          11 :         return Rectangle( nXMin, nYMin, nXMax, nYMax );
     520             :     else
     521          35 :         return Rectangle();
     522             : }
     523             : 
     524         713 : Polygon& PolyPolygon::operator[]( sal_uInt16 nPos )
     525             : {
     526             :     DBG_CHKTHIS( PolyPolygon, NULL );
     527             :     DBG_ASSERT( nPos < Count(), "PolyPolygon::[](): nPos >= nSize" );
     528             : 
     529         713 :     if ( mpImplPolyPolygon->mnRefCount > 1 )
     530             :     {
     531          91 :         mpImplPolyPolygon->mnRefCount--;
     532          91 :         mpImplPolyPolygon = new ImplPolyPolygon( *mpImplPolyPolygon );
     533             :     }
     534             : 
     535         713 :     return *(mpImplPolyPolygon->mpPolyAry[nPos]);
     536             : }
     537             : 
     538         172 : PolyPolygon& PolyPolygon::operator=( const PolyPolygon& rPolyPoly )
     539             : {
     540             :     DBG_CHKTHIS( PolyPolygon, NULL );
     541             :     DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
     542             :     DBG_ASSERT( rPolyPoly.mpImplPolyPolygon->mnRefCount < 0xFFFFFFFE, "PolyPolygon: RefCount overflow" );
     543             : 
     544         172 :     rPolyPoly.mpImplPolyPolygon->mnRefCount++;
     545             : 
     546         172 :     if ( mpImplPolyPolygon->mnRefCount > 1 )
     547          75 :         mpImplPolyPolygon->mnRefCount--;
     548             :     else
     549          97 :         delete mpImplPolyPolygon;
     550             : 
     551         172 :     mpImplPolyPolygon = rPolyPoly.mpImplPolyPolygon;
     552         172 :     return *this;
     553             : }
     554             : 
     555           0 : sal_Bool PolyPolygon::operator==( const PolyPolygon& rPolyPoly ) const
     556             : {
     557             :     DBG_CHKTHIS( PolyPolygon, NULL );
     558             :     DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
     559             : 
     560           0 :     if ( rPolyPoly.mpImplPolyPolygon == mpImplPolyPolygon )
     561           0 :         return sal_True;
     562             :     else
     563           0 :         return sal_False;
     564             : }
     565             : 
     566           0 : sal_Bool PolyPolygon::IsEqual( const PolyPolygon& rPolyPoly ) const
     567             : {
     568           0 :     sal_Bool bIsEqual = sal_True;
     569           0 :     if ( Count() != rPolyPoly.Count() )
     570           0 :         bIsEqual = sal_False;
     571             :     else
     572             :     {
     573             :         sal_uInt16 i;
     574           0 :         for ( i = 0; i < Count(); i++ )
     575             :         {
     576           0 :             if (!GetObject( i ).IsEqual( rPolyPoly.GetObject( i ) ) )
     577             :             {
     578           0 :                 bIsEqual = sal_False;
     579           0 :                 break;
     580             :             }
     581             :         }
     582             :     }
     583           0 :     return bIsEqual;
     584             : }
     585             : 
     586           0 : SvStream& operator>>( SvStream& rIStream, PolyPolygon& rPolyPoly )
     587             : {
     588             :     DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
     589             :     DBG_ASSERTWARNING( rIStream.GetVersion(), "PolyPolygon::>> - Solar-Version not set on rIStream" );
     590             : 
     591             :     Polygon* pPoly;
     592             :     sal_uInt16   nPolyCount;
     593             : 
     594             :     // read number of polygons
     595           0 :     rIStream >> nPolyCount;
     596             : 
     597           0 :     if( nPolyCount )
     598             :     {
     599           0 :         if ( rPolyPoly.mpImplPolyPolygon->mnRefCount > 1 )
     600           0 :             rPolyPoly.mpImplPolyPolygon->mnRefCount--;
     601             :         else
     602           0 :             delete rPolyPoly.mpImplPolyPolygon;
     603             : 
     604           0 :         rPolyPoly.mpImplPolyPolygon = new ImplPolyPolygon( nPolyCount );
     605             : 
     606           0 :         for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
     607             :         {
     608           0 :             pPoly = new Polygon;
     609           0 :             rIStream >> *pPoly;
     610           0 :             rPolyPoly.mpImplPolyPolygon->mpPolyAry[i] = pPoly;
     611             :         }
     612             :     }
     613             :     else
     614           0 :         rPolyPoly = PolyPolygon();
     615             : 
     616           0 :     return rIStream;
     617             : }
     618             : 
     619           0 : SvStream& operator<<( SvStream& rOStream, const PolyPolygon& rPolyPoly )
     620             : {
     621             :     DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
     622             :     DBG_ASSERTWARNING( rOStream.GetVersion(), "PolyPolygon::<< - Solar-Version not set on rOStream" );
     623             : 
     624             :     // Write number of polygons
     625           0 :     sal_uInt16 nPolyCount = rPolyPoly.mpImplPolyPolygon->mnCount;
     626           0 :     rOStream << nPolyCount;
     627             : 
     628             :     // output polygons
     629           0 :     for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
     630           0 :         rOStream << *(rPolyPoly.mpImplPolyPolygon->mpPolyAry[i]);
     631             : 
     632           0 :     return rOStream;
     633             : }
     634             : 
     635           0 : void PolyPolygon::Read( SvStream& rIStream )
     636             : {
     637           0 :     VersionCompat aCompat( rIStream, STREAM_READ );
     638             : 
     639             :     DBG_CHKTHIS( PolyPolygon, NULL );
     640             :     DBG_ASSERTWARNING( rIStream.GetVersion(), "PolyPolygon::>> - Solar-Version not set on rIStream" );
     641             : 
     642             :     Polygon* pPoly;
     643             :     sal_uInt16   nPolyCount;
     644             : 
     645             :     // Read number of polygons
     646           0 :     rIStream >> nPolyCount;
     647             : 
     648           0 :     if( nPolyCount )
     649             :     {
     650           0 :         if ( mpImplPolyPolygon->mnRefCount > 1 )
     651           0 :             mpImplPolyPolygon->mnRefCount--;
     652             :         else
     653           0 :             delete mpImplPolyPolygon;
     654             : 
     655           0 :         mpImplPolyPolygon = new ImplPolyPolygon( nPolyCount );
     656             : 
     657           0 :         for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
     658             :         {
     659           0 :             pPoly = new Polygon;
     660           0 :             pPoly->ImplRead( rIStream );
     661           0 :             mpImplPolyPolygon->mpPolyAry[i] = pPoly;
     662             :         }
     663             :     }
     664             :     else
     665           0 :         *this = PolyPolygon();
     666           0 : }
     667             : 
     668          31 : void PolyPolygon::Write( SvStream& rOStream ) const
     669             : {
     670          31 :     VersionCompat aCompat( rOStream, STREAM_WRITE, 1 );
     671             : 
     672             :     DBG_CHKTHIS( PolyPolygon, NULL );
     673             :     DBG_ASSERTWARNING( rOStream.GetVersion(), "PolyPolygon::<< - Solar-Version not set on rOStream" );
     674             : 
     675             :     // Write number of polygons
     676          31 :     sal_uInt16 nPolyCount = mpImplPolyPolygon->mnCount;
     677          31 :     rOStream << nPolyCount;
     678             : 
     679             :     // Output polygons
     680          59 :     for ( sal_uInt16 i = 0; i < nPolyCount; i++ )
     681          59 :         mpImplPolyPolygon->mpPolyAry[i]->ImplWrite( rOStream );
     682          31 : }
     683             : 
     684             : // convert to basegfx::B2DPolyPolygon and return
     685          92 : basegfx::B2DPolyPolygon PolyPolygon::getB2DPolyPolygon() const
     686             : {
     687          92 :     basegfx::B2DPolyPolygon aRetval;
     688             : 
     689         381 :     for(sal_uInt16 a(0); a < mpImplPolyPolygon->mnCount; a++)
     690             :     {
     691         289 :         Polygon* pCandidate = mpImplPolyPolygon->mpPolyAry[a];
     692         289 :         aRetval.append(pCandidate->getB2DPolygon());
     693             :     }
     694             : 
     695          92 :     return aRetval;
     696             : }
     697             : 
     698             : // constructor to convert from basegfx::B2DPolyPolygon
     699         465 : PolyPolygon::PolyPolygon(const basegfx::B2DPolyPolygon& rPolyPolygon)
     700             : {
     701             :     DBG_CTOR( PolyPolygon, NULL );
     702         465 :     const sal_uInt16 nCount(sal_uInt16(rPolyPolygon.count()));
     703             :     DBG_ASSERT(sal_uInt32(nCount) == rPolyPolygon.count(),
     704             :         "PolyPolygon::PolyPolygon: Too many sub-polygons in given basegfx::B2DPolyPolygon (!)");
     705             : 
     706         465 :     if ( nCount )
     707             :     {
     708         454 :         mpImplPolyPolygon = new ImplPolyPolygon( nCount );
     709             : 
     710        1124 :         for(sal_uInt16 a(0); a < nCount; a++)
     711             :         {
     712         670 :             basegfx::B2DPolygon aCandidate(rPolyPolygon.getB2DPolygon(sal_uInt32(a)));
     713         670 :             mpImplPolyPolygon->mpPolyAry[a] = new Polygon( aCandidate );
     714         670 :         }
     715             :     }
     716             :     else
     717             :     {
     718          11 :         mpImplPolyPolygon = new ImplPolyPolygon( 16, 16 );
     719             :     }
     720         465 : }
     721             : 
     722             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10