aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2018-02-26 17:00:58 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-02-27 15:11:39 +0000
commit0a3b12bbcec77cb7007e0c3421a84affdc27a146 (patch)
tree7ab24e63085e13961632cbb74d99e22561a72bd5 /src/core
parent222346541911c7908418a2ba9d60d27b56821998 (diff)
keep points as floats until after clipping
Bug: oss-fuzz:6539 Change-Id: Ia91dee2a023c9b17d06948c455b8ea6a1b213e0d Reviewed-on: https://skia-review.googlesource.com/110501 Reviewed-by: Yuqian Li <liyuqian@google.com> Commit-Queue: Mike Reed <reed@google.com>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkDraw.cpp58
-rw-r--r--src/core/SkRectPriv.h3
2 files changed, 33 insertions, 28 deletions
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 6f8ee30602..21a89ae5a9 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -233,7 +233,8 @@ struct PtProcRec {
const SkRasterClip* fRC;
// computed values
- SkFixed fRadius;
+ SkRect fClipBounds;
+ SkScalar fRadius;
typedef void (*Proc)(const PtProcRec&, const SkPoint devPts[], int count,
SkBlitter*);
@@ -341,37 +342,38 @@ static void aa_poly_hair_proc(const PtProcRec& rec, const SkPoint devPts[],
// square procs (strokeWidth > 0 but matrix is square-scale (sx == sy)
+static SkRect make_square_rad(SkPoint center, SkScalar radius) {
+ return {
+ center.fX - radius, center.fY - radius,
+ center.fX + radius, center.fY + radius
+ };
+}
+
+static SkXRect make_xrect(const SkRect& r) {
+ SkASSERT(SkRectPriv::FitsInFixed(r));
+ return {
+ SkScalarToFixed(r.fLeft), SkScalarToFixed(r.fTop),
+ SkScalarToFixed(r.fRight), SkScalarToFixed(r.fBottom)
+ };
+}
+
static void bw_square_proc(const PtProcRec& rec, const SkPoint devPts[],
int count, SkBlitter* blitter) {
- const SkFixed radius = rec.fRadius;
for (int i = 0; i < count; i++) {
- SkFixed x = SkScalarToFixed(devPts[i].fX);
- SkFixed y = SkScalarToFixed(devPts[i].fY);
-
- SkXRect r;
- r.fLeft = x - radius;
- r.fTop = y - radius;
- r.fRight = x + radius;
- r.fBottom = y + radius;
-
- SkScan::FillXRect(r, *rec.fRC, blitter);
+ SkRect r = make_square_rad(devPts[i], rec.fRadius);
+ if (r.intersect(rec.fClipBounds)) {
+ SkScan::FillXRect(make_xrect(r), *rec.fRC, blitter);
+ }
}
}
static void aa_square_proc(const PtProcRec& rec, const SkPoint devPts[],
int count, SkBlitter* blitter) {
- const SkFixed radius = rec.fRadius;
for (int i = 0; i < count; i++) {
- SkFixed x = SkScalarToFixed(devPts[i].fX);
- SkFixed y = SkScalarToFixed(devPts[i].fY);
-
- SkXRect r;
- r.fLeft = x - radius;
- r.fTop = y - radius;
- r.fRight = x + radius;
- r.fBottom = y + radius;
-
- SkScan::AntiFillXRect(r, *rec.fRC, blitter);
+ SkRect r = make_square_rad(devPts[i], rec.fRadius);
+ if (r.intersect(rec.fClipBounds)) {
+ SkScan::AntiFillXRect(make_xrect(r), *rec.fRC, blitter);
+ }
}
}
@@ -398,16 +400,18 @@ bool PtProcRec::init(SkCanvas::PointMode mode, const SkPaint& paint,
}
}
if (radius > 0) {
+ SkRect clipBounds = SkRect::Make(rc->getBounds());
// if we return true, the caller may assume that the constructed shapes can be represented
- // using SkFixed, so we preflight that here, looking at the radius and clip-bounds
- if (!SkRectPriv::FitsInFixed(SkRect::Make(rc->getBounds()).makeOutset(radius, radius))) {
+ // using SkFixed (after clipping), so we preflight that here.
+ if (!SkRectPriv::FitsInFixed(clipBounds)) {
return false;
}
fMode = mode;
fPaint = &paint;
fClip = nullptr;
fRC = rc;
- fRadius = SkScalarToFixed(radius);
+ fClipBounds = clipBounds;
+ fRadius = radius;
return true;
}
return false;
@@ -443,7 +447,7 @@ PtProcRec::Proc PtProcRec::chooseProc(SkBlitter** blitterPtr) {
proc = aa_square_proc;
}
} else { // BW
- if (fRadius <= SK_FixedHalf) { // small radii and hairline
+ if (fRadius <= 0.5f) { // small radii and hairline
if (SkCanvas::kPoints_PointMode == fMode && fClip->isRect()) {
uint32_t value;
const SkPixmap* bm = blitter->justAnOpaqueColor(&value);
diff --git a/src/core/SkRectPriv.h b/src/core/SkRectPriv.h
index d2a2ce4665..3bf90f8be7 100644
--- a/src/core/SkRectPriv.h
+++ b/src/core/SkRectPriv.h
@@ -47,7 +47,8 @@ public:
r->fBottom = SkMaxScalar(pt.fY, r->fBottom);
}
- // conservative check. will return false for very large values that "could" fit
+ // Conservative check if r can be expressed in fixed-point.
+ // Will return false for very large values that might have fit
static bool FitsInFixed(const SkRect& r) {
return SkFitsInFixed(r.fLeft) && SkFitsInFixed(r.fTop) &&
SkFitsInFixed(r.fRight) && SkFitsInFixed(r.fBottom);