diff --git a/modules/juce_graphics/geometry/juce_EdgeTable.cpp b/modules/juce_graphics/geometry/juce_EdgeTable.cpp index bfcb7c7d96..5caa8bf130 100644 --- a/modules/juce_graphics/geometry/juce_EdgeTable.cpp +++ b/modules/juce_graphics/geometry/juce_EdgeTable.cpp @@ -30,12 +30,10 @@ namespace juce const int juce_edgeTableDefaultEdgesPerLine = 32; //============================================================================== -EdgeTable::EdgeTable (const Rectangle& area, - const Path& path, const AffineTransform& transform) +EdgeTable::EdgeTable (Rectangle area, const Path& path, const AffineTransform& transform) : bounds (area), maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine), - lineStrideElements (juce_edgeTableDefaultEdgesPerLine * 2 + 1), - needToCheckEmptiness (true) + lineStrideElements (juce_edgeTableDefaultEdgesPerLine * 2 + 1) { allocate(); int* t = table; @@ -46,24 +44,24 @@ EdgeTable::EdgeTable (const Rectangle& area, t += lineStrideElements; } - const int leftLimit = bounds.getX() << 8; - const int topLimit = bounds.getY() << 8; - const int rightLimit = bounds.getRight() << 8; - const int heightLimit = bounds.getHeight() << 8; + auto leftLimit = bounds.getX() << 8; + auto topLimit = bounds.getY() << 8; + auto rightLimit = bounds.getRight() << 8; + auto heightLimit = bounds.getHeight() << 8; PathFlatteningIterator iter (path, transform); while (iter.next()) { - int y1 = roundToInt (iter.y1 * 256.0f); - int y2 = roundToInt (iter.y2 * 256.0f); + auto y1 = roundToInt (iter.y1 * 256.0f); + auto y2 = roundToInt (iter.y2 * 256.0f); if (y1 != y2) { y1 -= topLimit; y2 -= topLimit; - const int startY = y1; + auto startY = y1; int direction = -1; if (y1 > y2) @@ -82,12 +80,12 @@ EdgeTable::EdgeTable (const Rectangle& area, { const double startX = 256.0f * iter.x1; const double multiplier = (iter.x2 - iter.x1) / (iter.y2 - iter.y1); - const int stepSize = jlimit (1, 256, 256 / (1 + (int) std::abs (multiplier))); + auto stepSize = jlimit (1, 256, 256 / (1 + (int) std::abs (multiplier))); do { - const int step = jmin (stepSize, y2 - y1, 256 - (y1 & 255)); - int x = roundToInt (startX + multiplier * ((y1 + (step >> 1)) - startY)); + auto step = jmin (stepSize, y2 - y1, 256 - (y1 & 255)); + auto x = roundToInt (startX + multiplier * ((y1 + (step >> 1)) - startY)); if (x < leftLimit) x = leftLimit; @@ -105,19 +103,18 @@ EdgeTable::EdgeTable (const Rectangle& area, sanitiseLevels (path.isUsingNonZeroWinding()); } -EdgeTable::EdgeTable (const Rectangle& rectangleToAdd) +EdgeTable::EdgeTable (Rectangle rectangleToAdd) : bounds (rectangleToAdd), maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine), - lineStrideElements (juce_edgeTableDefaultEdgesPerLine * 2 + 1), - needToCheckEmptiness (true) + lineStrideElements (juce_edgeTableDefaultEdgesPerLine * 2 + 1) { allocate(); table[0] = 0; - const int x1 = rectangleToAdd.getX() << 8; - const int x2 = rectangleToAdd.getRight() << 8; - + auto x1 = rectangleToAdd.getX() << 8; + auto x2 = rectangleToAdd.getRight() << 8; int* t = table; + for (int i = rectangleToAdd.getHeight(); --i >= 0;) { t[0] = 2; @@ -140,9 +137,9 @@ EdgeTable::EdgeTable (const RectangleList& rectanglesToAdd) for (auto& r : rectanglesToAdd) { - const int x1 = r.getX() << 8; - const int x2 = r.getRight() << 8; - int y = r.getY() - bounds.getY(); + auto x1 = r.getX() << 8; + auto x2 = r.getRight() << 8; + auto y = r.getY() - bounds.getY(); for (int j = r.getHeight(); --j >= 0;) addEdgePointPair (x1, x2, y++, 255); @@ -154,8 +151,7 @@ EdgeTable::EdgeTable (const RectangleList& rectanglesToAdd) EdgeTable::EdgeTable (const RectangleList& rectanglesToAdd) : bounds (rectanglesToAdd.getBounds().getSmallestIntegerContainer()), maxEdgesPerLine (rectanglesToAdd.getNumRectangles() * 2), - lineStrideElements (rectanglesToAdd.getNumRectangles() * 4 + 1), - needToCheckEmptiness (true) + lineStrideElements (rectanglesToAdd.getNumRectangles() * 4 + 1) { bounds.setHeight (bounds.getHeight() + 1); allocate(); @@ -163,17 +159,17 @@ EdgeTable::EdgeTable (const RectangleList& rectanglesToAdd) for (auto& r : rectanglesToAdd) { - const int x1 = roundToInt (r.getX() * 256.0f); - const int x2 = roundToInt (r.getRight() * 256.0f); + auto x1 = roundToInt (r.getX() * 256.0f); + auto x2 = roundToInt (r.getRight() * 256.0f); - const int y1 = roundToInt (r.getY() * 256.0f) - (bounds.getY() << 8); - const int y2 = roundToInt (r.getBottom() * 256.0f) - (bounds.getY() << 8); + auto y1 = roundToInt (r.getY() * 256.0f) - (bounds.getY() << 8); + auto y2 = roundToInt (r.getBottom() * 256.0f) - (bounds.getY() << 8); if (x2 <= x1 || y2 <= y1) continue; - int y = y1 >> 8; - const int lastLine = y2 >> 8; + auto y = y1 >> 8; + auto lastLine = y2 >> 8; if (y == lastLine) { @@ -194,25 +190,23 @@ EdgeTable::EdgeTable (const RectangleList& rectanglesToAdd) sanitiseLevels (true); } -EdgeTable::EdgeTable (const Rectangle& rectangleToAdd) - : bounds (Rectangle ((int) std::floor (rectangleToAdd.getX()), - roundToInt (rectangleToAdd.getY() * 256.0f) >> 8, - 2 + (int) rectangleToAdd.getWidth(), - 2 + (int) rectangleToAdd.getHeight())), +EdgeTable::EdgeTable (Rectangle rectangleToAdd) + : bounds ((int) std::floor (rectangleToAdd.getX()), + roundToInt (rectangleToAdd.getY() * 256.0f) >> 8, + 2 + (int) rectangleToAdd.getWidth(), + 2 + (int) rectangleToAdd.getHeight()), maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine), - lineStrideElements ((juce_edgeTableDefaultEdgesPerLine << 1) + 1), - needToCheckEmptiness (true) + lineStrideElements ((juce_edgeTableDefaultEdgesPerLine * 2) + 1) { jassert (! rectangleToAdd.isEmpty()); allocate(); table[0] = 0; - const int x1 = roundToInt (rectangleToAdd.getX() * 256.0f); - const int x2 = roundToInt (rectangleToAdd.getRight() * 256.0f); - - int y1 = roundToInt (rectangleToAdd.getY() * 256.0f) - (bounds.getY() << 8); + auto x1 = roundToInt (rectangleToAdd.getX() * 256.0f); + auto x2 = roundToInt (rectangleToAdd.getRight() * 256.0f); + auto y1 = roundToInt (rectangleToAdd.getY() * 256.0f) - (bounds.getY() << 8); + auto y2 = roundToInt (rectangleToAdd.getBottom() * 256.0f) - (bounds.getY() << 8); jassert (y1 < 256); - int y2 = roundToInt (rectangleToAdd.getBottom() * 256.0f) - (bounds.getY() << 8); if (x2 <= x1 || y2 <= y1) { @@ -308,6 +302,7 @@ void EdgeTable::allocate() void EdgeTable::clearLineSizes() noexcept { int* t = table; + for (int i = bounds.getHeight(); --i >= 0;) { *t = 0; @@ -315,7 +310,7 @@ void EdgeTable::clearLineSizes() noexcept } } -void EdgeTable::copyEdgeTableData (int* dest, const int destLineStride, const int* src, const int srcLineStride, int numLines) noexcept +void EdgeTable::copyEdgeTableData (int* dest, int destLineStride, const int* src, int srcLineStride, int numLines) noexcept { while (--numLines >= 0) { @@ -332,24 +327,24 @@ void EdgeTable::sanitiseLevels (const bool useNonZeroWinding) noexcept for (int y = bounds.getHeight(); --y >= 0;) { - int num = lineStart[0]; + auto num = lineStart[0]; if (num > 0) { - LineItem* items = reinterpret_cast (lineStart + 1); - LineItem* const itemsEnd = items + num; + auto* items = reinterpret_cast (lineStart + 1); + auto* itemsEnd = items + num; // sort the X coords std::sort (items, itemsEnd); - const LineItem* src = items; - int correctedNum = num; + auto* src = items; + auto correctedNum = num; int level = 0; while (src < itemsEnd) { level += src->level; - const int x = src->x; + auto x = src->x; ++src; while (src < itemsEnd && src->x == x) @@ -359,7 +354,7 @@ void EdgeTable::sanitiseLevels (const bool useNonZeroWinding) noexcept --correctedNum; } - int corrected = std::abs (level); + auto corrected = std::abs (level); if (corrected >> 8) { @@ -370,6 +365,7 @@ void EdgeTable::sanitiseLevels (const bool useNonZeroWinding) noexcept else { corrected &= 511; + if (corrected >> 8) corrected = 511 - corrected; } @@ -395,7 +391,7 @@ void EdgeTable::remapTableForNumEdges (const int newNumEdgesPerLine) maxEdgesPerLine = newNumEdgesPerLine; jassert (bounds.getHeight() > 0); - const int newLineStrideElements = maxEdgesPerLine * 2 + 1; + auto newLineStrideElements = maxEdgesPerLine * 2 + 1; HeapBlock newTable (getEdgeTableAllocationSize (newLineStrideElements, bounds.getHeight())); @@ -406,12 +402,18 @@ void EdgeTable::remapTableForNumEdges (const int newNumEdgesPerLine) } } +inline void EdgeTable::remapWithExtraSpace (int numPoints) +{ + remapTableForNumEdges (numPoints + jmax (juce_edgeTableDefaultEdgesPerLine, numPoints / 2)); + jassert (numPoints < maxEdgesPerLine); +} + void EdgeTable::optimiseTable() { int maxLineElements = 0; for (int i = bounds.getHeight(); --i >= 0;) - maxLineElements = jmax (maxLineElements, table [i * lineStrideElements]); + maxLineElements = jmax (maxLineElements, table[i * lineStrideElements]); remapTableForNumEdges (maxLineElements); } @@ -420,56 +422,54 @@ void EdgeTable::addEdgePoint (const int x, const int y, const int winding) { jassert (y >= 0 && y < bounds.getHeight()); - int* line = table + lineStrideElements * y; - const int numPoints = line[0]; + auto* line = table + lineStrideElements * y; + auto numPoints = line[0]; if (numPoints >= maxEdgesPerLine) { - remapTableForNumEdges (maxEdgesPerLine + juce_edgeTableDefaultEdgesPerLine); - jassert (numPoints < maxEdgesPerLine); + remapWithExtraSpace (numPoints); line = table + lineStrideElements * y; } - line[0]++; - int n = numPoints << 1; - line [n + 1] = x; - line [n + 2] = winding; + line[0] = numPoints + 1; + line += numPoints * 2; + line[1] = x; + line[2] = winding; } void EdgeTable::addEdgePointPair (int x1, int x2, int y, int winding) { jassert (y >= 0 && y < bounds.getHeight()); - int* line = table + lineStrideElements * y; - const int numPoints = line[0]; + auto* line = table + lineStrideElements * y; + auto numPoints = line[0]; if (numPoints + 1 >= maxEdgesPerLine) { - remapTableForNumEdges (maxEdgesPerLine + juce_edgeTableDefaultEdgesPerLine); - jassert (numPoints < maxEdgesPerLine); + remapWithExtraSpace (numPoints + 1); line = table + lineStrideElements * y; } line[0] = numPoints + 2; - line += numPoints << 1; + line += numPoints * 2; line[1] = x1; line[2] = winding; line[3] = x2; line[4] = -winding; } -void EdgeTable::translate (float dx, const int dy) noexcept +void EdgeTable::translate (float dx, int dy) noexcept { bounds.translate ((int) std::floor (dx), dy); int* lineStart = table; - const int intDx = (int) (dx * 256.0f); + auto intDx = (int) (dx * 256.0f); for (int i = bounds.getHeight(); --i >= 0;) { - int* line = lineStart; + auto* line = lineStart; lineStart += lineStrideElements; - int num = *line++; + auto num = *line++; while (--num >= 0) { @@ -482,12 +482,12 @@ void EdgeTable::translate (float dx, const int dy) noexcept void EdgeTable::multiplyLevels (float amount) { int* lineStart = table; - const int multiplier = (int) (amount * 256.0f); + auto multiplier = (int) (amount * 256.0f); for (int y = 0; y < bounds.getHeight(); ++y) { - int numPoints = lineStart[0]; - LineItem* item = reinterpret_cast (lineStart + 1); + auto numPoints = lineStart[0]; + auto* item = reinterpret_cast (lineStart + 1); lineStart += lineStrideElements; while (--numPoints > 0) @@ -502,13 +502,13 @@ void EdgeTable::intersectWithEdgeTableLine (const int y, const int* const otherL { jassert (y >= 0 && y < bounds.getHeight()); - int* srcLine = table + lineStrideElements * y; - int srcNum1 = *srcLine; + auto* srcLine = table + lineStrideElements * y; + auto srcNum1 = *srcLine; if (srcNum1 == 0) return; - int srcNum2 = *otherLine; + auto srcNum2 = *otherLine; if (srcNum2 == 0) { @@ -516,7 +516,7 @@ void EdgeTable::intersectWithEdgeTableLine (const int y, const int* const otherL return; } - const int right = bounds.getRight() << 8; + auto right = bounds.getRight() << 8; // optimise for the common case where our line lies entirely within a // single pair of points, as happens when clipping to a simple rect. @@ -529,10 +529,10 @@ void EdgeTable::intersectWithEdgeTableLine (const int y, const int* const otherL bool isUsingTempSpace = false; const int* src1 = srcLine + 1; - int x1 = *src1++; + auto x1 = *src1++; const int* src2 = otherLine + 1; - int x2 = *src2++; + auto x2 = *src2++; int destIndex = 0, destTotal = 0; int level1 = 0, level2 = 0; @@ -571,7 +571,7 @@ void EdgeTable::intersectWithEdgeTableLine (const int y, const int* const otherL lastX = nextX; - const int nextLevel = (level1 * (level2 + 1)) >> 8; + auto nextLevel = (level1 * (level2 + 1)) >> 8; jassert (isPositiveAndBelow (nextLevel, 256)); if (nextLevel != lastLevel) @@ -582,14 +582,14 @@ void EdgeTable::intersectWithEdgeTableLine (const int y, const int* const otherL if (isUsingTempSpace) { - const size_t tempSize = (size_t) srcNum1 * 2 * sizeof (int); - int* const oldTemp = static_cast (alloca (tempSize)); + auto tempSize = (size_t) srcNum1 * 2 * sizeof (int); + auto oldTemp = static_cast (alloca (tempSize)); memcpy (oldTemp, src1, tempSize); remapTableForNumEdges (jmax (256, destTotal * 2)); srcLine = table + lineStrideElements * y; - int* const newTemp = table + lineStrideElements * bounds.getHeight(); + auto* newTemp = table + lineStrideElements * bounds.getHeight(); memcpy (newTemp, oldTemp, tempSize); src1 = newTemp; } @@ -606,7 +606,7 @@ void EdgeTable::intersectWithEdgeTableLine (const int y, const int* const otherL if (! isUsingTempSpace) { isUsingTempSpace = true; - int* const temp = table + lineStrideElements * bounds.getHeight(); + auto* temp = table + lineStrideElements * bounds.getHeight(); memcpy (temp, src1, (size_t) srcNum1 * 2 * sizeof (int)); src1 = temp; } @@ -661,7 +661,7 @@ void EdgeTable::clipEdgeTableLineToRange (int* dest, const int x1, const int x2) while (lastItem[0] > x1) lastItem -= 2; - const int itemsRemoved = (int) (lastItem - (dest + 1)) / 2; + auto itemsRemoved = (int) (lastItem - (dest + 1)) / 2; if (itemsRemoved > 0) { @@ -677,7 +677,7 @@ void EdgeTable::clipEdgeTableLineToRange (int* dest, const int x1, const int x2) //============================================================================== void EdgeTable::clipToRectangle (const Rectangle& r) { - const Rectangle clipped (r.getIntersection (bounds)); + auto clipped = r.getIntersection (bounds); if (clipped.isEmpty()) { @@ -686,19 +686,19 @@ void EdgeTable::clipToRectangle (const Rectangle& r) } else { - const int top = clipped.getY() - bounds.getY(); - const int bottom = clipped.getBottom() - bounds.getY(); + auto top = clipped.getY() - bounds.getY(); + auto bottom = clipped.getBottom() - bounds.getY(); if (bottom < bounds.getHeight()) bounds.setHeight (bottom); - for (int i = top; --i >= 0;) - table [lineStrideElements * i] = 0; + for (int i = 0; i < top; ++i) + table[lineStrideElements * i] = 0; if (clipped.getX() > bounds.getX() || clipped.getRight() < bounds.getRight()) { - const int x1 = clipped.getX() << 8; - const int x2 = jmin (bounds.getRight(), clipped.getRight()) << 8; + auto x1 = clipped.getX() << 8; + auto x2 = jmin (bounds.getRight(), clipped.getRight()) << 8; int* line = table + lineStrideElements * top; for (int i = bottom - top; --i >= 0;) @@ -716,12 +716,12 @@ void EdgeTable::clipToRectangle (const Rectangle& r) void EdgeTable::excludeRectangle (const Rectangle& r) { - const Rectangle clipped (r.getIntersection (bounds)); + auto clipped = r.getIntersection (bounds); if (! clipped.isEmpty()) { - const int top = clipped.getY() - bounds.getY(); - const int bottom = clipped.getBottom() - bounds.getY(); + auto top = clipped.getY() - bounds.getY(); + auto bottom = clipped.getBottom() - bounds.getY(); const int rectLine[] = { 4, std::numeric_limits::min(), 255, clipped.getX() << 8, 0, @@ -737,7 +737,7 @@ void EdgeTable::excludeRectangle (const Rectangle& r) void EdgeTable::clipToEdgeTable (const EdgeTable& other) { - const Rectangle clipped (other.bounds.getIntersection (bounds)); + auto clipped = other.bounds.getIntersection (bounds); if (clipped.isEmpty()) { @@ -746,8 +746,8 @@ void EdgeTable::clipToEdgeTable (const EdgeTable& other) } else { - const int top = clipped.getY() - bounds.getY(); - const int bottom = clipped.getBottom() - bounds.getY(); + auto top = clipped.getY() - bounds.getY(); + auto bottom = clipped.getBottom() - bounds.getY(); if (bottom < bounds.getHeight()) bounds.setHeight (bottom); @@ -756,9 +756,9 @@ void EdgeTable::clipToEdgeTable (const EdgeTable& other) bounds.setRight (clipped.getRight()); for (int i = 0; i < top; ++i) - table [lineStrideElements * i] = 0; + table[lineStrideElements * i] = 0; - const int* otherLine = other.table + other.lineStrideElements * (clipped.getY() - other.bounds.getY()); + auto* otherLine = other.table + other.lineStrideElements * (clipped.getY() - other.bounds.getY()); for (int i = top; i < bottom; ++i) { @@ -781,16 +781,16 @@ void EdgeTable::clipLineToMask (int x, int y, const uint8* mask, int maskStride, if (numPixels <= 0) { - table [lineStrideElements * y] = 0; + table[lineStrideElements * y] = 0; return; } - int* tempLine = static_cast (alloca ((size_t) (numPixels * 2 + 4) * sizeof (int))); + auto* tempLine = static_cast (alloca ((size_t) (numPixels * 2 + 4) * sizeof (int))); int destIndex = 0, lastLevel = 0; while (--numPixels >= 0) { - const int alpha = *mask; + auto alpha = *mask; mask += maskStride; if (alpha != lastLevel) diff --git a/modules/juce_graphics/geometry/juce_EdgeTable.h b/modules/juce_graphics/geometry/juce_EdgeTable.h index 5311a894e2..e72ee6e07d 100644 --- a/modules/juce_graphics/geometry/juce_EdgeTable.h +++ b/modules/juce_graphics/geometry/juce_EdgeTable.h @@ -46,12 +46,15 @@ public: @param pathToAdd the path to add to the table @param transform a transform to apply to the path being added */ - EdgeTable (const Rectangle& clipLimits, + EdgeTable (Rectangle clipLimits, const Path& pathToAdd, const AffineTransform& transform); /** Creates an edge table containing a rectangle. */ - explicit EdgeTable (const Rectangle& rectangleToAdd); + explicit EdgeTable (Rectangle rectangleToAdd); + + /** Creates an edge table containing a rectangle. */ + explicit EdgeTable (Rectangle rectangleToAdd); /** Creates an edge table containing a rectangle list. */ explicit EdgeTable (const RectangleList& rectanglesToAdd); @@ -59,9 +62,6 @@ public: /** Creates an edge table containing a rectangle list. */ explicit EdgeTable (const RectangleList& rectanglesToAdd); - /** Creates an edge table containing a rectangle. */ - explicit EdgeTable (const Rectangle& rectangleToAdd); - /** Creates a copy of another edge table. */ EdgeTable (const EdgeTable&); @@ -202,13 +202,14 @@ private: HeapBlock table; Rectangle bounds; int maxEdgesPerLine, lineStrideElements; - bool needToCheckEmptiness; + bool needToCheckEmptiness = true; void allocate(); void clearLineSizes() noexcept; void addEdgePoint (int x, int y, int winding); void addEdgePointPair (int x1, int x2, int y, int winding); void remapTableForNumEdges (int newNumEdgesPerLine); + void remapWithExtraSpace (int numPointsNeeded); void intersectWithEdgeTableLine (int y, const int* otherLine); void clipEdgeTableLineToRange (int* line, int x1, int x2) noexcept; void sanitiseLevels (bool useNonZeroWinding) noexcept;