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 2013/08/13 17:10:34 UTC

svn commit: r1513541 - in /openoffice/trunk/main: basegfx/inc/basegfx/matrix/ basegfx/inc/basegfx/polygon/ basegfx/inc/basegfx/tuple/ basegfx/source/matrix/ basegfx/source/polygon/ sc/source/ui/inc/ sc/source/ui/view/ vcl/source/gdi/ vcl/win/source/gdi/

Author: alg
Date: Tue Aug 13 15:10:34 2013
New Revision: 1513541

URL: http://svn.apache.org/r1513541
Log:
i122149 Corrected stuff around polygon-based clip regions, do not use them where nt needed

Modified:
    openoffice/trunk/main/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx
    openoffice/trunk/main/basegfx/inc/basegfx/polygon/b2dpolygontools.hxx
    openoffice/trunk/main/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx
    openoffice/trunk/main/basegfx/inc/basegfx/tuple/b2dtuple.hxx
    openoffice/trunk/main/basegfx/inc/basegfx/tuple/b3dtuple.hxx
    openoffice/trunk/main/basegfx/source/matrix/b2dhommatrixtools.cxx
    openoffice/trunk/main/basegfx/source/polygon/b2dpolygon.cxx
    openoffice/trunk/main/basegfx/source/polygon/b2dpolygontools.cxx
    openoffice/trunk/main/basegfx/source/polygon/b2dpolypolygoncutter.cxx
    openoffice/trunk/main/basegfx/source/polygon/b2dpolypolygontools.cxx
    openoffice/trunk/main/sc/source/ui/inc/output.hxx
    openoffice/trunk/main/sc/source/ui/view/gridwin.cxx
    openoffice/trunk/main/sc/source/ui/view/output.cxx
    openoffice/trunk/main/vcl/source/gdi/region.cxx
    openoffice/trunk/main/vcl/win/source/gdi/salgdi.cxx

Modified: openoffice/trunk/main/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx?rev=1513541&r1=1513540&r2=1513541&view=diff
==============================================================================
--- openoffice/trunk/main/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx (original)
+++ openoffice/trunk/main/basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx Tue Aug 13 15:10:34 2013
@@ -27,6 +27,7 @@
 #include <sal/types.h>
 #include <basegfx/matrix/b2dhommatrix.hxx>
 #include <basegfx/vector/b2dvector.hxx>
+#include <basegfx/range/b2drange.hxx>
 
 namespace rtl { class OUString; }
 
@@ -131,6 +132,11 @@ namespace basegfx
                 fRadiant);
         }
 
+        /// special for the case to map from source range to target range
+        B2DHomMatrix createSourceRangeTargetRangeTransform(
+            const B2DRange& rSourceRange,
+            const B2DRange& rTargetRange);
+
     } // end of namespace tools
 } // end of namespace basegfx
 

Modified: openoffice/trunk/main/basegfx/inc/basegfx/polygon/b2dpolygontools.hxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/basegfx/inc/basegfx/polygon/b2dpolygontools.hxx?rev=1513541&r1=1513540&r2=1513541&view=diff
==============================================================================
--- openoffice/trunk/main/basegfx/inc/basegfx/polygon/b2dpolygontools.hxx (original)
+++ openoffice/trunk/main/basegfx/inc/basegfx/polygon/b2dpolygontools.hxx Tue Aug 13 15:10:34 2013
@@ -527,6 +527,11 @@ namespace basegfx
 		*/
 		B2DPolygon snapPointsOfHorizontalOrVerticalEdges(const B2DPolygon& rCandidate);
 
+        /** returns true if the Polygon only contains horizontal or vertical edges
+            so that it could be represented by RegionBands
+        */
+        bool containsOnlyHorizontalAndVerticalEdges(const B2DPolygon& rCandidate);
+
     } // end of namespace tools
 } // end of namespace basegfx
 

