[Libreoffice-commits] core.git: filter/source include/svx include/tools svx/inc svx/source tools/inc tools/source

Noel Grandin noel.grandin at collabora.co.uk
Tue Feb 6 11:47:55 UTC 2018


 filter/source/msfilter/escherex.cxx |    6 
 include/svx/xpoly.hxx               |    9 
 include/tools/poly.hxx              |    1 
 svx/inc/xpolyimp.hxx                |   27 --
 svx/source/svdraw/svdoedge.cxx      |   21 +
 svx/source/xoutdev/_xpoly.cxx       |  401 ++++++++----------------------------
 tools/inc/poly.h                    |    1 
 tools/source/generic/poly.cxx       |   22 +
 8 files changed, 152 insertions(+), 336 deletions(-)

New commits:
commit f9c2bcc8b761f5e21354c0fb7bca6aa432d11ec2
Author: Noel Grandin <noel.grandin at collabora.co.uk>
Date:   Mon Feb 5 15:56:12 2018 +0200

    simplify ImpXPolygon
    
    just use a std::vector<std::pair<Point,PolyFlags>>
    
    Change-Id: I85de832af9095a33bda1620781c3b231a345e07c
    Reviewed-on: https://gerrit.libreoffice.org/49275
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/filter/source/msfilter/escherex.cxx b/filter/source/msfilter/escherex.cxx
index 561c98f49ccc..a4888620a0bb 100644
--- a/filter/source/msfilter/escherex.cxx
+++ b/filter/source/msfilter/escherex.cxx
@@ -2029,7 +2029,7 @@ when save as MS file, the connector must be convert to corresponding type.
 sal_Int32 lcl_GetAdjustValueCount( const XPolygon& rPoly )
 {
     int nRet = 0;
-    switch (  rPoly.GetSize() )
+    switch (  rPoly.GetPointCount() )
     {
     case 2 :
     case 3:
@@ -2042,7 +2042,7 @@ sal_Int32 lcl_GetAdjustValueCount( const XPolygon& rPoly )
         nRet = 2;
         break;
     default:
-        if ( rPoly.GetSize()>=6 )
+        if ( rPoly.GetPointCount()>=6 )
             nRet = 3;
         break;
     }
@@ -2052,7 +2052,7 @@ sal_Int32 lcl_GetAdjustValueCount( const XPolygon& rPoly )
 // Adjust value decide the position which connector should turn a corner
 sal_Int32 lcl_GetConnectorAdjustValue ( const XPolygon& rPoly, sal_uInt16 nIndex )
 {
-    sal_uInt16 k =  rPoly.GetSize();
+    sal_uInt16 k =  rPoly.GetPointCount();
     OSL_ASSERT ( k >= ( 3 + nIndex ) );
 
     Point aPt;
diff --git a/include/svx/xpoly.hxx b/include/svx/xpoly.hxx
index 2c6f848d00be..ffc95ab3f4d0 100644
--- a/include/svx/xpoly.hxx
+++ b/include/svx/xpoly.hxx
@@ -53,7 +53,8 @@ class SVX_DLLPUBLIC XPolygon final
     static bool CheckAngles(sal_uInt16& nStart, sal_uInt16 nEnd, sal_uInt16& nA1, sal_uInt16& nA2);
 
 public:
-    XPolygon( sal_uInt16 nSize=16 );
+    XPolygon();
+    XPolygon( sal_uInt16 nSize );
     XPolygon( const XPolygon& rXPoly );
     XPolygon( XPolygon&& rXPoly );
     XPolygon( const tools::Polygon& rPoly );
@@ -64,10 +65,8 @@ public:
 
     ~XPolygon();
 
-    sal_uInt16      GetSize() const;
-
-    void        SetPointCount( sal_uInt16 nPoints );
     sal_uInt16      GetPointCount() const;
+    void            SetPointCount( sal_uInt16 nPoints );
 
     void        Insert( sal_uInt16 nPos, const Point& rPt, PolyFlags eFlags );
     void        Insert( sal_uInt16 nPos, const XPolygon& rXPoly );
@@ -81,7 +80,7 @@ public:
     XPolygon&       operator=( XPolygon&& rXPoly );
     bool            operator==( const XPolygon& rXPoly ) const;
 
-    PolyFlags  GetFlags( sal_uInt16 nPos ) const;
+    PolyFlags   GetFlags( sal_uInt16 nPos ) const;
     void        SetFlags( sal_uInt16 nPos, PolyFlags eFlags );
     bool        IsControl(sal_uInt16 nPos) const;
     bool        IsSmooth(sal_uInt16 nPos) const;
diff --git a/include/tools/poly.hxx b/include/tools/poly.hxx
index 1a0926ecfff3..259aeac21b9c 100644
--- a/include/tools/poly.hxx
+++ b/include/tools/poly.hxx
@@ -88,6 +88,7 @@ public:
                         Polygon( sal_uInt16 nSize );
                         Polygon( sal_uInt16 nPoints, const Point* pPtAry,
                                  const PolyFlags* pFlagAry = nullptr );
+                        Polygon( std::vector< std::pair<Point, PolyFlags> > const & );
                         Polygon( const tools::Rectangle& rRect );
                         Polygon( const tools::Rectangle& rRect,
                                  sal_uInt32 nHorzRound, sal_uInt32 nVertRound );
diff --git a/svx/inc/xpolyimp.hxx b/svx/inc/xpolyimp.hxx
index fd0fe2905d8b..76f4ae24c87f 100644
--- a/svx/inc/xpolyimp.hxx
+++ b/svx/inc/xpolyimp.hxx
@@ -29,26 +29,13 @@ class Point;
 class ImpXPolygon
 {
 public:
-    Point*              pPointAry;
-    std::unique_ptr<PolyFlags[]>
-                        pFlagAry;
-    Point*              pOldPointAry;
-    bool                bDeleteOldPoints;
-    sal_uInt16          nSize;
-    sal_uInt16          nResize;
-    sal_uInt16          nPoints;
-
-    ImpXPolygon( sal_uInt16 nInitSize, sal_uInt16 nResize=16 );
-    ImpXPolygon( const ImpXPolygon& rImpXPoly );
-    ~ImpXPolygon();
-
-    bool operator==(const ImpXPolygon& rImpXPoly) const;
-
-    void CheckPointDelete() const;
-
-    void Resize( sal_uInt16 nNewSize, bool bDeletePoints = true );
-    void InsertSpace( sal_uInt16 nPos, sal_uInt16 nCount );
-    void Remove( sal_uInt16 nPos, sal_uInt16 nCount );
+    std::vector<std::pair<Point, PolyFlags>> mvPointsAndFlags;
+    ImpXPolygon() = default;
+    ImpXPolygon(sal_uInt16 nSize)
+    {
+        mvPointsAndFlags.resize(nSize);
+    }
+    bool operator==(ImpXPolygon const & rOther) const { return mvPointsAndFlags == rOther.mvPointsAndFlags; }
 };
 
 class ImpXPolyPolygon
diff --git a/svx/source/svdraw/svdoedge.cxx b/svx/source/svdraw/svdoedge.cxx
index b14201f24cab..f0fdf4e06730 100644
--- a/svx/source/svdraw/svdoedge.cxx
+++ b/svx/source/svdraw/svdoedge.cxx
@@ -505,14 +505,23 @@ void SdrEdgeObj::ImpSetTailPoint(bool bTail1, const Point& rPt)
 {
     sal_uInt16 nPointCount=pEdgeTrack->GetPointCount();
     if (nPointCount==0) {
+        pEdgeTrack->SetPointCount(2);
         (*pEdgeTrack)[0]=rPt;
         (*pEdgeTrack)[1]=rPt;
     } else if (nPointCount==1) {
-        if (!bTail1) (*pEdgeTrack)[1]=rPt;
-        else { (*pEdgeTrack)[1]=(*pEdgeTrack)[0]; (*pEdgeTrack)[0]=rPt; }
+        pEdgeTrack->SetPointCount(2);
+        if (!bTail1)
+            (*pEdgeTrack)[1]=rPt;
+        else
+        {
+            (*pEdgeTrack)[1]=(*pEdgeTrack)[0];
+            (*pEdgeTrack)[0]=rPt;
+        }
     } else {
-        if (!bTail1) (*pEdgeTrack)[sal_uInt16(nPointCount-1)]=rPt;
-        else (*pEdgeTrack)[0]=rPt;
+        if (!bTail1)
+            (*pEdgeTrack)[sal_uInt16(nPointCount-1)]=rPt;
+        else
+            (*pEdgeTrack)[0]=rPt;
     }
     ImpRecalcEdgeTrack();
     SetRectsDirty();
@@ -2402,9 +2411,11 @@ void SdrEdgeObj::NbcSetPoint(const Point& rPnt, sal_uInt32 i)
     // TODO: Need an implementation to connect differently.
     ImpUndirtyEdgeTrack();
     sal_uInt16 nCount=pEdgeTrack->GetPointCount();
+    if (nCount == 0)
+        pEdgeTrack->SetPointCount(1);
     if (0 == i)
         (*pEdgeTrack)[0]=rPnt;
-    if (1 == i)
+    else if (1 == i)
         (*pEdgeTrack)[nCount-1]=rPnt;
     SetEdgeTrackDirty();
     SetRectsDirty();
diff --git a/svx/source/xoutdev/_xpoly.cxx b/svx/source/xoutdev/_xpoly.cxx
index 07ff1d214ec3..76bf2d4be071 100644
--- a/svx/source/xoutdev/_xpoly.cxx
+++ b/svx/source/xoutdev/_xpoly.cxx
@@ -38,174 +38,14 @@
 #include <basegfx/numeric/ftools.hxx>
 
 
-ImpXPolygon::ImpXPolygon(sal_uInt16 nInitSize, sal_uInt16 _nResize)
-    : pPointAry(nullptr)
-    , pFlagAry(nullptr)
-    , pOldPointAry(nullptr)
-    , bDeleteOldPoints(false)
-    , nSize(0)
-    , nResize(_nResize)
-    , nPoints(0)
-{
-    Resize(nInitSize);
-}
-
-ImpXPolygon::ImpXPolygon( const ImpXPolygon& rImpXPoly )
-    : pPointAry(nullptr)
-    , pFlagAry(nullptr)
-    , pOldPointAry(nullptr)
-    , bDeleteOldPoints(false)
-    , nSize(0)
-    , nResize(rImpXPoly.nResize)
-    , nPoints(0)
-{
-    rImpXPoly.CheckPointDelete();
-
-    Resize( rImpXPoly.nSize );
-
-    // copy
-    nPoints = rImpXPoly.nPoints;
-    memcpy( pPointAry, rImpXPoly.pPointAry, nSize*sizeof( Point ) );
-    memcpy( pFlagAry.get(), rImpXPoly.pFlagAry.get(), nSize );
-}
-
-ImpXPolygon::~ImpXPolygon()
-{
-    delete[] pPointAry;
-    if ( bDeleteOldPoints )
-    {
-        delete[] pOldPointAry;
-        pOldPointAry = nullptr;
-    }
-}
-
-bool ImpXPolygon::operator==(const ImpXPolygon& rImpXPoly) const
-{
-    return nPoints==rImpXPoly.nPoints &&
-           (nPoints==0 ||
-            (memcmp(pPointAry, rImpXPoly.pPointAry, nPoints*sizeof(Point))==0 &&
-             memcmp(pFlagAry.get(), rImpXPoly.pFlagAry.get(), nPoints)==0));
-}
-
-/** Change polygon size
- *
- * @param nNewSize      the new size of the polygon
- * @param bDeletePoints if FALSE, do not delete the point array directly but
- *                      wait for the next call before doing so. This prevents
- *                      errors with XPoly[n] = XPoly[0] where a resize might
- *                      destroy the right side point array too early.
- */
-void ImpXPolygon::Resize( sal_uInt16 nNewSize, bool bDeletePoints )
-{
-    if( nNewSize == nSize )
-        return;
-
-    PolyFlags*  pOldFlagAry  = pFlagAry.release();
-    sal_uInt16  nOldSize     = nSize;
-
-    CheckPointDelete();
-    pOldPointAry = pPointAry;
-
-    // Round the new size to a multiple of nResize, if
-    // the object was not newly created (nSize != 0)
-    if ( nSize != 0 && nNewSize > nSize )
-    {
-        DBG_ASSERT(nResize, "Trying to resize but nResize = 0 !");
-        nNewSize = nSize + ((nNewSize-nSize-1) / nResize + 1) * nResize;
-    }
-    // create point array
-    nSize     = nNewSize;
-    pPointAry = new Point[ nSize ];
-
-    // create flag array
-    pFlagAry.reset( new PolyFlags[ nSize ] );
-    memset( pFlagAry.get(), 0, nSize );
-
-    // copy if needed
-    if( nOldSize )
-    {
-        if( nOldSize < nSize )
-        {
-            memcpy( pPointAry, pOldPointAry, nOldSize*sizeof( Point ) );
-            memcpy( pFlagAry.get(),  pOldFlagAry, nOldSize );
-        }
-        else
-        {
-            memcpy( pPointAry, pOldPointAry, nSize*sizeof( Point ) );
-            memcpy( pFlagAry.get(), pOldFlagAry, nSize );
-
-            // adjust number of valid points
-            if( nPoints > nSize )
-                nPoints = nSize;
-        }
-        if ( bDeletePoints )
-        {
-            delete[] pOldPointAry;
-            pOldPointAry = nullptr;
-        }
-        else
-            bDeleteOldPoints = true;
-        delete[] pOldFlagAry;
-    }
-}
 
-void ImpXPolygon::InsertSpace( sal_uInt16 nPos, sal_uInt16 nCount )
+XPolygon::XPolygon()
+    : pImpXPolygon( ImpXPolygon() )
 {
-    CheckPointDelete();
-
-    if ( nPos > nPoints )
-        nPos = nPoints;
-
-    // if the polygon is too small than enlarge it
-    if( (nPoints + nCount) > nSize )
-        Resize( nPoints + nCount );
-
-    // If the insert is not at the last position, move everything after backwards
-    if( nPos < nPoints )
-    {
-        sal_uInt16 nMove = nPoints - nPos;
-        memmove( &pPointAry[nPos+nCount], &pPointAry[nPos],
-                 nMove * sizeof(Point) );
-        memmove( &pFlagAry[nPos+nCount], &pFlagAry[nPos], nMove );
-    }
-    std::fill(pPointAry + nPos, pPointAry + nPos + nCount, Point());
-    memset( &pFlagAry [nPos], 0, nCount );
-
-    nPoints = nPoints + nCount;
-}
-
-void ImpXPolygon::Remove( sal_uInt16 nPos, sal_uInt16 nCount )
-{
-    CheckPointDelete();
-
-    if( (nPos + nCount) <= nPoints )
-    {
-        sal_uInt16 nMove = nPoints - nPos - nCount;
-
-        if( nMove )
-        {
-            memmove( &pPointAry[nPos], &pPointAry[nPos+nCount],
-                     nMove * sizeof(Point) );
-            memmove( &pFlagAry[nPos], &pFlagAry[nPos+nCount], nMove );
-        }
-        std::fill(pPointAry + (nPoints - nCount), pPointAry + nPoints, Point());
-        memset( &pFlagAry [nPoints - nCount], 0, nCount );
-        nPoints = nPoints - nCount;
-    }
-}
-
-void ImpXPolygon::CheckPointDelete() const
-{
-    if ( bDeleteOldPoints )
-    {
-        delete[] pOldPointAry;
-        const_cast< ImpXPolygon* >(this)->pOldPointAry = nullptr;
-        const_cast< ImpXPolygon* >(this)->bDeleteOldPoints = false;
-    }
 }
 
 XPolygon::XPolygon( sal_uInt16 nSize )
-    : pImpXPolygon( ImpXPolygon( nSize, 16 ) )
+    : pImpXPolygon( ImpXPolygon( nSize ) )
 {
 }
 
@@ -224,12 +64,12 @@ XPolygon::XPolygon( const tools::Polygon& rPoly )
     : pImpXPolygon( rPoly.GetSize() )
 {
     sal_uInt16 nSize = rPoly.GetSize();
-    pImpXPolygon->nPoints = nSize;
+    pImpXPolygon->mvPointsAndFlags.resize(nSize);
 
     for( sal_uInt16 i = 0; i < nSize;  i++ )
     {
-        pImpXPolygon->pPointAry[i] = rPoly[i];
-        pImpXPolygon->pFlagAry[i] = rPoly.GetFlags( i );
+        pImpXPolygon->mvPointsAndFlags[i].first = rPoly[i];
+        pImpXPolygon->mvPointsAndFlags[i].second = rPoly.GetFlags( i );
     }
 }
 
@@ -251,6 +91,8 @@ XPolygon::XPolygon(const tools::Rectangle& rRect, long nRx, long nRy)
     long    nYHdl = static_cast<long>(0.552284749 * nRy);
     sal_uInt16  nPos = 0;
 
+    pImpXPolygon->mvPointsAndFlags.resize(17);
+
     if ( nRx && nRy )
     {
         Point aCenter;
@@ -277,20 +119,20 @@ XPolygon::XPolygon(const tools::Rectangle& rRect, long nRx, long nRy)
                         break;
             }
             GenBezArc(aCenter, nRx, nRy, nXHdl, nYHdl, 0, 900, nQuad, nPos);
-            pImpXPolygon->pFlagAry[nPos  ] = PolyFlags::Smooth;
-            pImpXPolygon->pFlagAry[nPos+3] = PolyFlags::Smooth;
+            pImpXPolygon->mvPointsAndFlags[nPos  ].second = PolyFlags::Smooth;
+            pImpXPolygon->mvPointsAndFlags[nPos+3].second = PolyFlags::Smooth;
             nPos += 4;
         }
     }
     else
     {
-        pImpXPolygon->pPointAry[nPos++] = rRect.TopLeft();
-        pImpXPolygon->pPointAry[nPos++] = rRect.TopRight();
-        pImpXPolygon->pPointAry[nPos++] = rRect.BottomRight();
-        pImpXPolygon->pPointAry[nPos++] = rRect.BottomLeft();
+        pImpXPolygon->mvPointsAndFlags[nPos++].first = rRect.TopLeft();
+        pImpXPolygon->mvPointsAndFlags[nPos++].first = rRect.TopRight();
+        pImpXPolygon->mvPointsAndFlags[nPos++].first = rRect.BottomRight();
+        pImpXPolygon->mvPointsAndFlags[nPos++].first = rRect.BottomLeft();
     }
-    pImpXPolygon->pPointAry[nPos] = pImpXPolygon->pPointAry[0];
-    pImpXPolygon->nPoints = nPos + 1;
+    pImpXPolygon->mvPointsAndFlags[nPos].first = pImpXPolygon->mvPointsAndFlags[0].first;
+    pImpXPolygon->mvPointsAndFlags.resize(nPos + 1);
 }
 
 /// create a ellipse (curve) as Bézier polygon
