Skip to content

TTF Fonts not rendering correctly

Overview

I'm having a problem with the rendering of a TTF font in Solarus where it looks awful because the letters look misaligned vertically. The font also does not look as bold as it should.

The font I am using is Andika New Basic (the bold variant) with anti-aliasing enabled. However, the problem is most pronounced with antialiasing turned off:

Rendered in Solarus with rendering mode: solid
solid

For example, the "Z" appears to be higher than "A".

Steps to Reproduce

Sample Code to reproduce the problem:

local text_surface = sol.text_surface.create{
    font = "AndikaNewBasic/AndikaNewBasic-Bold",
    font_size = 16,
    color = {255, 255, 255},
    rendering_mode = "antialiasing",
    horizontal_alignment = "left",
    vertical_alignment = "top",
}

Project Files

font_test.zip

This project simply draws a menu displaying a single text surface.

Potential Solution: Hinting

@hhromic on discord was able to determine that adjusting the hinting options could fix the vertical alignment issue. The following image shows how the font renders in GIMP on the top line, then shows how it renders in Solarus with each of the possible hinting options (where Solarus is currently hard-coded to use normal hinting):

hinting_compare

(latest -dev version of Solarus running on Ubuntu was used to generate the above image)

Here is a zoomed in view showing the most noticeable problem: the uppercase "i" appears shorter than the adjacent letters on line 2 (current Solarus behavior).

font_hinting_zoom

Using the hinting value of "None" or "Light" fixes the problem where "i" appears to be shorter.

It's also strange that using a hinting value of "None" seems to adjust the kerning to make only that line longer, whereas the top line from GIMP is also using hinting of "None" while remaining the same width as the other lines.

Modifying the Solarus Source Code

The following Solarus code was modified to generate the image above.

File location: solarus/src/core/FontResource.cpp

  ); //original line 221
  TTF_SetFontHinting(outline_font.get(), TTF_HINTING_NONE); //new code
  OutlineFontReader reader = { std::move(rw), std::move(outline_font) }; //original line 222

Where values of TTF_HINTING_NORMAL (default), TTF_HINTING_MONO, TTF_HINTING_LIGHT and TTF_HINTING_NONE were tested.

from the SDL_TTF documentation:

Set the hinting of the loaded font. You should experiment with this setting if you know which font you are using beforehand, especially when using smaller sized fonts. If the user is selecting a font, you may wish to let them select the hinting mode for that font as well.

Final Mystery: Lack of Bold

There remains the other question as to why the font doesn't get rendered bold in Solarus like it does in GIMP.

One thing I noticed is that GIMP has a bold attribute that can be enabled/disabled, but for the AndikaNewBasic-Bold font, pressing the button to toggle this attribute has no effect in GIMP. I wonder if this means that GIMP is forcing the bold attribute to be enabled for the font. So does that mean that the bold attribute has to be active for it to appear bold like it does in GIMP?

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information