|
|
@@ -28,15 +28,12 @@ namespace juce |
|
|
|
|
|
|
|
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (6255 6263 6386)
|
|
|
|
|
|
|
|
const int juce_edgeTableDefaultEdgesPerLine = 32;
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
EdgeTable::EdgeTable (Rectangle<int> area, const Path& path, const AffineTransform& transform)
|
|
|
|
: bounds (area),
|
|
|
|
// this is a very vague heuristic to make a rough guess at a good table size
|
|
|
|
// 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,
|
|
|
|
maxEdgesPerLine (jmax (defaultEdgesPerLine / 2,
|
|
|
|
4 * (int) std::sqrt (path.data.size()))),
|
|
|
|
lineStrideElements (maxEdgesPerLine * 2 + 1)
|
|
|
|
{
|
|
|
@@ -49,10 +46,10 @@ EdgeTable::EdgeTable (Rectangle<int> area, const Path& path, const AffineTransfo |
|
|
|
t += lineStrideElements;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto leftLimit = bounds.getX() * 256;
|
|
|
|
auto topLimit = bounds.getY() * 256;
|
|
|
|
auto rightLimit = bounds.getRight() * 256;
|
|
|
|
auto heightLimit = bounds.getHeight() * 256;
|
|
|
|
auto leftLimit = scale * bounds.getX();
|
|
|
|
auto topLimit = scale * bounds.getY();
|
|
|
|
auto rightLimit = scale * bounds.getRight();
|
|
|
|
auto heightLimit = scale * bounds.getHeight();
|
|
|
|
|
|
|
|
PathFlatteningIterator iter (path, transform);
|
|
|
|
|
|
|
@@ -97,7 +94,7 @@ EdgeTable::EdgeTable (Rectangle<int> area, const Path& path, const AffineTransfo |
|
|
|
else if (x >= rightLimit)
|
|
|
|
x = rightLimit - 1;
|
|
|
|
|
|
|
|
addEdgePoint (x, y1 >> 8, direction * step);
|
|
|
|
addEdgePoint (x, y1 / scale, direction * step);
|
|
|
|
y1 += step;
|
|
|
|
}
|
|
|
|
while (y1 < y2);
|
|
|
@@ -110,14 +107,14 @@ EdgeTable::EdgeTable (Rectangle<int> area, const Path& path, const AffineTransfo |
|
|
|
|
|
|
|
EdgeTable::EdgeTable (Rectangle<int> rectangleToAdd)
|
|
|
|
: bounds (rectangleToAdd),
|
|
|
|
maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine),
|
|
|
|
lineStrideElements (juce_edgeTableDefaultEdgesPerLine * 2 + 1)
|
|
|
|
maxEdgesPerLine (defaultEdgesPerLine),
|
|
|
|
lineStrideElements (defaultEdgesPerLine * 2 + 1)
|
|
|
|
{
|
|
|
|
allocate();
|
|
|
|
table[0] = 0;
|
|
|
|
|
|
|
|
auto x1 = rectangleToAdd.getX() << 8;
|
|
|
|
auto x2 = rectangleToAdd.getRight() << 8;
|
|
|
|
auto x1 = scale * rectangleToAdd.getX();
|
|
|
|
auto x2 = scale * rectangleToAdd.getRight();
|
|
|
|
int* t = table;
|
|
|
|
|
|
|
|
for (int i = rectangleToAdd.getHeight(); --i >= 0;)
|
|
|
@@ -133,8 +130,8 @@ EdgeTable::EdgeTable (Rectangle<int> rectangleToAdd) |
|
|
|
|
|
|
|
EdgeTable::EdgeTable (const RectangleList<int>& rectanglesToAdd)
|
|
|
|
: bounds (rectanglesToAdd.getBounds()),
|
|
|
|
maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine),
|
|
|
|
lineStrideElements (juce_edgeTableDefaultEdgesPerLine * 2 + 1),
|
|
|
|
maxEdgesPerLine (defaultEdgesPerLine),
|
|
|
|
lineStrideElements (defaultEdgesPerLine * 2 + 1),
|
|
|
|
needToCheckEmptiness (true)
|
|
|
|
{
|
|
|
|
allocate();
|
|
|
@@ -142,8 +139,8 @@ EdgeTable::EdgeTable (const RectangleList<int>& rectanglesToAdd) |
|
|
|
|
|
|
|
for (auto& r : rectanglesToAdd)
|
|
|
|
{
|
|
|
|
auto x1 = r.getX() << 8;
|
|
|
|
auto x2 = r.getRight() << 8;
|
|
|
|
auto x1 = scale * r.getX();
|
|
|
|
auto x2 = scale * r.getRight();
|
|
|
|
auto y = r.getY() - bounds.getY();
|
|
|
|
|
|
|
|
for (int j = r.getHeight(); --j >= 0;)
|
|
|
@@ -164,17 +161,17 @@ EdgeTable::EdgeTable (const RectangleList<float>& rectanglesToAdd) |
|
|
|
|
|
|
|
for (auto& r : rectanglesToAdd)
|
|
|
|
{
|
|
|
|
auto x1 = roundToInt (r.getX() * 256.0f);
|
|
|
|
auto x2 = roundToInt (r.getRight() * 256.0f);
|
|
|
|
auto x1 = roundToInt ((float) scale * r.getX());
|
|
|
|
auto x2 = roundToInt ((float) scale * r.getRight());
|
|
|
|
|
|
|
|
auto y1 = roundToInt (r.getY() * 256.0f) - (bounds.getY() << 8);
|
|
|
|
auto y2 = roundToInt (r.getBottom() * 256.0f) - (bounds.getY() << 8);
|
|
|
|
auto y1 = roundToInt ((float) scale * r.getY()) - (bounds.getY() * scale);
|
|
|
|
auto y2 = roundToInt ((float) scale * r.getBottom()) - (bounds.getY() * scale);
|
|
|
|
|
|
|
|
if (x2 <= x1 || y2 <= y1)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
auto y = y1 >> 8;
|
|
|
|
auto lastLine = y2 >> 8;
|
|
|
|
auto y = y1 / scale;
|
|
|
|
auto lastLine = y2 / scale;
|
|
|
|
|
|
|
|
if (y == lastLine)
|
|
|
|
{
|
|
|
@@ -197,20 +194,20 @@ EdgeTable::EdgeTable (const RectangleList<float>& rectanglesToAdd) |
|
|
|
|
|
|
|
EdgeTable::EdgeTable (Rectangle<float> rectangleToAdd)
|
|
|
|
: bounds ((int) std::floor (rectangleToAdd.getX()),
|
|
|
|
roundToInt (rectangleToAdd.getY() * 256.0f) >> 8,
|
|
|
|
roundToInt (rectangleToAdd.getY() * 256.0f) / scale,
|
|
|
|
2 + (int) rectangleToAdd.getWidth(),
|
|
|
|
2 + (int) rectangleToAdd.getHeight()),
|
|
|
|
maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine),
|
|
|
|
lineStrideElements ((juce_edgeTableDefaultEdgesPerLine * 2) + 1)
|
|
|
|
maxEdgesPerLine (defaultEdgesPerLine),
|
|
|
|
lineStrideElements ((defaultEdgesPerLine * 2) + 1)
|
|
|
|
{
|
|
|
|
jassert (! rectangleToAdd.isEmpty());
|
|
|
|
allocate();
|
|
|
|
table[0] = 0;
|
|
|
|
|
|
|
|
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);
|
|
|
|
auto x1 = roundToInt ((float) scale * rectangleToAdd.getX());
|
|
|
|
auto x2 = roundToInt ((float) scale * rectangleToAdd.getRight());
|
|
|
|
auto y1 = roundToInt ((float) scale * rectangleToAdd.getY()) - (bounds.getY() * scale);
|
|
|
|
auto y2 = roundToInt ((float) scale * rectangleToAdd.getBottom()) - (bounds.getY() * scale);
|
|
|
|
jassert (y1 < 256);
|
|
|
|
|
|
|
|
if (x2 <= x1 || y2 <= y1)
|
|
|
@@ -222,7 +219,7 @@ EdgeTable::EdgeTable (Rectangle<float> rectangleToAdd) |
|
|
|
int lineY = 0;
|
|
|
|
int* t = table;
|
|
|
|
|
|
|
|
if ((y1 >> 8) == (y2 >> 8))
|
|
|
|
if ((y1 / scale) == (y2 / scale))
|
|
|
|
{
|
|
|
|
t[0] = 2;
|
|
|
|
t[1] = x1;
|
|
|
@@ -242,7 +239,7 @@ EdgeTable::EdgeTable (Rectangle<float> rectangleToAdd) |
|
|
|
++lineY;
|
|
|
|
t += lineStrideElements;
|
|
|
|
|
|
|
|
while (lineY < (y2 >> 8))
|
|
|
|
while (lineY < (y2 / scale))
|
|
|
|
{
|
|
|
|
t[0] = 2;
|
|
|
|
t[1] = x1;
|
|
|
@@ -361,7 +358,7 @@ void EdgeTable::sanitiseLevels (const bool useNonZeroWinding) noexcept |
|
|
|
|
|
|
|
auto corrected = std::abs (level);
|
|
|
|
|
|
|
|
if (corrected >> 8)
|
|
|
|
if (corrected / scale)
|
|
|
|
{
|
|
|
|
if (useNonZeroWinding)
|
|
|
|
{
|
|
|
@@ -371,7 +368,7 @@ void EdgeTable::sanitiseLevels (const bool useNonZeroWinding) noexcept |
|
|
|
{
|
|
|
|
corrected &= 511;
|
|
|
|
|
|
|
|
if (corrected >> 8)
|
|
|
|
if (corrected / scale)
|
|
|
|
corrected = 511 - corrected;
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -497,7 +494,7 @@ void EdgeTable::multiplyLevels (float amount) |
|
|
|
|
|
|
|
while (--numPoints > 0)
|
|
|
|
{
|
|
|
|
item->level = jmin (255, (item->level * multiplier) >> 8);
|
|
|
|
item->level = jmin (255, (item->level * multiplier) / scale);
|
|
|
|
++item;
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -521,7 +518,7 @@ void EdgeTable::intersectWithEdgeTableLine (const int y, const int* const otherL |
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto right = bounds.getRight() << 8;
|
|
|
|
auto right = bounds.getRight() * scale;
|
|
|
|
|
|
|
|
// optimise for the common case where our line lies entirely within a
|
|
|
|
// single pair of points, as happens when clipping to a simple rect.
|
|
|
@@ -576,7 +573,7 @@ void EdgeTable::intersectWithEdgeTableLine (const int y, const int* const otherL |
|
|
|
|
|
|
|
lastX = nextX;
|
|
|
|
|
|
|
|
auto nextLevel = (level1 * (level2 + 1)) >> 8;
|
|
|
|
auto nextLevel = (level1 * (level2 + 1)) / scale;
|
|
|
|
jassert (isPositiveAndBelow (nextLevel, 256));
|
|
|
|
|
|
|
|
if (nextLevel != lastLevel)
|
|
|
@@ -702,8 +699,8 @@ void EdgeTable::clipToRectangle (Rectangle<int> r) |
|
|
|
|
|
|
|
if (clipped.getX() > bounds.getX() || clipped.getRight() < bounds.getRight())
|
|
|
|
{
|
|
|
|
auto x1 = clipped.getX() << 8;
|
|
|
|
auto x2 = jmin (bounds.getRight(), clipped.getRight()) << 8;
|
|
|
|
auto x1 = scale * clipped.getX();
|
|
|
|
auto x2 = scale * jmin (bounds.getRight(), clipped.getRight());
|
|
|
|
int* line = table + lineStrideElements * top;
|
|
|
|
|
|
|
|
for (int i = bottom - top; --i >= 0;)
|
|
|
@@ -729,8 +726,8 @@ void EdgeTable::excludeRectangle (Rectangle<int> r) |
|
|
|
auto bottom = clipped.getBottom() - bounds.getY();
|
|
|
|
|
|
|
|
const int rectLine[] = { 4, std::numeric_limits<int>::min(), 255,
|
|
|
|
clipped.getX() << 8, 0,
|
|
|
|
clipped.getRight() << 8, 255,
|
|
|
|
scale * clipped.getX(), 0,
|
|
|
|
scale * clipped.getRight(), 255,
|
|
|
|
std::numeric_limits<int>::max(), 0 };
|
|
|
|
|
|
|
|
for (int i = top; i < bottom; ++i)
|
|
|
@@ -800,7 +797,7 @@ void EdgeTable::clipLineToMask (int x, int y, const uint8* mask, int maskStride, |
|
|
|
|
|
|
|
if (alpha != lastLevel)
|
|
|
|
{
|
|
|
|
tempLine[++destIndex] = (x << 8);
|
|
|
|
tempLine[++destIndex] = (x * scale);
|
|
|
|
tempLine[++destIndex] = alpha;
|
|
|
|
lastLevel = alpha;
|
|
|
|
}
|
|
|
@@ -810,7 +807,7 @@ void EdgeTable::clipLineToMask (int x, int y, const uint8* mask, int maskStride, |
|
|
|
|
|
|
|
if (lastLevel > 0)
|
|
|
|
{
|
|
|
|
tempLine[++destIndex] = (x << 8);
|
|
|
|
tempLine[++destIndex] = (x * scale);
|
|
|
|
tempLine[++destIndex] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|