Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: sf::Font: Abstraction and Bitmap Fonts  (Read 3301 times)

0 Members and 1 Guest are viewing this topic.

Mario

  • Moderator
  • Hero Member
  • *****
  • Posts: 877
    • View Profile
sf::Font: Abstraction and Bitmap Fonts
« 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:
  • Rather than using sf::Font you pick either sf::TrueTypeFont, sf::BitmapFont, or any derived class you create on your own. The rename of the old sf::Font is important to avoid confusion and provide an easier to understand naming scheme.
  • Therefore sf::Font is the new name of the abstract base class (similar to sf::Drawable).
  • The behavior of sf::TrueTypeFont is 100% identical to the classic sf::Font.
  • sf::BitmapFont utilizes image files rather than font files together with a simple mapping.
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:
  • filename: I'll leave this one for you to figure out. This can be any image format supported by sf::Texture.
  • mapping: This is a string representing the characters the way they're aligned in the image. Columns aren't separated; rows are separated by line breaks.

    Note that this also allows you to map special glyphs or icons (like button images) to Unicode characters. You're also not forced to map every possible codepoint. Invalid ones would be skipped or replaced by the first one.

    The default value could look like this:
" !\"#$%&'()*+,-./01234567890:;<=>\n"
"?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^\n"
// ...
  • glyphSize: This is the size of individual characters. The default value forces SFML to derive the dimensions based on the image size and character mapping.
  • glyphSpacing: This is simply the distance between glyphs in the image (if any). Many premade or generated bitmap font textures come with no spacing or one line between rows and columns. This allows you to load these as well.
Are there any downsides or points not yet covered?
  • Sure! One popular example would be proportional fonts (i.e. no fixed width). Should SFML support these? If so, how?
  • We could make the abstraction generic enough so it becomes possible to also implement something like sf::VectorFont later on. Opinions?
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.

Nexus

  • Moderator
  • Hero Member
  • *****
  • Posts: 6225
  • Thor Developer
    • View Profile
    • Bromeon
Re: sf::Font: Abstraction and Bitmap Fonts
« Reply #1 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.
« Last Edit: April 09, 2017, 04:13:48 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development: first SFML book

DeathRay2K

  • Newbie
  • *
  • Posts: 24
    • View Profile
    • Email
Re: sf::Font: Abstraction and Bitmap Fonts
« Reply #2 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.

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.

Mario

  • Moderator
  • Hero Member
  • *****
  • Posts: 877
    • View Profile
Re: sf::Font: Abstraction and Bitmap Fonts
« Reply #3 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.

DeathRay2K

  • Newbie
  • *
  • Posts: 24
    • View Profile
    • Email
Re: sf::Font: Abstraction and Bitmap Fonts
« Reply #4 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.
« Last Edit: April 11, 2017, 04:21:03 pm by DeathRay2K »

 

anything