You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by al...@apache.org on 2012/10/23 15:46:30 UTC

svn commit: r1401294 [4/4] - in /incubator/ooo/trunk/main: canvas/source/vcl/ cppcanvas/source/mtfrenderer/ drawinglayer/source/primitive2d/ filter/source/graphicfilter/eps/ sd/source/ui/slidesorter/view/ svx/source/sdr/overlay/ svx/source/sdr/properti...

Added: incubator/ooo/trunk/main/vcl/source/gdi/regionband.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/source/gdi/regionband.cxx?rev=1401294&view=auto
==============================================================================
--- incubator/ooo/trunk/main/vcl/source/gdi/regionband.cxx (added)
+++ incubator/ooo/trunk/main/vcl/source/gdi/regionband.cxx Tue Oct 23 13:46:28 2012
@@ -0,0 +1,1384 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_vcl.hxx"
+
+#include <tools/stream.hxx>
+#include <tools/debug.hxx>
+#include <regionband.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+DBG_NAME( RegionBand )
+DBG_NAMEEX( Polygon )
+DBG_NAMEEX( PolyPolygon )
+
+//////////////////////////////////////////////////////////////////////////////
+
+RegionBand::RegionBand()
+:   mpFirstBand(0),
+    mpLastCheckedBand(0)
+{
+    DBG_CTOR(RegionBand, ImplDbgTestRegionBand);
+}
+
+RegionBand::RegionBand(const RegionBand& rRef)
+:   mpFirstBand(0),
+    mpLastCheckedBand(0)
+{
+    *this = rRef;
+    DBG_CTOR(RegionBand, ImplDbgTestRegionBand);
+}
+
+RegionBand& RegionBand::operator=(const RegionBand& rRef)
+{
+	ImplRegionBand* pPrevBand = 0;
+	ImplRegionBand* pBand = rRef.mpFirstBand;
+	
+    while(pBand)
+	{
+		ImplRegionBand* pNewBand = new ImplRegionBand(*pBand);
+
+		// first element? -> set as first into the list
+		if(pBand == rRef.mpFirstBand)
+        {
+			mpFirstBand = pNewBand;
+        }
+		else
+        {
+			pPrevBand->mpNextBand = pNewBand;
+        }
+
+		pPrevBand = pNewBand;
+		pBand = pBand->mpNextBand;
+	}
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+    DBG_CHKOBJ(&rRef, RegionBand, ImplDbgTestRegionBand);
+
+    return *this;
+}
+
+RegionBand::RegionBand(const Rectangle& rRect)
+:   mpFirstBand(0),
+    mpLastCheckedBand(0)
+{
+    const long nTop(std::min(rRect.Top(), rRect.Bottom()));
+    const long nBottom(std::max(rRect.Top(), rRect.Bottom()));
+    const long nLeft(std::min(rRect.Left(), rRect.Right()));
+    const long nRight(std::max(rRect.Left(), rRect.Right()));
+
+    // add band with boundaries of the rectangle
+    mpFirstBand = new ImplRegionBand(nTop, nBottom);
+
+    // Set left and right boundaries of the band
+    mpFirstBand->Union(nLeft, nRight);
+
+    DBG_CTOR(RegionBand, ImplDbgTestRegionBand);
+}
+
+void RegionBand::implReset()
+{
+	ImplRegionBand* pBand = mpFirstBand;
+
+    while(pBand)
+	{
+		ImplRegionBand* pTempBand = pBand->mpNextBand;
+		delete pBand;
+		pBand = pTempBand;
+	}
+
+    mpLastCheckedBand = 0;
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+}
+
+RegionBand::~RegionBand()
+{
+    implReset();
+    DBG_DTOR(RegionBand, ImplDbgTestRegionBand);
+}
+
+bool RegionBand::operator==( const RegionBand& rRegionBand ) const
+{
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+    DBG_CHKOBJ(&rRegionBand, RegionBand, ImplDbgTestRegionBand);
+
+	// initialise pointers
+	ImplRegionBand* 	 pOwnRectBand = mpFirstBand;
+	ImplRegionBandSep*	 pOwnRectBandSep = pOwnRectBand->mpFirstSep;
+	ImplRegionBand* 	 pSecondRectBand = rRegionBand.mpFirstBand;
+	ImplRegionBandSep*	 pSecondRectBandSep = pSecondRectBand->mpFirstSep;
+
+    while ( pOwnRectBandSep && pSecondRectBandSep )
+	{
+		// get boundaries of current rectangle
+		long nOwnXLeft = pOwnRectBandSep->mnXLeft;
+		long nSecondXLeft = pSecondRectBandSep->mnXLeft;
+	
+        if ( nOwnXLeft != nSecondXLeft )
+        {
+			return false;
+        }
+
+		long nOwnYTop = pOwnRectBand->mnYTop;
+		long nSecondYTop = pSecondRectBand->mnYTop;
+		
+        if ( nOwnYTop != nSecondYTop )
+        {
+			return false;
+        }
+
+		long nOwnXRight = pOwnRectBandSep->mnXRight;
+		long nSecondXRight = pSecondRectBandSep->mnXRight;
+		
+        if ( nOwnXRight != nSecondXRight )
+        {
+			return false;
+        }
+
+		long nOwnYBottom = pOwnRectBand->mnYBottom;
+		long nSecondYBottom = pSecondRectBand->mnYBottom;
+		
+        if ( nOwnYBottom != nSecondYBottom )
+        {
+			return false;
+        }
+
+		// get next separation from current band
+		pOwnRectBandSep = pOwnRectBandSep->mpNextSep;
+
+		// no separation found? -> go to next band!
+		if ( !pOwnRectBandSep )
+		{
+			// get next band
+			pOwnRectBand = pOwnRectBand->mpNextBand;
+
+			// get first separation in current band
+			if( pOwnRectBand )
+            {
+				pOwnRectBandSep = pOwnRectBand->mpFirstSep;
+            }
+		}
+
+		// get next separation from current band
+		pSecondRectBandSep = pSecondRectBandSep->mpNextSep;
+
+		// no separation found? -> go to next band!
+		if ( !pSecondRectBandSep )
+		{
+			// get next band
+			pSecondRectBand = pSecondRectBand->mpNextBand;
+
+			// get first separation in current band
+			if( pSecondRectBand )
+            {
+				pSecondRectBandSep = pSecondRectBand->mpFirstSep;
+            }
+		}
+
+		if ( pOwnRectBandSep && !pSecondRectBandSep )
+        {
+			return false;
+        }
+
+		if ( !pOwnRectBandSep && pSecondRectBandSep )
+        {
+			return false;
+        }
+	}
+
+	return true;
+}
+
+enum StreamEntryType { STREAMENTRY_BANDHEADER, STREAMENTRY_SEPARATION, STREAMENTRY_END };
+
+void RegionBand::load(SvStream& rIStrm)
+{
+    // clear this nstance's data
+    implReset();
+
+    // get all bands
+    ImplRegionBand* pCurrBand = 0;
+
+    // get header from first element
+    sal_uInt16 nTmp16(0);
+    rIStrm >> nTmp16;
+
+    while(STREAMENTRY_END != (StreamEntryType)nTmp16)
+    {
+        // insert new band or new separation?
+        if(STREAMENTRY_BANDHEADER == (StreamEntryType)nTmp16)
+        {
+            long nYTop;
+            long nYBottom;
+
+            rIStrm >> nYTop;
+            rIStrm >> nYBottom;
+
+            // create band
+            ImplRegionBand* pNewBand = new ImplRegionBand( nYTop, nYBottom );
+
+            // first element? -> set as first into the list
+            if ( !pCurrBand )
+            {
+                mpFirstBand = pNewBand;
+            }
+            else
+            {
+                pCurrBand->mpNextBand = pNewBand;
+            }
+
+            // save pointer for next creation
+            pCurrBand = pNewBand;
+        }
+        else
+        {
+            long nXLeft;
+            long nXRight;
+
+            rIStrm >> nXLeft;
+            rIStrm >> nXRight;
+
+            // add separation
+            if ( pCurrBand )
+            {
+                pCurrBand->Union( nXLeft, nXRight );
+            }
+        }
+                
+        if( rIStrm.IsEof() )
+        {
+            DBG_ERROR( "premature end of region stream" );
+            implReset();
+            return;
+        }
+
+        // get next header
+        rIStrm >> nTmp16;
+    }
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+}
+
+void RegionBand::save(SvStream& rOStrm) const
+{
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+    ImplRegionBand* pBand = mpFirstBand;
+
+    while(pBand)
+    {
+        // put boundaries
+        rOStrm << (sal_uInt16)STREAMENTRY_BANDHEADER;
+        rOStrm << pBand->mnYTop;
+        rOStrm << pBand->mnYBottom;
+        
+        // put separations of current band
+        ImplRegionBandSep* pSep = pBand->mpFirstSep;
+
+        while(pSep)
+        {
+            // put separation
+            rOStrm << (sal_uInt16)STREAMENTRY_SEPARATION;
+            rOStrm << pSep->mnXLeft;
+            rOStrm << pSep->mnXRight;
+
+            // next separation from current band
+            pSep = pSep->mpNextSep;
+        }
+        
+        pBand = pBand->mpNextBand;
+    }
+
+    // put endmarker
+    rOStrm << (sal_uInt16)STREAMENTRY_END;
+}
+
+bool RegionBand::isSingleRectangle() const 
+{ 
+    // just one band?
+    if(mpFirstBand && !mpFirstBand->mpNextBand)
+    {
+        // just one sep?
+        if(mpFirstBand->mpFirstSep && !mpFirstBand->mpFirstSep->mpNextSep)
+        {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+void RegionBand::InsertBand(ImplRegionBand* pPreviousBand, ImplRegionBand* pBandToInsert)
+{
+    OSL_ASSERT(pBandToInsert!=NULL);
+
+    if(!pPreviousBand)
+    {
+        // Insert band before all others.
+        if(mpFirstBand)
+        {
+            mpFirstBand->mpPrevBand = pBandToInsert;
+        }
+
+        pBandToInsert->mpNextBand = mpFirstBand;
+        mpFirstBand = pBandToInsert;
+    }
+    else
+    {
+        // Insert band directly after pPreviousBand.
+        pBandToInsert->mpNextBand = pPreviousBand->mpNextBand;
+        pPreviousBand->mpNextBand = pBandToInsert;
+        pBandToInsert->mpPrevBand = pPreviousBand;
+    }
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+}
+
+void RegionBand::processPoints()
+{
+	ImplRegionBand* pRegionBand = mpFirstBand;
+
+    while(pRegionBand)
+	{
+		// generate separations from the lines and process union
+		pRegionBand->ProcessPoints();
+		pRegionBand = pRegionBand->mpNextBand;
+	}
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+}
+
+/** This function is similar to the RegionBand::InsertBands() method.
+    It creates a minimal set of missing bands so that the entire vertical
+    interval from nTop to nBottom is covered by bands.
+*/
+void RegionBand::ImplAddMissingBands(const long nTop, const long nBottom)
+{
+    // Iterate over already existing bands and add missing bands atop the
+    // first and between two bands.
+    ImplRegionBand* pPreviousBand = NULL;
+    ImplRegionBand* pBand = ImplGetFirstRegionBand();
+    long nCurrentTop (nTop);
+
+    while (pBand != NULL && nCurrentTop<nBottom)
+    {
+        if (nCurrentTop < pBand->mnYTop)
+        {
+            // Create new band above the current band.
+            ImplRegionBand* pAboveBand = new ImplRegionBand(
+                nCurrentTop,
+                ::std::min(nBottom,pBand->mnYTop-1));
+            InsertBand(pPreviousBand, pAboveBand);
+        }
+
+        // Adapt the top of the interval to prevent overlapping bands.
+        nCurrentTop = ::std::max(nTop, pBand->mnYBottom+1);
+
+        // Advance to next band.
+        pPreviousBand = pBand;
+        pBand = pBand->mpNextBand;
+    }
+
+    // We still have to cover two cases:
+    // 1. The region does not yet contain any bands.
+    // 2. The intervall nTop->nBottom extends past the bottom most band.
+    if (nCurrentTop <= nBottom
+        && (pBand==NULL || nBottom>pBand->mnYBottom))
+    {
+        // When there is no previous band then the new one will be the
+        // first.  Otherwise the new band is inserted behind the last band.
+        InsertBand(
+            pPreviousBand,
+            new ImplRegionBand(
+                nCurrentTop,
+                nBottom));
+    }
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+}
+
+void RegionBand::CreateBandRange(long nYTop, long nYBottom)
+{
+	// add top band
+	mpFirstBand = new ImplRegionBand( nYTop-1, nYTop-1 );
+
+	// begin first search from the first element
+	mpLastCheckedBand = mpFirstBand;
+	ImplRegionBand* pBand = mpFirstBand;
+
+    for ( int i = nYTop; i <= nYBottom+1; i++ )
+	{
+		// create new band
+		ImplRegionBand* pNewBand = new ImplRegionBand( i, i );
+		pBand->mpNextBand = pNewBand;
+	
+        if ( pBand != mpFirstBand )
+        {
+			pNewBand->mpPrevBand = pBand;
+        }
+
+		pBand = pBand->mpNextBand;
+	}
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+}
+
+bool RegionBand::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 )
+    {
+        DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+		return true;
+    }
+
+	LineType eLineType = (rStartPt.Y() > rEndPt.Y()) ? LINE_DESCENDING : LINE_ASCENDING;
+	if ( rStartPt.X() == rEndPt.X() )
+	{
+		// vertical line
+		const long nEndY = rEndPt.Y();
+
+		nX = rStartPt.X();
+		nY = rStartPt.Y();
+
+		if( nEndY > nY )
+		{
+			for ( ; nY <= nEndY; nY++ )
+			{
+				Point aNewPoint( nX, nY );
+				InsertPoint( aNewPoint, nLineId,
+							 (aNewPoint == rEndPt) || (aNewPoint == rStartPt),
+							 eLineType );
+			}
+		}
+		else
+		{
+			for ( ; nY >= nEndY; nY-- )
+			{
+				Point aNewPoint( nX, nY );
+				InsertPoint( aNewPoint, nLineId,
+							 (aNewPoint == rEndPt) || (aNewPoint == rStartPt),
+							 eLineType );
+			}
+		}
+	}
+	else if ( rStartPt.Y() != rEndPt.Y() )
+	{
+		const long	nDX = labs( rEndPt.X() - rStartPt.X() );
+		const long	nDY = labs( rEndPt.Y() - rStartPt.Y() );
+		const long	nStartX = rStartPt.X();
+		const long	nStartY = rStartPt.Y();
+		const long	nEndX = rEndPt.X();
+		const long	nEndY = rEndPt.Y();
+		const long	nXInc = ( nStartX < nEndX ) ? 1L : -1L;
+		const long	nYInc = ( nStartY < nEndY ) ? 1L : -1L;
+
+		if ( nDX >= nDY )
+		{
+			const long	nDYX = ( nDY - nDX ) << 1;
+			const long	nDY2 = nDY << 1;
+			long		nD = nDY2 - nDX;
+
+			for ( nX = nStartX, nY = nStartY; nX != nEndX; nX += nXInc )
+			{
+				InsertPoint( Point( nX, nY ), nLineId, nStartX == nX, eLineType );
+
+				if ( nD < 0L )
+					nD += nDY2;
+				else
+					nD += nDYX, nY += nYInc;
+			}
+		}
+		else
+		{
+			const long	nDYX = ( nDX - nDY ) << 1;
+			const long	nDY2 = nDX << 1;
+			long		nD = nDY2 - nDY;
+
+			for ( nX = nStartX, nY = nStartY; nY != nEndY; nY += nYInc )
+			{
+				InsertPoint( Point( nX, nY ), nLineId, nStartY == nY, eLineType );
+
+				if ( nD < 0L )
+					nD += nDY2;
+				else
+					nD += nDYX, nX += nXInc;
+			}
+		}
+
+		// last point
+		InsertPoint( Point( nEndX, nEndY ), nLineId, true, eLineType );
+	}
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+	return true;
+}
+
+bool RegionBand::InsertPoint(const Point &rPoint, long nLineID, bool bEndPoint, LineType eLineType)
+{
+	DBG_ASSERT( mpFirstBand != NULL, "RegionBand::InsertPoint - no bands available!" );
+
+	if ( rPoint.Y() == mpLastCheckedBand->mnYTop )
+	{
+		mpLastCheckedBand->InsertPoint( rPoint.X(), nLineID, bEndPoint, eLineType );
+		return true;
+	}
+
+	if ( rPoint.Y() > mpLastCheckedBand->mnYTop )
+	{
+		// Search ascending
+		while ( mpLastCheckedBand )
+		{
+			// Insert point if possible
+			if ( rPoint.Y() == mpLastCheckedBand->mnYTop )
+			{
+				mpLastCheckedBand->InsertPoint( rPoint.X(), nLineID, bEndPoint, eLineType );
+                DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+				return true;
+			}
+
+			mpLastCheckedBand = mpLastCheckedBand->mpNextBand;
+		}
+
+		DBG_ERROR( "RegionBand::InsertPoint reached the end of the list!" );
+	}
+	else
+	{
+		// Search descending
+		while ( mpLastCheckedBand )
+		{
+			// Insert point if possible
+			if ( rPoint.Y() == mpLastCheckedBand->mnYTop )
+			{
+				mpLastCheckedBand->InsertPoint( rPoint.X(), nLineID, bEndPoint, eLineType );
+                DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+				return true;
+			}
+
+			mpLastCheckedBand = mpLastCheckedBand->mpPrevBand;
+		}
+
+		DBG_ERROR( "RegionBand::InsertPoint reached the beginning of the list!" );
+	}
+
+	DBG_ERROR( "RegionBand::InsertPoint point not inserted!" );
+
+	// reinitialize pointer (should never be reached!)
+	mpLastCheckedBand = mpFirstBand;
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+	return false;
+}
+
+bool RegionBand::OptimizeBandList()
+{
+	ImplRegionBand* pPrevBand = 0;
+	ImplRegionBand* pBand = mpFirstBand;
+
+    while ( pBand )
+	{
+		const bool bBTEqual = pBand->mpNextBand && (pBand->mnYBottom == pBand->mpNextBand->mnYTop);
+
+		// no separation? -> remove!
+		if ( pBand->IsEmpty() || (bBTEqual && (pBand->mnYBottom == pBand->mnYTop)) )
+		{
+			// save pointer
+			ImplRegionBand* pOldBand = pBand;
+
+			// previous element of the list
+			if ( pBand == mpFirstBand )
+				mpFirstBand = pBand->mpNextBand;
+			else
+				pPrevBand->mpNextBand = pBand->mpNextBand;
+
+			pBand = pBand->mpNextBand;
+			delete pOldBand;
+		}
+		else
+		{
+			// fixup
+			if ( bBTEqual )
+				pBand->mnYBottom = pBand->mpNextBand->mnYTop-1;
+
+			// this and next band with equal separations? -> combine!
+			if ( pBand->mpNextBand &&
+				 ((pBand->mnYBottom+1) == pBand->mpNextBand->mnYTop) &&
+				 (*pBand == *pBand->mpNextBand) )
+			{
+				// expand current height
+				pBand->mnYBottom = pBand->mpNextBand->mnYBottom;
+
+				// remove next band from list
+				ImplRegionBand* pDeletedBand = pBand->mpNextBand;
+				pBand->mpNextBand = pDeletedBand->mpNextBand;
+				delete pDeletedBand;
+
+				// check band again!
+			}
+			else
+			{
+				// count rectangles within band
+				ImplRegionBandSep* pSep = pBand->mpFirstSep;
+				while ( pSep )
+				{
+					pSep = pSep->mpNextSep;
+				}
+
+				pPrevBand = pBand;
+				pBand = pBand->mpNextBand;
+			}
+		}
+	}
+
+#ifdef DBG_UTIL
+	pBand = mpFirstBand;
+	while ( pBand )
+	{
+		DBG_ASSERT( pBand->mpFirstSep != NULL, "Exiting RegionBand::OptimizeBandList(): empty band in region!" );
+
+		if ( pBand->mnYBottom < pBand->mnYTop )
+			DBG_ERROR( "RegionBand::OptimizeBandList(): YBottomBoundary < YTopBoundary" );
+
+		if ( pBand->mpNextBand )
+		{
+			if ( pBand->mnYBottom >= pBand->mpNextBand->mnYTop )
+				DBG_ERROR( "RegionBand::OptimizeBandList(): overlapping bands in region!" );
+		}
+
+		pBand = pBand->mpNextBand;
+	}
+#endif
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+	return (0 != mpFirstBand);
+}
+
+void RegionBand::Move(long nHorzMove, long nVertMove)
+{
+    ImplRegionBand* pBand = mpFirstBand;
+
+    while(pBand)
+	{
+		// process the vertical move
+		if(nVertMove)
+		{
+			pBand->mnYTop = pBand->mnYTop + nVertMove;
+			pBand->mnYBottom = pBand->mnYBottom + nVertMove;
+		}
+
+		// process the horizontal move
+		if(nHorzMove)
+        {
+			pBand->MoveX(nHorzMove);
+        }
+
+		pBand = pBand->mpNextBand;
+	}
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+}
+
+void RegionBand::Scale(double fScaleX, double fScaleY)
+{
+    ImplRegionBand* pBand = mpFirstBand;
+
+    while(pBand)
+	{
+		// process the vertical move
+		if(0.0 != fScaleY)
+		{
+			pBand->mnYTop = basegfx::fround(pBand->mnYTop * fScaleY);
+			pBand->mnYBottom = basegfx::fround(pBand->mnYBottom * fScaleY);
+		}
+
+		// process the horizontal move
+		if(0.0 != fScaleX)
+        {
+			pBand->ScaleX(fScaleX);
+        }
+
+		pBand = pBand->mpNextBand;
+	}
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+}
+
+void RegionBand::InsertBands(long nTop, long nBottom)
+{
+	// region empty? -> set rectagle as first entry!
+	if ( !mpFirstBand )
+	{
+		// add band with boundaries of the rectangle
+		mpFirstBand = new ImplRegionBand( nTop, nBottom );
+        DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+		return;
+	}
+
+	// find/insert bands for the boundaries of the rectangle
+	bool bTopBoundaryInserted = false;
+	bool bTop2BoundaryInserted = false;
+	bool bBottomBoundaryInserted = false;
+
+	// special case: top boundary is above the first band
+	ImplRegionBand* pNewBand;
+
+    if ( nTop < mpFirstBand->mnYTop )
+	{
+		// create new band above the first in the list
+		pNewBand = new ImplRegionBand( nTop, mpFirstBand->mnYTop );
+
+		if ( nBottom < mpFirstBand->mnYTop )
+        {
+			pNewBand->mnYBottom = nBottom;
+        }
+
+		// insert band into the list
+		pNewBand->mpNextBand = mpFirstBand;
+		mpFirstBand = pNewBand;
+
+		bTopBoundaryInserted = true;
+	}
+
+	// insert band(s) into the list
+	ImplRegionBand* pBand = mpFirstBand;
+
+    while ( pBand )
+	{
+		// Insert Bands if possible
+		if ( !bTopBoundaryInserted )
+        {
+			bTopBoundaryInserted = InsertSingleBand( pBand, nTop - 1 );
+        }
+
+		if ( !bTop2BoundaryInserted )
+        {
+			bTop2BoundaryInserted = InsertSingleBand( pBand, nTop );
+        }
+
+		if ( !bBottomBoundaryInserted && (nTop != nBottom) )
+        {
+			bBottomBoundaryInserted = InsertSingleBand( pBand, nBottom );
+        }
+
+		// both boundaries inserted? -> nothing more to do
+		if ( bTopBoundaryInserted && bTop2BoundaryInserted && bBottomBoundaryInserted )
+        {
+			break;
+        }
+
+		// insert bands between two bands if neccessary
+		if ( pBand->mpNextBand )
+		{
+			if ( (pBand->mnYBottom + 1) < pBand->mpNextBand->mnYTop )
+			{
+				// copy band with list and set new boundary
+				pNewBand = new ImplRegionBand( pBand->mnYBottom+1, pBand->mpNextBand->mnYTop-1 );
+
+				// insert band into the list
+				pNewBand->mpNextBand = pBand->mpNextBand;
+				pBand->mpNextBand = pNewBand;
+			}
+		}
+
+		pBand = pBand->mpNextBand;
+	}
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+}
+
+bool RegionBand::InsertSingleBand(ImplRegionBand* pBand, long nYBandPosition)
+{
+	// boundary already included in band with height 1? -> nothing to do!
+	if ( (pBand->mnYTop == pBand->mnYBottom) && (nYBandPosition == pBand->mnYTop) )
+    {
+        DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+		return true;
+    }
+
+	// insert single height band on top?
+	ImplRegionBand* pNewBand;
+
+    if ( nYBandPosition == pBand->mnYTop )
+	{
+		// copy band with list and set new boundary
+		pNewBand = new ImplRegionBand( *pBand );
+		pNewBand->mnYTop = nYBandPosition+1;
+
+		// insert band into the list
+		pNewBand->mpNextBand = pBand->mpNextBand;
+		pBand->mnYBottom = nYBandPosition;
+		pBand->mpNextBand = pNewBand;
+
+        DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+		return true;
+	}
+
+	// top of new rectangle within the current band? -> insert new band and copy data
+	if ( (nYBandPosition > pBand->mnYTop) && (nYBandPosition < pBand->mnYBottom) )
+	{
+		// copy band with list and set new boundary
+		pNewBand = new ImplRegionBand( *pBand );
+		pNewBand->mnYTop = nYBandPosition;
+
+		// insert band into the list
+		pNewBand->mpNextBand = pBand->mpNextBand;
+		pBand->mnYBottom = nYBandPosition;
+		pBand->mpNextBand = pNewBand;
+
+		// copy band with list and set new boundary
+		pNewBand = new ImplRegionBand( *pBand );
+		pNewBand->mnYTop = nYBandPosition;
+
+		// insert band into the list
+		pBand->mpNextBand->mnYTop = nYBandPosition+1;
+
+		pNewBand->mpNextBand = pBand->mpNextBand;
+		pBand->mnYBottom = nYBandPosition - 1;
+		pBand->mpNextBand = pNewBand;
+
+        DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+		return true;
+	}
+
+	// create new band behind the current in the list
+	if ( !pBand->mpNextBand )
+	{
+		if ( nYBandPosition == pBand->mnYBottom )
+		{
+			// copy band with list and set new boundary
+			pNewBand = new ImplRegionBand( *pBand );
+			pNewBand->mnYTop = pBand->mnYBottom;
+			pNewBand->mnYBottom = nYBandPosition;
+
+			pBand->mnYBottom = nYBandPosition-1;
+
+			// append band to the list
+			pBand->mpNextBand = pNewBand;
+            DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+			return true;
+		}
+
+		if ( nYBandPosition > pBand->mnYBottom )
+		{
+			// create new band
+			pNewBand = new ImplRegionBand( pBand->mnYBottom + 1, nYBandPosition );
+
+			// append band to the list
+			pBand->mpNextBand = pNewBand;
+            DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+			return true;
+		}
+	}
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+	return false;
+}
+
+void RegionBand::Union(long nLeft, long nTop, long nRight, long nBottom)
+{
+	DBG_ASSERT( nLeft <= nRight, "RegionBand::Union() - nLeft > nRight" );
+	DBG_ASSERT( nTop <= nBottom, "RegionBand::Union() - nTop > nBottom" );
+
+	// process union
+	ImplRegionBand* pBand = mpFirstBand;
+	while ( pBand )
+	{
+		if ( pBand->mnYTop >= nTop )
+		{
+			if ( pBand->mnYBottom <= nBottom )
+				pBand->Union( nLeft, nRight );
+			else
+			{
+#ifdef DBG_UTIL
+				long nCurY = pBand->mnYBottom;
+				pBand = pBand->mpNextBand;
+				while ( pBand )
+				{
+					if ( (pBand->mnYTop < nCurY) || (pBand->mnYBottom < nCurY) )
+					{
+						DBG_ERROR( "RegionBand::Union() - Bands not sorted!" );
+					}
+					pBand = pBand->mpNextBand;
+				}
+#endif
+				break;
+			}
+		}
+
+		pBand = pBand->mpNextBand;
+	}
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+}
+
+void RegionBand::Intersect(long nLeft, long nTop, long nRight, long nBottom)
+{
+    // process intersections
+    ImplRegionBand* pPrevBand = 0;
+    ImplRegionBand* pBand = mpFirstBand;
+
+    while(pBand)
+    {
+        // band within intersection boundary? -> process. otherwise remove
+        if((pBand->mnYTop >= nTop) && (pBand->mnYBottom <= nBottom))
+        {
+            // process intersection
+            pBand->Intersect(nLeft, nRight);
+            pPrevBand = pBand;
+            pBand = pBand->mpNextBand;
+        }
+        else
+        {
+            ImplRegionBand* pOldBand = pBand;
+
+            if(pBand == mpFirstBand)
+            {
+                mpFirstBand = pBand->mpNextBand;
+            }
+            else
+            {
+                pPrevBand->mpNextBand = pBand->mpNextBand;
+            }
+
+            pBand = pBand->mpNextBand;
+            delete pOldBand;
+        }
+    }
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+}
+
+void RegionBand::Union(const RegionBand& rSource)
+{
+	// apply all rectangles from rSource to this
+	ImplRegionBand* pBand = rSource.mpFirstBand;
+
+    while ( pBand )
+	{
+		// insert bands if the boundaries are not allready in the list
+		InsertBands(pBand->mnYTop, pBand->mnYBottom);
+
+		// process all elements of the list
+		ImplRegionBandSep* pSep = pBand->mpFirstSep;
+	
+        while(pSep)
+		{
+			Union(pSep->mnXLeft, pBand->mnYTop, pSep->mnXRight, pBand->mnYBottom);
+			pSep = pSep->mpNextSep;
+		}
+
+		pBand = pBand->mpNextBand;
+	}
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+}
+
+void RegionBand::Exclude(long nLeft, long nTop, long nRight, long nBottom)
+{
+	DBG_ASSERT( nLeft <= nRight, "RegionBand::Exclude() - nLeft > nRight" );
+	DBG_ASSERT( nTop <= nBottom, "RegionBand::Exclude() - nTop > nBottom" );
+
+	// process exclude
+	ImplRegionBand* pBand = mpFirstBand;
+
+    while(pBand)
+	{
+		if(pBand->mnYTop >= nTop)
+		{
+			if(pBand->mnYBottom <= nBottom)
+            {
+				pBand->Exclude(nLeft, nRight);
+            }
+			else
+			{
+#ifdef DBG_UTIL
+				long nCurY = pBand->mnYBottom;
+				pBand = pBand->mpNextBand;
+
+                while(pBand)
+				{
+					if((pBand->mnYTop < nCurY) || (pBand->mnYBottom < nCurY))
+					{
+						DBG_ERROR( "RegionBand::Exclude() - Bands not sorted!" );
+					}
+
+                    pBand = pBand->mpNextBand;
+				}
+#endif
+				break;
+			}
+		}
+
+		pBand = pBand->mpNextBand;
+	}
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+}
+
+void RegionBand::XOr(long nLeft, long nTop, long nRight, long nBottom)
+{
+	DBG_ASSERT( nLeft <= nRight, "RegionBand::Exclude() - nLeft > nRight" );
+	DBG_ASSERT( nTop <= nBottom, "RegionBand::Exclude() - nTop > nBottom" );
+
+	// process xor
+	ImplRegionBand* pBand = mpFirstBand;
+
+    while(pBand)
+	{
+		if(pBand->mnYTop >= nTop)
+		{
+			if(pBand->mnYBottom <= nBottom)
+            {
+				pBand->XOr(nLeft, nRight);
+            }
+			else
+			{
+#ifdef DBG_UTIL
+				long nCurY = pBand->mnYBottom;
+				pBand = pBand->mpNextBand;
+				
+                while(pBand)
+				{
+					if((pBand->mnYTop < nCurY) || (pBand->mnYBottom < nCurY))
+					{
+						DBG_ERROR( "RegionBand::XOr() - Bands not sorted!" );
+					}
+
+                    pBand = pBand->mpNextBand;
+				}
+#endif
+				break;
+			}
+		}
+
+		pBand = pBand->mpNextBand;
+	}
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+}
+
+void RegionBand::Intersect(const RegionBand& rSource)
+{
+    // mark all bands as untouched
+    ImplRegionBand* pBand = mpFirstBand;
+
+    while ( pBand )
+    {
+	    pBand->mbTouched = false;
+	    pBand = pBand->mpNextBand;
+    }
+
+    pBand = rSource.mpFirstBand;
+		
+    while ( pBand )
+    {
+	    // insert bands if the boundaries are not allready in the list
+	    InsertBands( pBand->mnYTop, pBand->mnYBottom );
+
+	    // process all elements of the list
+	    ImplRegionBandSep* pSep = pBand->mpFirstSep;
+		
+        while ( pSep )
+	    {
+		    // left boundary?
+		    if ( pSep == pBand->mpFirstSep )
+		    {
+			    // process intersection and do not remove untouched bands
+			    Exclude( LONG_MIN+1, pBand->mnYTop, pSep->mnXLeft-1, pBand->mnYBottom );
+		    }
+
+		    // right boundary?
+		    if ( pSep->mpNextSep == NULL )
+		    {
+			    // process intersection and do not remove untouched bands
+			    Exclude( pSep->mnXRight+1, pBand->mnYTop, LONG_MAX-1, pBand->mnYBottom );
+		    }
+		    else
+		    {
+			    // process intersection and do not remove untouched bands
+			    Exclude( pSep->mnXRight+1, pBand->mnYTop, pSep->mpNextSep->mnXLeft-1, pBand->mnYBottom );
+		    }
+
+		    pSep = pSep->mpNextSep;
+	    }
+
+	    pBand = pBand->mpNextBand;
+    }
+
+    // remove all untouched bands if bands allready left
+    ImplRegionBand* pPrevBand = 0;
+    pBand = mpFirstBand;
+
+    while ( pBand )
+    {
+	    if ( !pBand->mbTouched )
+	    {
+		    // save pointer
+		    ImplRegionBand* pOldBand = pBand;
+
+		    // previous element of the list
+		    if ( pBand == mpFirstBand )
+            {
+			    mpFirstBand = pBand->mpNextBand;
+            }
+		    else
+            {
+			    pPrevBand->mpNextBand = pBand->mpNextBand;
+            }
+
+		    pBand = pBand->mpNextBand;
+		    delete pOldBand;
+	    }
+	    else
+	    {
+		    pPrevBand = pBand;
+		    pBand = pBand->mpNextBand;
+	    }
+    }
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+}
+
+bool RegionBand::Exclude(const RegionBand& rSource)
+{
+    // Alle Rechtecke aus der uebergebenen Region auf diese Region anwenden
+    ImplRegionBand* pBand = rSource.mpFirstBand;
+
+    while ( pBand )
+    {
+	    // insert bands if the boundaries are not allready in the list
+	    InsertBands( pBand->mnYTop, pBand->mnYBottom );
+
+	    // process all elements of the list
+	    ImplRegionBandSep* pSep = pBand->mpFirstSep;
+	
+        while ( pSep )
+	    {
+		    Exclude( pSep->mnXLeft, pBand->mnYTop, pSep->mnXRight, pBand->mnYBottom );
+		    pSep = pSep->mpNextSep;
+	    }
+
+        // to test less bands, already check in the loop
+	    if ( !OptimizeBandList() )
+	    {
+            DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+            return false;
+	    }
+
+	    pBand = pBand->mpNextBand;
+    }
+
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+    return true;
+}
+
+Rectangle RegionBand::GetBoundRect() const
+{
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+
+    // get the boundaries of the first band
+	long nYTop(mpFirstBand->mnYTop);
+	long nYBottom(mpFirstBand->mnYBottom);
+	long nXLeft(mpFirstBand->GetXLeftBoundary());
+	long nXRight(mpFirstBand->GetXRightBoundary());
+
+	// look in the band list (don't test first band again!)
+	ImplRegionBand* pBand = mpFirstBand->mpNextBand;
+
+	while ( pBand )
+	{
+		nYBottom = pBand->mnYBottom;
+		nXLeft = std::min( nXLeft, pBand->GetXLeftBoundary() );
+		nXRight = std::max( nXRight, pBand->GetXRightBoundary() );
+
+		pBand = pBand->mpNextBand;
+	}
+
+    return Rectangle( nXLeft, nYTop, nXRight, nYBottom );
+}
+
+void RegionBand::XOr(const RegionBand& rSource)
+{
+    ImplRegionBand* pBand = rSource.mpFirstBand;
+
+    while ( pBand )
+    {
+	    // insert bands if the boundaries are not allready in the list
+	    InsertBands( pBand->mnYTop, pBand->mnYBottom );
+
+	    // process all elements of the list
+	    ImplRegionBandSep* pSep = pBand->mpFirstSep;
+
+        while ( pSep )
+	    {
+		    XOr( pSep->mnXLeft, pBand->mnYTop, pSep->mnXRight, pBand->mnYBottom );
+		    pSep = pSep->mpNextSep;
+	    }
+
+	    pBand = pBand->mpNextBand;
+    }
+}
+
+bool RegionBand::IsInside(const Point& rPoint) const
+{
+    DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+
+    // search band list
+    ImplRegionBand* pBand = mpFirstBand;
+
+    while(pBand)
+    {
+        // is point within band?
+        if((pBand->mnYTop <= rPoint.Y()) && (pBand->mnYBottom >= rPoint.Y()))
+        {
+            // is point within separation of the band?
+            DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
+            if(pBand->IsInside(rPoint.X()))
+            {
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+        
+        pBand = pBand->mpNextBand;
+    }
+
+    return false;
+}
+
+void RegionBand::GetRegionRectangles(RectangleVector& rTarget) const
+{
+    // clear result vector
+    rTarget.clear();
+    ImplRegionBand* mpCurrRectBand = mpFirstBand;
+    Rectangle aRectangle;
+
+    while(mpCurrRectBand)
+    {
+        ImplRegionBandSep* mpCurrRectBandSep = mpCurrRectBand->mpFirstSep;
+
+        aRectangle.Top() = mpCurrRectBand->mnYTop;
+        aRectangle.Bottom() = mpCurrRectBand->mnYBottom;
+
+        while(mpCurrRectBandSep)
+        {
+            aRectangle.Left() = mpCurrRectBandSep->mnXLeft;
+            aRectangle.Right() = mpCurrRectBandSep->mnXRight;
+            rTarget.push_back(aRectangle);
+            mpCurrRectBandSep = mpCurrRectBandSep->mpNextSep;
+        }
+
+        mpCurrRectBand = mpCurrRectBand->mpNextBand;
+    }
+}
+
+sal_uInt32 RegionBand::getRectangleCount() const
+{
+    sal_uInt32 nCount = 0;
+    const ImplRegionBand* pBand = mpFirstBand;
+
+    while(pBand)
+    {
+        ImplRegionBandSep* pSep = pBand->mpFirstSep;
+
+        while(pSep)
+        {
+            nCount++;
+            pSep = pSep->mpNextSep;
+        }
+
+        pBand = pBand->mpNextBand;
+    }
+
+    return 0;
+}
+
+#ifdef DBG_UTIL
+const char* ImplDbgTestRegionBand(const void* pObj)
+{
+    const RegionBand* pRegionBand = reinterpret_cast< const RegionBand* >(pObj);
+
+    if(pRegionBand)
+    {
+        const ImplRegionBand* pBand = pRegionBand->ImplGetFirstRegionBand();
+
+        while(pBand)
+        {
+            if(pBand->mnYBottom < pBand->mnYTop)
+            {
+                return "YBottom < YTop";
+            }
+
+            if(pBand->mpNextBand)
+            {
+                if(pBand->mnYBottom >= pBand->mpNextBand->mnYTop)
+                {
+                    return "overlapping bands in region";
+                }
+            }
+
+            if(pBand->mbTouched)
+            {
+                return "Band-mbTouched overwrite";
+            }
+
+            ImplRegionBandSep* pSep = pBand->mpFirstSep;
+
+            while(pSep)
+            {
+                if(pSep->mnXRight < pSep->mnXLeft)
+                {
+                    return "XLeft < XRight";
+                }
+
+                if(pSep->mpNextSep)
+                {
+                    if(pSep->mnXRight >= pSep->mpNextSep->mnXLeft)
+                    {
+                        return "overlapping separations in region";
+                    }
+                }
+
+                if ( pSep->mbRemoved > 1 )
+                {
+                    return "Sep-mbRemoved overwrite";
+                }
+
+                pSep = pSep->mpNextSep;
+            }
+
+            pBand = pBand->mpNextBand;
+        }
+    }
+
+    return 0;
+}
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+// eof

Propchange: incubator/ooo/trunk/main/vcl/source/gdi/regionband.cxx
------------------------------------------------------------------------------
    svn:executable = *

Modified: incubator/ooo/trunk/main/vcl/source/gdi/salgdilayout.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/source/gdi/salgdilayout.cxx?rev=1401294&r1=1401293&r2=1401294&view=diff
==============================================================================
--- incubator/ooo/trunk/main/vcl/source/gdi/salgdilayout.cxx (original)
+++ incubator/ooo/trunk/main/vcl/source/gdi/salgdilayout.cxx Tue Oct 23 13:46:28 2012
@@ -39,7 +39,6 @@
 #include <vcl/unowrap.hxx>
 
 #include <window.h>
-#include <region.h>
 #include <outdev.h>
 #include <sallayout.hxx>
 #include <salgdi.hxx>
@@ -250,28 +249,38 @@ sal_Bool SalGraphics::mirror( sal_uInt32
 
 void SalGraphics::mirror( Region& rRgn, const OutputDevice *pOutDev, bool bBack ) const
 {
-    if( rRgn.HasPolyPolygon() )
+    if( rRgn.HasPolyPolygonOrB2DPolyPolygon() )
     {
-        basegfx::B2DPolyPolygon aPolyPoly( rRgn.ConvertToB2DPolyPolygon() );
-        aPolyPoly = mirror( aPolyPoly, pOutDev, bBack );
-        rRgn = Region( aPolyPoly );
+        const basegfx::B2DPolyPolygon aPolyPoly(mirror(rRgn.GetAsB2DPolyPolygon(), pOutDev, bBack));
+
+        rRgn = Region(aPolyPoly);
     }
     else
     {
-        ImplRegionInfo		aInfo;
-        bool				bRegionRect;
-        Region              aMirroredRegion;
-        long nX, nY, nWidth, nHeight;
-        
-        bRegionRect = rRgn.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
-        while ( bRegionRect )
+        RectangleVector aRectangles;
+        rRgn.GetRegionRectangles(aRectangles);
+        rRgn.SetEmpty();
+
+        for(RectangleVector::iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
         {
-            Rectangle aRect( Point(nX, nY), Size(nWidth, nHeight) );
-            mirror( aRect, pOutDev, bBack );
-            aMirroredRegion.Union( aRect );
-            bRegionRect = rRgn.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
+            mirror(*aRectIter, pOutDev, bBack);
+            rRgn.Union(*aRectIter);
         }
-        rRgn = aMirroredRegion;
+
+        //ImplRegionInfo		aInfo;
+        //bool				bRegionRect;
+        //Region              aMirroredRegion;
+        //long nX, nY, nWidth, nHeight;
+        //
+        //bRegionRect = rRgn.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
+        //while ( bRegionRect )
+        //{
+        //    Rectangle aRect( Point(nX, nY), Size(nWidth, nHeight) );
+        //    mirror( aRect, pOutDev, bBack );
+        //    aMirroredRegion.Union( aRect );
+        //    bRegionRect = rRgn.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
+        //}
+        //rRgn = aMirroredRegion;
     }
 }
 

Modified: incubator/ooo/trunk/main/vcl/source/window/window.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/source/window/window.cxx?rev=1401294&r1=1401293&r2=1401294&view=diff
==============================================================================
--- incubator/ooo/trunk/main/vcl/source/window/window.cxx (original)
+++ incubator/ooo/trunk/main/vcl/source/window/window.cxx Tue Oct 23 13:46:28 2012
@@ -68,7 +68,6 @@
 #include "window.h"
 #include "toolbox.h"
 #include "outdev.h"
-#include "region.h"
 #include "brdwin.hxx"
 #include "helpwin.hxx"
 #include "sallayout.hxx"
@@ -151,8 +150,8 @@ ImplAccessibleInfos::~ImplAccessibleInfo
 WindowImpl::WindowImpl( WindowType nType )
 {
 	maZoom              = Fraction( 1, 1 );
-	maWinRegion         = Region( REGION_NULL );
-	maWinClipRegion                   = Region( REGION_NULL );
+	maWinRegion         = Region(true);
+	maWinClipRegion     = Region(true);
 	mpWinData           = NULL;         // Extra Window Data, that we dont need for all windows
 	mpOverlapData       = NULL;         // Overlap Data
 	mpFrameData         = NULL;         // Frame Data
@@ -1809,23 +1808,38 @@ sal_Bool Window::ImplSysObjClip( const R
                         aRegion.Move( -mnOutOffX, -mnOutOffY );
 
                     // ClipRegion setzen/updaten
-                    long                nX;
-                    long                nY;
-                    long                nWidth;
-                    long                nHeight;
-                    sal_uLong               nRectCount;
-                    ImplRegionInfo      aInfo;
-                    sal_Bool                bRegionRect;
-
-                    nRectCount = aRegion.GetRectCount();
-                    mpWindowImpl->mpSysObj->BeginSetClipRegion( nRectCount );
-                    bRegionRect = aRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
-                    while ( bRegionRect )
+                    RectangleVector aRectangles;
+                    aRegion.GetRegionRectangles(aRectangles);
+                    mpWindowImpl->mpSysObj->BeginSetClipRegion(aRectangles.size());
+
+                    for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
                     {
-                        mpWindowImpl->mpSysObj->UnionClipRegion( nX, nY, nWidth, nHeight );
-                        bRegionRect = aRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
+                        mpWindowImpl->mpSysObj->UnionClipRegion(
+                            aRectIter->Left(), 
+                            aRectIter->Top(), 
+                            aRectIter->GetWidth(),   // orig nWidth was ((R - L) + 1), same as GetWidth does
+                            aRectIter->GetHeight()); // same for height
                     }
+
                     mpWindowImpl->mpSysObj->EndSetClipRegion();
+
+                    //long                nX;
+                    //long                nY;
+                    //long                nWidth;
+                    //long                nHeight;
+                    //sal_uLong               nRectCount;
+                    //ImplRegionInfo      aInfo;
+                    //sal_Bool                bRegionRect;
+                    //
+                    //nRectCount = aRegion.GetRectCount();
+                    //mpWindowImpl->mpSysObj->BeginSetClipRegion( nRectCount );
+                    //bRegionRect = aRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
+                    //while ( bRegionRect )
+                    //{
+                    //    mpWindowImpl->mpSysObj->UnionClipRegion( nX, nY, nWidth, nHeight );
+                    //    bRegionRect = aRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
+                    //}
+                    //mpWindowImpl->mpSysObj->EndSetClipRegion();
                 }
             }
             else
@@ -2348,6 +2362,9 @@ void Window::ImplCalcOverlapRegion( cons
 
 void Window::ImplCallPaint( const Region* pRegion, sal_uInt16 nPaintFlags )
 {
+    Exception aException;
+    bool bExceptionCaught(false);
+
     // call PrePaint. PrePaint may add to the invalidate region as well as
     // other parameters used below.
     PrePaint();
@@ -2441,7 +2458,19 @@ void Window::ImplCallPaint( const Region
             if( mpWindowImpl->mbDrawSelectionBackground )
                 aSelectionRect = aPaintRect;
 
-            Paint( aPaintRect );
+            // Paint can throw exceptions; to not have a situation where
+            // mpWindowImpl->mbInPaint keeps to be on true (and other 
+            // settings, too) better catch here to avoid to go completely out of
+            // this method without executing the after-paint stuff
+            try
+            {
+                Paint( aPaintRect );
+            }
+            catch(Exception& rException)
+            {
+                aException = rException;
+                bExceptionCaught = true;
+            }
 
             if ( mpWindowImpl->mpWinData )
             {
@@ -2482,6 +2511,11 @@ void Window::ImplCallPaint( const Region
 
     if ( pChildRegion )
         delete pChildRegion;
+
+    if(bExceptionCaught)
+    {
+        throw(aException);
+    }
 }
 
 // -----------------------------------------------------------------------
@@ -6023,7 +6057,7 @@ void Window::SetWindowRegionPixel()
         mpWindowImpl->mpBorderWindow->SetWindowRegionPixel();
     else if( mpWindowImpl->mbFrame )
     {
-        mpWindowImpl->maWinRegion = Region( REGION_NULL);
+        mpWindowImpl->maWinRegion = Region(true);
         mpWindowImpl->mbWinRegion = sal_False;
         mpWindowImpl->mpFrame->ResetClipRegion();
     }
@@ -6031,7 +6065,7 @@ void Window::SetWindowRegionPixel()
     {
         if ( mpWindowImpl->mbWinRegion )
         {
-            mpWindowImpl->maWinRegion = Region( REGION_NULL );
+            mpWindowImpl->maWinRegion = Region(true);
             mpWindowImpl->mbWinRegion = sal_False;
             ImplSetClipFlag();
 
@@ -6060,30 +6094,46 @@ void Window::SetWindowRegionPixel( const
         mpWindowImpl->mpBorderWindow->SetWindowRegionPixel( rRegion );
     else if( mpWindowImpl->mbFrame )
     {
-        if( rRegion.GetType() != REGION_NULL )
+        if( !rRegion.IsNull() )
         {
             mpWindowImpl->maWinRegion = rRegion;
             mpWindowImpl->mbWinRegion = ! rRegion.IsEmpty();
+
             if( mpWindowImpl->mbWinRegion )
             {
                 // ClipRegion setzen/updaten
-                long                nX;
-                long                nY;
-                long                nWidth;
-                long                nHeight;
-                sal_uLong               nRectCount;
-                ImplRegionInfo      aInfo;
-                sal_Bool                bRegionRect;
-
-                nRectCount = mpWindowImpl->maWinRegion.GetRectCount();
-                mpWindowImpl->mpFrame->BeginSetClipRegion( nRectCount );
-                bRegionRect = mpWindowImpl->maWinRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
-                while ( bRegionRect )
+                RectangleVector aRectangles;
+                mpWindowImpl->maWinRegion.GetRegionRectangles(aRectangles);
+                mpWindowImpl->mpFrame->BeginSetClipRegion(aRectangles.size());
+
+                for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
                 {
-                    mpWindowImpl->mpFrame->UnionClipRegion( nX, nY, nWidth, nHeight );
-                    bRegionRect = mpWindowImpl->maWinRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
+                    mpWindowImpl->mpFrame->UnionClipRegion( 
+                        aRectIter->Left(), 
+                        aRectIter->Top(), 
+                        aRectIter->GetWidth(),       // orig nWidth was ((R - L) + 1), same as GetWidth does
+                        aRectIter->GetHeight());     // same for height
                 }
+
                 mpWindowImpl->mpFrame->EndSetClipRegion();
+
+                //long                nX;
+                //long                nY;
+                //long                nWidth;
+                //long                nHeight;
+                //sal_uLong               nRectCount;
+                //ImplRegionInfo      aInfo;
+                //sal_Bool                bRegionRect;
+                //
+                //nRectCount = mpWindowImpl->maWinRegion.GetRectCount();
+                //mpWindowImpl->mpFrame->BeginSetClipRegion( nRectCount );
+                //bRegionRect = mpWindowImpl->maWinRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
+                //while ( bRegionRect )
+                //{
+                //    mpWindowImpl->mpFrame->UnionClipRegion( nX, nY, nWidth, nHeight );
+                //    bRegionRect = mpWindowImpl->maWinRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
+                //}
+                //mpWindowImpl->mpFrame->EndSetClipRegion();
             }
             else
                 SetWindowRegionPixel();
@@ -6095,11 +6145,11 @@ void Window::SetWindowRegionPixel( const
     {
         sal_Bool bInvalidate = sal_False;
 
-        if ( rRegion.GetType() == REGION_NULL )
+        if ( rRegion.IsNull() )
         {
             if ( mpWindowImpl->mbWinRegion )
             {
-                mpWindowImpl->maWinRegion = Region( REGION_NULL );
+                mpWindowImpl->maWinRegion = Region(true);
                 mpWindowImpl->mbWinRegion = sal_False;
                 ImplSetClipFlag();
                 bInvalidate = sal_True;
@@ -6202,7 +6252,7 @@ Region Window::GetPaintRegion() const
     }
     else
     {
-        Region aPaintRegion( REGION_NULL );
+        Region aPaintRegion(true);
         return aPaintRegion;
     }
 }
@@ -6452,7 +6502,7 @@ void Window::Show( sal_Bool bVisible, sa
 
         if ( mpWindowImpl->mbReallyVisible )
         {
-            Region  aInvRegion( REGION_EMPTY );
+            Region  aInvRegion;
             sal_Bool    bSaveBack = sal_False;
 
             if ( ImplIsOverlapWindow() && !mpWindowImpl->mbFrame )

Modified: incubator/ooo/trunk/main/vcl/unx/generic/gdi/pspgraphics.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/unx/generic/gdi/pspgraphics.cxx?rev=1401294&r1=1401293&r2=1401294&view=diff
==============================================================================
--- incubator/ooo/trunk/main/vcl/unx/generic/gdi/pspgraphics.cxx (original)
+++ incubator/ooo/trunk/main/vcl/unx/generic/gdi/pspgraphics.cxx Tue Oct 23 13:46:28 2012
@@ -46,7 +46,6 @@
 #include "outfont.hxx"
 #include "fontsubset.hxx"
 #include "salprn.hxx"
-#include "region.h"
 
 #ifdef ENABLE_GRAPHITE
 #include <graphite_layout.hxx>
@@ -295,20 +294,45 @@ void PspGraphics::ResetClipRegion()
 bool PspGraphics::setClipRegion( const Region& i_rClip )
 {
     // TODO: support polygonal clipregions here
-    m_pPrinterGfx->BeginSetClipRegion( i_rClip.GetRectCount() );
+    RectangleVector aRectangles;
+    i_rClip.GetRegionRectangles(aRectangles);
+    m_pPrinterGfx->BeginSetClipRegion(aRectangles.size());
 
-    ImplRegionInfo aInfo;
-    long nX, nY, nW, nH;
-    bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
-    while( bRegionRect )
+    for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
     {
-        if ( nW && nH )
+        const long nW(aRectIter->GetWidth());
+
+        if(nW)
         {
-            m_pPrinterGfx->UnionClipRegion( nX, nY, nW, nH );
+            const long nH(aRectIter->GetHeight());
+
+            if(nH)
+            {
+                m_pPrinterGfx->UnionClipRegion(
+                    aRectIter->Left(), 
+                    aRectIter->Top(), 
+                    nW, 
+                    nH);
+            }
         }
-        bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
     }
+
     m_pPrinterGfx->EndSetClipRegion();
+
+    //m_pPrinterGfx->BeginSetClipRegion( i_rClip.GetRectCount() );
+    //
+    //ImplRegionInfo aInfo;
+    //long nX, nY, nW, nH;
+    //bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
+    //while( bRegionRect )
+    //{
+    //    if ( nW && nH )
+    //    {
+    //        m_pPrinterGfx->UnionClipRegion( nX, nY, nW, nH );
+    //    }
+    //    bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
+    //}
+    //m_pPrinterGfx->EndSetClipRegion();
     return true;
 }
 

Modified: incubator/ooo/trunk/main/vcl/unx/generic/gdi/salgdi.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/unx/generic/gdi/salgdi.cxx?rev=1401294&r1=1401293&r2=1401294&view=diff
==============================================================================
--- incubator/ooo/trunk/main/vcl/unx/generic/gdi/salgdi.cxx (original)
+++ incubator/ooo/trunk/main/vcl/unx/generic/gdi/salgdi.cxx Tue Oct 23 13:46:28 2012
@@ -49,7 +49,6 @@
 
 #include "printergfx.hxx"
 #include "xrender_peer.hxx"
-#include "region.h"
 
 #include <vector>
 #include <queue>
@@ -590,25 +589,49 @@ bool X11SalGraphics::setClipRegion( cons
     if( mpClipRegion )
         XDestroyRegion( mpClipRegion );
     mpClipRegion = XCreateRegion();
-    
-    ImplRegionInfo aInfo;
-    long nX, nY, nW, nH;
-    bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
-    while( bRegionRect )
+
+    RectangleVector aRectangles;
+    i_rClip.GetRegionRectangles(aRectangles);
+
+    for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
     {
-        if ( nW && nH )
+        const long nW(aRectIter->GetWidth());
+
+        if(nW)
         {
-            XRectangle aRect;
-            aRect.x			= (short)nX;
-            aRect.y			= (short)nY;
-            aRect.width		= (unsigned short)nW;
-            aRect.height	= (unsigned short)nH;
-            
-            XUnionRectWithRegion( &aRect, mpClipRegion, mpClipRegion );
+            const long nH(aRectIter->GetHeight());
+
+            if(nH)
+            {
+                XRectangle aRect;
+
+                aRect.x = (short)aRectIter->Left();
+                aRect.y = (short)aRectIter->Top();
+                aRect.width = (unsigned short)nW;
+                aRect.height = (unsigned short)nH;
+                XUnionRectWithRegion(&aRect, mpClipRegion, mpClipRegion);
+            }
         }
-        bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
     }
 
+    //ImplRegionInfo aInfo;
+    //long nX, nY, nW, nH;
+    //bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
+    //while( bRegionRect )
+    //{
+    //    if ( nW && nH )
+    //    {
+    //        XRectangle aRect;
+    //        aRect.x			= (short)nX;
+    //        aRect.y			= (short)nY;
+    //        aRect.width		= (unsigned short)nW;
+    //        aRect.height	= (unsigned short)nH;
+    //        
+    //        XUnionRectWithRegion( &aRect, mpClipRegion, mpClipRegion );
+    //    }
+    //    bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
+    //}
+
     // done, invalidate GCs
     bPenGC_			= sal_False;
     bFontGC_		= sal_False;

Modified: incubator/ooo/trunk/main/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx?rev=1401294&r1=1401293&r2=1401294&view=diff
==============================================================================
--- incubator/ooo/trunk/main/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx (original)
+++ incubator/ooo/trunk/main/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx Tue Oct 23 13:46:28 2012
@@ -760,16 +760,29 @@ sal_Bool GtkSalGraphics::drawNativeContr
     }
     else
     {
-        RegionHandle aHdl = aClipRegion.BeginEnumRects();
-        Rectangle aPaintRect;
-        while( aClipRegion.GetNextEnumRect( aHdl, aPaintRect ) )
+        RectangleVector aRectangles;
+        aClipRegion.GetRegionRectangles(aRectangles);
+
+        for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
         {
-            aPaintRect = aCtrlRect.GetIntersection( aPaintRect );
-            if( aPaintRect.IsEmpty() )
+            if(aRectIter->IsEmpty())
+            {
                 continue;
-            aClip.push_back( aPaintRect );
+            }
+
+            aClip.push_back(*aRectIter);
         }
-        aClipRegion.EndEnumRects( aHdl );
+
+        //RegionHandle aHdl = aClipRegion.BeginEnumRects();
+        //Rectangle aPaintRect;
+        //while( aClipRegion.GetEnumRects( aHdl, aPaintRect ) )
+        //{
+        //    aPaintRect = aCtrlRect.GetIntersection( aPaintRect );
+        //    if( aPaintRect.IsEmpty() )
+        //        continue;
+        //    aClip.push_back( aPaintRect );
+        //}
+        //aClipRegion.EndEnumRects( aHdl );
     }
     
     if ( (nType==CTRL_PUSHBUTTON) && (nPart==PART_ENTIRE_CONTROL) )

Modified: incubator/ooo/trunk/main/vcl/unx/headless/svpgdi.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/unx/headless/svpgdi.cxx?rev=1401294&r1=1401293&r2=1401294&view=diff
==============================================================================
--- incubator/ooo/trunk/main/vcl/unx/headless/svpgdi.cxx (original)
+++ incubator/ooo/trunk/main/vcl/unx/headless/svpgdi.cxx Tue Oct 23 13:46:28 2012
@@ -42,7 +42,6 @@
 #endif
 
 #include <svppspgraphics.hxx>
-#include <region.h>
 
 using namespace basegfx;
 using namespace basebmp;
@@ -149,40 +148,71 @@ void SvpSalGraphics::ResetClipRegion()
     m_aClipMap.reset();
 }
 
-bool SvpSalGraphics::setClipRegion( const Region& i_rClip )
-{
-    if( i_rClip.IsEmpty() )
-        m_aClipMap.reset();
-    else if( i_rClip.GetRectCount() == 1 )
-    {
-        m_aClipMap.reset();
-        Rectangle aBoundRect( i_rClip.GetBoundRect() );
-        m_aDevice = basebmp::subsetBitmapDevice( m_aOrigDevice,
-                                                 basegfx::B2IRange(aBoundRect.Left(),aBoundRect.Top(),aBoundRect.Right(),aBoundRect.Bottom()) );
-    }
-    else
-    {
-        m_aDevice = m_aOrigDevice;
-        B2IVector aSize = m_aDevice->getSize();
-        m_aClipMap = createBitmapDevice( aSize, false, Format::ONE_BIT_MSB_GREY );
-        m_aClipMap->clear( basebmp::Color(0xFFFFFFFF) );
-
-        ImplRegionInfo aInfo;
-        long nX, nY, nW, nH;
-        bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
-        while( bRegionRect )
-        {
-            if ( nW && nH )
-            {
-                B2DPolyPolygon aFull;
-                aFull.append( tools::createPolygonFromRect( B2DRectangle( nX, nY, nX+nW, nY+nH ) ) ); 
-                m_aClipMap->fillPolyPolygon( aFull, basebmp::Color(0), DrawMode_PAINT );
-            }
-            bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
-        }
-    }
-    return true;
-}
+bool SvpSalGraphics::setClipRegion( const Region& i_rClip )
+{
+    if( i_rClip.IsEmpty() )
+    {
+        m_aClipMap.reset();
+        return true;
+    }
+
+    RectangleVector aRectangles;
+    i_rClip.GetRegionRectangles(aRectangles);
+
+    if(1 == aRectangles.size())
+    {
+        m_aClipMap.reset();
+        const Rectangle& aBoundRect = aRectangles[0];
+        m_aDevice = basebmp::subsetBitmapDevice( 
+            m_aOrigDevice,
+            basegfx::B2IRange(aBoundRect.Left(),aBoundRect.Top(),aBoundRect.Right(),aBoundRect.Bottom()) );
+        return true;
+    }
+
+    m_aDevice = m_aOrigDevice;
+    B2IVector aSize = m_aDevice->getSize();
+    m_aClipMap = createBitmapDevice( aSize, false, Format::ONE_BIT_MSB_GREY );
+    m_aClipMap->clear( basebmp::Color(0xFFFFFFFF) );
+
+    for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
+    {
+        const long nW(aRectIter->GetWidth());
+
+        if(nW)
+        {
+            const long nH(aRectIter->GetHeight());
+
+            if(nH)
+            {
+                B2DPolyPolygon aFull;
+                
+                aFull.append(
+                    tools::createPolygonFromRect(
+                        B2DRectangle(
+                            aRectIter->Left(), 
+                            aRectIter->Top(), 
+                            aRectIter->Left() + nW, 
+                            aRectIter->Top() + nH))); 
+                m_aClipMap->fillPolyPolygon(aFull, basebmp::Color(0), DrawMode_PAINT);
+            }
+        }
+    }
+
+    //ImplRegionInfo aInfo;
+    //long nX, nY, nW, nH;
+    //bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
+    //while( bRegionRect )
+    //{
+    //    if ( nW && nH )
+    //    {
+    //        B2DPolyPolygon aFull;
+    //        aFull.append( tools::createPolygonFromRect( B2DRectangle( nX, nY, nX+nW, nY+nH ) ) ); 
+    //        m_aClipMap->fillPolyPolygon( aFull, basebmp::Color(0), DrawMode_PAINT );
+    //    }
+    //    bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
+    //}
+    return true;
+}
 
 void SvpSalGraphics::SetLineColor()
 {

Modified: incubator/ooo/trunk/main/vcl/unx/headless/svppspgraphics.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/unx/headless/svppspgraphics.cxx?rev=1401294&r1=1401293&r2=1401294&view=diff
==============================================================================
--- incubator/ooo/trunk/main/vcl/unx/headless/svppspgraphics.cxx (original)
+++ incubator/ooo/trunk/main/vcl/unx/headless/svppspgraphics.cxx Tue Oct 23 13:46:28 2012
@@ -51,7 +51,6 @@
 #include "printergfx.hxx"
 #include "svppspgraphics.hxx"
 #include "svpbmp.hxx"
-#include "region.h"
 
 using namespace psp;
 using namespace rtl;
@@ -220,19 +219,41 @@ void PspGraphics::ResetClipRegion()
 bool PspGraphics::setClipRegion( const Region& i_rClip )
 {
     // TODO: support polygonal clipregions here
-    m_pPrinterGfx->BeginSetClipRegion( i_rClip.GetRectCount() );
+    RectangleVector aRectangles;
+    i_rClip.GetRegionRectangles(aRectangles);
+    m_pPrinterGfx->BeginSetClipRegion(aRectangles.size());
 
-    ImplRegionInfo aInfo;
-    long nX, nY, nW, nH;
-    bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
-    while( bRegionRect )
+    for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
     {
-        if ( nW && nH )
+        const long nW(aRectIter->GetWidth());
+
+        if(nW)
         {
-            m_pPrinterGfx->UnionClipRegion( nX, nY, nW, nH );
+            const long nH(aRectIter->GetHeight());
+
+            if(nH)
+            {
+                m_pPrinterGfx->UnionClipRegion(
+                    aRectIter->Left(), 
+                    aRectIter->Top(), 
+                    nW, 
+                    nH);
+            }
         }
-        bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
     }
+
+    //ImplRegionInfo aInfo;
+    //long nX, nY, nW, nH;
+    //bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
+    //while( bRegionRect )
+    //{
+    //    if ( nW && nH )
+    //    {
+    //        m_pPrinterGfx->UnionClipRegion( nX, nY, nW, nH );
+    //    }
+    //    bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
+    //}
+
     m_pPrinterGfx->EndSetClipRegion();
     return true;
 }

Modified: incubator/ooo/trunk/main/vcl/win/source/gdi/salgdi.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/vcl/win/source/gdi/salgdi.cxx?rev=1401294&r1=1401293&r2=1401294&view=diff
==============================================================================
--- incubator/ooo/trunk/main/vcl/win/source/gdi/salgdi.cxx (original)
+++ incubator/ooo/trunk/main/vcl/win/source/gdi/salgdi.cxx Tue Oct 23 13:46:28 2012
@@ -41,8 +41,6 @@
 #include <win/salgdi.h>
 #include <win/salframe.h>
 
-#include <region.h>
-
 using namespace rtl;
 
 // =======================================================================
@@ -861,10 +859,9 @@ bool WinSalGraphics::setClipRegion( cons
 		mhRegion = 0;
 	}
 	
-	if( i_rClip.HasPolyPolygon() )
+	if( i_rClip.HasPolyPolygonOrB2DPolyPolygon() )
 	{
-	    // TODO: ConvertToB2DPolyPolygon actually is kind of const, just it does not advertise it in the header
-	    basegfx::B2DPolyPolygon aPolyPolygon( const_cast<Region&>(i_rClip).ConvertToB2DPolyPolygon() );
+	    const basegfx::B2DPolyPolygon aPolyPolygon( i_rClip.GetAsB2DPolyPolygon() );
         const sal_uInt32 nCount(aPolyPolygon.count());
     
         if( nCount )
@@ -872,12 +869,15 @@ bool WinSalGraphics::setClipRegion( cons
             std::vector< POINT > aPolyPoints;
             aPolyPoints.reserve( 1024 );
             std::vector< INT > aPolyCounts( nCount, 0 );
+            
             for(sal_uInt32 a(0); a < nCount; a++)
             {
-                basegfx::B2DPolygon aPoly( aPolyPolygon.getB2DPolygon(a) );
+                basegfx::B2DPolygon aPoly(aPolyPolygon.getB2DPolygon(a));
+                
                 aPoly = basegfx::tools::adaptiveSubdivideByDistance( aPoly, 1 );
                 const sal_uInt32 nPoints = aPoly.count();
                 aPolyCounts[a] = nPoints;
+                
                 for( sal_uInt32 b = 0; b < nPoints; b++ )
                 {
                     basegfx::B2DPoint aPt( aPoly.getB2DPoint( b ) );
@@ -887,15 +887,18 @@ bool WinSalGraphics::setClipRegion( cons
                     aPolyPoints.push_back( aPOINT );
                 }
             }
+            
             mhRegion = CreatePolyPolygonRgn( &aPolyPoints[0], &aPolyCounts[0], nCount, ALTERNATE );
         }
 	}
 	else
 	{
-	    ULONG nRectCount = i_rClip.GetRectCount();
+        RectangleVector aRectangles;
+        i_rClip.GetRegionRectangles(aRectangles);
 
-	    ULONG nRectBufSize = sizeof(RECT)*nRectCount;
-        if ( nRectCount < SAL_CLIPRECT_COUNT )
+        //ULONG nRectCount = i_rClip.GetRectCount();
+	    ULONG nRectBufSize = sizeof(RECT)*aRectangles.size();
+        if ( aRectangles.size() < SAL_CLIPRECT_COUNT )
         {
             if ( !mpStdClipRgnData )
                 mpStdClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+(SAL_CLIPRECT_COUNT*sizeof(RECT))];
@@ -905,50 +908,58 @@ bool WinSalGraphics::setClipRegion( cons
             mpClipRgnData = (RGNDATA*)new BYTE[sizeof(RGNDATA)-1+nRectBufSize];
         mpClipRgnData->rdh.dwSize	= sizeof( RGNDATAHEADER );
         mpClipRgnData->rdh.iType 	= RDH_RECTANGLES;
-        mpClipRgnData->rdh.nCount	= nRectCount;
+        mpClipRgnData->rdh.nCount	= aRectangles.size();
         mpClipRgnData->rdh.nRgnSize	= nRectBufSize;
         RECT*		pBoundRect = &(mpClipRgnData->rdh.rcBound);
         SetRectEmpty( pBoundRect );
         RECT* pNextClipRect         = (RECT*)(&(mpClipRgnData->Buffer));
         bool bFirstClipRect         = true;
 
-        ImplRegionInfo aInfo;
-        long nX, nY, nW, nH;
-        bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
-        while( bRegionRect )
+        for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
         {
-            if ( nW && nH )
+            const long nW(aRectIter->GetWidth());
+            const long nH(aRectIter->GetHeight());
+
+            if(nW && nH)
             {
-                long		nRight = nX + nW;
-                long		nBottom = nY + nH;
-                
-                if ( bFirstClipRect )
+                const long nRight(aRectIter->Left() + nW);
+                const long nBottom(aRectIter->Top() + nH);
+
+                if(bFirstClipRect)
                 {
-                    pBoundRect->left	= nX;
-                    pBoundRect->top 	= nY;
-                    pBoundRect->right	= nRight;
-                    pBoundRect->bottom	= nBottom;
+                    pBoundRect->left = aRectIter->Left();
+                    pBoundRect->top = aRectIter->Top();
+                    pBoundRect->right = nRight;
+                    pBoundRect->bottom = nBottom;
                     bFirstClipRect = false;
                 }
                 else
                 {
-                    if ( nX < pBoundRect->left )
-                        pBoundRect->left = (int)nX;
-                    
-                    if ( nY < pBoundRect->top )
-                        pBoundRect->top = (int)nY;
-                    
-                    if ( nRight > pBoundRect->right )
+                    if(aRectIter->Left() < pBoundRect->left)
+                    {
+                        pBoundRect->left = (int)aRectIter->Left();
+                    }
+
+                    if(aRectIter->Top() < pBoundRect->top)
+                    {
+                        pBoundRect->top = (int)aRectIter->Top();
+                    }
+
+                    if(nRight > pBoundRect->right)
+                    {
                         pBoundRect->right = (int)nRight;
-                    
-                    if ( nBottom > pBoundRect->bottom )
+                    }
+
+                    if(nBottom > pBoundRect->bottom)
+                    {
                         pBoundRect->bottom = (int)nBottom;
+                    }
                 }
-                
-                pNextClipRect->left 	= (int)nX;
-                pNextClipRect->top		= (int)nY;
-                pNextClipRect->right	= (int)nRight;
-                pNextClipRect->bottom	= (int)nBottom;
+
+                pNextClipRect->left = (int)aRectIter->Left();
+                pNextClipRect->top = (int)aRectIter->Top();
+                pNextClipRect->right = (int)nRight;
+                pNextClipRect->bottom = (int)nBottom;
                 pNextClipRect++;
             }
             else
@@ -956,8 +967,55 @@ bool WinSalGraphics::setClipRegion( cons
                 mpClipRgnData->rdh.nCount--;
                 mpClipRgnData->rdh.nRgnSize -= sizeof( RECT );
             }
-            bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
         }
+
+        //ImplRegionInfo aInfo;
+        //long nX, nY, nW, nH;
+        //bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
+        //while( bRegionRect )
+        //{
+        //    if ( nW && nH )
+        //    {
+        //        long		nRight = nX + nW;
+        //        long		nBottom = nY + nH;
+        //        
+        //        if ( bFirstClipRect )
+        //        {
+        //            pBoundRect->left	= nX;
+        //            pBoundRect->top 	= nY;
+        //            pBoundRect->right	= nRight;
+        //            pBoundRect->bottom	= nBottom;
+        //            bFirstClipRect = false;
+        //        }
+        //        else
+        //        {
+        //            if ( nX < pBoundRect->left )
+        //                pBoundRect->left = (int)nX;
+        //            
+        //            if ( nY < pBoundRect->top )
+        //                pBoundRect->top = (int)nY;
+        //            
+        //            if ( nRight > pBoundRect->right )
+        //                pBoundRect->right = (int)nRight;
+        //            
+        //            if ( nBottom > pBoundRect->bottom )
+        //                pBoundRect->bottom = (int)nBottom;
+        //        }
+        //        
+        //        pNextClipRect->left 	= (int)nX;
+        //        pNextClipRect->top		= (int)nY;
+        //        pNextClipRect->right	= (int)nRight;
+        //        pNextClipRect->bottom	= (int)nBottom;
+        //        pNextClipRect++;
+        //    }
+        //    else
+        //    {
+        //        mpClipRgnData->rdh.nCount--;
+        //        mpClipRgnData->rdh.nRgnSize -= sizeof( RECT );
+        //    }
+        //    bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
+        //}
+
         // create clip region from ClipRgnData
         if ( mpClipRgnData->rdh.nCount == 1 )
         {