Chlumsky / msdfgen

Multi-channel signed distance field generator
MIT License
3.91k stars 404 forks source link

loadGlyph: Allow for specifying glyph index instead of Unicode codepoint #105

Closed Tearnote closed 3 years ago

Tearnote commented 4 years ago

Currently, for specifying the glyph to render from a font file a Unicode codepoint is used to specify the glyph to use. This works fine when doing simple positioning and kerning by means of FreeType's horiAdvance metric, but this approach breaks down when trying to use HarfBuzz for shaping whole lines of text.

For anyone less familiar with the concept, text shaping is a process that turns a series of Unicode codepoints into positioned glyph indexes. During this process, rules specified in the font are applied to perform more complex kerning and arbitrary transformations. Common examples of changes performed during shaping is more pleasing kerning between some pairs of characters such as AV (closer together,) and ligatures such as the "ffi" sequence being clumped together into a single glyph. This also deals with some less common Unicode features such as combining marks, but I do not personally have experience with languages that make use of these. To summarize, the logical essence of the operation is that a purely conceptual representation of the text is turned into a purely graphical one.

The core of the issue that makes msdfgen and generators based on it unusable for shaped passages is the fact that glyphs in a font do not have to map to any Unicode codepoint, and in fact glyphs output by HarfBuzz have no Unicode mapping quite often. This happens even in English text, such as when a ligature is triggered. (While the ffi ligature actually exists as a separate Unicode codepoint, most fonts don't bother mapping it there.) Therefore, a series of glyph renders or a packed atlas will not have the needed glyphs to render shaped text even if it iterated across all of Unicode.

This could be fixed by providing an alternative to loadGlyph which takes a glyph index instead of a codepoint. The only needed change to the contents of the function would be the use of FT_Load_Glyph instead of FT_Load_Char. The codepoint-based version should still exist because simple kerning is sufficient for most purposes, but it could become a wrapper that calls the glyph index version after translating the codepoint with FT_Get_Char_Index.

Chlumsky commented 3 years ago

Thank you for the suggestion, it has been implemented in 38ef289f25e6e58c63a11dc6f1cb29dbf6c3d6a4 and released in version 1.8.