aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gm/hugepath.cpp31
-rw-r--r--src/core/SkScanPriv.h4
-rw-r--r--src/core/SkScan_AntiPath.cpp34
3 files changed, 35 insertions, 34 deletions
diff --git a/gm/hugepath.cpp b/gm/hugepath.cpp
index dbca413093..83dff9ec3e 100644
--- a/gm/hugepath.cpp
+++ b/gm/hugepath.cpp
@@ -9,20 +9,29 @@
#include "SkCanvas.h"
#include "SkPath.h"
-DEF_SIMPLE_GM(path_huge_crbug_800804, canvas, 30, 600) {
+DEF_SIMPLE_GM(path_huge_crbug_800804, canvas, 50, 600) {
SkPaint paint;
paint.setAntiAlias(true);
-
paint.setStyle(SkPaint::kStroke_Style);
- paint.setStrokeWidth(1);
+
+ // exercise various special-cases (e.g. hairlines or not)
+ const float widths[] = { 0.9f, 1.0f, 1.1f };
+
SkPath path;
- path.moveTo(-1000,12345678901234567890.f);
- path.lineTo(10.5f,200);
- canvas->drawPath(path, paint);
-
- path.reset();
- path.moveTo(20.5f,400);
- path.lineTo(1000,-9.8765432109876543210e+19f);
- canvas->drawPath(path, paint);
+ for (float w : widths) {
+ paint.setStrokeWidth(w);
+
+ path.reset();
+ path.moveTo(-1000,12345678901234567890.f);
+ path.lineTo(10.5f,200);
+ canvas->drawPath(path, paint);
+
+ path.reset();
+ path.moveTo(30.5f,400);
+ path.lineTo(1000,-9.8765432109876543210e+19f);
+ canvas->drawPath(path, paint);
+
+ canvas->translate(3, 0);
+ }
}
diff --git a/src/core/SkScanPriv.h b/src/core/SkScanPriv.h
index 544f5f5dd6..3d364988db 100644
--- a/src/core/SkScanPriv.h
+++ b/src/core/SkScanPriv.h
@@ -5,7 +5,6 @@
* found in the LICENSE file.
*/
-
#ifndef SkScanPriv_DEFINED
#define SkScanPriv_DEFINED
@@ -13,6 +12,9 @@
#include "SkScan.h"
#include "SkBlitter.h"
+// controls how much we super-sample (when we use that scan convertion)
+#define SK_SUPERSAMPLE_SHIFT 2
+
class SkScanClipper {
public:
SkScanClipper(SkBlitter* blitter, const SkRegion* clip, const SkIRect& bounds,
diff --git a/src/core/SkScan_AntiPath.cpp b/src/core/SkScan_AntiPath.cpp
index f903a4fd5c..70c8d1f972 100644
--- a/src/core/SkScan_AntiPath.cpp
+++ b/src/core/SkScan_AntiPath.cpp
@@ -13,7 +13,7 @@
#include "SkRegion.h"
#include "SkAntiRun.h"
-#define SHIFT 2
+#define SHIFT SK_SUPERSAMPLE_SHIFT
#define SCALE (1 << SHIFT)
#define MASK (SCALE - 1)
@@ -630,12 +630,6 @@ void SkScan::SAAFillPath(const SkPath& path, SkBlitter* blitter, const SkIRect&
}
}
-static bool fitsInsideLimit(const SkRect& r, SkScalar max) {
- const SkScalar min = -max;
- return r.fLeft > min && r.fTop > min &&
- r.fRight < max && r.fBottom < max;
-}
-
static int overflows_short_shift(int value, int shift) {
const int s = 16 + shift;
return (SkLeftShift(value, s) >> s) - value;
@@ -659,14 +653,17 @@ static int rect_overflows_short_shift(SkIRect rect, int shift) {
overflows_short_shift(rect.fBottom, shift);
}
-static bool safeRoundOut(const SkRect& src, SkIRect* dst, int32_t maxInt) {
- const SkScalar maxScalar = SkIntToScalar(maxInt);
+static SkIRect safeRoundOut(const SkRect& src) {
+ // roundOut will pin huge floats to max/min int
+ SkIRect dst = src.roundOut();
- if (fitsInsideLimit(src, maxScalar)) {
- src.roundOut(dst);
- return true;
- }
- return false;
+ // intersect with a smaller huge rect, so the rect will not be considered empty for being
+ // too large. e.g. { -SK_MaxS32 ... SK_MaxS32 } is considered empty because its width
+ // exceeds signed 32bit.
+ const int32_t limit = SK_MaxS32 >> SK_SUPERSAMPLE_SHIFT;
+ (void)dst.intersect({ -limit, -limit, limit, limit});
+
+ return dst;
}
void SkScan::AntiFillPath(const SkPath& path, const SkRegion& origClip,
@@ -676,12 +673,7 @@ void SkScan::AntiFillPath(const SkPath& path, const SkRegion& origClip,
}
const bool isInverse = path.isInverseFillType();
- SkIRect ir;
-
- if (!safeRoundOut(path.getBounds(), &ir, SK_MaxS32 >> SHIFT)) {
- // Bounds can't fit in SkIRect; we'll return without drawing
- return;
- }
+ SkIRect ir = safeRoundOut(path.getBounds());
if (ir.isEmpty()) {
if (isInverse) {
blitter->blitRegion(origClip);
@@ -745,8 +737,6 @@ void SkScan::AntiFillPath(const SkPath& path, const SkRegion& origClip,
sk_blit_above(blitter, ir, *clipRgn);
}
- SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop);
-
if (forceDAA || ShouldUseDAA(path)) {
SkScan::DAAFillPath(path, blitter, ir, clipRgn->getBounds(), forceRLE);
} else if (ShouldUseAAA(path)) {