Reland: add SkPath::shrinkToFit

Original CL: https://skia-review.googlesource.com/c/skia/+/150967

  * expanded tests
  * fixed shared pathref copying

Change-Id: I4bfe89f597485aa2db68f58d99112188615faceb
Reviewed-on: https://skia-review.googlesource.com/153553
Commit-Queue: Florin Malita <fmalita@chromium.org>
Reviewed-by: Mike Reed <reed@google.com>
Auto-Submit: Florin Malita <fmalita@chromium.org>
diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp
index 67bba43..acf0e25 100644
--- a/tests/PathTest.cpp
+++ b/tests/PathTest.cpp
@@ -5103,3 +5103,49 @@
     draw_triangle(surface->getCanvas(), pts);
 }
 
+static void add_verbs(SkPath* path, int count) {
+    path->moveTo(0, 0);
+    for (int i = 0; i < count; ++i) {
+        switch (i & 3) {
+            case 0: path->lineTo(10, 20); break;
+            case 1: path->quadTo(5, 6, 7, 8); break;
+            case 2: path->conicTo(1, 2, 3, 4, 0.5f); break;
+            case 3: path->cubicTo(2, 4, 6, 8, 10, 12); break;
+        }
+    }
+}
+
+// Make sure when we call shrinkToFit() that we always shrink (or stay the same)
+// and that if we call twice, we stay the same.
+DEF_TEST(Path_shrinkToFit, reporter) {
+    size_t max_free = 0;
+    for (int verbs = 0; verbs < 100; ++verbs) {
+        SkPath unique_path, shared_path;
+        add_verbs(&unique_path, verbs);
+        add_verbs(&shared_path, verbs);
+
+        const SkPath copy = shared_path;
+        REPORTER_ASSERT(reporter, shared_path == unique_path);
+        REPORTER_ASSERT(reporter, shared_path == copy);
+
+#ifdef SK_DEBUG
+        size_t before = unique_path.debugging_private_getFreeSpace();
+#endif
+        unique_path.shrinkToFit();
+        shared_path.shrinkToFit();
+        REPORTER_ASSERT(reporter, shared_path == unique_path);
+        REPORTER_ASSERT(reporter, shared_path == copy);
+
+#ifdef SK_DEBUG
+        size_t after = unique_path.debugging_private_getFreeSpace();
+        REPORTER_ASSERT(reporter, before >= after);
+        max_free = std::max(max_free, before - after);
+
+        size_t after2 = unique_path.debugging_private_getFreeSpace();
+        REPORTER_ASSERT(reporter, after == after2);
+#endif
+    }
+    if (false) {
+        SkDebugf("max_free %zu\n", max_free);
+    }
+}