Quick start
This example uses explicit font files. GlyphKit reads a font's bytes once, while the library is built, so a later change to the path does not alter the layout.
from glyphkit import FontLibrary, FontSource, Paragraph, TextSpan, TextStyle
library = FontLibrary.from_sources((FontSource.path("fonts/SourceSans3-Regular.ttf"),))
family = library.faces[0].family
paragraph = Paragraph(
(TextSpan("Utility U(x₁, x₂)", TextStyle((family,), 18)),),
max_width=360,
)
layout = library.layout(paragraph)
print(layout.logical_bounds)
print(layout.lines[0].runs[0].glyphs[0])
FontSource(_kind, _value, label)
FontSource.path(path) → FontSource
FontSource.bytes(data, *, label) → FontSource
FontSource.stream(stream, *, label) → FontSource
A font file. Its content is read once, when the library is built.
A caller-owned font source: a path, bytes or a stream. Paths and streams are read when a FontLibrary is created, and bytes keep the supplied bytes.
FontLibrary(faces, *, generic_families=None, strict=True)
FontLibrary.from_sources(sources, *, generic_families=None, strict=True) → FontLibrary
Caller-owned font sources. Their order breaks ties in matching.
Maps a generic name such as "sans-serif" to an ordered list of families.
Raise on a font that cannot be read instead of skipping it.
The main typography engine. Its face catalogue, matching rules and source identity are fixed once it is built. faces lists the faces, and library.faces[0].family is the family name to use in a style.
Shapes every span, wraps at legal break opportunities and returns an immutable TextLayout.
Paragraph(
spans,
max_width=None,
max_height=None,
align='start',
line_height=None,
first_line_indent=0.0,
hanging_indent=0.0,
paragraph_spacing=0.0,
tab_stops=(),
default_tab_width=None,
)
The styled fragments, in logical order.
Wrap at this width. None keeps one unconstrained line.
Accept lines up to this height; the rest is recorded as vertical overflow.
"start", "center", "end" or "justify".
Distance between baselines. None derives it from the largest style.
Indent of the first line.
Indent of every later line.
An immutable sequence of styled text spans, plus optional width, height, alignment, indentation and line settings.
TextSpan(text, style, semantic_role=None)
A fragment of source text paired with one TextStyle.
TextStyle(
families,
size,
weight=400,
width=100,
slant='normal',
axes=(),
features=(),
language=None,
script=None,
direction=None,
letter_spacing=0.0,
word_spacing=0.0,
)
Font families in fallback order, or a generic name from the library.
Font size in layout units.
Font weight from 100 to 900.
Width class in percent of normal.
"normal", "italic" or "oblique".
OpenType features, for example (("liga", 0),).
BCP 47 language tag for language-specific shaping.
Extra space after every glyph.
Extra space after every space character.
Font families, size, weight, width, slant, language, direction, spacing and OpenType features for one span.
TextLayout(
text,
lines,
logical_bounds,
ink_bounds,
diagnostics=(),
vertical_overflow=0.0,
)
The immutable result of laying out a paragraph: lines, runs, positioned glyphs, source ranges, bounds, baselines, overflow and the fonts that were used.
Coordinates
GlyphKit uses layout units, not pixels tied to a DPI. The consumer decides how those units map to its canvas. A layout is y-up: the first baseline is at y = 0, and each later line has a baseline at a smaller, negative y. A positioned glyph carries the position x, y of its origin on its baseline.
Baselines, width, and vertical font metrics
Text in more than one script works the same way. The families are tried in the order of the style, and each character takes the first family that covers it. A character that no configured family covers raises MissingGlyphError.
A mixed Latin and Chinese paragraph wrapped at max_width. Each box is a line's logical bounds and the dotted line is its baseline.