love icon indicating copy to clipboard operation
love copied to clipboard

Alternative scalable font type?

Open slime73 opened this issue 6 years ago • 8 comments

Original report by jarodwright (Bitbucket: jarodwright, ).


Because fonts are rasterized, when applying a transform to a font it doesn't scale well like most other draw functions.

For performance reasons rasterizing should be kept, however I propose that an alternative dynamic font which renders characters each frame would be desirable for scaling text.

An argument against this would be that you shouldn't ever be drawing text to the world and should instead be drawing it to the UI at a screen position based on the world.

slime73 avatar Mar 22 '18 09:03 slime73

Original comment by Sasha Szpakowski (Bitbucket: slime73, GitHub: slime73).


LÖVE can load BMFont files, and there are tools to produce BMFont glyph atlases which use signed distance fields for the glyphs. You can then write a shader which renders those. https://github.com/libgdx/libgdx/wiki/Distance-field-fonts

It might be worth looking into making a shader included by default in LÖVE for that, although I'm not sure how useful that would be since typically you'd want to tailor things a bit to how your game is going to use the distance field font. Some documentation on the wiki about this would be good, in any case.

slime73 avatar Apr 05 '18 03:04 slime73

Definite +1 here, I did search for SDF so missed this issue. Adding SDF to the comments so that it will be found for anyone else searching for that.

kruncher avatar Jan 03 '21 16:01 kruncher

The Unity engine does a good job at implementing SDF text rendering with its TextMesh Pro component. It might be a good reference implementation. It would be good if the render function allowed the font size to be specified each time love.graphics.printSdf("Hello", 32, 0, 0) or alternatively if there was a font size state love.graphics.setFontSize(32).

kruncher avatar Jan 03 '21 16:01 kruncher

All that you need is a shader that works with distance field font glyphs and a love.graphics.setShader call before printing text, everything else is already supported by love (for example love.graphics.print accepts scale parameters already, and love.graphics.newFont accepts BMFonts which can have SDF glyphs).

slime73 avatar Jan 03 '21 16:01 slime73

Upgrading FreeType to 2.11.0 or later would allow Löve to use its SDF render mode to output SDF glyphs from any font. I already have a working proof of concept (adding "sdf" HintingMode paired with a shader)

(excuse the experimental subpixel font test) Screen Shot 2022-10-14 at 5 02 46 PM

Screen Shot 2022-10-14 at 6 48 26 PM

I'll probably clean it up and open a PR soon.

Labrium avatar Sep 01 '23 13:09 Labrium

For now I've figured out you can use a simple shader that will use the antialiasing as a small section of a distance field, although it only works for upscaling:

uniform float scl; // the scale factor you use to draw the text
vec4 effect(vec4 color, Image texture, vec2 tc, vec2 sc) {
	vec4 c = gammaToLinear(color);
	float d = clamp(Texel(texture, tc).a * scl - 0.5 * scl + 0.5, 0.0, 1.0);
	return linearToGamma(vec4(c.rgb, c.a * d));
}

Labrium avatar Sep 01 '23 13:09 Labrium

@Labrium it would be cool if you did open a PR for this :D I am still wanting this

kruncher avatar Sep 01 '23 19:09 kruncher

#1966 :)

Labrium avatar Sep 02 '23 00:09 Labrium