Home

Awesome

fontwriter

Generates and optimizes Structured JSON fonts for TextraTypist.

Also stores pre-made Structured JSON fonts here in the repo.

Wait, what?

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 multi-channel 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 snapshot builds and is expected in 1.0.0 (the next release). That release also includes (or will include) 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.

Do I need to run this at all?

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 or DAT font file, the PNG file with the same filename but different extension, and any license file(s) related to that font, copy them into your assets folder in a libGDX project, and load the JSON/DAT using code from TextraTypist (maybe just copied without a dependency). Using BitmapFontSupport, you can load Structured JSON into BitmapFont objects (this class can probably be copied). Otherwise, you can use the 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.

Note that the .json files are generated by msdf-atlas-gen, and the .dat files are simply compressed (binary) versions of the corresponding .json files. You only need one or the other. 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, so .dat is usually better and a substantially smaller file. 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.

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.

OK, how do I use this?

For now, this is Windows-only. I would need to build some tools for other platforms to get this to work on Linux or macOS.

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-1.0.4.jar and run java -jar fontwriter-1.0.4.jar "MyFont.ttf" msdf 60 , where "MyFont.ttf" can be any path to a .ttf file or probably also an .otf file. "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-1.0.4.jar to enter its absolute path). The second parameter, msdf, can also be sdf or standard. 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 cannot be used with colorful emoji or other fonts to the same extent. 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 unfortunately doesn't work well with other fonts. The "60" parameter is a size, I think measured in pt or px. It isn't necessarily going to be used as-is. 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 last argument is there so that you can quickly see all chars, even on a white background.

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/, 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!

Windows Binaries? Gross!

They're both downloaded from the official project pages, and you can replace them if you want!

The msdf-atlas-gen binary uses this starting in fontwriter 1.0.4: version v1.3, and older versions of fontwriter depended on a self-built, slightly modified fork of msdf-atlas-gen. That self-built mess isn't needed now.

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.

Oxipng works on many desktop platforms, but I can't compile msdf-atlas-gen for Linux, macOS, or ARM Windows currently.

License

This uses the Apache License v2.0.

The included msdf-atlas-gen uses the MIT License. The version used here is an identical binary to the one distributed at that repo (v1.3).

The included oxipng also uses the MIT License.