LMMS
Loading...
Searching...
No Matches
juce_PathIterator.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce
27{
28
29#if JUCE_MSVC && JUCE_DEBUG
30 #pragma optimize ("t", on)
31#endif
32
33//==============================================================================
35 const AffineTransform& t,
36 float tolerance)
37 : x2 (0),
38 y2 (0),
40 subPathIndex (-1),
41 path (pathToUse),
42 transform (t),
44 toleranceSquared (tolerance * tolerance),
45 isIdentityTransform (t.isIdentity())
46{
48}
49
53
59
61{
62 x1 = x2;
63 y1 = y2;
64
65 float x3 = 0;
66 float y3 = 0;
67 float x4 = 0;
68 float y4 = 0;
69
70 for (;;)
71 {
72 float type;
73
74 if (stackPos == stackBase.get())
75 {
76 if (source == path.data.end())
77 return false;
78
79 type = *source++;
80
82 {
83 x2 = *source++;
84 y2 = *source++;
85
87 {
88 x3 = *source++;
89 y3 = *source++;
90
92 transform.transformPoints (x2, y2, x3, y3);
93 }
95 {
96 x3 = *source++;
97 y3 = *source++;
98 x4 = *source++;
99 y4 = *source++;
100
102 transform.transformPoints (x2, y2, x3, y3, x4, y4);
103 }
104 else
105 {
107 transform.transformPoint (x2, y2);
108 }
109 }
110 }
111 else
112 {
113 type = *--stackPos;
114
116 {
117 x2 = *--stackPos;
118 y2 = *--stackPos;
119
121 {
122 x3 = *--stackPos;
123 y3 = *--stackPos;
124 }
125 else if (isMarker (type, Path::cubicMarker))
126 {
127 x3 = *--stackPos;
128 y3 = *--stackPos;
129 x4 = *--stackPos;
130 y4 = *--stackPos;
131 }
132 }
133 }
134
136 {
137 ++subPathIndex;
138
140 && source != path.data.end()
142 && x2 == subPathCloseX
143 && y2 == subPathCloseY;
144
145 return true;
146 }
147
149 {
150 const size_t offset = (size_t) (stackPos - stackBase);
151
152 if (offset >= stackSize - 10)
153 {
154 stackSize <<= 1;
155 stackBase.realloc (stackSize);
156 stackPos = stackBase + offset;
157 }
158
159 auto m1x = (x1 + x2) * 0.5f;
160 auto m1y = (y1 + y2) * 0.5f;
161 auto m2x = (x2 + x3) * 0.5f;
162 auto m2y = (y2 + y3) * 0.5f;
163 auto m3x = (m1x + m2x) * 0.5f;
164 auto m3y = (m1y + m2y) * 0.5f;
165
166 auto errorX = m3x - x2;
167 auto errorY = m3y - y2;
168
169 auto outsideTolerance = errorX * errorX + errorY * errorY > toleranceSquared;
170 auto canBeSubdivided = (m3x != m1x && m3x != m2x)
171 || (m3y != m1y && m3y != m2y);
172
173 if (outsideTolerance && canBeSubdivided)
174 {
175 *stackPos++ = y3;
176 *stackPos++ = x3;
177 *stackPos++ = m2y;
178 *stackPos++ = m2x;
180
181 *stackPos++ = m3y;
182 *stackPos++ = m3x;
183 *stackPos++ = m1y;
184 *stackPos++ = m1x;
186 }
187 else
188 {
189 *stackPos++ = y3;
190 *stackPos++ = x3;
192
193 *stackPos++ = m3y;
194 *stackPos++ = m3x;
196 }
197
199 }
200 else if (isMarker (type, Path::cubicMarker))
201 {
202 const size_t offset = (size_t) (stackPos - stackBase);
203
204 if (offset >= stackSize - 16)
205 {
206 stackSize <<= 1;
207 stackBase.realloc (stackSize);
208 stackPos = stackBase + offset;
209 }
210
211 auto m1x = (x1 + x2) * 0.5f;
212 auto m1y = (y1 + y2) * 0.5f;
213 auto m2x = (x3 + x2) * 0.5f;
214 auto m2y = (y3 + y2) * 0.5f;
215 auto m3x = (x3 + x4) * 0.5f;
216 auto m3y = (y3 + y4) * 0.5f;
217 auto m4x = (m1x + m2x) * 0.5f;
218 auto m4y = (m1y + m2y) * 0.5f;
219 auto m5x = (m3x + m2x) * 0.5f;
220 auto m5y = (m3y + m2y) * 0.5f;
221
222 auto error1X = m4x - x2;
223 auto error1Y = m4y - y2;
224 auto error2X = m5x - x3;
225 auto error2Y = m5y - y3;
226
227 auto outsideTolerance = error1X * error1X + error1Y * error1Y > toleranceSquared
228 || error2X * error2X + error2Y * error2Y > toleranceSquared;
229 auto canBeSubdivided = (m4x != m1x && m4x != m2x)
230 || (m4y != m1y && m4y != m2y)
231 || (m5x != m3x && m5x != m2x)
232 || (m5y != m3y && m5y != m2y);
233
234 if (outsideTolerance && canBeSubdivided)
235 {
236 *stackPos++ = y4;
237 *stackPos++ = x4;
238 *stackPos++ = m3y;
239 *stackPos++ = m3x;
240 *stackPos++ = m5y;
241 *stackPos++ = m5x;
243
244 *stackPos++ = (m4y + m5y) * 0.5f;
245 *stackPos++ = (m4x + m5x) * 0.5f;
246 *stackPos++ = m4y;
247 *stackPos++ = m4x;
248 *stackPos++ = m1y;
249 *stackPos++ = m1x;
251 }
252 else
253 {
254 *stackPos++ = y4;
255 *stackPos++ = x4;
257
258 *stackPos++ = m5y;
259 *stackPos++ = m5x;
261
262 *stackPos++ = m4y;
263 *stackPos++ = m4x;
265 }
266 }
268 {
269 if (x2 != subPathCloseX || y2 != subPathCloseY)
270 {
271 x1 = x2;
272 y1 = y2;
275 closesSubPath = true;
276
277 return true;
278 }
279 }
280 else
281 {
283
284 subPathIndex = -1;
285 subPathCloseX = x1 = x2;
286 subPathCloseY = y1 = y2;
287 }
288 }
289}
290
291#if JUCE_MSVC && JUCE_DEBUG
292 #pragma optimize ("", on) // resets optimisations to the project defaults
293#endif
294
295} // namespace juce
#define noexcept
Definition DistrhoDefines.h:72
CAdPlugDatabase::CRecord::RecordType type
Definition adplugdb.cpp:93
Definition juce_AffineTransform.h:43
bool closesSubPath
Definition juce_PathIterator.h:83
bool next()
Definition juce_PathIterator.cpp:60
HeapBlock< float > stackBase
Definition juce_PathIterator.h:104
const float * source
Definition juce_PathIterator.h:99
float * stackPos
Definition juce_PathIterator.h:105
float subPathCloseY
Definition juce_PathIterator.h:101
~PathFlatteningIterator()
Definition juce_PathIterator.cpp:50
float y2
Definition juce_PathIterator.h:76
const AffineTransform transform
Definition juce_PathIterator.h:98
const Path & path
Definition juce_PathIterator.h:97
float x2
Definition juce_PathIterator.h:75
float y1
Definition juce_PathIterator.h:74
float subPathCloseX
Definition juce_PathIterator.h:101
PathFlatteningIterator(const Path &path, const AffineTransform &transform=AffineTransform(), float tolerance=Path::defaultToleranceForMeasurement)
Definition juce_PathIterator.cpp:34
size_t stackSize
Definition juce_PathIterator.h:106
float x1
Definition juce_PathIterator.h:73
int subPathIndex
Definition juce_PathIterator.h:90
const bool isIdentityTransform
Definition juce_PathIterator.h:102
const float toleranceSquared
Definition juce_PathIterator.h:100
bool isLastInSubpath() const noexcept
Definition juce_PathIterator.cpp:54
Definition juce_Path.h:65
static const float cubicMarker
Definition juce_Path.h:833
static const float closeSubPathMarker
Definition juce_Path.h:834
static const float quadMarker
Definition juce_Path.h:832
static const float lineMarker
Definition juce_Path.h:830
static const float moveMarker
Definition juce_Path.h:831
struct huft * t
Definition inflate.c:943
JSAMPIMAGE data
Definition jpeglib.h:945
#define jassert(expression)
Definition carla_juce.cpp:31
static bool isMarker(float value, float marker) noexcept
Definition juce_Path.cpp:70
RangedDirectoryIterator begin(const RangedDirectoryIterator &it)
Definition juce_RangedDirectoryIterator.h:179
#define false
Definition ordinals.h:83
#define const
Definition zconf.h:137