fix bug (and add test) for drawing an inverse-path whose bounds do intersect

the clip, but whose edges do not (e.g. a curve). We used to overdraw a section
(and assert).



git-svn-id: http://skia.googlecode.com/svn/trunk@3809 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@google.com 2012-05-01 14:49:28 +00:00
parent af7e6943b7
commit 9d5f76a250
2 changed files with 62 additions and 5 deletions

View File

@ -424,11 +424,25 @@ void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitte
if (count < 2) {
if (path.isInverseFillType()) {
const SkIRect& clipRect = clipRgn.getBounds();
blitter->blitRect(clipRect.fLeft << shiftEdgesUp,
clipRect.fTop << shiftEdgesUp,
clipRect.width() << shiftEdgesUp,
clipRect.height() << shiftEdgesUp);
/*
* Since we are in inverse-fill, our caller has already drawn above
* our top (start_y) and will draw below our bottom (stop_y). Thus
* we need to restrict our drawing to the intersection of the clip
* and those two limits.
*/
SkIRect rect = clipRgn.getBounds();
if (rect.fTop < start_y) {
rect.fTop = start_y;
}
if (rect.fBottom > stop_y) {
rect.fBottom = stop_y;
}
if (!rect.isEmpty()) {
blitter->blitRect(rect.fLeft << shiftEdgesUp,
rect.fTop << shiftEdgesUp,
rect.width() << shiftEdgesUp,
rect.height() << shiftEdgesUp);
}
}
return;

View File

@ -28,6 +28,48 @@ static SkCanvas* new_canvas(int w, int h) {
///////////////////////////////////////////////////////////////////////////////
// Need to exercise drawing an inverse-path whose bounds intersect the clip,
// but whose edges do not (since its a quad which draws only in the bottom half
// of its bounds).
// In the debug build, we used to assert in this case, until it was fixed.
//
static void test_inversepathwithclip(skiatest::Reporter* reporter) {
SkPath path;
path.moveTo(0, SkIntToScalar(20));
path.quadTo(SkIntToScalar(10), SkIntToScalar(10),
SkIntToScalar(20), SkIntToScalar(20));
path.toggleInverseFillType();
SkPaint paint;
SkAutoTUnref<SkCanvas> canvas(new_canvas(640, 480));
canvas.get()->save();
canvas.get()->clipRect(SkRect::MakeWH(SkIntToScalar(19), SkIntToScalar(11)));
paint.setAntiAlias(false);
canvas.get()->drawPath(path, paint);
paint.setAntiAlias(true);
canvas.get()->drawPath(path, paint);
canvas.get()->restore();
// Now do the test again, with the path flipped, so we only draw in the
// top half of our bounds, and have the clip intersect our bounds at the
// bottom.
path.reset(); // preserves our filltype
path.moveTo(0, SkIntToScalar(10));
path.quadTo(SkIntToScalar(10), SkIntToScalar(20),
SkIntToScalar(20), SkIntToScalar(10));
canvas.get()->clipRect(SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(19),
SkIntToScalar(19), SkIntToScalar(11)));
paint.setAntiAlias(false);
canvas.get()->drawPath(path, paint);
paint.setAntiAlias(true);
canvas.get()->drawPath(path, paint);
}
static void test_bug533(skiatest::Reporter* reporter) {
#ifdef SK_SCALAR_IS_FLOAT
/*
@ -95,6 +137,7 @@ static void TestDrawPath(skiatest::Reporter* reporter) {
test_bug533(reporter);
test_bigcubic(reporter);
test_crbug_124652(reporter);
test_inversepathwithclip(reporter);
}
#include "TestClassDef.h"