Modified: openoffice/trunk/main/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx?rev=1513541&r1=1513540&r2=1513541&view=diff
==============================================================================
--- openoffice/trunk/main/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx (original)
+++ openoffice/trunk/main/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx Tue Aug 13 15:10:34 2013
@@ -275,7 +275,12 @@ namespace basegfx
 		*/
 		B2DPolyPolygon snapPointsOfHorizontalOrVerticalEdges(const B2DPolyPolygon& rCandidate);
 
-	} // end of namespace tools
+        /** returns true if the Polygon only contains horizontal or vertical edges
+            so that it could be represented by RegionBands
+        */
+        bool containsOnlyHorizontalAndVerticalEdges(const B2DPolyPolygon& rCandidate);
+
+    } // end of namespace tools
 } // end of namespace basegfx
 
 #endif /* _BGFX_POLYPOLYGON_B2DPOLYGONTOOLS_HXX */

Modified: openoffice/trunk/main/basegfx/inc/basegfx/tuple/b2dtuple.hxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/basegfx/inc/basegfx/tuple/b2dtuple.hxx?rev=1513541&r1=1513540&r2=1513541&view=diff
==============================================================================
--- openoffice/trunk/main/basegfx/inc/basegfx/tuple/b2dtuple.hxx (original)
+++ openoffice/trunk/main/basegfx/inc/basegfx/tuple/b2dtuple.hxx Tue Aug 13 15:10:34 2013
@@ -220,12 +220,12 @@ namespace basegfx
 		
 		bool operator==( const B2DTuple& rTup ) const 
 		{ 
-			return equal(rTup);
+			return mfX == rTup.mfX && mfY == rTup.mfY;
 		}
 
 		bool operator!=( const B2DTuple& rTup ) const 
 		{ 
-			return !equal(rTup);
+			return mfX != rTup.mfX || mfY != rTup.mfY;
 		}
 		
 		B2DTuple& operator=( const B2DTuple& rTup ) 

Modified: openoffice/trunk/main/basegfx/inc/basegfx/tuple/b3dtuple.hxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/basegfx/inc/basegfx/tuple/b3dtuple.hxx?rev=1513541&r1=1513540&r2=1513541&view=diff
==============================================================================
--- openoffice/trunk/main/basegfx/inc/basegfx/tuple/b3dtuple.hxx (original)
+++ openoffice/trunk/main/basegfx/inc/basegfx/tuple/b3dtuple.hxx Tue Aug 13 15:10:34 2013
@@ -252,12 +252,12 @@ namespace basegfx
 
 		bool operator==( const B3DTuple& rTup ) const 
 		{ 
-			return equal(rTup);
+			return mfX == rTup.mfX && mfY == rTup.mfY && mfZ == rTup.mfZ;
 		}
 
 		bool operator!=( const B3DTuple& rTup ) const 
 		{ 
-			return !equal(rTup);
+			return mfX != rTup.mfX || mfY != rTup.mfY || mfZ != rTup.mfZ;
 		}
 		
 		B3DTuple& operator=( const B3DTuple& rTup ) 

Modified: openoffice/trunk/main/basegfx/source/matrix/b2dhommatrixtools.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/basegfx/source/matrix/b2dhommatrixtools.cxx?rev=1513541&r1=1513540&r2=1513541&view=diff
==============================================================================
--- openoffice/trunk/main/basegfx/source/matrix/b2dhommatrixtools.cxx (original)
+++ openoffice/trunk/main/basegfx/source/matrix/b2dhommatrixtools.cxx Tue Aug 13 15:10:34 2013
@@ -390,6 +390,47 @@ namespace basegfx
 
             return aRetval;
         }
