Generates and optimizes Structured JSON fonts for TextraTypist.
Also stores pre-made Structured JSON fonts here in the repo.
This is a command-line tool that takes .ttf or .otf files and makes bitmap fonts out of them for libGDX to use.
You can load Structured JSON fonts this makes with TextraTypist or BitmapFontBridge. TextraTypist uses them natively and supports the better-when-scaled "distance field fonts" with its own Font class, while BitmapFontBridge makes normal libGDX BitmapFont objects, and doesn't do anything special with distance fields.
TextraTypist has the class Font, a... fairly complete replacement
of the BitmapFont code in libGDX. It supports various extra features, including
rendering signed distance field (SDF) and multichannel signed distance field (MSDF) fonts out-of-the-box.
These are ways of rendering fonts using a different shader internally, and allow one font image to scale
smoothly to much larger sizes without losing much quality. However, generating these fonts can be a
challenge; MSDF fonts in particular only had a few options (such as
msdf-gdx-gen, an inspiration for this project), and most of the
existing options had to clumsily wrap the one utility for generating MSDF fonts... one character at a time.
Having to stitch together sometimes hundreds of individual textures, one per char, tended to cause issues
where letters would "wobble" up and down over a sentence, especially for smaller chars or fonts with many
chars. The author of MSDF and most utilities surrounding it relatively-recently wrote
msdf-atlas-gen, which can output to several font file formats,
but not the AngelCode BMFont format that libGDX and TextraTypist can natively read. It can produce JSON,
though!
The Structured JSON msdf-atlas-gen produces can be read in by TextraTypist to produce working fonts.
Support for loading Structured JSON is present in TextraTypist from 1.0.0 onward.
That release also includes BitmapFontSupport, which can load a libGDX BitmapFont from a Structured JSON
font file, and FWSkin to load fonts produced by "FW" (FontWriter, this project) as BitmapFont or
Font. Another micro-library exists, FreeTypist, to load FreeType font configuration in a way that both
Font and BitmapFont can read, as well as loading those from .fnt or .json files. There's also now
BitmapFontBridge, which avoids any dependency on
TextraTypist, and produces only libGDX BitmapFonts from Structured JSON (or AngelCode BMFont) files.
Possibly not! There are quite a few pre-made Structured JSON fonts in a variety of styles in
the docs/knownFonts folder. You can copy the .json.lzma font file, the .png file with the same
filename but different extension, and any license file(s) related to that font. Paste them into your assets
folder in a libGDX project, and load the .json.lzma file using code from TextraTypist or BitmapFontBridge.
Using BitmapFontBridge, you can load Structured JSON into BitmapFont objects.
Otherwise, you can use TextraTypist's Font constructor that takes as its last parameter
boolean ignoredStructuredJsonFlag (its value doesn't matter, just that you pass a boolean there). You can
also use FWSkin, FreeTypistSkin, FWSkinLoader, or FreeTypistSkinLoader if you use these with scene2d.ui.
From then on, the font acts like a normal Font or BitmapFont. You probably shouldn't try loading distance field
fonts with BitmapFont; it may be possible to load DistanceFieldFont objects later. For now, "standard" is the
best option with BitmapFont, and "standard" or "sdf" are good options for Font.
Note that the .json files are generated by msdf-atlas-gen, and there are a few other types of compressed (binary)
versions of the corresponding .json files, such as .json.lzma, .ubj, .ubj.lzma, and .dat . You only need one such file
per font, plus the matching .png with the same name (minus extensions). The .json files are larger, but human-readable
and human-editable, somewhat. It isn't often that you'll need to edit one of the .json files, but .json.lzma files will
allow you to at least read the file if you extract the .json out of it with a tool like 7-Zip,
and are close to the smallest files here. You can also use LzmaUtils.decompress() in TextraTypist to extract a .lzma
file with code, or use the Lzma class in libGDX.
The actual smallest files are the .ubj.lzma files, which aren't always compatible with GWT (due to a bug in libGDX), and can't be made human-readable easily. The file size will matter less in a JAR, but it matters a lot for a Git repo like this one or like TextraTypist that hosts a lot of fonts. The bug affecting UBJ files is present in libGDX 1.13.1, but not the subsequent 1.13.5 or 1.14.0 releases. Avoiding UBJ is still a good idea unless you know you will never target the browser; the size difference is small. TeaVM might not have the same bug in some versions or even in any version; it isn't yet clear.
This can generate SDF and MSDF fonts about as easily as it can "standard" (non-distance field) fonts, and so there are
SDF and MSDF versions of every "standard" font here. Crispness is handled automatically by information in the .json
or .dat file, and by TextraTypist. This is an improvement over the .fnt approach, which couldn't store crispness info
in the file. BitmapFont doesn't store any info about distance fields in its files, or even in its class. There's a
DistanceFieldFont subclass of BitmapFont in libGDX, but it hasn't been used much.
This has always worked on Windows, but now we have a working release for macOS (x64 and arm64) and Linux (x64)!
If you have the JAR from the releases, unzip it so the other files it came with are all in the same folder
structure. Then, you can enter the directory with that holds fontwriter-2.2.13.1.jar and run
java -jar fontwriter-2.2.13.1.jar "MyFont.ttf" standard 60 , where "MyFont.ttf" can be any path to a .ttf file
or an .otf file (.ttc may work). "MyFont.ttf" doesn't have to be in the same folder if you give it an absolute
path (on Windows, you can drag and drop a file after typing java -jar fontwriter-2.2.13.1.jar to enter its
absolute path). The second parameter, standard, can also be sdf or msdf. You might just want standard
for many reasons; even though it won't scale up nicely, it will scale down fairly well, and you can
interchange standard fonts using FontFamily or using colorful emoji. On the other hand is msdf, which
scales up very well, but looks a little odd with colorful emoji. Then sdf is somewhere
in the middle; it works somewhat well with emoji, though it doesn't handle their partially transparent edge
very well, scales up nicely, and optionally can allow a shader to automatically outline text. The
"60" parameter is a size, I think measured in pt or px. It isn't necessarily going to be used as-is; if the
size is too large, progressively smaller sizes will get tried until all glyphs fit. You
can optionally specify a size of image to write (the default is 2048x2048, and fonts that only use ASCII
probably don't need that much space) as the next parameter. After that you can optionally specify a color
by name (such as "black" or "red") or RGB hex code (such as "BB3311"; RGBA also works but alpha is
ignored), which will write an extra preview of all chars using that color. The fifth argument is there so
that you can quickly see all chars, even on a white background. The extra previews won't look very good if
you're using msdf or sdf, but the regular preview will typically be more clear/crisp. An optional sixth
argument is a path (local or absolute) to a folder containing I18N files: either text files that have names
starting with "lang_" or files with the extension ".properties". If any files are present with matching names
in that folder, their contents will be used to determine the character set used by the font. If the sixth
argument is not present or is a non-existent path, then the folder containing the font file is used, and will
look for the same name patterns in the folder with the font file. If no text files have matching names, then
every char in the font will be used in the generated files. If you have lang_* or *.properties files in
your project, it is suggested to put them in their own folder or folders and specify the path yourself,
rather than relying on having a mix of I18N and font files in one folder.
Running that command will try the size you give it first, and if it can't fit all chars in the font into
a 2048x2048 (or other size, if specified) image, it will reduce the size and try again, repeatedly. Once
it can fit everything, it saves the file into fonts/, including saving various compressed variants on
the .json file, then starts doing some TextraTypist-related processing.
It paints a small "block" of solid white pixels into the lower right corner, then (if using
sdf or standard) optimizes the image so that it only uses the alpha channel with white pixels. That
last step helps texture filtering; without it, fully transparent pixels are fully-transparent black rather
than fully-transparent white, and mixing with black will darken sometimes even if the mixed color is
transparent (with white usually doesn't do this). It then optimizes the image in fonts/ with oxipng,
and generates a preview image that it places in previews/. If you specified a color name or hex code,
it also writes a preview of all chars in that color. It then optimizes the preview image(s), and then
you're done!
As an overview: The minimal arguments are the font's path, the distance field type, and the max font size.
The maximal arguments are the font's path, the distance field type, the font size, the size of the image to
write (such as 4096x4096, with an x separating width and height), and a color (by name or hex code).
All arguments are positional; the order is the only thing that matters. Arguments after the font size are
optional, and default to 2048x2048 and "" (without the color argument, it won't make an extra preview).
Well, it turns out this isn't the case anymore, and we can now include "gross binaries" from oxipng's official releases as well as Linux and Mac ones built by GitHub Actions from (my fork of) the msdf-atlas-gen repo. Big thanks to @EvergineTeam for setting up GH Actions in a PR to the main msdf-atlas-gen repo! On Windows, the PR's changes don't seem to produce a working binary, so we use the official .exe (version 1.4) there. I don't actually know if the binaries on Linux or Mac work. I don't have a Mac to test on and haven't yet tested on Linux, so if they work on the first try... I'll be surprised. Windows x64 works, at least.
In earlier versions, msdf-atlas-gen binary used this from in fontwriter 1.0.4 to 2.0.0: version v1.3, and older versions of fontwriter depended on a self-built, slightly modified fork of msdf-atlas-gen. That self-built modification isn't needed anymore; EvergineTeam's changes have been applied cleanly to version 1.3 of the official msdf-atlas-gen repo.
The oxipng binary used this in earlier releases: version v9.0.0 (which is a little old by now), or this: version v9.1.1 starting in fontwriter 1.0.3, or this: version v10.1.0 starting in fontwriter 2.2.13.
This uses the Apache License v2.0.
The included msdf-atlas-gen uses the MIT License. The version used here is built by GitHub Actions rather than being built by Chlumsky, but is still MIT-licensed.
The included oxipng also uses the MIT License.