imagine.strokefont
import imagine.strokefont
imaginelifts part of this module out to its own top level; each name below is shown with the path that reaches it. Anything still spelledimagine.strokefont.*needsimport imagine.strokefont.
StrokeFont: the font built into the module, defined as stroke geometry
rather than glyph outlines.
It exists so that text can be drawn with no font file present at all. Because a glyph is a path rather than a filled shape, it scales to any size and takes a weight without needing a separate face per weight.
Constants
EM
imagine.strokefont.EM: number = 20
The em square’s height in design units. A font asked for 20 pixels draws
its em at 20 pixels, so scale is simply size / EM.
CAP_HEIGHT
imagine.strokefont.CAP_HEIGHT: number = 14
The height of a capital letter.
X_HEIGHT
imagine.strokefont.X_HEIGHT: number = 10
The height of a lowercase letter with no ascender.
ASCENDER
imagine.strokefont.ASCENDER: number = 15
How far the tallest glyphs rise above the baseline.
DESCENDER
imagine.strokefont.DESCENDER: number
How far descenders fall below the baseline, as a negative number.
WEIGHT
imagine.strokefont.WEIGHT: number
The default stroke width in design units, a little under a tenth of the em, which is the usual weight for a regular sans-serif.
GLYPHS
imagine.strokefont.GLYPHS = {...}
Every glyph, keyed by character.
advance is how far the pen moves after drawing, in design units.
strokes is a list of polylines.
NOTDEF
imagine.strokefont.NOTDEF = {...}
What an unmapped character draws: an empty box, the same convention a font uses for a glyph it does not have.
Classes
StrokeFont
class imagine.StrokeFont
The built-in font: a sans-serif drawn from centre-line strokes rather than loaded from a file.
imagine deliberately ships no font file, so [[imagine.Font.system]]
and [[imagine.Font.sans]] both depend on what happens to be installed.
This one is always there. It is defined as geometry in
[[imagine.strokefont]], drawn through the same anti-aliased rasterizer
everything else uses, and therefore scales cleanly to any size and takes
a weight as a parameter.
import imagine { Image, StrokeFont }
Image(300, 80, 'white')
.text(16, 22, 'Always available', StrokeFont(28), '#0f172a')
.save('label.png')
It has the same interface as [[imagine.Font]], so anywhere a font is accepted this can be used instead.
What it is for
Labels, chart axes, watermarks, diagrams, placeholder text, and any output that has to work on a machine with no fonts installed. The look is geometric and single-weight, closer to a technical drawing than to a typeface, because that is what centre-line strokes give you honestly.
It is not a substitute for real typography. For body text, a headline, or anything where the shapes matter, load an actual font with [[imagine.Font.load]].
Coverage
Printable ASCII, from space through ~. Anything else draws the empty
box a font uses for a glyph it does not have, so text in another script
comes out visibly missing rather than silently blank.
- printable — has a
@to_string(), soechoandprint()show something useful
Constructor
imagine.StrokeFont(size: ?number, weight: ?number)
Creates the built-in font at a size.
Parameters
size(?number) — The size in pixels - Default: 16.weight(?number) — The stroke width, as a fraction of the size - Default: 0.085, a regular weight. Around 0.13 reads as bold.
StrokeFont.size()
imagine.StrokeFont.size(pixels) -> StrokeFont
Returns the same font at a different size.
Parameters
pixels(number)
Returns StrokeFont
StrokeFont.weight()
imagine.StrokeFont.weight(weight) -> StrokeFont
Returns the same font at a different stroke weight.
Parameters
weight(number) — A fraction of the size. 0.085 is regular, 0.13 reads as bold, 0.05 as light.
Returns StrokeFont
StrokeFont.pixel_size()
imagine.StrokeFont.pixel_size() -> number
The size in pixels this font draws at.
Returns number
StrokeFont.name()
imagine.StrokeFont.name() -> string
The font’s name.
Returns string
StrokeFont.source()
imagine.StrokeFont.source() -> string
Where this font came from.
Returns string
StrokeFont.has_glyph()
imagine.StrokeFont.has_glyph(character) -> bool
true when this font has a glyph for a character, which for the
built-in font means printable ASCII.
Parameters
character(string)
Returns bool
StrokeFont.metrics()
imagine.StrokeFont.metrics() -> dict
The font’s vertical metrics at its current size, in pixels.
The dictionary holds name, ascent, descent (negative), line_gap
and line_height, the same shape [[imagine.Font]] reports. The em is
the size, so single-spaced lines sit exactly size pixels apart.
Returns dict
StrokeFont.wrap()
imagine.StrokeFont.wrap(text, width: number, options) -> string
Breaks a string into lines that fit within a width, returning the text with newlines inserted.
Parameters
text(string)width(number) — The maximum line width in pixels.options(?dict) —tracking.
Returns string
StrokeFont.measure()
imagine.StrokeFont.measure(text, options) -> dict
Measures a string without drawing it.
Returns width, height, baseline (the first line’s baseline,
measured down from the top of the box) and lines.
Parameters
text(string)options(?dict) —tracking,line_height,align.
Returns dict
StrokeFont.render()
imagine.StrokeFont.render(text, options) -> dict
Rasterizes a string into an 8-bit coverage mask.
Returns coverage, width, height and baseline, the same shape
[[imagine.Font]] returns, which is what lets both be handed to
Image.text() interchangeably.
Parameters
text(string)options(?dict) —tracking,line_height,align.
Returns dict
StrokeFont.to_string()
imagine.StrokeFont.to_string()
2026, Richard Ore and Zuri contributors