LCOV - code coverage report
Current view: top level - basegfx/source/polygon - b2dpolygon.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 544 643 84.6 %
Date: 2012-08-25 Functions: 112 123 91.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 368 696 52.9 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include <osl/diagnose.h>
      30                 :            : #include <basegfx/polygon/b2dpolygon.hxx>
      31                 :            : #include <basegfx/point/b2dpoint.hxx>
      32                 :            : #include <basegfx/vector/b2dvector.hxx>
      33                 :            : #include <basegfx/matrix/b2dhommatrix.hxx>
      34                 :            : #include <basegfx/curve/b2dcubicbezier.hxx>
      35                 :            : #include <rtl/instance.hxx>
      36                 :            : #include <basegfx/polygon/b2dpolygontools.hxx>
      37                 :            : #include <boost/scoped_ptr.hpp>
      38                 :            : #include <vector>
      39                 :            : #include <algorithm>
      40                 :            : 
      41                 :            : //////////////////////////////////////////////////////////////////////////////
      42                 :            : 
      43                 :   60371702 : struct CoordinateData2D : public basegfx::B2DPoint
      44                 :            : {
      45                 :            : public:
      46                 :          0 :     CoordinateData2D() {}
      47                 :            : 
      48                 :    7940099 :     explicit CoordinateData2D(const basegfx::B2DPoint& rData)
      49                 :    7940099 :     :   B2DPoint(rData)
      50                 :    7940099 :     {}
      51                 :            : 
      52                 :   11021722 :     CoordinateData2D& operator=(const basegfx::B2DPoint& rData)
      53                 :            :     {
      54                 :   11021722 :         B2DPoint::operator=(rData);
      55                 :   11021722 :         return *this;
      56                 :            :     }
      57                 :            : 
      58                 :    2886881 :     void transform(const basegfx::B2DHomMatrix& rMatrix)
      59                 :            :     {
      60                 :    2886881 :         *this *= rMatrix;
      61                 :    2886881 :     }
      62                 :            : };
      63                 :            : 
      64                 :            : //////////////////////////////////////////////////////////////////////////////
      65                 :            : 
      66                 :    5030679 : class CoordinateDataArray2D
      67                 :            : {
      68                 :            :     typedef ::std::vector< CoordinateData2D > CoordinateData2DVector;
      69                 :            : 
      70                 :            :     CoordinateData2DVector                          maVector;
      71                 :            : 
      72                 :            : public:
      73                 :        206 :     explicit CoordinateDataArray2D(sal_uInt32 nCount)
      74                 :        206 :     :   maVector(nCount)
      75                 :            :     {
      76                 :        206 :     }
      77                 :            : 
      78                 :    5030695 :     explicit CoordinateDataArray2D(const CoordinateDataArray2D& rOriginal)
      79                 :    5030695 :     :   maVector(rOriginal.maVector)
      80                 :            :     {
      81                 :    5030695 :     }
      82                 :            : 
      83                 :          0 :     CoordinateDataArray2D(const CoordinateDataArray2D& rOriginal, sal_uInt32 nIndex, sal_uInt32 nCount)
      84 [ #  # ][ #  # ]:          0 :     :   maVector(rOriginal.maVector.begin() + nIndex, rOriginal.maVector.begin() + (nIndex + nCount))
                 [ #  # ]
      85                 :            :     {
      86                 :          0 :     }
      87                 :            : 
      88                 :   13115853 :     sal_uInt32 count() const
      89                 :            :     {
      90                 :   13115853 :         return maVector.size();
      91                 :            :     }
      92                 :            : 
      93                 :      60738 :     bool operator==(const CoordinateDataArray2D& rCandidate) const
      94                 :            :     {
      95                 :      60738 :         return (maVector == rCandidate.maVector);
      96                 :            :     }
      97                 :            : 
      98                 :   62760160 :     const basegfx::B2DPoint& getCoordinate(sal_uInt32 nIndex) const
      99                 :            :     {
     100                 :   62760160 :         return maVector[nIndex];
     101                 :            :     }
     102                 :            : 
     103                 :   11021722 :     void setCoordinate(sal_uInt32 nIndex, const basegfx::B2DPoint& rValue)
     104                 :            :     {
     105                 :   11021722 :         maVector[nIndex] = rValue;
     106                 :   11021722 :     }
     107                 :            : 
     108                 :        245 :     void reserve(sal_uInt32 nCount)
     109                 :            :     {
     110                 :        245 :         maVector.reserve(nCount);
     111                 :        245 :     }
     112                 :            : 
     113                 :    4927504 :     void append(const CoordinateData2D& rValue)
     114                 :            :     {
     115                 :    4927504 :         maVector.push_back(rValue);
     116                 :    4927504 :     }
     117                 :            : 
     118                 :    3012595 :     void insert(sal_uInt32 nIndex, const CoordinateData2D& rValue, sal_uInt32 nCount)
     119                 :            :     {
     120         [ +  - ]:    3012595 :         if(nCount)
     121                 :            :         {
     122                 :            :             // add nCount copies of rValue
     123                 :    3012595 :             CoordinateData2DVector::iterator aIndex(maVector.begin());
     124                 :    3012595 :             aIndex += nIndex;
     125         [ +  - ]:    3012595 :             maVector.insert(aIndex, nCount, rValue);
     126                 :            :         }
     127                 :    3012595 :     }
     128                 :            : 
     129                 :         68 :     void insert(sal_uInt32 nIndex, const CoordinateDataArray2D& rSource)
     130                 :            :     {
     131                 :         68 :         const sal_uInt32 nCount(rSource.maVector.size());
     132                 :            : 
     133         [ +  - ]:         68 :         if(nCount)
     134                 :            :         {
     135                 :            :             // insert data
     136                 :         68 :             CoordinateData2DVector::iterator aIndex(maVector.begin());
     137                 :         68 :             aIndex += nIndex;
     138                 :         68 :             CoordinateData2DVector::const_iterator aStart(rSource.maVector.begin());
     139                 :         68 :             CoordinateData2DVector::const_iterator aEnd(rSource.maVector.end());
     140         [ +  - ]:         68 :             maVector.insert(aIndex, aStart, aEnd);
     141                 :            :         }
     142                 :         68 :     }
     143                 :            : 
     144                 :      18932 :     void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
     145                 :            :     {
     146         [ +  - ]:      18932 :         if(nCount)
     147                 :            :         {
     148                 :            :             // remove point data
     149                 :      18932 :             CoordinateData2DVector::iterator aStart(maVector.begin());
     150                 :      18932 :             aStart += nIndex;
     151         [ +  - ]:      18932 :             const CoordinateData2DVector::iterator aEnd(aStart + nCount);
     152         [ +  - ]:      18932 :             maVector.erase(aStart, aEnd);
     153                 :            :         }
     154                 :      18932 :     }
     155                 :            : 
     156                 :       4325 :     void flip(bool bIsClosed)
     157                 :            :     {
     158         [ +  - ]:       4325 :         if(maVector.size() > 1)
     159                 :            :         {
     160                 :            :             // to keep the same point at index 0, just flip all points except the
     161                 :            :             // first one when closed
     162         [ +  - ]:       4325 :             const sal_uInt32 nHalfSize(bIsClosed ? (maVector.size() - 1) >> 1 : maVector.size() >> 1);
     163 [ +  - ][ +  - ]:       4325 :             CoordinateData2DVector::iterator aStart(bIsClosed ? maVector.begin() + 1 : maVector.begin());
         [ +  - ][ +  - ]
           [ #  #  #  # ]
     164         [ +  - ]:       4325 :             CoordinateData2DVector::iterator aEnd(maVector.end() - 1);
     165                 :            : 
     166         [ +  + ]:      10505 :             for(sal_uInt32 a(0); a < nHalfSize; a++)
     167                 :            :             {
     168                 :       6180 :                 ::std::swap(*aStart, *aEnd);
     169                 :       6180 :                 ++aStart;
     170                 :       6180 :                 --aEnd;
     171                 :            :             }
     172                 :            :         }
     173                 :       4325 :     }
     174                 :            : 
     175                 :         32 :     void removeDoublePointsAtBeginEnd()
     176                 :            :     {
     177                 :            :         // remove from end as long as there are at least two points
     178                 :            :         // and begin/end are equal
     179 [ +  - ][ +  + ]:         34 :         while((maVector.size() > 1) && (maVector[0] == maVector[maVector.size() - 1]))
                 [ +  + ]
     180                 :            :         {
     181                 :          2 :             maVector.pop_back();
     182                 :            :         }
     183                 :         32 :     }
     184                 :            : 
     185                 :         86 :     void removeDoublePointsWholeTrack()
     186                 :            :     {
     187                 :         86 :         sal_uInt32 nIndex(0);
     188                 :            : 
     189                 :            :         // test as long as there are at least two points and as long as the index
     190                 :            :         // is smaller or equal second last point
     191 [ +  - ][ +  + ]:        412 :         while((maVector.size() > 1) && (nIndex <= maVector.size() - 2))
                 [ +  + ]
     192                 :            :         {
     193         [ +  + ]:        326 :             if(maVector[nIndex] == maVector[nIndex + 1])
     194                 :            :             {
     195                 :            :                 // if next is same as index, delete next
     196 [ +  - ][ +  - ]:         86 :                 maVector.erase(maVector.begin() + (nIndex + 1));
     197                 :            :             }
     198                 :            :             else
     199                 :            :             {
     200                 :            :                 // if different, step forward
     201                 :        240 :                 nIndex++;
     202                 :            :             }
     203                 :            :         }
     204                 :         86 :     }
     205                 :            : 
     206                 :     814873 :     void transform(const basegfx::B2DHomMatrix& rMatrix)
     207                 :            :     {
     208                 :     814873 :         CoordinateData2DVector::iterator aStart(maVector.begin());
     209                 :     814873 :         CoordinateData2DVector::iterator aEnd(maVector.end());
     210                 :            : 
     211 [ +  - ][ +  + ]:    3701754 :         for(; aStart != aEnd; ++aStart)
     212                 :            :         {
     213         [ +  - ]:    2886881 :             aStart->transform(rMatrix);
     214                 :            :         }
     215                 :     814873 :     }
     216                 :            : 
     217                 :            :     const basegfx::B2DPoint* begin() const
     218                 :            :     {
     219                 :            :         if(maVector.empty())
     220                 :            :             return 0;
     221                 :            :         else
     222                 :            :             return &maVector.front();
     223                 :            :     }
     224                 :            : 
     225                 :            :     const basegfx::B2DPoint* end() const
     226                 :            :     {
     227                 :            :         if(maVector.empty())
     228                 :            :             return 0;
     229                 :            :         else
     230                 :            :             return (&maVector.back())+1;
     231                 :            :     }
     232                 :            : 
     233                 :            :     basegfx::B2DPoint* begin()
     234                 :            :     {
     235                 :            :         if(maVector.empty())
     236                 :            :             return 0;
     237                 :            :         else
     238                 :            :             return &maVector.front();
     239                 :            :     }
     240                 :            : 
     241                 :            :     basegfx::B2DPoint* end()
     242                 :            :     {
     243                 :            :         if(maVector.empty())
     244                 :            :             return 0;
     245                 :            :         else
     246                 :            :             return (&maVector.back())+1;
     247                 :            :     }
     248                 :            : };
     249                 :            : 
     250                 :            : //////////////////////////////////////////////////////////////////////////////
     251                 :            : 
     252                 :     482017 : class ControlVectorPair2D
     253                 :            : {
     254                 :            :     basegfx::B2DVector                          maPrevVector;
     255                 :            :     basegfx::B2DVector                          maNextVector;
     256                 :            : 
     257                 :            : public:
     258                 :      50971 :     ControlVectorPair2D() {}
     259                 :            : 
     260                 :     538883 :     const basegfx::B2DVector& getPrevVector() const
     261                 :            :     {
     262                 :     538883 :         return maPrevVector;
     263                 :            :     }
     264                 :            : 
     265                 :     166278 :     void setPrevVector(const basegfx::B2DVector& rValue)
     266                 :            :     {
     267         [ +  + ]:     166278 :         if(rValue != maPrevVector)
     268                 :     152339 :             maPrevVector = rValue;
     269                 :     166278 :     }
     270                 :            : 
     271                 :     524799 :     const basegfx::B2DVector& getNextVector() const
     272                 :            :     {
     273                 :     524799 :         return maNextVector;
     274                 :            :     }
     275                 :            : 
     276                 :     164248 :     void setNextVector(const basegfx::B2DVector& rValue)
     277                 :            :     {
     278         [ +  + ]:     164248 :         if(rValue != maNextVector)
     279                 :     150274 :             maNextVector = rValue;
     280                 :     164248 :     }
     281                 :            : 
     282                 :       5221 :     bool operator==(const ControlVectorPair2D& rData) const
     283                 :            :     {
     284 [ +  - ][ +  - ]:       5221 :         return (maPrevVector == rData.getPrevVector() && maNextVector == rData.getNextVector());
     285                 :            :     }
     286                 :            : 
     287                 :          0 :     void flip()
     288                 :            :     {
     289                 :          0 :         ::std::swap(maPrevVector, maNextVector);
     290                 :          0 :     }
     291                 :            : };
     292                 :            : 
     293                 :            : //////////////////////////////////////////////////////////////////////////////
     294                 :            : 
     295                 :      24249 : class ControlVectorArray2D
     296                 :            : {
     297                 :            :     typedef ::std::vector< ControlVectorPair2D > ControlVectorPair2DVector;
     298                 :            : 
     299                 :            :     ControlVectorPair2DVector                           maVector;
     300                 :            :     sal_uInt32                                          mnUsedVectors;
     301                 :            : 
     302                 :            : public:
     303                 :       4489 :     explicit ControlVectorArray2D(sal_uInt32 nCount)
     304                 :            :     :   maVector(nCount),
     305                 :       4489 :         mnUsedVectors(0)
     306                 :       4489 :     {}
     307                 :            : 
     308                 :          0 :     ControlVectorArray2D(const ControlVectorArray2D& rOriginal, sal_uInt32 nIndex, sal_uInt32 nCount)
     309                 :            :     :   maVector(),
     310                 :          0 :         mnUsedVectors(0)
     311                 :            :     {
     312                 :          0 :         ControlVectorPair2DVector::const_iterator aStart(rOriginal.maVector.begin());
     313                 :          0 :         aStart += nIndex;
     314                 :          0 :         ControlVectorPair2DVector::const_iterator aEnd(aStart);
     315                 :          0 :         aEnd += nCount;
     316         [ #  # ]:          0 :         maVector.reserve(nCount);
     317                 :            : 
     318 [ #  # ][ #  # ]:          0 :         for(; aStart != aEnd; ++aStart)
     319                 :            :         {
     320 [ #  # ][ #  # ]:          0 :             if(!aStart->getPrevVector().equalZero())
     321                 :          0 :                 mnUsedVectors++;
     322                 :            : 
     323 [ #  # ][ #  # ]:          0 :             if(!aStart->getNextVector().equalZero())
     324                 :          0 :                 mnUsedVectors++;
     325                 :            : 
     326         [ #  # ]:          0 :             maVector.push_back(*aStart);
     327                 :            :         }
     328                 :          0 :     }
     329                 :            : 
     330                 :            :     sal_uInt32 count() const
     331                 :            :     {
     332                 :            :         return maVector.size();
     333                 :            :     }
     334                 :            : 
     335                 :       1642 :     bool operator==(const ControlVectorArray2D& rCandidate) const
     336                 :            :     {
     337                 :       1642 :         return (maVector == rCandidate.maVector);
     338                 :            :     }
     339                 :            : 
     340                 :     522680 :     bool isUsed() const
     341                 :            :     {
     342                 :     522680 :         return (0 != mnUsedVectors);
     343                 :            :     }
     344                 :            : 
     345                 :     319962 :     const basegfx::B2DVector& getPrevVector(sal_uInt32 nIndex) const
     346                 :            :     {
     347                 :     319962 :         return maVector[nIndex].getPrevVector();
     348                 :            :     }
     349                 :            : 
     350                 :     166354 :     void setPrevVector(sal_uInt32 nIndex, const basegfx::B2DVector& rValue)
     351                 :            :     {
     352 [ +  + ][ +  + ]:     166354 :         bool bWasUsed(mnUsedVectors && !maVector[nIndex].getPrevVector().equalZero());
     353                 :     166354 :         bool bIsUsed(!rValue.equalZero());
     354                 :            : 
     355         [ +  + ]:     166354 :         if(bWasUsed)
     356                 :            :         {
     357         [ +  - ]:     128120 :             if(bIsUsed)
     358                 :            :             {
     359                 :     128120 :                 maVector[nIndex].setPrevVector(rValue);
     360                 :            :             }
     361                 :            :             else
     362                 :            :             {
     363                 :          0 :                 maVector[nIndex].setPrevVector(basegfx::B2DVector::getEmptyVector());
     364                 :          0 :                 mnUsedVectors--;
     365                 :            :             }
     366                 :            :         }
     367                 :            :         else
     368                 :            :         {
     369         [ +  + ]:      38234 :             if(bIsUsed)
     370                 :            :             {
     371                 :      38158 :                 maVector[nIndex].setPrevVector(rValue);
     372                 :      38158 :                 mnUsedVectors++;
     373                 :            :             }
     374                 :            :         }
     375                 :     166354 :     }
     376                 :            : 
     377                 :     312351 :     const basegfx::B2DVector& getNextVector(sal_uInt32 nIndex) const
     378                 :            :     {
     379                 :     312351 :         return maVector[nIndex].getNextVector();
     380                 :            :     }
     381                 :            : 
     382                 :     164278 :     void setNextVector(sal_uInt32 nIndex, const basegfx::B2DVector& rValue)
     383                 :            :     {
     384 [ +  + ][ +  + ]:     164278 :         bool bWasUsed(mnUsedVectors && !maVector[nIndex].getNextVector().equalZero());
     385                 :     164278 :         bool bIsUsed(!rValue.equalZero());
     386                 :            : 
     387         [ +  + ]:     164278 :         if(bWasUsed)
     388                 :            :         {
     389         [ +  - ]:     128172 :             if(bIsUsed)
     390                 :            :             {
     391                 :     128172 :                 maVector[nIndex].setNextVector(rValue);
     392                 :            :             }
     393                 :            :             else
     394                 :            :             {
     395                 :          0 :                 maVector[nIndex].setNextVector(basegfx::B2DVector::getEmptyVector());
     396                 :          0 :                 mnUsedVectors--;
     397                 :            :             }
     398                 :            :         }
     399                 :            :         else
     400                 :            :         {
     401         [ +  + ]:      36106 :             if(bIsUsed)
     402                 :            :             {
     403                 :      36076 :                 maVector[nIndex].setNextVector(rValue);
     404                 :      36076 :                 mnUsedVectors++;
     405                 :            :             }
     406                 :            :         }
     407                 :     164278 :     }
     408                 :            : 
     409                 :       7797 :     void append(const ControlVectorPair2D& rValue)
     410                 :            :     {
     411                 :       7797 :         maVector.push_back(rValue);
     412                 :            : 
     413         [ -  + ]:       7797 :         if(!rValue.getPrevVector().equalZero())
     414                 :          0 :             mnUsedVectors += 1;
     415                 :            : 
     416         [ -  + ]:       7797 :         if(!rValue.getNextVector().equalZero())
     417                 :          0 :             mnUsedVectors += 1;
     418                 :       7797 :     }
     419                 :            : 
     420                 :      36021 :     void insert(sal_uInt32 nIndex, const ControlVectorPair2D& rValue, sal_uInt32 nCount)
     421                 :            :     {
     422         [ +  - ]:      36021 :         if(nCount)
     423                 :            :         {
     424                 :            :             // add nCount copies of rValue
     425                 :      36021 :             ControlVectorPair2DVector::iterator aIndex(maVector.begin());
     426                 :      36021 :             aIndex += nIndex;
     427         [ +  - ]:      36021 :             maVector.insert(aIndex, nCount, rValue);
     428                 :            : 
     429 [ +  - ][ -  + ]:      36021 :             if(!rValue.getPrevVector().equalZero())
     430                 :          0 :                 mnUsedVectors += nCount;
     431                 :            : 
     432 [ +  - ][ -  + ]:      36021 :             if(!rValue.getNextVector().equalZero())
     433                 :      36021 :                 mnUsedVectors += nCount;
     434                 :            :         }
     435                 :      36021 :     }
     436                 :            : 
     437                 :          6 :     void insert(sal_uInt32 nIndex, const ControlVectorArray2D& rSource)
     438                 :            :     {
     439                 :          6 :         const sal_uInt32 nCount(rSource.maVector.size());
     440                 :            : 
     441         [ +  - ]:          6 :         if(nCount)
     442                 :            :         {
     443                 :            :             // insert data
     444                 :          6 :             ControlVectorPair2DVector::iterator aIndex(maVector.begin());
     445                 :          6 :             aIndex += nIndex;
     446                 :          6 :             ControlVectorPair2DVector::const_iterator aStart(rSource.maVector.begin());
     447                 :          6 :             ControlVectorPair2DVector::const_iterator aEnd(rSource.maVector.end());
     448         [ +  - ]:          6 :             maVector.insert(aIndex, aStart, aEnd);
     449                 :            : 
     450 [ +  - ][ +  + ]:         78 :             for(; aStart != aEnd; ++aStart)
     451                 :            :             {
     452 [ +  - ][ +  - ]:         72 :                 if(!aStart->getPrevVector().equalZero())
     453                 :         72 :                     mnUsedVectors++;
     454                 :            : 
     455 [ +  - ][ +  - ]:         72 :                 if(!aStart->getNextVector().equalZero())
     456                 :         72 :                     mnUsedVectors++;
     457                 :            :             }
     458                 :            :         }
     459                 :          6 :     }
     460                 :            : 
     461                 :       3409 :     void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
     462                 :            :     {
     463         [ +  - ]:       3409 :         if(nCount)
     464                 :            :         {
     465         [ +  - ]:       3409 :             const ControlVectorPair2DVector::iterator aDeleteStart(maVector.begin() + nIndex);
     466         [ +  - ]:       3409 :             const ControlVectorPair2DVector::iterator aDeleteEnd(aDeleteStart + nCount);
     467         [ +  - ]:       3409 :             ControlVectorPair2DVector::const_iterator aStart(aDeleteStart);
     468                 :            : 
     469 [ +  - ][ +  - ]:       6908 :             for(; mnUsedVectors && aStart != aDeleteEnd; ++aStart)
         [ +  + ][ +  + ]
     470                 :            :             {
     471 [ +  - ][ +  + ]:       3499 :                 if(!aStart->getPrevVector().equalZero())
     472                 :       2117 :                     mnUsedVectors--;
     473                 :            : 
     474 [ +  - ][ +  - ]:       3499 :                 if(mnUsedVectors && !aStart->getNextVector().equalZero())
         [ -  + ][ -  + ]
     475                 :          0 :                     mnUsedVectors--;
     476                 :            :             }
     477                 :            : 
     478                 :            :             // remove point data
     479         [ +  - ]:       3409 :             maVector.erase(aDeleteStart, aDeleteEnd);
     480                 :            :         }
     481                 :       3409 :     }
     482                 :            : 
     483                 :          0 :     void flip(bool bIsClosed)
     484                 :            :     {
     485         [ #  # ]:          0 :         if(maVector.size() > 1)
     486                 :            :         {
     487                 :            :             // to keep the same point at index 0, just flip all points except the
     488                 :            :             // first one when closed
     489         [ #  # ]:          0 :             const sal_uInt32 nHalfSize(bIsClosed ? (maVector.size() - 1) >> 1 : maVector.size() >> 1);
     490 [ #  # ][ #  # ]:          0 :             ControlVectorPair2DVector::iterator aStart(bIsClosed ? maVector.begin() + 1 : maVector.begin());
         [ #  # ][ #  # ]
           [ #  #  #  # ]
     491         [ #  # ]:          0 :             ControlVectorPair2DVector::iterator aEnd(maVector.end() - 1);
     492                 :            : 
     493         [ #  # ]:          0 :             for(sal_uInt32 a(0); a < nHalfSize; a++)
     494                 :            :             {
     495                 :            :                 // swap Prev and Next
     496         [ #  # ]:          0 :                 aStart->flip();
     497         [ #  # ]:          0 :                 aEnd->flip();
     498                 :            : 
     499                 :            :                 // swap entries
     500         [ #  # ]:          0 :                 ::std::swap(*aStart, *aEnd);
     501                 :            : 
     502                 :          0 :                 ++aStart;
     503                 :          0 :                 --aEnd;
     504                 :            :             }
     505                 :            : 
     506 [ #  # ][ #  # ]:          0 :             if(aStart == aEnd)
     507                 :            :             {
     508                 :            :                 // swap Prev and Next at middle element (if exists)
     509         [ #  # ]:          0 :                 aStart->flip();
     510                 :            :             }
     511                 :            : 
     512         [ #  # ]:          0 :             if(bIsClosed)
     513                 :            :             {
     514                 :            :                 // swap Prev and Next at start element
     515         [ #  # ]:          0 :                 maVector.begin()->flip();
     516                 :            :             }
     517                 :            :         }
     518                 :          0 :     }
     519                 :            : };
     520                 :            : 
     521                 :            : //////////////////////////////////////////////////////////////////////////////
     522                 :            : 
     523         [ +  - ]:    3891240 : class ImplBufferedData
     524                 :            : {
     525                 :            : private:
     526                 :            :     // Possibility to hold the last subdivision
     527                 :            :     boost::scoped_ptr< basegfx::B2DPolygon >        mpDefaultSubdivision;
     528                 :            : 
     529                 :            :     // Possibility to hold the last B2DRange calculation
     530                 :            :     boost::scoped_ptr< basegfx::B2DRange >          mpB2DRange;
     531                 :            : 
     532                 :            : public:
     533                 :    3891272 :     ImplBufferedData()
     534                 :            :     :   mpDefaultSubdivision(),
     535                 :    3891272 :         mpB2DRange()
     536                 :    3891272 :     {}
     537                 :            : 
     538                 :          0 :     const basegfx::B2DPolygon& getDefaultAdaptiveSubdivision(const basegfx::B2DPolygon& rSource) const
     539                 :            :     {
     540         [ #  # ]:          0 :         if(!mpDefaultSubdivision)
     541                 :            :         {
     542         [ #  # ]:          0 :             const_cast< ImplBufferedData* >(this)->mpDefaultSubdivision.reset(new basegfx::B2DPolygon(basegfx::tools::adaptiveSubdivideByCount(rSource, 9)));
     543                 :            :         }
     544                 :            : 
     545                 :          0 :         return *mpDefaultSubdivision;
     546                 :            :     }
     547                 :            : 
     548                 :    4740645 :     const basegfx::B2DRange& getB2DRange(const basegfx::B2DPolygon& rSource) const
     549                 :            :     {
     550         [ +  + ]:    4740645 :         if(!mpB2DRange)
     551                 :            :         {
     552         [ +  - ]:    3891272 :             basegfx::B2DRange aNewRange;
     553         [ +  - ]:    3891272 :             const sal_uInt32 nPointCount(rSource.count());
     554                 :            : 
     555         [ +  - ]:    3891272 :             if(nPointCount)
     556                 :            :             {
     557         [ +  + ]:   21348801 :                 for(sal_uInt32 a(0); a < nPointCount; a++)
     558                 :            :                 {
     559 [ +  - ][ +  - ]:   17457529 :                     aNewRange.expand(rSource.getB2DPoint(a));
     560                 :            :                 }
     561                 :            : 
     562 [ +  - ][ +  + ]:    3891272 :                 if(rSource.areControlPointsUsed())
     563                 :            :                 {
     564 [ +  - ][ +  + ]:        795 :                     const sal_uInt32 nEdgeCount(rSource.isClosed() ? nPointCount : nPointCount - 1);
     565                 :            : 
     566         [ +  - ]:        795 :                     if(nEdgeCount)
     567                 :            :                     {
     568         [ +  - ]:        795 :                         basegfx::B2DCubicBezier aEdge;
     569         [ +  - ]:        795 :                         aEdge.setStartPoint(rSource.getB2DPoint(0));
     570                 :            : 
     571         [ +  + ]:       8896 :                         for(sal_uInt32 b(0); b < nEdgeCount; b++)
     572                 :            :                         {
     573                 :       8101 :                             const sal_uInt32 nNextIndex((b + 1) % nPointCount);
     574         [ +  - ]:       8101 :                             aEdge.setControlPointA(rSource.getNextControlPoint(b));
     575         [ +  - ]:       8101 :                             aEdge.setControlPointB(rSource.getPrevControlPoint(nNextIndex));
     576         [ +  - ]:       8101 :                             aEdge.setEndPoint(rSource.getB2DPoint(nNextIndex));
     577                 :            : 
     578 [ +  + ][ +  - ]:       8101 :                             if(aEdge.isBezier())
     579                 :            :                             {
     580         [ +  - ]:       5681 :                                 const basegfx::B2DRange aBezierRangeWithControlPoints(aEdge.getRange());
     581                 :            : 
     582 [ +  - ][ +  + ]:       5681 :                                 if(!aNewRange.isInside(aBezierRangeWithControlPoints))
     583                 :            :                                 {
     584                 :            :                                     // the range with control points of the current edge is not completely
     585                 :            :                                     // inside the current range without control points. Expand current range by
     586                 :            :                                     // subdividing the bezier segment.
     587                 :            :                                     // Ideal here is a subdivision at the extreme values, so use
     588                 :            :                                     // getAllExtremumPositions to get all extremas in one run
     589         [ +  - ]:        776 :                                     ::std::vector< double > aExtremas;
     590                 :            : 
     591         [ +  - ]:        776 :                                     aExtremas.reserve(4);
     592         [ +  - ]:        776 :                                     aEdge.getAllExtremumPositions(aExtremas);
     593                 :            : 
     594                 :        776 :                                     const sal_uInt32 nExtremaCount(aExtremas.size());
     595                 :            : 
     596         [ +  + ]:       1363 :                                     for(sal_uInt32 c(0); c < nExtremaCount; c++)
     597                 :            :                                     {
     598 [ +  - ][ +  - ]:        587 :                                         aNewRange.expand(aEdge.interpolatePoint(aExtremas[c]));
                 [ +  - ]
     599                 :       5681 :                                     }
     600                 :            :                                 }
     601                 :            :                             }
     602                 :            : 
     603                 :            :                             // prepare next edge
     604                 :       8101 :                             aEdge.setStartPoint(aEdge.getEndPoint());
     605         [ +  - ]:        795 :                         }
     606                 :            :                     }
     607                 :            :                 }
     608                 :            :             }
     609                 :            : 
     610 [ +  - ][ +  - ]:    3891272 :             const_cast< ImplBufferedData* >(this)->mpB2DRange.reset(new basegfx::B2DRange(aNewRange));
     611                 :            :         }
     612                 :            : 
     613                 :    4740645 :         return *mpB2DRange;
     614                 :            :     }
     615                 :            : };
     616                 :            : 
     617                 :            : //////////////////////////////////////////////////////////////////////////////
     618                 :            : 
     619 [ +  - ][ +  - ]:    5030679 : class ImplB2DPolygon
     620                 :            : {
     621                 :            : private:
     622                 :            :     // The point vector. This vector exists always and defines the
     623                 :            :     // count of members.
     624                 :            :     CoordinateDataArray2D                           maPoints;
     625                 :            : 
     626                 :            :     // The control point vectors. This vectors are created on demand
     627                 :            :     // and may be zero.
     628                 :            :     boost::scoped_ptr< ControlVectorArray2D >       mpControlVector;
     629                 :            : 
     630                 :            :     // buffered data for e.g. default subdivision and range
     631                 :            :     boost::scoped_ptr< ImplBufferedData >           mpBufferedData;
     632                 :            : 
     633                 :            :     // flag which decides if this polygon is opened or closed
     634                 :            :     bool                                            mbIsClosed;
     635                 :            : 
     636                 :            : public:
     637                 :         18 :     const basegfx::B2DPolygon& getDefaultAdaptiveSubdivision(const basegfx::B2DPolygon& rSource) const
     638                 :            :     {
     639 [ -  + ][ #  # ]:         18 :         if(!mpControlVector || !mpControlVector->isUsed())
                 [ +  - ]
     640                 :            :         {
     641                 :         18 :             return rSource;
     642                 :            :         }
     643                 :            : 
     644         [ #  # ]:          0 :         if(!mpBufferedData)
     645                 :            :         {
     646         [ #  # ]:          0 :             const_cast< ImplB2DPolygon* >(this)->mpBufferedData.reset(new ImplBufferedData);
     647                 :            :         }
     648                 :            : 
     649                 :         18 :         return mpBufferedData->getDefaultAdaptiveSubdivision(rSource);
     650                 :            :     }
     651                 :            : 
     652                 :    4740645 :     const basegfx::B2DRange& getB2DRange(const basegfx::B2DPolygon& rSource) const
     653                 :            :     {
     654         [ +  + ]:    4740645 :         if(!mpBufferedData)
     655                 :            :         {
     656         [ +  - ]:    3891272 :             const_cast< ImplB2DPolygon* >(this)->mpBufferedData.reset(new ImplBufferedData);
     657                 :            :         }
     658                 :            : 
     659                 :    4740645 :         return mpBufferedData->getB2DRange(rSource);
     660                 :            :     }
     661                 :            : 
     662                 :        206 :     ImplB2DPolygon()
     663                 :            :     :   maPoints(0),
     664                 :            :         mpControlVector(),
     665                 :            :         mpBufferedData(),
     666                 :        206 :         mbIsClosed(false)
     667                 :        206 :     {}
     668                 :            : 
     669                 :    5030695 :     ImplB2DPolygon(const ImplB2DPolygon& rToBeCopied)
     670                 :            :     :   maPoints(rToBeCopied.maPoints),
     671                 :            :         mpControlVector(),
     672                 :            :         mpBufferedData(),
     673                 :    5030695 :         mbIsClosed(rToBeCopied.mbIsClosed)
     674                 :            :     {
     675                 :            :         // complete initialization using copy
     676 [ +  - ][ +  + ]:    5030695 :         if(rToBeCopied.mpControlVector && rToBeCopied.mpControlVector->isUsed())
                 [ +  + ]
     677                 :            :         {
     678 [ +  - ][ +  - ]:       9880 :             mpControlVector.reset( new ControlVectorArray2D(*rToBeCopied.mpControlVector) );
                 [ +  - ]
     679                 :            :         }
     680                 :    5030695 :     }
     681                 :            : 
     682                 :          0 :     ImplB2DPolygon(const ImplB2DPolygon& rToBeCopied, sal_uInt32 nIndex, sal_uInt32 nCount)
     683                 :            :     :   maPoints(rToBeCopied.maPoints, nIndex, nCount),
     684                 :            :         mpControlVector(),
     685                 :            :         mpBufferedData(),
     686                 :          0 :         mbIsClosed(rToBeCopied.mbIsClosed)
     687                 :            :     {
     688                 :            :         // complete initialization using partly copy
     689 [ #  # ][ #  # ]:          0 :         if(rToBeCopied.mpControlVector && rToBeCopied.mpControlVector->isUsed())
                 [ #  # ]
     690                 :            :         {
     691 [ #  # ][ #  # ]:          0 :             mpControlVector.reset( new ControlVectorArray2D(*rToBeCopied.mpControlVector, nIndex, nCount) );
                 [ #  # ]
     692                 :            : 
     693         [ #  # ]:          0 :             if(!mpControlVector->isUsed())
     694         [ #  # ]:          0 :                 mpControlVector.reset();
     695                 :            :         }
     696                 :          0 :     }
     697                 :            : 
     698                 :            :     ImplB2DPolygon& operator=( const ImplB2DPolygon& rToBeCopied )
     699                 :            :     {
     700                 :            :         maPoints = rToBeCopied.maPoints;
     701                 :            :         mpControlVector.reset();
     702                 :            :         mpBufferedData.reset();
     703                 :            :         mbIsClosed = rToBeCopied.mbIsClosed;
     704                 :            : 
     705                 :            :         // complete initialization using copy
     706                 :            :         if(rToBeCopied.mpControlVector && rToBeCopied.mpControlVector->isUsed())
     707                 :            :             mpControlVector.reset( new ControlVectorArray2D(*rToBeCopied.mpControlVector) );
     708                 :            : 
     709                 :            :         return *this;
     710                 :            :     }
     711                 :            : 
     712                 :   12841713 :     sal_uInt32 count() const
     713                 :            :     {
     714                 :   12841713 :         return maPoints.count();
     715                 :            :     }
     716                 :            : 
     717                 :    4992042 :     bool isClosed() const
     718                 :            :     {
     719                 :    4992042 :         return mbIsClosed;
     720                 :            :     }
     721                 :            : 
     722                 :    3839587 :     void setClosed(bool bNew)
     723                 :            :     {
     724         [ +  - ]:    3839587 :         if(bNew != mbIsClosed)
     725                 :            :         {
     726                 :    3839587 :             mpBufferedData.reset();
     727                 :    3839587 :             mbIsClosed = bNew;
     728                 :            :         }
     729                 :    3839587 :     }
     730                 :            : 
     731                 :      61476 :     bool operator==(const ImplB2DPolygon& rCandidate) const
     732                 :            :     {
     733         [ +  + ]:      61476 :         if(mbIsClosed == rCandidate.mbIsClosed)
     734                 :            :         {
     735         [ +  + ]:      60738 :             if(maPoints == rCandidate.maPoints)
     736                 :            :             {
     737                 :      46052 :                 bool bControlVectorsAreEqual(true);
     738                 :            : 
     739         [ +  + ]:      46052 :                 if(mpControlVector)
     740                 :            :                 {
     741         [ +  - ]:       1642 :                     if(rCandidate.mpControlVector)
     742                 :            :                     {
     743                 :       1642 :                         bControlVectorsAreEqual = ((*mpControlVector) == (*rCandidate.mpControlVector));
     744                 :            :                     }
     745                 :            :                     else
     746                 :            :                     {
     747                 :            :                         // candidate has no control vector, so it's assumed all unused.
     748                 :          0 :                         bControlVectorsAreEqual = !mpControlVector->isUsed();
     749                 :            :                     }
     750                 :            :                 }
     751                 :            :                 else
     752                 :            :                 {
     753         [ +  + ]:      44410 :                     if(rCandidate.mpControlVector)
     754                 :            :                     {
     755                 :            :                         // we have no control vector, so it's assumed all unused.
     756                 :         56 :                         bControlVectorsAreEqual = !rCandidate.mpControlVector->isUsed();
     757                 :            :                     }
     758                 :            :                 }
     759                 :            : 
     760         [ +  + ]:      46052 :                 if(bControlVectorsAreEqual)
     761                 :            :                 {
     762                 :      45996 :                     return true;
     763                 :            :                 }
     764                 :            :             }
     765                 :            :         }
     766                 :            : 
     767                 :      61476 :         return false;
     768                 :            :     }
     769                 :            : 
     770                 :   62523287 :     const basegfx::B2DPoint& getPoint(sal_uInt32 nIndex) const
     771                 :            :     {
     772                 :   62523287 :         return maPoints.getCoordinate(nIndex);
     773                 :            :     }
     774                 :            : 
     775                 :   10864813 :     void setPoint(sal_uInt32 nIndex, const basegfx::B2DPoint& rValue)
     776                 :            :     {
     777                 :   10864813 :         mpBufferedData.reset();
     778                 :   10864813 :         maPoints.setCoordinate(nIndex, rValue);
     779                 :   10864813 :     }
     780                 :            : 
     781                 :        245 :     void reserve(sal_uInt32 nCount)
     782                 :            :     {
     783                 :        245 :         maPoints.reserve(nCount);
     784                 :        245 :     }
     785                 :            : 
     786                 :    4927504 :     void append(const basegfx::B2DPoint& rPoint)
     787                 :            :     {
     788         [ +  - ]:    4927504 :         mpBufferedData.reset(); // TODO: is this needed?
     789                 :    4927504 :         const CoordinateData2D aCoordinate(rPoint);
     790         [ +  - ]:    4927504 :         maPoints.append(aCoordinate);
     791                 :            : 
     792         [ +  + ]:    4927504 :         if(mpControlVector)
     793                 :            :         {
     794                 :       7797 :             const ControlVectorPair2D aVectorPair;
     795         [ +  - ]:       7797 :             mpControlVector->append(aVectorPair);
     796                 :    4927504 :         }
     797                 :    4927504 :     }
     798                 :            : 
     799                 :    3012595 :     void insert(sal_uInt32 nIndex, const basegfx::B2DPoint& rPoint, sal_uInt32 nCount)
     800                 :            :     {
     801         [ +  - ]:    3012595 :         if(nCount)
     802                 :            :         {
     803         [ +  - ]:    3012595 :             mpBufferedData.reset();
     804                 :    3012595 :             CoordinateData2D aCoordinate(rPoint);
     805         [ +  - ]:    3012595 :             maPoints.insert(nIndex, aCoordinate, nCount);
     806                 :            : 
     807         [ +  + ]:    3012595 :             if(mpControlVector)
     808                 :            :             {
     809                 :      36013 :                 ControlVectorPair2D aVectorPair;
     810         [ +  - ]:      36013 :                 mpControlVector->insert(nIndex, aVectorPair, nCount);
     811                 :    3012595 :             }
     812                 :            :         }
     813                 :    3012595 :     }
     814                 :            : 
     815                 :     163064 :     const basegfx::B2DVector& getPrevControlVector(sal_uInt32 nIndex) const
     816                 :            :     {
     817         [ +  + ]:     163064 :         if(mpControlVector)
     818                 :            :         {
     819                 :     163037 :             return mpControlVector->getPrevVector(nIndex);
     820                 :            :         }
     821                 :            :         else
     822                 :            :         {
     823                 :     163064 :             return basegfx::B2DVector::getEmptyVector();
     824                 :            :         }
     825                 :            :     }
     826                 :            : 
     827                 :      38295 :     void setPrevControlVector(sal_uInt32 nIndex, const basegfx::B2DVector& rValue)
     828                 :            :     {
     829         [ +  + ]:      38295 :         if(!mpControlVector)
     830                 :            :         {
     831         [ +  + ]:         48 :             if(!rValue.equalZero())
     832                 :            :             {
     833                 :         43 :                 mpBufferedData.reset();
     834         [ +  - ]:         43 :                 mpControlVector.reset( new ControlVectorArray2D(maPoints.count()) );
     835                 :         43 :                 mpControlVector->setPrevVector(nIndex, rValue);
     836                 :            :             }
     837                 :            :         }
     838                 :            :         else
     839                 :            :         {
     840                 :      38247 :             mpBufferedData.reset();
     841                 :      38247 :             mpControlVector->setPrevVector(nIndex, rValue);
     842                 :            : 
     843         [ -  + ]:      38247 :             if(!mpControlVector->isUsed())
     844                 :          0 :                 mpControlVector.reset();
     845                 :            :         }
     846                 :      38295 :     }
     847                 :            : 
     848                 :     155455 :     const basegfx::B2DVector& getNextControlVector(sal_uInt32 nIndex) const
     849                 :            :     {
     850         [ +  + ]:     155455 :         if(mpControlVector)
     851                 :            :         {
     852                 :     155434 :             return mpControlVector->getNextVector(nIndex);
     853                 :            :         }
     854                 :            :         else
     855                 :            :         {
     856                 :     155455 :             return basegfx::B2DVector::getEmptyVector();
     857                 :            :         }
     858                 :            :     }
     859                 :            : 
     860                 :      36182 :     void setNextControlVector(sal_uInt32 nIndex, const basegfx::B2DVector& rValue)
     861                 :            :     {
     862         [ +  + ]:      36182 :         if(!mpControlVector)
     863                 :            :         {
     864         [ +  + ]:       4456 :             if(!rValue.equalZero())
     865                 :            :             {
     866                 :       4440 :                 mpBufferedData.reset();
     867         [ +  - ]:       4440 :                 mpControlVector.reset( new ControlVectorArray2D(maPoints.count()) );
     868                 :       4440 :                 mpControlVector->setNextVector(nIndex, rValue);
     869                 :            :             }
     870                 :            :         }
     871                 :            :         else
     872                 :            :         {
     873                 :      31726 :             mpBufferedData.reset();
     874                 :      31726 :             mpControlVector->setNextVector(nIndex, rValue);
     875                 :            : 
     876         [ -  + ]:      31726 :             if(!mpControlVector->isUsed())
     877                 :          0 :                 mpControlVector.reset();
     878                 :            :         }
     879                 :      36182 :     }
     880                 :            : 
     881                 :    8900646 :     bool areControlPointsUsed() const
     882                 :            :     {
     883 [ +  + ][ +  - ]:    8900646 :         return (mpControlVector && mpControlVector->isUsed());
     884                 :            :     }
     885                 :            : 
     886                 :            :     void resetControlVectors(sal_uInt32 nIndex)
     887                 :            :     {
     888                 :            :         setPrevControlVector(nIndex, basegfx::B2DVector::getEmptyVector());
     889                 :            :         setNextControlVector(nIndex, basegfx::B2DVector::getEmptyVector());
     890                 :            :     }
     891                 :            : 
     892                 :          5 :     void resetControlVectors()
     893                 :            :     {
     894                 :          5 :         mpBufferedData.reset();
     895                 :          5 :         mpControlVector.reset();
     896                 :          5 :     }
     897                 :            : 
     898                 :          5 :     void setControlVectors(sal_uInt32 nIndex, const basegfx::B2DVector& rPrev, const basegfx::B2DVector& rNext)
     899                 :            :     {
     900                 :          5 :         setPrevControlVector(nIndex, rPrev);
     901                 :          5 :         setNextControlVector(nIndex, rNext);
     902                 :          5 :     }
     903                 :            : 
     904                 :      36025 :     void appendBezierSegment(const basegfx::B2DVector& rNext, const basegfx::B2DVector& rPrev, const basegfx::B2DPoint& rPoint)
     905                 :            :     {
     906                 :      36025 :         mpBufferedData.reset();
     907                 :      36025 :         const sal_uInt32 nCount(maPoints.count());
     908                 :            : 
     909         [ +  + ]:      36025 :         if(nCount)
     910                 :            :         {
     911                 :      36020 :             setNextControlVector(nCount - 1, rNext);
     912                 :            :         }
     913                 :            : 
     914                 :      36025 :         insert(nCount, rPoint, 1);
     915                 :      36025 :         setPrevControlVector(nCount, rPrev);
     916                 :      36025 :     }
     917                 :            : 
     918                 :         68 :     void insert(sal_uInt32 nIndex, const ImplB2DPolygon& rSource)
     919                 :            :     {
     920                 :         68 :         const sal_uInt32 nCount(rSource.maPoints.count());
     921                 :            : 
     922         [ +  - ]:         68 :         if(nCount)
     923                 :            :         {
     924                 :         68 :             mpBufferedData.reset();
     925                 :            : 
     926 [ +  - ][ +  - ]:         68 :             if(rSource.mpControlVector && rSource.mpControlVector->isUsed() && !mpControlVector)
         [ +  + ][ +  + ]
     927                 :            :             {
     928         [ +  - ]:          6 :                 mpControlVector.reset( new ControlVectorArray2D(maPoints.count()) );
     929                 :            :             }
     930                 :            : 
     931                 :         68 :             maPoints.insert(nIndex, rSource.maPoints);
     932                 :            : 
     933         [ +  + ]:         68 :             if(rSource.mpControlVector)
     934                 :            :             {
     935                 :          6 :                 mpControlVector->insert(nIndex, *rSource.mpControlVector);
     936                 :            : 
     937         [ -  + ]:          6 :                 if(!mpControlVector->isUsed())
     938                 :          0 :                     mpControlVector.reset();
     939                 :            :             }
     940         [ +  + ]:         62 :             else if(mpControlVector)
     941                 :            :             {
     942                 :          8 :                 ControlVectorPair2D aVectorPair;
     943         [ +  - ]:          8 :                 mpControlVector->insert(nIndex, aVectorPair, nCount);
     944                 :            :             }
     945                 :            :         }
     946                 :         68 :     }
     947                 :            : 
     948                 :      18932 :     void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
     949                 :            :     {
     950         [ +  - ]:      18932 :         if(nCount)
     951                 :            :         {
     952                 :      18932 :             mpBufferedData.reset();
     953                 :      18932 :             maPoints.remove(nIndex, nCount);
     954                 :            : 
     955         [ +  + ]:      18932 :             if(mpControlVector)
     956                 :            :             {
     957                 :       3409 :                 mpControlVector->remove(nIndex, nCount);
     958                 :            : 
     959         [ -  + ]:       3409 :                 if(!mpControlVector->isUsed())
     960                 :          0 :                     mpControlVector.reset();
     961                 :            :             }
     962                 :            :         }
     963                 :      18932 :     }
     964                 :            : 
     965                 :       4325 :     void flip()
     966                 :            :     {
     967         [ +  - ]:       4325 :         if(maPoints.count() > 1)
     968                 :            :         {
     969                 :       4325 :             mpBufferedData.reset();
     970                 :            : 
     971                 :            :             // flip points
     972                 :       4325 :             maPoints.flip(mbIsClosed);
     973                 :            : 
     974         [ -  + ]:       4325 :             if(mpControlVector)
     975                 :            :             {
     976                 :            :                 // flip control vector
     977                 :          0 :                 mpControlVector->flip(mbIsClosed);
     978                 :            :             }
     979                 :            :         }
     980                 :       4325 :     }
     981                 :            : 
     982                 :      16168 :     bool hasDoublePoints() const
     983                 :            :     {
     984         [ +  + ]:      16168 :         if(mbIsClosed)
     985                 :            :         {
     986                 :            :             // check for same start and end point
     987                 :       5375 :             const sal_uInt32 nIndex(maPoints.count() - 1);
     988                 :            : 
     989         [ +  + ]:       5375 :             if(maPoints.getCoordinate(0) == maPoints.getCoordinate(nIndex))
     990                 :            :             {
     991         [ -  + ]:          4 :                 if(mpControlVector)
     992                 :            :                 {
     993 [ #  # ][ #  # ]:          0 :                     if(mpControlVector->getNextVector(nIndex).equalZero() && mpControlVector->getPrevVector(0).equalZero())
                 [ #  # ]
     994                 :            :                     {
     995                 :          0 :                         return true;
     996                 :            :                     }
     997                 :            :                 }
     998                 :            :                 else
     999                 :            :                 {
    1000                 :          4 :                     return true;
    1001                 :            :                 }
    1002                 :            :             }
    1003                 :            :         }
    1004                 :            : 
    1005                 :            :         // test for range
    1006         [ +  + ]:      50655 :         for(sal_uInt32 a(0); a < maPoints.count() - 1; a++)
    1007                 :            :         {
    1008         [ +  + ]:      34599 :             if(maPoints.getCoordinate(a) == maPoints.getCoordinate(a + 1))
    1009                 :            :             {
    1010         [ +  + ]:        108 :                 if(mpControlVector)
    1011                 :            :                 {
    1012 [ +  - ][ +  - ]:          4 :                     if(mpControlVector->getNextVector(a).equalZero() && mpControlVector->getPrevVector(a + 1).equalZero())
                 [ +  - ]
    1013                 :            :                     {
    1014                 :          4 :                         return true;
    1015                 :            :                     }
    1016                 :            :                 }
    1017                 :            :                 else
    1018                 :            :                 {
    1019                 :        104 :                     return true;
    1020                 :            :                 }
    1021                 :            :             }
    1022                 :            :         }
    1023                 :            : 
    1024                 :      16168 :         return false;
    1025                 :            :     }
    1026                 :            : 
    1027                 :         90 :     void removeDoublePointsAtBeginEnd()
    1028                 :            :     {
    1029                 :            :         // Only remove DoublePoints at Begin and End when poly is closed
    1030         [ +  + ]:         90 :         if(mbIsClosed)
    1031                 :            :         {
    1032                 :         32 :             mpBufferedData.reset();
    1033                 :            : 
    1034         [ -  + ]:         32 :             if(mpControlVector)
    1035                 :            :             {
    1036                 :            :                 bool bRemove;
    1037                 :            : 
    1038         [ #  # ]:          0 :                 do
    1039                 :            :                 {
    1040                 :          0 :                     bRemove = false;
    1041                 :            : 
    1042         [ #  # ]:          0 :                     if(maPoints.count() > 1)
    1043                 :            :                     {
    1044                 :          0 :                         const sal_uInt32 nIndex(maPoints.count() - 1);
    1045                 :            : 
    1046         [ #  # ]:          0 :                         if(maPoints.getCoordinate(0) == maPoints.getCoordinate(nIndex))
    1047                 :            :                         {
    1048         [ #  # ]:          0 :                             if(mpControlVector)
    1049                 :            :                             {
    1050 [ #  # ][ #  # ]:          0 :                                 if(mpControlVector->getNextVector(nIndex).equalZero() && mpControlVector->getPrevVector(0).equalZero())
                 [ #  # ]
    1051                 :            :                                 {
    1052                 :          0 :                                     bRemove = true;
    1053                 :            :                                 }
    1054                 :            :                             }
    1055                 :            :                             else
    1056                 :            :                             {
    1057                 :          0 :                                 bRemove = true;
    1058                 :            :                             }
    1059                 :            :                         }
    1060                 :            :                     }
    1061                 :            : 
    1062         [ #  # ]:          0 :                     if(bRemove)
    1063                 :            :                     {
    1064                 :          0 :                         const sal_uInt32 nIndex(maPoints.count() - 1);
    1065                 :            : 
    1066 [ #  # ][ #  # ]:          0 :                         if(mpControlVector && !mpControlVector->getPrevVector(nIndex).equalZero())
                 [ #  # ]
    1067                 :            :                         {
    1068                 :          0 :                             mpControlVector->setPrevVector(0, mpControlVector->getPrevVector(nIndex));
    1069                 :            :                         }
    1070                 :            : 
    1071                 :          0 :                         remove(nIndex, 1);
    1072                 :            :                     }
    1073                 :            :                 }
    1074                 :            :                 while(bRemove);
    1075                 :            :             }
    1076                 :            :             else
    1077                 :            :             {
    1078                 :         32 :                 maPoints.removeDoublePointsAtBeginEnd();
    1079                 :            :             }
    1080                 :            :         }
    1081                 :         90 :     }
    1082                 :            : 
    1083                 :         90 :     void removeDoublePointsWholeTrack()
    1084                 :            :     {
    1085                 :         90 :         mpBufferedData.reset();
    1086                 :            : 
    1087         [ +  + ]:         90 :         if(mpControlVector)
    1088                 :            :         {
    1089                 :          4 :             sal_uInt32 nIndex(0);
    1090                 :            : 
    1091                 :            :             // test as long as there are at least two points and as long as the index
    1092                 :            :             // is smaller or equal second last point
    1093 [ +  - ][ +  + ]:         12 :             while((maPoints.count() > 1) && (nIndex <= maPoints.count() - 2))
                 [ +  + ]
    1094                 :            :             {
    1095                 :          8 :                 bool bRemove(maPoints.getCoordinate(nIndex) == maPoints.getCoordinate(nIndex + 1));
    1096                 :            : 
    1097         [ +  + ]:          8 :                 if(bRemove)
    1098                 :            :                 {
    1099         [ +  - ]:          4 :                     if(mpControlVector)
    1100                 :            :                     {
    1101 [ +  - ][ -  + ]:          4 :                         if(!mpControlVector->getNextVector(nIndex).equalZero() || !mpControlVector->getPrevVector(nIndex + 1).equalZero())
                 [ -  + ]
    1102                 :            :                         {
    1103                 :          0 :                             bRemove = false;
    1104                 :            :                         }
    1105                 :            :                     }
    1106                 :            :                 }
    1107                 :            : 
    1108         [ +  + ]:          8 :                 if(bRemove)
    1109                 :            :                 {
    1110 [ +  - ][ +  - ]:          4 :                     if(mpControlVector && !mpControlVector->getPrevVector(nIndex).equalZero())
                 [ +  - ]
    1111                 :            :                     {
    1112                 :          4 :                         mpControlVector->setPrevVector(nIndex + 1, mpControlVector->getPrevVector(nIndex));
    1113                 :            :                     }
    1114                 :            : 
    1115                 :            :                     // if next is same as index and the control vectors are unused, delete index
    1116                 :          4 :                     remove(nIndex, 1);
    1117                 :            :                 }
    1118                 :            :                 else
    1119                 :            :                 {
    1120                 :            :                     // if different, step forward
    1121                 :          4 :                     nIndex++;
    1122                 :            :                 }
    1123                 :            :             }
    1124                 :            :         }
    1125                 :            :         else
    1126                 :            :         {
    1127                 :         86 :             maPoints.removeDoublePointsWholeTrack();
    1128                 :            :         }
    1129                 :         90 :     }
    1130                 :            : 
    1131                 :     831143 :     void transform(const basegfx::B2DHomMatrix& rMatrix)
    1132                 :            :     {
    1133                 :     831143 :         mpBufferedData.reset();
    1134                 :            : 
    1135         [ +  + ]:     831143 :         if(mpControlVector)
    1136                 :            :         {
    1137         [ +  + ]:     173179 :             for(sal_uInt32 a(0); a < maPoints.count(); a++)
    1138                 :            :             {
    1139         [ +  - ]:     156909 :                 basegfx::B2DPoint aCandidate = maPoints.getCoordinate(a);
    1140                 :            : 
    1141         [ +  - ]:     156909 :                 if(mpControlVector->isUsed())
    1142                 :            :                 {
    1143         [ +  - ]:     156909 :                     const basegfx::B2DVector& rPrevVector(mpControlVector->getPrevVector(a));
    1144         [ +  - ]:     156909 :                     const basegfx::B2DVector& rNextVector(mpControlVector->getNextVector(a));
    1145                 :            : 
    1146 [ +  - ][ +  + ]:     156909 :                     if(!rPrevVector.equalZero())
    1147                 :            :                     {
    1148         [ +  - ]:     128060 :                         basegfx::B2DVector aPrevVector(rMatrix * rPrevVector);
    1149         [ +  - ]:     128060 :                         mpControlVector->setPrevVector(a, aPrevVector);
    1150                 :            :                     }
    1151                 :            : 
    1152 [ +  - ][ +  + ]:     156909 :                     if(!rNextVector.equalZero())
    1153                 :            :                     {
    1154         [ +  - ]:     128112 :                         basegfx::B2DVector aNextVector(rMatrix * rNextVector);
    1155         [ +  - ]:     128112 :                         mpControlVector->setNextVector(a, aNextVector);
    1156                 :            :                     }
    1157                 :            :                 }
    1158                 :            : 
    1159         [ +  - ]:     156909 :                 aCandidate *= rMatrix;
    1160         [ +  - ]:     156909 :                 maPoints.setCoordinate(a, aCandidate);
    1161                 :     156909 :             }
    1162                 :            : 
    1163         [ -  + ]:      16270 :             if(!mpControlVector->isUsed())
    1164                 :          0 :                 mpControlVector.reset();
    1165                 :            :         }
    1166                 :            :         else
    1167                 :            :         {
    1168                 :     814873 :             maPoints.transform(rMatrix);
    1169                 :            :         }
    1170                 :     831143 :     }
    1171                 :            : 
    1172                 :            :     const basegfx::B2DPoint* begin() const
    1173                 :            :     {
    1174                 :            :         return maPoints.begin();
    1175                 :            :     }
    1176                 :            : 
    1177                 :            :     const basegfx::B2DPoint* end() const
    1178                 :            :     {
    1179                 :            :         return maPoints.end();
    1180                 :            :     }
    1181                 :            : 
    1182                 :            :     basegfx::B2DPoint* begin()
    1183                 :            :     {
    1184                 :            :        mpBufferedData.reset();
    1185                 :            :        return maPoints.begin();
    1186                 :            :     }
    1187                 :            : 
    1188                 :            :     basegfx::B2DPoint* end()
    1189                 :            :     {
    1190                 :            :         mpBufferedData.reset();
    1191                 :            :         return maPoints.end();
    1192                 :            :     }
    1193                 :            : };
    1194                 :            : 
    1195                 :            : //////////////////////////////////////////////////////////////////////////////
    1196                 :            : 
    1197                 :            : namespace basegfx
    1198                 :            : {
    1199                 :            :     namespace
    1200                 :            :     {
    1201                 :            :         struct DefaultPolygon: public rtl::Static<B2DPolygon::ImplType, DefaultPolygon> {};
    1202                 :            :     }
    1203                 :            : 
    1204                 :    4181656 :     B2DPolygon::B2DPolygon()
    1205                 :    4181656 :     :   mpPolygon(DefaultPolygon::get())
    1206                 :    4181656 :     {}
    1207                 :            : 
    1208                 :   17698978 :     B2DPolygon::B2DPolygon(const B2DPolygon& rPolygon)
    1209                 :   17698978 :     :   mpPolygon(rPolygon.mpPolygon)
    1210                 :   17698978 :     {}
    1211                 :            : 
    1212                 :          0 :     B2DPolygon::B2DPolygon(const B2DPolygon& rPolygon, sal_uInt32 nIndex, sal_uInt32 nCount)
    1213         [ #  # ]:          0 :     :   mpPolygon(ImplB2DPolygon(*rPolygon.mpPolygon, nIndex, nCount))
    1214                 :            :     {
    1215                 :            :         // TODO(P2): one extra temporary here (cow_wrapper copies
    1216                 :            :         // given ImplB2DPolygon into its internal impl_t wrapper type)
    1217                 :            :         OSL_ENSURE(nIndex + nCount <= rPolygon.mpPolygon->count(), "B2DPolygon constructor outside range (!)");
    1218                 :          0 :     }
    1219                 :            : 
    1220                 :   21880377 :     B2DPolygon::~B2DPolygon()
    1221                 :            :     {
    1222                 :   21880377 :     }
    1223                 :            : 
    1224                 :      39029 :     B2DPolygon& B2DPolygon::operator=(const B2DPolygon& rPolygon)
    1225                 :            :     {
    1226                 :      39029 :         mpPolygon = rPolygon.mpPolygon;
    1227                 :      39029 :         return *this;
    1228                 :            :     }
    1229                 :            : 
    1230                 :        150 :     void B2DPolygon::makeUnique()
    1231                 :            :     {
    1232                 :        150 :         mpPolygon.make_unique();
    1233                 :        150 :     }
    1234                 :            : 
    1235                 :      64402 :     bool B2DPolygon::operator==(const B2DPolygon& rPolygon) const
    1236                 :            :     {
    1237         [ +  + ]:      64402 :         if(mpPolygon.same_object(rPolygon.mpPolygon))
    1238                 :       2926 :             return true;
    1239                 :            : 
    1240                 :      64402 :         return ((*mpPolygon) == (*rPolygon.mpPolygon));
    1241                 :            :     }
    1242                 :            : 
    1243                 :      10815 :     bool B2DPolygon::operator!=(const B2DPolygon& rPolygon) const
    1244                 :            :     {
    1245                 :      10815 :         return !(*this == rPolygon);
    1246                 :            :     }
    1247                 :            : 
    1248                 :    8914912 :     sal_uInt32 B2DPolygon::count() const
    1249                 :            :     {
    1250                 :    8914912 :         return mpPolygon->count();
    1251                 :            :     }
    1252                 :            : 
    1253                 :   62246701 :     B2DPoint B2DPolygon::getB2DPoint(sal_uInt32 nIndex) const
    1254                 :            :     {
    1255                 :            :         OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
    1256                 :            : 
    1257                 :   62246701 :         return mpPolygon->getPoint(nIndex);
    1258                 :            :     }
    1259                 :            : 
    1260                 :   11462894 :     void B2DPolygon::setB2DPoint(sal_uInt32 nIndex, const B2DPoint& rValue)
    1261                 :            :     {
    1262                 :            :         OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
    1263                 :            : 
    1264         [ +  + ]:   11462894 :         if(getB2DPoint(nIndex) != rValue)
    1265                 :            :         {
    1266                 :   10864813 :             mpPolygon->setPoint(nIndex, rValue);
    1267                 :            :         }
    1268                 :   11462894 :     }
    1269                 :            : 
    1270                 :        245 :     void B2DPolygon::reserve(sal_uInt32 nCount)
    1271                 :            :     {
    1272                 :        245 :         mpPolygon->reserve(nCount);
    1273                 :        245 :     }
    1274                 :            : 
    1275                 :          0 :     void B2DPolygon::insert(sal_uInt32 nIndex, const B2DPoint& rPoint, sal_uInt32 nCount)
    1276                 :            :     {
    1277                 :            :         OSL_ENSURE(nIndex <= mpPolygon->count(), "B2DPolygon Insert outside range (!)");
    1278                 :            : 
    1279         [ #  # ]:          0 :         if(nCount)
    1280                 :            :         {
    1281                 :          0 :             mpPolygon->insert(nIndex, rPoint, nCount);
    1282                 :            :         }
    1283                 :          0 :     }
    1284                 :            : 
    1285                 :    2976523 :     void B2DPolygon::append(const B2DPoint& rPoint, sal_uInt32 nCount)
    1286                 :            :     {
    1287         [ +  - ]:    2976523 :         if(nCount)
    1288                 :            :         {
    1289                 :    2976523 :             mpPolygon->insert(mpPolygon->count(), rPoint, nCount);
    1290                 :            :         }
    1291                 :    2976523 :     }
    1292                 :            : 
    1293                 :    4927504 :     void B2DPolygon::append(const B2DPoint& rPoint)
    1294                 :            :     {
    1295                 :    4927504 :         mpPolygon->append(rPoint);
    1296                 :    4927504 :     }
    1297                 :            : 
    1298                 :     108153 :     B2DPoint B2DPolygon::getPrevControlPoint(sal_uInt32 nIndex) const
    1299                 :            :     {
    1300                 :            :         OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
    1301                 :            : 
    1302         [ +  + ]:     108153 :         if(mpPolygon->areControlPointsUsed())
    1303                 :            :         {
    1304                 :      91926 :             return mpPolygon->getPoint(nIndex) + mpPolygon->getPrevControlVector(nIndex);
    1305                 :            :         }
    1306                 :            :         else
    1307                 :            :         {
    1308                 :     108153 :             return mpPolygon->getPoint(nIndex);
    1309                 :            :         }
    1310                 :            :     }
    1311                 :            : 
    1312                 :     105675 :     B2DPoint B2DPolygon::getNextControlPoint(sal_uInt32 nIndex) const
    1313                 :            :     {
    1314                 :            :         OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
    1315                 :            : 
    1316         [ +  + ]:     105675 :         if(mpPolygon->areControlPointsUsed())
    1317                 :            :         {
    1318                 :      89508 :             return mpPolygon->getPoint(nIndex) + mpPolygon->getNextControlVector(nIndex);
    1319                 :            :         }
    1320                 :            :         else
    1321                 :            :         {
    1322                 :     105675 :             return mpPolygon->getPoint(nIndex);
    1323                 :            :         }
    1324                 :            :     }
    1325                 :            : 
    1326                 :       2271 :     void B2DPolygon::setPrevControlPoint(sal_uInt32 nIndex, const B2DPoint& rValue)
    1327                 :            :     {
    1328                 :            :         OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
    1329 [ +  - ][ +  - ]:       2271 :         const basegfx::B2DVector aNewVector(rValue - mpPolygon->getPoint(nIndex));
    1330                 :            : 
    1331 [ +  - ][ +  + ]:       2271 :         if(mpPolygon->getPrevControlVector(nIndex) != aNewVector)
                 [ +  - ]
    1332                 :            :         {
    1333 [ +  - ][ +  - ]:       2265 :             mpPolygon->setPrevControlVector(nIndex, aNewVector);
    1334                 :       2271 :         }
    1335                 :       2271 :     }
    1336                 :            : 
    1337                 :        163 :     void B2DPolygon::setNextControlPoint(sal_uInt32 nIndex, const B2DPoint& rValue)
    1338                 :            :     {
    1339                 :            :         OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
    1340 [ +  - ][ +  - ]:        163 :         const basegfx::B2DVector aNewVector(rValue - mpPolygon->getPoint(nIndex));
    1341                 :            : 
    1342 [ +  - ][ +  + ]:        163 :         if(mpPolygon->getNextControlVector(nIndex) != aNewVector)
                 [ +  - ]
    1343                 :            :         {
    1344 [ +  - ][ +  - ]:        157 :             mpPolygon->setNextControlVector(nIndex, aNewVector);
    1345                 :        163 :         }
    1346                 :        163 :     }
    1347                 :            : 
    1348                 :          5 :     void B2DPolygon::setControlPoints(sal_uInt32 nIndex, const basegfx::B2DPoint& rPrev, const basegfx::B2DPoint& rNext)
    1349                 :            :     {
    1350                 :            :         OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
    1351 [ +  - ][ +  - ]:          5 :         const B2DPoint aPoint(mpPolygon->getPoint(nIndex));
    1352                 :          5 :         const basegfx::B2DVector aNewPrev(rPrev - aPoint);
    1353                 :          5 :         const basegfx::B2DVector aNewNext(rNext - aPoint);
    1354                 :            : 
    1355 [ +  - ][ +  - ]:          5 :         if(mpPolygon->getPrevControlVector(nIndex) != aNewPrev || mpPolygon->getNextControlVector(nIndex) != aNewNext)
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
    1356                 :            :         {
    1357 [ +  - ][ +  - ]:          5 :             mpPolygon->setControlVectors(nIndex, aNewPrev, aNewNext);
    1358                 :          5 :         }
    1359                 :          5 :     }
    1360                 :            : 
    1361                 :          0 :     void B2DPolygon::resetPrevControlPoint(sal_uInt32 nIndex)
    1362                 :            :     {
    1363                 :            :         OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
    1364                 :            : 
    1365 [ #  # ][ #  # ]:          0 :         if(mpPolygon->areControlPointsUsed() && !mpPolygon->getPrevControlVector(nIndex).equalZero())
                 [ #  # ]
    1366                 :            :         {
    1367                 :          0 :             mpPolygon->setPrevControlVector(nIndex, B2DVector::getEmptyVector());
    1368                 :            :         }
    1369                 :          0 :     }
    1370                 :            : 
    1371                 :          0 :     void B2DPolygon::resetNextControlPoint(sal_uInt32 nIndex)
    1372                 :            :     {
    1373                 :            :         OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
    1374                 :            : 
    1375 [ #  # ][ #  # ]:          0 :         if(mpPolygon->areControlPointsUsed() && !mpPolygon->getNextControlVector(nIndex).equalZero())
                 [ #  # ]
    1376                 :            :         {
    1377                 :          0 :             mpPolygon->setNextControlVector(nIndex, B2DVector::getEmptyVector());
    1378                 :            :         }
    1379                 :          0 :     }
    1380                 :            : 
    1381                 :          5 :     void B2DPolygon::resetControlPoints()
    1382                 :            :     {
    1383         [ +  - ]:          5 :         if(mpPolygon->areControlPointsUsed())
    1384                 :            :         {
    1385                 :          5 :             mpPolygon->resetControlVectors();
    1386                 :            :         }
    1387                 :          5 :     }
    1388                 :            : 
    1389                 :      36072 :     void B2DPolygon::appendBezierSegment(
    1390                 :            :         const B2DPoint& rNextControlPoint,
    1391                 :            :         const B2DPoint& rPrevControlPoint,
    1392                 :            :         const B2DPoint& rPoint)
    1393                 :            :     {
    1394 [ +  - ][ +  + ]:      36072 :         const B2DVector aNewNextVector(mpPolygon->count() ? B2DVector(rNextControlPoint - mpPolygon->getPoint(mpPolygon->count() - 1)) : B2DVector::getEmptyVector());
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  + ][ #  # ]
    1395                 :      36072 :         const B2DVector aNewPrevVector(rPrevControlPoint - rPoint);
    1396                 :            : 
    1397 [ +  + ][ +  - ]:      36072 :         if(aNewNextVector.equalZero() && aNewPrevVector.equalZero())
         [ +  + ][ +  + ]
                 [ +  - ]
    1398                 :            :         {
    1399 [ +  - ][ +  - ]:         47 :             mpPolygon->insert(mpPolygon->count(), rPoint, 1);
                 [ +  - ]
    1400                 :            :         }
    1401                 :            :         else
    1402                 :            :         {
    1403 [ +  - ][ +  - ]:      36025 :             mpPolygon->appendBezierSegment(aNewNextVector, aNewPrevVector, rPoint);
    1404                 :      36072 :         }
    1405                 :      36072 :     }
    1406                 :            : 
    1407                 :    8605102 :     bool B2DPolygon::areControlPointsUsed() const
    1408                 :            :     {
    1409                 :    8605102 :         return mpPolygon->areControlPointsUsed();
    1410                 :            :     }
    1411                 :            : 
    1412                 :       4248 :     bool B2DPolygon::isPrevControlPointUsed(sal_uInt32 nIndex) const
    1413                 :            :     {
    1414                 :            :         OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
    1415                 :            : 
    1416 [ +  + ][ +  + ]:       4248 :         return (mpPolygon->areControlPointsUsed() && !mpPolygon->getPrevControlVector(nIndex).equalZero());
    1417                 :            :     }
    1418                 :            : 
    1419                 :       1143 :     bool B2DPolygon::isNextControlPointUsed(sal_uInt32 nIndex) const
    1420                 :            :     {
    1421                 :            :         OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
    1422                 :            : 
    1423 [ +  + ][ +  + ]:       1143 :         return (mpPolygon->areControlPointsUsed() && !mpPolygon->getNextControlVector(nIndex).equalZero());
    1424                 :            :     }
    1425                 :            : 
    1426                 :      64217 :     B2VectorContinuity B2DPolygon::getContinuityInPoint(sal_uInt32 nIndex) const
    1427                 :            :     {
    1428                 :            :         OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
    1429                 :            : 
    1430         [ +  - ]:      64217 :         if(mpPolygon->areControlPointsUsed())
    1431                 :            :         {
    1432                 :      64217 :             const B2DVector& rPrev(mpPolygon->getPrevControlVector(nIndex));
    1433                 :      64217 :             const B2DVector& rNext(mpPolygon->getNextControlVector(nIndex));
    1434                 :            : 
    1435                 :      64217 :             return getContinuity(rPrev, rNext);
    1436                 :            :         }
    1437                 :            :         else
    1438                 :            :         {
    1439                 :      64217 :             return CONTINUITY_NONE;
    1440                 :            :         }
    1441                 :            :     }
    1442                 :            : 
    1443                 :      12149 :     void B2DPolygon::getBezierSegment(sal_uInt32 nIndex, B2DCubicBezier& rTarget) const
    1444                 :            :     {
    1445                 :            :         OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
    1446                 :      12149 :         const bool bNextIndexValidWithoutClose(nIndex + 1 < mpPolygon->count());
    1447                 :            : 
    1448 [ +  + ][ +  + ]:      12149 :         if(bNextIndexValidWithoutClose || mpPolygon->isClosed())
                 [ +  + ]
    1449                 :            :         {
    1450         [ +  + ]:      12103 :             const sal_uInt32 nNextIndex(bNextIndexValidWithoutClose ? nIndex + 1 : 0);
    1451                 :      12103 :             rTarget.setStartPoint(mpPolygon->getPoint(nIndex));
    1452                 :      12103 :             rTarget.setEndPoint(mpPolygon->getPoint(nNextIndex));
    1453                 :            : 
    1454         [ +  + ]:      12103 :             if(mpPolygon->areControlPointsUsed())
    1455                 :            :             {
    1456                 :        545 :                 rTarget.setControlPointA(rTarget.getStartPoint() + mpPolygon->getNextControlVector(nIndex));
    1457                 :        545 :                 rTarget.setControlPointB(rTarget.getEndPoint() + mpPolygon->getPrevControlVector(nNextIndex));
    1458                 :            :             }
    1459                 :            :             else
    1460                 :            :             {
    1461                 :            :                 // no bezier, reset control poins at rTarget
    1462                 :      11558 :                 rTarget.setControlPointA(rTarget.getStartPoint());
    1463                 :      11558 :                 rTarget.setControlPointB(rTarget.getEndPoint());
    1464                 :            :             }
    1465                 :            :         }
    1466                 :            :         else
    1467                 :            :         {
    1468                 :            :             // no valid edge at all, reset rTarget to current point
    1469         [ +  - ]:         46 :             const B2DPoint aPoint(mpPolygon->getPoint(nIndex));
    1470                 :         46 :             rTarget.setStartPoint(aPoint);
    1471                 :         46 :             rTarget.setEndPoint(aPoint);
    1472                 :         46 :             rTarget.setControlPointA(aPoint);
    1473                 :         46 :             rTarget.setControlPointB(aPoint);
    1474                 :            :         }
    1475                 :      12149 :     }
    1476                 :            : 
    1477                 :         18 :     B2DPolygon B2DPolygon::getDefaultAdaptiveSubdivision() const
    1478                 :            :     {
    1479                 :         18 :         return mpPolygon->getDefaultAdaptiveSubdivision(*this);
    1480                 :            :     }
    1481                 :            : 
    1482                 :    4740645 :     B2DRange B2DPolygon::getB2DRange() const
    1483                 :            :     {
    1484                 :    4740645 :         return mpPolygon->getB2DRange(*this);
    1485                 :            :     }
    1486                 :            : 
    1487                 :         68 :     void B2DPolygon::append(const B2DPolygon& rPoly, sal_uInt32 nIndex, sal_uInt32 nCount)
    1488                 :            :     {
    1489         [ +  - ]:         68 :         if(rPoly.count())
    1490                 :            :         {
    1491         [ +  - ]:         68 :             if(!nCount)
    1492                 :            :             {
    1493                 :         68 :                 nCount = rPoly.count();
    1494                 :            :             }
    1495                 :            : 
    1496 [ +  - ][ +  - ]:         68 :             if(0 == nIndex && nCount == rPoly.count())
                 [ +  - ]
    1497                 :            :             {
    1498                 :         68 :                 mpPolygon->insert(mpPolygon->count(), *rPoly.mpPolygon);
    1499                 :            :             }
    1500                 :            :             else
    1501                 :            :             {
    1502                 :            :                 OSL_ENSURE(nIndex + nCount <= rPoly.mpPolygon->count(), "B2DPolygon Append outside range (!)");
    1503         [ #  # ]:          0 :                 ImplB2DPolygon aTempPoly(*rPoly.mpPolygon, nIndex, nCount);
    1504 [ #  # ][ #  # ]:          0 :                 mpPolygon->insert(mpPolygon->count(), aTempPoly);
         [ #  # ][ #  # ]
    1505                 :            :             }
    1506                 :            :         }
    1507                 :         68 :     }
    1508                 :            : 
    1509                 :      18928 :     void B2DPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount)
    1510                 :            :     {
    1511                 :            :         OSL_ENSURE(nIndex + nCount <= mpPolygon->count(), "B2DPolygon Remove outside range (!)");
    1512                 :            : 
    1513         [ +  - ]:      18928 :         if(nCount)
    1514                 :            :         {
    1515                 :      18928 :             mpPolygon->remove(nIndex, nCount);
    1516                 :            :         }
    1517                 :      18928 :     }
    1518                 :            : 
    1519                 :      97162 :     void B2DPolygon::clear()
    1520                 :            :     {
    1521                 :      97162 :         mpPolygon = DefaultPolygon::get();
    1522                 :      97162 :     }
    1523                 :            : 
    1524                 :    4989811 :     bool B2DPolygon::isClosed() const
    1525                 :            :     {
    1526                 :    4989811 :         return mpPolygon->isClosed();
    1527                 :            :     }
    1528                 :            : 
    1529                 :    4062279 :     void B2DPolygon::setClosed(bool bNew)
    1530                 :            :     {
    1531         [ +  + ]:    4062279 :         if(isClosed() != bNew)
    1532                 :            :         {
    1533                 :    3839587 :             mpPolygon->setClosed(bNew);
    1534                 :            :         }
    1535                 :    4062279 :     }
    1536                 :            : 
    1537                 :       4325 :     void B2DPolygon::flip()
    1538                 :            :     {
    1539         [ +  - ]:       4325 :         if(count() > 1)
    1540                 :            :         {
    1541                 :       4325 :             mpPolygon->flip();
    1542                 :            :         }
    1543                 :       4325 :     }
    1544                 :            : 
    1545                 :      16168 :     bool B2DPolygon::hasDoublePoints() const
    1546                 :            :     {
    1547 [ +  - ][ +  + ]:      16168 :         return (mpPolygon->count() > 1 && mpPolygon->hasDoublePoints());
    1548                 :            :     }
    1549                 :            : 
    1550                 :      10888 :     void B2DPolygon::removeDoublePoints()
    1551                 :            :     {
    1552         [ +  + ]:      10888 :         if(hasDoublePoints())
    1553                 :            :         {
    1554                 :         90 :             mpPolygon->removeDoublePointsAtBeginEnd();
    1555                 :         90 :             mpPolygon->removeDoublePointsWholeTrack();
    1556                 :            :         }
    1557                 :      10888 :     }
    1558                 :            : 
    1559                 :     849707 :     void B2DPolygon::transform(const B2DHomMatrix& rMatrix)
    1560                 :            :     {
    1561 [ +  - ][ +  + ]:     849707 :         if(mpPolygon->count() && !rMatrix.isIdentity())
                 [ +  + ]
    1562                 :            :         {
    1563                 :     831143 :             mpPolygon->transform(rMatrix);
    1564                 :            :         }
    1565                 :     849707 :     }
    1566                 :            : 
    1567                 :            : } // end of namespace basegfx
    1568                 :            : 
    1569                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10