summaryrefslogtreecommitdiff
path: root/vcl/source/gdi/region.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/gdi/region.cxx')
-rwxr-xr-x[-rw-r--r--]vcl/source/gdi/region.cxx435
1 files changed, 305 insertions, 130 deletions
diff --git a/vcl/source/gdi/region.cxx b/vcl/source/gdi/region.cxx
index a00795e2e2ce..480a17a9f88b 100644..100755
--- a/vcl/source/gdi/region.cxx
+++ b/vcl/source/gdi/region.cxx
@@ -41,6 +41,8 @@
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygonclipper.hxx>
+#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
#include <basegfx/range/b2drange.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
@@ -79,19 +81,19 @@ namespace {
bool ImplIsPolygonRectilinear (const PolyPolygon& rPolyPoly)
{
// Iterate over all polygons.
- const USHORT nPolyCount = rPolyPoly.Count();
- for (USHORT nPoly = 0; nPoly < nPolyCount; ++nPoly)
+ const sal_uInt16 nPolyCount = rPolyPoly.Count();
+ for (sal_uInt16 nPoly = 0; nPoly < nPolyCount; ++nPoly)
{
const Polygon& aPoly = rPolyPoly.GetObject(nPoly);
// Iterate over all edges of the current polygon.
- const USHORT nSize = aPoly.GetSize();
+ const sal_uInt16 nSize = aPoly.GetSize();
if (nSize < 2)
continue;
Point aPoint (aPoly.GetPoint(0));
const Point aLastPoint (aPoint);
- for (USHORT nPoint = 1; nPoint < nSize; ++nPoint)
+ for (sal_uInt16 nPoint = 1; nPoint < nSize; ++nPoint)
{
const Point aNextPoint (aPoly.GetPoint(nPoint));
// When there is at least one edge that is neither vertical nor
@@ -183,20 +185,20 @@ ImplRegion* ImplRectilinearPolygonToBands (const PolyPolygon& rPolyPoly)
long nLineId = 0L;
// Iterate over all polygons.
- const USHORT nPolyCount = rPolyPoly.Count();
- for (USHORT nPoly = 0; nPoly < nPolyCount; ++nPoly)
+ const sal_uInt16 nPolyCount = rPolyPoly.Count();
+ for (sal_uInt16 nPoly = 0; nPoly < nPolyCount; ++nPoly)
{
const Polygon& aPoly = rPolyPoly.GetObject(nPoly);
// Iterate over all edges of the current polygon.
- const USHORT nSize = aPoly.GetSize();
+ const sal_uInt16 nSize = aPoly.GetSize();
if (nSize < 2)
continue;
// Avoid fetching every point twice (each point is the start point
// of one and the end point of another edge.)
Point aStart (aPoly.GetPoint(0));
Point aEnd;
- for (USHORT nPoint = 1; nPoint <= nSize; ++nPoint, aStart=aEnd)
+ for (sal_uInt16 nPoint = 1; nPoint <= nSize; ++nPoint, aStart=aEnd)
{
// We take the implicit closing edge into account by mapping
// index nSize to 0.
@@ -262,7 +264,7 @@ ImplRegion* ImplRectilinearPolygonToBands (const PolyPolygon& rPolyPoly)
// Add the x-value as point to all bands in the nTop->nBottom range.
for (pBand=pTopBand; pBand!=NULL&&pBand->mnYTop<=nBottom; pBand=pBand->mpNextBand)
- pBand->InsertPoint(aStart.X(), nLineId++, TRUE, eLineType);
+ pBand->InsertPoint(aStart.X(), nLineId++, sal_True, eLineType);
}
}
@@ -286,19 +288,19 @@ ImplRegion* ImplGeneralPolygonToBands (
pImplRegion->CreateBandRange( rPolygonBoundingBox.Top(), rPolygonBoundingBox.Bottom() );
// insert polygons
- const USHORT nPolyCount = rPolyPoly.Count();
- for ( USHORT nPoly = 0; nPoly < nPolyCount; nPoly++ )
+ const sal_uInt16 nPolyCount = rPolyPoly.Count();
+ for ( sal_uInt16 nPoly = 0; nPoly < nPolyCount; nPoly++ )
{
// get reference to current polygon
const Polygon& aPoly = rPolyPoly.GetObject( nPoly );
- const USHORT nSize = aPoly.GetSize();
+ const sal_uInt16 nSize = aPoly.GetSize();
// not enough points ( <= 2 )? -> nothing to do!
if ( nSize <= 2 )
continue;
// band the polygon
- for ( USHORT nPoint = 1; nPoint < nSize; nPoint++ )
+ for ( sal_uInt16 nPoint = 1; nPoint < nSize; nPoint++ )
pImplRegion->InsertLine( aPoly.GetPoint(nPoint-1), aPoly.GetPoint(nPoint), nLineID++ );
// close polygon with line from first point to last point, if neccesary
@@ -338,7 +340,7 @@ const char* ImplDbgTestRegion( const void* pObj )
if ( (pImplRegion != &aImplEmptyRegion) && (pImplRegion != &aImplNullRegion) )
{
- ULONG nCount = 0;
+ sal_uLong nCount = 0;
const ImplRegionBand* pBand = pImplRegion->ImplGetFirstRegionBand();
while ( pBand )
{
@@ -536,14 +538,14 @@ void ImplRegion::CreateBandRange( long nYTop, long nYBottom )
// -----------------------------------------------------------------------
-BOOL ImplRegion::InsertLine( const Point& rStartPt, const Point& rEndPt,
+sal_Bool ImplRegion::InsertLine( const Point& rStartPt, const Point& rEndPt,
long nLineId )
{
long nX, nY;
// lines consisting of a single point do not interest here
if ( rStartPt == rEndPt )
- return TRUE;
+ return sal_True;
LineType eLineType = (rStartPt.Y() > rEndPt.Y()) ? LINE_DESCENDING : LINE_ASCENDING;
if ( rStartPt.X() == rEndPt.X() )
@@ -620,25 +622,25 @@ BOOL ImplRegion::InsertLine( const Point& rStartPt, const Point& rEndPt,
}
// last point
- InsertPoint( Point( nEndX, nEndY ), nLineId, TRUE, eLineType );
+ InsertPoint( Point( nEndX, nEndY ), nLineId, sal_True, eLineType );
}
- return TRUE;
+ return sal_True;
}
// -----------------------------------------------------------------------
//
// search for appropriate place for the new point
-BOOL ImplRegion::InsertPoint( const Point &rPoint, long nLineID,
- BOOL bEndPoint, LineType eLineType )
+sal_Bool ImplRegion::InsertPoint( const Point &rPoint, long nLineID,
+ sal_Bool bEndPoint, LineType eLineType )
{
DBG_ASSERT( mpFirstBand != NULL, "ImplRegion::InsertPoint - no bands available!" );
if ( rPoint.Y() == mpLastCheckedBand->mnYTop )
{
mpLastCheckedBand->InsertPoint( rPoint.X(), nLineID, bEndPoint, eLineType );
- return TRUE;
+ return sal_True;
}
if ( rPoint.Y() > mpLastCheckedBand->mnYTop )
@@ -650,7 +652,7 @@ BOOL ImplRegion::InsertPoint( const Point &rPoint, long nLineID,
if ( rPoint.Y() == mpLastCheckedBand->mnYTop )
{
mpLastCheckedBand->InsertPoint( rPoint.X(), nLineID, bEndPoint, eLineType );
- return TRUE;
+ return sal_True;
}
mpLastCheckedBand = mpLastCheckedBand->mpNextBand;
@@ -667,7 +669,7 @@ BOOL ImplRegion::InsertPoint( const Point &rPoint, long nLineID,
if ( rPoint.Y() == mpLastCheckedBand->mnYTop )
{
mpLastCheckedBand->InsertPoint( rPoint.X(), nLineID, bEndPoint, eLineType );
- return TRUE;
+ return sal_True;
}
mpLastCheckedBand = mpLastCheckedBand->mpPrevBand;
@@ -681,7 +683,7 @@ BOOL ImplRegion::InsertPoint( const Point &rPoint, long nLineID,
// reinitialize pointer (should never be reached!)
mpLastCheckedBand = mpFirstBand;
- return FALSE;
+ return sal_False;
}
// -----------------------------------------------------------------------
@@ -699,9 +701,9 @@ void ImplRegion::InsertBands( long nTop, long nBottom )
}
// find/insert bands for the boundaries of the rectangle
- BOOL bTopBoundaryInserted = FALSE;
- BOOL bTop2BoundaryInserted = FALSE;
- BOOL bBottomBoundaryInserted = FALSE;
+ sal_Bool bTopBoundaryInserted = sal_False;
+ sal_Bool bTop2BoundaryInserted = sal_False;
+ sal_Bool bBottomBoundaryInserted = sal_False;
// special case: top boundary is above the first band
ImplRegionBand* pNewBand;
@@ -716,7 +718,7 @@ void ImplRegion::InsertBands( long nTop, long nBottom )
pNewBand->mpNextBand = mpFirstBand;
mpFirstBand = pNewBand;
- bTopBoundaryInserted = TRUE;
+ bTopBoundaryInserted = sal_True;
}
// insert band(s) into the list
@@ -760,13 +762,13 @@ void ImplRegion::InsertBands( long nTop, long nBottom )
//
// create new band and insert it into the list
-BOOL ImplRegion::InsertSingleBand( ImplRegionBand* pBand,
+sal_Bool ImplRegion::InsertSingleBand( ImplRegionBand* pBand,
long nYBandPosition )
{
// boundary already included in band with height 1? -> nothing to do!
if ( (pBand->mnYTop == pBand->mnYBottom) &&
(nYBandPosition == pBand->mnYTop) )
- return TRUE;
+ return sal_True;
// insert single height band on top?
ImplRegionBand* pNewBand;
@@ -781,7 +783,7 @@ BOOL ImplRegion::InsertSingleBand( ImplRegionBand* pBand,
pBand->mnYBottom = nYBandPosition;
pBand->mpNextBand = pNewBand;
- return TRUE;
+ return sal_True;
}
// top of new rectangle within the current band? -> insert new band and copy data
@@ -808,7 +810,7 @@ BOOL ImplRegion::InsertSingleBand( ImplRegionBand* pBand,
pBand->mnYBottom = nYBandPosition - 1;
pBand->mpNextBand = pNewBand;
- return TRUE;
+ return sal_True;
}
// create new band behind the current in the list
@@ -825,7 +827,7 @@ BOOL ImplRegion::InsertSingleBand( ImplRegionBand* pBand,
// append band to the list
pBand->mpNextBand = pNewBand;
- return TRUE;
+ return sal_True;
}
if ( nYBandPosition > pBand->mnYBottom )
@@ -835,11 +837,11 @@ BOOL ImplRegion::InsertSingleBand( ImplRegionBand* pBand,
// append band to the list
pBand->mpNextBand = pNewBand;
- return TRUE;
+ return sal_True;
}
}
- return FALSE;
+ return sal_False;
}
// ------------------------------------------------------------------------
@@ -980,7 +982,7 @@ void ImplRegion::XOr( long nLeft, long nTop, long nRight, long nBottom )
//
// remove empty bands
-BOOL ImplRegion::OptimizeBandList()
+sal_Bool ImplRegion::OptimizeBandList()
{
DBG_ASSERT( (this != &aImplNullRegion) && (this != &aImplEmptyRegion),
"ImplRegion::OptimizeBandList() - Empty oder NULL-Region" );
@@ -991,7 +993,7 @@ BOOL ImplRegion::OptimizeBandList()
ImplRegionBand* pBand = mpFirstBand;
while ( pBand )
{
- const BOOL bBTEqual = pBand->mpNextBand &&
+ const sal_Bool bBTEqual = pBand->mpNextBand &&
(pBand->mnYBottom == pBand->mpNextBand->mnYTop);
// no separation? -> remove!
@@ -1199,7 +1201,7 @@ void Region::ImplCreateRectRegion( const Rectangle& rRect )
void Region::ImplCreatePolyPolyRegion( const PolyPolygon& rPolyPoly )
{
- const USHORT nPolyCount = rPolyPoly.Count();
+ const sal_uInt16 nPolyCount = rPolyPoly.Count();
if ( nPolyCount )
{
// polypolygon empty? -> empty region
@@ -1363,13 +1365,35 @@ void Region::Scale( double fScaleX, double fScaleY )
// -----------------------------------------------------------------------
-BOOL Region::Union( const Rectangle& rRect )
+sal_Bool Region::Union( const Rectangle& rRect )
{
DBG_CHKTHIS( Region, ImplDbgTestRegion );
// is rectangle empty? -> nothing to do
if ( rRect.IsEmpty() )
- return TRUE;
+ return sal_True;
+
+ if( HasPolyPolygon() )
+ {
+ // get this B2DPolyPolygon
+ basegfx::B2DPolyPolygon aThisPolyPoly( ConvertToB2DPolyPolygon() );
+ aThisPolyPoly = basegfx::tools::prepareForPolygonOperation( aThisPolyPoly );
+
+ if( aThisPolyPoly.count() == 0 )
+ {
+ *this = rRect;
+ return true;
+ }
+
+ // get the other B2DPolyPolygon
+ basegfx::B2DPolygon aRectPoly( basegfx::tools::createPolygonFromRect( basegfx::B2DRectangle( rRect.Left(), rRect.Top(), rRect.Right(), rRect.Bottom() ) ) );
+ basegfx::B2DPolyPolygon aOtherPolyPoly( aRectPoly );
+
+ basegfx::B2DPolyPolygon aClip = basegfx::tools::solvePolygonOperationOr( aThisPolyPoly, aOtherPolyPoly );
+ *this = Region( aClip );
+
+ return sal_True;
+ }
ImplPolyPolyRegionToBandRegion();
@@ -1400,12 +1424,12 @@ BOOL Region::Union( const Rectangle& rRect )
mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
}
- return TRUE;
+ return sal_True;
}
// -----------------------------------------------------------------------
-BOOL Region::Intersect( const Rectangle& rRect )
+sal_Bool Region::Intersect( const Rectangle& rRect )
{
DBG_CHKTHIS( Region, ImplDbgTestRegion );
@@ -1421,7 +1445,7 @@ BOOL Region::Intersect( const Rectangle& rRect )
delete mpImplRegion;
}
mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
- return TRUE;
+ return sal_True;
}
// #103137# Avoid banding for special cases
@@ -1439,14 +1463,30 @@ BOOL Region::Intersect( const Rectangle& rRect )
// unnecessary banding
mpImplRegion->mpPolyPoly->Clip( rRect );
- return TRUE;
+ return sal_True;
+ }
+ else if( mpImplRegion->mpB2DPolyPoly )
+ {
+ // #127431# make ImplRegion unique, if not already.
+ if( mpImplRegion->mnRefCount > 1 )
+ {
+ mpImplRegion->mnRefCount--;
+ mpImplRegion = new ImplRegion( *mpImplRegion->mpB2DPolyPoly );
+ }
+
+ *mpImplRegion->mpB2DPolyPoly =
+ basegfx::tools::clipPolyPolygonOnRange( *mpImplRegion->mpB2DPolyPoly,
+ basegfx::B2DRange( rRect.Left(), rRect.Top(),
+ rRect.Right(), rRect.Bottom() ),
+ true, false );
+ return sal_True;
}
else
ImplPolyPolyRegionToBandRegion();
// is region empty? -> nothing to do!
if ( mpImplRegion == &aImplEmptyRegion )
- return TRUE;
+ return sal_True;
// get justified rectangle
long nLeft = Min( rRect.Left(), rRect.Right() );
@@ -1467,7 +1507,7 @@ BOOL Region::Intersect( const Rectangle& rRect )
mpImplRegion->mpFirstBand->Union( nLeft, nRight );
mpImplRegion->mnRectCount = 1;
- return TRUE;
+ return sal_True;
}
// no own instance data? -> make own copy!
@@ -1511,24 +1551,43 @@ BOOL Region::Intersect( const Rectangle& rRect )
mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
}
- return TRUE;
+ return sal_True;
}
// -----------------------------------------------------------------------
-BOOL Region::Exclude( const Rectangle& rRect )
+sal_Bool Region::Exclude( const Rectangle& rRect )
{
DBG_CHKTHIS( Region, ImplDbgTestRegion );
// is rectangle empty? -> nothing to do
if ( rRect.IsEmpty() )
- return TRUE;
+ return sal_True;
+
+ if( HasPolyPolygon() )
+ {
+ // get this B2DPolyPolygon
+ basegfx::B2DPolyPolygon aThisPolyPoly( ConvertToB2DPolyPolygon() );
+ aThisPolyPoly = basegfx::tools::prepareForPolygonOperation( aThisPolyPoly );
+
+ if( aThisPolyPoly.count() == 0 )
+ return sal_True;
+
+ // get the other B2DPolyPolygon
+ basegfx::B2DPolygon aRectPoly( basegfx::tools::createPolygonFromRect( basegfx::B2DRectangle( rRect.Left(), rRect.Top(), rRect.Right(), rRect.Bottom() ) ) );
+ basegfx::B2DPolyPolygon aOtherPolyPoly( aRectPoly );
+
+ basegfx::B2DPolyPolygon aClip = basegfx::tools::solvePolygonOperationDiff( aThisPolyPoly, aOtherPolyPoly );
+ *this = Region( aClip );
+
+ return sal_True;
+ }
ImplPolyPolyRegionToBandRegion();
// no instance data? -> create!
if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
- return TRUE;
+ return sal_True;
// no own instance data? -> make own copy!
if ( mpImplRegion->mnRefCount > 1 )
@@ -1553,18 +1612,40 @@ BOOL Region::Exclude( const Rectangle& rRect )
mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
}
- return TRUE;
+ return sal_True;
}
// -----------------------------------------------------------------------
-BOOL Region::XOr( const Rectangle& rRect )
+sal_Bool Region::XOr( const Rectangle& rRect )
{
DBG_CHKTHIS( Region, ImplDbgTestRegion );
// is rectangle empty? -> nothing to do
if ( rRect.IsEmpty() )
- return TRUE;
+ return sal_True;
+
+ if( HasPolyPolygon() )
+ {
+ // get this B2DPolyPolygon
+ basegfx::B2DPolyPolygon aThisPolyPoly( ConvertToB2DPolyPolygon() );
+ aThisPolyPoly = basegfx::tools::prepareForPolygonOperation( aThisPolyPoly );
+
+ if( aThisPolyPoly.count() == 0 )
+ {
+ *this = rRect;
+ return sal_True;
+ }
+
+ // get the other B2DPolyPolygon
+ basegfx::B2DPolygon aRectPoly( basegfx::tools::createPolygonFromRect( basegfx::B2DRectangle( rRect.Left(), rRect.Top(), rRect.Right(), rRect.Bottom() ) ) );
+ basegfx::B2DPolyPolygon aOtherPolyPoly( aRectPoly );
+
+ basegfx::B2DPolyPolygon aClip = basegfx::tools::solvePolygonOperationXor( aThisPolyPoly, aOtherPolyPoly );
+ *this = Region( aClip );
+
+ return sal_True;
+ }
ImplPolyPolyRegionToBandRegion();
@@ -1595,21 +1676,48 @@ BOOL Region::XOr( const Rectangle& rRect )
mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
}
- return TRUE;
+ return sal_True;
}
// -----------------------------------------------------------------------
+void Region::ImplUnionPolyPolygon( const Region& i_rRegion )
+{
+ // get this B2DPolyPolygon
+ basegfx::B2DPolyPolygon aThisPolyPoly( ConvertToB2DPolyPolygon() );
+ aThisPolyPoly = basegfx::tools::prepareForPolygonOperation( aThisPolyPoly );
+
+ if( aThisPolyPoly.count() == 0 )
+ {
+ *this = i_rRegion;
+ return;
+ }
+
+ // get the other B2DPolyPolygon
+ basegfx::B2DPolyPolygon aOtherPolyPoly( const_cast<Region&>(i_rRegion).ConvertToB2DPolyPolygon() );
+ aOtherPolyPoly = basegfx::tools::prepareForPolygonOperation( aOtherPolyPoly );
-BOOL Region::Union( const Region& rRegion )
+
+ basegfx::B2DPolyPolygon aClip = basegfx::tools::solvePolygonOperationOr( aThisPolyPoly, aOtherPolyPoly );
+
+ *this = Region( aClip );
+}
+
+sal_Bool Region::Union( const Region& rRegion )
{
DBG_CHKTHIS( Region, ImplDbgTestRegion );
+ if( rRegion.HasPolyPolygon() || HasPolyPolygon() )
+ {
+ ImplUnionPolyPolygon( rRegion );
+ return sal_True;
+ }
+
ImplPolyPolyRegionToBandRegion();
((Region*)&rRegion)->ImplPolyPolyRegionToBandRegion();
// is region empty or null? -> nothing to do
if ( (rRegion.mpImplRegion == &aImplEmptyRegion) || (rRegion.mpImplRegion == &aImplNullRegion) )
- return TRUE;
+ return sal_True;
// no instance data? -> create!
if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
@@ -1645,28 +1753,50 @@ BOOL Region::Union( const Region& rRegion )
mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
}
- return TRUE;
+ return sal_True;
}
// -----------------------------------------------------------------------
+void Region::ImplIntersectWithPolyPolygon( const Region& i_rRegion )
+{
+ // get this B2DPolyPolygon
+ basegfx::B2DPolyPolygon aThisPolyPoly( ConvertToB2DPolyPolygon() );
+ if( aThisPolyPoly.count() == 0 )
+ {
+ *this = i_rRegion;
+ return;
+ }
-BOOL Region::Intersect( const Region& rRegion )
+ // get the other B2DPolyPolygon
+ basegfx::B2DPolyPolygon aOtherPolyPoly( const_cast<Region&>(i_rRegion).ConvertToB2DPolyPolygon() );
+
+ basegfx::B2DPolyPolygon aClip = basegfx::tools::clipPolyPolygonOnPolyPolygon( aOtherPolyPoly, aThisPolyPoly, true, false );
+ *this = Region( aClip );
+}
+
+sal_Bool Region::Intersect( const Region& rRegion )
{
DBG_CHKTHIS( Region, ImplDbgTestRegion );
// same instance data? -> nothing to do!
if ( mpImplRegion == rRegion.mpImplRegion )
- return TRUE;
+ return sal_True;
+
+ if( rRegion.HasPolyPolygon() || HasPolyPolygon() )
+ {
+ ImplIntersectWithPolyPolygon( rRegion );
+ return sal_True;
+ }
ImplPolyPolyRegionToBandRegion();
((Region*)&rRegion)->ImplPolyPolyRegionToBandRegion();
if ( mpImplRegion == &aImplEmptyRegion )
- return TRUE;
+ return sal_True;
// is region null? -> nothing to do
if ( rRegion.mpImplRegion == &aImplNullRegion )
- return TRUE;
+ return sal_True;
// is rectangle empty? -> nothing to do
if ( rRegion.mpImplRegion == &aImplEmptyRegion )
@@ -1680,7 +1810,7 @@ BOOL Region::Intersect( const Region& rRegion )
delete mpImplRegion;
}
mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
- return TRUE;
+ return sal_True;
}
// is own region NULL-region? -> copy data!
@@ -1688,7 +1818,7 @@ BOOL Region::Intersect( const Region& rRegion )
{
mpImplRegion = rRegion.mpImplRegion;
rRegion.mpImplRegion->mnRefCount++;
- return TRUE;
+ return sal_True;
}
// Wenn wir weniger Rechtecke haben, drehen wir den Intersect-Aufruf um
@@ -1708,7 +1838,7 @@ BOOL Region::Intersect( const Region& rRegion )
ImplRegionBand* pBand = mpImplRegion->mpFirstBand;
while ( pBand )
{
- pBand->mbTouched = FALSE;
+ pBand->mbTouched = sal_False;
pBand = pBand->mpNextBand;
}
@@ -1784,25 +1914,46 @@ BOOL Region::Intersect( const Region& rRegion )
}
}
- return TRUE;
+ return sal_True;
}
// -----------------------------------------------------------------------
+void Region::ImplExcludePolyPolygon( const Region& i_rRegion )
+{
+ // get this B2DPolyPolygon
+ basegfx::B2DPolyPolygon aThisPolyPoly( ConvertToB2DPolyPolygon() );
+ if( aThisPolyPoly.count() == 0 )
+ return;
+ aThisPolyPoly = basegfx::tools::prepareForPolygonOperation( aThisPolyPoly );
+
+ // get the other B2DPolyPolygon
+ basegfx::B2DPolyPolygon aOtherPolyPoly( const_cast<Region&>(i_rRegion).ConvertToB2DPolyPolygon() );
+ aOtherPolyPoly = basegfx::tools::prepareForPolygonOperation( aOtherPolyPoly );
+
+ basegfx::B2DPolyPolygon aClip = basegfx::tools::solvePolygonOperationDiff( aThisPolyPoly, aOtherPolyPoly );
+ *this = Region( aClip );
+}
-BOOL Region::Exclude( const Region& rRegion )
+sal_Bool Region::Exclude( const Region& rRegion )
{
DBG_CHKTHIS( Region, ImplDbgTestRegion );
+ if( rRegion.HasPolyPolygon() || HasPolyPolygon() )
+ {
+ ImplExcludePolyPolygon( rRegion );
+ return sal_True;
+ }
+
ImplPolyPolyRegionToBandRegion();
((Region*)&rRegion)->ImplPolyPolyRegionToBandRegion();
// is region empty or null? -> nothing to do
if ( (rRegion.mpImplRegion == &aImplEmptyRegion) || (rRegion.mpImplRegion == &aImplNullRegion) )
- return TRUE;
+ return sal_True;
// no instance data? -> nothing to do
if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
- return TRUE;
+ return sal_True;
// no own instance data? -> make own copy!
if ( mpImplRegion->mnRefCount > 1 )
@@ -1837,27 +1988,51 @@ BOOL Region::Exclude( const Region& rRegion )
pBand = pBand->mpNextBand;
}
- return TRUE;
+ return sal_True;
}
// -----------------------------------------------------------------------
+void Region::ImplXOrPolyPolygon( const Region& i_rRegion )
+{
+ // get this B2DPolyPolygon
+ basegfx::B2DPolyPolygon aThisPolyPoly( ConvertToB2DPolyPolygon() );
+ if( aThisPolyPoly.count() == 0 )
+ {
+ *this = i_rRegion;
+ return;
+ }
+ aThisPolyPoly = basegfx::tools::prepareForPolygonOperation( aThisPolyPoly );
+
+ // get the other B2DPolyPolygon
+ basegfx::B2DPolyPolygon aOtherPolyPoly( const_cast<Region&>(i_rRegion).ConvertToB2DPolyPolygon() );
+ aOtherPolyPoly = basegfx::tools::prepareForPolygonOperation( aOtherPolyPoly );
+
+ basegfx::B2DPolyPolygon aClip = basegfx::tools::solvePolygonOperationXor( aThisPolyPoly, aOtherPolyPoly );
+ *this = Region( aClip );
+}
-BOOL Region::XOr( const Region& rRegion )
+sal_Bool Region::XOr( const Region& rRegion )
{
DBG_CHKTHIS( Region, ImplDbgTestRegion );
+ if( rRegion.HasPolyPolygon() || HasPolyPolygon() )
+ {
+ ImplXOrPolyPolygon( rRegion );
+ return sal_True;
+ }
+
ImplPolyPolyRegionToBandRegion();
((Region*)&rRegion)->ImplPolyPolyRegionToBandRegion();
// is region empty or null? -> nothing to do
if ( (rRegion.mpImplRegion == &aImplEmptyRegion) || (rRegion.mpImplRegion == &aImplNullRegion) )
- return TRUE;
+ return sal_True;
// no own instance data? -> XOr = copy
if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
{
*this = rRegion;
- return TRUE;
+ return sal_True;
}
// no own instance data? -> make own copy!
@@ -1890,7 +2065,7 @@ BOOL Region::XOr( const Region& rRegion )
mpImplRegion = (ImplRegion*)(&aImplEmptyRegion);
}
- return TRUE;
+ return sal_True;
}
// -----------------------------------------------------------------------
@@ -1944,7 +2119,7 @@ Rectangle Region::GetBoundRect() const
// -----------------------------------------------------------------------
-BOOL Region::HasPolyPolygon() const
+sal_Bool Region::HasPolyPolygon() const
{
DBG_CHKTHIS( Region, ImplDbgTestRegion );
if( !mpImplRegion )
@@ -2026,7 +2201,7 @@ basegfx::B2DPolyPolygon Region::ConvertToB2DPolyPolygon()
// -----------------------------------------------------------------------
-BOOL Region::ImplGetFirstRect( ImplRegionInfo& rImplRegionInfo,
+bool Region::ImplGetFirstRect( ImplRegionInfo& rImplRegionInfo,
long& rX, long& rY,
long& rWidth, long& rHeight ) const
{
@@ -2036,11 +2211,11 @@ BOOL Region::ImplGetFirstRect( ImplRegionInfo& rImplRegionInfo,
// no internal data? -> region is empty!
if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
- return FALSE;
+ return false;
// no band in the list? -> region is empty!
if ( mpImplRegion->mpFirstBand == NULL )
- return FALSE;
+ return false;
// initialise pointer for first access
ImplRegionBand* pCurrRectBand = mpImplRegion->mpFirstBand;
@@ -2048,7 +2223,7 @@ BOOL Region::ImplGetFirstRect( ImplRegionInfo& rImplRegionInfo,
DBG_ASSERT( pCurrRectBandSep != NULL, "Erstes Band wurde nicht optimiert." );
if ( !pCurrRectBandSep )
- return FALSE;
+ return false;
// get boundaries of current rectangle
rX = pCurrRectBandSep->mnXLeft;
@@ -2060,12 +2235,12 @@ BOOL Region::ImplGetFirstRect( ImplRegionInfo& rImplRegionInfo,
rImplRegionInfo.mpVoidCurrRectBand = (void*)pCurrRectBand;
rImplRegionInfo.mpVoidCurrRectBandSep = (void*)pCurrRectBandSep;
- return TRUE;
+ return true;
}
// -----------------------------------------------------------------------
-BOOL Region::ImplGetNextRect( ImplRegionInfo& rImplRegionInfo,
+bool Region::ImplGetNextRect( ImplRegionInfo& rImplRegionInfo,
long& rX, long& rY,
long& rWidth, long& rHeight ) const
{
@@ -2073,7 +2248,7 @@ BOOL Region::ImplGetNextRect( ImplRegionInfo& rImplRegionInfo,
// no internal data? -> region is empty!
if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
- return FALSE;
+ return false;
// get last pointers
ImplRegionBand* pCurrRectBand = (ImplRegionBand*)rImplRegionInfo.mpVoidCurrRectBand;
@@ -2090,7 +2265,7 @@ BOOL Region::ImplGetNextRect( ImplRegionInfo& rImplRegionInfo,
// no band found? -> not further rectangles!
if( !pCurrRectBand )
- return FALSE;
+ return false;
// get first separation in current band
pCurrRectBandSep = pCurrRectBand->mpFirstSep;
@@ -2106,7 +2281,7 @@ BOOL Region::ImplGetNextRect( ImplRegionInfo& rImplRegionInfo,
rImplRegionInfo.mpVoidCurrRectBand = (void*)pCurrRectBand;
rImplRegionInfo.mpVoidCurrRectBandSep = (void*)pCurrRectBandSep;
- return TRUE;
+ return true;
}
// -----------------------------------------------------------------------
@@ -2125,7 +2300,7 @@ RegionType Region::GetType() const
// -----------------------------------------------------------------------
-BOOL Region::IsInside( const Point& rPoint ) const
+sal_Bool Region::IsInside( const Point& rPoint ) const
{
DBG_CHKTHIS( Region, ImplDbgTestRegion );
@@ -2138,7 +2313,7 @@ BOOL Region::IsInside( const Point& rPoint ) const
// no instance data? -> not inside
if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
- return FALSE;
+ return sal_False;
// search band list
ImplRegionBand* pBand = mpImplRegion->mpFirstBand;
@@ -2150,30 +2325,30 @@ BOOL Region::IsInside( const Point& rPoint ) const
{
// is point within separation of the band?
if ( pBand->IsInside( rPoint.X() ) )
- return TRUE;
+ return sal_True;
else
- return FALSE;
+ return sal_False;
}
pBand = pBand->mpNextBand;
}
- return FALSE;
+ return sal_False;
}
// -----------------------------------------------------------------------
-BOOL Region::IsInside( const Rectangle& rRect ) const
+sal_Bool Region::IsInside( const Rectangle& rRect ) const
{
DBG_CHKTHIS( Region, ImplDbgTestRegion );
// is rectangle empty? -> not inside
if ( rRect.IsEmpty() )
- return FALSE;
+ return sal_False;
// no instance data? -> not inside
if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
- return FALSE;
+ return sal_False;
// create region from rectangle and intersect own region
Region aRegion = rRect;
@@ -2185,12 +2360,12 @@ BOOL Region::IsInside( const Rectangle& rRect ) const
// -----------------------------------------------------------------------
-BOOL Region::IsOver( const Rectangle& rRect ) const
+sal_Bool Region::IsOver( const Rectangle& rRect ) const
{
DBG_CHKTHIS( Region, ImplDbgTestRegion );
if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
- return FALSE;
+ return sal_False;
// Can we optimize this ??? - is used in StarDraw for brushes pointers
// Why we have no IsOver for Regions ???
@@ -2287,20 +2462,20 @@ Region& Region::operator=( const Rectangle& rRect )
// -----------------------------------------------------------------------
-BOOL Region::operator==( const Region& rRegion ) const
+sal_Bool Region::operator==( const Region& rRegion ) const
{
DBG_CHKTHIS( Region, ImplDbgTestRegion );
DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion );
// reference to same object? -> equal!
if ( mpImplRegion == rRegion.mpImplRegion )
- return TRUE;
+ return sal_True;
if ( (mpImplRegion == &aImplEmptyRegion) || (mpImplRegion == &aImplNullRegion) )
- return FALSE;
+ return sal_False;
if ( (rRegion.mpImplRegion == &aImplEmptyRegion) || (rRegion.mpImplRegion == &aImplNullRegion) )
- return FALSE;
+ return sal_False;
if ( rRegion.mpImplRegion->mpPolyPoly && mpImplRegion->mpPolyPoly )
return *rRegion.mpImplRegion->mpPolyPoly == *mpImplRegion->mpPolyPoly;
@@ -2311,13 +2486,13 @@ BOOL Region::operator==( const Region& rRegion ) const
// Eine der beiden Regions kann jetzt Empty sein
if ( mpImplRegion == rRegion.mpImplRegion )
- return TRUE;
+ return sal_True;
if ( mpImplRegion == &aImplEmptyRegion )
- return FALSE;
+ return sal_False;
if ( rRegion.mpImplRegion == &aImplEmptyRegion )
- return FALSE;
+ return sal_False;
}
// initialise pointers
@@ -2331,22 +2506,22 @@ BOOL Region::operator==( const Region& rRegion ) const
long nOwnXLeft = pOwnRectBandSep->mnXLeft;
long nSecondXLeft = pSecondRectBandSep->mnXLeft;
if ( nOwnXLeft != nSecondXLeft )
- return FALSE;
+ return sal_False;
long nOwnYTop = pOwnRectBand->mnYTop;
long nSecondYTop = pSecondRectBand->mnYTop;
if ( nOwnYTop != nSecondYTop )
- return FALSE;
+ return sal_False;
long nOwnXRight = pOwnRectBandSep->mnXRight;
long nSecondXRight = pSecondRectBandSep->mnXRight;
if ( nOwnXRight != nSecondXRight )
- return FALSE;
+ return sal_False;
long nOwnYBottom = pOwnRectBand->mnYBottom;
long nSecondYBottom = pSecondRectBand->mnYBottom;
if ( nOwnYBottom != nSecondYBottom )
- return FALSE;
+ return sal_False;
// get next separation from current band
pOwnRectBandSep = pOwnRectBandSep->mpNextSep;
@@ -2377,13 +2552,13 @@ BOOL Region::operator==( const Region& rRegion ) const
}
if ( pOwnRectBandSep && !pSecondRectBandSep )
- return FALSE;
+ return sal_False;
if ( !pOwnRectBandSep && pSecondRectBandSep )
- return FALSE;
+ return sal_False;
}
- return TRUE;
+ return sal_True;
}
// -----------------------------------------------------------------------
@@ -2395,8 +2570,8 @@ SvStream& operator>>( SvStream& rIStrm, Region& rRegion )
DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion );
VersionCompat aCompat( rIStrm, STREAM_READ );
- UINT16 nVersion;
- UINT16 nTmp16;
+ sal_uInt16 nVersion;
+ sal_uInt16 nTmp16;
// statische Object haben RefCount von 0
if ( rRegion.mpImplRegion->mnRefCount )
@@ -2489,7 +2664,7 @@ SvStream& operator>>( SvStream& rIStrm, Region& rRegion )
if( aCompat.GetVersion() >= 2 )
{
- BOOL bHasPolyPolygon;
+ sal_Bool bHasPolyPolygon;
rIStrm >> bHasPolyPolygon;
@@ -2513,7 +2688,7 @@ SvStream& operator<<( SvStream& rOStrm, const Region& rRegion )
{
DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion );
- UINT16 nVersion = 2;
+ sal_uInt16 nVersion = 2;
VersionCompat aCompat( rOStrm, STREAM_WRITE, nVersion );
Region aTmpRegion( rRegion );
@@ -2524,7 +2699,7 @@ SvStream& operator<<( SvStream& rOStrm, const Region& rRegion )
rOStrm << nVersion;
// put type
- rOStrm << (UINT16)aTmpRegion.GetType();
+ rOStrm << (sal_uInt16)aTmpRegion.GetType();
// put all bands if not null or empty
if ( (aTmpRegion.mpImplRegion != &aImplEmptyRegion) && (aTmpRegion.mpImplRegion != &aImplNullRegion) )
@@ -2533,7 +2708,7 @@ SvStream& operator<<( SvStream& rOStrm, const Region& rRegion )
while ( pBand )
{
// put boundaries
- rOStrm << (UINT16) STREAMENTRY_BANDHEADER;
+ rOStrm << (sal_uInt16) STREAMENTRY_BANDHEADER;
rOStrm << pBand->mnYTop;
rOStrm << pBand->mnYBottom;
@@ -2542,7 +2717,7 @@ SvStream& operator<<( SvStream& rOStrm, const Region& rRegion )
while ( pSep )
{
// put separation
- rOStrm << (UINT16) STREAMENTRY_SEPARATION;
+ rOStrm << (sal_uInt16) STREAMENTRY_SEPARATION;
rOStrm << pSep->mnXLeft;
rOStrm << pSep->mnXRight;
@@ -2554,10 +2729,10 @@ SvStream& operator<<( SvStream& rOStrm, const Region& rRegion )
}
// put endmarker
- rOStrm << (UINT16) STREAMENTRY_END;
+ rOStrm << (sal_uInt16) STREAMENTRY_END;
// write polypolygon if available
- const BOOL bHasPolyPolygon = rRegion.HasPolyPolygon();
+ const sal_Bool bHasPolyPolygon = rRegion.HasPolyPolygon();
rOStrm << bHasPolyPolygon;
if( bHasPolyPolygon )
@@ -2594,12 +2769,12 @@ void Region::ImplBeginAddRect()
// -----------------------------------------------------------------------
-BOOL Region::ImplAddRect( const Rectangle& rRect )
+sal_Bool Region::ImplAddRect( const Rectangle& rRect )
{
// Hier kein CheckThis, da nicht alle Daten auf Stand
if ( rRect.IsEmpty() )
- return TRUE;
+ return sal_True;
// get justified rectangle
long nTop;
@@ -2659,7 +2834,7 @@ BOOL Region::ImplAddRect( const Rectangle& rRect )
mpImplRegion->mpLastCheckedBand->Union( nLeft, nRight );
}
- return TRUE;
+ return sal_True;
}
// -----------------------------------------------------------------------
@@ -2728,14 +2903,14 @@ void Region::ImplEndAddRect()
// -----------------------------------------------------------------------
-ULONG Region::GetRectCount() const
+sal_uLong Region::GetRectCount() const
{
DBG_CHKTHIS( Region, ImplDbgTestRegion );
((Region*)this)->ImplPolyPolyRegionToBandRegion();
#ifdef DBG_UTIL
- ULONG nCount = 0;
+ sal_uLong nCount = 0;
// all bands if not null or empty
if ( (mpImplRegion != &aImplEmptyRegion) && (mpImplRegion != &aImplNullRegion) )
@@ -2781,7 +2956,7 @@ RegionHandle Region::BeginEnumRects()
ImplRegionHandle* pData = new ImplRegionHandle;
pData->mpRegion = new Region( *this );
- pData->mbFirst = TRUE;
+ pData->mbFirst = sal_True;
// save pointers
pData->mpCurrRectBand = pData->mpRegion->mpImplRegion->mpFirstBand;
@@ -2792,16 +2967,16 @@ RegionHandle Region::BeginEnumRects()
// -----------------------------------------------------------------------
-BOOL Region::GetEnumRects( RegionHandle pVoidData, Rectangle& rRect )
+sal_Bool Region::GetEnumRects( RegionHandle pVoidData, Rectangle& rRect )
{
DBG_CHKTHIS( Region, ImplDbgTestRegion );
ImplRegionHandle* pData = (ImplRegionHandle*)pVoidData;
if ( !pData )
- return FALSE;
+ return sal_False;
if ( pData->mbFirst )
- pData->mbFirst = FALSE;
+ pData->mbFirst = sal_False;
else
{
// get next separation from current band
@@ -2815,7 +2990,7 @@ BOOL Region::GetEnumRects( RegionHandle pVoidData, Rectangle& rRect )
// no band found? -> not further rectangles!
if ( !pData->mpCurrRectBand )
- return FALSE;
+ return sal_False;
// get first separation in current band
pData->mpCurrRectBandSep = pData->mpCurrRectBand->mpFirstSep;
@@ -2827,7 +3002,7 @@ BOOL Region::GetEnumRects( RegionHandle pVoidData, Rectangle& rRect )
rRect.Bottom() = pData->mpCurrRectBand->mnYBottom;
rRect.Left() = pData->mpCurrRectBandSep->mnXLeft;
rRect.Right() = pData->mpCurrRectBandSep->mnXRight;
- return TRUE;
+ return sal_True;
}
// -----------------------------------------------------------------------
@@ -2851,7 +3026,7 @@ static inline bool ImplPolygonRectTest( const Polygon& rPoly, Rectangle* pRectOu
{
bool bIsRect = false;
const Point* pPoints = rPoly.GetConstPointAry();
- USHORT nPoints = rPoly.GetSize();
+ sal_uInt16 nPoints = rPoly.GetSize();
if( nPoints == 4 || (nPoints == 5 && pPoints[0] == pPoints[4]) )
{
long nX1 = pPoints[0].X(), nX2 = pPoints[2].X(),
@@ -2902,7 +3077,7 @@ Region Region::GetRegionFromPolyPolygon( const PolyPolygon& rPolyPoly )
int nPolygonRects = 0, nPolygonPolygons = 0;
int nPolygons = rPolyPoly.Count();
- for( USHORT i = 0; i < nPolygons; i++ )
+ for( sal_uInt16 i = 0; i < nPolygons; i++ )
{
const Polygon& rPoly = rPolyPoly[i];
if( ImplPolygonRectTest( rPoly ) )
@@ -2915,7 +3090,7 @@ Region Region::GetRegionFromPolyPolygon( const PolyPolygon& rPolyPoly )
Region aResult;
Rectangle aRect;
- for( USHORT i = 0; i < nPolygons; i++ )
+ for( sal_uInt16 i = 0; i < nPolygons; i++ )
{
const Polygon& rPoly = rPolyPoly[i];
if( ImplPolygonRectTest( rPoly, &aRect ) )