I recently switched SilverNode from NanoVG to vg-renderer, which was a fun experience. The API is good, and I like the library. I did however run into a few problems which I fixed along the way. This is a PR with all the fixes and improvements.
Notably, regarding fontstash, there is a problem with the way the kern array was constructed if the range of ASCII characters is huge. A font I was testing with has some ASCII letters in really low glyph indexes, and some other ASCII characters in really high glyph indices. The result was a range of 2500 glyphs. The kern array gets allocated as the square of that, which was super slow to both allocate and then fill the kern array with 2500*2500 looked up kern values.
So to fix this, I did four things:
introduce an inverse mapping from glyph index to codepoint to be able to compact the kern array to be really only 100*100 approximately for only the selected range within ASCII.
reduce the kerning array datatype from int to int16_t.
use Rosenberg-Strong's pairing function as indexing scheme to map a glyph-glyph pair to an index, in an attempt to get more relevant entries in the table to be closer together: .
introduce a 2-bit-per-glyph caching system that can optimize performance for other glyph combinations to remember whether the kerning was zero or not (most combinations actually are zero for my tests). This saves the lookup work in the TTF file. This system is not great as it still only covers the glyph index range determined by highest and lowest ASCII glyph index, as I didn't seem to find a way to get the actual glyph range of the entire font.
Overall, I got font loading back from 500ms for the font to 3ms, doing these changes.
I recently switched SilverNode from NanoVG to vg-renderer, which was a fun experience. The API is good, and I like the library. I did however run into a few problems which I fixed along the way. This is a PR with all the fixes and improvements.
Notably, regarding fontstash, there is a problem with the way the kern array was constructed if the range of ASCII characters is huge. A font I was testing with has some ASCII letters in really low glyph indexes, and some other ASCII characters in really high glyph indices. The result was a range of 2500 glyphs. The kern array gets allocated as the square of that, which was super slow to both allocate and then fill the kern array with 2500*2500 looked up kern values.
So to fix this, I did four things:
int
toint16_t
.Overall, I got font loading back from 500ms for the font to 3ms, doing these changes.