aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkScan_Path.cpp
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-07-11 12:21:30 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-07-11 12:21:30 +0000
commit1501803e93a9c76b4632086d05c2813cb475db27 (patch)
tree6e3c9c5cd0bf7d0d48b44d9ee4b115f59dfe73b7 /src/core/SkScan_Path.cpp
parent991e5535fa759ded1b1c5a460c1e209e38f9b791 (diff)
limit clip to fixed-point range, so our edges don't overflow
git-svn-id: http://skia.googlecode.com/svn/trunk@1835 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core/SkScan_Path.cpp')
-rw-r--r--src/core/SkScan_Path.cpp39
1 files changed, 32 insertions, 7 deletions
diff --git a/src/core/SkScan_Path.cpp b/src/core/SkScan_Path.cpp
index af5d4b183c..8f5f99f691 100644
--- a/src/core/SkScan_Path.cpp
+++ b/src/core/SkScan_Path.cpp
@@ -578,33 +578,58 @@ SkScanClipper::SkScanClipper(SkBlitter* blitter, const SkRegion* clip,
///////////////////////////////////////////////////////////////////////////////
-void SkScan::FillPath(const SkPath& path, const SkRegion& clip,
+static bool clip_to_limit(const SkRegion& orig, SkRegion* reduced) {
+ const int32_t limit = 32767;
+
+ SkIRect limitR;
+ limitR.set(-limit, -limit, limit, limit);
+ if (limitR.contains(orig.getBounds())) {
+ return false;
+ }
+ reduced->op(orig, limitR, SkRegion::kIntersect_Op);
+ return true;
+}
+
+void SkScan::FillPath(const SkPath& path, const SkRegion& origClip,
SkBlitter* blitter) {
- if (clip.isEmpty()) {
+ if (origClip.isEmpty()) {
return;
}
+ // Our edges are fixed-point, and don't like the bounds of the clip to
+ // exceed that. Here we trim the clip just so we don't overflow later on
+ const SkRegion* clipPtr = &origClip;
+ SkRegion finiteClip;
+ if (clip_to_limit(origClip, &finiteClip)) {
+ if (finiteClip.isEmpty()) {
+ return;
+ }
+ clipPtr = &finiteClip;
+ }
+ // don't reference "origClip" any more, just use clipPtr
+
SkIRect ir;
path.getBounds().round(&ir);
if (ir.isEmpty()) {
if (path.isInverseFillType()) {
- blitter->blitRegion(clip);
+ blitter->blitRegion(*clipPtr);
}
return;
}
- SkScanClipper clipper(blitter, &clip, ir);
+ SkScanClipper clipper(blitter, clipPtr, ir);
blitter = clipper.getBlitter();
if (blitter) {
// we have to keep our calls to blitter in sorted order, so we
// must blit the above section first, then the middle, then the bottom.
if (path.isInverseFillType()) {
- sk_blit_above(blitter, ir, clip);
+ sk_blit_above(blitter, ir, *clipPtr);
}
- sk_fill_path(path, clipper.getClipRect(), blitter, ir.fTop, ir.fBottom, 0, clip);
+ sk_fill_path(path, clipper.getClipRect(), blitter, ir.fTop, ir.fBottom,
+ 0, *clipPtr);
if (path.isInverseFillType()) {
- sk_blit_below(blitter, ir, clip);
+ sk_blit_below(blitter, ir, *clipPtr);
}
} else {
// what does it mean to not have a blitter if path.isInverseFillType???