+
+        /// special for the case to map from source range to target range
+        B2DHomMatrix createSourceRangeTargetRangeTransform(
+            const B2DRange& rSourceRange,
+            const B2DRange& rTargetRange)
+        {
+            B2DHomMatrix aRetval;
+
+            if(&rSourceRange == &rTargetRange)
+            {
+                return aRetval;
+            }
+
+            if(!fTools::equalZero(rSourceRange.getMinX()) || !fTools::equalZero(rSourceRange.getMinY()))
+            {
+                aRetval.set(0, 2, -rSourceRange.getMinX());
+                aRetval.set(1, 2, -rSourceRange.getMinY());
+            }
+
+            const double fSourceW(rSourceRange.getWidth());
+            const double fSourceH(rSourceRange.getHeight());
+            const bool bDivX(!fTools::equalZero(fSourceW) && !fTools::equal(fSourceW, 1.0));
+            const bool bDivY(!fTools::equalZero(fSourceH) && !fTools::equal(fSourceH, 1.0));
+            const double fScaleX(bDivX ? rTargetRange.getWidth() / fSourceW : rTargetRange.getWidth());
+            const double fScaleY(bDivY ? rTargetRange.getHeight() / fSourceH : rTargetRange.getHeight());
+
+            if(!fTools::equalZero(fScaleX) || !fTools::equalZero(fScaleY))
+            {
+                aRetval.scale(fScaleX, fScaleY);
+            }
+
+            if(!fTools::equalZero(rTargetRange.getMinX()) || !fTools::equalZero(rTargetRange.getMinY()))
+            {
+                aRetval.translate(
+                    rTargetRange.getMinX(), 
+                    rTargetRange.getMinY());
+            }
+
+            return aRetval;
+        }
+
     } // end of namespace tools
 } // end of namespace basegfx
 

Modified: openoffice/trunk/main/basegfx/source/polygon/b2dpolygon.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/basegfx/source/polygon/b2dpolygon.cxx?rev=1513541&r1=1513540&r2=1513541&view=diff
==============================================================================
--- openoffice/trunk/main/basegfx/source/polygon/b2dpolygon.cxx (original)
+++ openoffice/trunk/main/basegfx/source/polygon/b2dpolygon.cxx Tue Aug 13 15:10:34 2013
@@ -1258,7 +1258,7 @@ namespace basegfx
 	{
 		OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
 
-		if(getB2DPoint(nIndex) != rValue)
+		if(mpPolygon->getPoint(nIndex) != rValue)
 		{
 			mpPolygon->setPoint(nIndex, rValue);
 		}

Modified: openoffice/trunk/main/basegfx/source/polygon/b2dpolygontools.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/basegfx/source/polygon/b2dpolygontools.cxx?rev=1513541&r1=1513540&r2=1513541&view=diff
==============================================================================
--- openoffice/trunk/main/basegfx/source/polygon/b2dpolygontools.cxx (original)
+++ openoffice/trunk/main/basegfx/source/polygon/b2dpolygontools.cxx Tue Aug 13 15:10:34 2013
@@ -3627,7 +3627,40 @@ namespace basegfx
 			}
 		}
 
-	} // end of namespace tools
+        bool containsOnlyHorizontalAndVerticalEdges(const B2DPolygon& rCandidate)
+        {
+            if(rCandidate.areControlPointsUsed())
+            {
+                return false;
+            }
+
+            const sal_uInt32 nPointCount(rCandidate.count());
+
+            if(nPointCount < 2)
+            {
+                return true;
+            }
+
+            const sal_uInt32 nEdgeCount(rCandidate.isClosed() ? nPointCount + 1 : nPointCount);
+            basegfx::B2DPoint aLast(rCandidate.getB2DPoint(0));
+
+            for(sal_uInt32 a(1); a < nEdgeCount; a++)
+            {
+                const sal_uInt32 nNextIndex(a % nPointCount);
+                const basegfx::B2DPoint aCurrent(rCandidate.getB2DPoint(nNextIndex));
+
+                if(!basegfx::fTools::equal(aLast.getX(), aCurrent.getX()) && !basegfx::fTools::equal(aLast.getY(), aCurrent.getY()))
+                {
+                    return false;
+                }
+
+                aLast = aCurrent;
+            }
+
+            return true;
+        }
+
+    } // end of namespace tools
 } // end of namespace basegfx
 
 //////////////////////////////////////////////////////////////////////////////

