From 1fc1bd3a03a75618b528bac07b43f09713cecfe9 Mon Sep 17 00:00:00 2001 From: Chris Dalton Date: Wed, 6 May 2020 11:44:51 -0600 Subject: [PATCH] Don't modify the pts array in SkOpEdgeBuilder::preFetch Change-Id: I2596986cb203e00b1d6d24c0086e98eb6373142b Reviewed-on: https://skia-review.googlesource.com/c/skia/+/288178 Reviewed-by: Mike Reed Commit-Queue: Chris Dalton --- src/pathops/SkOpEdgeBuilder.cpp | 59 +++++++++++++++------------------ 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/src/pathops/SkOpEdgeBuilder.cpp b/src/pathops/SkOpEdgeBuilder.cpp index 5e72d9a0a81d2..f8d73c39161a5 100644 --- a/src/pathops/SkOpEdgeBuilder.cpp +++ b/src/pathops/SkOpEdgeBuilder.cpp @@ -17,13 +17,15 @@ void SkOpEdgeBuilder::init() { } // very tiny points cause numerical instability : don't allow them -static void force_small_to_zero(SkPoint* pt) { - if (SkScalarAbs(pt->fX) < FLT_EPSILON_ORDERABLE_ERR) { - pt->fX = 0; +static SkPoint force_small_to_zero(const SkPoint& pt) { + SkPoint ret = pt; + if (SkScalarAbs(ret.fX) < FLT_EPSILON_ORDERABLE_ERR) { + ret.fX = 0; } - if (SkScalarAbs(pt->fY) < FLT_EPSILON_ORDERABLE_ERR) { - pt->fY = 0; + if (SkScalarAbs(ret.fY) < FLT_EPSILON_ORDERABLE_ERR) { + ret.fY = 0; } + return ret; } static bool can_add_curve(SkPath::Verb verb, SkPoint* curve) { @@ -31,7 +33,7 @@ static bool can_add_curve(SkPath::Verb verb, SkPoint* curve) { return false; } for (int index = 0; index <= SkPathOpsVerbToPoints(verb); ++index) { - force_small_to_zero(&curve[index]); + curve[index] = force_small_to_zero(curve[index]); } return SkPath::kLine_Verb != verb || !SkDPoint::ApproximatelyEqual(curve[0], curve[1]); } @@ -95,37 +97,33 @@ int SkOpEdgeBuilder::preFetch() { closeContour(curve[0], curveStart); } *fPathVerbs.append() = verb; - force_small_to_zero(&pts[0]); - *fPathPts.append() = pts[0]; - curveStart = curve[0] = pts[0]; + curve[0] = force_small_to_zero(pts[0]); + *fPathPts.append() = curve[0]; + curveStart = curve[0]; lastCurve = false; continue; case SkPath::kLine_Verb: - force_small_to_zero(&pts[1]); - if (SkDPoint::ApproximatelyEqual(curve[0], pts[1])) { + curve[1] = force_small_to_zero(pts[1]); + if (SkDPoint::ApproximatelyEqual(curve[0], curve[1])) { uint8_t lastVerb = fPathVerbs.top(); if (lastVerb != SkPath::kLine_Verb && lastVerb != SkPath::kMove_Verb) { - fPathPts.top() = curve[0] = pts[1]; + fPathPts.top() = curve[0] = curve[1]; } continue; // skip degenerate points } break; case SkPath::kQuad_Verb: - force_small_to_zero(&pts[1]); - force_small_to_zero(&pts[2]); - curve[1] = pts[1]; - curve[2] = pts[2]; - verb = SkReduceOrder::Quad(curve, pts); + curve[1] = force_small_to_zero(pts[1]); + curve[2] = force_small_to_zero(pts[2]); + verb = SkReduceOrder::Quad(curve, curve); if (verb == SkPath::kMove_Verb) { continue; // skip degenerate points } break; case SkPath::kConic_Verb: - force_small_to_zero(&pts[1]); - force_small_to_zero(&pts[2]); - curve[1] = pts[1]; - curve[2] = pts[2]; - verb = SkReduceOrder::Quad(curve, pts); + curve[1] = force_small_to_zero(pts[1]); + curve[2] = force_small_to_zero(pts[2]); + verb = SkReduceOrder::Quad(curve, curve); if (SkPath::kQuad_Verb == verb && 1 != iter.conicWeight()) { verb = SkPath::kConic_Verb; } else if (verb == SkPath::kMove_Verb) { @@ -133,13 +131,10 @@ int SkOpEdgeBuilder::preFetch() { } break; case SkPath::kCubic_Verb: - force_small_to_zero(&pts[1]); - force_small_to_zero(&pts[2]); - force_small_to_zero(&pts[3]); - curve[1] = pts[1]; - curve[2] = pts[2]; - curve[3] = pts[3]; - verb = SkReduceOrder::Cubic(curve, pts); + curve[1] = force_small_to_zero(pts[1]); + curve[2] = force_small_to_zero(pts[2]); + curve[3] = force_small_to_zero(pts[3]); + verb = SkReduceOrder::Cubic(curve, curve); if (verb == SkPath::kMove_Verb) { continue; // skip degenerate points } @@ -153,11 +148,11 @@ int SkOpEdgeBuilder::preFetch() { } *fPathVerbs.append() = verb; int ptCount = SkPathOpsVerbToPoints(verb); - fPathPts.append(ptCount, &pts[1]); + fPathPts.append(ptCount, &curve[1]); if (verb == SkPath::kConic_Verb) { *fWeights.append() = iter.conicWeight(); } - curve[0] = pts[ptCount]; + curve[0] = curve[ptCount]; lastCurve = true; } while (verb != SkPath::kDone_Verb); if (!fAllowOpenContours && lastCurve) { @@ -218,7 +213,7 @@ bool SkOpEdgeBuilder::walk() { return false; } for (unsigned index = 0; index < SK_ARRAY_COUNT(pair); ++index) { - force_small_to_zero(&pair[index]); + pair[index] = force_small_to_zero(pair[index]); } SkPoint cStorage[2][2]; SkPath::Verb v1 = SkReduceOrder::Quad(&pair[0], cStorage[0]);