SFML community forums

General => SFML development => Topic started by: Mario on April 09, 2017, 01:40:20 pm

Title: sf::Font: Abstraction and Bitmap Fonts
Post by: Mario on April 09, 2017, 01:40:20 pm
With sf::Text and sf::Font SFML offers a clean and easy way to load True Type fonts and show some text on screen.

However, when you want to create some old school like pixel art game using bitmap fonts, you're quite lost.

Using True Type in such situations often looks out of place, even if you're trying to use a bitmap style font. Things never line up perfectly.

If you'd like to use a real bitmap font from a texture, you'll have to implement it yourself (or reuse some existing code).

SFML 3 gives us the opportunity to do something I've been trying to do for a long time: Splitting sf::Font to have a base class you can derive from. Since this changes the API and breaks existing code, it wouldn't have been that great to introduce it during 2.x.

Here's the basic idea:
How would you use sf::BitmapFont?

The basic concept is identical to the True Type counterpart, with the minor exception of having to provide a mapping so SFML knows where to find the actual glyphs. This implementation doesn't require any special texture markers. The following interface is subject to change; feel free to suggest changes and improvements.
void sf::BitmapFont::loadFromFile(const sf::String &filename, const sf::String &mapping = "...", const sf::Size glyphSize = {0, 0}, const sf::Size glyphSpacing = {0, 0});
 

Parameters:
" !\"#$%&'()*+,-./01234567890:;<=>\n"
"?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^\n"
// ...
Are there any downsides or points not yet covered?
Anything else to keep in mind?
Unfortunately there's no standard or most common image format for bitmap fonts, so there's no "TTF" to implement here.
Title: Re: sf::Font: Abstraction and Bitmap Fonts
Post by: Nexus on April 09, 2017, 04:07:38 pm
How would the API of sf::BitmapFont look, and where would it differ from TrueTypeFont? I don't think it will be nearly identical apart from the mapping, because all the glyph- and metric-related functionality is not there for bitmap fonts...

Also, are bitmap fonts with fixed width characters really useful? Monospace never really looks good unless you have a console or deliberately old-school typewriter style, so it would be extremely limited.

Another option would be to separate alignment/rendering from the glyph source, and use an exchangeable back-end for sf::Font glyphs. Design-wise, I would like this approach more than inheritance.
Title: Re: sf::Font: Abstraction and Bitmap Fonts
Post by: DeathRay2K on April 10, 2017, 03:39:54 pm
I think rather than specifying character size and spacing, it might be better to supply description of the font's layout.
Ages ago I used HGE to develop some games, and what they did for fonts was accept a bitmap and a font description file. You can find some information on their implementation here (http://kvakvs.github.io/hge/doc/index.html?fbuilder__main.html).

They also supplied a small piece of software to help lay out fonts and automatically generate that description file, but given SFML's cross platform nature that may not be possible.
In any case, I think being able to specify texture coordinates for each character would be useful, and tools can definitely make generating those a simple matter for any developer that cares to use bitmap fonts.
Title: Re: sf::Font: Abstraction and Bitmap Fonts
Post by: Mario on April 11, 2017, 02:38:19 pm
How would the API of sf::BitmapFont look, and where would it differ from TrueTypeFont? I don't think it will be nearly identical apart from the mapping, because all the glyph- and metric-related functionality is not there for bitmap fonts...
That heavily depends on *how* fonts would be made up. What I'd try to avoid is having users create the font with some specific program or toolset. Of course stuff like outlines or glyph metrics aren't really useful for these, but the baisc idea is to have a base class so you can use your custom font objects with sf::Text.

Also, are bitmap fonts with fixed width characters really useful? Monospace never really looks good unless you have a console or deliberately old-school typewriter style, so it would be extremely limited.
It certainly depends on what you're aiming for, true. If we can come up with a good system I could definitely imagine aiming for proportional fonts as well.

Another option would be to separate alignment/rendering from the glyph source, and use an exchangeable back-end for sf::Font glyphs. Design-wise, I would like this approach more than inheritance.

So you mean in a way similar to texture and audio loading?

In any case, I think being able to specify texture coordinates for each character would be useful, and tools can definitely make generating those a simple matter for any developer that cares to use bitmap fonts.

Yeah, I agree, but at the same time that tool usage is something I'd like to avoid, if possible. You can't just create TTF files out of thin air either, but at least it's standardized and you're free to pick any tool you want.
Title: Re: sf::Font: Abstraction and Bitmap Fonts
Post by: DeathRay2K on April 11, 2017, 04:17:21 pm
Yeah, I agree, but at the same time that tool usage is something I'd like to avoid, if possible. You can't just create TTF files out of thin air either, but at least it's standardized and you're free to pick any tool you want.
It's true unfortunately that there isn't a common standard format for describing bitmap font layouts, but having some kind of format is still a necessity. Every bitmap font tool out there generates some kind of layout information because of this necessity, so adapting one of those existing formats seems reasonable. I pointed out the HGE font format because it separates the character layout from the actual texture and it's human-readable and editable. Taking a look at other options out there, BMFont looks like more or less a de facto standard:
http://www.angelcode.com/products/bmfont/doc/file_format.html
Their tool can output XML formatted font descriptions as well, and there's a third party JSON formatted version: https://github.com/mattdesl/bmfont2json/wiki/JsonSpec

There's also Microsoft's .fnt file format, which supports both bitmap and vector fonts: https://support.microsoft.com/en-us/help/65123/windows-developers-notes-font-file-format

There are many other tools with other layout formats of course but many are not well documented online.
The nice thing about the tools out there is that because of this format problem, a number of them support output plugins, allowing the user to output the data in whatever format suits them (And has a plugin), which probably eases the burden of giving users the tools to generate one of the more complex formats. In this way, much like TTF, users have a variety of tools they can use on different platforms to generate the required files. This is especially true if it supports an existing format for which there are already export plugins available.