Modified: openoffice/trunk/main/basegfx/source/polygon/b2dpolypolygoncutter.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/basegfx/source/polygon/b2dpolypolygoncutter.cxx?rev=1513541&r1=1513540&r2=1513541&view=diff
==============================================================================
--- openoffice/trunk/main/basegfx/source/polygon/b2dpolypolygoncutter.cxx (original)
+++ openoffice/trunk/main/basegfx/source/polygon/b2dpolypolygoncutter.cxx Tue Aug 13 15:10:34 2013
@@ -110,6 +110,8 @@ namespace basegfx
 		typedef ::std::vector< PN > PNV;
 		typedef ::std::vector< VN > VNV;
 		typedef ::std::vector< SN > SNV;
+        typedef ::std::pair< basegfx::B2DPoint /*orig*/, basegfx::B2DPoint /*repl*/ > CorrectionPair;
+        typedef ::std::vector< CorrectionPair > CorrectionTable;
 
 		//////////////////////////////////////////////////////////////////////////////
 
@@ -120,6 +122,7 @@ namespace basegfx
             PNV                     maPNV;
             VNV                     maVNV;
             SNV                     maSNV;
+            CorrectionTable         maCorrectionTable;
 
             unsigned                mbIsCurve : 1;
             unsigned                mbChanged : 1;
@@ -462,25 +465,56 @@ namespace basegfx
                 }
             }
 
-			void impSolve()
-			{
-		        // sort by point to identify common nodes
-		        ::std::sort(maSNV.begin(), maSNV.end());
+            void impSolve()
+            {
+                // sort by point to identify common nodes easier
+                ::std::sort(maSNV.begin(), maSNV.end());
 
-		        // handle common nodes
-				const sal_uInt32 nNodeCount(maSNV.size());
+                // handle common nodes
+                const sal_uInt32 nNodeCount(maSNV.size());
+                sal_uInt32 a(0);
+
+                // snap unsharp-equal points
+                if(nNodeCount)
+                {
+                    basegfx::B2DPoint* pLast(&maSNV[0].mpPN->maPoint);
 
-		        for(sal_uInt32 a(0); a < nNodeCount - 1; a++)
-		        {
-			        // test a before using it, not after. Also use nPointCount instead of aSortNodes.size()
+                    for(a = 1; a < nNodeCount; a++)
+                    {
+                        basegfx::B2DPoint* pCurrent(&maSNV[a].mpPN->maPoint);
+
+                        if(pLast->equal(*pCurrent) && (pLast->getX() != pCurrent->getX() || pLast->getY() != pCurrent->getY()))
+                        {
+                            const basegfx::B2DPoint aMiddle((*pLast + *pCurrent) * 0.5);
+
+                            if(pLast->getX() != aMiddle.getX() || pLast->getY() != aMiddle.getY())
+                            {
+                                maCorrectionTable.push_back(CorrectionPair(*pLast, aMiddle));
+                                *pLast = aMiddle;
+                            }
+
+                            if(pCurrent->getX() != aMiddle.getX() || pCurrent->getY() != aMiddle.getY())
+                            {
+                                maCorrectionTable.push_back(CorrectionPair(*pCurrent, aMiddle));
+                                *pCurrent = aMiddle;
+                            }
+                        }
+
+                        pLast = pCurrent;
+                    }
+                }
+
+                for(a = 0; a < nNodeCount - 1; a++)
+                {
+                    // test a before using it, not after. Also use nPointCount instead of aSortNodes.size()
                     PN& rPNb = *(maSNV[a].mpPN);
 
-			        for(sal_uInt32 b(a + 1); b < nNodeCount && rPNb.maPoint.equal(maSNV[b].mpPN->maPoint); b++)
-			        {
-				        impHandleCommon(rPNb, *maSNV[b].mpPN);
-			        }
-		        }
-			}
+                    for(sal_uInt32 b(a + 1); b < nNodeCount && rPNb.maPoint.equal(maSNV[b].mpPN->maPoint); b++)
+                    {
+                        impHandleCommon(rPNb, *maSNV[b].mpPN);
+                    }
+                }
+            }
 
 		public:
             solver(const B2DPolygon& rOriginal)
