aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Cary Clark <caryclark@skia.org>2018-05-16 21:28:55 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-17 14:02:43 +0000
commitc06754b0466e14e1611fa3144bf337289e6ca82f (patch)
tree287a31a09b4556003569103655a855f8eefd43a6 /src
parentbd74e6a02ae0e7b031aa1d1cd73062dba2c93daf (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.cpp2
-rw-r--r--src/core/SkRect.cpp41
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); \