golang/freetype

Combining / Non-spacing characters don't work correctly

jerbob92 opened this issue · 6 comments

When I use this module to print text to an image file, everything seems to work correctly.
However, in a special case, I want to underline some characters, I tried to use the Combining / Non-spacing character \u0332 for that, but it just comes out as a separate character. There are quite some combining / non-spacing characters, check: http://www.fileformat.info/info/unicode/category/Mn/list.htm

Here's the result:
selection_988

(the text on the right should be underlined)

I tried to look into the code to pinpoint the issue, but the code is a little too advanced for me to understand it in a quick look but I'm pretty sure it's in func (g *GlyphBuf) Load(f *Font, scale fixed.Int26_6, i Index, h font.Hinting) error { in truetype/glyph.go, where it calculates the advanceWidth. The font I'm using is DejaVu Sans Mono and DejaVu Sans Mono Bold.

You need a proper text layout engine like HarfBuzz to shape and position glyphs, then use freetype-go to rasterize/render them. In DejaVu Sans Mono all glyphs have the same advance width, including combining marks, and the font relays on 1) the layout engine zeroing the advance of glyphs with mark glyph class or 2) applying OpenType feature in the fonts that does the same.

I don't really get what you are saying. Isn't this issue as simple as just not advancing when there is an combining mark?

Proper text layout is a bit more involved than this. You can hack your way around this particular issue e.g. check if the character is not a combining mark and not advance the width, but this might not give you the correct result in any font, and there are many more things that might still be broken in your layout, not to mention other writing systems that need more sophisticated handling.

Ah yeah, I get that just not advancing would be a silly hack.
But that should work for all monospace fonts right?

Depends on how the glyph is placed on the font, it is hangs on the left then it should work, but if it hangs on the right (can happen) the mark will be applied to the next glyph not the previous one.

Ah okay, thanks for the info! I will try with HarfBuzz then. Guess this issue can be closed as this sounds too advanced to fix directly in freetype-go.