summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2018-02-05 15:56:12 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2018-02-06 12:47:32 +0100
commitf9c2bcc8b761f5e21354c0fb7bca6aa432d11ec2 (patch)
treea40dbc3e6d1b7476ad93cee29f19590103c4e756
parente1f479af4ddde90f9e80b5079ac759cb9f7743a1 (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.cxx6
-rw-r--r--include/svx/xpoly.hxx9
-rw-r--r--include/tools/poly.hxx1
-rw-r--r--svx/inc/xpolyimp.hxx27
-rw-r--r--svx/source/svdraw/svdoedge.cxx21
-rw-r--r--svx/source/xoutdev/_xpoly.cxx401
-rw-r--r--tools/inc/poly.h1
-rw-r--r--tools/source/generic/poly.cxx22
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)
{
}