Font Bitmaps in DDS Files

From The DarkMod Wiki
Jump to navigationJump to search

Introduction

It would be good to review these articles first:

Briefly, a font DDS is a 256 x 256 bitmap, containing the usual additional "MipMaps" pyramid of images, into which individual glyphs (all or part of a font set) are packed.

It may have started life as a TGA file from a generation tool, but is distributed in TDM as a DDS.

Attributes of a Good Glyph Packing/Layout

The layout of glyphs into any given bitmap may be done by a generation tool. Or perhaps a manual layout is involved, either within an empty bitmap or to extend the content of a generated one. With a manual layout, usually you devise an organizing grid structure. And if a set involves multiple bitmaps (which is normal for sizes 24 and 48), you have to decide into which bitmap each new glyph goes.

The algorithms of generated layouts typically strive to place glyphs snugly against the top and left edges of the bitmap. This can be a problem if you need to enlarge the glyphs (e.g., for bolding, or menu-system "glow").

Glyph bitmap placement and DAT metrics need to avoid introducing stray marks from adjoining glyphs. Consider the tight bounding box containing any given character (shown in gray in Figure 1 of Font Metrics & DAT File Format) and the looser overall cell given by imageWidth x imageHeight. A good packing strives to ensure that the gray bounding box from only one character is contained in any given cell.

Pixel Color Representation in a DDS File

Each pixel of the bitmap is an RGBA value, where R, G, B, and A values are 8-bit (i.e., 256 values).

Back in Doom3 days, fonts tended to be multicolor, and a bit ragged. For examples, see Doom3 Tutorials 10 and 11.

TDM has gone in another direction. The glyphs are "gray-level" (i.e., with anti-aliased edges), so it is the Alpha channel that defines them. TDM convention has the fonts stored with a white color. This is for the benefit of GUI coding, so the font can be recolored using the GUI "forecolor" command.

That means that every pixel whose Alpha channel has a non-zero value must have RGB of white (e.g., all max values). This can be done in different ways:

  • Have the entire bitmap uniformly white in RGB.
  • Have just the bounding boxes in white, with the rest 0 (representing transparent). This is the approach of tool ExportFontToDoom3. It is useful if editing the DDS while leaving the DAT data unchanged. Doom3 Tutorial 11 shows this approach too.
  • Have the only the character strokes in 100% white. This is can be done manually in the bitmap editor.

Example of ExportFontToDoom3 Generation

Figure 1 (below) shows a fresh generation of a font using the ASCII-only version of ExportFontToDoom3 v1.02 with its default options. By default, files for sizes 12, 24, and 48 are generated, and the bitmap is TGA (because the tool author warns against using the built-in DDS output.) The TrueType font in this example, StonePrint.tff, is of the same family as Stone in TDM, but perhaps not the same variant. One of the generated files, StonePrint_0_24.tga, is examined here in GIMP.

In the left panel, the soft-edged white characters appear on a transparent background (shown as the usual checkerboard). If you turn off visibility of the Alpha channel (middle panel), you see the white backing rectangle behind each character. Inside GIMP, you can toggle this back and forth while focused on any individual character, to see the relationship between a character and its backing white rectangle. (TIP: turn off the blue channel, so pixels appear in yellow, easier to distinguish from grey checkerboard empty pixels.)

It is possible in GIMP to get a static simultaneous representation of characters and their backings, such as the "G" closeup in the right panel, where the inside of the character itself is transparent. (With the image layer chosen, click the lower-right button "Add a mask to a layer". In the pop-up "Initialize Layer Mask to:" dialog, select "Transfer Layer's alpha channel", as well as checkbox "Invert Mask".)

ExportFont2Doom3 fulfills the requirement to generate backing rectangles at least as big as our abstract gray rectangles earlier. But some are randomly larger in one or both dimensions, and relationship to imageWidth x imageHeigth less clear. Also, some font glyphs will need to have a more-generous spacing within the bitmap than this tool creates (e.g., to allow hand-thickening for bolding, or for main-menu peripheral "glow" treatment).

Another Example – Cumulative Adjustments with Diverse Methods

Figure 2 shows an actual DDS file (namely, fonts/english/Stone_0_24.dds) from TDM 2.11 and earlier.

For this font and size, there has been a substantial (though incomplete) effort to incorporate European characters in conjunction with TDM's custom character mapping. A glance makes it is apparent that several methods have worked over this file during its creation and life, resulting in many "footprints" in the middle panel, where the Alpha channel is turned off. While a mess, this doesn't harm the end result in the left panel. The right panel shows a closeup of the backing RGB pixels for the Polish L, from the third row of characters. Aligned with it, the alpha channel (not shown here, unlike Figure 1) would have the same outline, but with anti-aliased edges.