summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXisco Fauli <anistenis@gmail.com>2016-06-30 01:11:39 +0200
committerNoel Grandin <noelgrandin@gmail.com>2016-07-13 07:01:12 +0000
commit7346a0cbea43f49578c5209da1416aa0b27fbddb (patch)
tree9f683b176040817e24f7ca506c3ec4a74c0fe0d2
parenta54d466edc456be5dfd5c695c6b99f570e228916 (diff)
tdf#62525 vcl: use cow_wrapper for ImpXPolygon
Change-Id: If3596f7b2b546f360774e995867d18c9ba543737 Reviewed-on: https://gerrit.libreoffice.org/26785 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noelgrandin@gmail.com>
-rw-r--r--include/svx/xpoly.hxx6
-rw-r--r--svx/inc/xpolyimp.hxx10
-rw-r--r--svx/source/xoutdev/_xpoly.cxx87
3 files changed, 31 insertions, 72 deletions
diff --git a/include/svx/xpoly.hxx b/include/svx/xpoly.hxx
index 8015ac346e2c..e68d89dd4420 100644
--- a/include/svx/xpoly.hxx
+++ b/include/svx/xpoly.hxx
@@ -21,6 +21,7 @@
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <svx/svxdllapi.h>
+#include <o3tl/cow_wrapper.hxx>
class Point;
class Rectangle;
@@ -50,10 +51,7 @@ class ImpXPolygon;
class SVX_DLLPUBLIC XPolygon
{
protected:
- ImpXPolygon* pImpXPolygon;
-
- // check ImpXPolygon-ReferenceCount and decouple if necessary
- void CheckReference();
+ o3tl::cow_wrapper< ImpXPolygon > pImpXPolygon;
// auxiliary functions for Bezier conversion
void SubdivideBezier(sal_uInt16 nPos, bool bCalcFirst, double fT);
diff --git a/svx/inc/xpolyimp.hxx b/svx/inc/xpolyimp.hxx
index 49a332c6d4f8..bf6acd47a047 100644
--- a/svx/inc/xpolyimp.hxx
+++ b/svx/inc/xpolyimp.hxx
@@ -35,7 +35,6 @@ public:
sal_uInt16 nSize;
sal_uInt16 nResize;
sal_uInt16 nPoints;
- sal_uInt16 nRefCount;
ImpXPolygon( sal_uInt16 nInitSize = 16, sal_uInt16 nResize=16 );
ImpXPolygon( const ImpXPolygon& rImpXPoly );
@@ -43,14 +42,7 @@ public:
bool operator==(const ImpXPolygon& rImpXPoly) const;
- void CheckPointDelete()
- {
- if ( bDeleteOldPoints )
- {
- delete[] reinterpret_cast<char*>(pOldPointAry);
- bDeleteOldPoints = false;
- }
- }
+ void CheckPointDelete() const;
void Resize( sal_uInt16 nNewSize, bool bDeletePoints = true );
void InsertSpace( sal_uInt16 nPos, sal_uInt16 nCount );
diff --git a/svx/source/xoutdev/_xpoly.cxx b/svx/source/xoutdev/_xpoly.cxx
index de87258087c8..309411668456 100644
--- a/svx/source/xoutdev/_xpoly.cxx
+++ b/svx/source/xoutdev/_xpoly.cxx
@@ -42,7 +42,6 @@ ImpXPolygon::ImpXPolygon(sal_uInt16 nInitSize, sal_uInt16 _nResize)
, nSize(0)
, nResize(_nResize)
, nPoints(0)
- , nRefCount(1)
{
Resize(nInitSize);
}
@@ -55,9 +54,8 @@ ImpXPolygon::ImpXPolygon( const ImpXPolygon& rImpXPoly )
, nSize(0)
, nResize(rImpXPoly.nResize)
, nPoints(0)
- , nRefCount(1)
{
- ( (ImpXPolygon&) rImpXPoly ).CheckPointDelete();
+ rImpXPoly.CheckPointDelete();
Resize( rImpXPoly.nSize );
@@ -72,7 +70,10 @@ ImpXPolygon::~ImpXPolygon()
delete[] reinterpret_cast<char*>(pPointAry);
delete[] pFlagAry;
if ( bDeleteOldPoints )
+ {
delete[] reinterpret_cast<char*>(pOldPointAry);
+ pOldPointAry = nullptr;
+ }
}
bool ImpXPolygon::operator==(const ImpXPolygon& rImpXPoly) const
@@ -135,8 +136,13 @@ void ImpXPolygon::Resize( sal_uInt16 nNewSize, bool bDeletePoints )
if( nPoints > nSize )
nPoints = nSize;
}
- if ( bDeletePoints ) delete[] reinterpret_cast<char*>(pOldPointAry);
- else bDeleteOldPoints = true;
+ if ( bDeletePoints )
+ {
+ delete[] reinterpret_cast<char*>(pOldPointAry);
+ pOldPointAry = nullptr;
+ }
+ else
+ bDeleteOldPoints = true;
delete[] pOldFlagAry;
}
}
@@ -186,23 +192,31 @@ void ImpXPolygon::Remove( sal_uInt16 nPos, sal_uInt16 nCount )
}
}
+void ImpXPolygon::CheckPointDelete() const
+{
+ if ( bDeleteOldPoints )
+ {
+ delete[] reinterpret_cast<char*>(pOldPointAry);
+ const_cast< ImpXPolygon* >(this)->pOldPointAry = nullptr;
+ const_cast< ImpXPolygon* >(this)->bDeleteOldPoints = false;
+ }
+}
+
XPolygon::XPolygon( sal_uInt16 nSize, sal_uInt16 nResize )
+ : pImpXPolygon( ImpXPolygon( nSize, nResize ) )
{
- pImpXPolygon = new ImpXPolygon( nSize, nResize );
}
XPolygon::XPolygon( const XPolygon& rXPoly )
+ : pImpXPolygon(rXPoly.pImpXPolygon)
{
- pImpXPolygon = rXPoly.pImpXPolygon;
- pImpXPolygon->nRefCount++;
}
/// create a XPolygon out of a standard polygon
XPolygon::XPolygon( const tools::Polygon& rPoly )
+ : pImpXPolygon( rPoly.GetSize() )
{
-
sal_uInt16 nSize = rPoly.GetSize();
- pImpXPolygon = new ImpXPolygon( nSize );
pImpXPolygon->nPoints = nSize;
for( sal_uInt16 i = 0; i < nSize; i++ )
@@ -214,8 +228,8 @@ XPolygon::XPolygon( const tools::Polygon& rPoly )
/// create a rectangle (also with rounded corners) as a Bézier polygon
XPolygon::XPolygon(const Rectangle& rRect, long nRx, long nRy)
+ : pImpXPolygon( 17 )
{
- pImpXPolygon = new ImpXPolygon(17);
long nWh = (rRect.GetWidth() - 1) / 2;
long nHh = (rRect.GetHeight() - 1) / 2;
@@ -275,9 +289,8 @@ XPolygon::XPolygon(const Rectangle& rRect, long nRx, long nRy)
/// create a ellipse (curve) as Bézier polygon
XPolygon::XPolygon(const Point& rCenter, long nRx, long nRy,
sal_uInt16 nStartAngle, sal_uInt16 nEndAngle, bool bClose)
+ : pImpXPolygon( 17 )
{
- pImpXPolygon = new ImpXPolygon(17);
-
nStartAngle %= 3600;
if ( nEndAngle > 3600 ) nEndAngle %= 3600;
bool bFull = (nStartAngle == 0 && nEndAngle == 3600);
@@ -315,26 +328,11 @@ XPolygon::XPolygon(const Point& rCenter, long nRx, long nRy,
XPolygon::~XPolygon()
{
- if( pImpXPolygon->nRefCount > 1 )
- pImpXPolygon->nRefCount--;
- else
- delete pImpXPolygon;
-}
-
-/// check reference counter and decouple if > 1
-void XPolygon::CheckReference()
-{
- if( pImpXPolygon->nRefCount > 1 )
- {
- pImpXPolygon->nRefCount--;
- pImpXPolygon = new ImpXPolygon( *pImpXPolygon );
- }
}
void XPolygon::SetPointCount( sal_uInt16 nPoints )
{
pImpXPolygon->CheckPointDelete();
- CheckReference();
if( pImpXPolygon->nSize < nPoints )
pImpXPolygon->Resize( nPoints );
@@ -362,7 +360,6 @@ sal_uInt16 XPolygon::GetPointCount() const
void XPolygon::Insert( sal_uInt16 nPos, const Point& rPt, XPolyFlags eFlags )
{
- CheckReference();
if (nPos>pImpXPolygon->nPoints) nPos=pImpXPolygon->nPoints;
pImpXPolygon->InsertSpace( nPos, 1 );
pImpXPolygon->pPointAry[nPos] = rPt;
@@ -371,7 +368,6 @@ void XPolygon::Insert( sal_uInt16 nPos, const Point& rPt, XPolyFlags eFlags )
void XPolygon::Insert( sal_uInt16 nPos, const XPolygon& rXPoly )
{
- CheckReference();
if (nPos>pImpXPolygon->nPoints) nPos=pImpXPolygon->nPoints;
sal_uInt16 nPoints = rXPoly.GetPointCount();
@@ -388,7 +384,6 @@ void XPolygon::Insert( sal_uInt16 nPos, const XPolygon& rXPoly )
void XPolygon::Remove( sal_uInt16 nPos, sal_uInt16 nCount )
{
- CheckReference();
pImpXPolygon->Remove( nPos, nCount );
}
@@ -397,8 +392,6 @@ void XPolygon::Move( long nHorzMove, long nVertMove )
if ( !nHorzMove && !nVertMove )
return;
- CheckReference();
-
// move points
sal_uInt16 nCount = pImpXPolygon->nPoints;
for ( sal_uInt16 i = 0; i < nCount; i++ )
@@ -442,7 +435,6 @@ const Point& XPolygon::operator[]( sal_uInt16 nPos ) const
Point& XPolygon::operator[]( sal_uInt16 nPos )
{
pImpXPolygon->CheckPointDelete();
- CheckReference();
if( nPos >= pImpXPolygon->nSize )
{
@@ -457,18 +449,6 @@ Point& XPolygon::operator[]( sal_uInt16 nPos )
XPolygon& XPolygon::operator=( const XPolygon& rXPoly )
{
- if (this == &rXPoly)
- return *this;
-
- pImpXPolygon->CheckPointDelete();
-
- rXPoly.pImpXPolygon->nRefCount++;
-
- if( pImpXPolygon->nRefCount > 1 )
- pImpXPolygon->nRefCount--;
- else
- delete pImpXPolygon;
-
pImpXPolygon = rXPoly.pImpXPolygon;
return *this;
}
@@ -476,8 +456,7 @@ XPolygon& XPolygon::operator=( const XPolygon& rXPoly )
bool XPolygon::operator==( const XPolygon& rXPoly ) const
{
pImpXPolygon->CheckPointDelete();
- if (rXPoly.pImpXPolygon==pImpXPolygon) return true;
- return *rXPoly.pImpXPolygon == *pImpXPolygon;
+ return rXPoly.pImpXPolygon == pImpXPolygon;
}
/// get the flags for the point at the given position
@@ -491,7 +470,6 @@ XPolyFlags XPolygon::GetFlags( sal_uInt16 nPos ) const
void XPolygon::SetFlags( sal_uInt16 nPos, XPolyFlags eFlags )
{
pImpXPolygon->CheckPointDelete();
- CheckReference();
pImpXPolygon->pFlagAry[nPos] = (sal_uInt8) eFlags;
}
@@ -643,8 +621,6 @@ bool XPolygon::CheckAngles(sal_uInt16& nStart, sal_uInt16 nEnd, sal_uInt16& nA1,
*/
void XPolygon::CalcSmoothJoin(sal_uInt16 nCenter, sal_uInt16 nDrag, sal_uInt16 nPnt)
{
- CheckReference();
-
// If nPoint is no control point, i.e. cannot be moved, than
// move nDrag instead on the line between nCenter and nPnt
if ( !IsControl(nPnt) )
@@ -678,8 +654,6 @@ void XPolygon::CalcSmoothJoin(sal_uInt16 nCenter, sal_uInt16 nDrag, sal_uInt16 n
*/
void XPolygon::CalcTangent(sal_uInt16 nCenter, sal_uInt16 nPrev, sal_uInt16 nNext)
{
- CheckReference();
-
double fAbsLen = CalcDistance(nNext, nPrev);
if ( fAbsLen )
@@ -717,8 +691,6 @@ void XPolygon::PointsToBezier(sal_uInt16 nFirst)
IsControl(nFirst+1) || IsControl(nFirst+2) || IsControl(nFirst+3) )
return;
- CheckReference();
-
fTx1 = pPoints[nFirst+1].X();
fTy1 = pPoints[nFirst+1].Y();
fTx2 = pPoints[nFirst+2].X();
@@ -777,7 +749,6 @@ void XPolygon::PointsToBezier(sal_uInt16 nFirst)
void XPolygon::Scale(double fSx, double fSy)
{
pImpXPolygon->CheckPointDelete();
- CheckReference();
sal_uInt16 nPntCnt = pImpXPolygon->nPoints;
@@ -803,7 +774,6 @@ void XPolygon::Distort(const Rectangle& rRefRect,
const XPolygon& rDistortedRect)
{
pImpXPolygon->CheckPointDelete();
- CheckReference();
long Xr, Wr;
long Yr, Hr;
@@ -854,13 +824,13 @@ 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
- DBG_ASSERT(pImpXPolygon != nullptr, "XPolygon::getB2DPolygon(): XPolygon has no implementation incarnated (!)");
const tools::Polygon aSource(GetPointCount(), pImpXPolygon->pPointAry, pImpXPolygon->pFlagAry);
return aSource.getB2DPolygon();
}
XPolygon::XPolygon(const basegfx::B2DPolygon& rPolygon)
+ : pImpXPolygon( tools::Polygon( rPolygon ).GetSize() )
{
// #i74631# use tools Polygon class for conversion to not have the code doubled
// here. This needs one more conversion but avoids different convertors in
@@ -868,7 +838,6 @@ XPolygon::XPolygon(const basegfx::B2DPolygon& rPolygon)
const tools::Polygon aSource(rPolygon);
sal_uInt16 nSize = aSource.GetSize();
- pImpXPolygon = new ImpXPolygon( nSize );
pImpXPolygon->nPoints = nSize;
for( sal_uInt16 i = 0; i < nSize; i++ )