vexflow
vexflow copied to clipboard
SVGContext's scale(x, y) works differently from CanvasContext's scale(x,y)
While migrating tests, I encountered a weird bit of code in NoteHeadTests:
https://github.com/0xfe/vexflow/blob/b37ddd7a228c69b165c96f4431598b703585fc37/tests/notehead_tests.ts#L34-L62
The setupContext() scales the context to 0.9, 0.9. The basic() test case applies another scale of 2.0, 2.0. (It also ignores the stave created by setupContext and creates its own stave, but that's another story.)
The scaling transformation should be multiplied against the existing scale: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/scale
So 0.9 * 2.0 => 1.8 final scale.
flow.html
shows that the Canvas renderer works as expected, but the SVG renderer sets the final scale to 2.0, 2.0.
The fix might be straightforward. In SVGContext's scale method, we have:
this.state.scale = { x, y };
We probably just need to multiply it into the existing scale.
This bug has existed for a while, as it repros on vexflow.com: https://www.vexflow.com/tests/?module=NoteHead
You can verify the bug by doing something like this:
ctx.scale(2.0, 2.0);
ctx.scale(0.5, 0.5);
ctx.scale(2.0, 2.0);
ctx.scale(0.5, 0.5);
The final output will look like:

That is a bug -- and great catch! It's an implementation detail I never realized.
I think we should fix it for correctness, however practically, scale
is just called once on a new renderer.
@ronyeh you wanted to correct that in 4.1