1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2015 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/core/SkMathPriv.h" 9cb93a386Sopenharmony_ci#include "src/core/SkPathPriv.h" 10cb93a386Sopenharmony_ci#include "tests/SubsetPath.h" 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_ciSubsetPath::SubsetPath(const SkPath& path) 13cb93a386Sopenharmony_ci : fPath(path) 14cb93a386Sopenharmony_ci , fSubset(1) { 15cb93a386Sopenharmony_ci} 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_ciint SubsetPath::range(int* end) const { 18cb93a386Sopenharmony_ci int leadingZero = SkCLZ(fSubset); 19cb93a386Sopenharmony_ci int parts = 1 << (31 - leadingZero); 20cb93a386Sopenharmony_ci int partIndex = fSubset - parts; 21cb93a386Sopenharmony_ci SkASSERT(partIndex >= 0); 22cb93a386Sopenharmony_ci int count = fSelected.count(); 23cb93a386Sopenharmony_ci int start = count * partIndex / parts; 24cb93a386Sopenharmony_ci *end = count * (partIndex + 1) / parts; 25cb93a386Sopenharmony_ci return start; 26cb93a386Sopenharmony_ci} 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_cibool SubsetPath::subset(bool testFailed, SkPath* sub) { 29cb93a386Sopenharmony_ci int start, end; 30cb93a386Sopenharmony_ci if (!testFailed) { 31cb93a386Sopenharmony_ci start = range(&end); 32cb93a386Sopenharmony_ci for (; start < end; ++start) { 33cb93a386Sopenharmony_ci fSelected[start] = true; 34cb93a386Sopenharmony_ci } 35cb93a386Sopenharmony_ci } 36cb93a386Sopenharmony_ci do { 37cb93a386Sopenharmony_ci do { 38cb93a386Sopenharmony_ci ++fSubset; 39cb93a386Sopenharmony_ci start = range(&end); 40cb93a386Sopenharmony_ci // SkDebugf("%d s=%d e=%d t=%d\n", fSubset, start, end, fTries); 41cb93a386Sopenharmony_ci if (end - start > 1) { 42cb93a386Sopenharmony_ci fTries = fSelected.count(); 43cb93a386Sopenharmony_ci } else if (end - start == 1) { 44cb93a386Sopenharmony_ci if (--fTries <= 0) { 45cb93a386Sopenharmony_ci return false; 46cb93a386Sopenharmony_ci } 47cb93a386Sopenharmony_ci } 48cb93a386Sopenharmony_ci } while (start == end); 49cb93a386Sopenharmony_ci } while (!fSelected[start]); 50cb93a386Sopenharmony_ci for (; start < end; ++start) { 51cb93a386Sopenharmony_ci fSelected[start] = false; 52cb93a386Sopenharmony_ci } 53cb93a386Sopenharmony_ci#if 1 54cb93a386Sopenharmony_ci SkDebugf("selected: "); 55cb93a386Sopenharmony_ci for (int index = 0; index < fSelected.count(); ++index) { 56cb93a386Sopenharmony_ci SkDebugf("%c", fSelected[index] ? 'x' : '-'); 57cb93a386Sopenharmony_ci } 58cb93a386Sopenharmony_ci#endif 59cb93a386Sopenharmony_ci *sub = getSubsetPath(); 60cb93a386Sopenharmony_ci return true; 61cb93a386Sopenharmony_ci} 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_ciSubsetContours::SubsetContours(const SkPath& path) 64cb93a386Sopenharmony_ci : SubsetPath(path) { 65cb93a386Sopenharmony_ci bool foundCurve = false; 66cb93a386Sopenharmony_ci int contourCount = 0; 67cb93a386Sopenharmony_ci for (auto [verb, pts, w] : SkPathPriv::Iterate(fPath)) { 68cb93a386Sopenharmony_ci switch (verb) { 69cb93a386Sopenharmony_ci case SkPathVerb::kMove: 70cb93a386Sopenharmony_ci break; 71cb93a386Sopenharmony_ci case SkPathVerb::kLine: 72cb93a386Sopenharmony_ci case SkPathVerb::kQuad: 73cb93a386Sopenharmony_ci case SkPathVerb::kConic: 74cb93a386Sopenharmony_ci case SkPathVerb::kCubic: 75cb93a386Sopenharmony_ci foundCurve = true; 76cb93a386Sopenharmony_ci break; 77cb93a386Sopenharmony_ci case SkPathVerb::kClose: 78cb93a386Sopenharmony_ci ++contourCount; 79cb93a386Sopenharmony_ci foundCurve = false; 80cb93a386Sopenharmony_ci break; 81cb93a386Sopenharmony_ci default: 82cb93a386Sopenharmony_ci SkDEBUGFAIL("bad verb"); 83cb93a386Sopenharmony_ci return; 84cb93a386Sopenharmony_ci } 85cb93a386Sopenharmony_ci } 86cb93a386Sopenharmony_ci contourCount += foundCurve; 87cb93a386Sopenharmony_ci for (int index = 0; index < contourCount; ++index) { 88cb93a386Sopenharmony_ci *fSelected.append() = true; 89cb93a386Sopenharmony_ci } 90cb93a386Sopenharmony_ci fTries = contourCount; 91cb93a386Sopenharmony_ci} 92cb93a386Sopenharmony_ci 93cb93a386Sopenharmony_ciSkPath SubsetContours::getSubsetPath() const { 94cb93a386Sopenharmony_ci SkPath result; 95cb93a386Sopenharmony_ci result.setFillType(fPath.getFillType()); 96cb93a386Sopenharmony_ci if (!fSelected.count()) { 97cb93a386Sopenharmony_ci return result; 98cb93a386Sopenharmony_ci } 99cb93a386Sopenharmony_ci int contourCount = 0; 100cb93a386Sopenharmony_ci bool enabled = fSelected[0]; 101cb93a386Sopenharmony_ci bool addMoveTo = true; 102cb93a386Sopenharmony_ci for (auto [verb, pts, w] : SkPathPriv::Iterate(fPath)) { 103cb93a386Sopenharmony_ci if (enabled && addMoveTo) { 104cb93a386Sopenharmony_ci result.moveTo(pts[0]); 105cb93a386Sopenharmony_ci addMoveTo = false; 106cb93a386Sopenharmony_ci } 107cb93a386Sopenharmony_ci switch (verb) { 108cb93a386Sopenharmony_ci case SkPathVerb::kMove: 109cb93a386Sopenharmony_ci break; 110cb93a386Sopenharmony_ci case SkPathVerb::kLine: 111cb93a386Sopenharmony_ci if (enabled) { 112cb93a386Sopenharmony_ci result.lineTo(pts[1]); 113cb93a386Sopenharmony_ci } 114cb93a386Sopenharmony_ci break; 115cb93a386Sopenharmony_ci case SkPathVerb::kQuad: 116cb93a386Sopenharmony_ci if (enabled) { 117cb93a386Sopenharmony_ci result.quadTo(pts[1], pts[2]); 118cb93a386Sopenharmony_ci } 119cb93a386Sopenharmony_ci break; 120cb93a386Sopenharmony_ci case SkPathVerb::kConic: 121cb93a386Sopenharmony_ci if (enabled) { 122cb93a386Sopenharmony_ci result.conicTo(pts[1], pts[2], *w); 123cb93a386Sopenharmony_ci } 124cb93a386Sopenharmony_ci break; 125cb93a386Sopenharmony_ci case SkPathVerb::kCubic: 126cb93a386Sopenharmony_ci if (enabled) { 127cb93a386Sopenharmony_ci result.cubicTo(pts[1], pts[2], pts[3]); 128cb93a386Sopenharmony_ci } 129cb93a386Sopenharmony_ci break; 130cb93a386Sopenharmony_ci case SkPathVerb::kClose: 131cb93a386Sopenharmony_ci if (enabled) { 132cb93a386Sopenharmony_ci result.close(); 133cb93a386Sopenharmony_ci } 134cb93a386Sopenharmony_ci if (++contourCount >= fSelected.count()) { 135cb93a386Sopenharmony_ci break; 136cb93a386Sopenharmony_ci } 137cb93a386Sopenharmony_ci enabled = fSelected[contourCount]; 138cb93a386Sopenharmony_ci addMoveTo = true; 139cb93a386Sopenharmony_ci continue; 140cb93a386Sopenharmony_ci default: 141cb93a386Sopenharmony_ci SkDEBUGFAIL("bad verb"); 142cb93a386Sopenharmony_ci return result; 143cb93a386Sopenharmony_ci } 144cb93a386Sopenharmony_ci } 145cb93a386Sopenharmony_ci return result; 146cb93a386Sopenharmony_ci} 147cb93a386Sopenharmony_ci 148cb93a386Sopenharmony_ciSubsetVerbs::SubsetVerbs(const SkPath& path) 149cb93a386Sopenharmony_ci : SubsetPath(path) { 150cb93a386Sopenharmony_ci int verbCount = 0; 151cb93a386Sopenharmony_ci for (auto [verb, pts, w] : SkPathPriv::Iterate(fPath)) { 152cb93a386Sopenharmony_ci switch (verb) { 153cb93a386Sopenharmony_ci case SkPathVerb::kMove: 154cb93a386Sopenharmony_ci break; 155cb93a386Sopenharmony_ci case SkPathVerb::kLine: 156cb93a386Sopenharmony_ci case SkPathVerb::kQuad: 157cb93a386Sopenharmony_ci case SkPathVerb::kConic: 158cb93a386Sopenharmony_ci case SkPathVerb::kCubic: 159cb93a386Sopenharmony_ci ++verbCount; 160cb93a386Sopenharmony_ci break; 161cb93a386Sopenharmony_ci case SkPathVerb::kClose: 162cb93a386Sopenharmony_ci break; 163cb93a386Sopenharmony_ci default: 164cb93a386Sopenharmony_ci SkDEBUGFAIL("bad verb"); 165cb93a386Sopenharmony_ci return; 166cb93a386Sopenharmony_ci } 167cb93a386Sopenharmony_ci } 168cb93a386Sopenharmony_ci for (int index = 0; index < verbCount; ++index) { 169cb93a386Sopenharmony_ci *fSelected.append() = true; 170cb93a386Sopenharmony_ci } 171cb93a386Sopenharmony_ci fTries = verbCount; 172cb93a386Sopenharmony_ci} 173cb93a386Sopenharmony_ci 174cb93a386Sopenharmony_ciSkPath SubsetVerbs::getSubsetPath() const { 175cb93a386Sopenharmony_ci SkPath result; 176cb93a386Sopenharmony_ci result.setFillType(fPath.getFillType()); 177cb93a386Sopenharmony_ci if (!fSelected.count()) { 178cb93a386Sopenharmony_ci return result; 179cb93a386Sopenharmony_ci } 180cb93a386Sopenharmony_ci int verbIndex = 0; 181cb93a386Sopenharmony_ci bool addMoveTo = true; 182cb93a386Sopenharmony_ci bool addLineTo = false; 183cb93a386Sopenharmony_ci for (auto [verb, pts, w] : SkPathPriv::Iterate(fPath)) { 184cb93a386Sopenharmony_ci bool enabled = SkPathVerb::kLine <= verb && verb <= SkPathVerb::kCubic 185cb93a386Sopenharmony_ci ? fSelected[verbIndex++] : false; 186cb93a386Sopenharmony_ci if (enabled) { 187cb93a386Sopenharmony_ci if (addMoveTo) { 188cb93a386Sopenharmony_ci result.moveTo(pts[0]); 189cb93a386Sopenharmony_ci addMoveTo = false; 190cb93a386Sopenharmony_ci } else if (addLineTo) { 191cb93a386Sopenharmony_ci result.lineTo(pts[0]); 192cb93a386Sopenharmony_ci addLineTo = false; 193cb93a386Sopenharmony_ci } 194cb93a386Sopenharmony_ci } 195cb93a386Sopenharmony_ci switch (verb) { 196cb93a386Sopenharmony_ci case SkPathVerb::kMove: 197cb93a386Sopenharmony_ci break; 198cb93a386Sopenharmony_ci case SkPathVerb::kLine: 199cb93a386Sopenharmony_ci if (enabled) { 200cb93a386Sopenharmony_ci result.lineTo(pts[1]); 201cb93a386Sopenharmony_ci } 202cb93a386Sopenharmony_ci break; 203cb93a386Sopenharmony_ci case SkPathVerb::kQuad: 204cb93a386Sopenharmony_ci if (enabled) { 205cb93a386Sopenharmony_ci result.quadTo(pts[1], pts[2]); 206cb93a386Sopenharmony_ci } 207cb93a386Sopenharmony_ci break; 208cb93a386Sopenharmony_ci case SkPathVerb::kConic: 209cb93a386Sopenharmony_ci if (enabled) { 210cb93a386Sopenharmony_ci result.conicTo(pts[1], pts[2], *w); 211cb93a386Sopenharmony_ci } 212cb93a386Sopenharmony_ci break; 213cb93a386Sopenharmony_ci case SkPathVerb::kCubic: 214cb93a386Sopenharmony_ci if (enabled) { 215cb93a386Sopenharmony_ci result.cubicTo(pts[1], pts[2], pts[3]); 216cb93a386Sopenharmony_ci } 217cb93a386Sopenharmony_ci break; 218cb93a386Sopenharmony_ci case SkPathVerb::kClose: 219cb93a386Sopenharmony_ci result.close(); 220cb93a386Sopenharmony_ci addMoveTo = true; 221cb93a386Sopenharmony_ci addLineTo = false; 222cb93a386Sopenharmony_ci continue; 223cb93a386Sopenharmony_ci default: 224cb93a386Sopenharmony_ci SkDEBUGFAIL("bad verb"); 225cb93a386Sopenharmony_ci return result; 226cb93a386Sopenharmony_ci } 227cb93a386Sopenharmony_ci addLineTo = !enabled; 228cb93a386Sopenharmony_ci } 229cb93a386Sopenharmony_ci return result; 230cb93a386Sopenharmony_ci} 231