@@ -308,6 +150,7 @@ XPolygon::XPolygon(const Point& rCenter, long nRx, long nRy,
     sal_uInt16  nPos = 0;
     bool    bLoopEnd = false;
 
+    pImpXPolygon->mvPointsAndFlags.resize(17);
     do
     {
         sal_uInt16 nA1, nA2;
@@ -317,20 +160,20 @@ XPolygon::XPolygon(const Point& rCenter, long nRx, long nRy,
         GenBezArc(rCenter, nRx, nRy, nXHdl, nYHdl, nA1, nA2, nQuad, nPos);
         nPos += 3;
         if ( !bLoopEnd )
-            pImpXPolygon->pFlagAry[nPos] = PolyFlags::Smooth;
+            pImpXPolygon->mvPointsAndFlags[nPos].second = PolyFlags::Smooth;
 
     } while ( !bLoopEnd );
 
     // if not a full circle than connect edges with center point if necessary
     if ( !bFull && bClose )
-        pImpXPolygon->pPointAry[++nPos] = rCenter;
+        pImpXPolygon->mvPointsAndFlags[++nPos].first = rCenter;
 
     if ( bFull )
     {
-        pImpXPolygon->pFlagAry[0   ] = PolyFlags::Smooth;
-        pImpXPolygon->pFlagAry[nPos] = PolyFlags::Smooth;
+        pImpXPolygon->mvPointsAndFlags[0   ].second = PolyFlags::Smooth;
+        pImpXPolygon->mvPointsAndFlags[nPos].second = PolyFlags::Smooth;
     }
-    pImpXPolygon->nPoints = nPos + 1;
+    pImpXPolygon->mvPointsAndFlags.resize( nPos + 1 );
 }
 
 XPolygon::~XPolygon()
@@ -339,60 +182,33 @@ XPolygon::~XPolygon()
 
 void XPolygon::SetPointCount( sal_uInt16 nPoints )
 {
-    pImpXPolygon->CheckPointDelete();
-
-    if( pImpXPolygon->nSize < nPoints )
-        pImpXPolygon->Resize( nPoints );
-
-    if ( nPoints < pImpXPolygon->nPoints )
-    {
-        sal_uInt16 nSize = pImpXPolygon->nPoints - nPoints;
-        std::fill(
-            pImpXPolygon->pPointAry + nPoints, pImpXPolygon->pPointAry + nPoints + nSize, Point());
-        memset( &pImpXPolygon->pFlagAry [nPoints], 0, nSize );
-    }
-    pImpXPolygon->nPoints = nPoints;
-}
-
-sal_uInt16 XPolygon::GetSize() const
-{
-    pImpXPolygon->CheckPointDelete();
-    return pImpXPolygon->nSize;
+    pImpXPolygon->mvPointsAndFlags.resize( nPoints );
 }
 
 sal_uInt16 XPolygon::GetPointCount() const
 {
-    pImpXPolygon->CheckPointDelete();
-    return pImpXPolygon->nPoints;
+    return pImpXPolygon->mvPointsAndFlags.size();
 }
 
 void XPolygon::Insert( sal_uInt16 nPos, const Point& rPt, PolyFlags eFlags )
 {
-    if (nPos>pImpXPolygon->nPoints) nPos=pImpXPolygon->nPoints;
-    pImpXPolygon->InsertSpace( nPos, 1 );
-    pImpXPolygon->pPointAry[nPos] = rPt;
-    pImpXPolygon->pFlagAry[nPos]  = eFlags;
+    if (nPos>pImpXPolygon->mvPointsAndFlags.size()) nPos=pImpXPolygon->mvPointsAndFlags.size();
+    pImpXPolygon->mvPointsAndFlags.emplace(pImpXPolygon->mvPointsAndFlags.begin() + nPos, rPt, eFlags);
 }
 
 void XPolygon::Insert( sal_uInt16 nPos, const XPolygon& rXPoly )
 {
-    if (nPos>pImpXPolygon->nPoints) nPos=pImpXPolygon->nPoints;
+    if (nPos>pImpXPolygon->mvPointsAndFlags.size()) nPos=pImpXPolygon->mvPointsAndFlags.size();
 
-    sal_uInt16 nPoints = rXPoly.GetPointCount();
-
-    pImpXPolygon->InsertSpace( nPos, nPoints );
-
-    memcpy( &(pImpXPolygon->pPointAry[nPos]),
-            rXPoly.pImpXPolygon->pPointAry,
-            nPoints*sizeof( Point ) );
-    memcpy( &(pImpXPolygon->pFlagAry[nPos]),
-            rXPoly.pImpXPolygon->pFlagAry.get(),
-            nPoints );
+    std::copy( rXPoly.pImpXPolygon->mvPointsAndFlags.begin(),
+               rXPoly.pImpXPolygon->mvPointsAndFlags.end(),
+               pImpXPolygon->mvPointsAndFlags.begin() + nPos );
 }
 
 void XPolygon::Remove( sal_uInt16 nPos, sal_uInt16 nCount )
 {
-    pImpXPolygon->Remove( nPos, nCount );
+    pImpXPolygon->mvPointsAndFlags.erase( pImpXPolygon->mvPointsAndFlags.begin() + nPos,
+                                          pImpXPolygon->mvPointsAndFlags.begin() + nPos + nCount );
 }
 
 void XPolygon::Move( long nHorzMove, long nVertMove )
@@ -401,10 +217,10 @@ void XPolygon::Move( long nHorzMove, long nVertMove )
         return;
 
     // move points
-    sal_uInt16 nCount = pImpXPolygon->nPoints;
+    sal_uInt16 nCount = pImpXPolygon->mvPointsAndFlags.size();
     for ( sal_uInt16 i = 0; i < nCount; i++ )
     {
-        Point* pPt = &(pImpXPolygon->pPointAry[i]);
+        Point* pPt = &(pImpXPolygon->mvPointsAndFlags[i].first);
         pPt->X() += nHorzMove;
         pPt->Y() += nVertMove;
     }
@@ -412,10 +228,9 @@ void XPolygon::Move( long nHorzMove, long nVertMove )
 
 tools::Rectangle XPolygon::GetBoundRect() const
 {
-    pImpXPolygon->CheckPointDelete();
     tools::Rectangle aRetval;
 
-    if(pImpXPolygon->nPoints)
+    if(pImpXPolygon->mvPointsAndFlags.size())
     {
         // #i37709#
         // For historical reasons the control points are not part of the
@@ -434,25 +249,12 @@ tools::Rectangle XPolygon::GetBoundRect() const
 
 const Point& XPolygon::operator[]( sal_uInt16 nPos ) const
 {
-    DBG_ASSERT(nPos < pImpXPolygon->nPoints, "Invalid index at const array access to XPolygon");
-
-    pImpXPolygon->CheckPointDelete();
-    return pImpXPolygon->pPointAry[nPos];
+    return pImpXPolygon->mvPointsAndFlags[nPos].first;
 }
 
 Point& XPolygon::operator[]( sal_uInt16 nPos )
 {
-    pImpXPolygon->CheckPointDelete();
-
-    if( nPos >= pImpXPolygon->nSize )
-    {
-        DBG_ASSERT(pImpXPolygon->nResize, "Invalid index at array access to XPolygon");
-        pImpXPolygon->Resize(nPos + 1, false);
-    }
-    if( nPos >= pImpXPolygon->nPoints )
-        pImpXPolygon->nPoints = nPos + 1;
-
-    return pImpXPolygon->pPointAry[nPos];
+    return pImpXPolygon->mvPointsAndFlags[nPos].first;
 }
 
 XPolygon& XPolygon::operator=( const XPolygon& rXPoly )
@@ -469,34 +271,31 @@ XPolygon& XPolygon::operator=( XPolygon&& rXPoly )
 
 bool XPolygon::operator==( const XPolygon& rXPoly ) const
 {
-    pImpXPolygon->CheckPointDelete();
     return rXPoly.pImpXPolygon == pImpXPolygon;
 }
 
 /// get the flags for the point at the given position
 PolyFlags XPolygon::GetFlags( sal_uInt16 nPos ) const
 {
-    pImpXPolygon->CheckPointDelete();
-    return pImpXPolygon->pFlagAry[nPos];
+    return pImpXPolygon->mvPointsAndFlags[nPos].second;
 }
 
 /// set the flags for the point at the given position
 void XPolygon::SetFlags( sal_uInt16 nPos, PolyFlags eFlags )
 {
-    pImpXPolygon->CheckPointDelete();
-    pImpXPolygon->pFlagAry[nPos] = eFlags;
+    pImpXPolygon->mvPointsAndFlags[nPos].second = eFlags;
 }
 
 /// short path to read the CONTROL flag directly (TODO: better explain what the sense behind this flag is!)
 bool XPolygon::IsControl(sal_uInt16 nPos) const
 {
-    return pImpXPolygon->pFlagAry[nPos] == PolyFlags::Control;
+    return pImpXPolygon->mvPointsAndFlags[nPos].second == PolyFlags::Control;
 }
 
 /// short path to read the SMOOTH and SYMMTR flag directly (TODO: better explain what the sense behind these flags is!)
 bool XPolygon::IsSmooth(sal_uInt16 nPos) const
 {
-    PolyFlags eFlag = pImpXPolygon->pFlagAry[nPos];
+    PolyFlags eFlag = pImpXPolygon->mvPointsAndFlags[nPos].second;
     return ( eFlag == PolyFlags::Smooth || eFlag == PolyFlags::Symmetric );
 }
 
@@ -507,8 +306,8 @@ bool XPolygon::IsSmooth(sal_uInt16 nPos) const
  */
 double XPolygon::CalcDistance(sal_uInt16 nP1, sal_uInt16 nP2)
 {
-    const Point& rP1 = pImpXPolygon->pPointAry[nP1];
-    const Point& rP2 = pImpXPolygon->pPointAry[nP2];
+    const Point& rP1 = pImpXPolygon->mvPointsAndFlags[nP1].first;
+    const Point& rP2 = pImpXPolygon->mvPointsAndFlags[nP2].first;
     double fDx = rP2.X() - rP1.X();
     double fDy = rP2.Y() - rP1.Y();
     return sqrt(fDx * fDx + fDy * fDy);
@@ -516,7 +315,7 @@ double XPolygon::CalcDistance(sal_uInt16 nP1, sal_uInt16 nP2)
 
 void XPolygon::SubdivideBezier(sal_uInt16 nPos, bool bCalcFirst, double fT)
 {
-    Point*  pPoints = pImpXPolygon->pPointAry;
+    auto &  rPoints = pImpXPolygon->mvPointsAndFlags;
     double  fT2 = fT * fT;
     double  fT3 = fT * fT2;
     double  fU = 1.0 - fT;
@@ -536,28 +335,28 @@ void XPolygon::SubdivideBezier(sal_uInt16 nPos, bool bCalcFirst, double fT)
         nPosInc = 1;
         nIdxInc = 1;
     }
-    pPoints[nPos].X() = static_cast<long>(fU3 *       pPoints[nIdx  ].X() +
-                                fT  * fU2 * pPoints[nIdx+1].X() * 3 +
-                                fT2 * fU  * pPoints[nIdx+2].X() * 3 +
-                                fT3 *       pPoints[nIdx+3].X());
-    pPoints[nPos].Y() = static_cast<long>(fU3 *       pPoints[nIdx  ].Y() +
-                                fT  * fU2 * pPoints[nIdx+1].Y() * 3 +
-                                fT2 * fU  * pPoints[nIdx+2].Y() * 3 +
-                                fT3 *       pPoints[nIdx+3].Y());
+    rPoints[nPos].first.X() = static_cast<long>(fU3 *       rPoints[nIdx  ].first.X() +
+                                fT  * fU2 * rPoints[nIdx+1].first.X() * 3 +
+                                fT2 * fU  * rPoints[nIdx+2].first.X() * 3 +
+                                fT3 *       rPoints[nIdx+3].first.X());
+    rPoints[nPos].first.Y() = static_cast<long>(fU3 *       rPoints[nIdx  ].first.Y() +
+                                fT  * fU2 * rPoints[nIdx+1].first.Y() * 3 +
+                                fT2 * fU  * rPoints[nIdx+2].first.Y() * 3 +
+                                fT3 *       rPoints[nIdx+3].first.Y());
     nPos = nPos + nPosInc;
     nIdx = nIdx + nIdxInc;
-    pPoints[nPos].X() = static_cast<long>(fU2 *       pPoints[nIdx  ].X() +
-                                fT  * fU *  pPoints[nIdx+1].X() * 2 +
-                                fT2 *       pPoints[nIdx+2].X());
-    pPoints[nPos].Y() = static_cast<long>(fU2 *       pPoints[nIdx  ].Y() +
-                                fT  * fU *  pPoints[nIdx+1].Y() * 2 +
-                                fT2 *       pPoints[nIdx+2].Y());
+    rPoints[nPos].first.X() = static_cast<long>(fU2 *       rPoints[nIdx  ].first.X() +
+                                fT  * fU *  rPoints[nIdx+1].first.X() * 2 +
+                                fT2 *       rPoints[nIdx+2].first.X());
+    rPoints[nPos].first.Y() = static_cast<long>(fU2 *       rPoints[nIdx  ].first.Y() +
+                                fT  * fU *  rPoints[nIdx+1].first.Y() * 2 +
+                                fT2 *       rPoints[nIdx+2].first.Y());
     nPos = nPos + nPosInc;
     nIdx = nIdx + nIdxInc;
-    pPoints[nPos].X() = static_cast<long>(fU * pPoints[nIdx  ].X() +
-                                fT * pPoints[nIdx+1].X());
-    pPoints[nPos].Y() = static_cast<long>(fU * pPoints[nIdx  ].Y() +
-                                fT * pPoints[nIdx+1].Y());
+    rPoints[nPos].first.X() = static_cast<long>(fU * rPoints[nIdx  ].first.X() +
+                                fT * rPoints[nIdx+1].first.X());
+    rPoints[nPos].first.Y() = static_cast<long>(fU * rPoints[nIdx  ].first.Y() +
+                                fT * rPoints[nIdx+1].first.Y());
 }
 
 /// Generate a Bézier arc
@@ -565,9 +364,9 @@ void XPolygon::GenBezArc(const Point& rCenter, long nRx, long nRy,
                          long nXHdl, long nYHdl, sal_uInt16 nStart, sal_uInt16 nEnd,
                          sal_uInt16 nQuad, sal_uInt16 nFirst)
 {
-    Point* pPoints = pImpXPolygon->pPointAry;
-    pPoints[nFirst  ] = rCenter;
-    pPoints[nFirst+3] = rCenter;
+    auto& rPoints = pImpXPolygon->mvPointsAndFlags;
+    rPoints[nFirst  ].first = rCenter;
+    rPoints[nFirst+3].first = rCenter;
 
     if ( nQuad == 1 || nQuad == 2 )
     {
@@ -580,22 +379,22 @@ void XPolygon::GenBezArc(const Point& rCenter, long nRx, long nRy,
 
     if ( nQuad == 0 || nQuad == 2 )
     {
-        pPoints[nFirst].X() += nRx; pPoints[nFirst+3].Y() += nRy;
+        rPoints[nFirst].first.X() += nRx; rPoints[nFirst+3].first.Y() += nRy;
     }
     else
     {
-        pPoints[nFirst].Y() += nRy; pPoints[nFirst+3].X() += nRx;
+        rPoints[nFirst].first.Y() += nRy; rPoints[nFirst+3].first.X() += nRx;
     }
-    pPoints[nFirst+1] = pPoints[nFirst];
-    pPoints[nFirst+2] = pPoints[nFirst+3];
+    rPoints[nFirst+1] = rPoints[nFirst];
+    rPoints[nFirst+2] = rPoints[nFirst+3];
 
     if ( nQuad == 0 || nQuad == 2 )
     {
-        pPoints[nFirst+1].Y() += nYHdl; pPoints[nFirst+2].X() += nXHdl;
+        rPoints[nFirst+1].first.Y() += nYHdl; rPoints[nFirst+2].first.X() += nXHdl;
     }
     else
     {
-        pPoints[nFirst+1].X() += nXHdl; pPoints[nFirst+2].Y() += nYHdl;
+        rPoints[nFirst+1].first.X() += nXHdl; rPoints[nFirst+2].first.Y() += nYHdl;
     }
     if ( nStart > 0 )
         SubdivideBezier(nFirst, false, static_cast<double>(nStart) / 900);
@@ -643,8 +442,8 @@ void XPolygon::CalcSmoothJoin(sal_uInt16 nCenter, sal_uInt16 nDrag, sal_uInt16 n
         nDrag = nPnt;
         nPnt = nTmp;
     }
-    Point*  pPoints = pImpXPolygon->pPointAry;
-    Point   aDiff   = pPoints[nDrag] - pPoints[nCenter];
+    auto&   rPoints = pImpXPolygon->mvPointsAndFlags;
+    Point   aDiff   = rPoints[nDrag].first - rPoints[nCenter].first;
     double  fDiv    = CalcDistance(nCenter, nDrag);
 
     if ( fDiv )
@@ -656,7 +455,7 @@ void XPolygon::CalcSmoothJoin(sal_uInt16 nCenter, sal_uInt16 nDrag, sal_uInt16 n
             aDiff.X() = static_cast<long>(fRatio * aDiff.X());
             aDiff.Y() = static_cast<long>(fRatio * aDiff.Y());
         }
-        pPoints[nPnt] = pPoints[nCenter] - aDiff;
+        rPoints[nPnt].first = rPoints[nCenter].first - aDiff;
     }
 }
 
@@ -673,9 +472,9 @@ void XPolygon::CalcTangent(sal_uInt16 nCenter, sal_uInt16 nPrev, sal_uInt16 nNex
     if ( !fAbsLen )
         return;
 
-    const Point& rCenter = pImpXPolygon->pPointAry[nCenter];
-    Point&  rNext = pImpXPolygon->pPointAry[nNext];
-    Point&  rPrev = pImpXPolygon->pPointAry[nPrev];
+    const Point& rCenter = pImpXPolygon->mvPointsAndFlags[nCenter].first;
+    Point&  rNext = pImpXPolygon->mvPointsAndFlags[nNext].first;
+    Point&  rPrev = pImpXPolygon->mvPointsAndFlags[nPrev].first;
     Point   aDiff = rNext - rPrev;
     double  fNextLen = CalcDistance(nCenter, nNext) / fAbsLen;
     double  fPrevLen = CalcDistance(nCenter, nPrev) / fAbsLen;
@@ -699,20 +498,20 @@ void XPolygon::PointsToBezier(sal_uInt16 nFirst)
     double  fX0, fY0, fX1, fY1, fX2, fY2, fX3, fY3;
     double  fTx1, fTx2, fTy1, fTy2;
     double  fT1, fU1, fT2, fU2, fV;
-    Point*  pPoints = pImpXPolygon->pPointAry;
+    auto&   rPoints = pImpXPolygon->mvPointsAndFlags;
 
-    if ( nFirst > pImpXPolygon->nPoints - 4 || IsControl(nFirst) ||
+    if ( nFirst > pImpXPolygon->mvPointsAndFlags.size() - 4 || IsControl(nFirst) ||
          IsControl(nFirst+1) || IsControl(nFirst+2) || IsControl(nFirst+3) )
         return;
 
-    fTx1 = pPoints[nFirst+1].X();
-    fTy1 = pPoints[nFirst+1].Y();
-    fTx2 = pPoints[nFirst+2].X();
-    fTy2 = pPoints[nFirst+2].Y();
-    fX0  = pPoints[nFirst  ].X();
-    fY0  = pPoints[nFirst  ].Y();
-    fX3  = pPoints[nFirst+3].X();
-    fY3  = pPoints[nFirst+3].Y();
+    fTx1 = rPoints[nFirst+1].first.X();
+    fTy1 = rPoints[nFirst+1].first.Y();
+    fTx2 = rPoints[nFirst+2].first.X();
+    fTy2 = rPoints[nFirst+2].first.Y();
+    fX0  = rPoints[nFirst  ].first.X();
+    fY0  = rPoints[nFirst  ].first.Y();
+    fX3  = rPoints[nFirst+3].first.X();
+    fY3  = rPoints[nFirst+3].first.Y();
 
     nPart1Length = CalcDistance(nFirst, nFirst+1);
     nPart2Length = nPart1Length + CalcDistance(nFirst+1, nFirst+2);
@@ -753,8 +552,8 @@ void XPolygon::PointsToBezier(sal_uInt16 nFirst)
     fY2 -= fY1 * fU2 / fT2;
     fY2 -= fY3 * fT2 / (fU2 * 3);
 
-    pPoints[nFirst+1] = Point(static_cast<long>(fX1), static_cast<long>(fY1));
-    pPoints[nFirst+2] = Point(static_cast<long>(fX2), static_cast<long>(fY2));
+    rPoints[nFirst+1].first = Point(static_cast<long>(fX1), static_cast<long>(fY1));
+    rPoints[nFirst+2].first = Point(static_cast<long>(fX2), static_cast<long>(fY2));
     SetFlags(nFirst+1, PolyFlags::Control);
     SetFlags(nFirst+2, PolyFlags::Control);
 }
@@ -762,13 +561,11 @@ void XPolygon::PointsToBezier(sal_uInt16 nFirst)
 /// scale in X- and/or Y-direction
 void XPolygon::Scale(double fSx, double fSy)
 {
-    pImpXPolygon->CheckPointDelete();
-
-    sal_uInt16 nPntCnt = pImpXPolygon->nPoints;
+    sal_uInt16 nPntCnt = pImpXPolygon->mvPointsAndFlags.size();
 
     for (sal_uInt16 i = 0; i < nPntCnt; i++)
     {
-        Point& rPnt = pImpXPolygon->pPointAry[i];
+        Point& rPnt = pImpXPolygon->mvPointsAndFlags[i].first;
         rPnt.X() = static_cast<long>(fSx * rPnt.X());
         rPnt.Y() = static_cast<long>(fSy * rPnt.Y());
     }
@@ -787,8 +584,6 @@ void XPolygon::Scale(double fSx, double fSy)
 void XPolygon::Distort(const tools::Rectangle& rRefRect,
                        const XPolygon& rDistortedRect)
 {
-    pImpXPolygon->CheckPointDelete();
-
     long    Xr, Wr;
     long    Yr, Hr;
 
@@ -802,7 +597,7 @@ void XPolygon::Distort(const tools::Rectangle& rRefRect,
 
     long    X1, X2, X3, X4;
     long    Y1, Y2, Y3, Y4;
-    DBG_ASSERT(rDistortedRect.pImpXPolygon->nPoints >= 4,
+    DBG_ASSERT(rDistortedRect.pImpXPolygon->mvPointsAndFlags.size() >= 4,
                "Distort: rectangle to small");
 
     X1 = rDistortedRect[0].X();
@@ -814,12 +609,12 @@ void XPolygon::Distort(const tools::Rectangle& rRefRect,
     X4 = rDistortedRect[2].X();
     Y4 = rDistortedRect[2].Y();
 
-    sal_uInt16 nPntCnt = pImpXPolygon->nPoints;
+    sal_uInt16 nPntCnt = pImpXPolygon->mvPointsAndFlags.size();
 
     for (sal_uInt16 i = 0; i < nPntCnt; i++)
     {
         double  fTx, fTy, fUx, fUy;
-        Point& rPnt = pImpXPolygon->pPointAry[i];
+        Point& rPnt = pImpXPolygon->mvPointsAndFlags[i].first;
 
         fTx = static_cast<double>(rPnt.X() - Xr) / Wr;
         fTy = static_cast<double>(rPnt.Y() - Yr) / Hr;
@@ -838,7 +633,7 @@ basegfx::B2DPolygon XPolygon::getB2DPolygon() const
     // #i74631# use tools Polygon class for conversion to not have the code doubled
     // here. This needs one more conversion but avoids different convertors in
     // the long run
-    const tools::Polygon aSource(GetPointCount(), pImpXPolygon->pPointAry, pImpXPolygon->pFlagAry.get());
+    const tools::Polygon aSource(pImpXPolygon->mvPointsAndFlags);
 
     return aSource.getB2DPolygon();
 }
@@ -852,12 +647,12 @@ XPolygon::XPolygon(const basegfx::B2DPolygon& rPolygon)
 
     const tools::Polygon aSource(rPolygon);
     sal_uInt16 nSize = aSource.GetSize();
-    pImpXPolygon->nPoints = nSize;
+    pImpXPolygon->mvPointsAndFlags.resize(nSize);
 
     for( sal_uInt16 i = 0; i < nSize;  i++ )
     {
-        pImpXPolygon->pPointAry[i] = aSource[i];
-        pImpXPolygon->pFlagAry[i] = aSource.GetFlags( i );
+        pImpXPolygon->mvPointsAndFlags[i].first = aSource[i];
+        pImpXPolygon->mvPointsAndFlags[i].second = aSource.GetFlags( i );
     }
 }
 
diff --git a/tools/inc/poly.h b/tools/inc/poly.h
index 88da80ca1615..3c7b0c923465 100644
--- a/tools/inc/poly.h
+++ b/tools/inc/poly.h
@@ -35,6 +35,7 @@ public:
                     ImplPolygon() : mnPoints(0) {}
                     ImplPolygon( sal_uInt16 nInitSize, bool bFlags = false );
                     ImplPolygon( sal_uInt16 nPoints, const Point* pPtAry, const PolyFlags* pInitFlags );
+                    ImplPolygon( std::vector< std::pair<Point, PolyFlags> > const & );
                     ImplPolygon( const ImplPolygon& rImplPoly );
                     ImplPolygon( const tools::Rectangle& rRect );
                     ImplPolygon( const tools::Rectangle& rRect, sal_uInt32 nHorzRound, sal_uInt32 nVertRound);
diff --git a/tools/source/generic/poly.cxx b/tools/source/generic/poly.cxx
index 3c78b5a04bc8..b88c411a927b 100644
--- a/tools/source/generic/poly.cxx
+++ b/tools/source/generic/poly.cxx
@@ -100,6 +100,24 @@ ImplPolygon::ImplPolygon( sal_uInt16 nInitSize, const Point* pInitAry, const Pol
     mnPoints   = nInitSize;
 }
 
+ImplPolygon::ImplPolygon( std::vector< std::pair<Point, PolyFlags> > const & rPointsAndFlags )
+{
+    auto nInitSize = rPointsAndFlags.size();
+    if ( nInitSize )
+    {
+        mxPointAry.reset(new Point[nInitSize]);
+        mxFlagAry.reset(new PolyFlags[nInitSize]);
+        int i = 0;
+        for (auto const & rPair : rPointsAndFlags) {
+            mxPointAry[i] = rPair.first;
+            mxFlagAry[i] = rPair.second;
+            ++i;
+        }
+    }
+
+    mnPoints   = nInitSize;
+}
+
 ImplPolygon::ImplPolygon( const tools::Rectangle& rRect )
 {
     if ( !rRect.IsEmpty() )
@@ -868,6 +886,10 @@ Polygon::Polygon( sal_uInt16 nPoints, const Point* pPtAry, const PolyFlags* pFla
 {
 }
 
+Polygon::Polygon( std::vector< std::pair<Point, PolyFlags> > const & rPointsAndFlags ) : mpImplPolygon(ImplPolygon(rPointsAndFlags))
+{
+}
+
 Polygon::Polygon( const tools::Polygon& rPoly ) : mpImplPolygon(rPoly.mpImplPolygon)
 {
 }


More information about the Libreoffice-commits mailing list