/src/skia/modules/pathops/src/SkIntersections.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2012 Google Inc. |
3 | | * |
4 | | * Use of this source code is governed by a BSD-style license that can be |
5 | | * found in the LICENSE file. |
6 | | */ |
7 | | |
8 | | #include "modules/pathops/src/SkIntersections.h" |
9 | | |
10 | | #include <cstring> |
11 | | |
12 | | int SkIntersections::closestTo(double rangeStart, double rangeEnd, const SkDPoint& testPt, |
13 | 1.74M | double* closestDist) const { |
14 | 1.74M | int closest = -1; |
15 | 1.74M | *closestDist = SK_ScalarMax; |
16 | 3.34M | for (int index = 0; index < fUsed; ++index) { |
17 | 1.59M | if (!between(rangeStart, fT[0][index], rangeEnd)) { |
18 | 606k | continue; |
19 | 606k | } |
20 | 989k | const SkDPoint& iPt = fPt[index]; |
21 | 989k | double dist = testPt.distanceSquared(iPt); |
22 | 989k | if (*closestDist > dist) { |
23 | 850k | *closestDist = dist; |
24 | 850k | closest = index; |
25 | 850k | } |
26 | 989k | } |
27 | 1.74M | return closest; |
28 | 1.74M | } |
29 | | |
30 | 4.76M | void SkIntersections::flip() { |
31 | 9.00M | for (int index = 0; index < fUsed; ++index) { |
32 | 4.24M | fT[1][index] = 1 - fT[1][index]; |
33 | 4.24M | } |
34 | 4.76M | } |
35 | | |
36 | 217M | int SkIntersections::insert(double one, double two, const SkDPoint& pt) { |
37 | 217M | if (fIsCoincident[0] == 3 && between(fT[0][0], one, fT[0][1])) { |
38 | | // For now, don't allow a mix of coincident and non-coincident intersections |
39 | 2.75M | return -1; |
40 | 2.75M | } |
41 | 214M | SkASSERT(fUsed <= 1 || fT[0][0] <= fT[0][1]); |
42 | 214M | int index; |
43 | 237M | for (index = 0; index < fUsed; ++index) { |
44 | 114M | double oldOne = fT[0][index]; |
45 | 114M | double oldTwo = fT[1][index]; |
46 | 114M | if (one == oldOne && two == oldTwo) { |
47 | 89.3M | return -1; |
48 | 89.3M | } |
49 | 25.3M | if (more_roughly_equal(oldOne, one) && more_roughly_equal(oldTwo, two)) { |
50 | 2.11M | if ((!precisely_zero(one) || precisely_zero(oldOne)) |
51 | 2.11M | && (!precisely_equal(one, 1) || precisely_equal(oldOne, 1)) |
52 | 2.11M | && (!precisely_zero(two) || precisely_zero(oldTwo)) |
53 | 2.11M | && (!precisely_equal(two, 1) || precisely_equal(oldTwo, 1))) { |
54 | 938k | return -1; |
55 | 938k | } |
56 | 1.18M | SkASSERT(one >= 0 && one <= 1); |
57 | 1.18M | SkASSERT(two >= 0 && two <= 1); |
58 | | // remove this and reinsert below in case replacing would make list unsorted |
59 | 1.18M | int remaining = fUsed - index - 1; |
60 | 1.18M | memmove(&fPt[index], &fPt[index + 1], sizeof(fPt[0]) * remaining); |
61 | 1.18M | memmove(&fT[0][index], &fT[0][index + 1], sizeof(fT[0][0]) * remaining); |
62 | 1.18M | memmove(&fT[1][index], &fT[1][index + 1], sizeof(fT[1][0]) * remaining); |
63 | 1.18M | int clearMask = ~((1 << index) - 1); |
64 | 1.18M | fIsCoincident[0] -= (fIsCoincident[0] >> 1) & clearMask; |
65 | 1.18M | fIsCoincident[1] -= (fIsCoincident[1] >> 1) & clearMask; |
66 | 1.18M | --fUsed; |
67 | 1.18M | break; |
68 | 2.11M | } |
69 | | #if ONE_OFF_DEBUG |
70 | | if (pt.roughlyEqual(fPt[index])) { |
71 | | SkDebugf("%s t=%1.9g pts roughly equal\n", __FUNCTION__, one); |
72 | | } |
73 | | #endif |
74 | 25.3M | } |
75 | 135M | for (index = 0; index < fUsed; ++index) { |
76 | 16.8M | if (fT[0][index] > one) { |
77 | 5.27M | break; |
78 | 5.27M | } |
79 | 16.8M | } |
80 | 124M | if (fUsed >= fMax) { |
81 | 4.93k | SkOPASSERT(0); // FIXME : this error, if it is to be handled at runtime in release, must |
82 | | // be propagated all the way back down to the caller, and return failure. |
83 | 4.93k | fUsed = 0; |
84 | 4.93k | return 0; |
85 | 4.93k | } |
86 | 124M | int remaining = fUsed - index; |
87 | 124M | if (remaining > 0) { |
88 | 5.26M | memmove(&fPt[index + 1], &fPt[index], sizeof(fPt[0]) * remaining); |
89 | 5.26M | memmove(&fT[0][index + 1], &fT[0][index], sizeof(fT[0][0]) * remaining); |
90 | 5.26M | memmove(&fT[1][index + 1], &fT[1][index], sizeof(fT[1][0]) * remaining); |
91 | 5.26M | int clearMask = ~((1 << index) - 1); |
92 | 5.26M | fIsCoincident[0] += fIsCoincident[0] & clearMask; |
93 | 5.26M | fIsCoincident[1] += fIsCoincident[1] & clearMask; |
94 | 5.26M | } |
95 | 124M | fPt[index] = pt; |
96 | 124M | if (one < 0 || one > 1) { |
97 | 0 | return -1; |
98 | 0 | } |
99 | 124M | if (two < 0 || two > 1) { |
100 | 0 | return -1; |
101 | 0 | } |
102 | 124M | fT[0][index] = one; |
103 | 124M | fT[1][index] = two; |
104 | 124M | ++fUsed; |
105 | 124M | SkASSERT(fUsed <= std::size(fPt)); |
106 | 124M | return index; |
107 | 124M | } SkIntersections::insert(double, double, SkDPoint const&) Line | Count | Source | 36 | 217M | int SkIntersections::insert(double one, double two, const SkDPoint& pt) { | 37 | 217M | if (fIsCoincident[0] == 3 && between(fT[0][0], one, fT[0][1])) { | 38 | | // For now, don't allow a mix of coincident and non-coincident intersections | 39 | 2.75M | return -1; | 40 | 2.75M | } | 41 | 214M | SkASSERT(fUsed <= 1 || fT[0][0] <= fT[0][1]); | 42 | 214M | int index; | 43 | 237M | for (index = 0; index < fUsed; ++index) { | 44 | 114M | double oldOne = fT[0][index]; | 45 | 114M | double oldTwo = fT[1][index]; | 46 | 114M | if (one == oldOne && two == oldTwo) { | 47 | 89.3M | return -1; | 48 | 89.3M | } | 49 | 25.3M | if (more_roughly_equal(oldOne, one) && more_roughly_equal(oldTwo, two)) { | 50 | 2.11M | if ((!precisely_zero(one) || precisely_zero(oldOne)) | 51 | 2.11M | && (!precisely_equal(one, 1) || precisely_equal(oldOne, 1)) | 52 | 2.11M | && (!precisely_zero(two) || precisely_zero(oldTwo)) | 53 | 2.11M | && (!precisely_equal(two, 1) || precisely_equal(oldTwo, 1))) { | 54 | 938k | return -1; | 55 | 938k | } | 56 | 1.18M | SkASSERT(one >= 0 && one <= 1); | 57 | 1.18M | SkASSERT(two >= 0 && two <= 1); | 58 | | // remove this and reinsert below in case replacing would make list unsorted | 59 | 1.18M | int remaining = fUsed - index - 1; | 60 | 1.18M | memmove(&fPt[index], &fPt[index + 1], sizeof(fPt[0]) * remaining); | 61 | 1.18M | memmove(&fT[0][index], &fT[0][index + 1], sizeof(fT[0][0]) * remaining); | 62 | 1.18M | memmove(&fT[1][index], &fT[1][index + 1], sizeof(fT[1][0]) * remaining); | 63 | 1.18M | int clearMask = ~((1 << index) - 1); | 64 | 1.18M | fIsCoincident[0] -= (fIsCoincident[0] >> 1) & clearMask; | 65 | 1.18M | fIsCoincident[1] -= (fIsCoincident[1] >> 1) & clearMask; | 66 | 1.18M | --fUsed; | 67 | 1.18M | break; | 68 | 2.11M | } | 69 | | #if ONE_OFF_DEBUG | 70 | | if (pt.roughlyEqual(fPt[index])) { | 71 | | SkDebugf("%s t=%1.9g pts roughly equal\n", __FUNCTION__, one); | 72 | | } | 73 | | #endif | 74 | 25.3M | } | 75 | 135M | for (index = 0; index < fUsed; ++index) { | 76 | 16.8M | if (fT[0][index] > one) { | 77 | 5.27M | break; | 78 | 5.27M | } | 79 | 16.8M | } | 80 | 124M | if (fUsed >= fMax) { | 81 | 4.93k | SkOPASSERT(0); // FIXME : this error, if it is to be handled at runtime in release, must | 82 | | // be propagated all the way back down to the caller, and return failure. | 83 | 4.93k | fUsed = 0; | 84 | 4.93k | return 0; | 85 | 4.93k | } | 86 | 124M | int remaining = fUsed - index; | 87 | 124M | if (remaining > 0) { | 88 | 5.26M | memmove(&fPt[index + 1], &fPt[index], sizeof(fPt[0]) * remaining); | 89 | 5.26M | memmove(&fT[0][index + 1], &fT[0][index], sizeof(fT[0][0]) * remaining); | 90 | 5.26M | memmove(&fT[1][index + 1], &fT[1][index], sizeof(fT[1][0]) * remaining); | 91 | 5.26M | int clearMask = ~((1 << index) - 1); | 92 | 5.26M | fIsCoincident[0] += fIsCoincident[0] & clearMask; | 93 | 5.26M | fIsCoincident[1] += fIsCoincident[1] & clearMask; | 94 | 5.26M | } | 95 | 124M | fPt[index] = pt; | 96 | 124M | if (one < 0 || one > 1) { | 97 | 0 | return -1; | 98 | 0 | } | 99 | 124M | if (two < 0 || two > 1) { | 100 | 0 | return -1; | 101 | 0 | } | 102 | 124M | fT[0][index] = one; | 103 | 124M | fT[1][index] = two; | 104 | 124M | ++fUsed; | 105 | 124M | SkASSERT(fUsed <= std::size(fPt)); | 106 | 124M | return index; | 107 | 124M | } |
Unexecuted instantiation: SkIntersections::insert(double, double, SkDPoint const&) |
108 | | |
109 | 441k | void SkIntersections::insertNear(double one, double two, const SkDPoint& pt1, const SkDPoint& pt2) { |
110 | 441k | SkASSERT(one == 0 || one == 1); |
111 | 441k | SkASSERT(two == 0 || two == 1); |
112 | 441k | SkASSERT(pt1 != pt2); |
113 | 441k | fNearlySame[one ? 1 : 0] = true; |
114 | 441k | (void) insert(one, two, pt1); |
115 | 441k | fPt2[one ? 1 : 0] = pt2; |
116 | 441k | } |
117 | | |
118 | 4.05M | int SkIntersections::insertCoincident(double one, double two, const SkDPoint& pt) { |
119 | 4.05M | int index = insertSwap(one, two, pt); |
120 | 4.05M | if (index >= 0) { |
121 | 3.97M | setCoincident(index); |
122 | 3.97M | } |
123 | 4.05M | return index; |
124 | 4.05M | } |
125 | | |
126 | 8.52M | void SkIntersections::setCoincident(int index) { |
127 | 8.52M | SkASSERT(index >= 0); |
128 | 8.52M | int bit = 1 << index; |
129 | 8.52M | fIsCoincident[0] |= bit; |
130 | 8.52M | fIsCoincident[1] |= bit; |
131 | 8.52M | } |
132 | | |
133 | | void SkIntersections::merge(const SkIntersections& a, int aIndex, const SkIntersections& b, |
134 | 3.61M | int bIndex) { |
135 | 3.61M | this->reset(); |
136 | 3.61M | fT[0][0] = a.fT[0][aIndex]; |
137 | 3.61M | fT[1][0] = b.fT[0][bIndex]; |
138 | 3.61M | fPt[0] = a.fPt[aIndex]; |
139 | 3.61M | fPt2[0] = b.fPt[bIndex]; |
140 | 3.61M | fUsed = 1; |
141 | 3.61M | } |
142 | | |
143 | 8.22M | int SkIntersections::mostOutside(double rangeStart, double rangeEnd, const SkDPoint& origin) const { |
144 | 8.22M | int result = -1; |
145 | 20.0M | for (int index = 0; index < fUsed; ++index) { |
146 | 11.7M | if (!between(rangeStart, fT[0][index], rangeEnd)) { |
147 | 3.04M | continue; |
148 | 3.04M | } |
149 | 8.74M | if (result < 0) { |
150 | 7.44M | result = index; |
151 | 7.44M | continue; |
152 | 7.44M | } |
153 | 1.29M | SkDVector best = fPt[result] - origin; |
154 | 1.29M | SkDVector test = fPt[index] - origin; |
155 | 1.29M | if (test.crossCheck(best) < 0) { |
156 | 49.7k | result = index; |
157 | 49.7k | } |
158 | 1.29M | } |
159 | 8.22M | return result; |
160 | 8.22M | } |
161 | | |
162 | 1.75M | void SkIntersections::removeOne(int index) { |
163 | 1.75M | int remaining = --fUsed - index; |
164 | 1.75M | if (remaining <= 0) { |
165 | 726k | return; |
166 | 726k | } |
167 | 1.03M | memmove(&fPt[index], &fPt[index + 1], sizeof(fPt[0]) * remaining); |
168 | 1.03M | memmove(&fT[0][index], &fT[0][index + 1], sizeof(fT[0][0]) * remaining); |
169 | 1.03M | memmove(&fT[1][index], &fT[1][index + 1], sizeof(fT[1][0]) * remaining); |
170 | | // SkASSERT(fIsCoincident[0] == 0); |
171 | 1.03M | int coBit = fIsCoincident[0] & (1 << index); |
172 | 1.03M | fIsCoincident[0] -= ((fIsCoincident[0] >> 1) & ~((1 << index) - 1)) + coBit; |
173 | 1.03M | SkASSERT(!(coBit ^ (fIsCoincident[1] & (1 << index)))); |
174 | 1.03M | fIsCoincident[1] -= ((fIsCoincident[1] >> 1) & ~((1 << index) - 1)) + coBit; |
175 | 1.03M | } |