aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkScan_Hairline.cpp
diff options
context:
space:
mode:
authorGravatar caryclark <caryclark@google.com>2015-12-22 06:13:33 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-12-22 06:13:33 -0800
commit40b7d3b48b522e233ee63d2c88cff82c4bd5fb15 (patch)
tree1112e387259788d114c81e8e6b1dfb2172462057 /src/core/SkScan_Hairline.cpp
parent83ba585ecbf0270261196cf90ceaeeb22d345452 (diff)
fix hair fuzz
If the end and control points of a quad, conic, or cubic are the same, adjust all of them when stretching the curve to account for a square or round end cap. If all of the points are the same, move all but the last. Enlarge the clip check to account for the cap. The clip bug was detected by ASAN. R=reed@google.com, msarett@google.com BUG=571214 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1547483003 Review URL: https://codereview.chromium.org/1547483003
Diffstat (limited to 'src/core/SkScan_Hairline.cpp')
-rw-r--r--src/core/SkScan_Hairline.cpp20
1 files changed, 14 insertions, 6 deletions
diff --git a/src/core/SkScan_Hairline.cpp b/src/core/SkScan_Hairline.cpp
index c59521abc7..12553a4a54 100644
--- a/src/core/SkScan_Hairline.cpp
+++ b/src/core/SkScan_Hairline.cpp
@@ -428,11 +428,15 @@ void extend_pts(SkPath::Verb prevVerb, SkPath::Verb nextVerb, SkPoint* pts, int
} while (tangent.isZero() && --controls > 0);
if (tangent.isZero()) {
tangent.set(1, 0);
+ controls = ptCount - 1; // If all points are equal, move all but one
} else {
tangent.normalize();
}
- first->fX += tangent.fX * capOutset;
- first->fY += tangent.fY * capOutset;
+ do { // If the end point and control points are equal, loop to move them in tandem.
+ first->fX += tangent.fX * capOutset;
+ first->fY += tangent.fY * capOutset;
+ ++first;
+ } while (++controls < ptCount);
}
if (SkPath::kMove_Verb == nextVerb || SkPath::kDone_Verb == nextVerb) {
SkPoint* last = &pts[ptCount - 1];
@@ -444,11 +448,15 @@ void extend_pts(SkPath::Verb prevVerb, SkPath::Verb nextVerb, SkPoint* pts, int
} while (tangent.isZero() && --controls > 0);
if (tangent.isZero()) {
tangent.set(-1, 0);
+ controls = ptCount - 1;
} else {
tangent.normalize();
}
- last->fX += tangent.fX * capOutset;
- last->fY += tangent.fY * capOutset;
+ do {
+ last->fX += tangent.fX * capOutset;
+ last->fY += tangent.fY * capOutset;
+ --last;
+ } while (++controls < ptCount);
}
}
@@ -466,8 +474,8 @@ void hair_path(const SkPath& path, const SkRasterClip& rclip, SkBlitter* blitter
const SkRect* outsetClip = nullptr;
{
- const SkIRect ibounds = path.getBounds().roundOut().makeOutset(1, 1);
-
+ const int capOut = SkPaint::kButt_Cap == capStyle ? 1 : 2;
+ const SkIRect ibounds = path.getBounds().roundOut().makeOutset(capOut, capOut);
if (rclip.quickReject(ibounds)) {
return;
}