Skip to content
Matt DesLauriers edited this page May 21, 2014 · 3 revisions

NOTHING TO SEE HERE...

This is just some brainstorming on different ways of handling the file spec and the future of this tool. Not all of it is implemented.

--

Intro

Formats

Currently only json output is supported. Binary would be a nice to have.

"Font" objects

A "font" object holds information about scale, underline and glyph metrics, family name, kerning data, and so forth. It presents a single font family with a single style, e.g. Verdana Bold, at a particular size. There are currently two types of fonts:

  • bitmap: if a font has the bitmap flag set to true, the values are all assumed to be scaled to the pixel size this font should be rendered at, and the glyph data should contain the x and y offsets into the texture atlas, as well as the sheet index to sample from. For bitmap fonts, the paths array will be empty.
  • path: if no bitmap flag is specified, the font is assumed to be defined by paths. This will give us a paths array, which defines the unscaled outlines for each path as a series of moveTo, bezierCurveTo, etc. operations.

Spec

{
    fontpath_version
    units_per_EM - only included with path fonts
    type - bit flag TYPE_PATH or TYPE_BITMAP from fontpath-flags
    scaled - default false (hint that the values are not scaled) - included for future enhancements
    family_name - pulled from TTF; in the case of bmfont, uses 'info.face' name
    size - the size that it was exported at; in the case of bmfont, uses 'info.size'
    style_flags - style flags; bmfont exporters are not always accurate so be careful
    face_flags - face flags; bmfont exports with FIXED_WIDTH and KERNING if a table was included
    style_name - may be empty string in the case of bmfont exports
    ascender - computed in the case of bmfont based on lineHeight/base
    underline_thickness - bmfont defaults to N
    underline_position  - bmfont defaults to N
    max_advance_width - computed in the case of bmfont
    width - computed in the case of bmfont; max glyph width
    height - bmfont will use lineHeight
    bitmap {  - will be undefined if type is not bitmap
        padding
        spacing
        width - texture size
        height - texture size
        pages [ "sheet1.png" ] - list of sheets
    }
    glyphs {
        "A" {
            xoffset - only for bitmap fonts
            yoffset - only for bitmap fonts
            width
            height
            hbx - horizontal bearing
            hby - horizontal bearing
            ha - horizontal advance
        }
    }
    kerning [
        ["A","B",-2],
        ...
    ]
    paths [
        ["m",25,25],
        ["c",25,15,62,42,15,15]
    ]
}

vertical text

Vertical text is not supported yet. Eventually fontpath will examine the font, determine if it is vertical, and if so, export vertical metrics instead of horizontal (with optional override for CLI). This means that glyphs will have va (vertical advance) instead of ha, vbx/vby instead of hbx/hby, max_advance_width instead of max_advance_height, and kerning values will be vertical.

Exporting Path Fonts

Path fonts are better suited for text animations and large, scalable text. This is the default type with the fontpath tool:

fontpath MyFont.ttf -o MyFont-path-32pt.json -s 64

The above exports a path font intended to be rendered at 64pt.

complex use case

Let's say we want the following fonts: OpenSans and Droid Serif. You want them in the following sizes: 12, 14, 16, 18, 24, 32. You want bold, italic, and regular styles. You also want to export the paths for sizes greater than 32. How do we lay out all the data?

Ideally we could push everything into a single JSON. But it would get complicated. Especially since each one has different values for glyph metrics (size, xadvance, kerning, etc). This is because BMFont is only designed for "one font at a time", and also because different sizes will produce different kerning/metrics because of rounding, grid-fitting, hinting, etc. So really we probably do need to produce different kerning/metrics for each font.. :(

If we use a seaprate JSON file for each font/style/size, this makes the code easier, but bulkier.

How about:

  • Target the simplest use case.
  • Expose APIs so user can export kernings as a separate file, and the rest of the files without kernings, and then handle scaling themselves. (if they need a really advanced renderer)
  • Allow the tool to be integrated with node server, so that user can request fonts and glyphs dynamically.
{
    bitmap: true   //the glyphs contain offsets into bitmap region, and 'sheets' is included
    paths: [ ... ] //if exported (default false with bitmap), the values are scaled
    sheets: [ "1.png", "2.png" ]
    glyphs: {
        "A": { ... }, 
        ...
    }
    kernings: [ ... ]
}

The reality is this tool will not be able to replace BMFont, GlyphDesigner, gdx-fontpack, etc. So it instead will try to interop with it nicely. Basically, you use those tools to export the fonts at the exact sizes, styles, etc. that you want. They might already be packed into a single texture atlas. They give you the x and y offsets, and sheet index (for multiple pages), into the texture atlas. Then you run this through fontpath to get a fontpath-friendly output.

So it looks like this:

fontpath-bmfont MyFile.xml -o MyFile.json

This exports a font with resolution 72, size as defined by the BMFont file, etc. For additional metrics, like underline position, units_per_EM, family name, font/style flags:

fontpath-bmfont MyFile.xml -f MyFile.ttf -o MyFile.json

This will grab the metrics from MyFile.ttf and merge them into the output bitmap font.

Clone this wiki locally