diff options
author | Greg Daniel <egdaniel@google.com> | 2017-12-21 14:33:20 +0000 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-12-21 14:33:31 +0000 |
commit | fa6b6c2d1b613faf72071b99f4b404fa4ee5e076 (patch) | |
tree | 6989c773fea78fe0076069ca830760da7eac2383 /src/utils/SkDashPath.cpp | |
parent | 47fdf6c85ee8151c14529e5322d63636c36ecdb8 (diff) |
Revert "long rect dash fix with guards"
This reverts commit 93ceab1b59f06c828cf62aa6a700e7f81620f23d.
Reason for revert: breaking layout test
Original change's description:
> long rect dash fix with guards
>
> long rect dash with guards
>
> check dash fix back in with
> guards against changing
> chrome layout test results
>
> original change clipped against wrong rectangle
> some of the time, causing tiled drawing to fail.
> Always clip against outset rectangle.
>
> original CL: skia-review.googlesource.com/c/skia/+/84862
>
> efficiently dash very large rectangles and very long lines
> Speed up dashing when lines and rects are absurdly large.
>
> Prior to this CL, only horizontal lines were detected.
>
> Also folded in a change to handle dashing of zero length lines.
>
> TBR=egdaniel@google.com
> Bug: skia:7311
> Change-Id: Ic3c68ec8ea35d0597c892c3b26ba7bb077045990
> Reviewed-on: https://skia-review.googlesource.com/87768
> Reviewed-by: Cary Clark <caryclark@skia.org>
> Commit-Queue: Cary Clark <caryclark@skia.org>
TBR=egdaniel@google.com,caryclark@skia.org
Change-Id: I56ef771ccb281887d7381c2bd8a2553acbd30621
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:7311
Reviewed-on: https://skia-review.googlesource.com/88421
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
Diffstat (limited to 'src/utils/SkDashPath.cpp')
-rw-r--r-- | src/utils/SkDashPath.cpp | 131 |
1 files changed, 0 insertions, 131 deletions
diff --git a/src/utils/SkDashPath.cpp b/src/utils/SkDashPath.cpp index 8d6c3cf567..cbfc8f2168 100644 --- a/src/utils/SkDashPath.cpp +++ b/src/utils/SkDashPath.cpp @@ -83,95 +83,11 @@ static void outset_for_stroke(SkRect* rect, const SkStrokeRec& rec) { rect->outset(radius, radius); } -#ifndef SK_SUPPORT_LEGACY_DASH_CULL_PATH -// If line is zero-length, bump out the end by a tiny amount -// to draw endcaps. The bump factor is sized so that -// SkPoint::Distance() computes a non-zero length. -// Offsets SK_ScalarNearlyZero or smaller create empty paths when Iter measures length. -// Large values are scaled by SK_ScalarNearlyZero so significant bits change. -static void adjust_zero_length_line(SkPoint pts[2]) { - SkASSERT(pts[0] == pts[1]); - pts[1].fX += SkTMax(1.001f, pts[1].fX) * SK_ScalarNearlyZero; -} - -static bool clip_line(SkPoint pts[2], const SkRect& bounds, SkScalar intervalLength, - SkScalar priorPhase) { - SkVector dxy = pts[1] - pts[0]; - - // only horizontal or vertical lines - if (dxy.fX && dxy.fY) { - return false; - } - int xyOffset = SkToBool(dxy.fY); // 0 to adjust horizontal, 1 to adjust vertical - - SkScalar minXY = (&pts[0].fX)[xyOffset]; - SkScalar maxXY = (&pts[1].fX)[xyOffset]; - bool swapped = maxXY < minXY; - if (swapped) { - SkTSwap(minXY, maxXY); - } - - SkASSERT(minXY <= maxXY); - SkScalar leftTop = (&bounds.fLeft)[xyOffset]; - SkScalar rightBottom = (&bounds.fRight)[xyOffset]; - if (maxXY < leftTop || minXY > rightBottom) { - return false; - } - - // Now we actually perform the chop, removing the excess to the left/top and - // right/bottom of the bounds (keeping our new line "in phase" with the dash, - // hence the (mod intervalLength). - - if (minXY < leftTop) { - minXY = leftTop - SkScalarMod(leftTop - minXY, intervalLength); - if (!swapped) { - minXY -= priorPhase; // for rectangles, adjust by prior phase - } - } - if (maxXY > rightBottom) { - maxXY = rightBottom + SkScalarMod(maxXY - rightBottom, intervalLength); - if (swapped) { - maxXY += priorPhase; // for rectangles, adjust by prior phase - } - } - - SkASSERT(maxXY >= minXY); - if (swapped) { - SkTSwap(minXY, maxXY); - } - (&pts[0].fX)[xyOffset] = minXY; - (&pts[1].fX)[xyOffset] = maxXY; - - if (minXY == maxXY) { - adjust_zero_length_line(pts); - } - return true; -} - -static bool contains_inclusive(const SkRect& rect, const SkPoint& pt) { - return rect.fLeft <= pt.fX && pt.fX <= rect.fRight && - rect.fTop <= pt.fY && pt.fY <= rect.fBottom; -} - -// Returns true is b is between a and c, that is: a <= b <= c, or a >= b >= c. -// Can perform this test with one branch by observing that, relative to b, -// the condition is true only if one side is positive and one side is negative. -// If the numbers are very small, the optimization may return the wrong result -// because the multiply may generate a zero where the simple compare does not. -// For this reason the assert does not fire when all three numbers are near zero. -static bool between(SkScalar a, SkScalar b, SkScalar c) { - SkASSERT(((a <= b && b <= c) || (a >= b && b >= c)) == ((a - b) * (c - b) <= 0) - || (SkScalarNearlyZero(a) && SkScalarNearlyZero(b) && SkScalarNearlyZero(c))); - return (a - b) * (c - b) <= 0; -} -#endif - // Only handles lines for now. If returns true, dstPath is the new (smaller) // path. If returns false, then dstPath parameter is ignored. static bool cull_path(const SkPath& srcPath, const SkStrokeRec& rec, const SkRect* cullRect, SkScalar intervalLength, SkPath* dstPath) { -#ifdef SK_SUPPORT_LEGACY_DASH_CULL_PATH if (nullptr == cullRect) { return false; } @@ -230,53 +146,6 @@ static bool cull_path(const SkPath& srcPath, const SkStrokeRec& rec, if (minX == maxX) { pts[1].fX += maxX * FLT_EPSILON * 32; // 16 instead of 32 does not draw; length stays zero } -#else // !SK_SUPPORT_LEGACY_DASH_CULL_PATH - SkPoint pts[4]; - if (nullptr == cullRect) { - if (srcPath.isLine(pts) && pts[0] == pts[1]) { - adjust_zero_length_line(pts); - } else { - return false; - } - } else { - SkRect bounds; - bool isLine = srcPath.isLine(pts); - bool isRect = !isLine && srcPath.isRect(nullptr); - if (!isLine && !isRect) { - return false; - } - bounds = *cullRect; - outset_for_stroke(&bounds, rec); - if (isRect) { - // break rect into four lines, and call each one separately - SkPath::Iter iter(srcPath, false); - SkAssertResult(SkPath::kMove_Verb == iter.next(pts)); - SkScalar priorLength = 0; - while (SkPath::kLine_Verb == iter.next(pts)) { - SkVector v = pts[1] - pts[0]; - // if line is entirely outside clip rect, skip it - if (v.fX ? between(bounds.fTop, pts[0].fY, bounds.fBottom) : - between(bounds.fLeft, pts[0].fX, bounds.fRight)) { - bool skipMoveTo = contains_inclusive(bounds, pts[0]); - if (clip_line(pts, bounds, intervalLength, - SkScalarMod(priorLength, intervalLength))) { - if (0 == priorLength || !skipMoveTo) { - dstPath->moveTo(pts[0]); - } - dstPath->lineTo(pts[1]); - } - } - // keep track of all prior lengths to set phase of next line - priorLength += SkScalarAbs(v.fX ? v.fX : v.fY); - } - return !dstPath->isEmpty(); - } - SkASSERT(isLine); - if (!clip_line(pts, bounds, intervalLength, 0)) { - return false; - } - } -#endif dstPath->moveTo(pts[0]); dstPath->lineTo(pts[1]); return true; |