diff options
author | Cary Clark <caryclark@skia.org> | 2018-05-16 21:28:55 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-05-17 14:02:43 +0000 |
commit | c06754b0466e14e1611fa3144bf337289e6ca82f (patch) | |
tree | 287a31a09b4556003569103655a855f8eefd43a6 /src | |
parent | bd74e6a02ae0e7b031aa1d1cd73062dba2c93daf (diff) |
mapRect should not fiddle with nonfinite values.
Docs-Preview: https://skia.org/?cl=128682
Bug: skia:7967
Change-Id: Ic43387b7705ee8385b8df2430886484ff856077c
Reviewed-on: https://skia-review.googlesource.com/128682
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkMatrix.cpp | 2 | ||||
-rw-r--r-- | src/core/SkRect.cpp | 41 |
2 files changed, 42 insertions, 1 deletions
diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp index 344701d560..990f5b4652 100644 --- a/src/core/SkMatrix.cpp +++ b/src/core/SkMatrix.cpp @@ -1143,7 +1143,7 @@ bool SkMatrix::mapRect(SkRect* dst, const SkRect& src) const { src.toQuad(quad); this->mapPoints(quad, quad, 4); - dst->set(quad, 4); + dst->setBoundsNoCheck(quad, 4); return this->rectStaysRect(); // might still return true if rotated by 90, etc. } } diff --git a/src/core/SkRect.cpp b/src/core/SkRect.cpp index 10002898e5..2d6ee53f10 100644 --- a/src/core/SkRect.cpp +++ b/src/core/SkRect.cpp @@ -95,6 +95,47 @@ bool SkRect::setBoundsCheck(const SkPoint pts[], int count) { return isFinite; } +void SkRect::setBoundsNoCheck(const SkPoint pts[], int count) { + SkASSERT((pts && count > 0) || count == 0); + + if (count <= 0) { + sk_bzero(this, sizeof(SkRect)); + } else { + Sk4s min, max, accum; + + if (count & 1) { + min = Sk4s(pts[0].fX, pts[0].fY, pts[0].fX, pts[0].fY); + pts += 1; + count -= 1; + } else { + min = Sk4s::Load(pts); + pts += 2; + count -= 2; + } + accum = max = min; + accum = accum * Sk4s(0); + + count >>= 1; + for (int i = 0; i < count; ++i) { + Sk4s xy = Sk4s::Load(pts); + accum = accum * xy; + min = Sk4s::Min(min, xy); + max = Sk4s::Max(max, xy); + pts += 2; + } + + float minArray[4], maxArray[4]; + min.store(minArray); + max.store(maxArray); + this->set(SkTMin(minArray[0], minArray[2]), SkTMin(minArray[1], minArray[3]), + SkTMax(maxArray[0], maxArray[2]), SkTMax(maxArray[1], maxArray[3])); + + if (!is_finite(accum)) { + this->set(SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN); + } + } +} + #define CHECK_INTERSECT(al, at, ar, ab, bl, bt, br, bb) \ SkScalar L = SkMaxScalar(al, bl); \ SkScalar R = SkMinScalar(ar, br); \ |