@@ -638,12 +672,49 @@ namespace basegfx
 
 					return aRetval;
 				}
-				else
-				{
-					// no change, return original
-					return maOriginal;
-				}
-			}
+                else
+                {
+                    const sal_uInt32 nCorrectionSize(maCorrectionTable.size());
+
+                    // no change, return original
+                    if(!nCorrectionSize)
+                    {
+                        return maOriginal;
+                    }
+
+                    // apply coordinate corrections to ensure inside/outside correctness after solving
+                    const sal_uInt32 nPolygonCount(maOriginal.count());
+                    basegfx::B2DPolyPolygon aRetval(maOriginal);
+
+                    for(sal_uInt32 a(0); a < nPolygonCount; a++)
+                    {
+                        basegfx::B2DPolygon aTemp(aRetval.getB2DPolygon(a));
+                        const sal_uInt32 nPointCount(aTemp.count());
+                        bool bChanged;
+
+                        for(sal_uInt32 b(0); b < nPointCount; b++)
+                        {
+                            const basegfx::B2DPoint aCandidate(aTemp.getB2DPoint(b));
+
+                            for(sal_uInt32 c(0); c < nCorrectionSize; c++)
+                            {
+                                if(maCorrectionTable[c].first.getX() == aCandidate.getX() && maCorrectionTable[c].first.getY() == aCandidate.getY())
+                                {
+                                    aTemp.setB2DPoint(b, maCorrectionTable[c].second);
+                                    bChanged = true;
+                                }
+                            }
+                        }
+
+                        if(bChanged)
+                        {
+                            aRetval.setB2DPolygon(a, aTemp);
+                        }
+                    }
+
+                    return aRetval;
+                }
+            }
         };
 
 		//////////////////////////////////////////////////////////////////////////////

Modified: openoffice/trunk/main/basegfx/source/polygon/b2dpolypolygontools.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/basegfx/source/polygon/b2dpolypolygontools.cxx?rev=1513541&r1=1513540&r2=1513541&view=diff
==============================================================================
--- openoffice/trunk/main/basegfx/source/polygon/b2dpolypolygontools.cxx (original)
+++ openoffice/trunk/main/basegfx/source/polygon/b2dpolypolygontools.cxx Tue Aug 13 15:10:34 2013
@@ -594,7 +594,24 @@ namespace basegfx
 			return aRetval;
 		}
 
