| @@ -78829,8 +78829,7 @@ EdgeTable::EdgeTable (const int top_, const int height_) throw() | |||||
| : top (top_), | : top (top_), | ||||
| height (height_), | height (height_), | ||||
| maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine), | maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine), | ||||
| lineStrideElements ((juce_edgeTableDefaultEdgesPerLine << 1) + 1), | |||||
| nonZeroWinding (true) | |||||
| lineStrideElements ((juce_edgeTableDefaultEdgesPerLine << 1) + 1) | |||||
| { | { | ||||
| table = (int*) juce_calloc (height * lineStrideElements * sizeof (int)); | table = (int*) juce_calloc (height * lineStrideElements * sizeof (int)); | ||||
| } | } | ||||
| @@ -78849,7 +78848,6 @@ const EdgeTable& EdgeTable::operator= (const EdgeTable& other) throw() | |||||
| height = other.height; | height = other.height; | ||||
| maxEdgesPerLine = other.maxEdgesPerLine; | maxEdgesPerLine = other.maxEdgesPerLine; | ||||
| lineStrideElements = other.lineStrideElements; | lineStrideElements = other.lineStrideElements; | ||||
| nonZeroWinding = other.nonZeroWinding; | |||||
| const int tableSize = height * lineStrideElements * sizeof (int); | const int tableSize = height * lineStrideElements * sizeof (int); | ||||
| table = (int*) juce_malloc (tableSize); | table = (int*) juce_malloc (tableSize); | ||||
| @@ -78938,10 +78936,8 @@ void EdgeTable::addEdgePoint (const int x, const int y, const int winding) throw | |||||
| lineStart[0]++; | lineStart[0]++; | ||||
| } | } | ||||
| void EdgeTable::addPath (const Path& path, | |||||
| const AffineTransform& transform) throw() | |||||
| void EdgeTable::addPath (const Path& path, const AffineTransform& transform) throw() | |||||
| { | { | ||||
| nonZeroWinding = path.isUsingNonZeroWinding(); | |||||
| const int bottomLimit = height << 8; | const int bottomLimit = height << 8; | ||||
| PathFlatteningIterator iter (path, transform); | PathFlatteningIterator iter (path, transform); | ||||
| @@ -78953,6 +78949,7 @@ void EdgeTable::addPath (const Path& path, | |||||
| if (y1 != y2) | if (y1 != y2) | ||||
| { | { | ||||
| const int oldY1 = y1; | |||||
| const double x1 = 256.0 * iter.x1; | const double x1 = 256.0 * iter.x1; | ||||
| const double x2 = 256.0 * iter.x2; | const double x2 = 256.0 * iter.x2; | ||||
| const double multiplier = (x2 - x1) / (y2 - y1); | const double multiplier = (x2 - x1) / (y2 - y1); | ||||
| @@ -78970,7 +78967,6 @@ void EdgeTable::addPath (const Path& path, | |||||
| if (y2 > bottomLimit) | if (y2 > bottomLimit) | ||||
| y2 = bottomLimit; | y2 = bottomLimit; | ||||
| const int oldY1 = y1; | |||||
| const int stepSize = jlimit (1, 256, 256 / (1 + abs ((int) multiplier))); | const int stepSize = jlimit (1, 256, 256 / (1 + abs ((int) multiplier))); | ||||
| while (y1 < y2) | while (y1 < y2) | ||||
| @@ -78984,6 +78980,36 @@ void EdgeTable::addPath (const Path& path, | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (! path.isUsingNonZeroWinding()) | |||||
| { | |||||
| int* lineStart = table; | |||||
| for (int i = height; --i >= 0;) | |||||
| { | |||||
| int* line = lineStart; | |||||
| lineStart += lineStrideElements; | |||||
| int num = *line; | |||||
| int level = 0; | |||||
| int lastCorrected = 0; | |||||
| while (--num >= 0) | |||||
| { | |||||
| line += 2; | |||||
| level += *line; | |||||
| int corrected = abs (level); | |||||
| if (corrected >> 8) | |||||
| { | |||||
| corrected &= 511; | |||||
| if (corrected >> 8) | |||||
| corrected = 511 - corrected; | |||||
| } | |||||
| *line = corrected - lastCorrected; | |||||
| lastCorrected = corrected; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | } | ||||
| /*void EdgeTable::clipToRectangle (const Rectangle& r) throw() | /*void EdgeTable::clipToRectangle (const Rectangle& r) throw() | ||||
| @@ -266085,7 +266111,11 @@ public: | |||||
| flip(); | flip(); | ||||
| applyTransform (transform); | applyTransform (transform); | ||||
| createPath (path); | createPath (path); | ||||
| CGContextFillPath (context); | |||||
| if (path.isUsingNonZeroWinding()) | |||||
| CGContextFillPath (context); | |||||
| else | |||||
| CGContextEOFillPath (context); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -17092,10 +17092,10 @@ public: | |||||
| A table is created with a fixed vertical size, and only sections of paths | A table is created with a fixed vertical size, and only sections of paths | ||||
| which lie within their range will be added to the table. | which lie within their range will be added to the table. | ||||
| @param topY the lowest y co-ordinate that the table can contain | |||||
| @param height the number of horizontal lines it can contain | |||||
| @param y the lowest y co-ordinate that the table can contain | |||||
| @param height the number of horizontal lines it contains | |||||
| */ | */ | ||||
| EdgeTable (const int topY, const int height) throw(); | |||||
| EdgeTable (const int y, const int height) throw(); | |||||
| /** Creates a copy of another edge table. */ | /** Creates a copy of another edge table. */ | ||||
| EdgeTable (const EdgeTable& other) throw(); | EdgeTable (const EdgeTable& other) throw(); | ||||
| @@ -17179,18 +17179,7 @@ public: | |||||
| { | { | ||||
| int correctedLevel = abs (level); | int correctedLevel = abs (level); | ||||
| if (correctedLevel >> 8) | if (correctedLevel >> 8) | ||||
| { | |||||
| if (nonZeroWinding) | |||||
| { | |||||
| correctedLevel = 0xff; | |||||
| } | |||||
| else | |||||
| { | |||||
| correctedLevel &= 511; | |||||
| if (correctedLevel >> 8) | |||||
| correctedLevel = 511 - correctedLevel; | |||||
| } | |||||
| } | |||||
| correctedLevel = 0xff; | |||||
| const int endX = subPixelXOffset + *++line; | const int endX = subPixelXOffset + *++line; | ||||
| jassert (endX >= x); | jassert (endX >= x); | ||||
| @@ -37,8 +37,7 @@ EdgeTable::EdgeTable (const int top_, const int height_) throw() | |||||
| : top (top_), | : top (top_), | ||||
| height (height_), | height (height_), | ||||
| maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine), | maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine), | ||||
| lineStrideElements ((juce_edgeTableDefaultEdgesPerLine << 1) + 1), | |||||
| nonZeroWinding (true) | |||||
| lineStrideElements ((juce_edgeTableDefaultEdgesPerLine << 1) + 1) | |||||
| { | { | ||||
| table = (int*) juce_calloc (height * lineStrideElements * sizeof (int)); | table = (int*) juce_calloc (height * lineStrideElements * sizeof (int)); | ||||
| } | } | ||||
| @@ -57,7 +56,6 @@ const EdgeTable& EdgeTable::operator= (const EdgeTable& other) throw() | |||||
| height = other.height; | height = other.height; | ||||
| maxEdgesPerLine = other.maxEdgesPerLine; | maxEdgesPerLine = other.maxEdgesPerLine; | ||||
| lineStrideElements = other.lineStrideElements; | lineStrideElements = other.lineStrideElements; | ||||
| nonZeroWinding = other.nonZeroWinding; | |||||
| const int tableSize = height * lineStrideElements * sizeof (int); | const int tableSize = height * lineStrideElements * sizeof (int); | ||||
| table = (int*) juce_malloc (tableSize); | table = (int*) juce_malloc (tableSize); | ||||
| @@ -149,10 +147,8 @@ void EdgeTable::addEdgePoint (const int x, const int y, const int winding) throw | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void EdgeTable::addPath (const Path& path, | |||||
| const AffineTransform& transform) throw() | |||||
| void EdgeTable::addPath (const Path& path, const AffineTransform& transform) throw() | |||||
| { | { | ||||
| nonZeroWinding = path.isUsingNonZeroWinding(); | |||||
| const int bottomLimit = height << 8; | const int bottomLimit = height << 8; | ||||
| PathFlatteningIterator iter (path, transform); | PathFlatteningIterator iter (path, transform); | ||||
| @@ -164,6 +160,7 @@ void EdgeTable::addPath (const Path& path, | |||||
| if (y1 != y2) | if (y1 != y2) | ||||
| { | { | ||||
| const int oldY1 = y1; | |||||
| const double x1 = 256.0 * iter.x1; | const double x1 = 256.0 * iter.x1; | ||||
| const double x2 = 256.0 * iter.x2; | const double x2 = 256.0 * iter.x2; | ||||
| const double multiplier = (x2 - x1) / (y2 - y1); | const double multiplier = (x2 - x1) / (y2 - y1); | ||||
| @@ -181,7 +178,6 @@ void EdgeTable::addPath (const Path& path, | |||||
| if (y2 > bottomLimit) | if (y2 > bottomLimit) | ||||
| y2 = bottomLimit; | y2 = bottomLimit; | ||||
| const int oldY1 = y1; | |||||
| const int stepSize = jlimit (1, 256, 256 / (1 + abs ((int) multiplier))); | const int stepSize = jlimit (1, 256, 256 / (1 + abs ((int) multiplier))); | ||||
| while (y1 < y2) | while (y1 < y2) | ||||
| @@ -195,6 +191,36 @@ void EdgeTable::addPath (const Path& path, | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (! path.isUsingNonZeroWinding()) | |||||
| { | |||||
| int* lineStart = table; | |||||
| for (int i = height; --i >= 0;) | |||||
| { | |||||
| int* line = lineStart; | |||||
| lineStart += lineStrideElements; | |||||
| int num = *line; | |||||
| int level = 0; | |||||
| int lastCorrected = 0; | |||||
| while (--num >= 0) | |||||
| { | |||||
| line += 2; | |||||
| level += *line; | |||||
| int corrected = abs (level); | |||||
| if (corrected >> 8) | |||||
| { | |||||
| corrected &= 511; | |||||
| if (corrected >> 8) | |||||
| corrected = 511 - corrected; | |||||
| } | |||||
| *line = corrected - lastCorrected; | |||||
| lastCorrected = corrected; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | } | ||||
| /*void EdgeTable::clipToRectangle (const Rectangle& r) throw() | /*void EdgeTable::clipToRectangle (const Rectangle& r) throw() | ||||
| @@ -47,10 +47,10 @@ public: | |||||
| A table is created with a fixed vertical size, and only sections of paths | A table is created with a fixed vertical size, and only sections of paths | ||||
| which lie within their range will be added to the table. | which lie within their range will be added to the table. | ||||
| @param topY the lowest y co-ordinate that the table can contain | |||||
| @param height the number of horizontal lines it can contain | |||||
| @param y the lowest y co-ordinate that the table can contain | |||||
| @param height the number of horizontal lines it contains | |||||
| */ | */ | ||||
| EdgeTable (const int topY, const int height) throw(); | |||||
| EdgeTable (const int y, const int height) throw(); | |||||
| /** Creates a copy of another edge table. */ | /** Creates a copy of another edge table. */ | ||||
| EdgeTable (const EdgeTable& other) throw(); | EdgeTable (const EdgeTable& other) throw(); | ||||
| @@ -137,18 +137,7 @@ public: | |||||
| { | { | ||||
| int correctedLevel = abs (level); | int correctedLevel = abs (level); | ||||
| if (correctedLevel >> 8) | if (correctedLevel >> 8) | ||||
| { | |||||
| if (nonZeroWinding) | |||||
| { | |||||
| correctedLevel = 0xff; | |||||
| } | |||||
| else | |||||
| { | |||||
| correctedLevel &= 511; | |||||
| if (correctedLevel >> 8) | |||||
| correctedLevel = 511 - correctedLevel; | |||||
| } | |||||
| } | |||||
| correctedLevel = 0xff; | |||||
| const int endX = subPixelXOffset + *++line; | const int endX = subPixelXOffset + *++line; | ||||
| jassert (endX >= x); | jassert (endX >= x); | ||||
| @@ -196,7 +196,11 @@ public: | |||||
| flip(); | flip(); | ||||
| applyTransform (transform); | applyTransform (transform); | ||||
| createPath (path); | createPath (path); | ||||
| CGContextFillPath (context); | |||||
| if (path.isUsingNonZeroWinding()) | |||||
| CGContextFillPath (context); | |||||
| else | |||||
| CGContextEOFillPath (context); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||