LCOV - code coverage report
Current view: top level - tools/source/generic - poly2.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 184 334 55.1 %
Date: 2012-08-25 Functions: 22 39 56.4 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 119 350 34.0 %

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

Generated by: LCOV version 1.10