-	} // end of namespace tools
+        bool containsOnlyHorizontalAndVerticalEdges(const B2DPolyPolygon& rCandidate)
+        {
+            if(rCandidate.areControlPointsUsed())
+            {
+                return false;
+            }
+
+            for(sal_uInt32 a(0); a < rCandidate.count(); a++)
+            {
+                if(!containsOnlyHorizontalAndVerticalEdges(rCandidate.getB2DPolygon(a)))
+                {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+    } // end of namespace tools
 } // end of namespace basegfx
 
 //////////////////////////////////////////////////////////////////////////////

Modified: openoffice/trunk/main/sc/source/ui/inc/output.hxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/sc/source/ui/inc/output.hxx?rev=1513541&r1=1513540&r2=1513541&view=diff
==============================================================================
--- openoffice/trunk/main/sc/source/ui/inc/output.hxx (original)
+++ openoffice/trunk/main/sc/source/ui/inc/output.hxx Tue Aug 13 15:10:34 2013
@@ -245,7 +245,7 @@ public:
 	void	DrawSelectiveObjects(const sal_uInt16 nLayer);
 
 	sal_Bool	SetChangedClip();		// sal_False = nix
-    PolyPolygon GetChangedArea();
+    Region      GetChangedAreaRegion();
 
 	void	FindChanged();
 	void	SetPagebreakMode( ScPageBreakData* pPageData );

Modified: openoffice/trunk/main/sc/source/ui/view/gridwin.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/sc/source/ui/view/gridwin.cxx?rev=1513541&r1=1513540&r2=1513541&view=diff
==============================================================================
--- openoffice/trunk/main/sc/source/ui/view/gridwin.cxx (original)
+++ openoffice/trunk/main/sc/source/ui/view/gridwin.cxx Tue Aug 13 15:10:34 2013
@@ -4449,10 +4449,12 @@ void ScGridWindow::UpdateFormulas()
 
     aOutputData.FindChanged();
 
-    PolyPolygon aChangedPoly( aOutputData.GetChangedArea() );   // logic (PixelToLogic)
-    if ( aChangedPoly.Count() )
+    // #122149# do not use old GetChangedArea() which used polygon-based Regions, but use
+    // the region-band based new version; anyways, only rectangles are added
+    Region aChangedRegion( aOutputData.GetChangedAreaRegion() );   // logic (PixelToLogic)
+    if(!aChangedRegion.IsEmpty())
     {
-        Invalidate( aChangedPoly );
+        Invalidate(aChangedRegion);
     }
 
     CheckNeedsRepaint();    // #i90362# used to be called via Draw() - still needed here

Modified: openoffice/trunk/main/sc/source/ui/view/output.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/sc/source/ui/view/output.cxx?rev=1513541&r1=1513540&r2=1513541&view=diff
==============================================================================
--- openoffice/trunk/main/sc/source/ui/view/output.cxx (original)
+++ openoffice/trunk/main/sc/source/ui/view/output.cxx Tue Aug 13 15:10:34 2013
@@ -1685,42 +1685,46 @@ void ScOutputData::DrawRotatedFrame( con
 
 //	Drucker
 
-PolyPolygon ScOutputData::GetChangedArea()
+Region ScOutputData::GetChangedAreaRegion()
 {
-	PolyPolygon aPoly;
+    Region aRegion;
+    Rectangle aDrawingRect;
+    bool bHad(false);
+    long nPosY = nScrY;
+    SCSIZE nArrY;
 
-	Rectangle aDrawingRect;
-	aDrawingRect.Left() = nScrX;
-	aDrawingRect.Right() = nScrX+nScrW-1;
+    aDrawingRect.Left() = nScrX;
+    aDrawingRect.Right() = nScrX+nScrW-1;
 
-	sal_Bool	bHad	= sal_False;
-	long	nPosY	= nScrY;
-	SCSIZE	nArrY;
-	for (nArrY=1; nArrY+1<nArrCount; nArrY++)
-	{
-		RowInfo* pThisRowInfo = &pRowInfo[nArrY];
+    for(nArrY=1; nArrY+1<nArrCount; nArrY++)
+    {
+        RowInfo* pThisRowInfo = &pRowInfo[nArrY];
 
-		if ( pThisRowInfo->bChanged )
-		{
-			if (!bHad)
-			{
-				aDrawingRect.Top() = nPosY;
-				bHad = sal_True;
-			}
-			aDrawingRect.Bottom() = nPosY + pRowInfo[nArrY].nHeight - 1;
-		}
-		else if (bHad)
-		{
-			aPoly.Insert( Polygon( pDev->PixelToLogic(aDrawingRect) ) );
-			bHad = sal_False;
-		}
-		nPosY += pRowInfo[nArrY].nHeight;
-	}
+        if(pThisRowInfo->bChanged)
+        {
+            if(!bHad)
+            {
+                aDrawingRect.Top() = nPosY;
+                bHad = true;
+            }
 
-	if (bHad)
-		aPoly.Insert( Polygon( pDev->PixelToLogic(aDrawingRect) ) );
+            aDrawingRect.Bottom() = nPosY + pRowInfo[nArrY].nHeight - 1;
+        }
+        else if(bHad)
+        {
+            aRegion.Union(pDev->PixelToLogic(aDrawingRect));
+            bHad = false;
+        }
+
+        nPosY += pRowInfo[nArrY].nHeight;
+    }
+
+    if(bHad)
+    {
+        aRegion.Union(pDev->PixelToLogic(aDrawingRect));
+    }
 
-    return aPoly;
+    return aRegion;
 }
 
 sal_Bool ScOutputData::SetChangedClip()

Modified: openoffice/trunk/main/vcl/source/gdi/region.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/source/gdi/region.cxx?rev=1513541&r1=1513540&r2=1513541&view=diff
==============================================================================
--- openoffice/trunk/main/vcl/source/gdi/region.cxx (original)
+++ openoffice/trunk/main/vcl/source/gdi/region.cxx Tue Aug 13 15:10:34 2013
@@ -1274,9 +1274,10 @@ Rectangle Region::GetBoundRect() const
         }
         else
         {
+            // #122149# corrected rounding, no need for ceil() and floor() here
             return Rectangle(
-                static_cast<sal_Int32>(floor(aRange.getMinX())), static_cast<sal_Int32>(floor(aRange.getMinY())),
-                static_cast<sal_Int32>(ceil(aRange.getMaxX())), static_cast<sal_Int32>(ceil(aRange.getMaxY())));
+                basegfx::fround(aRange.getMinX()), basegfx::fround(aRange.getMinY()), 
+                basegfx::fround(aRange.getMaxX()), basegfx::fround(aRange.getMaxY()));
         }
 	}
 

