diff --git a/modules/juce_graphics/geometry/juce_EdgeTable.cpp b/modules/juce_graphics/geometry/juce_EdgeTable.cpp index 723a20ec4e..dd4c6eb203 100644 --- a/modules/juce_graphics/geometry/juce_EdgeTable.cpp +++ b/modules/juce_graphics/geometry/juce_EdgeTable.cpp @@ -36,7 +36,7 @@ EdgeTable::EdgeTable (Rectangle area, const Path& path, const AffineTransfo // for a given path, such that it's big enough to mostly avoid remapping, but also // not so big that it's wasteful for simple paths. maxEdgesPerLine (jmax (juce_edgeTableDefaultEdgesPerLine / 2, - 4 * (int) std::sqrt (path.numElements))), + 4 * (int) std::sqrt (path.data.size()))), lineStrideElements (maxEdgesPerLine * 2 + 1) { allocate(); diff --git a/modules/juce_graphics/geometry/juce_Path.cpp b/modules/juce_graphics/geometry/juce_Path.cpp index 196582d9c9..ac54f3195f 100644 --- a/modules/juce_graphics/geometry/juce_Path.cpp +++ b/modules/juce_graphics/geometry/juce_Path.cpp @@ -137,37 +137,26 @@ Path::~Path() } Path::Path (const Path& other) - : numElements (other.numElements), + : data (other.data), bounds (other.bounds), useNonZeroWinding (other.useNonZeroWinding) { - if (numElements > 0) - { - data.setAllocatedSize ((int) numElements); - memcpy (data.elements, other.data.elements, numElements * sizeof (float)); - } } Path& Path::operator= (const Path& other) { if (this != &other) { - data.ensureAllocatedSize ((int) other.numElements); - - numElements = other.numElements; + data = other.data; bounds = other.bounds; useNonZeroWinding = other.useNonZeroWinding; - - if (numElements > 0) - memcpy (data.elements, other.data.elements, numElements * sizeof (float)); } return *this; } Path::Path (Path&& other) noexcept - : data (static_cast&&> (other.data)), - numElements (other.numElements), + : data (static_cast&&> (other.data)), bounds (other.bounds), useNonZeroWinding (other.useNonZeroWinding) { @@ -175,40 +164,24 @@ Path::Path (Path&& other) noexcept Path& Path::operator= (Path&& other) noexcept { - data = static_cast&&> (other.data); - numElements = other.numElements; + data = static_cast&&> (other.data); bounds = other.bounds; useNonZeroWinding = other.useNonZeroWinding; return *this; } -bool Path::operator== (const Path& other) const noexcept -{ - return ! operator!= (other); -} - -bool Path::operator!= (const Path& other) const noexcept -{ - if (numElements != other.numElements || useNonZeroWinding != other.useNonZeroWinding) - return true; - - for (size_t i = 0; i < numElements; ++i) - if (data.elements[i] != other.data.elements[i]) - return true; - - return false; -} +bool Path::operator== (const Path& other) const noexcept { return useNonZeroWinding == other.useNonZeroWinding && data == other.data; } +bool Path::operator!= (const Path& other) const noexcept { return ! operator== (other); } void Path::clear() noexcept { - numElements = 0; + data.clearQuick(); bounds.reset(); } void Path::swapWithPath (Path& other) noexcept { data.swapWith (other.data); - std::swap (numElements, other.numElements); std::swap (bounds.pathXMin, other.bounds.pathXMin); std::swap (bounds.pathXMax, other.bounds.pathXMax); std::swap (bounds.pathYMin, other.bounds.pathYMin); @@ -230,11 +203,9 @@ void Path::scaleToFit (float x, float y, float w, float h, bool preserveProporti //============================================================================== bool Path::isEmpty() const noexcept { - size_t i = 0; - - while (i < numElements) + for (auto i = data.begin(), e = data.end(); i != e; ++i) { - auto type = data.elements[i++]; + auto type = *i; if (isMarker (type, moveMarker)) { @@ -264,23 +235,19 @@ Rectangle Path::getBoundsTransformed (const AffineTransform& transform) c //============================================================================== void Path::preallocateSpace (int numExtraCoordsToMakeSpaceFor) { - data.ensureAllocatedSize ((int) numElements + numExtraCoordsToMakeSpaceFor); + data.ensureStorageAllocated (data.size() + numExtraCoordsToMakeSpaceFor); } void Path::startNewSubPath (const float x, const float y) { JUCE_CHECK_COORDS_ARE_VALID (x, y); - if (numElements == 0) + if (data.isEmpty()) bounds.reset (x, y); else bounds.extend (x, y); - preallocateSpace (3); - - data.elements[numElements++] = moveMarker; - data.elements[numElements++] = x; - data.elements[numElements++] = y; + data.add (moveMarker, x, y); } void Path::startNewSubPath (Point start) @@ -292,15 +259,10 @@ void Path::lineTo (const float x, const float y) { JUCE_CHECK_COORDS_ARE_VALID (x, y); - if (numElements == 0) + if (data.isEmpty()) startNewSubPath (0, 0); - preallocateSpace (3); - - data.elements[numElements++] = lineMarker; - data.elements[numElements++] = x; - data.elements[numElements++] = y; - + data.add (lineMarker, x, y); bounds.extend (x, y); } @@ -315,17 +277,10 @@ void Path::quadraticTo (const float x1, const float y1, JUCE_CHECK_COORDS_ARE_VALID (x1, y1); JUCE_CHECK_COORDS_ARE_VALID (x2, y2); - if (numElements == 0) + if (data.isEmpty()) startNewSubPath (0, 0); - preallocateSpace (5); - - data.elements[numElements++] = quadMarker; - data.elements[numElements++] = x1; - data.elements[numElements++] = y1; - data.elements[numElements++] = x2; - data.elements[numElements++] = y2; - + data.add (quadMarker, x1, y1, x2, y2); bounds.extend (x1, y1, x2, y2); } @@ -343,19 +298,10 @@ void Path::cubicTo (const float x1, const float y1, JUCE_CHECK_COORDS_ARE_VALID (x2, y2); JUCE_CHECK_COORDS_ARE_VALID (x3, y3); - if (numElements == 0) + if (data.isEmpty()) startNewSubPath (0, 0); - preallocateSpace (7); - - data.elements[numElements++] = cubicMarker; - data.elements[numElements++] = x1; - data.elements[numElements++] = y1; - data.elements[numElements++] = x2; - data.elements[numElements++] = y2; - data.elements[numElements++] = x3; - data.elements[numElements++] = y3; - + data.add (cubicMarker, x1, y1, x2, y2, x3, y3); bounds.extend (x1, y1, x2, y2); bounds.extend (x3, y3); } @@ -371,48 +317,43 @@ void Path::cubicTo (Point controlPoint1, void Path::closeSubPath() { - if (numElements > 0 && ! isMarker (data.elements[numElements - 1], closeSubPathMarker)) - { - preallocateSpace (1); - data.elements[numElements++] = closeSubPathMarker; - } + if (! (data.isEmpty() || isMarker (data.getLast(), closeSubPathMarker))) + data.add (closeSubPathMarker); } Point Path::getCurrentPosition() const { - int i = (int) numElements - 1; + if (data.isEmpty()) + return {}; + + auto* i = data.end() - 1; - if (i > 0 && isMarker (data.elements[i], closeSubPathMarker)) + if (isMarker (*i, closeSubPathMarker)) { - while (i >= 0) + while (i != data.begin()) { - if (isMarker (data.elements[i], moveMarker)) + if (isMarker (*--i, moveMarker)) { i += 2; break; } - - --i; } } - if (i > 0) - return { data.elements[i - 1], data.elements[i] }; + if (i != data.begin()) + return { *(i - 1), *i }; return {}; } -void Path::addRectangle (const float x, const float y, - const float w, const float h) +void Path::addRectangle (float x, float y, float w, float h) { - float x1 = x, y1 = y, x2 = x + w, y2 = y + h; + auto x1 = x, y1 = y, x2 = x + w, y2 = y + h; if (w < 0) std::swap (x1, x2); if (h < 0) std::swap (y1, y2); - preallocateSpace (13); - - if (numElements == 0) + if (data.isEmpty()) { bounds.pathXMin = x1; bounds.pathXMax = x2; @@ -427,19 +368,11 @@ void Path::addRectangle (const float x, const float y, bounds.pathYMax = jmax (bounds.pathYMax, y2); } - data.elements[numElements++] = moveMarker; - data.elements[numElements++] = x1; - data.elements[numElements++] = y2; - data.elements[numElements++] = lineMarker; - data.elements[numElements++] = x1; - data.elements[numElements++] = y1; - data.elements[numElements++] = lineMarker; - data.elements[numElements++] = x2; - data.elements[numElements++] = y1; - data.elements[numElements++] = lineMarker; - data.elements[numElements++] = x2; - data.elements[numElements++] = y2; - data.elements[numElements++] = closeSubPathMarker; + data.add (moveMarker, x1, y2, + lineMarker, x1, y1, + lineMarker, x2, y1, + lineMarker, x2, y2, + closeSubPathMarker); } void Path::addRoundedRectangle (float x, float y, float w, float h, float csx, float csy) @@ -511,9 +444,9 @@ void Path::addTriangle (float x1, float y1, float x2, float y2, float x3, float y3) { - addTriangle (Point (x1, y1), - Point (x2, y2), - Point (x3, y3)); + addTriangle ({ x1, y1 }, + { x2, y2 }, + { x3, y3 }); } void Path::addTriangle (Point p1, Point p2, Point p3) @@ -524,10 +457,10 @@ void Path::addTriangle (Point p1, Point p2, Point p3) closeSubPath(); } -void Path::addQuadrilateral (const float x1, const float y1, - const float x2, const float y2, - const float x3, const float y3, - const float x4, const float y4) +void Path::addQuadrilateral (float x1, float y1, + float x2, float y2, + float x3, float y3, + float x4, float y4) { startNewSubPath (x1, y1); lineTo (x2, y2); @@ -538,7 +471,7 @@ void Path::addQuadrilateral (const float x1, const float y1, void Path::addEllipse (float x, float y, float w, float h) { - addEllipse (Rectangle (x, y, w, h)); + addEllipse ({ x, y, w, h }); } void Path::addEllipse (Rectangle area) @@ -558,11 +491,9 @@ void Path::addEllipse (Rectangle area) closeSubPath(); } -void Path::addArc (const float x, const float y, - const float w, const float h, - const float fromRadians, - const float toRadians, - const bool startAsNewSubPath) +void Path::addArc (float x, float y, float w, float h, + float fromRadians, float toRadians, + bool startAsNewSubPath) { auto radiusX = w / 2.0f; auto radiusY = h / 2.0f; @@ -575,16 +506,15 @@ void Path::addArc (const float x, const float y, startAsNewSubPath); } -void Path::addCentredArc (const float centreX, const float centreY, - const float radiusX, const float radiusY, - const float rotationOfEllipse, - const float fromRadians, - float toRadians, - const bool startAsNewSubPath) +void Path::addCentredArc (float centreX, float centreY, + float radiusX, float radiusY, + float rotationOfEllipse, + float fromRadians, float toRadians, + bool startAsNewSubPath) { if (radiusX > 0.0f && radiusY > 0.0f) { - const Point centre (centreX, centreY); + Point centre (centreX, centreY); auto rotation = AffineTransform::rotation (rotationOfEllipse, centreX, centreY); auto angle = fromRadians; @@ -618,15 +548,13 @@ void Path::addCentredArc (const float centreX, const float centreY, } } -void Path::addPieSegment (const float x, const float y, - const float width, const float height, - const float fromRadians, - const float toRadians, - const float innerCircleProportionalSize) +void Path::addPieSegment (float x, float y, float width, float height, + float fromRadians, float toRadians, + float innerCircleProportionalSize) { - float radiusX = width * 0.5f; - float radiusY = height * 0.5f; - const Point centre (x + radiusX, y + radiusY); + auto radiusX = width * 0.5f; + auto radiusY = height * 0.5f; + Point centre (x + radiusX, y + radiusY); startNewSubPath (centre.getPointOnCircumference (radiusX, radiusY, fromRadians)); addArc (x, y, width, height, fromRadians, toRadians); @@ -663,9 +591,8 @@ void Path::addPieSegment (const float x, const float y, } void Path::addPieSegment (Rectangle segmentBounds, - const float fromRadians, - const float toRadians, - const float innerCircleProportionalSize) + float fromRadians, float toRadians, + float innerCircleProportionalSize) { addPieSegment (segmentBounds.getX(), segmentBounds.getY(), @@ -760,8 +687,8 @@ void Path::addStar (Point centre, int numberOfPoints, float innerRadius, void Path::addBubble (Rectangle bodyArea, Rectangle maximumArea, Point arrowTip, - const float cornerSize, - const float arrowBaseWidth) + float cornerSize, + float arrowBaseWidth) { auto halfW = bodyArea.getWidth() / 2.0f; auto halfH = bodyArea.getHeight() / 2.0f; @@ -824,10 +751,9 @@ void Path::addBubble (Rectangle bodyArea, void Path::addPath (const Path& other) { - size_t i = 0; - const float* d = other.data.elements; + const auto* d = other.data.begin(); - while (i < other.numElements) + for (int i = 0; i < other.data.size();) { auto type = d[i++]; @@ -866,10 +792,9 @@ void Path::addPath (const Path& other) void Path::addPath (const Path& other, const AffineTransform& transformToApply) { - size_t i = 0; - const float* d = other.data.elements; + const auto* d = other.data.begin(); - while (i < other.numElements) + for (int i = 0; i < other.data.size();) { auto type = d[i++]; @@ -923,8 +848,8 @@ void Path::applyTransform (const AffineTransform& transform) noexcept { bounds.reset(); bool firstPoint = true; - float* d = data.elements; - auto* end = d + numElements; + float* d = data.begin(); + auto* end = data.end(); while (d < end) { @@ -977,9 +902,8 @@ AffineTransform Path::getTransformToScaleToFit (Rectangle area, bool pres preserveProportions, justification); } -AffineTransform Path::getTransformToScaleToFit (const float x, const float y, - const float w, const float h, - const bool preserveProportions, +AffineTransform Path::getTransformToScaleToFit (float x, float y, float w, float h, + bool preserveProportions, Justification justification) const { auto boundsRect = getBounds(); @@ -1030,7 +954,7 @@ AffineTransform Path::getTransformToScaleToFit (const float x, const float y, } //============================================================================== -bool Path::contains (const float x, const float y, const float tolerance) const +bool Path::contains (float x, float y, float tolerance) const { if (x <= bounds.pathXMin || x >= bounds.pathXMax || y <= bounds.pathYMin || y >= bounds.pathYMax) @@ -1061,12 +985,12 @@ bool Path::contains (const float x, const float y, const float tolerance) const : ((negativeCrossings + positiveCrossings) & 1) != 0; } -bool Path::contains (Point point, const float tolerance) const +bool Path::contains (Point point, float tolerance) const { return contains (point.x, point.y, tolerance); } -bool Path::intersectsLine (Line line, const float tolerance) +bool Path::intersectsLine (Line line, float tolerance) { PathFlatteningIterator i (*this, AffineTransform(), tolerance); Point intersection; @@ -1078,7 +1002,7 @@ bool Path::intersectsLine (Line line, const float tolerance) return false; } -Line Path::getClippedLine (Line line, const bool keepSectionOutsidePath) const +Line Path::getClippedLine (Line line, bool keepSectionOutsidePath) const { Line result (line); const bool startInside = contains (line.getStart()); @@ -1174,23 +1098,23 @@ Path Path::createPathWithRoundedCorners (const float cornerRadius) const return *this; Path p; - size_t indexOfPathStart = 0, indexOfPathStartThis = 0; - size_t n = 0; + int n = 0, indexOfPathStart = 0, indexOfPathStartThis = 0; + auto* elements = data.begin(); bool lastWasLine = false, firstWasLine = false; - while (n < numElements) + while (n < data.size()) { - auto type = data.elements[n++]; + auto type = elements[n++]; if (isMarker (type, moveMarker)) { - indexOfPathStart = p.numElements; + indexOfPathStart = p.data.size(); indexOfPathStartThis = n - 1; - auto x = data.elements[n++]; - auto y = data.elements[n++]; + auto x = elements[n++]; + auto y = elements[n++]; p.startNewSubPath (x, y); lastWasLine = false; - firstWasLine = (isMarker (data.elements[n], lineMarker)); + firstWasLine = (isMarker (elements[n], lineMarker)); } else if (isMarker (type, lineMarker) || isMarker (type, closeSubPathMarker)) { @@ -1198,28 +1122,28 @@ Path Path::createPathWithRoundedCorners (const float cornerRadius) const if (isMarker (type, lineMarker)) { - endX = data.elements[n++]; - endY = data.elements[n++]; + endX = elements[n++]; + endY = elements[n++]; if (n > 8) { - startX = data.elements[n - 8]; - startY = data.elements[n - 7]; - joinX = data.elements[n - 5]; - joinY = data.elements[n - 4]; + startX = elements[n - 8]; + startY = elements[n - 7]; + joinX = elements[n - 5]; + joinY = elements[n - 4]; } } else { - endX = data.elements[indexOfPathStartThis + 1]; - endY = data.elements[indexOfPathStartThis + 2]; + endX = elements[indexOfPathStartThis + 1]; + endY = elements[indexOfPathStartThis + 2]; if (n > 6) { - startX = data.elements[n - 6]; - startY = data.elements[n - 5]; - joinX = data.elements[n - 3]; - joinY = data.elements[n - 2]; + startX = elements[n - 6]; + startY = elements[n - 5]; + joinX = elements[n - 3]; + joinY = elements[n - 2]; } } @@ -1231,8 +1155,8 @@ Path Path::createPathWithRoundedCorners (const float cornerRadius) const { auto propNeeded = jmin (0.5, cornerRadius / len1); - p.data.elements[p.numElements - 2] = (float) (joinX - (joinX - startX) * propNeeded); - p.data.elements[p.numElements - 1] = (float) (joinY - (joinY - startY) * propNeeded); + *(p.data.end() - 2) = (float) (joinX - (joinX - startX) * propNeeded); + *(p.data.end() - 1) = (float) (joinY - (joinY - startY) * propNeeded); } auto len2 = PathHelpers::lengthOf (endX, endY, joinX, joinY); @@ -1258,12 +1182,12 @@ Path Path::createPathWithRoundedCorners (const float cornerRadius) const { if (firstWasLine) { - startX = data.elements[n - 3]; - startY = data.elements[n - 2]; + startX = elements[n - 3]; + startY = elements[n - 2]; joinX = endX; joinY = endY; - endX = data.elements[indexOfPathStartThis + 4]; - endY = data.elements[indexOfPathStartThis + 5]; + endX = elements[indexOfPathStartThis + 4]; + endY = elements[indexOfPathStartThis + 5]; auto len1 = PathHelpers::lengthOf (startX, startY, joinX, joinY); @@ -1271,8 +1195,8 @@ Path Path::createPathWithRoundedCorners (const float cornerRadius) const { auto propNeeded = jmin (0.5, cornerRadius / len1); - p.data.elements[p.numElements - 2] = (float) (joinX - (joinX - startX) * propNeeded); - p.data.elements[p.numElements - 1] = (float) (joinY - (joinY - startY) * propNeeded); + *(p.data.end() - 2) = (float) (joinX - (joinX - startX) * propNeeded); + *(p.data.end() - 1) = (float) (joinY - (joinY - startY) * propNeeded); } auto len2 = PathHelpers::lengthOf (endX, endY, joinX, joinY); @@ -1286,8 +1210,8 @@ Path Path::createPathWithRoundedCorners (const float cornerRadius) const p.quadraticTo (joinX, joinY, endX, endY); - p.data.elements[indexOfPathStart + 1] = endX; - p.data.elements[indexOfPathStart + 2] = endY; + p.data.begin()[indexOfPathStart + 1] = endX; + p.data.begin()[indexOfPathStart + 2] = endY; } } @@ -1297,21 +1221,21 @@ Path Path::createPathWithRoundedCorners (const float cornerRadius) const else if (isMarker (type, quadMarker)) { lastWasLine = false; - auto x1 = data.elements[n++]; - auto y1 = data.elements[n++]; - auto x2 = data.elements[n++]; - auto y2 = data.elements[n++]; + auto x1 = elements[n++]; + auto y1 = elements[n++]; + auto x2 = elements[n++]; + auto y2 = elements[n++]; p.quadraticTo (x1, y1, x2, y2); } else if (isMarker (type, cubicMarker)) { lastWasLine = false; - auto x1 = data.elements[n++]; - auto y1 = data.elements[n++]; - auto x2 = data.elements[n++]; - auto y2 = data.elements[n++]; - auto x3 = data.elements[n++]; - auto y3 = data.elements[n++]; + auto x1 = elements[n++]; + auto y1 = elements[n++]; + auto x2 = elements[n++]; + auto y2 = elements[n++]; + auto x3 = elements[n++]; + auto y3 = elements[n++]; p.cubicTo (x1, y1, x2, y2, x3, y3); } } @@ -1396,39 +1320,39 @@ void Path::writePathToStream (OutputStream& dest) const { dest.writeByte (useNonZeroWinding ? 'n' : 'z'); - for (size_t i = 0; i < numElements;) + for (auto* i = data.begin(); i != data.end();) { - auto type = data.elements[i++]; + auto type = *i++; if (isMarker (type, moveMarker)) { dest.writeByte ('m'); - dest.writeFloat (data.elements[i++]); - dest.writeFloat (data.elements[i++]); + dest.writeFloat (*i++); + dest.writeFloat (*i++); } else if (isMarker (type, lineMarker)) { dest.writeByte ('l'); - dest.writeFloat (data.elements[i++]); - dest.writeFloat (data.elements[i++]); + dest.writeFloat (*i++); + dest.writeFloat (*i++); } else if (isMarker (type, quadMarker)) { dest.writeByte ('q'); - dest.writeFloat (data.elements[i++]); - dest.writeFloat (data.elements[i++]); - dest.writeFloat (data.elements[i++]); - dest.writeFloat (data.elements[i++]); + dest.writeFloat (*i++); + dest.writeFloat (*i++); + dest.writeFloat (*i++); + dest.writeFloat (*i++); } else if (isMarker (type, cubicMarker)) { dest.writeByte ('b'); - dest.writeFloat (data.elements[i++]); - dest.writeFloat (data.elements[i++]); - dest.writeFloat (data.elements[i++]); - dest.writeFloat (data.elements[i++]); - dest.writeFloat (data.elements[i++]); - dest.writeFloat (data.elements[i++]); + dest.writeFloat (*i++); + dest.writeFloat (*i++); + dest.writeFloat (*i++); + dest.writeFloat (*i++); + dest.writeFloat (*i++); + dest.writeFloat (*i++); } else if (isMarker (type, closeSubPathMarker)) { @@ -1445,12 +1369,11 @@ String Path::toString() const if (! useNonZeroWinding) s << 'a'; - size_t i = 0; float lastMarker = 0.0f; - while (i < numElements) + for (int i = 0; i < data.size();) { - auto type = data.elements[i++]; + auto type = data.begin()[i++]; char markerChar = 0; int numCoords = 0; @@ -1489,9 +1412,9 @@ String Path::toString() const lastMarker = type; } - while (--numCoords >= 0 && i < numElements) + while (--numCoords >= 0 && i < data.size()) { - String coord (data.elements[i++], 3); + String coord (data.begin()[i++], 3); while (coord.endsWithChar ('0') && coord != "0") coord = coord.dropLastCharacters (1); @@ -1576,7 +1499,7 @@ void Path::restoreFromString (StringRef stringVersion) //============================================================================== Path::Iterator::Iterator (const Path& p) noexcept - : elementType (startNewSubPath), path (p) + : elementType (startNewSubPath), path (p), index (path.data.begin()) { } @@ -1586,41 +1509,39 @@ Path::Iterator::~Iterator() noexcept bool Path::Iterator::next() noexcept { - const float* elements = path.data.elements; - - if (index < path.numElements) + if (index != path.data.end()) { - auto type = elements[index++]; + auto type = *index++; if (isMarker (type, moveMarker)) { elementType = startNewSubPath; - x1 = elements[index++]; - y1 = elements[index++]; + x1 = *index++; + y1 = *index++; } else if (isMarker (type, lineMarker)) { elementType = lineTo; - x1 = elements[index++]; - y1 = elements[index++]; + x1 = *index++; + y1 = *index++; } else if (isMarker (type, quadMarker)) { elementType = quadraticTo; - x1 = elements[index++]; - y1 = elements[index++]; - x2 = elements[index++]; - y2 = elements[index++]; + x1 = *index++; + y1 = *index++; + x2 = *index++; + y2 = *index++; } else if (isMarker (type, cubicMarker)) { elementType = cubicTo; - x1 = elements[index++]; - y1 = elements[index++]; - x2 = elements[index++]; - y2 = elements[index++]; - x3 = elements[index++]; - y3 = elements[index++]; + x1 = *index++; + y1 = *index++; + x2 = *index++; + y2 = *index++; + x3 = *index++; + y3 = *index++; } else if (isMarker (type, closeSubPathMarker)) { diff --git a/modules/juce_graphics/geometry/juce_Path.h b/modules/juce_graphics/geometry/juce_Path.h index eda4f2d5b1..96b231efe5 100644 --- a/modules/juce_graphics/geometry/juce_Path.h +++ b/modules/juce_graphics/geometry/juce_Path.h @@ -753,7 +753,7 @@ public: //============================================================================== private: const Path& path; - size_t index = 0; + const float* index; JUCE_DECLARE_NON_COPYABLE (Iterator) }; @@ -803,8 +803,7 @@ private: friend class Path::Iterator; friend class EdgeTable; - ArrayAllocationBase data; - size_t numElements = 0; + Array data; struct PathBounds { diff --git a/modules/juce_graphics/geometry/juce_PathIterator.cpp b/modules/juce_graphics/geometry/juce_PathIterator.cpp index ca239d4f95..d695bcfc59 100644 --- a/modules/juce_graphics/geometry/juce_PathIterator.cpp +++ b/modules/juce_graphics/geometry/juce_PathIterator.cpp @@ -32,18 +32,18 @@ namespace juce #endif //============================================================================== -PathFlatteningIterator::PathFlatteningIterator (const Path& path_, - const AffineTransform& transform_, - const float tolerance) +PathFlatteningIterator::PathFlatteningIterator (const Path& pathToUse, + const AffineTransform& t, + float tolerance) : x2 (0), y2 (0), closesSubPath (false), subPathIndex (-1), - path (path_), - transform (transform_), - points (path_.data.elements), + path (pathToUse), + transform (t), + source (path.data.begin()), toleranceSquared (tolerance * tolerance), - isIdentityTransform (transform_.isIdentity()) + isIdentityTransform (t.isIdentity()) { stackPos = stackBase; } @@ -55,7 +55,7 @@ PathFlatteningIterator::~PathFlatteningIterator() bool PathFlatteningIterator::isLastInSubpath() const noexcept { return stackPos == stackBase.get() - && (index >= path.numElements || isMarker (points[index], Path::moveMarker)); + && (source == path.data.end() || isMarker (*source, Path::moveMarker)); } bool PathFlatteningIterator::next() @@ -74,30 +74,30 @@ bool PathFlatteningIterator::next() if (stackPos == stackBase) { - if (index >= path.numElements) + if (source == path.data.end()) return false; - type = points [index++]; + type = *source++; if (! isMarker (type, Path::closeSubPathMarker)) { - x2 = points [index++]; - y2 = points [index++]; + x2 = *source++; + y2 = *source++; if (isMarker (type, Path::quadMarker)) { - x3 = points [index++]; - y3 = points [index++]; + x3 = *source++; + y3 = *source++; if (! isIdentityTransform) transform.transformPoints (x2, y2, x3, y3); } else if (isMarker (type, Path::cubicMarker)) { - x3 = points [index++]; - y3 = points [index++]; - x4 = points [index++]; - y4 = points [index++]; + x3 = *source++; + y3 = *source++; + x4 = *source++; + y4 = *source++; if (! isIdentityTransform) transform.transformPoints (x2, y2, x3, y3, x4, y4); @@ -137,9 +137,9 @@ bool PathFlatteningIterator::next() { ++subPathIndex; - closesSubPath = (stackPos == stackBase) - && (index < path.numElements) - && (points [index] == Path::closeSubPathMarker) + closesSubPath = stackPos == stackBase + && source != path.data.end() + && *source == Path::closeSubPathMarker && x2 == subPathCloseX && y2 == subPathCloseY; diff --git a/modules/juce_graphics/geometry/juce_PathIterator.h b/modules/juce_graphics/geometry/juce_PathIterator.h index 70917c13f3..3dff28b2d2 100644 --- a/modules/juce_graphics/geometry/juce_PathIterator.h +++ b/modules/juce_graphics/geometry/juce_PathIterator.h @@ -95,14 +95,14 @@ private: //============================================================================== const Path& path; const AffineTransform transform; - float* points; + const float* source; const float toleranceSquared; float subPathCloseX = 0, subPathCloseY = 0; const bool isIdentityTransform; HeapBlock stackBase { 32 }; float* stackPos; - size_t index = 0, stackSize = 32; + size_t stackSize = 32; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PathFlatteningIterator) };