aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/SubsetPath.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/SubsetPath.cpp')
-rw-r--r--tests/SubsetPath.cpp240
1 files changed, 240 insertions, 0 deletions
diff --git a/tests/SubsetPath.cpp b/tests/SubsetPath.cpp
new file mode 100644
index 0000000000..e67df1210b
--- /dev/null
+++ b/tests/SubsetPath.cpp
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SubsetPath.h"
+
+SubsetPath::SubsetPath(const SkPath& path)
+ : fPath(path)
+ , fSubset(1) {
+}
+
+int SubsetPath::range(int* end) const {
+ int leadingZero = SkCLZ(fSubset);
+ int parts = 1 << (31 - leadingZero);
+ int partIndex = fSubset - parts;
+ SkASSERT(partIndex >= 0);
+ int count = fSelected.count();
+ int start = count * partIndex / parts;
+ *end = count * (partIndex + 1) / parts;
+ return start;
+}
+
+bool SubsetPath::subset(bool testFailed, SkPath* sub) {
+ int start, end;
+ if (!testFailed) {
+ start = range(&end);
+ for (; start < end; ++start) {
+ fSelected[start] = true;
+ }
+ }
+ do {
+ do {
+ ++fSubset;
+ start = range(&end);
+ // SkDebugf("%d s=%d e=%d t=%d\n", fSubset, start, end, fTries);
+ if (end - start > 1) {
+ fTries = fSelected.count();
+ } else if (end - start == 1) {
+ if (--fTries <= 0) {
+ return false;
+ }
+ }
+ } while (start == end);
+ } while (!fSelected[start]);
+ for (; start < end; ++start) {
+ fSelected[start] = false;
+ }
+#if 1
+ SkDebugf("selected: ");
+ for (int index = 0; index < fSelected.count(); ++index) {
+ SkDebugf("%c", fSelected[index] ? 'x' : '-');
+ }
+#endif
+ *sub = getSubsetPath();
+ return true;
+}
+
+SubsetContours::SubsetContours(const SkPath& path)
+ : SubsetPath(path) {
+ SkPath::RawIter iter(fPath);
+ uint8_t verb;
+ SkPoint pts[4];
+ bool foundCurve = false;
+ int contourCount = 0;
+ while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
+ switch (verb) {
+ case SkPath::kMove_Verb:
+ break;
+ case SkPath::kLine_Verb:
+ case SkPath::kQuad_Verb:
+ case SkPath::kConic_Verb:
+ case SkPath::kCubic_Verb:
+ foundCurve = true;
+ break;
+ case SkPath::kClose_Verb:
+ ++contourCount;
+ foundCurve = false;
+ break;
+ default:
+ SkDEBUGFAIL("bad verb");
+ return;
+ }
+ }
+ contourCount += foundCurve;
+ for (int index = 0; index < contourCount; ++index) {
+ *fSelected.append() = true;
+ }
+ fTries = contourCount;
+}
+
+SkPath SubsetContours::getSubsetPath() const {
+ SkPath result;
+ result.setFillType(fPath.getFillType());
+ if (!fSelected.count()) {
+ return result;
+ }
+ SkPath::RawIter iter(fPath);
+ uint8_t verb;
+ SkPoint pts[4];
+ int contourCount = 0;
+ bool enabled = fSelected[0];
+ bool addMoveTo = true;
+ while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
+ if (enabled && addMoveTo) {
+ result.moveTo(pts[0]);
+ addMoveTo = false;
+ }
+ switch (verb) {
+ case SkPath::kMove_Verb:
+ break;
+ case SkPath::kLine_Verb:
+ if (enabled) {
+ result.lineTo(pts[1]);
+ }
+ break;
+ case SkPath::kQuad_Verb:
+ if (enabled) {
+ result.quadTo(pts[1], pts[2]);
+ }
+ break;
+ case SkPath::kConic_Verb:
+ if (enabled) {
+ result.conicTo(pts[1], pts[2], iter.conicWeight());
+ }
+ break;
+ case SkPath::kCubic_Verb:
+ if (enabled) {
+ result.cubicTo(pts[1], pts[2], pts[3]);
+ }
+ break;
+ case SkPath::kClose_Verb:
+ if (enabled) {
+ result.close();
+ }
+ if (++contourCount >= fSelected.count()) {
+ break;
+ }
+ enabled = fSelected[contourCount];
+ addMoveTo = true;
+ continue;
+ default:
+ SkDEBUGFAIL("bad verb");
+ return result;
+ }
+ }
+ return result;
+}
+
+SubsetVerbs::SubsetVerbs(const SkPath& path)
+ : SubsetPath(path) {
+ SkPath::RawIter iter(fPath);
+ uint8_t verb;
+ SkPoint pts[4];
+ int verbCount = 0;
+ while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
+ switch (verb) {
+ case SkPath::kMove_Verb:
+ break;
+ case SkPath::kLine_Verb:
+ case SkPath::kQuad_Verb:
+ case SkPath::kConic_Verb:
+ case SkPath::kCubic_Verb:
+ ++verbCount;
+ break;
+ case SkPath::kClose_Verb:
+ break;
+ default:
+ SkDEBUGFAIL("bad verb");
+ return;
+ }
+ }
+ for (int index = 0; index < verbCount; ++index) {
+ *fSelected.append() = true;
+ }
+ fTries = verbCount;
+}
+
+SkPath SubsetVerbs::getSubsetPath() const {
+ SkPath result;
+ result.setFillType(fPath.getFillType());
+ if (!fSelected.count()) {
+ return result;
+ }
+ SkPath::RawIter iter(fPath);
+ uint8_t verb;
+ SkPoint pts[4];
+ int verbIndex = 0;
+ bool addMoveTo = true;
+ bool addLineTo = false;
+ while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
+ bool enabled = SkPath::kLine_Verb <= verb && verb <= SkPath::kCubic_Verb
+ ? fSelected[verbIndex++] : false;
+ if (enabled) {
+ if (addMoveTo) {
+ result.moveTo(pts[0]);
+ addMoveTo = false;
+ } else if (addLineTo) {
+ result.lineTo(pts[0]);
+ addLineTo = false;
+ }
+ }
+ switch (verb) {
+ case SkPath::kMove_Verb:
+ break;
+ case SkPath::kLine_Verb:
+ if (enabled) {
+ result.lineTo(pts[1]);
+ }
+ break;
+ case SkPath::kQuad_Verb:
+ if (enabled) {
+ result.quadTo(pts[1], pts[2]);
+ }
+ break;
+ case SkPath::kConic_Verb:
+ if (enabled) {
+ result.conicTo(pts[1], pts[2], iter.conicWeight());
+ }
+ break;
+ case SkPath::kCubic_Verb:
+ if (enabled) {
+ result.cubicTo(pts[1], pts[2], pts[3]);
+ }
+ break;
+ case SkPath::kClose_Verb:
+ result.close();
+ addMoveTo = true;
+ addLineTo = false;
+ continue;
+ default:
+ SkDEBUGFAIL("bad verb");
+ return result;
+ }
+ addLineTo = !enabled;
+ }
+ return result;
+}