Modified: openoffice/trunk/main/vcl/win/source/gdi/salgdi.cxx
URL: http://svn.apache.org/viewvc/openoffice/trunk/main/vcl/win/source/gdi/salgdi.cxx?rev=1513541&r1=1513540&r2=1513541&view=diff
==============================================================================
--- openoffice/trunk/main/vcl/win/source/gdi/salgdi.cxx (original)
+++ openoffice/trunk/main/vcl/win/source/gdi/salgdi.cxx Tue Aug 13 15:10:34 2013
@@ -26,20 +26,18 @@
 
 #include <stdio.h>
 #include <string.h>
-
 #include <rtl/strbuf.hxx>
-
 #include <tools/svwin.h>
 #include <tools/debug.hxx>
 #include <tools/poly.hxx>
-
 #include <basegfx/polygon/b2dpolygon.hxx>
 #include <basegfx/polygon/b2dpolygontools.hxx>
-
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
 #include <win/wincomp.hxx>
 #include <win/saldata.hxx>
 #include <win/salgdi.h>
 #include <win/salframe.h>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
 
 using namespace rtl;
 
@@ -853,15 +851,47 @@ void WinSalGraphics::ResetClipRegion()
 
 bool WinSalGraphics::setClipRegion( const Region& i_rClip )
 {
-	if ( mhRegion )
-	{
-		DeleteRegion( mhRegion );
-		mhRegion = 0;
-	}
-	
-	if( i_rClip.HasPolyPolygonOrB2DPolyPolygon() )
-	{
-	    const basegfx::B2DPolyPolygon aPolyPolygon( i_rClip.GetAsB2DPolyPolygon() );
+    if ( mhRegion )
+    {
+        DeleteRegion( mhRegion );
+        mhRegion = 0;
+    }
+
+    bool bUsePolygon(i_rClip.HasPolyPolygonOrB2DPolyPolygon());
+    static bool bTryToAvoidPolygon(true);
+
+    // #122149# try to avoid usage of PolyPolygon ClipRegions when PolyPolygon is no curve
+    // and only contains horizontal/vertical edges. In that case, use the fallback
+    // in GetRegionRectangles which will use Region::GetAsRegionBand() which will do
+    // the correct polygon-to-RegionBand transformation.
+    // Background is that when using the same Rectangle as rectangle or as Polygon
+    // clip region will lead to different results; the polygon-based one will be
+    // one pixel less to the right and down (see GDI docu for CreatePolygonRgn). This
+    // again is because of the polygon-nature and it's classic handling when filling.
+    // This also means that all cases which use a 'true' polygon-based incarnation of
+    // a Region should know what they do - it may lead to repaint errors.
+    if(bUsePolygon && bTryToAvoidPolygon)
+    {
+        const basegfx::B2DPolyPolygon aPolyPolygon( i_rClip.GetAsB2DPolyPolygon() );
+
+        if(!aPolyPolygon.areControlPointsUsed())
+        {
+            if(basegfx::tools::containsOnlyHorizontalAndVerticalEdges(aPolyPolygon))
+            {
+                bUsePolygon = false;
+            }
+        }
+    }
+
+    if(bUsePolygon)
+    {
+        // #122149# check the comment above to know that this may lead to potentioal repaint
+        // problems. It may be solved (if needed) by scaling the polygon by one in X
+        // and Y. Currently the workaround to only use it if really unavoidable will
+        // solve most cases. When someone is really using polygon-based Regions he 
+        // should know what he is doing.
+        // Added code to do that scaling to check if it works, testing it.
+        const basegfx::B2DPolyPolygon aPolyPolygon( i_rClip.GetAsB2DPolyPolygon() );
         const sal_uInt32 nCount(aPolyPolygon.count());
     
         if( nCount )
@@ -869,21 +899,38 @@ bool WinSalGraphics::setClipRegion( cons
             std::vector< POINT > aPolyPoints;
             aPolyPoints.reserve( 1024 );
             std::vector< INT > aPolyCounts( nCount, 0 );
-            
+            basegfx::B2DHomMatrix aExpand;
+            static bool bExpandByOneInXandY(true);
+
+            if(bExpandByOneInXandY)
+            {
+                const basegfx::B2DRange aRangeS(aPolyPolygon.getB2DRange());
+                const basegfx::B2DRange aRangeT(aRangeS.getMinimum(), aRangeS.getMaximum() + basegfx::B2DTuple(1.0, 1.0));
+                aExpand = basegfx::B2DHomMatrix(basegfx::tools::createSourceRangeTargetRangeTransform(aRangeS, aRangeT));
+            }
+
             for(sal_uInt32 a(0); a < nCount; a++)
             {
-                basegfx::B2DPolygon aPoly(aPolyPolygon.getB2DPolygon(a));
-                
-                aPoly = basegfx::tools::adaptiveSubdivideByDistance( aPoly, 1 );
-                const sal_uInt32 nPoints = aPoly.count();
+                const basegfx::B2DPolygon aPoly(
+                    basegfx::tools::adaptiveSubdivideByDistance(
+                        aPolyPolygon.getB2DPolygon(a), 
+                        1));
+                const sal_uInt32 nPoints(aPoly.count());
                 aPolyCounts[a] = nPoints;
-                
+
                 for( sal_uInt32 b = 0; b < nPoints; b++ )
                 {
-                    basegfx::B2DPoint aPt( aPoly.getB2DPoint( b ) );
+                    basegfx::B2DPoint aPt(aPoly.getB2DPoint(b));
+
+                    if(bExpandByOneInXandY)
+                    {
+                        aPt = aExpand * aPt;
+                    }
+
                     POINT aPOINT;
-                    aPOINT.x = (LONG)aPt.getX();
-                    aPOINT.y = (LONG)aPt.getY();
+                    // #122149# do correct rounding
+                    aPOINT.x = basegfx::fround(aPt.getX());
+                    aPOINT.y = basegfx::fround(aPt.getY());
                     aPolyPoints.push_back( aPOINT );
                 }
             }
@@ -969,53 +1016,6 @@ bool WinSalGraphics::setClipRegion( cons
             }
         }
 
-        //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 )
         {
@@ -1054,7 +1054,16 @@ bool WinSalGraphics::setClipRegion( cons
 	}
 
 	if( mhRegion )
-	    SelectClipRgn( getHDC(), mhRegion );
+    {
+        SelectClipRgn( getHDC(), mhRegion );
+
+        // debug code if you weant to check range of the newly applied ClipRegion
+        //RECT aBound;
+        //const int aRegionType = GetRgnBox(mhRegion, &aBound);
+        //
+        //bool bBla = true;
+    }
+
 	return mhRegion != 0;
 }