aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-04-08 11:50:46 +0000
committerGravatar caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-04-08 11:50:46 +0000
commit818b0cc1b8b0c4acc565e8e2cb8b0b61aa5a300e (patch)
tree358cf664d3979252f881a6c45c4dfa93fa75de46
parent9166dcb3a0e8784bea83d76ae01aa338c049ae05 (diff)
Add implementation of path ops
This CL depends on https://codereview.chromium.org/12880016/ "Add intersections for path ops" Given a path, iterate through its contour, and construct an array of segments containing its curves. Intersect each curve with every other curve, and for cubics, with itself. Given the set of intersections, find one with the smallest y and sort the curves eminating from the intersection. Assign each curve a winding value. Operate on the curves, keeping and discarding them according to the current operation and the sum of the winding values. Assemble the kept curves into an output path. Review URL: https://codereview.chromium.org/13094010 git-svn-id: http://skia.googlecode.com/svn/trunk@8553 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--gyp/pathops_unittest.gyp137
-rw-r--r--tests/PathOpsExtendedTest.cpp822
-rw-r--r--tests/PathOpsExtendedTest.h102
-rw-r--r--tests/PathOpsOpCubicThreadedTest.cpp93
-rw-r--r--tests/PathOpsOpRectThreadedTest.cpp102
-rw-r--r--tests/PathOpsOpTest.cpp1240
-rw-r--r--tests/PathOpsQuadLineIntersectionThreadedTest.cpp135
-rwxr-xr-xtests/PathOpsSimplifyDegenerateThreadedTest.cpp103
-rw-r--r--tests/PathOpsSimplifyQuadThreadedTest.cpp104
-rwxr-xr-xtests/PathOpsSimplifyQuadralateralsThreadedTest.cpp106
-rw-r--r--tests/PathOpsSimplifyRectThreadedTest.cpp208
-rw-r--r--tests/PathOpsSimplifyTest.cpp3943
-rwxr-xr-xtests/PathOpsSimplifyTrianglesThreadedTest.cpp109
-rw-r--r--tests/PathOpsTestCommon.cpp27
-rw-r--r--tests/PathOpsTestCommon.h15
15 files changed, 7246 insertions, 0 deletions
diff --git a/gyp/pathops_unittest.gyp b/gyp/pathops_unittest.gyp
new file mode 100644
index 0000000000..e595c8673b
--- /dev/null
+++ b/gyp/pathops_unittest.gyp
@@ -0,0 +1,137 @@
+# GYP file to build unit tests.
+{
+ 'includes': [
+ 'apptype_console.gypi',
+ ],
+ 'targets': [
+ {
+ 'target_name': 'pathops_unittest',
+ 'type': 'executable',
+ 'include_dirs' : [
+ '../include/pathops',
+ '../src/core',
+ '../src/effects',
+ '../src/lazy',
+ '../src/pathops',
+ '../src/pdf',
+ '../src/pipe/utils',
+ '../src/utils',
+ '../tools/',
+ ],
+ 'sources': [
+ '../include/pathops/SkPathOps.h',
+ '../src/pathops/SkAddIntersections.cpp',
+ '../src/pathops/SkDCubicIntersection.cpp',
+ '../src/pathops/SkDCubicLineIntersection.cpp',
+ '../src/pathops/SkDCubicToQuads.cpp',
+ '../src/pathops/SkDLineIntersection.cpp',
+ '../src/pathops/SkDQuadImplicit.cpp',
+ '../src/pathops/SkDQuadIntersection.cpp',
+ '../src/pathops/SkDQuadLineIntersection.cpp',
+ '../src/pathops/SkIntersections.cpp',
+ '../src/pathops/SkOpAngle.cpp',
+ '../src/pathops/SkOpContour.cpp',
+ '../src/pathops/SkOpEdgeBuilder.cpp',
+ '../src/pathops/SkOpSegment.cpp',
+ '../src/pathops/SkPathOpsBounds.cpp',
+ '../src/pathops/SkPathOpsCommon.cpp',
+ '../src/pathops/SkPathOpsCubic.cpp',
+ '../src/pathops/SkPathOpsDebug.cpp',
+ '../src/pathops/SkPathOpsLine.cpp',
+ '../src/pathops/SkPathOpsOp.cpp',
+ '../src/pathops/SkPathOpsPoint.cpp',
+ '../src/pathops/SkPathOpsQuad.cpp',
+ '../src/pathops/SkPathOpsRect.cpp',
+ '../src/pathops/SkPathOpsSimplify.cpp',
+ '../src/pathops/SkPathOpsTriangle.cpp',
+ '../src/pathops/SkPathOpsTypes.cpp',
+ '../src/pathops/SkPathWriter.cpp',
+ '../src/pathops/SkQuarticRoot.cpp',
+ '../src/pathops/SkReduceOrder.cpp',
+ '../src/pathops/SkAddIntersections.h',
+ '../src/pathops/SkDQuadImplicit.h',
+ '../src/pathops/SkIntersectionHelper.h',
+ '../src/pathops/SkIntersections.h',
+ '../src/pathops/SkLineParameters.h',
+ '../src/pathops/SkOpAngle.h',
+ '../src/pathops/SkOpContour.h',
+ '../src/pathops/SkOpEdgeBuilder.h',
+ '../src/pathops/SkOpSegment.h',
+ '../src/pathops/SkOpSpan.h',
+ '../src/pathops/SkPathOpsBounds.h',
+ '../src/pathops/SkPathOpsCommon.h',
+ '../src/pathops/SkPathOpsCubic.h',
+ '../src/pathops/SkPathOpsCurve.h',
+ '../src/pathops/SkPathOpsDebug.h',
+ '../src/pathops/SkPathOpsLine.h',
+ '../src/pathops/SkPathOpsPoint.h',
+ '../src/pathops/SkPathOpsQuad.h',
+ '../src/pathops/SkPathOpsRect.h',
+ '../src/pathops/SkPathOpsSpan.h',
+ '../src/pathops/SkPathOpsTriangle.h',
+ '../src/pathops/SkPathOpsTypes.h',
+ '../src/pathops/SkPathWriter.h',
+ '../src/pathops/SkQuarticRoot.h',
+ '../src/pathops/SkReduceOrder.h',
+ '../src/pathops/TSearch.h',
+ '../tests/PathOpsBoundsTest.cpp',
+ '../tests/PathOpsCubicIntersectionTest.cpp',
+ '../tests/PathOpsCubicIntersectionTestData.cpp',
+ '../tests/PathOpsCubicLineIntersectionTest.cpp',
+ '../tests/PathOpsCubicReduceOrderTest.cpp',
+ '../tests/PathOpsCubicToQuadsTest.cpp',
+ '../tests/PathOpsDCubicTest.cpp',
+ '../tests/PathOpsDLineTest.cpp',
+ '../tests/PathOpsDPointTest.cpp',
+ '../tests/PathOpsDQuadTest.cpp',
+ '../tests/PathOpsDRectTest.cpp',
+ '../tests/PathOpsDTriangleTest.cpp',
+ '../tests/PathOpsDVectorTest.cpp',
+ '../tests/PathOpsExtendedTest.cpp',
+ '../tests/PathOpsLineIntersectionTest.cpp',
+ '../tests/PathOpsLineParametetersTest.cpp',
+ '../tests/PathOpsOpCubicThreadedTest.cpp',
+ '../tests/PathOpsOpRectThreadedTest.cpp',
+ '../tests/PathOpsOpTest.cpp',
+ '../tests/PathOpsQuadIntersectionTest.cpp',
+ '../tests/PathOpsQuadIntersectionTestData.cpp',
+ '../tests/PathOpsQuadLineIntersectionTest.cpp',
+ '../tests/PathOpsQuadLineIntersectionThreadedTest.cpp',
+ '../tests/PathOpsQuadParameterizationTest.cpp',
+ '../tests/PathOpsSimplifyDegenerateThreadedTest.cpp',
+ '../tests/PathOpsSimplifyQuadralateralsThreadedTest.cpp',
+ '../tests/PathOpsSimplifyQuadThreadedTest.cpp',
+ '../tests/PathOpsSimplifyRectThreadedTest.cpp',
+ '../tests/PathOpsSimplifyTest.cpp',
+ '../tests/PathOpsSimplifyTrianglesThreadedTest.cpp',
+ '../tests/PathOpsTestCommon.cpp',
+ '../tests/PathOpsCubicIntersectionTestData.h',
+ '../tests/PathOpsExtendedTest.h',
+ '../tests/PathOpsQuadIntersectionTestData.h',
+ '../tests/PathOpsTestCommon.h',
+ '../tests/Test.cpp',
+ '../tests/skia_test.cpp',
+ '../tests/Test.h',
+ ],
+ 'dependencies': [
+ 'skia_base_libs.gyp:skia_base_libs',
+ 'effects.gyp:effects',
+ 'images.gyp:images',
+ 'utils.gyp:utils',
+ ],
+ 'conditions': [
+ [ 'skia_gpu == 1', {
+ 'include_dirs': [
+ '../src/gpu',
+ ],
+ }],
+ ],
+ },
+ ],
+}
+
+# Local Variables:
+# tab-width:2
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=2 shiftwidth=2:
diff --git a/tests/PathOpsExtendedTest.cpp b/tests/PathOpsExtendedTest.cpp
new file mode 100644
index 0000000000..f1748cdb4c
--- /dev/null
+++ b/tests/PathOpsExtendedTest.cpp
@@ -0,0 +1,822 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "PathOpsExtendedTest.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkMatrix.h"
+#include "SkPaint.h"
+#include "SkStream.h"
+
+#ifdef SK_BUILD_FOR_MAC
+#include <sys/sysctl.h>
+#endif
+
+bool gShowTestProgress = false;
+bool gAllowExtendedTest = false;
+
+static const char marker[] =
+ "</div>\n"
+ "\n"
+ "<script type=\"text/javascript\">\n"
+ "\n"
+ "var testDivs = [\n";
+
+static const char* opStrs[] = {
+ "kDifference_PathOp",
+ "kIntersect_PathOp",
+ "kUnion_PathOp",
+ "kXor_PathOp",
+};
+
+static const char* opSuffixes[] = {
+ "d",
+ "i",
+ "u",
+ "x",
+};
+
+static bool gShowPath = false;
+static bool gComparePaths = true;
+static bool gShowOutputProgress = false;
+static bool gComparePathsAssert = true;
+static bool gPathStrAssert = true;
+static bool gUsePhysicalFiles = false;
+
+#if FORCE_RELEASE && !defined SK_BUILD_FOR_WIN
+static bool gRunTestsInOneThread = false;
+#else
+static bool gRunTestsInOneThread = true;
+#endif
+
+static void showPathContour(SkPath::Iter& iter) {
+ uint8_t verb;
+ SkPoint pts[4];
+ while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
+ switch (verb) {
+ case SkPath::kMove_Verb:
+ SkDebugf("path.moveTo(%1.9g,%1.9g);\n", pts[0].fX, pts[0].fY);
+ continue;
+ case SkPath::kLine_Verb:
+ SkDebugf("path.lineTo(%1.9g,%1.9g);\n", pts[1].fX, pts[1].fY);
+ break;
+ case SkPath::kQuad_Verb:
+ SkDebugf("path.quadTo(%1.9g,%1.9g, %1.9g,%1.9g);\n",
+ pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
+ break;
+ case SkPath::kCubic_Verb:
+ SkDebugf("path.cubicTo(%1.9g,%1.9g, %1.9g,%1.9g, %1.9g,%1.9g);\n",
+ pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY, pts[3].fX, pts[3].fY);
+ break;
+ case SkPath::kClose_Verb:
+ SkDebugf("path.close();\n");
+ break;
+ default:
+ SkDEBUGFAIL("bad verb");
+ return;
+ }
+ }
+}
+
+void showPath(const SkPath& path, const char* str) {
+ SkDebugf("%s\n", !str ? "original:" : str);
+ showPath(path);
+}
+
+void showPath(const SkPath& path) {
+ SkPath::Iter iter(path, true);
+#define SUPPORT_RECT_CONTOUR_DETECTION 0
+#if SUPPORT_RECT_CONTOUR_DETECTION
+ int rectCount = path.isRectContours() ? path.rectContours(NULL, NULL) : 0;
+ if (rectCount > 0) {
+ SkTDArray<SkRect> rects;
+ SkTDArray<SkPath::Direction> directions;
+ rects.setCount(rectCount);
+ directions.setCount(rectCount);
+ path.rectContours(rects.begin(), directions.begin());
+ for (int contour = 0; contour < rectCount; ++contour) {
+ const SkRect& rect = rects[contour];
+ SkDebugf("path.addRect(%1.9g, %1.9g, %1.9g, %1.9g, %s);\n", rect.fLeft, rect.fTop,
+ rect.fRight, rect.fBottom, directions[contour] == SkPath::kCCW_Direction
+ ? "SkPath::kCCW_Direction" : "SkPath::kCW_Direction");
+ }
+ return;
+ }
+#endif
+ iter.setPath(path, true);
+ showPathContour(iter);
+}
+
+void showPathData(const SkPath& path) {
+ SkPath::Iter iter(path, true);
+ uint8_t verb;
+ SkPoint pts[4];
+ while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
+ switch (verb) {
+ case SkPath::kMove_Verb:
+ continue;
+ case SkPath::kLine_Verb:
+ SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY);
+ break;
+ case SkPath::kQuad_Verb:
+ SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n",
+ pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
+ break;
+ case SkPath::kCubic_Verb:
+ SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n",
+ pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY, pts[3].fX, pts[3].fY);
+ break;
+ case SkPath::kClose_Verb:
+ break;
+ default:
+ SkDEBUGFAIL("bad verb");
+ return;
+ }
+ }
+}
+
+void showOp(const SkPathOp op) {
+ switch (op) {
+ case kDifference_PathOp:
+ SkDebugf("op difference\n");
+ break;
+ case kIntersect_PathOp:
+ SkDebugf("op intersect\n");
+ break;
+ case kUnion_PathOp:
+ SkDebugf("op union\n");
+ break;
+ case kXOR_PathOp:
+ SkDebugf("op xor\n");
+ break;
+ default:
+ SkASSERT(0);
+ }
+}
+
+static void showPath(const SkPath& path, const char* str, const SkMatrix& scale) {
+ SkPath scaled;
+ SkMatrix inverse;
+ bool success = scale.invert(&inverse);
+ if (!success) {
+ SkASSERT(0);
+ }
+ path.transform(inverse, &scaled);
+ showPath(scaled, str);
+}
+
+const int bitWidth = 64;
+const int bitHeight = 64;
+
+static void scaleMatrix(const SkPath& one, const SkPath& two, SkMatrix& scale) {
+ SkRect larger = one.getBounds();
+ larger.join(two.getBounds());
+ SkScalar largerWidth = larger.width();
+ if (largerWidth < 4) {
+ largerWidth = 4;
+ }
+ SkScalar largerHeight = larger.height();
+ if (largerHeight < 4) {
+ largerHeight = 4;
+ }
+ SkScalar hScale = (bitWidth - 2) / largerWidth;
+ SkScalar vScale = (bitHeight - 2) / largerHeight;
+ scale.reset();
+ scale.preScale(hScale, vScale);
+}
+
+static int pathsDrawTheSame(SkBitmap& bits, const SkPath& scaledOne, const SkPath& scaledTwo,
+ int& error2x2) {
+ if (bits.width() == 0) {
+ bits.setConfig(SkBitmap::kARGB_8888_Config, bitWidth * 2, bitHeight);
+ bits.allocPixels();
+ }
+ SkCanvas canvas(bits);
+ canvas.drawColor(SK_ColorWHITE);
+ SkPaint paint;
+ canvas.save();
+ const SkRect& bounds1 = scaledOne.getBounds();
+ canvas.translate(-bounds1.fLeft + 1, -bounds1.fTop + 1);
+ canvas.drawPath(scaledOne, paint);
+ canvas.restore();
+ canvas.save();
+ canvas.translate(-bounds1.fLeft + 1 + bitWidth, -bounds1.fTop + 1);
+ canvas.drawPath(scaledTwo, paint);
+ canvas.restore();
+ int errors2 = 0;
+ int errors = 0;
+ for (int y = 0; y < bitHeight - 1; ++y) {
+ uint32_t* addr1 = bits.getAddr32(0, y);
+ uint32_t* addr2 = bits.getAddr32(0, y + 1);
+ uint32_t* addr3 = bits.getAddr32(bitWidth, y);
+ uint32_t* addr4 = bits.getAddr32(bitWidth, y + 1);
+ for (int x = 0; x < bitWidth - 1; ++x) {
+ // count 2x2 blocks
+ bool err = addr1[x] != addr3[x];
+ if (err) {
+ errors2 += addr1[x + 1] != addr3[x + 1]
+ && addr2[x] != addr4[x] && addr2[x + 1] != addr4[x + 1];
+ errors++;
+ }
+ }
+ }
+ if (errors2 >= 6 || errors > 160) {
+ SkDebugf("%s errors2=%d errors=%d\n", __FUNCTION__, errors2, errors);
+ }
+ error2x2 = errors2;
+ return errors;
+}
+
+static int pathsDrawTheSame(const SkPath& one, const SkPath& two, SkBitmap& bits, SkPath& scaledOne,
+ SkPath& scaledTwo, int& error2x2) {
+ SkMatrix scale;
+ scaleMatrix(one, two, scale);
+ one.transform(scale, &scaledOne);
+ two.transform(scale, &scaledTwo);
+ return pathsDrawTheSame(bits, scaledOne, scaledTwo, error2x2);
+}
+
+bool drawAsciiPaths(const SkPath& one, const SkPath& two, bool drawPaths) {
+ if (!drawPaths) {
+ return true;
+ }
+ const SkRect& bounds1 = one.getBounds();
+ const SkRect& bounds2 = two.getBounds();
+ SkRect larger = bounds1;
+ larger.join(bounds2);
+ SkBitmap bits;
+ char out[256];
+ int bitWidth = SkScalarCeil(larger.width()) + 2;
+ if (bitWidth * 2 + 1 >= (int) sizeof(out)) {
+ return false;
+ }
+ int bitHeight = SkScalarCeil(larger.height()) + 2;
+ if (bitHeight >= (int) sizeof(out)) {
+ return false;
+ }
+ bits.setConfig(SkBitmap::kARGB_8888_Config, bitWidth * 2, bitHeight);
+ bits.allocPixels();
+ SkCanvas canvas(bits);
+ canvas.drawColor(SK_ColorWHITE);
+ SkPaint paint;
+ canvas.save();
+ canvas.translate(-bounds1.fLeft + 1, -bounds1.fTop + 1);
+ canvas.drawPath(one, paint);
+ canvas.restore();
+ canvas.save();
+ canvas.translate(-bounds1.fLeft + 1 + bitWidth, -bounds1.fTop + 1);
+ canvas.drawPath(two, paint);
+ canvas.restore();
+ for (int y = 0; y < bitHeight; ++y) {
+ uint32_t* addr1 = bits.getAddr32(0, y);
+ int x;
+ char* outPtr = out;
+ for (x = 0; x < bitWidth; ++x) {
+ *outPtr++ = addr1[x] == (uint32_t) -1 ? '_' : 'x';
+ }
+ *outPtr++ = '|';
+ for (x = bitWidth; x < bitWidth * 2; ++x) {
+ *outPtr++ = addr1[x] == (uint32_t) -1 ? '_' : 'x';
+ }
+ *outPtr++ = '\0';
+ SkDebugf("%s\n", out);
+ }
+ return true;
+}
+
+static void showSimplifiedPath(const SkPath& one, const SkPath& two,
+ const SkPath& scaledOne, const SkPath& scaledTwo) {
+ showPath(one, "original:");
+ showPath(two, "simplified:");
+ drawAsciiPaths(scaledOne, scaledTwo, true);
+}
+
+static int comparePaths(skiatest::Reporter* reporter, const SkPath& one, const SkPath& two,
+ SkBitmap& bitmap) {
+ int errors2x2;
+ SkPath scaledOne, scaledTwo;
+ int errors = pathsDrawTheSame(one, two, bitmap, scaledOne, scaledTwo, errors2x2);
+ if (errors2x2 == 0) {
+ return 0;
+ }
+ const int MAX_ERRORS = 9;
+ if (errors2x2 == MAX_ERRORS || errors2x2 == MAX_ERRORS - 1) {
+ showSimplifiedPath(one, two, scaledOne, scaledTwo);
+ }
+ if (errors2x2 > MAX_ERRORS && gComparePathsAssert) {
+ SkDebugf("%s errors=%d\n", __FUNCTION__, errors);
+ showSimplifiedPath(one, two, scaledOne, scaledTwo);
+ REPORTER_ASSERT(reporter, 0);
+ }
+ return errors2x2 > MAX_ERRORS ? errors2x2 : 0;
+}
+
+static void showPathOpPath(const SkPath& one, const SkPath& two, const SkPath& a, const SkPath& b,
+ const SkPath& scaledOne, const SkPath& scaledTwo, const SkPathOp shapeOp,
+ const SkMatrix& scale) {
+ SkASSERT((unsigned) shapeOp < sizeof(opStrs) / sizeof(opStrs[0]));
+ showPath(a, "minuend:");
+ SkDebugf("op: %s\n", opStrs[shapeOp]);
+ showPath(b, "subtrahend:");
+ // the region often isn't very helpful since it approximates curves with a lot of line-tos
+ if (0) showPath(scaledOne, "region:", scale);
+ showPath(two, "op result:");
+ drawAsciiPaths(scaledOne, scaledTwo, true);
+}
+
+static int comparePaths(skiatest::Reporter* reporter, const SkPath& one, const SkPath& scaledOne,
+ const SkPath& two, const SkPath& scaledTwo, SkBitmap& bitmap,
+ const SkPath& a, const SkPath& b, const SkPathOp shapeOp,
+ const SkMatrix& scale) {
+ int errors2x2;
+ int errors = pathsDrawTheSame(bitmap, scaledOne, scaledTwo, errors2x2);
+ if (errors2x2 == 0) {
+ return 0;
+ }
+ const int MAX_ERRORS = 8;
+ if (errors2x2 == MAX_ERRORS || errors2x2 == MAX_ERRORS - 1) {
+ showPathOpPath(one, two, a, b, scaledOne, scaledTwo, shapeOp, scale);
+ }
+ if (errors2x2 > MAX_ERRORS && gComparePathsAssert) {
+ SkDebugf("%s errors=%d\n", __FUNCTION__, errors);
+ showPathOpPath(one, two, a, b, scaledOne, scaledTwo, shapeOp, scale);
+ REPORTER_ASSERT(reporter, 0);
+ }
+ return errors2x2 > MAX_ERRORS ? errors2x2 : 0;
+}
+
+bool testSimplify(SkPath& path, bool useXor, SkPath& out, State4& state, const char* pathStr) {
+ SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType;
+ path.setFillType(fillType);
+ if (gShowPath) {
+ showPath(path);
+ }
+ Simplify(path, &out);
+ if (!gComparePaths) {
+ return true;
+ }
+ int result = comparePaths(state.reporter, path, out, state.bitmap);
+ if (result && gPathStrAssert) {
+ SkDebugf("addTest %s\n", state.filename);
+ char temp[8192];
+ sk_bzero(temp, sizeof(temp));
+ SkMemoryWStream stream(temp, sizeof(temp));
+ const char* pathPrefix = NULL;
+ const char* nameSuffix = NULL;
+ if (fillType == SkPath::kEvenOdd_FillType) {
+ pathPrefix = " path.setFillType(SkPath::kEvenOdd_FillType);\n";
+ nameSuffix = "x";
+ }
+ const char testFunction[] = "testSimplifyx(path);";
+ outputToStream(state, pathStr, pathPrefix, nameSuffix, testFunction, stream);
+ SkDebugf(temp);
+ REPORTER_ASSERT(state.reporter, 0);
+ }
+ return result == 0;
+}
+
+bool testSimplify(skiatest::Reporter* reporter, const SkPath& path) {
+ SkPath out;
+ Simplify(path, &out);
+ SkBitmap bitmap;
+ int result = comparePaths(reporter, path, out, bitmap);
+ if (result && gPathStrAssert) {
+ REPORTER_ASSERT(reporter, 0);
+ }
+ return result == 0;
+}
+
+bool testPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
+ const SkPathOp shapeOp) {
+#if FORCE_RELEASE == 0
+ showPathData(a);
+ showOp(shapeOp);
+ showPathData(b);
+#endif
+ SkPath out;
+ Op(a, b, shapeOp, &out);
+ SkPath pathOut, scaledPathOut;
+ SkRegion rgnA, rgnB, openClip, rgnOut;
+ openClip.setRect(-16000, -16000, 16000, 16000);
+ rgnA.setPath(a, openClip);
+ rgnB.setPath(b, openClip);
+ rgnOut.op(rgnA, rgnB, (SkRegion::Op) shapeOp);
+ rgnOut.getBoundaryPath(&pathOut);
+
+ SkMatrix scale;
+ scaleMatrix(a, b, scale);
+ SkRegion scaledRgnA, scaledRgnB, scaledRgnOut;
+ SkPath scaledA, scaledB;
+ scaledA.addPath(a, scale);
+ scaledA.setFillType(a.getFillType());
+ scaledB.addPath(b, scale);
+ scaledB.setFillType(b.getFillType());
+ scaledRgnA.setPath(scaledA, openClip);
+ scaledRgnB.setPath(scaledB, openClip);
+ scaledRgnOut.op(scaledRgnA, scaledRgnB, (SkRegion::Op) shapeOp);
+ scaledRgnOut.getBoundaryPath(&scaledPathOut);
+ SkBitmap bitmap;
+ SkPath scaledOut;
+ scaledOut.addPath(out, scale);
+ scaledOut.setFillType(out.getFillType());
+ int result = comparePaths(reporter, pathOut, scaledPathOut, out, scaledOut, bitmap, a, b,
+ shapeOp, scale);
+ if (result && gPathStrAssert) {
+ REPORTER_ASSERT(reporter, 0);
+ }
+ return result == 0;
+}
+
+const int maxThreadsAllocated = 64;
+static int maxThreads = 1;
+static int threadIndex;
+State4 threadState[maxThreadsAllocated];
+static int testNumber;
+static const char* testName;
+static bool debugThreads = false;
+
+State4* State4::queue = NULL;
+
+#if HARD_CODE_PTHREAD
+pthread_mutex_t State4::addQueue = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t State4::checkQueue = PTHREAD_COND_INITIALIZER;
+#else
+SK_DECLARE_STATIC_MUTEX(gQueueMutex);
+#endif
+
+State4::State4() {
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config, 150 * 2, 100);
+ bitmap.allocPixels();
+}
+
+void createThread(State4* statePtr, ThreadFunction testFun) {
+#if HARD_CODE_PTHREAD
+ SkDEBUGCODE(int threadError =) pthread_create(&statePtr->threadID, NULL, testFun,
+ (void*) statePtr);
+ SkASSERT(!threadError);
+#else
+ statePtr->thread = new SkThread(testFun, (void*) statePtr);
+ statePtr->thread->start();
+#endif
+}
+
+int dispatchTest4(ThreadFunction testFun, int a, int b, int c, int d) {
+ int testsRun = 0;
+ State4* statePtr;
+ if (!gRunTestsInOneThread) {
+#if HARD_CODE_PTHREAD
+ pthread_mutex_lock(&State4::addQueue);
+#else
+ SkAutoMutexAcquire aq(&gQueueMutex);
+#endif
+ if (threadIndex < maxThreads) {
+ statePtr = &threadState[threadIndex];
+ statePtr->testsRun = 0;
+ statePtr->a = a;
+ statePtr->b = b;
+ statePtr->c = c;
+ statePtr->d = d;
+ statePtr->done = false;
+ statePtr->index = threadIndex;
+ statePtr->last = false;
+ if (debugThreads) SkDebugf("%s %d create done=%d last=%d\n", __FUNCTION__,
+ statePtr->index, statePtr->done, statePtr->last);
+#if HARD_CODE_PTHREAD
+ pthread_cond_init(&statePtr->initialized, NULL);
+#else
+ // statePtr->thread contains fData which points to SkThread_PThreadData which
+ // contains PThreadEvent fStarted, all of which is initialized by createThread below
+#endif
+ ++threadIndex;
+ createThread(statePtr, testFun);
+ } else {
+ while (!State4::queue) {
+ if (debugThreads) SkDebugf("%s checkQueue\n", __FUNCTION__);
+#if HARD_CODE_PTHREAD
+ pthread_cond_wait(&State4::checkQueue, &State4::addQueue);
+#else
+ // incomplete
+#endif
+ }
+ statePtr = State4::queue;
+ testsRun += statePtr->testsRun;
+ statePtr->testsRun = 0;
+ statePtr->a = a;
+ statePtr->b = b;
+ statePtr->c = c;
+ statePtr->d = d;
+ statePtr->done = false;
+ State4::queue = NULL;
+ for (int index = 0; index < maxThreads; ++index) {
+ if (threadState[index].done) {
+ State4::queue = &threadState[index];
+ }
+ }
+ if (debugThreads) SkDebugf("%s %d init done=%d last=%d queued=%d\n", __FUNCTION__,
+ statePtr->index, statePtr->done, statePtr->last,
+ State4::queue ? State4::queue->index : -1);
+#if HARD_CODE_PTHREAD
+ pthread_cond_signal(&statePtr->initialized);
+#else
+ // incomplete
+#endif
+ }
+#if HARD_CODE_PTHREAD
+ pthread_mutex_unlock(&State4::addQueue);
+#endif
+ } else {
+ statePtr = &threadState[0];
+ testsRun += statePtr->testsRun;
+ statePtr->testsRun = 0;
+ statePtr->a = a;
+ statePtr->b = b;
+ statePtr->c = c;
+ statePtr->d = d;
+ statePtr->done = false;
+ statePtr->index = threadIndex;
+ statePtr->last = false;
+ (*testFun)(statePtr);
+ }
+ return testsRun;
+}
+
+void initializeTests(skiatest::Reporter* reporter, const char* test, size_t testNameSize) {
+ testName = test;
+ if (!gRunTestsInOneThread) {
+ int threads = -1;
+#ifdef SK_BUILD_FOR_MAC
+ size_t size = sizeof(threads);
+ sysctlbyname("hw.logicalcpu_max", &threads, &size, NULL, 0);
+#endif
+ if (threads > 0) {
+ maxThreads = threads;
+ } else {
+ maxThreads = 8;
+ }
+ }
+ SkFILEStream inFile("../../experimental/Intersection/op.htm");
+ if (inFile.isValid()) {
+ SkTDArray<char> inData;
+ inData.setCount(inFile.getLength());
+ size_t inLen = inData.count();
+ inFile.read(inData.begin(), inLen);
+ inFile.setPath(NULL);
+ char* insert = strstr(inData.begin(), marker);
+ if (insert) {
+ insert += sizeof(marker) - 1;
+ const char* numLoc = insert + 4 /* indent spaces */ + testNameSize - 1;
+ testNumber = atoi(numLoc) + 1;
+ }
+ }
+ const char* filename = "debugXX.txt";
+ for (int index = 0; index < maxThreads; ++index) {
+ State4* statePtr = &threadState[index];
+ statePtr->reporter = reporter;
+ strcpy(statePtr->filename, filename);
+ size_t len = strlen(filename);
+ SkASSERT(statePtr->filename[len - 6] == 'X');
+ SkASSERT(statePtr->filename[len - 5] == 'X');
+ statePtr->filename[len - 6] = '0' + index / 10;
+ statePtr->filename[len - 5] = '0' + index % 10;
+ }
+ threadIndex = 0;
+}
+
+void outputProgress(const State4& state, const char* pathStr, SkPath::FillType pathFillType) {
+ if (gRunTestsInOneThread && gShowOutputProgress) {
+ if (pathFillType == SkPath::kEvenOdd_FillType) {
+ SkDebugf(" path.setFillType(SkPath::kEvenOdd_FillType);\n", pathStr);
+ }
+ SkDebugf("%s\n", pathStr);
+ }
+ const char testFunction[] = "testSimplifyx(path);";
+ const char* pathPrefix = NULL;
+ const char* nameSuffix = NULL;
+ if (pathFillType == SkPath::kEvenOdd_FillType) {
+ pathPrefix = " path.setFillType(SkPath::kEvenOdd_FillType);\n";
+ nameSuffix = "x";
+ }
+ if (gUsePhysicalFiles) {
+ SkFILEWStream outFile(state.filename);
+ if (!outFile.isValid()) {
+ SkASSERT(0);
+ return;
+ }
+ outputToStream(state, pathStr, pathPrefix, nameSuffix, testFunction, outFile);
+ return;
+ }
+ state.ramStream.reset();
+ outputToStream(state, pathStr, pathPrefix, nameSuffix, testFunction, state.ramStream);
+}
+
+void outputProgress(const State4& state, const char* pathStr, SkPathOp op) {
+ SkString testFunc("testPathOp(path, pathB, ");
+ testFunc += opStrs[op];
+ testFunc += ");";
+ const char* testFunction = testFunc.c_str();
+ if (gRunTestsInOneThread && gShowOutputProgress) {
+ SkDebugf("%s\n", pathStr);
+ SkDebugf(" %s\n", testFunction);
+ }
+ const char* nameSuffix = opSuffixes[op];
+ if (gUsePhysicalFiles) {
+ SkFILEWStream outFile(state.filename);
+ if (!outFile.isValid()) {
+ SkASSERT(0);
+ return;
+ }
+ outputToStream(state, pathStr, NULL, nameSuffix, testFunction, outFile);
+ return;
+ }
+ state.ramStream.reset();
+ outputToStream(state, pathStr, NULL, nameSuffix, testFunction, state.ramStream);
+}
+
+static void writeTestName(const char* nameSuffix, SkWStream& outFile) {
+ outFile.writeText(testName);
+ outFile.writeDecAsText(testNumber);
+ if (nameSuffix) {
+ outFile.writeText(nameSuffix);
+ }
+}
+
+void outputToStream(const State4& state, const char* pathStr, const char* pathPrefix,
+ const char* nameSuffix,
+ const char* testFunction, SkWStream& outFile) {
+ outFile.writeText("<div id=\"");
+ writeTestName(nameSuffix, outFile);
+ outFile.writeText("\">\n");
+ if (pathPrefix) {
+ outFile.writeText(pathPrefix);
+ }
+ outFile.writeText(pathStr);
+ outFile.writeText("</div>\n\n");
+
+ outFile.writeText(marker);
+ outFile.writeText(" ");
+ writeTestName(nameSuffix, outFile);
+ outFile.writeText(",\n\n\n");
+
+ outFile.writeText("static void ");
+ writeTestName(nameSuffix, outFile);
+ outFile.writeText("() {\n SkPath path");
+ if (!pathPrefix) {
+ outFile.writeText(", pathB");
+ }
+ outFile.writeText(";\n");
+ if (pathPrefix) {
+ outFile.writeText(pathPrefix);
+ }
+ outFile.writeText(pathStr);
+ outFile.writeText(" ");
+ outFile.writeText(testFunction);
+ outFile.writeText("\n}\n\n");
+ outFile.writeText("static void (*firstTest)() = ");
+ writeTestName(nameSuffix, outFile);
+ outFile.writeText(";\n\n");
+
+ outFile.writeText("static struct {\n");
+ outFile.writeText(" void (*fun)();\n");
+ outFile.writeText(" const char* str;\n");
+ outFile.writeText("} tests[] = {\n");
+ outFile.writeText(" TEST(");
+ writeTestName(nameSuffix, outFile);
+ outFile.writeText("),\n");
+ outFile.flush();
+}
+
+bool runNextTestSet(State4& state) {
+ if (gRunTestsInOneThread) {
+ return false;
+ }
+#if HARD_CODE_PTHREAD
+ pthread_mutex_lock(&State4::addQueue);
+#else
+ SkAutoMutexAcquire aq(&gQueueMutex);
+#endif
+ state.done = true;
+ State4::queue = &state;
+ if (debugThreads) SkDebugf("%s %d checkQueue done=%d last=%d\n", __FUNCTION__, state.index,
+ state.done, state.last);
+#if HARD_CODE_PTHREAD
+ pthread_cond_signal(&State4::checkQueue);
+#else
+ // incomplete
+#endif
+ while (state.done && !state.last) {
+ if (debugThreads) SkDebugf("%s %d done=%d last=%d\n", __FUNCTION__, state.index, state.done, state.last);
+#if HARD_CODE_PTHREAD
+ pthread_cond_wait(&state.initialized, &State4::addQueue);
+#else
+ // incomplete
+#endif
+ }
+#if HARD_CODE_PTHREAD
+ pthread_mutex_unlock(&State4::addQueue);
+#endif
+ return !state.last;
+}
+
+int waitForCompletion() {
+ int testsRun = 0;
+ if (!gRunTestsInOneThread) {
+#if HARD_CODE_PTHREAD
+ pthread_mutex_lock(&State4::addQueue);
+#else
+ SkAutoMutexAcquire aq(gQueueMutex);
+#endif
+ int runningThreads = threadIndex;
+ int index;
+ while (runningThreads > 0) {
+ while (!State4::queue) {
+ if (debugThreads) SkDebugf("%s checkQueue\n", __FUNCTION__);
+#if HARD_CODE_PTHREAD
+ pthread_cond_wait(&State4::checkQueue, &State4::addQueue);
+#else
+ // ioncomplete
+#endif
+ }
+ while (State4::queue) {
+ --runningThreads;
+#if DEBUG_SHOW_TEST_PROGRESS
+ SkDebugf("•");
+#endif
+ State4::queue->last = true;
+ State4* next = NULL;
+ for (index = 0; index < maxThreads; ++index) {
+ State4& test = threadState[index];
+ if (test.done && !test.last) {
+ next = &test;
+ }
+ }
+ if (debugThreads) SkDebugf("%s %d next=%d deQueue\n", __FUNCTION__,
+ State4::queue->index, next ? next->index : -1);
+#if HARD_CODE_PTHREAD
+ pthread_cond_signal(&State4::queue->initialized);
+#else
+ // incomplete
+#endif
+ State4::queue = next;
+ }
+ }
+#if HARD_CODE_PTHREAD
+ pthread_mutex_unlock(&State4::addQueue);
+#endif
+ for (index = 0; index < maxThreads; ++index) {
+#if HARD_CODE_PTHREAD
+ pthread_join(threadState[index].threadID, NULL);
+#else
+ threadState[index].thread->join();
+ delete threadState[index].thread;
+#endif
+ testsRun += threadState[index].testsRun;
+ }
+#if DEBUG_SHOW_TEST_PROGRESS
+ SkDebugf("\n");
+#endif
+ }
+#ifdef SK_DEBUG
+ gDebugMaxWindSum = SK_MaxS32;
+ gDebugMaxWindValue = SK_MaxS32;
+#endif
+ return testsRun;
+}
+
+void RunTestSet(skiatest::Reporter* reporter, TestDesc tests[], size_t count,
+ void (*firstTest)(skiatest::Reporter* ),
+ void (*stopTest)(skiatest::Reporter* ), bool reverse) {
+ size_t index;
+ if (firstTest) {
+ index = count - 1;
+ while (index > 0 && tests[index].fun != firstTest) {
+ --index;
+ }
+#if FORCE_RELEASE == 0
+ SkDebugf("<div id=\"%s\">\n", tests[index].str);
+ SkDebugf(" %s [%s]\n", __FUNCTION__, tests[index].str);
+#endif
+ (*tests[index].fun)(reporter);
+ }
+ index = reverse ? count - 1 : 0;
+ size_t last = reverse ? 0 : count - 1;
+ do {
+ if (tests[index].fun != firstTest) {
+ #if FORCE_RELEASE == 0
+ SkDebugf("<div id=\"%s\">\n", tests[index].str);
+ SkDebugf(" %s [%s]\n", __FUNCTION__, tests[index].str);
+ #endif
+ (*tests[index].fun)(reporter);
+ }
+ if (tests[index].fun == stopTest) {
+ SkDebugf("lastTest\n");
+ }
+ if (index == last) {
+ break;
+ }
+ index += reverse ? -1 : 1;
+ } while (true);
+}
diff --git a/tests/PathOpsExtendedTest.h b/tests/PathOpsExtendedTest.h
new file mode 100644
index 0000000000..59fb92d5b6
--- /dev/null
+++ b/tests/PathOpsExtendedTest.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef PathOpsExtendedTest_DEFINED
+#define PathOpsExtendedTest_DEFINED
+
+#include "Test.h"
+#include "SkPathOpsTypes.h"
+#include "SkBitmap.h"
+#include "SkPath.h"
+#include "SkStream.h"
+
+#ifdef SK_BUILD_FOR_WIN
+#define HARD_CODE_PTHREAD 0
+#else
+#define HARD_CODE_PTHREAD 1
+#endif
+
+#if HARD_CODE_PTHREAD
+#include <pthread.h>
+#else
+#include "SkThread.h"
+#include "../../src/utils/SkThreadUtils.h"
+#endif
+
+#if HARD_CODE_PTHREAD
+typedef void* (*ThreadFunction)(void*);
+#define THREAD_TYPE void*
+#define THREAD_RETURN return NULL;
+#else
+typedef void (*ThreadFunction)(void*);
+#define THREAD_TYPE void
+#define THREAD_RETURN
+#endif
+
+struct State4;
+
+struct TestDesc {
+ void (*fun)(skiatest::Reporter*);
+ const char* str;
+};
+
+extern bool gShowTestProgress;
+extern bool gAllowExtendedTest;
+
+//extern int comparePaths(const SkPath& one, const SkPath& two);
+extern int comparePaths(const SkPath& one, const SkPath& two, SkBitmap& bitmap);
+extern bool drawAsciiPaths(const SkPath& one, const SkPath& two, bool drawPaths);
+extern void showOp(const SkPathOp op);
+extern void showPath(const SkPath& path, const char* str);
+extern void showPath(const SkPath& path);
+extern void showPathData(const SkPath& path);
+extern bool testPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
+ const SkPathOp );
+extern bool testSimplify(SkPath& path, bool useXor, SkPath& out,
+ State4& state, const char* pathStr);
+extern bool testSimplify(skiatest::Reporter* reporter, const SkPath& path);
+
+struct State4 {
+ State4();
+#if HARD_CODE_PTHREAD
+ static pthread_mutex_t addQueue;
+ static pthread_cond_t checkQueue;
+ pthread_cond_t initialized;
+ pthread_t threadID;
+#else
+ SkThread* thread;
+#endif
+ static State4* queue;
+ int index;
+ bool done;
+ bool last;
+ int a;
+ int b;
+ int c;
+ int d; // sometimes 1 if abc_is_a_triangle
+ int testsRun;
+ char filename[256];
+ skiatest::Reporter* reporter;
+ SkBitmap bitmap;
+ mutable SkDynamicMemoryWStream ramStream;
+};
+
+void createThread(State4* statePtr, void* (*test)(void* ));
+int dispatchTest4(ThreadFunction testFun, int a, int b, int c, int d);
+void initializeTests(skiatest::Reporter* reporter, const char* testName, size_t testNameSize);
+void outputProgress(const State4& state, const char* pathStr, SkPath::FillType );
+void outputProgress(const State4& state, const char* pathStr, SkPathOp op);
+void outputToStream(const State4& state, const char* pathStr, const char* pathPrefix,
+ const char* nameSuffix,
+ const char* testFunction, SkWStream& outFile);
+bool runNextTestSet(State4& state);
+int waitForCompletion();
+
+void RunTestSet(skiatest::Reporter* reporter, TestDesc tests[], size_t count,
+ void (*firstTest)(skiatest::Reporter* ),
+ void (*stopTest)(skiatest::Reporter* ), bool reverse);
+
+#endif
diff --git a/tests/PathOpsOpCubicThreadedTest.cpp b/tests/PathOpsOpCubicThreadedTest.cpp
new file mode 100644
index 0000000000..80527f9e5e
--- /dev/null
+++ b/tests/PathOpsOpCubicThreadedTest.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "PathOpsExtendedTest.h"
+
+static THREAD_TYPE testOpCubicsMain(void* data)
+{
+ SkASSERT(data);
+ State4& state = *(State4*) data;
+ char pathStr[1024]; // gdb: set print elements 400
+ sk_bzero(pathStr, sizeof(pathStr));
+ do {
+ for (int a = 0 ; a < 6; ++a) {
+ for (int b = a + 1 ; b < 7; ++b) {
+ for (int c = 0 ; c < 6; ++c) {
+ for (int d = c + 1 ; d < 7; ++d) {
+ for (int e = SkPath::kWinding_FillType ; e <= SkPath::kEvenOdd_FillType; ++e) {
+ for (int f = SkPath::kWinding_FillType ; f <= SkPath::kEvenOdd_FillType; ++f) {
+ SkPath pathA, pathB;
+ char* str = pathStr;
+ pathA.setFillType((SkPath::FillType) e);
+ str += sprintf(str, " path.setFillType(SkPath::k%s_FillType);\n",
+ e == SkPath::kWinding_FillType ? "Winding" : e == SkPath::kEvenOdd_FillType
+ ? "EvenOdd" : "?UNDEFINED");
+ pathA.moveTo(SkIntToScalar(state.a), SkIntToScalar(state.b));
+ str += sprintf(str, " path.moveTo(%d,%d);\n", state.a, state.b);
+ pathA.cubicTo(SkIntToScalar(state.c), SkIntToScalar(state.d), SkIntToScalar(b),
+ SkIntToScalar(a), SkIntToScalar(d), SkIntToScalar(c));
+ str += sprintf(str, " path.cubicTo(%d,%d, %d,%d, %d,%d);\n", state.c, state.d,
+ b, a, d, c);
+ pathA.close();
+ str += sprintf(str, " path.close();\n");
+ pathB.setFillType((SkPath::FillType) f);
+ str += sprintf(str, " pathB.setFillType(SkPath::k%s_FillType);\n",
+ f == SkPath::kWinding_FillType ? "Winding" : f == SkPath::kEvenOdd_FillType
+ ? "EvenOdd" : "?UNDEFINED");
+ pathB.moveTo(SkIntToScalar(a), SkIntToScalar(b));
+ str += sprintf(str, " pathB.moveTo(%d,%d);\n", a, b);
+ pathB.cubicTo(SkIntToScalar(c), SkIntToScalar(d), SkIntToScalar(state.b),
+ SkIntToScalar(state.a), SkIntToScalar(state.d), SkIntToScalar(state.c));
+ str += sprintf(str, " pathB.cubicTo(%d,%d, %d,%d, %d,%d);\n", c, d,
+ state.b, state.a, state.d, state.c);
+ pathB.close();
+ str += sprintf(str, " pathB.close();\n");
+ for (int op = 0 ; op <= kXOR_PathOp; ++op) {
+ outputProgress(state, pathStr, (SkPathOp) op);
+ testPathOp(state.reporter, pathA, pathB, (SkPathOp) op);
+ state.testsRun++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } while (runNextTestSet(state));
+ THREAD_RETURN
+}
+
+static void TestOpCubicsThreaded(skiatest::Reporter* reporter)
+{
+ int testsRun = 0;
+ if (gShowTestProgress) SkDebugf("%s\n", __FUNCTION__);
+#ifdef SK_DEBUG
+ gDebugMaxWindSum = 4;
+ gDebugMaxWindValue = 4;
+#endif
+ const char testLineStr[] = "cubicOp";
+ initializeTests(reporter, testLineStr, sizeof(testLineStr));
+ for (int a = 0; a < 6; ++a) { // outermost
+ for (int b = a + 1; b < 7; ++b) {
+ for (int c = 0 ; c < 6; ++c) {
+ for (int d = c + 1; d < 7; ++d) {
+ testsRun += dispatchTest4(testOpCubicsMain, a, b, c, d);
+ }
+ if (gShowTestProgress) SkDebugf(".");
+ }
+ if (!gAllowExtendedTest) goto finish;
+ if (gShowTestProgress) SkDebugf("%d", b);
+ }
+ if (gShowTestProgress) SkDebugf("\n%d", a);
+ }
+finish:
+ testsRun += waitForCompletion();
+ if (gShowTestProgress) SkDebugf("%s tests=%d\n", __FUNCTION__, testsRun);
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("PathOpsOpCubicsThreaded", OpCubicsThreadedTestClass, \
+ TestOpCubicsThreaded)
diff --git a/tests/PathOpsOpRectThreadedTest.cpp b/tests/PathOpsOpRectThreadedTest.cpp
new file mode 100644
index 0000000000..a181485df2
--- /dev/null
+++ b/tests/PathOpsOpRectThreadedTest.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "PathOpsExtendedTest.h"
+
+// four rects, of four sizes
+// for 3 smaller sizes, tall, wide
+ // top upper mid lower bottom aligned (3 bits, 5 values)
+ // same with x (3 bits, 5 values)
+// not included, square, tall, wide (2 bits)
+// cw or ccw (1 bit)
+
+static THREAD_TYPE testPathOpsRectsMain(void* data)
+{
+ SkASSERT(data);
+ State4& state = *(State4*) data;
+ char pathStr[1024]; // gdb: set print elements 400
+ sk_bzero(pathStr, sizeof(pathStr));
+ do {
+ for (int a = 0 ; a < 6; ++a) {
+ for (int b = a + 1 ; b < 7; ++b) {
+ for (int c = 0 ; c < 6; ++c) {
+ for (int d = c + 1 ; d < 7; ++d) {
+ for (int e = SkPath::kWinding_FillType ; e <= SkPath::kEvenOdd_FillType; ++e) {
+ for (int f = SkPath::kWinding_FillType ; f <= SkPath::kEvenOdd_FillType; ++f) {
+ SkPath pathA, pathB;
+ char* str = pathStr;
+ pathA.setFillType((SkPath::FillType) e);
+ str += sprintf(str, " path.setFillType(SkPath::k%s_FillType);\n",
+ e == SkPath::kWinding_FillType ? "Winding" : e == SkPath::kEvenOdd_FillType
+ ? "EvenOdd" : "?UNDEFINED");
+ pathA.addRect(SkIntToScalar(state.a), SkIntToScalar(state.a), SkIntToScalar(state.b),
+ SkIntToScalar(state.b), SkPath::kCW_Direction);
+ str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
+ " SkPath::kCW_Direction);\n", state.a, state.a, state.b, state.b);
+ pathA.addRect(SkIntToScalar(state.c), SkIntToScalar(state.c), SkIntToScalar(state.d),
+ SkIntToScalar(state.d), SkPath::kCW_Direction);
+ str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
+ " SkPath::kCW_Direction);\n", state.c, state.c, state.d, state.d);
+ pathA.close();
+ pathB.setFillType((SkPath::FillType) f);
+ str += sprintf(str, " pathB.setFillType(SkPath::k%s_FillType);\n",
+ f == SkPath::kWinding_FillType ? "Winding" : f == SkPath::kEvenOdd_FillType
+ ? "EvenOdd" : "?UNDEFINED");
+ pathB.addRect(SkIntToScalar(a), SkIntToScalar(a), SkIntToScalar(b),
+ SkIntToScalar(b), SkPath::kCW_Direction);
+ str += sprintf(str, " pathB.addRect(%d, %d, %d, %d,"
+ " SkPath::kCW_Direction);\n", a, a, b, b);
+ pathB.addRect(SkIntToScalar(c), SkIntToScalar(c), SkIntToScalar(d),
+ SkIntToScalar(d), SkPath::kCW_Direction);
+ str += sprintf(str, " pathB.addRect(%d, %d, %d, %d,"
+ " SkPath::kCW_Direction);\n", c, c, d, d);
+ pathB.close();
+ for (int op = 0 ; op <= kXOR_PathOp; ++op) {
+ outputProgress(state, pathStr, (SkPathOp) op);
+ testPathOp(state.reporter, pathA, pathB, (SkPathOp) op);
+ state.testsRun++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } while (runNextTestSet(state));
+ THREAD_RETURN
+}
+
+static void TestPathOpsRectsThreaded(skiatest::Reporter* reporter) {
+ int testsRun = 0;
+ if (gShowTestProgress) SkDebugf("%s\n", __FUNCTION__);
+#ifdef SK_DEBUG
+ gDebugMaxWindSum = 4;
+ gDebugMaxWindValue = 4;
+#endif
+ const char testLineStr[] = "testOp";
+ initializeTests(reporter, testLineStr, sizeof(testLineStr));
+ for (int a = 0; a < 6; ++a) { // outermost
+ for (int b = a + 1; b < 7; ++b) {
+ for (int c = 0 ; c < 6; ++c) {
+ for (int d = c + 1; d < 7; ++d) {
+ testsRun += dispatchTest4(testPathOpsRectsMain, a, b, c, d);
+ }
+ if (gShowTestProgress) SkDebugf(".");
+ }
+ if (!gAllowExtendedTest) goto finish;
+ if (gShowTestProgress) SkDebugf("%d", b);
+ }
+ if (gShowTestProgress) SkDebugf("\n%d", a);
+ }
+finish:
+ testsRun += waitForCompletion();
+ if (gShowTestProgress) SkDebugf("%s tests=%d total=%d\n", __FUNCTION__, testsRun);
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("PathOpsRectsThreaded", OpRectsThreadedTestClass, \
+ TestPathOpsRectsThreaded)
+
diff --git a/tests/PathOpsOpTest.cpp b/tests/PathOpsOpTest.cpp
new file mode 100644
index 0000000000..97cd9e43fa
--- /dev/null
+++ b/tests/PathOpsOpTest.cpp
@@ -0,0 +1,1240 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "PathOpsExtendedTest.h"
+
+#define TEST(name) { name, #name }
+
+static void cubicOp1d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(0,2, 1,0, 1,0);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,1);
+ pathB.cubicTo(0,1, 1,0, 2,0);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp2d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,2);
+ path.cubicTo(0,1, 1,0, 1,0);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,1);
+ pathB.cubicTo(0,1, 2,0, 1,0);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp3d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(2,3, 1,0, 1,0);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,1);
+ pathB.cubicTo(0,1, 1,0, 3,2);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp5d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(0,2, 1,0, 2,0);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,1);
+ pathB.cubicTo(0,2, 1,0, 2,0);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp6d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(0,6, 1,0, 3,0);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,1);
+ pathB.cubicTo(0,3, 1,0, 6,0);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp7d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(3,4, 1,0, 3,0);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,1);
+ pathB.cubicTo(0,3, 1,0, 4,3);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp8d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(0,5, 1,0, 4,0);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,1);
+ pathB.cubicTo(0,4, 1,0, 5,0);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp9d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(1,6, 1,0, 2,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,1);
+ pathB.cubicTo(1,2, 1,0, 6,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void quadOp9d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.quadTo(1,6, 1.5f,1);
+ path.quadTo(1.5f,0.5f, 2,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,1);
+ pathB.quadTo(1,2, 1.4f,1);
+ pathB.quadTo(3,0.4f, 6,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void lineOp9d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.lineTo(1,6);
+ path.lineTo(1.5f,1);
+ path.lineTo(1.8f,0.8f);
+ path.lineTo(2,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,1);
+ pathB.lineTo(1,2);
+ pathB.lineTo(1.4f,1);
+ pathB.lineTo(3,0.4f);
+ pathB.lineTo(6,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp1i(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(1,2, 1,0, 2,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,1);
+ pathB.cubicTo(1,2, 1,0, 2,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kIntersect_PathOp);
+}
+
+static void cubicOp10d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(1,3, 1,0, 4,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,1);
+ pathB.cubicTo(1,4, 1,0, 3,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp11d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(3,4, 1,0, 5,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,1);
+ pathB.cubicTo(1,5, 1,0, 4,3);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp12d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(1,6, 1,0, 1,0);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,1);
+ pathB.cubicTo(0,1, 1,0, 6,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp13d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(4,5, 1,0, 5,3);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,1);
+ pathB.cubicTo(3,5, 1,0, 5,4);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp14d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(0,2, 2,0, 2,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,2);
+ pathB.cubicTo(1,2, 1,0, 2,0);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp15d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(3,6, 2,0, 2,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,2);
+ pathB.cubicTo(1,2, 1,0, 6,3);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp16d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,2);
+ path.cubicTo(0,1, 3,0, 1,0);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,3);
+ pathB.cubicTo(0,1, 2,0, 1,0);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp17d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,2);
+ path.cubicTo(0,2, 4,0, 2,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,4);
+ pathB.cubicTo(1,2, 2,0, 2,0);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp18d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(3,5, 2,0, 2,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,2);
+ pathB.cubicTo(1,2, 1,0, 5,3);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp19i(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,2);
+ path.cubicTo(0,1, 2,1, 6,2);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(1,2);
+ pathB.cubicTo(2,6, 2,0, 1,0);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kIntersect_PathOp);
+}
+
+static void cubicOp20d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(0,1, 6,0, 2,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,6);
+ pathB.cubicTo(1,2, 1,0, 1,0);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp21d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(0,1, 2,1, 6,5);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(1,2);
+ pathB.cubicTo(5,6, 1,0, 1,0);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp22d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(2,3, 3,0, 2,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,3);
+ pathB.cubicTo(1,2, 1,0, 3,2);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp23d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(1,2, 4,0, 2,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,4);
+ pathB.cubicTo(1,2, 1,0, 2,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp24d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(1,2, 2,0, 3,2);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,2);
+ pathB.cubicTo(2,3, 1,0, 2,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void testIntersect1(skiatest::Reporter* reporter) {
+ SkPath one, two;
+ one.addRect(0, 0, 6, 6, SkPath::kCW_Direction);
+ two.addRect(3, 3, 9, 9, SkPath::kCW_Direction);
+ testPathOp(reporter, one, two, kIntersect_PathOp);
+}
+
+static void testUnion1(skiatest::Reporter* reporter) {
+ SkPath one, two;
+ one.addRect(0, 0, 6, 6, SkPath::kCW_Direction);
+ two.addRect(3, 3, 9, 9, SkPath::kCW_Direction);
+ testPathOp(reporter, one, two, kUnion_PathOp);
+}
+
+static void testDiff1(skiatest::Reporter* reporter) {
+ SkPath one, two;
+ one.addRect(0, 0, 6, 6, SkPath::kCW_Direction);
+ two.addRect(3, 3, 9, 9, SkPath::kCW_Direction);
+ testPathOp(reporter, one, two, kDifference_PathOp);
+}
+
+static void testXor1(skiatest::Reporter* reporter) {
+ SkPath one, two;
+ one.addRect(0, 0, 6, 6, SkPath::kCW_Direction);
+ two.addRect(3, 3, 9, 9, SkPath::kCW_Direction);
+ testPathOp(reporter, one, two, kXOR_PathOp);
+}
+
+static void testIntersect2(skiatest::Reporter* reporter) {
+ SkPath one, two;
+ one.addRect(0, 0, 6, 6, SkPath::kCW_Direction);
+ two.addRect(0, 3, 9, 9, SkPath::kCW_Direction);
+ testPathOp(reporter, one, two, kIntersect_PathOp);
+}
+
+static void testUnion2(skiatest::Reporter* reporter) {
+ SkPath one, two;
+ one.addRect(0, 0, 6, 6, SkPath::kCW_Direction);
+ two.addRect(0, 3, 9, 9, SkPath::kCW_Direction);
+ testPathOp(reporter, one, two, kUnion_PathOp);
+}
+
+static void testDiff2(skiatest::Reporter* reporter) {
+ SkPath one, two;
+ one.addRect(0, 0, 6, 6, SkPath::kCW_Direction);
+ two.addRect(0, 3, 9, 9, SkPath::kCW_Direction);
+ testPathOp(reporter, one, two, kDifference_PathOp);
+}
+
+static void testXor2(skiatest::Reporter* reporter) {
+ SkPath one, two;
+ one.addRect(0, 0, 6, 6, SkPath::kCW_Direction);
+ two.addRect(0, 3, 9, 9, SkPath::kCW_Direction);
+ testPathOp(reporter, one, two, kXOR_PathOp);
+}
+
+static void testOp1d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ path.addRect(0, 0, 2, 2, SkPath::kCW_Direction);
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ pathB.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void testOp2d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ path.addRect(0, 0, 2, 2, SkPath::kCW_Direction);
+ pathB.setFillType(SkPath::kEvenOdd_FillType);
+ pathB.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ pathB.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void testOp3d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ path.addRect(1, 1, 2, 2, SkPath::kCW_Direction);
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ pathB.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void testOp1u(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ path.addRect(0, 0, 3, 3, SkPath::kCW_Direction);
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ pathB.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ testPathOp(reporter, path, pathB, kUnion_PathOp);
+}
+
+static void testOp4d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ path.addRect(2, 2, 4, 4, SkPath::kCW_Direction);
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ pathB.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void testOp5d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 2, 2, SkPath::kCW_Direction);
+ path.addRect(0, 0, 3, 3, SkPath::kCW_Direction);
+ pathB.setFillType(SkPath::kEvenOdd_FillType);
+ pathB.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ pathB.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void testOp6d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ path.addRect(0, 0, 3, 3, SkPath::kCW_Direction);
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ pathB.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void testOp7d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 2, 2, SkPath::kCW_Direction);
+ path.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ pathB.setFillType(SkPath::kEvenOdd_FillType);
+ pathB.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ pathB.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void testOp2u(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 2, 2, SkPath::kCW_Direction);
+ path.addRect(0, 0, 2, 2, SkPath::kCW_Direction);
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.addRect(0, 0, 3, 3, SkPath::kCW_Direction);
+ pathB.addRect(1, 1, 2, 2, SkPath::kCW_Direction);
+ testPathOp(reporter, path, pathB, kUnion_PathOp);
+}
+
+static void testOp8d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.addRect(0, 0, 640, 480);
+ pathB.moveTo(577330, 1971.72f);
+ pathB.cubicTo(10.7082f, -116.596f, 262.057f, 45.6468f, 294.694f, 1.96237f);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+static void cubicOp25i(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(2,4, 5,0, 3,2);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,5);
+ pathB.cubicTo(2,3, 1,0, 4,2);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kIntersect_PathOp);
+}
+
+static void cubicOp26d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(3,4, 4,0, 3,2);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,4);
+ pathB.cubicTo(2,3, 1,0, 4,3);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp27d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(3,6, 1,0, 5,2);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,1);
+ pathB.cubicTo(2,5, 1,0, 6,3);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp28u(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(1,4, 6,0, 3,2);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,6);
+ pathB.cubicTo(2,3, 1,0, 4,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kUnion_PathOp);
+}
+
+static void cubicOp29d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(2,5, 6,0, 4,2);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,6);
+ pathB.cubicTo(2,4, 1,0, 5,2);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp30d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(2,5, 6,0, 5,3);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,6);
+ pathB.cubicTo(3,5, 1,0, 5,2);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp31d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,2);
+ path.cubicTo(0,3, 2,1, 4,0);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(1,2);
+ pathB.cubicTo(0,4, 2,0, 3,0);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp31u(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,2);
+ path.cubicTo(0,3, 2,1, 4,0);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(1,2);
+ pathB.cubicTo(0,4, 2,0, 3,0);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kUnion_PathOp);
+}
+
+static void cubicOp31x(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,2);
+ path.cubicTo(0,3, 2,1, 4,0);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(1,2);
+ pathB.cubicTo(0,4, 2,0, 3,0);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kXOR_PathOp);
+}
+
+static void cubicOp32d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(1,2, 6,0, 3,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,6);
+ pathB.cubicTo(1,3, 1,0, 2,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp33i(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(1,2, 6,0, 3,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,6);
+ pathB.cubicTo(1,3, 1,0, 2,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kIntersect_PathOp);
+}
+
+static void cubicOp34d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(3,5, 2,1, 3,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(1,2);
+ pathB.cubicTo(1,3, 1,0, 5,3);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp35d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(1,5, 2,1, 4,0);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(1,2);
+ pathB.cubicTo(0,4, 1,0, 5,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp36u(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(1,6, 2,0, 5,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,2);
+ pathB.cubicTo(1,5, 1,0, 6,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kUnion_PathOp);
+}
+
+static void cubicOp37d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(2,6, 6,1, 4,3);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(1,6);
+ pathB.cubicTo(3,4, 1,0, 6,2);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+#if 1
+// this fails to detect a cubic/cubic intersection
+// the slight overlap is missed when the cubics are approximated by quadratics
+// and the subsequent line/cubic intersection also (correctly) misses the intersection
+// if the line/cubic was a matching line/approx.quadratic then the missing intersection
+// could have been detected
+static void cubicOp38d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(0,6, 3,2, 4,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(2,3);
+ pathB.cubicTo(1,4, 1,0, 6,0);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+#endif
+
+static void cubicOp39d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(2,3, 5,1, 4,3);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(1,5);
+ pathB.cubicTo(3,4, 1,0, 3,2);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp40d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(1,5, 3,2, 4,2);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(2,3);
+ pathB.cubicTo(2,4, 1,0, 5,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp41i(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(2,6, 4,3, 6,4);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(3,4);
+ pathB.cubicTo(4,6, 1,0, 6,2);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kIntersect_PathOp);
+}
+
+static void cubicOp42d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(1,2, 6,5, 5,4);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(5,6);
+ pathB.cubicTo(4,5, 1,0, 2,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp43d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,2);
+ path.cubicTo(1,2, 4,0, 3,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,4);
+ pathB.cubicTo(1,3, 2,0, 2,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp44d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,2);
+ path.cubicTo(3,6, 4,0, 3,2);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,4);
+ pathB.cubicTo(2,3, 2,0, 6,3);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp45d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,2);
+ path.cubicTo(2,4, 4,0, 3,2);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,4);
+ pathB.cubicTo(2,3, 2,0, 4,2);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp46d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,2);
+ path.cubicTo(3,5, 5,0, 4,2);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,5);
+ pathB.cubicTo(2,4, 2,0, 5,3);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp47d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(1,6, 6,2, 5,4);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(2,6);
+ pathB.cubicTo(4,5, 1,0, 6,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp48d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,2);
+ path.cubicTo(2,3, 5,1, 3,2);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(1,5);
+ pathB.cubicTo(2,3, 2,0, 3,2);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp49d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,2);
+ path.cubicTo(1,5, 3,2, 4,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(2,3);
+ pathB.cubicTo(1,4, 2,0, 5,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp50d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,3);
+ path.cubicTo(1,6, 5,0, 5,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,5);
+ pathB.cubicTo(1,5, 3,0, 6,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp51d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,3);
+ path.cubicTo(1,2, 4,1, 6,0);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(1,4);
+ pathB.cubicTo(0,6, 3,0, 2,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp52d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,2);
+ path.cubicTo(1,2, 5,4, 4,3);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(4,5);
+ pathB.cubicTo(3,4, 2,0, 2,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp53d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,3);
+ path.cubicTo(1,2, 5,3, 2,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(3,5);
+ pathB.cubicTo(1,2, 3,0, 2,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp54d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,4);
+ path.cubicTo(1,3, 5,4, 4,2);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(4,5);
+ pathB.cubicTo(2,4, 4,0, 3,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp55d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,5);
+ path.cubicTo(1,3, 3,2, 5,0);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(2,3);
+ pathB.cubicTo(0,5, 5,0, 3,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp56d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(2,6, 5,0, 2,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,5);
+ pathB.cubicTo(1,2, 1,0, 6,2);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp57d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,5);
+ path.cubicTo(0,5, 5,4, 6,4);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(4,5);
+ pathB.cubicTo(4,6, 5,0, 5,0);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp58d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,5);
+ path.cubicTo(3,4, 6,5, 5,3);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(5,6);
+ pathB.cubicTo(3,5, 5,0, 4,3);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp59d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,1);
+ path.cubicTo(5,6, 4,0, 4,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,4);
+ pathB.cubicTo(1,4, 1,0, 6,5);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp60d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0,2);
+ path.cubicTo(4,6, 6,0, 5,2);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(0,6);
+ pathB.cubicTo(2,5, 2,0, 6,4);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp61d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(1,2);
+ path.cubicTo(0,5, 3,2, 6,1);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(2,3);
+ pathB.cubicTo(1,6, 2,1, 5,0);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp62d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(1,3);
+ path.cubicTo(5,6, 5,3, 5,4);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(3,5);
+ pathB.cubicTo(4,5, 3,1, 6,5);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp63d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(2,3);
+ path.cubicTo(0,4, 3,2, 5,3);
+ path.close();
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(2,3);
+ pathB.cubicTo(3,5, 3,2, 4,0);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp64d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.moveTo(0,1);
+ path.cubicTo(0,1, 1,0, 3,0);
+ path.lineTo(0,1);
+ path.close();
+ pathB.moveTo(0,1);
+ pathB.cubicTo(0,3, 1,0, 1,0);
+ pathB.lineTo(0,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void cubicOp65d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.moveTo(0,1);
+ path.cubicTo(1,5, 1,0, 1,0);
+ path.lineTo(0,1);
+ path.close();
+ pathB.moveTo(0,1);
+ pathB.cubicTo(0,1, 1,0, 5,1);
+ pathB.lineTo(0,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void rectOp1d(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.moveTo(0,1);
+ path.cubicTo(0,1, 1,0, 3,0);
+ path.lineTo(0,1);
+ path.close();
+ pathB.moveTo(0,1);
+ pathB.cubicTo(0,3, 1,0, 1,0);
+ pathB.lineTo(0,1);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kDifference_PathOp);
+}
+
+static void (*firstTest)(skiatest::Reporter* ) = rectOp1d;
+
+static struct TestDesc tests[] = {
+ TEST(rectOp1d),
+ TEST(cubicOp65d),
+ TEST(cubicOp64d),
+ TEST(cubicOp63d),
+ TEST(cubicOp62d),
+ TEST(cubicOp61d),
+ TEST(cubicOp60d),
+ TEST(cubicOp59d),
+ TEST(cubicOp58d),
+ TEST(cubicOp57d),
+ TEST(cubicOp56d),
+ TEST(cubicOp55d),
+ TEST(cubicOp54d),
+ TEST(cubicOp53d),
+ TEST(cubicOp52d),
+ TEST(cubicOp51d),
+ TEST(cubicOp50d),
+ TEST(cubicOp49d),
+ TEST(cubicOp48d),
+ TEST(cubicOp47d),
+ TEST(cubicOp46d),
+ TEST(cubicOp45d),
+ TEST(cubicOp44d),
+ TEST(cubicOp43d),
+ TEST(cubicOp42d),
+ TEST(cubicOp41i),
+ TEST(cubicOp40d),
+ TEST(cubicOp39d),
+ TEST(cubicOp38d),
+ TEST(cubicOp37d),
+ TEST(cubicOp36u),
+ TEST(cubicOp35d),
+ TEST(cubicOp34d),
+ TEST(cubicOp33i),
+ TEST(cubicOp32d),
+ TEST(cubicOp31d),
+ TEST(cubicOp31x),
+ TEST(cubicOp31u),
+ TEST(cubicOp30d),
+ TEST(cubicOp29d),
+ TEST(cubicOp28u),
+ TEST(cubicOp27d),
+ TEST(cubicOp26d),
+ TEST(cubicOp25i),
+ TEST(testOp8d),
+ TEST(testDiff1),
+ TEST(testIntersect1),
+ TEST(testUnion1),
+ TEST(testXor1),
+ TEST(testDiff2),
+ TEST(testIntersect2),
+ TEST(testUnion2),
+ TEST(testXor2),
+ TEST(testOp1d),
+ TEST(testOp2d),
+ TEST(testOp3d),
+ TEST(testOp1u),
+ TEST(testOp4d),
+ TEST(testOp5d),
+ TEST(testOp6d),
+ TEST(testOp7d),
+ TEST(testOp2u),
+
+ TEST(cubicOp24d),
+ TEST(cubicOp23d),
+ TEST(cubicOp22d),
+ TEST(cubicOp21d),
+ TEST(cubicOp20d),
+ TEST(cubicOp19i),
+ TEST(cubicOp18d),
+ TEST(cubicOp17d),
+ TEST(cubicOp16d),
+ TEST(cubicOp15d),
+ TEST(cubicOp14d),
+ TEST(cubicOp13d),
+ TEST(cubicOp12d),
+ TEST(cubicOp11d),
+ TEST(cubicOp10d),
+ TEST(cubicOp1i),
+ TEST(cubicOp9d),
+ TEST(quadOp9d),
+ TEST(lineOp9d),
+ TEST(cubicOp8d),
+ TEST(cubicOp7d),
+ TEST(cubicOp6d),
+ TEST(cubicOp5d),
+ TEST(cubicOp3d),
+ TEST(cubicOp2d),
+ TEST(cubicOp1d),
+};
+
+static const size_t testCount = sizeof(tests) / sizeof(tests[0]);
+
+static struct TestDesc subTests[] = {
+ TEST(cubicOp43d),
+ TEST(quadOp9d),
+ TEST(cubicOp9d),
+ TEST(cubicOp1i),
+ TEST(cubicOp10d),
+ TEST(cubicOp11d),
+ TEST(cubicOp15d),
+ TEST(cubicOp18d),
+ TEST(cubicOp22d),
+ TEST(cubicOp23d),
+ TEST(cubicOp24d),
+ TEST(cubicOp28u),
+ TEST(cubicOp33i),
+ TEST(cubicOp36u),
+ TEST(cubicOp40d),
+};
+
+static const size_t subTestCount = sizeof(subTests) / sizeof(subTests[0]);
+
+static void (*firstSubTest)(skiatest::Reporter* ) = 0;
+
+static bool runSubTestsFirst = false;
+static bool runReverse = false;
+static void (*stopTest)(skiatest::Reporter* ) = 0;
+
+static void OpTest(skiatest::Reporter* reporter) {
+#ifdef SK_DEBUG
+ gDebugMaxWindSum = 4;
+ gDebugMaxWindValue = 4;
+#endif
+ if (runSubTestsFirst) {
+ RunTestSet(reporter, subTests, subTestCount, firstSubTest, stopTest, runReverse);
+ }
+ RunTestSet(reporter, tests, testCount, firstTest, stopTest, runReverse);
+ if (!runSubTestsFirst) {
+ RunTestSet(reporter, subTests, subTestCount, firstSubTest, stopTest, runReverse);
+ }
+#ifdef SK_DEBUG
+ gDebugMaxWindSum = SK_MaxS32;
+ gDebugMaxWindValue = SK_MaxS32;
+#endif
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("PathOpsOpTest", PathOpsOpClass, OpTest)
diff --git a/tests/PathOpsQuadLineIntersectionThreadedTest.cpp b/tests/PathOpsQuadLineIntersectionThreadedTest.cpp
new file mode 100644
index 0000000000..e3db87cfb0
--- /dev/null
+++ b/tests/PathOpsQuadLineIntersectionThreadedTest.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "PathOpsExtendedTest.h"
+#include "SkIntersections.h"
+#include "SkPathOpsLine.h"
+#include "SkPathOpsQuad.h"
+#include "SkReduceOrder.h"
+
+static int doIntersect(SkIntersections& intersections, const SkDQuad& quad, const SkDLine& line,
+ bool& flipped) {
+ int result;
+ flipped = false;
+ if (line[0].fX == line[1].fX) {
+ double top = line[0].fY;
+ double bottom = line[1].fY;
+ flipped = top > bottom;
+ if (flipped) {
+ SkTSwap<double>(top, bottom);
+ }
+ result = intersections.vertical(quad, top, bottom, line[0].fX, flipped);
+ } else if (line[0].fY == line[1].fY) {
+ double left = line[0].fX;
+ double right = line[1].fX;
+ flipped = left > right;
+ if (flipped) {
+ SkTSwap<double>(left, right);
+ }
+ result = intersections.horizontal(quad, left, right, line[0].fY, flipped);
+ } else {
+ intersections.intersect(quad, line);
+ result = intersections.used();
+ }
+ return result;
+}
+
+static void testLineIntersect(skiatest::Reporter* reporter, const SkDQuad& quad,
+ const SkDLine& line, const double x, const double y) {
+ char pathStr[1024];
+ sk_bzero(pathStr, sizeof(pathStr));
+ char* str = pathStr;
+ str += sprintf(str, " path.moveTo(%1.9g, %1.9g);\n", quad[0].fX, quad[0].fY);
+ str += sprintf(str, " path.quadTo(%1.9g, %1.9g, %1.9g, %1.9g);\n", quad[1].fX, quad[1].fY, quad[2].fX, quad[2].fY);
+ str += sprintf(str, " path.moveTo(%1.9g, %1.9g);\n", line[0].fX, line[0].fY);
+ str += sprintf(str, " path.lineTo(%1.9g, %1.9g);\n", line[1].fX, line[1].fY);
+
+ SkIntersections intersections;
+ bool flipped = false;
+ int result = doIntersect(intersections, quad, line, flipped);
+ bool found = false;
+ for (int index = 0; index < result; ++index) {
+ double quadT = intersections[0][index];
+ SkDPoint quadXY = quad.xyAtT(quadT);
+ double lineT = intersections[1][index];
+ SkDPoint lineXY = line.xyAtT(lineT);
+ if (quadXY.approximatelyEqual(lineXY)) {
+ found = true;
+ }
+ }
+ REPORTER_ASSERT(reporter, found);
+}
+
+
+// find a point on a quad by choosing a t from 0 to 1
+// create a vertical span above and below the point
+// verify that intersecting the vertical span and the quad returns t
+// verify that a vertical span starting at quad[0] intersects at t=0
+// verify that a vertical span starting at quad[2] intersects at t=1
+static THREAD_TYPE testQuadLineIntersectMain(void* data)
+{
+ State4& state = *(State4*) data;
+ REPORTER_ASSERT(state.reporter, data);
+ do {
+ int ax = state.a & 0x03;
+ int ay = state.a >> 2;
+ int bx = state.b & 0x03;
+ int by = state.b >> 2;
+ int cx = state.c & 0x03;
+ int cy = state.c >> 2;
+ SkDQuad quad = {{{ax, ay}, {bx, by}, {cx, cy}}};
+ SkReduceOrder reducer;
+ int order = reducer.reduce(quad, SkReduceOrder::kFill_Style);
+ if (order < 3) {
+ continue; // skip degenerates
+ }
+ for (int tIndex = 0; tIndex <= 4; ++tIndex) {
+ SkDPoint xy = quad.xyAtT(tIndex / 4.0);
+ for (int h = -2; h <= 2; ++h) {
+ for (int v = -2; v <= 2; ++v) {
+ if (h == v && abs(h) != 1) {
+ continue;
+ }
+ double x = xy.fX;
+ double y = xy.fY;
+ SkDLine line = {{{x - h, y - v}, {x, y}}};
+ testLineIntersect(state.reporter, quad, line, x, y);
+ SkDLine line2 = {{{x, y}, {x + h, y + v}}};
+ testLineIntersect(state.reporter, quad, line2, x, y);
+ SkDLine line3 = {{{x - h, y - v}, {x + h, y + v}}};
+ testLineIntersect(state.reporter, quad, line3, x, y);
+ state.testsRun += 3;
+ }
+ }
+ }
+ } while (runNextTestSet(state));
+ THREAD_RETURN
+}
+
+static void TestQuadLineIntersectionThreaded(skiatest::Reporter* reporter)
+{
+ int testsRun = 0;
+ if (gShowTestProgress) SkDebugf("%s\n", __FUNCTION__);
+ const char testStr[] = "testQuadLineIntersect";
+ initializeTests(reporter, testStr, sizeof(testStr));
+ for (int a = 0; a < 16; ++a) {
+ for (int b = 0 ; b < 16; ++b) {
+ for (int c = 0 ; c < 16; ++c) {
+ testsRun += dispatchTest4(testQuadLineIntersectMain, a, b, c, 0);
+ }
+ if (!gAllowExtendedTest) goto finish;
+ if (gShowTestProgress) SkDebugf(".");
+ }
+ if (gShowTestProgress) SkDebugf("%d", a);
+ }
+finish:
+ testsRun += waitForCompletion();
+ if (gShowTestProgress) SkDebugf("\n%s tests=%d\n", __FUNCTION__, testsRun);
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("PathOpsQuadLineIntersectionThreaded", QuadLineIntersectionThreadedTestClass, \
+ TestQuadLineIntersectionThreaded)
diff --git a/tests/PathOpsSimplifyDegenerateThreadedTest.cpp b/tests/PathOpsSimplifyDegenerateThreadedTest.cpp
new file mode 100755
index 0000000000..41ddd9d7b6
--- /dev/null
+++ b/tests/PathOpsSimplifyDegenerateThreadedTest.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "PathOpsExtendedTest.h"
+
+static THREAD_TYPE testSimplifyDegeneratesMain(void* data) {
+ SkASSERT(data);
+ State4& state = *(State4*) data;
+ char pathStr[1024];
+ sk_bzero(pathStr, sizeof(pathStr));
+ do {
+ int ax = state.a & 0x03;
+ int ay = state.a >> 2;
+ int bx = state.b & 0x03;
+ int by = state.b >> 2;
+ int cx = state.c & 0x03;
+ int cy = state.c >> 2;
+ for (int d = 0; d < 16; ++d) {
+ int dx = d & 0x03;
+ int dy = d >> 2;
+ for (int e = d ; e < 16; ++e) {
+ int ex = e & 0x03;
+ int ey = e >> 2;
+ for (int f = d ; f < 16; ++f) {
+ int fx = f & 0x03;
+ int fy = f >> 2;
+ if (state.d && (ex - dx) * (fy - dy)
+ != (ey - dy) * (fx - dx)) {
+ continue;
+ }
+ SkPath path, out;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(SkIntToScalar(ax), SkIntToScalar(ay));
+ path.lineTo(SkIntToScalar(bx), SkIntToScalar(by));
+ path.lineTo(SkIntToScalar(cx), SkIntToScalar(cy));
+ path.close();
+ path.moveTo(SkIntToScalar(dx), SkIntToScalar(dy));
+ path.lineTo(SkIntToScalar(ex), SkIntToScalar(ey));
+ path.lineTo(SkIntToScalar(fx), SkIntToScalar(fy));
+ path.close();
+ if (1) {
+ char* str = pathStr;
+ str += sprintf(str, " path.moveTo(%d, %d);\n", ax, ay);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", bx, by);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", cx, cy);
+ str += sprintf(str, " path.close();\n");
+ str += sprintf(str, " path.moveTo(%d, %d);\n", dx, dy);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", ex, ey);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", fx, fy);
+ str += sprintf(str, " path.close();\n");
+ }
+ outputProgress(state, pathStr, SkPath::kWinding_FillType);
+ testSimplify(path, false, out, state, pathStr);
+ state.testsRun++;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ outputProgress(state, pathStr, SkPath::kEvenOdd_FillType);
+ testSimplify(path, true, out, state, pathStr);
+ state.testsRun++;
+ }
+ }
+ }
+ } while (runNextTestSet(state));
+ THREAD_RETURN
+}
+
+static void TestSimplifyDegeneratesThreaded(skiatest::Reporter* reporter) {
+ int testsRun = 0;
+ if (gShowTestProgress) SkDebugf("%s\n", __FUNCTION__);
+#ifdef SK_DEBUG
+ gDebugMaxWindSum = 2;
+ gDebugMaxWindValue = 2;
+#endif
+ const char testStr[] = "testDegenerates";
+ initializeTests(reporter, testStr, sizeof(testStr));
+ for (int a = 0; a < 16; ++a) {
+ int ax = a & 0x03;
+ int ay = a >> 2;
+ for (int b = a ; b < 16; ++b) {
+ int bx = b & 0x03;
+ int by = b >> 2;
+ for (int c = a ; c < 16; ++c) {
+ int cx = c & 0x03;
+ int cy = c >> 2;
+ bool abcIsATriangle = (bx - ax) * (cy - ay) != (by - ay) * (cx - ax);
+ testsRun += dispatchTest4(testSimplifyDegeneratesMain,
+ a, b, c, abcIsATriangle);
+ }
+ if (!gAllowExtendedTest) goto finish;
+ if (gShowTestProgress) SkDebugf(".");
+ }
+ if (gShowTestProgress) SkDebugf("\n%d", a);
+ }
+finish:
+ testsRun += waitForCompletion();
+ if (gShowTestProgress) SkDebugf("%s tests=%d\n", __FUNCTION__, testsRun);
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("PathOpsSimplifyDegeneratesThreaded", SimplifyDegeneratesThreadedTestClass, \
+ TestSimplifyDegeneratesThreaded)
diff --git a/tests/PathOpsSimplifyQuadThreadedTest.cpp b/tests/PathOpsSimplifyQuadThreadedTest.cpp
new file mode 100644
index 0000000000..96626a61ad
--- /dev/null
+++ b/tests/PathOpsSimplifyQuadThreadedTest.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "PathOpsExtendedTest.h"
+
+static THREAD_TYPE testSimplifyQuadsMain(void* data)
+{
+ SkASSERT(data);
+ State4& state = *(State4*) data;
+ char pathStr[1024];
+ sk_bzero(pathStr, sizeof(pathStr));
+ do {
+ int ax = state.a & 0x03;
+ int ay = state.a >> 2;
+ int bx = state.b & 0x03;
+ int by = state.b >> 2;
+ int cx = state.c & 0x03;
+ int cy = state.c >> 2;
+ int dx = state.d & 0x03;
+ int dy = state.d >> 2;
+ for (int e = 0 ; e < 16; ++e) {
+ int ex = e & 0x03;
+ int ey = e >> 2;
+ for (int f = e ; f < 16; ++f) {
+ int fx = f & 0x03;
+ int fy = f >> 2;
+ for (int g = f ; g < 16; ++g) {
+ int gx = g & 0x03;
+ int gy = g >> 2;
+ for (int h = g ; h < 16; ++h) {
+ int hx = h & 0x03;
+ int hy = h >> 2;
+ SkPath path, out;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(SkIntToScalar(ax), SkIntToScalar(ay));
+ path.quadTo(SkIntToScalar(bx), SkIntToScalar(by),
+ SkIntToScalar(cx), SkIntToScalar(cy));
+ path.lineTo(SkIntToScalar(dx), SkIntToScalar(dy));
+ path.close();
+ path.moveTo(SkIntToScalar(ex), SkIntToScalar(ey));
+ path.lineTo(SkIntToScalar(fx), SkIntToScalar(fy));
+ path.quadTo(SkIntToScalar(gx), SkIntToScalar(gy),
+ SkIntToScalar(hx), SkIntToScalar(hy));
+ path.close();
+ // gdb: set print elements 400
+ char* str = pathStr;
+ str += sprintf(str, " path.moveTo(%d, %d);\n", ax, ay);
+ str += sprintf(str, " path.quadTo(%d, %d, %d, %d);\n", bx, by, cx, cy);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", dx, dy);
+ str += sprintf(str, " path.close();\n");
+ str += sprintf(str, " path.moveTo(%d, %d);\n", ex, ey);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", fx, fy);
+ str += sprintf(str, " path.quadTo(%d, %d, %d, %d);\n", gx, gy, hx, hy);
+ str += sprintf(str, " path.close();\n");
+ outputProgress(state, pathStr, SkPath::kWinding_FillType);
+ testSimplify(path, false, out, state, pathStr);
+ state.testsRun++;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ outputProgress(state, pathStr, SkPath::kEvenOdd_FillType);
+ testSimplify(path, true, out, state, pathStr);
+ state.testsRun++;
+ }
+ }
+ }
+ }
+ } while (runNextTestSet(state));
+ THREAD_RETURN
+}
+
+static void TestSimplifyQuadsThreaded(skiatest::Reporter* reporter)
+{
+ int testsRun = 0;
+ if (gShowTestProgress) SkDebugf("%s\n", __FUNCTION__);
+#ifdef SK_DEBUG
+ gDebugMaxWindSum = 4; // FIXME: 3?
+ gDebugMaxWindValue = 4;
+#endif
+ const char testStr[] = "testQuads";
+ initializeTests(reporter, testStr, sizeof(testStr));
+ int a = 0;
+ for (; a < 16; ++a) {
+ for (int b = a ; b < 16; ++b) {
+ for (int c = b ; c < 16; ++c) {
+ for (int d = c; d < 16; ++d) {
+ testsRun += dispatchTest4(testSimplifyQuadsMain, a, b, c, d);
+ }
+ if (!gAllowExtendedTest) goto finish;
+ if (gShowTestProgress) SkDebugf(".");
+ }
+ if (gShowTestProgress) SkDebugf("%d", b);
+ }
+ if (gShowTestProgress) SkDebugf("\n%d", a);
+ }
+finish:
+ testsRun += waitForCompletion();
+ if (gShowTestProgress) SkDebugf("%s tests=%d\n", __FUNCTION__, testsRun);
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("PathOpsSimplifyQuadsThreaded", SimplifyQuadsThreadedTestClass, \
+ TestSimplifyQuadsThreaded)
diff --git a/tests/PathOpsSimplifyQuadralateralsThreadedTest.cpp b/tests/PathOpsSimplifyQuadralateralsThreadedTest.cpp
new file mode 100755
index 0000000000..ebe7e2300d
--- /dev/null
+++ b/tests/PathOpsSimplifyQuadralateralsThreadedTest.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "PathOpsExtendedTest.h"
+
+static THREAD_TYPE testSimplifyQuadralateralsMain(void* data)
+{
+ SkASSERT(data);
+ State4& state = *(State4*) data;
+ char pathStr[1024];
+ sk_bzero(pathStr, sizeof(pathStr));
+ do {
+ int ax = state.a & 0x03;
+ int ay = state.a >> 2;
+ int bx = state.b & 0x03;
+ int by = state.b >> 2;
+ int cx = state.c & 0x03;
+ int cy = state.c >> 2;
+ int dx = state.d & 0x03;
+ int dy = state.d >> 2;
+ for (int e = 0 ; e < 16; ++e) {
+ int ex = e & 0x03;
+ int ey = e >> 2;
+ for (int f = e ; f < 16; ++f) {
+ int fx = f & 0x03;
+ int fy = f >> 2;
+ for (int g = f ; g < 16; ++g) {
+ int gx = g & 0x03;
+ int gy = g >> 2;
+ for (int h = g ; h < 16; ++h) {
+ int hx = h & 0x03;
+ int hy = h >> 2;
+ SkPath path, out;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(SkIntToScalar(ax), SkIntToScalar(ay));
+ path.lineTo(SkIntToScalar(bx), SkIntToScalar(by));
+ path.lineTo(SkIntToScalar(cx), SkIntToScalar(cy));
+ path.lineTo(SkIntToScalar(dx), SkIntToScalar(dy));
+ path.close();
+ path.moveTo(SkIntToScalar(ex), SkIntToScalar(ey));
+ path.lineTo(SkIntToScalar(fx), SkIntToScalar(fy));
+ path.lineTo(SkIntToScalar(gx), SkIntToScalar(gy));
+ path.lineTo(SkIntToScalar(hx), SkIntToScalar(hy));
+ path.close();
+ if (1) { // gdb: set print elements 400
+ char* str = pathStr;
+ str += sprintf(str, " path.moveTo(%d, %d);\n", ax, ay);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", bx, by);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", cx, cy);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", dx, dy);
+ str += sprintf(str, " path.close();\n");
+ str += sprintf(str, " path.moveTo(%d, %d);\n", ex, ey);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", fx, fy);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", gx, gy);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", hx, hy);
+ str += sprintf(str, " path.close();\n");
+ }
+ outputProgress(state, pathStr, SkPath::kWinding_FillType);
+ testSimplify(path, false, out, state, pathStr);
+ state.testsRun++;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ outputProgress(state, pathStr, SkPath::kEvenOdd_FillType);
+ testSimplify(path, true, out, state, pathStr);
+ state.testsRun++;
+ }
+ }
+ }
+ }
+ } while (runNextTestSet(state));
+ THREAD_RETURN
+}
+
+static void TestSimplifyQuadralateralsThreaded(skiatest::Reporter* reporter)
+{
+ int testsRun = 0;
+ if (gShowTestProgress) SkDebugf("%s\n", __FUNCTION__);
+#ifdef SK_DEBUG
+ gDebugMaxWindSum = 4; // FIXME: 3?
+ gDebugMaxWindValue = 4;
+#endif
+ const char testStr[] = "testQuadralaterals";
+ initializeTests(reporter, testStr, sizeof(testStr));
+ for (int a = 0; a < 16; ++a) {
+ for (int b = a ; b < 16; ++b) {
+ for (int c = b ; c < 16; ++c) {
+ for (int d = c; d < 16; ++d) {
+ testsRun += dispatchTest4(testSimplifyQuadralateralsMain, a, b, c, d);
+ }
+ if (!gAllowExtendedTest) goto finish;
+ if (gShowTestProgress) SkDebugf(".");
+ }
+ if (gShowTestProgress) SkDebugf("%d", b);
+ }
+ if (gShowTestProgress) SkDebugf("\n%d", a);
+ }
+finish:
+ testsRun += waitForCompletion();
+ if (gShowTestProgress) SkDebugf("%s tests=%d\n", __FUNCTION__, testsRun);
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("SimplifyQuadralateralsThreaded", SimplifyQuadralateralsThreadedTestClass, \
+ TestSimplifyQuadralateralsThreaded)
diff --git a/tests/PathOpsSimplifyRectThreadedTest.cpp b/tests/PathOpsSimplifyRectThreadedTest.cpp
new file mode 100644
index 0000000000..13f327a06f
--- /dev/null
+++ b/tests/PathOpsSimplifyRectThreadedTest.cpp
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "PathOpsExtendedTest.h"
+
+// four rects, of four sizes
+// for 3 smaller sizes, tall, wide
+ // top upper mid lower bottom aligned (3 bits, 5 values)
+ // same with x (3 bits, 5 values)
+// not included, square, tall, wide (2 bits)
+// cw or ccw (1 bit)
+
+static THREAD_TYPE testSimplify4x4RectsMain(void* data)
+{
+ SkASSERT(data);
+ State4& state = *(State4*) data;
+ char pathStr[1024]; // gdb: set print elements 400
+ sk_bzero(pathStr, sizeof(pathStr));
+ do {
+ int aShape = state.a & 0x03;
+ SkPath::Direction aCW = state.a >> 2 ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
+ int bShape = state.b & 0x03;
+ SkPath::Direction bCW = state.b >> 2 ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
+ int cShape = state.c & 0x03;
+ SkPath::Direction cCW = state.c >> 2 ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
+ int dShape = state.d & 0x03;
+ SkPath::Direction dCW = state.d >> 2 ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
+ for (int aXAlign = 0 ; aXAlign < 5; ++aXAlign) {
+ for (int aYAlign = 0 ; aYAlign < 5; ++aYAlign) {
+ for (int bXAlign = 0 ; bXAlign < 5; ++bXAlign) {
+ for (int bYAlign = 0 ; bYAlign < 5; ++bYAlign) {
+ for (int cXAlign = 0 ; cXAlign < 5; ++cXAlign) {
+ for (int cYAlign = 0 ; cYAlign < 5; ++cYAlign) {
+ for (int dXAlign = 0 ; dXAlign < 5; ++dXAlign) {
+ for (int dYAlign = 0 ; dYAlign < 5; ++dYAlign) {
+ SkPath path, out;
+ char* str = pathStr;
+ path.setFillType(SkPath::kWinding_FillType);
+ int l, t, r, b;
+ if (aShape) {
+ switch (aShape) {
+ case 1: // square
+ l = 0; r = 60;
+ t = 0; b = 60;
+ aXAlign = 5;
+ aYAlign = 5;
+ break;
+ case 2:
+ l = aXAlign * 12;
+ r = l + 30;
+ t = 0; b = 60;
+ aYAlign = 5;
+ break;
+ case 3:
+ l = 0; r = 60;
+ t = aYAlign * 12;
+ b = l + 30;
+ aXAlign = 5;
+ break;
+ }
+ path.addRect(SkIntToScalar(l), SkIntToScalar(t), SkIntToScalar(r), SkIntToScalar(b),
+ aCW);
+ str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
+ " SkPath::kC%sW_Direction);\n", l, t, r, b, aCW ? "C" : "");
+ } else {
+ aXAlign = 5;
+ aYAlign = 5;
+ }
+ if (bShape) {
+ switch (bShape) {
+ case 1: // square
+ l = bXAlign * 10;
+ r = l + 20;
+ t = bYAlign * 10;
+ b = l + 20;
+ break;
+ case 2:
+ l = bXAlign * 10;
+ r = l + 20;
+ t = 10; b = 40;
+ bYAlign = 5;
+ break;
+ case 3:
+ l = 10; r = 40;
+ t = bYAlign * 10;
+ b = l + 20;
+ bXAlign = 5;
+ break;
+ }
+ path.addRect(SkIntToScalar(l), SkIntToScalar(t), SkIntToScalar(r), SkIntToScalar(b),
+ bCW);
+ str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
+ " SkPath::kC%sW_Direction);\n", l, t, r, b, bCW ? "C" : "");
+ } else {
+ bXAlign = 5;
+ bYAlign = 5;
+ }
+ if (cShape) {
+ switch (cShape) {
+ case 1: // square
+ l = cXAlign * 6;
+ r = l + 12;
+ t = cYAlign * 6;
+ b = l + 12;
+ break;
+ case 2:
+ l = cXAlign * 6;
+ r = l + 12;
+ t = 20; b = 30;
+ cYAlign = 5;
+ break;
+ case 3:
+ l = 20; r = 30;
+ t = cYAlign * 6;
+ b = l + 20;
+ cXAlign = 5;
+ break;
+ }
+ path.addRect(SkIntToScalar(l), SkIntToScalar(t), SkIntToScalar(r), SkIntToScalar(b),
+ cCW);
+ str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
+ " SkPath::kC%sW_Direction);\n", l, t, r, b, cCW ? "C" : "");
+ } else {
+ cXAlign = 5;
+ cYAlign = 5;
+ }
+ if (dShape) {
+ switch (dShape) {
+ case 1: // square
+ l = dXAlign * 4;
+ r = l + 9;
+ t = dYAlign * 4;
+ b = l + 9;
+ break;
+ case 2:
+ l = dXAlign * 6;
+ r = l + 9;
+ t = 32; b = 36;
+ dYAlign = 5;
+ break;
+ case 3:
+ l = 32; r = 36;
+ t = dYAlign * 6;
+ b = l + 9;
+ dXAlign = 5;
+ break;
+ }
+ path.addRect(SkIntToScalar(l), SkIntToScalar(t), SkIntToScalar(r), SkIntToScalar(b),
+ dCW);
+ str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
+ " SkPath::kC%sW_Direction);\n", l, t, r, b, dCW ? "C" : "");
+ } else {
+ dXAlign = 5;
+ dYAlign = 5;
+ }
+ path.close();
+ outputProgress(state, pathStr, SkPath::kWinding_FillType);
+ testSimplify(path, false, out, state, pathStr);
+ state.testsRun++;
+ outputProgress(state, pathStr, SkPath::kEvenOdd_FillType);
+ testSimplify(path, true, out, state, pathStr);
+ state.testsRun++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } while (runNextTestSet(state));
+ THREAD_RETURN
+}
+
+static void TestSimplifyRectsThreaded(skiatest::Reporter* reporter)
+{
+ int testsRun = 0;
+ if (gShowTestProgress) SkDebugf("%s\n", __FUNCTION__);
+#ifdef SK_DEBUG
+ gDebugMaxWindSum = 4;
+ gDebugMaxWindValue = 4;
+#endif
+ const char testLineStr[] = "testLine";
+ initializeTests(reporter, testLineStr, sizeof(testLineStr));
+ for (int a = 0; a < 8; ++a) { // outermost
+ for (int b = a ; b < 8; ++b) {
+ for (int c = b ; c < 8; ++c) {
+ for (int d = c; d < 8; ++d) {
+ testsRun += dispatchTest4(testSimplify4x4RectsMain, a, b, c, d);
+ }
+ if (!gAllowExtendedTest) goto finish;
+ if (gShowTestProgress) SkDebugf(".");
+ }
+ if (gShowTestProgress) SkDebugf("%d", b);
+ }
+ if (gShowTestProgress) SkDebugf("\n%d", a);
+ }
+finish:
+ testsRun += waitForCompletion();
+ if (gShowTestProgress) SkDebugf("%s tests=%d\n", __FUNCTION__, testsRun);
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("PathOpsSimplifyRectsThreaded",SimplifyRectsThreadedTestClass, \
+ TestSimplifyRectsThreaded)
diff --git a/tests/PathOpsSimplifyTest.cpp b/tests/PathOpsSimplifyTest.cpp
new file mode 100644
index 0000000000..c8537dc97c
--- /dev/null
+++ b/tests/PathOpsSimplifyTest.cpp
@@ -0,0 +1,3943 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "PathOpsExtendedTest.h"
+
+#define TEST(name) { name, #name }
+
+static void testLine1(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(2,0);
+ path.lineTo(1,1);
+ path.lineTo(0,0);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine1x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(2,0);
+ path.lineTo(1,1);
+ path.lineTo(0,0);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void addInnerCWTriangle(SkPath& path) {
+ path.moveTo(3,0);
+ path.lineTo(4,1);
+ path.lineTo(2,1);
+ path.close();
+}
+
+static void addInnerCCWTriangle(SkPath& path) {
+ path.moveTo(3,0);
+ path.lineTo(2,1);
+ path.lineTo(4,1);
+ path.close();
+}
+
+static void addOuterCWTriangle(SkPath& path) {
+ path.moveTo(3,0);
+ path.lineTo(6,2);
+ path.lineTo(0,2);
+ path.close();
+}
+
+static void addOuterCCWTriangle(SkPath& path) {
+ path.moveTo(3,0);
+ path.lineTo(0,2);
+ path.lineTo(6,2);
+ path.close();
+}
+
+static void testLine2(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ addInnerCWTriangle(path);
+ addOuterCWTriangle(path);
+ testSimplify(reporter, path);
+}
+
+static void testLine2x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ addInnerCWTriangle(path);
+ addOuterCWTriangle(path);
+ testSimplify(reporter, path);
+}
+
+static void testLine3(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ addInnerCCWTriangle(path);
+ addOuterCWTriangle(path);
+ testSimplify(reporter, path);
+}
+
+static void testLine3x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ addInnerCCWTriangle(path);
+ addOuterCWTriangle(path);
+ testSimplify(reporter, path);
+}
+
+static void testLine3a(skiatest::Reporter* reporter) {
+ SkPath path;
+ addInnerCWTriangle(path);
+ addOuterCCWTriangle(path);
+ testSimplify(reporter, path);
+}
+
+static void testLine3ax(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ addInnerCWTriangle(path);
+ addOuterCCWTriangle(path);
+ testSimplify(reporter, path);
+}
+
+static void testLine3b(skiatest::Reporter* reporter) {
+ SkPath path;
+ addInnerCCWTriangle(path);
+ addOuterCCWTriangle(path);
+ testSimplify(reporter, path);
+}
+
+static void testLine3bx(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ addInnerCCWTriangle(path);
+ addOuterCCWTriangle(path);
+ testSimplify(reporter, path);
+}
+
+static void testLine4(skiatest::Reporter* reporter) {
+ SkPath path;
+ addOuterCCWTriangle(path);
+ addOuterCWTriangle(path);
+ testSimplify(reporter, path);
+}
+
+static void testLine4x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ addOuterCCWTriangle(path);
+ addOuterCWTriangle(path);
+ testSimplify(reporter, path);
+}
+
+static void testLine5(skiatest::Reporter* reporter) {
+ SkPath path;
+ addOuterCWTriangle(path);
+ addOuterCWTriangle(path);
+ testSimplify(reporter, path);
+}
+
+static void testLine5x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ addOuterCWTriangle(path);
+ addOuterCWTriangle(path);
+ testSimplify(reporter, path);
+}
+
+static void testLine6(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0,0);
+ path.lineTo(4,0);
+ path.lineTo(2,2);
+ path.close();
+ path.moveTo(2,0);
+ path.lineTo(6,0);
+ path.lineTo(4,2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine6x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0,0);
+ path.lineTo(4,0);
+ path.lineTo(2,2);
+ path.close();
+ path.moveTo(2,0);
+ path.lineTo(6,0);
+ path.lineTo(4,2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine7(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0,0);
+ path.lineTo(4,0);
+ path.lineTo(2,2);
+ path.close();
+ path.moveTo(6,0);
+ path.lineTo(2,0);
+ path.lineTo(4,2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine7x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0,0);
+ path.lineTo(4,0);
+ path.lineTo(2,2);
+ path.close();
+ path.moveTo(6,0);
+ path.lineTo(2,0);
+ path.lineTo(4,2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine7a(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0,0);
+ path.lineTo(4,0);
+ path.lineTo(2,2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine7ax(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0,0);
+ path.lineTo(4,0);
+ path.lineTo(2,2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine7b(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0,0);
+ path.lineTo(4,0);
+ path.close();
+ path.moveTo(6,0);
+ path.lineTo(2,0);
+ path.lineTo(4,2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine7bx(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0,0);
+ path.lineTo(4,0);
+ path.close();
+ path.moveTo(6,0);
+ path.lineTo(2,0);
+ path.lineTo(4,2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine8(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0,4);
+ path.lineTo(4,4);
+ path.lineTo(2,2);
+ path.close();
+ path.moveTo(2,4);
+ path.lineTo(6,4);
+ path.lineTo(4,2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine8x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0,4);
+ path.lineTo(4,4);
+ path.lineTo(2,2);
+ path.close();
+ path.moveTo(2,4);
+ path.lineTo(6,4);
+ path.lineTo(4,2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine9(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0,4);
+ path.lineTo(4,4);
+ path.lineTo(2,2);
+ path.close();
+ path.moveTo(6,4);
+ path.lineTo(2,4);
+ path.lineTo(4,2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine9x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0,4);
+ path.lineTo(4,4);
+ path.lineTo(2,2);
+ path.close();
+ path.moveTo(6,4);
+ path.lineTo(2,4);
+ path.lineTo(4,2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine10(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0,4);
+ path.lineTo(4,4);
+ path.lineTo(2,2);
+ path.close();
+ path.moveTo(2,1);
+ path.lineTo(3,4);
+ path.lineTo(6,1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine10x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0,4);
+ path.lineTo(4,4);
+ path.lineTo(2,2);
+ path.close();
+ path.moveTo(2,1);
+ path.lineTo(3,4);
+ path.lineTo(6,1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine10a(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0,4);
+ path.lineTo(8,4);
+ path.lineTo(4,0);
+ path.close();
+ path.moveTo(2,2);
+ path.lineTo(3,3);
+ path.lineTo(4,2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine10ax(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0,4);
+ path.lineTo(8,4);
+ path.lineTo(4,0);
+ path.close();
+ path.moveTo(2,2);
+ path.lineTo(3,3);
+ path.lineTo(4,2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void addCWContainer(SkPath& path) {
+ path.moveTo(6,4);
+ path.lineTo(0,4);
+ path.lineTo(3,1);
+ path.close();
+}
+
+static void addCCWContainer(SkPath& path) {
+ path.moveTo(0,4);
+ path.lineTo(6,4);
+ path.lineTo(3,1);
+ path.close();
+}
+
+static void addCWContents(SkPath& path) {
+ path.moveTo(2,3);
+ path.lineTo(3,2);
+ path.lineTo(4,3);
+ path.close();
+}
+
+static void addCCWContents(SkPath& path) {
+ path.moveTo(3,2);
+ path.lineTo(2,3);
+ path.lineTo(4,3);
+ path.close();
+}
+
+static void testLine11(skiatest::Reporter* reporter) {
+ SkPath path;
+ addCWContainer(path);
+ addCWContents(path);
+ testSimplify(reporter, path);
+}
+
+static void testLine11x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ addCWContainer(path);
+ addCWContents(path);
+ testSimplify(reporter, path);
+}
+
+static void testLine12(skiatest::Reporter* reporter) {
+ SkPath path;
+ addCCWContainer(path);
+ addCWContents(path);
+ testSimplify(reporter, path);
+}
+
+static void testLine12x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ addCCWContainer(path);
+ addCWContents(path);
+ testSimplify(reporter, path);
+}
+
+static void testLine13(skiatest::Reporter* reporter) {
+ SkPath path;
+ addCWContainer(path);
+ addCCWContents(path);
+ testSimplify(reporter, path);
+}
+
+static void testLine13x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ addCWContainer(path);
+ addCCWContents(path);
+ testSimplify(reporter, path);
+}
+
+static void testLine14(skiatest::Reporter* reporter) {
+ SkPath path;
+ addCCWContainer(path);
+ addCCWContents(path);
+ testSimplify(reporter, path);
+}
+
+static void testLine14x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ addCCWContainer(path);
+ addCCWContents(path);
+ testSimplify(reporter, path);
+}
+
+static void testLine15(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 9, 9, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine15x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 9, 9, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine16(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(0, 4, 9, 9, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine16x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(0, 4, 9, 9, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine17(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 12, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine17x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 12, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine18(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(12, 4, 21, 21, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine18x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(12, 4, 21, 21, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine19(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(12, 16, 21, 21, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine19x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(12, 16, 21, 21, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine20(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 12, 12, 12, SkPath::kCW_Direction);
+ path.addRect(0, 12, 9, 9, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine20x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 12, 12, 12, SkPath::kCW_Direction);
+ path.addRect(0, 12, 9, 9, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine21(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 12, 12, 12, SkPath::kCW_Direction);
+ path.addRect(0, 16, 9, 9, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine21x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 12, 12, 12, SkPath::kCW_Direction);
+ path.addRect(0, 16, 9, 9, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine22(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 12, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 12, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine22x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 12, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 12, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine23(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 12, 12, 12, SkPath::kCW_Direction);
+ path.addRect(12, 0, 21, 21, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine23x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 12, 12, 12, SkPath::kCW_Direction);
+ path.addRect(12, 0, 21, 21, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine24a(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(2,0);
+ path.lineTo(4,4);
+ path.lineTo(0,4);
+ path.close();
+ path.moveTo(2,0);
+ path.lineTo(1,2);
+ path.lineTo(2,2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine24ax(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(2,0);
+ path.lineTo(4,4);
+ path.lineTo(0,4);
+ path.close();
+ path.moveTo(2,0);
+ path.lineTo(1,2);
+ path.lineTo(2,2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine24(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 18, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 12, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine24x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 18, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 12, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine25(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 6, 12, 12, SkPath::kCW_Direction);
+ path.addRect(12, 0, 21, 21, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine25x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 6, 12, 12, SkPath::kCW_Direction);
+ path.addRect(12, 0, 21, 21, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine26(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 18, 12, 12, SkPath::kCW_Direction);
+ path.addRect(0, 12, 9, 9, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine26x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 18, 12, 12, SkPath::kCW_Direction);
+ path.addRect(0, 12, 9, 9, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine27(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 18, 12, 12, SkPath::kCW_Direction);
+ path.addRect(12, 8, 21, 21, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine27x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 18, 12, 12, SkPath::kCW_Direction);
+ path.addRect(12, 8, 21, 21, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine28(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 6, 12, 12, SkPath::kCW_Direction);
+ path.addRect(0, 0, 9, 9, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine28x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 6, 12, 12, SkPath::kCW_Direction);
+ path.addRect(0, 0, 9, 9, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine29(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 18, 12, 12, SkPath::kCW_Direction);
+ path.addRect(12, 12, 21, 21, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine29x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 18, 12, 12, SkPath::kCW_Direction);
+ path.addRect(12, 12, 21, 21, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine30(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 4, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine30x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 4, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine31(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(0, 4, 9, 9, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine31x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(0, 4, 9, 9, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine32(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 12, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine32x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 12, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine33(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 16, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine33x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 16, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine34(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 6, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 12, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine34x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 6, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 12, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine35(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(6, 0, 18, 18, SkPath::kCW_Direction);
+ path.addRect(4, 16, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine35x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(6, 0, 18, 18, SkPath::kCW_Direction);
+ path.addRect(4, 16, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine36(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 10, 20, 20, SkPath::kCW_Direction);
+ path.addRect(6, 12, 18, 18, SkPath::kCW_Direction);
+ path.addRect(4, 16, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine36x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 10, 20, 20, SkPath::kCW_Direction);
+ path.addRect(6, 12, 18, 18, SkPath::kCW_Direction);
+ path.addRect(4, 16, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine37(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 20, 20, 20, SkPath::kCW_Direction);
+ path.addRect(18, 24, 30, 30, SkPath::kCW_Direction);
+ path.addRect(0, 0, 9, 9, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine37x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 20, 20, 20, SkPath::kCW_Direction);
+ path.addRect(18, 24, 30, 30, SkPath::kCW_Direction);
+ path.addRect(0, 0, 9, 9, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine38(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(10, 0, 30, 30, SkPath::kCW_Direction);
+ path.addRect(6, 12, 18, 18, SkPath::kCW_Direction);
+ path.addRect(12, 12, 21, 21, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine38x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(10, 0, 30, 30, SkPath::kCW_Direction);
+ path.addRect(6, 12, 18, 18, SkPath::kCW_Direction);
+ path.addRect(12, 12, 21, 21, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine40(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(10, 0, 30, 30, SkPath::kCW_Direction);
+ path.addRect(12, 18, 24, 24, SkPath::kCW_Direction);
+ path.addRect(4, 16, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine40x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(10, 0, 30, 30, SkPath::kCW_Direction);
+ path.addRect(12, 18, 24, 24, SkPath::kCW_Direction);
+ path.addRect(4, 16, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine41(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(18, 24, 30, 30, SkPath::kCW_Direction);
+ path.addRect(12, 0, 21, 21, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine41x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(18, 24, 30, 30, SkPath::kCW_Direction);
+ path.addRect(12, 0, 21, 21, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine42(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(8, 16, 17, 17, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine42x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(8, 16, 17, 17, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine43(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(6, 24, 18, 18, SkPath::kCW_Direction);
+ path.addRect(0, 32, 9, 36, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine43x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(6, 24, 18, 18, SkPath::kCW_Direction);
+ path.addRect(0, 32, 9, 36, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine44(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(10, 40, 30, 30, SkPath::kCW_Direction);
+ path.addRect(18, 0, 30, 30, SkPath::kCW_Direction);
+ path.addRect(18, 32, 27, 36, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine44x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(10, 40, 30, 30, SkPath::kCW_Direction);
+ path.addRect(18, 0, 30, 30, SkPath::kCW_Direction);
+ path.addRect(18, 32, 27, 36, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine45(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(10, 0, 30, 30, SkPath::kCW_Direction);
+ path.addRect(18, 0, 30, 30, SkPath::kCW_Direction);
+ path.addRect(24, 32, 33, 36, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine45x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(10, 0, 30, 30, SkPath::kCW_Direction);
+ path.addRect(18, 0, 30, 30, SkPath::kCW_Direction);
+ path.addRect(24, 32, 33, 36, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine46(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(10, 40, 30, 30, SkPath::kCW_Direction);
+ path.addRect(24, 0, 36, 36, SkPath::kCW_Direction);
+ path.addRect(24, 32, 33, 36, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine46x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(10, 40, 30, 30, SkPath::kCW_Direction);
+ path.addRect(24, 0, 36, 36, SkPath::kCW_Direction);
+ path.addRect(24, 32, 33, 36, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine47(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(0, 0, 9, 9, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine47x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(0, 0, 9, 9, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine48(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 6, 12, 12, SkPath::kCW_Direction);
+ path.addRect(0, 0, 9, 9, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine48x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 6, 12, 12, SkPath::kCW_Direction);
+ path.addRect(0, 0, 9, 9, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine49(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(0, 0, 9, 9, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine49x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(0, 0, 9, 9, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine50(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(10, 30, 30, 30, SkPath::kCW_Direction);
+ path.addRect(24, 20, 36, 30, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine50x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(10, 30, 30, 30, SkPath::kCW_Direction);
+ path.addRect(24, 20, 36, 30, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine51(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 12, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 12, 13, 13, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine51x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 12, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 12, 13, 13, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine52(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 30, 20, 20, SkPath::kCW_Direction);
+ path.addRect(6, 20, 18, 30, SkPath::kCW_Direction);
+ path.addRect(32, 0, 36, 41, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine52x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 30, 20, 20, SkPath::kCW_Direction);
+ path.addRect(6, 20, 18, 30, SkPath::kCW_Direction);
+ path.addRect(32, 0, 36, 41, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine53(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(10, 30, 30, 30, SkPath::kCW_Direction);
+ path.addRect(12, 20, 24, 30, SkPath::kCW_Direction);
+ path.addRect(12, 32, 21, 36, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine53x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(10, 30, 30, 30, SkPath::kCW_Direction);
+ path.addRect(12, 20, 24, 30, SkPath::kCW_Direction);
+ path.addRect(12, 32, 21, 36, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine54(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(6, 0, 18, 18, SkPath::kCW_Direction);
+ path.addRect(8, 4, 17, 17, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine54x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(6, 0, 18, 18, SkPath::kCW_Direction);
+ path.addRect(8, 4, 17, 17, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine55(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(6, 6, 18, 18, SkPath::kCW_Direction);
+ path.addRect(4, 4, 13, 13, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine55x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(6, 6, 18, 18, SkPath::kCW_Direction);
+ path.addRect(4, 4, 13, 13, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine56(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 20, 20, 20, SkPath::kCW_Direction);
+ path.addRect(18, 20, 30, 30, SkPath::kCW_Direction);
+ path.addRect(12, 0, 21, 21, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine56x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 20, 20, 20, SkPath::kCW_Direction);
+ path.addRect(18, 20, 30, 30, SkPath::kCW_Direction);
+ path.addRect(12, 0, 21, 21, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine57(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(20, 0, 40, 40, SkPath::kCW_Direction);
+ path.addRect(20, 0, 30, 40, SkPath::kCW_Direction);
+ path.addRect(12, 0, 21, 21, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine57x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(20, 0, 40, 40, SkPath::kCW_Direction);
+ path.addRect(20, 0, 30, 40, SkPath::kCW_Direction);
+ path.addRect(12, 0, 21, 21, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine58(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 0, 12, 12, SkPath::kCCW_Direction);
+ path.addRect(0, 12, 9, 9, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine58x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 0, 12, 12, SkPath::kCCW_Direction);
+ path.addRect(0, 12, 9, 9, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine59(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(6, 6, 18, 18, SkPath::kCCW_Direction);
+ path.addRect(4, 4, 13, 13, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine59x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(6, 6, 18, 18, SkPath::kCCW_Direction);
+ path.addRect(4, 4, 13, 13, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine60(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(6, 12, 18, 18, SkPath::kCCW_Direction);
+ path.addRect(4, 12, 13, 13, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine60x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(6, 12, 18, 18, SkPath::kCCW_Direction);
+ path.addRect(4, 12, 13, 13, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine61(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(12, 0, 24, 24, SkPath::kCCW_Direction);
+ path.addRect(12, 0, 21, 21, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine61x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(12, 0, 24, 24, SkPath::kCCW_Direction);
+ path.addRect(12, 0, 21, 21, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine62(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 60, 60, SkPath::kCW_Direction);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 12, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 12, 13, 13, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine62x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 60, 60, SkPath::kCW_Direction);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 12, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 12, 13, 13, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine63(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 60, 60, SkPath::kCW_Direction);
+ path.addRect(0, 10, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 6, 12, 12, SkPath::kCCW_Direction);
+ path.addRect(0, 32, 9, 36, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine63x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 60, 60, SkPath::kCW_Direction);
+ path.addRect(0, 10, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 6, 12, 12, SkPath::kCCW_Direction);
+ path.addRect(0, 32, 9, 36, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine64(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 60, 60, SkPath::kCW_Direction);
+ path.addRect(10, 40, 30, 30, SkPath::kCW_Direction);
+ path.addRect(18, 6, 30, 30, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine64x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 60, 60, SkPath::kCW_Direction);
+ path.addRect(10, 40, 30, 30, SkPath::kCW_Direction);
+ path.addRect(18, 6, 30, 30, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine65(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 60, 60, SkPath::kCW_Direction);
+ path.addRect(10, 0, 30, 30, SkPath::kCW_Direction);
+ path.addRect(24, 0, 36, 36, SkPath::kCW_Direction);
+ path.addRect(32, 6, 36, 41, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine65x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 60, 60, SkPath::kCW_Direction);
+ path.addRect(10, 0, 30, 30, SkPath::kCW_Direction);
+ path.addRect(24, 0, 36, 36, SkPath::kCW_Direction);
+ path.addRect(32, 6, 36, 41, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine66(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 60, 60, SkPath::kCW_Direction);
+ path.addRect(0, 30, 20, 20, SkPath::kCW_Direction);
+ path.addRect(12, 20, 24, 30, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine66x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 60, 60, SkPath::kCW_Direction);
+ path.addRect(0, 30, 20, 20, SkPath::kCW_Direction);
+ path.addRect(12, 20, 24, 30, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine67(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 60, 60, SkPath::kCW_Direction);
+ path.addRect(10, 40, 30, 30, SkPath::kCW_Direction);
+ path.addRect(24, 20, 36, 30, SkPath::kCW_Direction);
+ path.addRect(32, 0, 36, 41, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine67x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 60, 60, SkPath::kCW_Direction);
+ path.addRect(10, 40, 30, 30, SkPath::kCW_Direction);
+ path.addRect(24, 20, 36, 30, SkPath::kCW_Direction);
+ path.addRect(32, 0, 36, 41, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine68a(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 8, 8, SkPath::kCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCW_Direction);
+ path.addRect(1, 2, 4, 2, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine68ax(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 8, 8, SkPath::kCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCW_Direction);
+ path.addRect(1, 2, 4, 2, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine68b(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 8, 8, SkPath::kCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCCW_Direction);
+ path.addRect(1, 2, 2, 2, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine68bx(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 8, 8, SkPath::kCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCCW_Direction);
+ path.addRect(1, 2, 2, 2, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine68c(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 8, 8, SkPath::kCCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCW_Direction);
+ path.addRect(1, 2, 4, 2, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine68cx(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 8, 8, SkPath::kCCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCW_Direction);
+ path.addRect(1, 2, 4, 2, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine68d(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 8, 8, SkPath::kCCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCCW_Direction);
+ path.addRect(1, 2, 4, 2, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine68dx(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 8, 8, SkPath::kCCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCCW_Direction);
+ path.addRect(1, 2, 4, 2, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine68e(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 8, 8, SkPath::kCW_Direction);
+ path.addRect(0, 0, 8, 8, SkPath::kCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCCW_Direction);
+ path.addRect(1, 2, 2, 2, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine68ex(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 8, 8, SkPath::kCW_Direction);
+ path.addRect(0, 0, 8, 8, SkPath::kCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCCW_Direction);
+ path.addRect(1, 2, 2, 2, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine68f(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 8, 8, SkPath::kCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCCW_Direction);
+ path.addRect(1, 2, 2, 2, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine68fx(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 8, 8, SkPath::kCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCCW_Direction);
+ path.addRect(1, 2, 2, 2, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine68g(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 8, 8, SkPath::kCW_Direction);
+ path.addRect(0, 0, 8, 8, SkPath::kCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCCW_Direction);
+ path.addRect(1, 2, 2, 2, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine68gx(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 8, 8, SkPath::kCW_Direction);
+ path.addRect(0, 0, 8, 8, SkPath::kCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCCW_Direction);
+ path.addRect(1, 2, 2, 2, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine68h(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 8, 8, SkPath::kCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCCW_Direction);
+ path.addRect(1, 2, 2, 2, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine68hx(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 8, 8, SkPath::kCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCCW_Direction);
+ path.addRect(2, 2, 6, 6, SkPath::kCCW_Direction);
+ path.addRect(1, 2, 2, 2, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine69(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 20, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 20, 12, 30, SkPath::kCW_Direction);
+ path.addRect(12, 32, 21, 36, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine69x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 20, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 20, 12, 30, SkPath::kCW_Direction);
+ path.addRect(12, 32, 21, 36, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine70(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 24, 12, 12, SkPath::kCW_Direction);
+ path.addRect(12, 32, 21, 36, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine70x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 24, 12, 12, SkPath::kCW_Direction);
+ path.addRect(12, 32, 21, 36, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine71(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(12, 0, 24, 24, SkPath::kCW_Direction);
+ path.addRect(12, 32, 21, 36, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine71x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 20, 20, SkPath::kCW_Direction);
+ path.addRect(12, 0, 24, 24, SkPath::kCW_Direction);
+ path.addRect(12, 32, 21, 36, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine72(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 60, 60, SkPath::kCW_Direction);
+ path.addRect(10, 40, 30, 30, SkPath::kCW_Direction);
+ path.addRect(6, 20, 18, 30, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine72x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 60, 60, SkPath::kCW_Direction);
+ path.addRect(10, 40, 30, 30, SkPath::kCW_Direction);
+ path.addRect(6, 20, 18, 30, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine73(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 60, 60, SkPath::kCW_Direction);
+ path.addRect(0, 40, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 20, 12, 30, SkPath::kCW_Direction);
+ path.addRect(0, 0, 9, 9, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine73x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 60, 60, SkPath::kCW_Direction);
+ path.addRect(0, 40, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 20, 12, 30, SkPath::kCW_Direction);
+ path.addRect(0, 0, 9, 9, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine74(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(20, 30, 40, 40, SkPath::kCW_Direction);
+ path.addRect(24, 20, 36, 30, SkPath::kCCW_Direction);
+ path.addRect(32, 24, 36, 41, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine74x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(20, 30, 40, 40, SkPath::kCW_Direction);
+ path.addRect(24, 20, 36, 30, SkPath::kCCW_Direction);
+ path.addRect(32, 24, 36, 41, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine75(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 60, 60, SkPath::kCW_Direction);
+ path.addRect(10, 0, 30, 30, SkPath::kCCW_Direction);
+ path.addRect(18, 0, 30, 30, SkPath::kCCW_Direction);
+ path.addRect(12, 0, 21, 21, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine75x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 60, 60, SkPath::kCW_Direction);
+ path.addRect(10, 0, 30, 30, SkPath::kCCW_Direction);
+ path.addRect(18, 0, 30, 30, SkPath::kCCW_Direction);
+ path.addRect(12, 0, 21, 21, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine76(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(36, 0, 66, 60, SkPath::kCW_Direction);
+ path.addRect(10, 20, 40, 30, SkPath::kCW_Direction);
+ path.addRect(24, 20, 36, 30, SkPath::kCCW_Direction);
+ path.addRect(32, 6, 36, 41, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine76x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(36, 0, 66, 60, SkPath::kCW_Direction);
+ path.addRect(10, 20, 40, 30, SkPath::kCW_Direction);
+ path.addRect(24, 20, 36, 30, SkPath::kCCW_Direction);
+ path.addRect(32, 6, 36, 41, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine77(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(20, 0, 40, 40, SkPath::kCW_Direction);
+ path.addRect(24, 6, 36, 36, SkPath::kCCW_Direction);
+ path.addRect(24, 32, 33, 36, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine77x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(20, 0, 40, 40, SkPath::kCW_Direction);
+ path.addRect(24, 6, 36, 36, SkPath::kCCW_Direction);
+ path.addRect(24, 32, 33, 36, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine78(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 30, 60, SkPath::kCW_Direction);
+ path.addRect(10, 20, 30, 30, SkPath::kCCW_Direction);
+ path.addRect(18, 20, 30, 30, SkPath::kCCW_Direction);
+ path.addRect(32, 0, 36, 41, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine78x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 30, 60, SkPath::kCW_Direction);
+ path.addRect(10, 20, 30, 30, SkPath::kCCW_Direction);
+ path.addRect(18, 20, 30, 30, SkPath::kCCW_Direction);
+ path.addRect(32, 0, 36, 41, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine79(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 36, 60, 30, SkPath::kCW_Direction);
+ path.addRect(10, 30, 40, 30, SkPath::kCW_Direction);
+ path.addRect(0, 20, 12, 30, SkPath::kCCW_Direction);
+ path.addRect(0, 32, 9, 36, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine79x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 36, 60, 30, SkPath::kCW_Direction);
+ path.addRect(10, 30, 40, 30, SkPath::kCW_Direction);
+ path.addRect(0, 20, 12, 30, SkPath::kCCW_Direction);
+ path.addRect(0, 32, 9, 36, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine81(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(-1, -1, 3, 3, SkPath::kCW_Direction);
+ path.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ path.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ path.addRect(0, 0, 1, 1, SkPath::kCW_Direction);
+ path.addRect(1, 1, 2, 2, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testDegenerate1(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(2, 0);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(2, 0);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testDegenerate1x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(2, 0);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(2, 0);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testDegenerate2(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(0, 0);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(0, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testDegenerate2x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(0, 0);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(0, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testDegenerate3(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(2, 0);
+ path.lineTo(1, 0);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(3, 0);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testDegenerate3x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.lineTo(2, 0);
+ path.lineTo(1, 0);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(3, 0);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testDegenerate4(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(1, 3);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(1, 1);
+ path.lineTo(1, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testDegenerate4x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(1, 3);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(1, 1);
+ path.lineTo(1, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testNondegenerate1(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(3, 0);
+ path.lineTo(1, 3);
+ path.close();
+ path.moveTo(1, 1);
+ path.lineTo(2, 1);
+ path.lineTo(1, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testNondegenerate1x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.lineTo(3, 0);
+ path.lineTo(1, 3);
+ path.close();
+ path.moveTo(1, 1);
+ path.lineTo(2, 1);
+ path.lineTo(1, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testNondegenerate2(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(1, 0);
+ path.lineTo(0, 1);
+ path.lineTo(1, 1);
+ path.close();
+ path.moveTo(0, 2);
+ path.lineTo(0, 3);
+ path.lineTo(1, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testNondegenerate2x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(1, 0);
+ path.lineTo(0, 1);
+ path.lineTo(1, 1);
+ path.close();
+ path.moveTo(0, 2);
+ path.lineTo(0, 3);
+ path.lineTo(1, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testNondegenerate3(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(2, 1);
+ path.close();
+ path.moveTo(0, 1);
+ path.lineTo(1, 1);
+ path.lineTo(0, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testNondegenerate3x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(2, 1);
+ path.close();
+ path.moveTo(0, 1);
+ path.lineTo(1, 1);
+ path.lineTo(0, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testNondegenerate4(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(1, 0);
+ path.lineTo(0, 1);
+ path.lineTo(1, 2);
+ path.close();
+ path.moveTo(0, 2);
+ path.lineTo(0, 3);
+ path.lineTo(1, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testNondegenerate4x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(1, 0);
+ path.lineTo(0, 1);
+ path.lineTo(1, 2);
+ path.close();
+ path.moveTo(0, 2);
+ path.lineTo(0, 3);
+ path.lineTo(1, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadralateral5(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(1, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(2, 2);
+ path.lineTo(3, 2);
+ path.lineTo(3, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadralateral5x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(1, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(2, 2);
+ path.lineTo(3, 2);
+ path.lineTo(3, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadralateral6(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(1, 1);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(2, 0);
+ path.lineTo(0, 2);
+ path.lineTo(2, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadralateral6x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(1, 1);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(2, 0);
+ path.lineTo(0, 2);
+ path.lineTo(2, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testFauxQuadralateral6(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(1, 1);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(2, 0);
+ path.lineTo(1 + 1.0f/3, 2.0f/3);
+ path.close();
+ path.moveTo(1 + 1.0f/3, 2.0f/3);
+ path.lineTo(0, 2);
+ path.lineTo(2, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testFauxQuadralateral6x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(1, 1);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(2, 0);
+ path.lineTo(1 + 1.0f/3, 2.0f/3);
+ path.close();
+ path.moveTo(1 + 1.0f/3, 2.0f/3);
+ path.lineTo(0, 2);
+ path.lineTo(2, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testFauxQuadralateral6a(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(3, 0);
+ path.lineTo(3, 3);
+ path.close();
+ path.moveTo(3, 0);
+ path.lineTo(6, 0);
+ path.lineTo(4, 2);
+ path.close();
+ path.moveTo(4, 2);
+ path.lineTo(0, 6);
+ path.lineTo(6, 6);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testFauxQuadralateral6ax(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.lineTo(3, 0);
+ path.lineTo(3, 3);
+ path.close();
+ path.moveTo(3, 0);
+ path.lineTo(6, 0);
+ path.lineTo(4, 2);
+ path.close();
+ path.moveTo(4, 2);
+ path.lineTo(0, 6);
+ path.lineTo(6, 6);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testFauxQuadralateral6b(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(3, 0);
+ path.lineTo(3, 3);
+ path.close();
+ path.moveTo(3, 0);
+ path.lineTo(6, 0);
+ path.lineTo(4, 2);
+ path.close();
+ path.moveTo(4, 2);
+ path.lineTo(6, 6);
+ path.lineTo(0, 6);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testFauxQuadralateral6bx(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.lineTo(3, 0);
+ path.lineTo(3, 3);
+ path.close();
+ path.moveTo(3, 0);
+ path.lineTo(6, 0);
+ path.lineTo(4, 2);
+ path.close();
+ path.moveTo(4, 2);
+ path.lineTo(6, 6);
+ path.lineTo(0, 6);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testFauxQuadralateral6c(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(3, 3);
+ path.lineTo(3, 0);
+ path.close();
+ path.moveTo(3, 0);
+ path.lineTo(6, 0);
+ path.lineTo(4, 2);
+ path.close();
+ path.moveTo(4, 2);
+ path.lineTo(0, 6);
+ path.lineTo(6, 6);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testFauxQuadralateral6cx(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.lineTo(3, 3);
+ path.lineTo(3, 0);
+ path.close();
+ path.moveTo(3, 0);
+ path.lineTo(6, 0);
+ path.lineTo(4, 2);
+ path.close();
+ path.moveTo(4, 2);
+ path.lineTo(0, 6);
+ path.lineTo(6, 6);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testFauxQuadralateral6d(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(3, 3);
+ path.lineTo(3, 0);
+ path.close();
+ path.moveTo(3, 0);
+ path.lineTo(6, 0);
+ path.lineTo(4, 2);
+ path.close();
+ path.moveTo(4, 2);
+ path.lineTo(6, 6);
+ path.lineTo(0, 6);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testFauxQuadralateral6dx(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.lineTo(3, 3);
+ path.lineTo(3, 0);
+ path.close();
+ path.moveTo(3, 0);
+ path.lineTo(6, 0);
+ path.lineTo(4, 2);
+ path.close();
+ path.moveTo(4, 2);
+ path.lineTo(6, 6);
+ path.lineTo(0, 6);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadralateral6a(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(3, 0);
+ path.lineTo(3, 3);
+ path.close();
+ path.moveTo(3, 0);
+ path.lineTo(6, 0);
+ path.lineTo(0, 6);
+ path.lineTo(6, 6);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadralateral6ax(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(3, 0);
+ path.lineTo(3, 3);
+ path.close();
+ path.moveTo(3, 0);
+ path.lineTo(6, 0);
+ path.lineTo(0, 6);
+ path.lineTo(6, 6);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadralateral7(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(2, 1);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(1, 1);
+ path.lineTo(2, 2);
+ path.lineTo(1, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadralateral7x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(2, 1);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(1, 1);
+ path.lineTo(2, 2);
+ path.lineTo(1, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadralateral8(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(3, 1);
+ path.lineTo(1, 3);
+ path.lineTo(3, 3);
+ path.close();
+ path.moveTo(2, 1);
+ path.lineTo(0, 2);
+ path.lineTo(3, 2);
+ path.lineTo(2, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadralateral8x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.lineTo(3, 1);
+ path.lineTo(1, 3);
+ path.lineTo(3, 3);
+ path.close();
+ path.moveTo(2, 1);
+ path.lineTo(0, 2);
+ path.lineTo(3, 2);
+ path.lineTo(2, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadralateral9(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(1, 2);
+ path.lineTo(2, 2);
+ path.close();
+ path.moveTo(1, 1);
+ path.lineTo(2, 1);
+ path.lineTo(1, 3);
+ path.lineTo(2, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadralateral9x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(1, 2);
+ path.lineTo(2, 2);
+ path.close();
+ path.moveTo(1, 1);
+ path.lineTo(2, 1);
+ path.lineTo(1, 3);
+ path.lineTo(2, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine1a(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 0, 13, 13, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine1ax(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 0, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 0, 13, 13, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine2ax(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 20, 20, 20, SkPath::kCW_Direction);
+ path.addRect(0, 20, 12, 30, SkPath::kCW_Direction);
+ path.addRect(12, 0, 21, 21, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine3aax(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(10, 30, 30, 30, SkPath::kCW_Direction);
+ path.addRect(18, 20, 30, 30, SkPath::kCCW_Direction);
+ path.addRect(0, 32, 9, 36, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine4ax(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(10, 30, 30, 30, SkPath::kCW_Direction);
+ path.addRect(24, 20, 36, 30, SkPath::kCCW_Direction);
+ path.addRect(0, 32, 9, 36, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic1(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 0, 0);
+ path.lineTo(1, 0);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(0, 0, 0, 0);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic1x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 0, 0);
+ path.lineTo(1, 0);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(0, 0, 0, 0);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic2(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 0, 0);
+ path.lineTo(3, 0);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(1, 0, 0, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic2x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 0, 0);
+ path.lineTo(3, 0);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(1, 0, 0, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic3(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 1, 0);
+ path.lineTo(0, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(1, 0, 0, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic3x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 1, 0);
+ path.lineTo(0, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(1, 0, 0, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic4(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 1, 0);
+ path.lineTo(0, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(1, 0, 0, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic4x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 1, 0);
+ path.lineTo(0, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(1, 0, 0, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic5(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 0, 0);
+ path.lineTo(0, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.quadTo(0, 1, 0, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic6(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 1, 0);
+ path.lineTo(2, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(2, 0, 0, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic7(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 1, 0);
+ path.lineTo(3, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(3, 0, 1, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic8(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 1, 0);
+ path.lineTo(0, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.quadTo(0, 1, 1, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic9(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 1, 0);
+ path.lineTo(3, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.quadTo(1, 2, 3, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic14(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 1, 0);
+ path.lineTo(3, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.quadTo(3, 2, 3, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic15(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 1, 0);
+ path.lineTo(1, 3);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(0, 1);
+ path.quadTo(1, 1, 0, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic17x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 3, 1);
+ path.lineTo(0, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.quadTo(3, 1, 0, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic18(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 0, 1);
+ path.lineTo(0, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(1, 0, 1, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic19(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 0, 1);
+ path.lineTo(0, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(2, 0, 0, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic20(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 0, 1);
+ path.lineTo(0, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(1, 0, 0, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic21(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 0, 1);
+ path.lineTo(0, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(1, 0, 0, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic22(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 0, 1);
+ path.lineTo(0, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(0, 1, 2, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic23(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 0, 1);
+ path.lineTo(0, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(0, 2, 1, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic24(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 0, 1);
+ path.lineTo(0, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.quadTo(2, 0, 0, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic25(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 1, 1);
+ path.lineTo(1, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(2, 1, 0, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic26(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 1, 1);
+ path.lineTo(0, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(1, 0, 0, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic27(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 1, 1);
+ path.lineTo(2, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(2, 1, 0, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic28(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 0, 1);
+ path.lineTo(0, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 2);
+ path.quadTo(1, 2, 0, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic29(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 2, 1);
+ path.lineTo(0, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(1, 0, 0, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic30(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 1, 2);
+ path.lineTo(1, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.quadTo(0, 1, 1, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic31(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 1, 2);
+ path.lineTo(1, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.quadTo(0, 1, 1, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic32(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 2, 3);
+ path.lineTo(2, 3);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(3, 1, 0, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic33(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(2, 0, 0, 1);
+ path.lineTo(0, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 1);
+ path.quadTo(2, 1, 2, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic34(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(2, 0, 0, 1);
+ path.lineTo(0, 1);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(1, 1);
+ path.quadTo(2, 1, 1, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic35(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(0, 1, 1, 1);
+ path.lineTo(1, 3);
+ path.close();
+ path.moveTo(2, 0);
+ path.lineTo(3, 0);
+ path.quadTo(0, 1, 1, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic36(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(2, 1, 2, 3);
+ path.lineTo(2, 3);
+ path.close();
+ path.moveTo(3, 1);
+ path.lineTo(1, 2);
+ path.quadTo(3, 2, 1, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic37(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(0, 2, 1, 2);
+ path.lineTo(1, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(3, 1);
+ path.quadTo(0, 2, 1, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic38(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(1, 0);
+ path.quadTo(0, 1, 1, 1);
+ path.lineTo(1, 1);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(1, 2);
+ path.quadTo(2, 2, 1, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic51(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(369.863983f, 145.645813f);
+ path.quadTo(382.380371f, 121.254936f, 406.236359f, 121.254936f);
+ path.lineTo(369.863983f, 145.645813f);
+ path.close();
+ path.moveTo(369.970581f, 137.94342f);
+ path.quadTo(383.98465f, 121.254936f, 406.235992f, 121.254936f);
+ path.lineTo(369.970581f, 137.94342f);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic53(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(303.12088f, 141.299606f);
+ path.lineTo(330.463562f, 217.659027f);
+ path.lineTo(303.12088f, 141.299606f);
+ path.close();
+ path.moveTo(371.919067f, 205.854996f);
+ path.lineTo(326.236786f, 205.854996f);
+ path.quadTo(329.104431f, 231.663818f, 351.512085f, 231.663818f);
+ path.lineTo(371.919067f, 205.854996f);
+ path.close();
+ testSimplify(reporter, path);
+}
+static void testQuadratic55(skiatest::Reporter* reporter) {
+ SkPath path;
+path.moveTo(303.12088f, 141.299606f);
+path.lineTo(330.463562f, 217.659027f);
+path.lineTo(358.606506f, 141.299606f);
+path.lineTo(303.12088f, 141.299606f);
+path.close();
+path.moveTo(326.236786f, 205.854996f);
+path.quadTo(329.104431f, 231.663818f, 351.512085f, 231.663818f);
+path.lineTo(326.236786f, 205.854996f);
+path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic56(skiatest::Reporter* reporter) {
+ SkPath path;
+path.moveTo(366.608826f, 151.196014f);
+path.quadTo(378.803101f, 136.674606f, 398.164948f, 136.674606f);
+path.lineTo(354.009216f, 208.816208f);
+path.lineTo(393.291473f, 102.232819f);
+path.lineTo(359.978058f, 136.581512f);
+path.quadTo(378.315979f, 136.581512f, 388.322723f, 149.613556f);
+path.lineTo(364.390686f, 157.898193f);
+path.quadTo(375.281769f, 136.674606f, 396.039917f, 136.674606f);
+path.lineTo(350, 120);
+path.lineTo(366.608826f, 151.196014f);
+path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine80(skiatest::Reporter* reporter) {
+ SkPath path;
+path.moveTo(4, 0);
+path.lineTo(3, 7);
+path.lineTo(7, 5);
+path.lineTo(2, 2);
+path.close();
+path.moveTo(0, 6);
+path.lineTo(6, 12);
+path.lineTo(8, 3);
+path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic58(skiatest::Reporter* reporter) {
+ SkPath path;
+path.moveTo(283.714233f, 240);
+path.lineTo(283.714233f, 141.299606f);
+path.lineTo(303.12088f, 141.299606f);
+path.lineTo(330.463562f, 217.659027f);
+path.lineTo(358.606506f, 141.299606f);
+path.lineTo(362.874634f, 159.705902f);
+path.lineTo(335.665344f, 233.397751f);
+path.lineTo(322.12738f, 233.397751f);
+path.lineTo(295.718353f, 159.505829f);
+path.lineTo(295.718353f, 240);
+path.lineTo(283.714233f, 240);
+path.close();
+path.moveTo(322.935669f, 231.030273f);
+path.quadTo(312.832214f, 220.393295f, 312.832214f, 203.454178f);
+path.quadTo(312.832214f, 186.981888f, 321.73526f, 176.444946f);
+path.quadTo(330.638306f, 165.90802f, 344.509705f, 165.90802f);
+path.quadTo(357.647522f, 165.90802f, 364.81665f, 175.244537f);
+path.lineTo(371.919067f, 205.854996f);
+path.lineTo(326.236786f, 205.854996f);
+path.quadTo(329.104431f, 231.663818f, 351.512085f, 231.663818f);
+path.lineTo(322.935669f, 231.030273f);
+path.close();
+path.moveTo(326.837006f, 195.984955f);
+path.lineTo(358.78125f, 195.984955f);
+path.quadTo(358.78125f, 175.778046f, 343.709442f, 175.778046f);
+path.quadTo(328.570923f, 175.778046f, 326.837006f, 195.984955f);
+path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic59x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 0, 0);
+ path.lineTo(2, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(2, 0);
+ path.quadTo(3, 1, 1, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic59(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 0, 0);
+ path.lineTo(2, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(2, 0);
+ path.quadTo(3, 1, 1, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic63(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 0, 0);
+ path.lineTo(3, 2);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(2, 1);
+ path.quadTo(2, 1, 2, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic64(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 0, 0);
+ path.lineTo(2, 3);
+ path.close();
+ path.moveTo(1, 2);
+ path.lineTo(2, 2);
+ path.quadTo(0, 3, 3, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic65(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 0, 0);
+ path.lineTo(3, 2);
+ path.close();
+ path.moveTo(2, 1);
+ path.lineTo(2, 2);
+ path.quadTo(0, 3, 1, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic67x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 2, 1);
+ path.lineTo(2, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(2, 0);
+ path.quadTo(1, 1, 3, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic68(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 0, 1);
+ path.lineTo(1, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(0, 1, 2, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic69(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 0, 1);
+ path.lineTo(3, 2);
+ path.close();
+ path.moveTo(2, 0);
+ path.lineTo(1, 1);
+ path.quadTo(3, 2, 2, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic70x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 0, 1);
+ path.lineTo(1, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(0, 1, 2, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic71(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 1, 1);
+ path.lineTo(3, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(1, 1, 3, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic72(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 1, 2);
+ path.lineTo(1, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.quadTo(0, 1, 3, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic73(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 0, 3);
+ path.lineTo(0, 3);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.quadTo(0, 1, 1, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic74(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 1, 3);
+ path.lineTo(1, 3);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 1);
+ path.quadTo(3, 2, 2, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic75(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 1, 3);
+ path.lineTo(2, 3);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 1);
+ path.quadTo(3, 2, 2, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic76(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 0, 0);
+ path.lineTo(2, 3);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(1, 2);
+ path.quadTo(1, 2, 2, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic77(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 1, 1);
+ path.lineTo(3, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.quadTo(0, 1, 3, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic78(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 1, 2);
+ path.lineTo(3, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(2, 1, 0, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic79(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 1, 2);
+ path.lineTo(3, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.quadTo(0, 1, 3, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testEight1(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(2, 2);
+ path.lineTo(0, 2);
+ path.lineTo(2, 0);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testEight2(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(2, 0);
+ path.lineTo(0, 2);
+ path.lineTo(2, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testEight3(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(0, 2);
+ path.lineTo(2, 0);
+ path.lineTo(2, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testEight4(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(2, 2);
+ path.lineTo(2, 0);
+ path.lineTo(0, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testEight5(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(1, 0);
+ path.lineTo(1, 2);
+ path.lineTo(0, 2);
+ path.lineTo(2, 0);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testEight6(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(1, 0);
+ path.lineTo(2, 0);
+ path.lineTo(0, 2);
+ path.lineTo(1, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testEight7(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(0, 1);
+ path.lineTo(2, 1);
+ path.lineTo(2, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testEight8(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(2, 2);
+ path.lineTo(2, 1);
+ path.lineTo(0, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testEight9(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(1, 0);
+ path.lineTo(1, 2);
+ path.lineTo(2, 1);
+ path.lineTo(0, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testEight10(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(1, 0);
+ path.lineTo(0, 1);
+ path.lineTo(2, 1);
+ path.lineTo(1, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic80(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(1, 0, 2, 3);
+ path.lineTo(2, 3);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(3, 0);
+ path.quadTo(0, 1, 1, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic81(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(2, 0, 1, 1);
+ path.lineTo(1, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(2, 1, 0, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic82(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(2, 0, 1, 1);
+ path.lineTo(0, 3);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(2, 1, 0, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic83(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(0, 0, 2, 0);
+ path.lineTo(2, 2);
+ path.close();
+ path.moveTo(0, 1);
+ path.lineTo(0, 2);
+ path.quadTo(2, 2, 1, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic84(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(2, 0, 1, 1);
+ path.lineTo(2, 1);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(2, 0);
+ path.quadTo(0, 1, 2, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic85(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(3, 0, 1, 1);
+ path.lineTo(1, 1);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(3, 0);
+ path.quadTo(0, 1, 1, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic86(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(0, 1, 1, 1);
+ path.lineTo(2, 3);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.quadTo(1, 1, 1, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic87(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(2, 1, 0, 2);
+ path.lineTo(2, 3);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 1);
+ path.quadTo(0, 2, 3, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic88(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(2, 1, 0, 2);
+ path.lineTo(2, 2);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(1, 1);
+ path.quadTo(0, 2, 2, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic89x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.quadTo(3, 1, 2, 2);
+ path.lineTo(0, 3);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(2, 1);
+ path.quadTo(3, 1, 3, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic90x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 0);
+ path.quadTo(3, 0, 2, 2);
+ path.lineTo(1, 3);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 1);
+ path.quadTo(3, 2, 2, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic91(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.quadTo(3, 2, 2, 3);
+ path.lineTo(2, 3);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 1);
+ path.quadTo(2, 1, 2, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic92x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(1, 0);
+ path.quadTo(3, 0, 2, 2);
+ path.lineTo(2, 2);
+ path.close();
+ path.moveTo(2, 0);
+ path.lineTo(0, 1);
+ path.quadTo(3, 2, 2, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testLine82(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(20, 0, 40, 40, SkPath::kCCW_Direction);
+ path.addRect(24, 20, 36, 30, SkPath::kCCW_Direction);
+ path.addRect(24, 32, 33, 36, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine82a(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 6, 10, SkPath::kCW_Direction);
+ path.addRect(2, 2, 4, 4, SkPath::kCW_Direction);
+ path.addRect(2, 6, 4, 8, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine82b(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 6, 10, SkPath::kCW_Direction);
+ path.addRect(2, 2, 4, 4, SkPath::kCW_Direction);
+ path.addRect(2, 6, 4, 8, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine82c(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 6, 10, SkPath::kCW_Direction);
+ path.addRect(2, 2, 4, 4, SkPath::kCCW_Direction);
+ path.addRect(2, 6, 4, 8, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine82d(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 6, 10, SkPath::kCW_Direction);
+ path.addRect(2, 2, 4, 4, SkPath::kCCW_Direction);
+ path.addRect(2, 6, 4, 8, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine82e(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 6, 10, SkPath::kCCW_Direction);
+ path.addRect(2, 2, 4, 4, SkPath::kCW_Direction);
+ path.addRect(2, 6, 4, 8, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine82f(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 6, 10, SkPath::kCCW_Direction);
+ path.addRect(2, 2, 4, 4, SkPath::kCW_Direction);
+ path.addRect(2, 6, 4, 8, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine82g(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 6, 10, SkPath::kCCW_Direction);
+ path.addRect(2, 2, 4, 4, SkPath::kCCW_Direction);
+ path.addRect(2, 6, 4, 8, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine82h(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 0, 6, 10, SkPath::kCCW_Direction);
+ path.addRect(2, 2, 4, 4, SkPath::kCCW_Direction);
+ path.addRect(2, 6, 4, 8, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine83(skiatest::Reporter* reporter) {
+ SkPath path;
+path.addRect(10, 30, 30, 40, SkPath::kCCW_Direction);
+path.addRect(0, 12, 12, 18, SkPath::kCCW_Direction);
+path.addRect(4, 13, 13, 16, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine84(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(0, 12, 60, 30, SkPath::kCCW_Direction);
+ path.addRect(10, 20, 40, 30, SkPath::kCW_Direction);
+ path.addRect(0, 12, 12, 12, SkPath::kCW_Direction);
+ path.addRect(4, 12, 13, 13, SkPath::kCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine84x(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.addRect(0, 12, 60, 30, SkPath::kCCW_Direction);
+ path.addRect(10, 20, 40, 30, SkPath::kCCW_Direction);
+ path.addRect(0, 12, 12, 12, SkPath::kCCW_Direction);
+ path.addRect(4, 12, 13, 13, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testLine85(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.addRect(36, 0, 66, 60, SkPath::kCCW_Direction);
+ path.addRect(20, 0, 40, 40, SkPath::kCCW_Direction);
+ path.addRect(12, 0, 24, 24, SkPath::kCCW_Direction);
+ path.addRect(32, 0, 36, 41, SkPath::kCCW_Direction);
+ testSimplify(reporter, path);
+}
+
+static void testQuadralateral1(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(3, 2);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(2, 1);
+ path.lineTo(2, 2);
+ path.lineTo(2, 3);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testCubic1(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.cubicTo(0, 1, 1, 1, 1, 0);
+ path.close();
+ path.moveTo(1, 0);
+ path.cubicTo(0, 0, 0, 1, 1, 1);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testQuadratic93(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(3, 0);
+ path.quadTo(0, 1, 3, 2);
+ path.lineTo(0, 3);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(2, 0);
+ path.quadTo(1, 1, 2, 2);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+static void testCubic2(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0,2);
+ path.cubicTo(0,3, 2,1, 4,0);
+ path.close();
+ path.moveTo(1,2);
+ path.cubicTo(0,4, 2,0, 3,0);
+ path.close();
+ testSimplify(reporter, path);
+}
+
+#if 01 // FIXME: enable and fix
+static void testQuad1(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.moveTo(0,0);
+ path.quadTo(0,0, 0,1);
+ path.lineTo(1,1);
+ path.close();
+ path.moveTo(0,0);
+ path.quadTo(1,1, 0,2);
+ path.close();
+ testSimplify(reporter, path);
+}
+#endif
+
+static void (*firstTest)(skiatest::Reporter* ) = 0;
+
+static TestDesc tests[] = {
+ TEST(testQuad1), // FIXME: fails, need to investigate
+ TEST(testCubic2),
+ TEST(testCubic1),
+ TEST(testQuadralateral1),
+ TEST(testLine85),
+ TEST(testLine84),
+ TEST(testLine84x),
+ TEST(testLine83),
+ TEST(testLine82h),
+ TEST(testLine82g),
+ TEST(testLine82f),
+ TEST(testLine82e),
+ TEST(testLine82d),
+ TEST(testLine82c),
+ TEST(testLine82b),
+ TEST(testLine82a),
+ TEST(testLine82),
+ TEST(testQuadratic93),
+ TEST(testQuadratic92x),
+ TEST(testQuadratic91),
+ TEST(testQuadratic90x),
+ TEST(testQuadratic89x),
+ TEST(testQuadratic88),
+ TEST(testQuadratic87),
+ TEST(testQuadratic86),
+ TEST(testQuadratic85),
+ TEST(testQuadratic84),
+ TEST(testQuadratic83),
+ TEST(testQuadratic82),
+ TEST(testQuadratic81),
+ TEST(testQuadratic80),
+ TEST(testEight1),
+ TEST(testEight2),
+ TEST(testEight3),
+ TEST(testEight4),
+ TEST(testEight5),
+ TEST(testEight6),
+ TEST(testEight7),
+ TEST(testEight8),
+ TEST(testEight9),
+ TEST(testEight10),
+ TEST(testQuadratic79),
+ TEST(testQuadratic78),
+ TEST(testQuadratic77),
+ TEST(testQuadratic76),
+ TEST(testQuadratic75),
+ TEST(testQuadratic74),
+ TEST(testQuadratic73),
+ TEST(testQuadratic72),
+ TEST(testQuadratic71),
+ TEST(testQuadratic70x),
+ TEST(testQuadratic69),
+ TEST(testQuadratic68),
+ TEST(testQuadratic67x),
+ TEST(testQuadratic65),
+ TEST(testQuadratic64),
+ TEST(testQuadratic63),
+ TEST(testLine1a),
+ TEST(testLine1ax),
+ TEST(testQuadratic59),
+ TEST(testQuadratic59x),
+ TEST(testQuadratic58),
+ TEST(testQuadratic56),
+ TEST(testQuadratic55),
+ TEST(testQuadratic53),
+ TEST(testQuadratic51),
+ TEST(testQuadratic38),
+ TEST(testQuadratic37),
+ TEST(testQuadratic36),
+ TEST(testQuadratic35),
+ TEST(testQuadratic34),
+ TEST(testQuadratic33),
+ TEST(testQuadratic32),
+ TEST(testQuadratic31),
+ TEST(testQuadratic30),
+ TEST(testQuadratic29),
+ TEST(testQuadratic28),
+ TEST(testQuadratic27),
+ TEST(testQuadratic26),
+ TEST(testQuadratic25),
+ TEST(testQuadratic24),
+ TEST(testQuadratic23),
+ TEST(testQuadratic22),
+ TEST(testQuadratic21),
+ TEST(testQuadratic20),
+ TEST(testQuadratic19),
+ TEST(testQuadratic18),
+ TEST(testQuadratic17x),
+ TEST(testQuadratic15),
+ TEST(testQuadratic14),
+ TEST(testQuadratic9),
+ TEST(testQuadratic8),
+ TEST(testQuadratic7),
+ TEST(testQuadratic6),
+ TEST(testQuadratic5),
+ TEST(testQuadratic4x),
+ TEST(testQuadratic3x),
+ TEST(testQuadratic2x),
+ TEST(testQuadratic1x),
+ TEST(testQuadratic4),
+ TEST(testQuadratic3),
+ TEST(testQuadratic2),
+ TEST(testQuadratic1),
+ TEST(testLine4ax),
+ TEST(testLine3aax),
+ TEST(testLine2ax),
+ TEST(testLine1ax),
+ TEST(testQuadralateral9x),
+ TEST(testQuadralateral8x),
+ TEST(testQuadralateral7x),
+ TEST(testQuadralateral6x),
+ TEST(testQuadralateral6ax),
+ TEST(testQuadralateral9),
+ TEST(testQuadralateral8),
+ TEST(testQuadralateral7),
+ TEST(testQuadralateral6),
+ TEST(testQuadralateral6a),
+ TEST(testFauxQuadralateral6dx),
+ TEST(testFauxQuadralateral6cx),
+ TEST(testFauxQuadralateral6bx),
+ TEST(testFauxQuadralateral6ax),
+ TEST(testFauxQuadralateral6x),
+ TEST(testFauxQuadralateral6d),
+ TEST(testFauxQuadralateral6c),
+ TEST(testFauxQuadralateral6b),
+ TEST(testFauxQuadralateral6a),
+ TEST(testFauxQuadralateral6),
+ TEST(testQuadralateral5x),
+ TEST(testQuadralateral5),
+ TEST(testNondegenerate4x),
+ TEST(testNondegenerate3x),
+ TEST(testNondegenerate2x),
+ TEST(testNondegenerate1x),
+ TEST(testNondegenerate4),
+ TEST(testNondegenerate3),
+ TEST(testNondegenerate2),
+ TEST(testNondegenerate1),
+ TEST(testDegenerate4x),
+ TEST(testDegenerate3x),
+ TEST(testDegenerate2x),
+ TEST(testDegenerate1x),
+ TEST(testDegenerate4),
+ TEST(testDegenerate3),
+ TEST(testDegenerate2),
+ TEST(testDegenerate1),
+ TEST(testLine79x),
+ TEST(testLine78x),
+ TEST(testLine77x),
+ TEST(testLine76x),
+ TEST(testLine75x),
+ TEST(testLine74x),
+ TEST(testLine73x),
+ TEST(testLine72x),
+ TEST(testLine71x),
+ TEST(testLine70x),
+ TEST(testLine69x),
+ TEST(testLine68hx),
+ TEST(testLine68gx),
+ TEST(testLine68fx),
+ TEST(testLine68ex),
+ TEST(testLine68dx),
+ TEST(testLine68cx),
+ TEST(testLine68bx),
+ TEST(testLine68ax),
+ TEST(testLine67x),
+ TEST(testLine66x),
+ TEST(testLine65x),
+ TEST(testLine64x),
+ TEST(testLine63x),
+ TEST(testLine62x),
+ TEST(testLine61x),
+ TEST(testLine60x),
+ TEST(testLine59x),
+ TEST(testLine58x),
+ TEST(testLine57x),
+ TEST(testLine56x),
+ TEST(testLine55x),
+ TEST(testLine54x),
+ TEST(testLine53x),
+ TEST(testLine52x),
+ TEST(testLine51x),
+ TEST(testLine50x),
+ TEST(testLine49x),
+ TEST(testLine48x),
+ TEST(testLine47x),
+ TEST(testLine46x),
+ TEST(testLine45x),
+ TEST(testLine44x),
+ TEST(testLine43x),
+ TEST(testLine42x),
+ TEST(testLine41x),
+ TEST(testLine40x),
+ TEST(testLine38x),
+ TEST(testLine37x),
+ TEST(testLine36x),
+ TEST(testLine35x),
+ TEST(testLine34x),
+ TEST(testLine33x),
+ TEST(testLine32x),
+ TEST(testLine31x),
+ TEST(testLine30x),
+ TEST(testLine29x),
+ TEST(testLine28x),
+ TEST(testLine27x),
+ TEST(testLine26x),
+ TEST(testLine25x),
+ TEST(testLine24ax),
+ TEST(testLine24x),
+ TEST(testLine23x),
+ TEST(testLine22x),
+ TEST(testLine21x),
+ TEST(testLine20x),
+ TEST(testLine19x),
+ TEST(testLine18x),
+ TEST(testLine17x),
+ TEST(testLine16x),
+ TEST(testLine15x),
+ TEST(testLine14x),
+ TEST(testLine13x),
+ TEST(testLine12x),
+ TEST(testLine11x),
+ TEST(testLine10ax),
+ TEST(testLine10x),
+ TEST(testLine9x),
+ TEST(testLine8x),
+ TEST(testLine7bx),
+ TEST(testLine7ax),
+ TEST(testLine7x),
+ TEST(testLine6x),
+ TEST(testLine5x),
+ TEST(testLine4x),
+ TEST(testLine3bx),
+ TEST(testLine3ax),
+ TEST(testLine3x),
+ TEST(testLine2x),
+ TEST(testLine1x),
+ TEST(testLine81),
+ TEST(testLine80),
+ TEST(testLine79),
+ TEST(testLine78),
+ TEST(testLine77),
+ TEST(testLine76),
+ TEST(testLine75),
+ TEST(testLine74),
+ TEST(testLine73),
+ TEST(testLine72),
+ TEST(testLine71),
+ TEST(testLine70),
+ TEST(testLine69),
+ TEST(testLine68h),
+ TEST(testLine68g),
+ TEST(testLine68f),
+ TEST(testLine68e),
+ TEST(testLine68d),
+ TEST(testLine68c),
+ TEST(testLine68b),
+ TEST(testLine68a),
+ TEST(testLine67),
+ TEST(testLine66),
+ TEST(testLine65),
+ TEST(testLine64),
+ TEST(testLine63),
+ TEST(testLine62),
+ TEST(testLine61),
+ TEST(testLine60),
+ TEST(testLine59),
+ TEST(testLine58),
+ TEST(testLine57),
+ TEST(testLine56),
+ TEST(testLine55),
+ TEST(testLine54),
+ TEST(testLine53),
+ TEST(testLine52),
+ TEST(testLine51),
+ TEST(testLine50),
+ TEST(testLine49),
+ TEST(testLine48),
+ TEST(testLine47),
+ TEST(testLine46),
+ TEST(testLine45),
+ TEST(testLine44),
+ TEST(testLine43),
+ TEST(testLine42),
+ TEST(testLine41),
+ TEST(testLine40),
+ TEST(testLine38),
+ TEST(testLine37),
+ TEST(testLine36),
+ TEST(testLine35),
+ TEST(testLine34),
+ TEST(testLine33),
+ TEST(testLine32),
+ TEST(testLine31),
+ TEST(testLine30),
+ TEST(testLine29),
+ TEST(testLine28),
+ TEST(testLine27),
+ TEST(testLine26),
+ TEST(testLine25),
+ TEST(testLine24a),
+ TEST(testLine24),
+ TEST(testLine23),
+ TEST(testLine22),
+ TEST(testLine21),
+ TEST(testLine20),
+ TEST(testLine19),
+ TEST(testLine18),
+ TEST(testLine17),
+ TEST(testLine16),
+ TEST(testLine15),
+ TEST(testLine14),
+ TEST(testLine13),
+ TEST(testLine12),
+ TEST(testLine11),
+ TEST(testLine10a),
+ TEST(testLine10),
+ TEST(testLine9),
+ TEST(testLine8),
+ TEST(testLine7b),
+ TEST(testLine7a),
+ TEST(testLine7),
+ TEST(testLine6),
+ TEST(testLine5),
+ TEST(testLine4),
+ TEST(testLine3b),
+ TEST(testLine3a),
+ TEST(testLine3),
+ TEST(testLine2),
+ TEST(testLine1),
+};
+
+static const size_t testCount = sizeof(tests) / sizeof(tests[0]);
+
+static TestDesc subTests[] = {
+ TEST(testLine3),
+ TEST(testLine2),
+ TEST(testLine1),
+};
+
+static const size_t subTestCount = sizeof(subTests) / sizeof(subTests[0]);
+
+static void (*firstSubTest)(skiatest::Reporter* ) = 0;
+
+static bool runSubTestsFirst = false;
+static bool runReverse = false;
+static void (*stopTest)(skiatest::Reporter* ) = 0;
+
+static void SimplifyTest(skiatest::Reporter* reporter) {
+#ifdef SK_DEBUG
+ gDebugMaxWindSum = 4;
+ gDebugMaxWindValue = 4;
+#endif
+ if (runSubTestsFirst) {
+ RunTestSet(reporter, subTests, subTestCount, firstSubTest, stopTest, runReverse);
+ }
+ RunTestSet(reporter, tests, testCount, firstTest, stopTest, runReverse);
+ if (!runSubTestsFirst) {
+ RunTestSet(reporter, subTests, subTestCount, firstSubTest, stopTest, runReverse);
+ }
+#ifdef SK_DEBUG
+ gDebugMaxWindSum = SK_MaxS32;
+ gDebugMaxWindValue = SK_MaxS32;
+#endif
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("PathOpsSimplifyTest", PathOpsSimplifyClass, SimplifyTest)
diff --git a/tests/PathOpsSimplifyTrianglesThreadedTest.cpp b/tests/PathOpsSimplifyTrianglesThreadedTest.cpp
new file mode 100755
index 0000000000..567713ce6e
--- /dev/null
+++ b/tests/PathOpsSimplifyTrianglesThreadedTest.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "PathOpsExtendedTest.h"
+
+static THREAD_TYPE testSimplifyTrianglesMain(void* data) {
+ SkASSERT(data);
+ State4& state = *(State4*) data;
+ char pathStr[1024];
+ sk_bzero(pathStr, sizeof(pathStr));
+ do {
+ int ax = state.a & 0x03;
+ int ay = state.a >> 2;
+ int bx = state.b & 0x03;
+ int by = state.b >> 2;
+ int cx = state.c & 0x03;
+ int cy = state.c >> 2;
+ for (int d = 0; d < 15; ++d) {
+ int dx = d & 0x03;
+ int dy = d >> 2;
+ for (int e = d + 1; e < 16; ++e) {
+ int ex = e & 0x03;
+ int ey = e >> 2;
+ for (int f = d + 1; f < 16; ++f) {
+ if (e == f) {
+ continue;
+ }
+ int fx = f & 0x03;
+ int fy = f >> 2;
+ if ((ex - dx) * (fy - dy) == (ey - dy) * (fx - dx)) {
+ continue;
+ }
+ SkPath path, out;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(SkIntToScalar(ax), SkIntToScalar(ay));
+ path.lineTo(SkIntToScalar(bx), SkIntToScalar(by));
+ path.lineTo(SkIntToScalar(cx), SkIntToScalar(cy));
+ path.close();
+ path.moveTo(SkIntToScalar(dx), SkIntToScalar(dy));
+ path.lineTo(SkIntToScalar(ex), SkIntToScalar(ey));
+ path.lineTo(SkIntToScalar(fx), SkIntToScalar(fy));
+ path.close();
+ if (1) {
+ char* str = pathStr;
+ str += sprintf(str, " path.moveTo(%d, %d);\n", ax, ay);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", bx, by);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", cx, cy);
+ str += sprintf(str, " path.close();\n");
+ str += sprintf(str, " path.moveTo(%d, %d);\n", dx, dy);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", ex, ey);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", fx, fy);
+ str += sprintf(str, " path.close();\n");
+ }
+ outputProgress(state, pathStr, SkPath::kWinding_FillType);
+ testSimplify(path, false, out, state, pathStr);
+ state.testsRun++;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ outputProgress(state, pathStr, SkPath::kEvenOdd_FillType);
+ testSimplify(path, true, out, state, pathStr);
+ state.testsRun++;
+ }
+ }
+ }
+ } while (runNextTestSet(state));
+ THREAD_RETURN
+}
+
+static void TestSimplifyTrianglesThreaded(skiatest::Reporter* reporter) {
+ int testsRun = 0;
+ if (gShowTestProgress) SkDebugf("%s\n", __FUNCTION__);
+#ifdef SK_DEBUG
+ gDebugMaxWindSum = 2;
+ gDebugMaxWindValue = 2;
+#endif
+ const char testStr[] = "testTriangles";
+ initializeTests(reporter, testStr, sizeof(testStr));
+ for (int a = 0; a < 15; ++a) {
+ int ax = a & 0x03;
+ int ay = a >> 2;
+ for (int b = a + 1; b < 16; ++b) {
+ int bx = b & 0x03;
+ int by = b >> 2;
+ for (int c = a + 1; c < 16; ++c) {
+ if (b == c) {
+ continue;
+ }
+ int cx = c & 0x03;
+ int cy = c >> 2;
+ if ((bx - ax) * (cy - ay) == (by - ay) * (cx - ax)) {
+ continue;
+ }
+ testsRun += dispatchTest4(testSimplifyTrianglesMain, a, b, c, 0);
+ }
+ if (!gAllowExtendedTest) goto finish;
+ if (gShowTestProgress) SkDebugf(".");
+ }
+ if (gShowTestProgress) SkDebugf("\n%d", a);
+ }
+finish:
+ testsRun += waitForCompletion();
+ if (gShowTestProgress) SkDebugf("%s tests=%d\n", __FUNCTION__, testsRun);
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS("SimplifyTrianglesThreaded", SimplifyTrianglesThreadedTestClass, \
+ TestSimplifyTrianglesThreaded)
diff --git a/tests/PathOpsTestCommon.cpp b/tests/PathOpsTestCommon.cpp
new file mode 100644
index 0000000000..cbea715b66
--- /dev/null
+++ b/tests/PathOpsTestCommon.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "PathOpsTestCommon.h"
+#include "SkPathOpsCubic.h"
+
+void CubicToQuads(const SkDCubic& cubic, double precision, SkTDArray<SkDQuad>& quads) {
+ SkTDArray<double> ts;
+ cubic.toQuadraticTs(precision, &ts);
+ if (ts.count() <= 1) {
+ SkDQuad quad = cubic.toQuad();
+ *quads.append() = quad;
+ return;
+ }
+ double tStart = 0;
+ for (int i1 = 0; i1 <= ts.count(); ++i1) {
+ const double tEnd = i1 < ts.count() ? ts[i1] : 1;
+ SkDCubic part = cubic.subDivide(tStart, tEnd);
+ SkDQuad quad = part.toQuad();
+ *quads.append() = quad;
+ tStart = tEnd;
+ }
+}
+
diff --git a/tests/PathOpsTestCommon.h b/tests/PathOpsTestCommon.h
new file mode 100644
index 0000000000..e4ab829577
--- /dev/null
+++ b/tests/PathOpsTestCommon.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef PathOpsTestCommon_DEFINED
+#define PathOpsTestCommon_DEFINED
+
+#include "SkPathOpsQuad.h"
+#include "SkTDArray.h"
+
+void CubicToQuads(const SkDCubic& cubic, double precision, SkTDArray<SkDQuad>& quads);
+
+#endif