nanovg
nanovg copied to clipboard
nvgArc draws an unexpected line
Since nvgArc
is a "shape" API call, I wouldn't expect it to draw a line from the current position to the beginning of the arc, which is what I'm seeing right now. I can encounter this behavior when drawing some lines with moveTo
and lineTo
and then calling drawArc
. I suspect this is not intentional and I've tracked it down to this line:
int move = ctx->ncommands > 0 ? NVG_LINETO : NVG_MOVETO;
The problem goes away if I hardcode that to just NVG_MOVETO, but I think that will break arcTo
behavior.
The solution should be adding some knowledge to the conditional so it knows if the function was called by itself or from arcTo somehow. Adding an argument would come out as odd to external users of the API, so I suppose something like a global state flag would have to be employed, unless I'm missing a cleaner way? (Edit: I suppose creating an "internal" nvgArc
and calling that from both the actual nvgArc
and nvgArcTo
would be one possible solution too)
An example demonstrating the problem:
Current behavior:
Expected behavior:
I fixed this in our internal fork by renaming the current nvgArc
function to a non-exposed nvg__Arc
function:
void nvg__Arc(struct NVGcontext* ctx, float cx, float cy, float r, float a0, float a1, int dir, NVGcommands firstCommand)
With this, firstCommand
replaces the move
var inside.
nvgArc
now just calls nvg__Arc
like so:
void nvgArc(struct NVGcontext* ctx, float cx, float cy, float r, float a0, float a1, int dir)
{
nvg__Arc(ctx, cx, cy, r, a0, a1, dir, NVG_MOVETO);
}
nvgArcTo
now calls nvg__Arc
with the previous logic for firstCommand
:
nvg__Arc(ctx, cx, cy, radius, a0, a1, dir, ctx->ncommands > 0 ? NVG_LINETO : NVG_MOVETO);
I believe something along those lines would be the best way to avoid this problem.
Hi @SmilyOrg where is this internal fork? I'm working with nanovg's arcs and I'm having a hard time with that too!
Thanks!
First up I don't think nvgArc
is supposed to be a standalone call. You can make it one, by issueing a nvgMoveTo
call before calling it though. As far as I know nanovg tries to mirror HTML5 canvas
for better and for worse. Therefore the Mozilla documentation for arcTo and arc can be very helpful to understand how both functions are supposed to work. arcTo
is considered sort of broken even in HTML5 and seems to be merely useful for drawing rounded rectangles and not much more.
My OP was 9 years ago! 🤯
@mulle-nat I think you may be right and this is actually expected behavior, but it wasn't that expected to me back then 😅
@GPrimola the above points considered, if you're still interested in the fork (well, it's more like a vendored copy), it's actually public and still online, here you go: https://github.com/LoomSDK/LoomSDK/blame/c6ff83f99b313f402326948c57661908933dabdd/loom/vendor/nanovg/src/nanovg.c#L1942-L1996