Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Unified Diff: src/utils/SkDashPath.cpp

Issue 1805963002: allow one zero length dash (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix dash nanobench Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/effects/SkDashPathEffect.cpp ('k') | src/utils/SkDashPathPriv.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/utils/SkDashPath.cpp
diff --git a/src/utils/SkDashPath.cpp b/src/utils/SkDashPath.cpp
index cd01a9972b94695e1a4b27e1e819bb675fcb56e0..9a607c47eb56cbd875bcaf79eda631d34884bc94 100644
--- a/src/utils/SkDashPath.cpp
+++ b/src/utils/SkDashPath.cpp
@@ -39,42 +39,35 @@ void SkDashPath::CalcDashParameters(SkScalar phase, const SkScalar intervals[],
len += intervals[i];
}
*intervalLength = len;
-
- // watch out for values that might make us go out of bounds
- if ((len > 0) && SkScalarIsFinite(phase) && SkScalarIsFinite(len)) {
-
- // Adjust phase to be between 0 and len, "flipping" phase if negative.
- // e.g., if len is 100, then phase of -20 (or -120) is equivalent to 80
- if (adjustedPhase) {
- if (phase < 0) {
- phase = -phase;
- if (phase > len) {
- phase = SkScalarMod(phase, len);
- }
- phase = len - phase;
-
- // Due to finite precision, it's possible that phase == len,
- // even after the subtract (if len >>> phase), so fix that here.
- // This fixes http://crbug.com/124652 .
- SkASSERT(phase <= len);
- if (phase == len) {
- phase = 0;
- }
- } else if (phase >= len) {
+ // Adjust phase to be between 0 and len, "flipping" phase if negative.
+ // e.g., if len is 100, then phase of -20 (or -120) is equivalent to 80
+ if (adjustedPhase) {
+ if (phase < 0) {
+ phase = -phase;
+ if (phase > len) {
phase = SkScalarMod(phase, len);
}
- *adjustedPhase = phase;
+ phase = len - phase;
+
+ // Due to finite precision, it's possible that phase == len,
+ // even after the subtract (if len >>> phase), so fix that here.
+ // This fixes http://crbug.com/124652 .
+ SkASSERT(phase <= len);
+ if (phase == len) {
+ phase = 0;
+ }
+ } else if (phase >= len) {
+ phase = SkScalarMod(phase, len);
}
- SkASSERT(phase >= 0 && phase < len);
+ *adjustedPhase = phase;
+ }
+ SkASSERT(phase >= 0 && phase < len);
- *initialDashLength = find_first_interval(intervals, phase,
- initialDashIndex, count);
+ *initialDashLength = find_first_interval(intervals, phase,
+ initialDashIndex, count);
- SkASSERT(*initialDashLength >= 0);
- SkASSERT(*initialDashIndex >= 0 && *initialDashIndex < count);
- } else {
- *initialDashLength = -1; // signal bad dash intervals
- }
+ SkASSERT(*initialDashLength >= 0);
+ SkASSERT(*initialDashIndex >= 0 && *initialDashIndex < count);
}
static void outset_for_stroke(SkRect* rect, const SkStrokeRec& rec) {
@@ -219,13 +212,13 @@ private:
};
-bool SkDashPath::FilterDashPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
+bool SkDashPath::InternalFilter(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
const SkRect* cullRect, const SkScalar aIntervals[],
int32_t count, SkScalar initialDashLength, int32_t initialDashIndex,
SkScalar intervalLength) {
- // we do nothing if the src wants to be filled, or if our dashlength is 0
- if (rec->isFillStyle() || initialDashLength < 0) {
+ // we do nothing if the src wants to be filled
+ if (rec->isFillStyle()) {
return false;
}
@@ -305,7 +298,7 @@ bool SkDashPath::FilterDashPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec
// extend if we ended on a segment and we need to join up with the (skipped) initial segment
if (meas.isClosed() && is_even(initialDashIndex) &&
- initialDashLength > 0) {
+ initialDashLength >= 0) {
meas.getSegment(0, initialDashLength, dst, !addedSegment);
++segCount;
}
@@ -320,11 +313,29 @@ bool SkDashPath::FilterDashPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec
bool SkDashPath::FilterDashPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
const SkRect* cullRect, const SkPathEffect::DashInfo& info) {
+ if (!ValidDashPath(info.fPhase, info.fIntervals, info.fCount)) {
+ return false;
+ }
SkScalar initialDashLength = 0;
int32_t initialDashIndex = 0;
SkScalar intervalLength = 0;
CalcDashParameters(info.fPhase, info.fIntervals, info.fCount,
&initialDashLength, &initialDashIndex, &intervalLength);
- return FilterDashPath(dst, src, rec, cullRect, info.fIntervals, info.fCount, initialDashLength,
+ return InternalFilter(dst, src, rec, cullRect, info.fIntervals, info.fCount, initialDashLength,
initialDashIndex, intervalLength);
}
+
+bool SkDashPath::ValidDashPath(SkScalar phase, const SkScalar intervals[], int32_t count) {
+ if (count < 2 || !SkIsAlign2(count)) {
+ return false;
+ }
+ SkScalar length = 0;
+ for (int i = 0; i < count; i++) {
+ if (intervals[i] < 0) {
+ return false;
+ }
+ length += intervals[i];
+ }
+ // watch out for values that might make us go out of bounds
+ return length > 0 && SkScalarIsFinite(phase) && SkScalarIsFinite(length);
+}
« no previous file with comments | « src/effects/SkDashPathEffect.cpp ('k') | src/utils/SkDashPathPriv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698