Open AaronDavidNewman opened 1 year ago
This is the initial text from this issue:
I can't get the tempos in my music to look right, if I am using a custom web font for the text, because the font is lazy loaded and the wrong font is used for estimation.
The only way I have found to do this properly is to append to an HTML element, measure it, and remove it, and make sure that the second text element falls after that. Or to use a custom SVGForeign element of the two HTML Elements.
(the particular solution in this case, though, is not to encourage people to play music arrogantly. there's enough of that in music as it is. :-D )
Ha! Not my tune, but yeah a bit overdone.
I suppose the html and canvas ideas are similar. Canvas might be faster since it's a pure raster operation and doesn't affect the flow.
I wonder why the browser doesn't just expose an API to get metrics without having to draw anything - it must know what they are. There must be some technical or security reason I don't understand, I'm sure other people have asked for it.
In #1466 I prototyped the idea from @ronyeh to use the font directly. I did it only for noteheadBlack, see latest commit https://github.com/0xfe/vexflow/commit/7be6d555796ef1d26f30ee87942f25cfa8fefd85 . The result is also very promising.
noteheadBlack rendered as a font
current svg path generation approach
The size of the SVGs produced by flow.html is reduced by 10MB as each print out of a notehead is now simply
<text stroke="none" x="317.11" y="110"></text>
rather than
<path stroke="none" d="M321.041 115.054C324.636 115.054,329.044 111.741,329.044 108.315C329.044
106.237,327.416 104.946,325.113 104.946C320.676 104.946,317.11 108.231,317.11 111.685C317.11
113.791,318.851 115.054,321.041 115.054"></path>
Yes! I never had time to look into just using the Bravura / Petaluma / Leland OTF files directly, but it would be cool for sure. Not sure if we could make it a backwards compatible upgrade. Or it might just be for VexFlow 5. :-)
Does using the font for the note head speed rendering also? The size of the SVG is definitely a problem for me. That is probably worthy of its own issue.
Unfortunately we don't have any good large-scale renders for benchmarking in native vex format. We need a Mahler symphony or something. I have a few of my big-band charts and I'd like to get them, at least a few pages, into vex code. We probably don't run them as part of the unit tests but they could be seperate.
I can extend my prototype to use the font approach for Bravura. This is easy. I can also use VexMl to convert a MusicXML score to VexFlow factory API. This is also easy although VexMl is not complete and some elements will be missing. I would need that @ronyeh releases a new Alpha to get more completeness.
@AaronDavidNewman I have reopen #1466 as draft so that you can look at the details in the prototype:
Prototype flow.html
Master flow.html
10MB less and 600ms less :+1:
I don't think removing TextFormatter is related to reading music font directly. Is the latter change in 466? I thought that was only about text fonts. Which file reads the music fonts directly?
I tried to make a minor change on master but TextFormatter was causing a runtime error. I did not investigate further. The important changes are glyph.ts, the list of WEB_FONT_FILES in font.ts and the change in textfonts.ts.
I started this with a specific issue in mind, but this quickly became a larger discussion in some PRs, so we are moving the discussion here.
Introduction
In many cases we need to know metrics of text font files to place and render them with music glyphs. Drawing and measuring the text has some problems: 1) during the format part of the pipeline, the rendering context isn't available, and 2) rendering anything on the VF renderer canvas/svg can cause a reflow which will greatly slow down the rendering of large scores (especially in SVG).
Summary of the Proposals
There are a couple of solutions to this that have been introduced, each has its own drawbacks: