7.9.6. STBIMAGE-06 — TrueType Fonts
This tutorial covers the stbimage_ttf module — loading a TrueType
(.ttf) font, querying metrics, rasterizing glyphs, and rendering text
onto an image with software alpha blending.
7.9.6.1. Loading a Font
load_ttf reads a .ttf file and packs a range of glyphs (by default
ASCII 32..127) into a 1-channel atlas bitmap stored on the returned Font.
The DroidSansMono font ships with dasStbImage; resolve its path through
get_das_root() so the tutorial runs from any working directory:
require stbimage/stbimage_boost
require stbimage/stbimage_ttf
let font_file = "{get_das_root()}/modules/dasStbImage/fonts/droidsansmono.ttf"
var font <- load_ttf(font_file, [pixel_height = 32.0])
assert(is_valid(font))
// font.bitmap is the packed atlas; font.char_range is (first_char, num_chars)
Use load_font instead when you only need metrics or glyph shapes and no
atlas.
7.9.6.2. Font Metrics
font_metrics returns ascent, descent, and line height in pixels at the
font’s loaded pixel_height. font_vmetrics returns the same values in raw
font units (before scaling):
let m = font_metrics(font)
// m.ascent, m.descent (negative), m.line_height — all in pixels
let vm = font_vmetrics(font)
// vm.ascent, vm.descent, vm.line_gap — in font units
7.9.6.3. Per-Glyph Metrics and Measuring Text
codepoint_hmetrics gives one glyph’s advance width and left side bearing
(in font units). measure_text sums advances to return a pixel width:
let hm = codepoint_hmetrics(font, 'A')
// hm.advance_width, hm.left_side_bearing
let width = measure_text(font, "Hello", 32.0) // pixels
7.9.6.4. Rasterizing a Single Glyph
codepoint_bitmap renders one glyph to a 1-channel (alpha) Image at a
scale computed from the desired pixel height, together with a pixel offset from
the origin:
let scale = scale_for_pixel_height(font, 32.0)
var bm = codepoint_bitmap(font, 'A', scale, scale)
// bm.image is 1-channel uint8; bm.offset is the int2 pixel offset
bm.image |> with_pixels() $(var px : array<uint8>#) {
// px[i] is the coverage/alpha of pixel i
}
7.9.6.5. Rendering Text onto a Canvas
render_text blits the packed atlas glyphs onto a 4-channel RGBA Image
at a baseline origin, in the given (r, g, b) color. Coordinates are clipped
to the destination bounds automatically:
var canvas = make_image(256, 64, 4)
canvas.fill_rect(0, 0, 256, 64, 0xFFFFFFFFu) // white background
let m = font_metrics(font)
render_text(canvas, font, "Hello, daslang!", 8, int(m.ascent) + 8, 0, 0, 0)
let (ok, err) = canvas.save("text.png")
render_text is built on blit_alpha (see
STBIMAGE-05 — Drawing and Alpha Blending): the font atlas is a 1-channel
coverage image, and each glyph is alpha-blended onto the canvas.
See also
Full source: tutorials/dasStbImage/06_truetype_fonts.das
Previous tutorial: STBIMAGE-05 — Drawing and Alpha Blending
Next tutorial: STBIMAGE-07 — HDR Images