explicitly pass bounds.top to the edgelist walker, so we don't leave any gaps

when the path is in an inverse fillmode, and its top or bottom are on a
fractional boundary. (thanks senorblanco)



git-svn-id: http://skia.googlecode.com/svn/trunk@504 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@android.com 2010-02-22 16:05:48 +00:00
parent da6fb3246a
commit dca6a56b71
3 changed files with 18 additions and 9 deletions

View File

@ -37,7 +37,7 @@ private:
// clipRect == null means path is entirely inside the clip
void sk_fill_path(const SkPath& path, const SkIRect* clipRect,
SkBlitter* blitter, int stop_y, int shiftEdgesUp,
SkBlitter* blitter, int start_y, int stop_y, int shiftEdgesUp,
const SkRegion& clipRgn);
// blit the rects above and below avoid, clipped to clp

View File

@ -412,11 +412,11 @@ void SkScan::AntiFillPath(const SkPath& path, const SkRegion& clip,
{
MaskSuperBlitter superBlit(blitter, ir, clip);
SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop);
sk_fill_path(path, superClipRect, &superBlit, ir.fBottom, SHIFT, clip);
sk_fill_path(path, superClipRect, &superBlit, ir.fTop, ir.fBottom, SHIFT, clip);
}
else
{
SuperBlitter superBlit(blitter, ir, clip);
sk_fill_path(path, superClipRect, &superBlit, ir.fBottom, SHIFT, clip);
sk_fill_path(path, superClipRect, &superBlit, ir.fTop, ir.fBottom, SHIFT, clip);
}
}

View File

@ -127,11 +127,12 @@ typedef void (*PrePostProc)(SkBlitter* blitter, int y, bool isStartOfScanline);
#define PREPOST_END false
static void walk_edges(SkEdge* prevHead, SkPath::FillType fillType,
SkBlitter* blitter, int stop_y, PrePostProc proc)
SkBlitter* blitter, int start_y, int stop_y,
PrePostProc proc)
{
validate_sort(prevHead->fNext);
int curr_y = prevHead->fNext->fFirstY;
int curr_y = start_y;
// returns 1 for evenodd, -1 for winding, regardless of inverse-ness
int windingMask = (fillType & 1) ? 1 : -1;
@ -476,7 +477,7 @@ static SkEdge* sort_edges(SkEdge* list[], int count, SkEdge** last) {
// clipRect (if no null) has already been shifted up
//
void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitter,
int stop_y, int shiftEdgesUp, const SkRegion& clipRgn)
int start_y, int stop_y, int shiftEdgesUp, const SkRegion& clipRgn)
{
SkASSERT(&path && blitter);
@ -527,7 +528,11 @@ void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitte
// now edge is the head of the sorted linklist
start_y <<= shiftEdgesUp;
stop_y <<= shiftEdgesUp;
if (clipRect && start_y < clipRect->fTop) {
start_y = clipRect->fTop;
}
if (clipRect && stop_y > clipRect->fBottom) {
stop_y = clipRect->fBottom;
}
@ -541,7 +546,7 @@ void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitte
proc = PrePostInverseBlitterProc;
}
walk_edges(&headEdge, path.getFillType(), blitter, stop_y, proc);
walk_edges(&headEdge, path.getFillType(), blitter, start_y, stop_y, proc);
}
void sk_blit_above_and_below(SkBlitter* blitter, const SkIRect& ir,
@ -625,7 +630,7 @@ void SkScan::FillPath(const SkPath& path, const SkRegion& clip,
if (path.isInverseFillType()) {
sk_blit_above_and_below(blitter, ir, clip);
}
sk_fill_path(path, clipper.getClipRect(), blitter, ir.fBottom, 0, clip);
sk_fill_path(path, clipper.getClipRect(), blitter, ir.fTop, ir.fBottom, 0, clip);
} else {
// what does it mean to not have a blitter if path.isInverseFillType???
}
@ -685,7 +690,11 @@ static void sk_fill_triangle(const SkPoint pts[], const SkIRect* clipRect,
if (clipRect && stop_y > clipRect->fBottom) {
stop_y = clipRect->fBottom;
}
walk_edges(&headEdge, SkPath::kEvenOdd_FillType, blitter, stop_y, NULL);
int start_y = ir.fTop;
if (clipRect && start_y < clipRect->fTop) {
start_y = clipRect->fTop;
}
walk_edges(&headEdge, SkPath::kEvenOdd_FillType, blitter, start_y, stop_y, NULL);
}
void SkScan::FillTriangle(const SkPoint pts[], const SkRegion* clip,