diff options
Diffstat (limited to 'tests/SubsetPath.cpp')
-rw-r--r-- | tests/SubsetPath.cpp | 240 |
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; +} |