observation:
I have the following code inside paint():
Path clipPath;
clipPath.setUsingNonZeroWinding(false);
clipPath.addEllipse(getLocalBounds().toFloat());
clipPath.addRoundedRectangle(getLocalBounds(), 5.0f);
g.reduceClipRegion(clipPath);
g.setColour(Colours::black);
g.fillAll();
The OpenGL renderer produces the following output:
The CoreGraphicsRenderer produces this:
expected: both renderers should produce (virtually) the same output.
discussion: CoreGraphicsContext::clipToPath() uses CGContextClip to set the clip path. CGContext clip uses “[…] the winding-number fill rule for deciding what’s inside the path”. But there is also CGContextEOClip which uses “[…] the even-odd fill rule for deciding what’s inside the path”. The documentation of setUsingNonZeroWinding() states: “If set to false, it uses an alternate-winding rule.”. Iff alternate-winding rule means the same as even-odd fill rule, then the following fix is proposed:
fix: change CoreGraphicsContext::clipToPath to:
void CoreGraphicsContext::clipToPath (const Path& path, const AffineTransform& transform)
{
createPath (path, transform);
if(path.isUsingNonZeroWinding())
CGContextClip (context);
else
CGContextEOClip (context);
lastClipRectIsValid = false;
}
Note: CoreGraphicsContext::fillPath() is doing:
...
if (path.isUsingNonZeroWinding())
CGContextFillPath (context);
else
CGContextEOFillPath (context);
...
Which further supports, that the suggested fix is correct.
@jules patch attachedfix_CoreGraphicsContext_clipToPath.mm (728 Bytes) (rename to .patch)