From 7346a0cbea43f49578c5209da1416aa0b27fbddb Mon Sep 17 00:00:00 2001 From: Xisco Fauli Date: Thu, 30 Jun 2016 01:11:39 +0200 Subject: tdf#62525 vcl: use cow_wrapper for ImpXPolygon Change-Id: If3596f7b2b546f360774e995867d18c9ba543737 Reviewed-on: https://gerrit.libreoffice.org/26785 Tested-by: Jenkins Reviewed-by: Noel Grandin --- include/svx/xpoly.hxx | 6 +-- svx/inc/xpolyimp.hxx | 10 +---- svx/source/xoutdev/_xpoly.cxx | 87 ++++++++++++++----------------------------- 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 #include +#include 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(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(pPointAry); delete[] pFlagAry; if ( bDeleteOldPoints ) + { delete[] reinterpret_cast(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(pOldPointAry); - else bDeleteOldPoints = true; + if ( bDeletePoints ) + { + delete[] reinterpret_cast(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(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++ ) -- cgit