29#if JUCE_MSVC && JUCE_DEBUG
30 #pragma optimize ("t", on)
39 closesSubPath (
false),
43 source (path.data.
begin()),
45 isIdentityTransform (t.isIdentity())
56 return stackPos == stackBase.
get()
57 && (source == path.data.
end() || isMarker (*source, Path::moveMarker));
74 if (stackPos == stackBase.
get())
76 if (source == path.data.
end())
81 if (! isMarker (type, Path::closeSubPathMarker))
86 if (isMarker (type, Path::quadMarker))
91 if (! isIdentityTransform)
94 else if (isMarker (type, Path::cubicMarker))
101 if (! isIdentityTransform)
106 if (! isIdentityTransform)
115 if (! isMarker (type, Path::closeSubPathMarker))
120 if (isMarker (type, Path::quadMarker))
125 else if (isMarker (type, Path::cubicMarker))
135 if (isMarker (type, Path::lineMarker))
140 && source != path.data.
end()
141 && isMarker (*source, Path::closeSubPathMarker)
148 if (isMarker (type, Path::quadMarker))
150 const size_t offset = (
size_t) (stackPos - stackBase);
152 if (offset >= stackSize - 10)
156 stackPos = stackBase + offset;
161 auto m2x = (
x2 + x3) * 0.5f;
162 auto m2y = (
y2 + y3) * 0.5f;
179 *stackPos++ = Path::quadMarker;
185 *stackPos++ = Path::quadMarker;
191 *stackPos++ = Path::lineMarker;
195 *stackPos++ = Path::lineMarker;
198 jassert (stackPos < stackBase + stackSize);
200 else if (isMarker (type, Path::cubicMarker))
202 const size_t offset = (
size_t) (stackPos - stackBase);
204 if (offset >= stackSize - 16)
208 stackPos = stackBase + offset;
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;
242 *stackPos++ = Path::cubicMarker;
244 *stackPos++ = (
m4y +
m5y) * 0.5f;
245 *stackPos++ = (
m4x +
m5x) * 0.5f;
250 *stackPos++ = Path::cubicMarker;
256 *stackPos++ = Path::lineMarker;
260 *stackPos++ = Path::lineMarker;
264 *stackPos++ = Path::lineMarker;
267 else if (isMarker (type, Path::closeSubPathMarker))
282 jassert (isMarker (type, Path::moveMarker));
285 subPathCloseX =
x1 =
x2;
286 subPathCloseY =
y1 =
y2;
291#if JUCE_MSVC && JUCE_DEBUG
292 #pragma optimize ("", on)
ElementType * end() noexcept
Returns a pointer to the element which follows the last element in the array.
ElementType * get() const noexcept
Returns a raw pointer to the allocated data.
void realloc(SizeType newNumElements, size_t elementSize=sizeof(ElementType))
Re-allocates a specified amount of memory.
bool closesSubPath
Indicates whether the current line segment is closing a sub-path.
bool next()
Fetches the next line segment from the path.
~PathFlatteningIterator()
Destructor.
float y2
The y position of the end of the current line segment.
float x2
The x position of the end of the current line segment.
float y1
The y position of the start of the current line segment.
PathFlatteningIterator(const Path &path, const AffineTransform &transform=AffineTransform(), float tolerance=Path::defaultToleranceForMeasurement)
Creates a PathFlatteningIterator.
float x1
The x position of the start of the current line segment.
int subPathIndex
The index of the current line within the current sub-path.
bool isLastInSubpath() const noexcept
Returns true if the current segment is the last in the current sub-path.
A path is a sequence of lines and curves that may either form a closed shape or be open-ended.
constexpr bool approximatelyEqual(Type a, Type b, Tolerance< Type > tolerance=Tolerance< Type >{} .withAbsolute(std::numeric_limits< Type >::min()) .withRelative(std::numeric_limits< Type >::epsilon()))
Returns true if the two floating-point numbers are approximately equal.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
RangedDirectoryIterator begin(const RangedDirectoryIterator &it)
Returns the iterator that was passed in.