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 )
{