aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2010-02-22 16:05:48 +0000
committerGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2010-02-22 16:05:48 +0000
commitdca6a56b71b922aab32098d6a55bbb041f3a2b48 (patch)
tree387ffb79788ac12f9a379890fa3458b94aecf7cf /src
parentda6fb3246a4f3e7e835f23b4834affb80bb613fa (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/core/SkScanPriv.h2
-rw-r--r--src/core/SkScan_AntiPath.cpp4
-rw-r--r--src/core/SkScan_Path.cpp21
3 files changed, 18 insertions, 9 deletions
diff --git a/src/core/SkScanPriv.h b/src/core/SkScanPriv.h
index 43dfdef486..74c2ee768e 100644
--- a/src/core/SkScanPriv.h
+++ b/src/core/SkScanPriv.h
@@ -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
diff --git a/src/core/SkScan_AntiPath.cpp b/src/core/SkScan_AntiPath.cpp
index 7b24f73d56..21fd5c99b7 100644
--- a/src/core/SkScan_AntiPath.cpp
+++ b/src/core/SkScan_AntiPath.cpp
@@ -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);
}
}
diff --git a/src/core/SkScan_Path.cpp b/src/core/SkScan_Path.cpp
index 9751d2a4c3..38f16e61e5 100644
--- a/src/core/SkScan_Path.cpp
+++ b/src/core/SkScan_Path.cpp
@@ -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,