summaryrefslogtreecommitdiff
path: root/basebmp/inc
diff options
context:
space:
mode:
authorThorsten Behrens <tbehrens@suse.com>2011-11-15 12:24:52 +0100
committerThorsten Behrens <tbehrens@suse.com>2011-11-15 12:38:50 +0100
commitb53d2bc9dd92079c030346af57e9b1a0078a05e7 (patch)
tree492f6e07cf7dc7251a83e1afa9a1b54c4137e3d6 /basebmp/inc
parent2264f482e57e989e649934d3980368f2b135d496 (diff)
Fix clipped line renderer.
Fix for a nasty corner case where supposedly clipped pixel were still rasterized (see polytest.cxx:implTestPolyDrawClip for what failed previously). Added much more unit tests while at it, clippedlinerenderer.hxx should now have 100% coverage.
Diffstat (limited to 'basebmp/inc')
-rw-r--r--basebmp/inc/basebmp/clippedlinerenderer.hxx55
-rw-r--r--basebmp/inc/basebmp/debug.hxx10
2 files changed, 40 insertions, 25 deletions
diff --git a/basebmp/inc/basebmp/clippedlinerenderer.hxx b/basebmp/inc/basebmp/clippedlinerenderer.hxx
index d1c06f66e076..01262c0f4056 100644
--- a/basebmp/inc/basebmp/clippedlinerenderer.hxx
+++ b/basebmp/inc/basebmp/clippedlinerenderer.hxx
@@ -65,7 +65,8 @@ inline bool prepareClip( sal_Int32 a1,
sal_uInt32 bMinFlag,
sal_Int32 bMax,
sal_uInt32 bMaxFlag,
- bool bRoundTowardsPt2 )
+ bool bRoundTowardsPt2,
+ bool& o_bUseAlternateBresenham )
{
int ca(0), cb(0);
if( clipCode1 )
@@ -103,13 +104,13 @@ inline bool prepareClip( sal_Int32 a1,
{
o_bs = b1 + cb;
if( o_bs > bMax )
- return false;
+ return false; // fully clipped
}
else
{
o_bs = b1 - cb;
if( o_bs < bMin )
- return false;
+ return false; // fully clipped
}
io_rem += ca - 2*da*cb;
@@ -121,13 +122,13 @@ inline bool prepareClip( sal_Int32 a1,
{
o_as = a1 + ca;
if( o_as > aMax )
- return false;
+ return false; // fully clipped
}
else
{
o_as = a1 - ca;
if( o_as < aMin )
- return false;
+ return false; // fully clipped
}
io_rem += 2*db*ca - cb;
@@ -138,7 +139,6 @@ inline bool prepareClip( sal_Int32 a1,
o_as = a1; o_bs = b1;
}
- bool bRetVal = false;
if( clipCode2 )
{
if( clipCount2 == 2 )
@@ -153,13 +153,13 @@ inline bool prepareClip( sal_Int32 a1,
else
{
o_n = (clipCode2 & bMinFlag) ? o_bs - bMin : bMax - o_bs;
- bRetVal = true;
+ o_bUseAlternateBresenham = true;
}
}
else
o_n = (a2 >= o_as) ? a2 - o_as : o_as - a2;
- return bRetVal;
+ return true; // at least one pixel to render
}
@@ -214,7 +214,7 @@ void renderClippedLine( basegfx::B2IPoint aPt1,
rClipRect);
if( clipCode1 & clipCode2 )
- return; // line fully clipped away
+ return; // line fully clipped away, both endpoints share a half-plane
sal_uInt32 clipCount1 = basegfx::tools::getNumberOfClipPlanes(clipCode1);
sal_uInt32 clipCount2 = basegfx::tools::getNumberOfClipPlanes(clipCode2);
@@ -254,19 +254,20 @@ void renderClippedLine( basegfx::B2IPoint aPt1,
int n = 0;
sal_Int32 xs = x1;
sal_Int32 ys = y1;
+ bool bUseAlternateBresenham=false;
if( adx >= ady )
{
// semi-horizontal line
sal_Int32 rem = 2*ady - adx - !bRoundTowardsPt2;
- const bool bUseAlternateBresenham(
- prepareClip(x1, x2, y1, adx, ady, xs, ys, sx, sy,
- rem, n, clipCode1, clipCount1, clipCode2, clipCount2,
- rClipRect.getMinX(), basegfx::tools::RectClipFlags::LEFT,
- rClipRect.getMaxX()-1, basegfx::tools::RectClipFlags::RIGHT,
- rClipRect.getMinY(), basegfx::tools::RectClipFlags::TOP,
- rClipRect.getMaxY()-1, basegfx::tools::RectClipFlags::BOTTOM,
- bRoundTowardsPt2 ));
+ if( !prepareClip(x1, x2, y1, adx, ady, xs, ys, sx, sy,
+ rem, n, clipCode1, clipCount1, clipCode2, clipCount2,
+ rClipRect.getMinX(), basegfx::tools::RectClipFlags::LEFT,
+ rClipRect.getMaxX()-1, basegfx::tools::RectClipFlags::RIGHT,
+ rClipRect.getMinY(), basegfx::tools::RectClipFlags::TOP,
+ rClipRect.getMaxY()-1, basegfx::tools::RectClipFlags::BOTTOM,
+ bRoundTowardsPt2, bUseAlternateBresenham ) )
+ return; // line fully clipped away, no active pixel inside rect
Iterator currIter( begin + vigra::Diff2D(0,ys) );
typename vigra::IteratorTraits<Iterator>::row_iterator
@@ -283,6 +284,8 @@ void renderClippedLine( basegfx::B2IPoint aPt1,
if( rem >= 0 )
{
+ // this is intended - we clip endpoint against y
+ // plane, so n here denotes y range to render
if( --n < 0 )
break;
@@ -335,14 +338,14 @@ void renderClippedLine( basegfx::B2IPoint aPt1,
// semi-vertical line
sal_Int32 rem = 2*adx - ady - !bRoundTowardsPt2;
- const bool bUseAlternateBresenham(
- prepareClip(y1, y2, x1, ady, adx, ys, xs, sy, sx,
- rem, n, clipCode1, clipCount1, clipCode2, clipCount2,
- rClipRect.getMinY(), basegfx::tools::RectClipFlags::TOP,
- rClipRect.getMaxY()-1, basegfx::tools::RectClipFlags::BOTTOM,
- rClipRect.getMinX(), basegfx::tools::RectClipFlags::LEFT,
- rClipRect.getMaxX()-1, basegfx::tools::RectClipFlags::RIGHT,
- bRoundTowardsPt2 ));
+ if( !prepareClip(y1, y2, x1, ady, adx, ys, xs, sy, sx,
+ rem, n, clipCode1, clipCount1, clipCode2, clipCount2,
+ rClipRect.getMinY(), basegfx::tools::RectClipFlags::TOP,
+ rClipRect.getMaxY()-1, basegfx::tools::RectClipFlags::BOTTOM,
+ rClipRect.getMinX(), basegfx::tools::RectClipFlags::LEFT,
+ rClipRect.getMaxX()-1, basegfx::tools::RectClipFlags::RIGHT,
+ bRoundTowardsPt2, bUseAlternateBresenham ) )
+ return; // line fully clipped away, no active pixel inside rect
Iterator currIter( begin + vigra::Diff2D(xs,0) );
typename vigra::IteratorTraits<Iterator>::column_iterator
@@ -359,6 +362,8 @@ void renderClippedLine( basegfx::B2IPoint aPt1,
if( rem >= 0 )
{
+ // this is intended - we clip endpoint against x
+ // plane, so n here denotes x range to render
if( --n < 0 )
break;
diff --git a/basebmp/inc/basebmp/debug.hxx b/basebmp/inc/basebmp/debug.hxx
index 0193af7e1498..0a8c7219318d 100644
--- a/basebmp/inc/basebmp/debug.hxx
+++ b/basebmp/inc/basebmp/debug.hxx
@@ -46,6 +46,16 @@ namespace basebmp
Stream to write output to.
Used in vcl/headless/svpgdi.cxx when OSL_DEBUG_LEVEL > 2
+
+ Use like this:
+<pre>
+ #include <basebmp/debug.hxx>
+ #include <iostream>
+ #include <fstream>
+
+ std::ofstream output("/tmp/my_test.dump");
+ debugDump( pMyDevice, output );
+</pre>
*/
void BASEBMP_DLLPUBLIC debugDump( const boost::shared_ptr< BitmapDevice >& rDevice,
::std::ostream& rOutputStream );