relax path bounds check so we can draw larger paths
Bug:800804 Change-Id: Ief0679de95887d8e11aa5853228c2bdef27d07a2 Reviewed-on: https://skia-review.googlesource.com/94100 Reviewed-by: Yuqian Li <liyuqian@google.com> Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
parent
7cdabedc8b
commit
e2330261a7
@ -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);
|
||||
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);
|
||||
// exercise various special-cases (e.g. hairlines or not)
|
||||
const float widths[] = { 0.9f, 1.0f, 1.1f };
|
||||
|
||||
SkPath path;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 >> 1;
|
||||
(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)) {
|
||||
|
Loading…
Reference in New Issue
Block a user