Use SkSpan in SkRect::setBounds

Change-Id: Ic159246f85c01c2ea286aa5ba2b57bcb696a5c62
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1002157
Reviewed-by: Florin Malita <fmalita@google.com>
Commit-Queue: Mike Reed <mike@reedtribe.org>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
diff --git a/docs/examples/Rect_setBoundsCheck.cpp b/docs/examples/Rect_setBoundsCheck.cpp
index cde8398..c7ab9c7 100644
--- a/docs/examples/Rect_setBoundsCheck.cpp
+++ b/docs/examples/Rect_setBoundsCheck.cpp
@@ -6,7 +6,7 @@
     SkPoint points[] = {{3, 4}, {1, 2}, {5, 6}, {SK_ScalarNaN, 8}};
     for (int count = 0; count <= (int) std::size(points); ++count) {
         SkRect rect;
-        bool success = rect.setBoundsCheck(points, count);
+        bool success = rect.setBoundsCheck({points, count});
         if (count > 0) {
             SkDebugf("added: %3g, %g ", points[count - 1].fX,  points[count - 1].fY);
         } else {
diff --git a/docs/examples/Rect_setBoundsNoCheck.cpp b/docs/examples/Rect_setBoundsNoCheck.cpp
index ef4f237..64a161b 100644
--- a/docs/examples/Rect_setBoundsNoCheck.cpp
+++ b/docs/examples/Rect_setBoundsNoCheck.cpp
@@ -6,7 +6,7 @@
     SkPoint points[] = {{3, 4}, {1, 2}, {SK_ScalarInfinity, 6}, {SK_ScalarNaN, 8}};
     for (int count = 0; count <= (int) std::size(points); ++count) {
         SkRect rect;
-        rect.setBoundsNoCheck(points, count);
+        rect.setBoundsNoCheck({points, count});
         if (count > 0) {
             SkDebugf("added: %3g, %g ", points[count - 1].fX,  points[count - 1].fY);
         } else {
diff --git a/fuzz/FuzzPolyUtils.cpp b/fuzz/FuzzPolyUtils.cpp
index 00d3599..203800d 100644
--- a/fuzz/FuzzPolyUtils.cpp
+++ b/fuzz/FuzzPolyUtils.cpp
@@ -34,7 +34,7 @@
         polygon[index] = sanitize_point(polygon[index]);
     }
     SkRect bounds;
-    bounds.setBoundsCheck(polygon, count);
+    bounds.setBoundsCheck({polygon, count});
 
     ignoreResult(SkGetPolygonWinding(polygon, count));
     bool isConvex = SkIsConvexPolygon(polygon, count);
diff --git a/gm/polygonoffset.cpp b/gm/polygonoffset.cpp
index 1673925..36e299c 100644
--- a/gm/polygonoffset.cpp
+++ b/gm/polygonoffset.cpp
@@ -520,7 +520,7 @@
                 GetSimplePolygon(index, SkPathDirection::kCW, &data, &numPts);
             }
             SkRect bounds;
-            bounds.setBounds(data.get(), numPts);
+            bounds.setBounds({data.get(), numPts});
             if (!fConvexOnly) {
                 bounds.outset(kMaxOutset, kMaxOutset);
             }
@@ -576,7 +576,7 @@
                 result = SkInsetConvexPolygon(data.get(), numPts, offset, &offsetPoly);
             } else {
                 SkRect bounds;
-                bounds.setBoundsCheck(data.get(), numPts);
+                bounds.setBoundsCheck({data.get(), numPts});
                 result = SkOffsetSimplePolygon(data.get(), numPts, bounds, offset, &offsetPoly);
             }
             if (result) {
diff --git a/include/core/SkRect.h b/include/core/SkRect.h
index 30b0457..893acbc 100644
--- a/include/core/SkRect.h
+++ b/include/core/SkRect.h
@@ -10,6 +10,7 @@
 
 #include "include/core/SkPoint.h"
 #include "include/core/SkSize.h"
+#include "include/core/SkSpan.h"
 #include "include/core/SkTypes.h"
 #include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkSafe32.h"
@@ -877,43 +878,49 @@
         fBottom = bottom;
     }
 
-    /** Sets to bounds of SkPoint array with count entries. If count is zero or smaller,
-        or if SkPoint array contains an infinity or NaN, sets to (0, 0, 0, 0).
+    /** Sets to bounds of the span of points. If the span is empty,
+        or if a point contains an infinity or NaN, sets to (0, 0, 0, 0).
 
         Result is either empty or sorted: fLeft is less than or equal to fRight, and
         fTop is less than or equal to fBottom.
 
-        @param pts    SkPoint array
-        @param count  entries in array
+        @param pts    SkPoint span
     */
-    void setBounds(const SkPoint pts[], int count) {
-        (void)this->setBoundsCheck(pts, count);
+    void setBounds(SkSpan<const SkPoint> pts) {
+        (void)this->setBoundsCheck(pts);
     }
 
-    /** Sets to bounds of SkPoint array with count entries. Returns false if count is
-        zero or smaller, or if SkPoint array contains an infinity or NaN; in these cases
-        sets SkRect to (0, 0, 0, 0).
+    /** Sets to bounds of the span of points, and return true (if all point values were finite).
+     *
+     * If the span is empty, set the rect to empty() and return true.
+     * If any point contains an infinity or NaN, set the rect to empty and return false.
+     *
+     * @param pts    SkPoint span
+     * example: https://fiddle.skia.org/c/@Rect_setBoundsCheck
+     */
+    bool setBoundsCheck(SkSpan<const SkPoint> pts);
 
-        Result is either empty or sorted: fLeft is less than or equal to fRight, and
-        fTop is less than or equal to fBottom.
+    /** Sets to bounds of the span of points.
+     *
+     * If the span is empty, set the rect to empty().
+     * If any point contains an infinity or NaN, set the rect to NaN.
+     *
+     * @param pts    SkPoint span
+     * example: https://fiddle.skia.org/c/@Rect_setBoundsNoCheck
+     */
+    void setBoundsNoCheck(SkSpan<const SkPoint> pts);
 
-        @param pts    SkPoint array
-        @param count  entries in array
-        @return       true if all SkPoint values are finite
-
-        example: https://fiddle.skia.org/c/@Rect_setBoundsCheck
-    */
-    bool setBoundsCheck(const SkPoint pts[], int count);
-
-    /** Sets to bounds of SkPoint pts array with count entries. If any SkPoint in pts
-        contains infinity or NaN, all SkRect dimensions are set to NaN.
-
-        @param pts    SkPoint array
-        @param count  entries in array
-
-        example: https://fiddle.skia.org/c/@Rect_setBoundsNoCheck
-    */
-    void setBoundsNoCheck(const SkPoint pts[], int count);
+#ifdef SK_SUPPORT_UNSPANNED_APIS
+    void setBounds(const SkPoint pts[], int count) {
+        this->setBounds({pts, count});
+    }
+    void setBoundsNoCheck(const SkPoint pts[], int count) {
+        this->setBoundsNoCheck({pts, count});
+    }
+    bool setBoundsCheck(const SkPoint pts[], int count) {
+        return this->setBoundsCheck({pts, count});
+    }
+#endif
 
     /** Sets bounds to the smallest SkRect enclosing SkPoint p0 and p1. The result is
         sorted and may be empty. Does not check to see if values are finite.
diff --git a/include/private/SkPathRef.h b/include/private/SkPathRef.h
index 5f9294f..939f6b8 100644
--- a/include/private/SkPathRef.h
+++ b/include/private/SkPathRef.h
@@ -395,7 +395,7 @@
 
     // Return true if the computed bounds are finite.
     static bool ComputePtBounds(SkRect* bounds, const SkPathRef& ref) {
-        return bounds->setBoundsCheck(ref.points(), ref.countPoints());
+        return bounds->setBoundsCheck({ref.points(), ref.countPoints()});
     }
 
     // called, if dirty, by getBounds()
diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp
index d04747b..91df9d9 100644
--- a/src/core/SkMatrix.cpp
+++ b/src/core/SkMatrix.cpp
@@ -1173,7 +1173,7 @@
 
         src.toQuad(quad);
         this->mapPoints(quad, quad, 4);
-        dst->setBoundsNoCheck(quad, 4);
+        dst->setBoundsNoCheck(quad);
         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 357405d..ed95a64 100644
--- a/src/core/SkRect.cpp
+++ b/src/core/SkRect.cpp
@@ -58,14 +58,14 @@
 
 #include "src/base/SkVx.h"
 
-bool SkRect::setBoundsCheck(const SkPoint pts[], int count) {
-    SkASSERT((pts && count > 0) || count == 0);
-
-    if (count <= 0) {
+bool SkRect::setBoundsCheck(SkSpan<const SkPoint> points) {
+    if (points.empty()) {
         this->setEmpty();
         return true;
     }
 
+    auto pts = points.data();
+    auto count = points.size();
     skvx::float4 min, max;
     if (count & 1) {
         min = max = skvx::float2::Load(pts).xyxy();
@@ -97,8 +97,8 @@
     return all_finite;
 }
 
-void SkRect::setBoundsNoCheck(const SkPoint pts[], int count) {
-    if (!this->setBoundsCheck(pts, count)) {
+void SkRect::setBoundsNoCheck(SkSpan<const SkPoint> points) {
+    if (!this->setBoundsCheck(points)) {
         this->setLTRB(SK_FloatNaN, SK_FloatNaN, SK_FloatNaN, SK_FloatNaN);
     }
 }
diff --git a/src/utils/SkPolyUtils.cpp b/src/utils/SkPolyUtils.cpp
index c122bb7..22cc169 100644
--- a/src/utils/SkPolyUtils.cpp
+++ b/src/utils/SkPolyUtils.cpp
@@ -1641,7 +1641,7 @@
 
     // get bounds
     SkRect bounds;
-    if (!bounds.setBoundsCheck(polygonVerts, polygonSize)) {
+    if (!bounds.setBoundsCheck({polygonVerts, polygonSize})) {
         return false;
     }
     // get winding direction
diff --git a/tests/OffsetSimplePolyTest.cpp b/tests/OffsetSimplePolyTest.cpp
index d3156c8..c8b27ea 100644
--- a/tests/OffsetSimplePolyTest.cpp
+++ b/tests/OffsetSimplePolyTest.cpp
@@ -40,7 +40,7 @@
     *rrectPoly.append() = SkPoint::Make(-100 - 3.535534f, 50 + 3.535534f);
     *rrectPoly.append() = SkPoint::Make(-100 - 2.5f, 50 + 4.330127f);
     SkRect bounds;
-    bounds.setBoundsCheck(rrectPoly.begin(), rrectPoly.size());
+    bounds.setBoundsCheck(rrectPoly);
 
     REPORTER_ASSERT(reporter, SkIsConvexPolygon(rrectPoly.begin(), rrectPoly.size()));
 
@@ -107,7 +107,7 @@
     *clippedRRectPoly.append() = SkPoint::Make(381.195313f, 432.207275f);
     *clippedRRectPoly.append() = SkPoint::Make(377.312134f, 432.947998f);
     *clippedRRectPoly.append() = SkPoint::Make(342.289948f, 432.947998f);
-    bounds.setBoundsCheck(clippedRRectPoly.begin(), clippedRRectPoly.size());
+    bounds.setBoundsCheck(clippedRRectPoly);
 
     REPORTER_ASSERT(reporter, SkIsConvexPolygon(clippedRRectPoly.begin(),
                                                 clippedRRectPoly.size()));
@@ -133,7 +133,7 @@
     *starPoly.append() = SkPoint::Make(-28.86f, 0.0f);
     *starPoly.append() = SkPoint::Make(-43.30f, -25.0f);
     *starPoly.append() = SkPoint::Make(-14.43f, -25.0f);
-    bounds.setBoundsCheck(starPoly.begin(), starPoly.size());
+    bounds.setBoundsCheck(starPoly);
 
     REPORTER_ASSERT(reporter, SkIsSimplePolygon(starPoly.begin(), starPoly.size()));
 
diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp
index b2cbee9..472f59e 100644
--- a/tests/PathTest.cpp
+++ b/tests/PathTest.cpp
@@ -947,17 +947,17 @@
         { 0, SK_Scalar1 },
     };
 
-    bool isFine = r.setBoundsCheck(pts, 3);
+    bool isFine = r.setBoundsCheck(pts);
     REPORTER_ASSERT(reporter, isFine);
     REPORTER_ASSERT(reporter, !r.isEmpty());
 
     pts[1].set(inf, 0);
-    isFine = r.setBoundsCheck(pts, 3);
+    isFine = r.setBoundsCheck(pts);
     REPORTER_ASSERT(reporter, !isFine);
     REPORTER_ASSERT(reporter, r.isEmpty());
 
     pts[1].set(nan, 0);
-    isFine = r.setBoundsCheck(pts, 3);
+    isFine = r.setBoundsCheck(pts);
     REPORTER_ASSERT(reporter, !isFine);
     REPORTER_ASSERT(reporter, r.isEmpty());
 }
diff --git a/tests/RectTest.cpp b/tests/RectTest.cpp
index 6b309f4..348f9ab 100644
--- a/tests/RectTest.cpp
+++ b/tests/RectTest.cpp
@@ -142,13 +142,13 @@
     const SkRect zeror = { 0, 0, 0, 0 };
     for (const SkPoint* pts : { p0, p1, p2, p3 }) {
         for (int n = 1; n <= 4; ++n) {
-            bool isfinite = r.setBoundsCheck(pts, n);
+            bool isfinite = r.setBoundsCheck({pts, n});
             REPORTER_ASSERT(reporter, !isfinite);
             REPORTER_ASSERT(reporter, r == zeror);
 
-            r.setBoundsNoCheck(pts, n);
+            r.setBoundsNoCheck({pts, n});
             if (r.isFinite())
-                r.setBoundsNoCheck(pts, n);
+                r.setBoundsNoCheck({pts, n});
             REPORTER_ASSERT(reporter, !r.isFinite());
         }
     }
diff --git a/tests/WangsFormulaTest.cpp b/tests/WangsFormulaTest.cpp
index d82901f..268c75f 100644
--- a/tests/WangsFormulaTest.cpp
+++ b/tests/WangsFormulaTest.cpp
@@ -339,7 +339,7 @@
     }
     auto check_worst_case_cubic = [&](const SkPoint* pts) {
         SkRect bbox;
-        bbox.setBoundsNoCheck(pts, 4);
+        bbox.setBoundsNoCheck({pts, 4});
         float worst = wangs_formula::worst_case_cubic(kPrecision, bbox.width(), bbox.height());
         int worst_log2 = wangs_formula::worst_case_cubic_log2(kPrecision, bbox.width(),
                                                                bbox.height());