nanovg icon indicating copy to clipboard operation
nanovg copied to clipboard

Confusion about the filling rule.

Open unvestigate opened this issue 4 years ago • 3 comments

The documentation for NVG claims that "NanoVG uses even-odd filling rule and by default the paths are wound in counter clockwise order." It then goes on to describe how shapes should be wound CCW and holes CW. I am doing a little bit of research on how to render SVG images using NVG and all documentation I have found on the subject suggests that the Even-Odd filling rule does not care about the winding, while the Non-Zero rule does. Eg:

https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/fill-rule https://www.w3.org/TR/SVG2/painting.html#WindingRule https://en.wikipedia.org/wiki/Even%E2%80%93odd_rule

Also I am a bit confused what it means that "NanoVG uses even-odd filling rule" in the first place. It would seem to me that whether or not a shape is filled is determined by (and only by) the winding order of the shape points. Am I right, or does the NVG library actually perform any filling rule tests at runtime? (Ie. fire a ray in any direction and counting intersections etc.)

unvestigate avatar Dec 09 '20 11:12 unvestigate

Actually, it seems I misunderstood the NVG docs a little. In nvg__flattenPaths() there is a piece of code labeled "Enforce winding" which makes sure the winding is what the path->winding variable specifies. Because of this it seems like the winding for shapes fed into NVG doesn't really matter, only the winding set with nvgPathWinding().

The docs make it seem like you can create holes by feeding shapes with CW winding into NVG: "In order to wind one of the predefined shapes as a hole, you should call nvgPathWinding(vg, NVG_HOLE)". (Emphasis on predefined by me).

Anyway, my original question remains. Does NVG perform any kind of even-odd filling rule logic, or is the solidness of a shape determined by the winding only?

unvestigate avatar Dec 09 '20 12:12 unvestigate

Hey, I've also stumbled across this today. From my testing, it seems that nanovg actually uses the non-zero fill rule: nvg-non-zero

(The documentation for nvgArc is wrong too: It does not start a new path. You have to nvgMoveTo manually.)

leddoo avatar Jul 22 '21 14:07 leddoo

Oh, by the way: NVG_SOLID == NVG_CCW and NVG_HOLE == NVG_CW.

leddoo avatar Jul 22 '21 14:07 leddoo