summaryrefslogtreecommitdiff
path: root/vcl/win
diff options
context:
space:
mode:
authorArmin Le Grand <alg@apache.org>2013-08-13 15:10:34 +0000
committerCaolán McNamara <caolanm@redhat.com>2013-08-14 11:32:19 +0100
commitb5c9668d34acdbce500609725760d6578debb95a (patch)
tree0e61d3bb269c40fb010b86684637a9be9cb13c1b /vcl/win
parentb74a2e6ee80e30ed42ef99e24f85eb1d2df346ca (diff)
Resolves: #i122149# Corrected stuff around polygon-based clip regions
do not use them where not needed (cherry picked from commit 4ccb1eb7d58005ab3b501b7c6ff128fadbcd5066) Conflicts: basegfx/inc/basegfx/matrix/b2dhommatrixtools.hxx basegfx/inc/basegfx/polygon/b2dpolygontools.hxx basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx basegfx/inc/basegfx/tuple/b2dtuple.hxx basegfx/inc/basegfx/tuple/b3dtuple.hxx sc/source/ui/inc/output.hxx sc/source/ui/view/gridwin.cxx sc/source/ui/view/output.cxx vcl/win/source/gdi/salgdi.cxx Change-Id: Ie265814a51180bffe3c821a3f2148cb3bb54ecad
Diffstat (limited to 'vcl/win')
-rw-r--r--vcl/win/source/gdi/salgdi.cxx80
1 files changed, 68 insertions, 12 deletions
diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx
index 8928d519cc18..e3a660f3f7b1 100644
--- a/vcl/win/source/gdi/salgdi.cxx
+++ b/vcl/win/source/gdi/salgdi.cxx
@@ -20,20 +20,18 @@
#include <stdio.h>
#include <string.h>
-
#include <svsys.h>
#include <rtl/strbuf.hxx>
-
#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>
// =======================================================================
@@ -846,8 +844,40 @@ bool WinSalGraphics::setClipRegion( const Region& i_rClip )
mhRegion = 0;
}
- if( i_rClip.HasPolyPolygonOrB2DPolyPolygon() )
+ bool bUsePolygon(i_rClip.HasPolyPolygonOrB2DPolyPolygon());
+ static bool bTryToAvoidPolygon(true);
+
+ // #i122149# 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)
{
+ // #i122149# 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());
@@ -856,21 +886,38 @@ bool WinSalGraphics::setClipRegion( const Region& i_rClip )
std::vector< POINT > aPolyPoints;
aPolyPoints.reserve( 1024 );
std::vector< INT > aPolyCounts( nCount, 0 );
+ basegfx::B2DHomMatrix aExpand;
+ static bool bExpandByOneInXandY(true);
- for(sal_uInt32 a(0); a < nCount; a++)
+ if(bExpandByOneInXandY)
{
- basegfx::B2DPolygon aPoly(aPolyPolygon.getB2DPolygon(a));
+ 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));
+ }
- aPoly = basegfx::tools::adaptiveSubdivideByDistance( aPoly, 1 );
- const sal_uInt32 nPoints = aPoly.count();
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ 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();
+ // #i122149# do correct rounding
+ aPOINT.x = basegfx::fround(aPt.getX());
+ aPOINT.y = basegfx::fround(aPt.getY());
aPolyPoints.push_back( aPOINT );
}
}
@@ -993,7 +1040,16 @@ bool WinSalGraphics::setClipRegion( const Region& i_rClip )
}
if( 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;
}