diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2018-02-05 15:56:12 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2018-02-06 12:47:32 +0100 |
commit | f9c2bcc8b761f5e21354c0fb7bca6aa432d11ec2 (patch) | |
tree | a40dbc3e6d1b7476ad93cee29f19590103c4e756 | |
parent | e1f479af4ddde90f9e80b5079ac759cb9f7743a1 (diff) |
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@libreoffice.org>
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
-rw-r--r-- | filter/source/msfilter/escherex.cxx | 6 | ||||
-rw-r--r-- | include/svx/xpoly.hxx | 9 | ||||
-rw-r--r-- | include/tools/poly.hxx | 1 | ||||
-rw-r--r-- | svx/inc/xpolyimp.hxx | 27 | ||||
-rw-r--r-- | svx/source/svdraw/svdoedge.cxx | 21 | ||||
-rw-r--r-- | svx/source/xoutdev/_xpoly.cxx | 401 | ||||
-rw-r--r-- | tools/inc/poly.h | 1 | ||||
-rw-r--r-- | tools/source/generic/poly.cxx | 22 |
8 files changed, 152 insertions, 336 deletions
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) { } |