diff options
author | Mike Reed <reed@google.com> | 2018-03-07 13:35:31 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-03-07 19:14:00 +0000 |
commit | c7fbda95404a9422d0dd762d35383d5a61e89440 (patch) | |
tree | 30726fca7ebc37f7c22462e1531f50538c457ae6 | |
parent | 73fb0c97e42995027c1f9e087b8faa24cfe84a19 (diff) |
chop down huge rects before hairlining
Bug: skia:
Change-Id: I18f4b1dc4f279e37832d4bced0a66b5c356d09c0
Reviewed-on: https://skia-review.googlesource.com/112572
Reviewed-by: Yuqian Li <liyuqian@google.com>
Commit-Queue: Mike Reed <reed@google.com>
-rw-r--r-- | src/core/SkScan_Hairline.cpp | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/src/core/SkScan_Hairline.cpp b/src/core/SkScan_Hairline.cpp index 1f12efefc5..7954ccc5a2 100644 --- a/src/core/SkScan_Hairline.cpp +++ b/src/core/SkScan_Hairline.cpp @@ -144,14 +144,25 @@ void SkScan::HairLineRgn(const SkPoint array[], int arrayCount, const SkRegion* // we don't just draw 4 lines, 'cause that can leave a gap in the bottom-right // and double-hit the top-left. -void SkScan::HairRect(const SkRect& rect, const SkRasterClip& clip, - SkBlitter* blitter) { +void SkScan::HairRect(const SkRect& rect, const SkRasterClip& clip, SkBlitter* blitter) { SkAAClipBlitterWrapper wrapper; SkBlitterClipper clipper; - const SkIRect r = SkIRect::MakeLTRB(SkScalarFloorToInt(rect.fLeft), - SkScalarFloorToInt(rect.fTop), - SkScalarFloorToInt(rect.fRight) + 1, - SkScalarFloorToInt(rect.fBottom) + 1); + // Create the enclosing bounds of the hairrect. i.e. we will stroke the interior of r. + SkIRect r = SkIRect::MakeLTRB(SkScalarFloorToInt(rect.fLeft), + SkScalarFloorToInt(rect.fTop), + SkScalarFloorToInt(rect.fRight + 1), + SkScalarFloorToInt(rect.fBottom + 1)); + + // Note: r might be crazy big, if rect was huge, possibly getting pinned to max/min s32. + // We need to trim it back to something reasonable before we can query its width etc. + // since r.fRight - r.fLeft might wrap around to negative even if fRight > fLeft. + // + // We outset the clip bounds by 1 before intersecting, since r is being stroked and not filled + // so we don't want to pin an edge of it to the clip. The intersect's job is mostly to just + // get the actual edge values into a reasonable range (e.g. so width() can't overflow). + if (!r.intersect(clip.getBounds().makeOutset(1, 1))) { + return; + } if (clip.quickReject(r)) { return; |