xref: /third_party/skia/tests/SubsetPath.cpp (revision cb93a386)
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