Quick Start¶
Installation¶
Install ManimPango from PyPI:
pip install manimpango
The Windows and macOS wheels bundle their native dependencies, so installing
them from PyPI does not require Pango or Cairo to be installed separately.
Linux has no binary wheels at present, so installation there builds from
source and requires a C compiler, pkg-config, and the Pango development
headers.
To build from source on macOS, install Pango and Cairo first, for example with Homebrew:
brew install pango cairo
Source builds on Windows need Pango 1.56 or newer to register private font files at runtime.
Rendering Plain Text¶
Use render() for plain text. It returns a
RenderedText object containing SVG and layout metadata.
import manimpango
result = manimpango.render("Hello, world!", size=24.0)
svg = result.svg
result.save("hello.svg")
save() writes to an existing parent directory; it does not create missing
directories.
Understanding RenderedText¶
Both rendering functions return a
RenderedText object rather than writing a temporary file.
It keeps the SVG document and the layout result together, so callers can
choose whether to keep the SVG in memory, save it, or inspect its geometry.
The basic result contract is executable and independent of the host’s font metrics:
>>> import manimpango
>>> result = manimpango.render("Hello, world!", size=24.0)
>>> isinstance(result, manimpango.RenderedText)
True
>>> result.line_count
1
>>> isinstance(result.svg, str) and result.width > 0 and result.height > 0
True
For example, one macOS/Pango installation produces the following selected values. The exact numbers vary with the selected font and native backend; the relationships and SVG user-space units do not.
>>> result
RenderedText(width=130.0, height=24.0, baseline=18.0, line_count=1)
>>> round(result.width, 1), round(result.height, 1), round(result.baseline, 1)
(130.0, 24.0, 18.0)
>>> result.ink_bounds
Bounds(x=0.38671875, y=1.546875, width=127.33203125, height=19.875)
>>> result.logical_bounds
Bounds(x=0.0, y=0.0, width=130.0, height=24.0)
width and height are the rendered SVG viewport dimensions, and
baseline is the first line’s baseline position. ink_bounds is tight
to glyph drawing, so it excludes the side bearings and whitespace visible in
logical_bounds. All of these values, as well as font size and an
optional layout width, are float values in SVG user-space units—not
raw Pango units or device pixels. An SVG consumer may subsequently scale the
document.
The complete SVG is available without another render operation, and may be written only when a file is needed:
svg = result.svg
result.save("hello.svg")
RenderedText is immutable and result.lines is a tuple. Its
lines describe the parsed text, code-point ranges, bounds, and baselines
for individual lines. The following section shows how to inspect them.
Rendering Markup¶
Pango markup has its own entry point. Do not pass markup to render().
result = manimpango.render_markup(
"<span foreground='red' weight='bold'>Important</span>",
font="Helvetica",
size=24.0,
)
Styling Plain Text with Spans¶
Use TextSpan for styled ranges in plain text. Span
offsets are Python code-point offsets and are half-open, just like string
slices. Spans and markup are deliberately separate APIs.
text = "Hello, world!"
result = manimpango.render(
text,
spans=(
manimpango.TextSpan(0, 5, weight=manimpango.Weight.BOLD),
manimpango.TextSpan(7, 12, foreground="#3366cc"),
),
)
Inspecting Layout Metadata¶
All geometry exposed by ManimPango is a float in SVG user-space units.
Bounds records an x, y, width, and height in that same
coordinate system. LineInfo contains the rendered line text, its
half-open code-point range, bounds, and baseline.
result = manimpango.render("Line 1\nLine 2", width=200.0)
print(result.width, result.height, result.baseline)
print(result.ink_bounds, result.logical_bounds)
for line in result.lines:
print(line.text, line.start, line.end, line.bounds, line.baseline)
Variable Fonts¶
weight accepts a Weight member or an integer from
1 through 1000. Use variations for OpenType axes; axis tags contain
exactly four ASCII characters. ManimPango forwards these settings to Pango,
but a visible effect depends on the selected font, axis, and renderer backend.
For example, the bundled test font’s wght axis changes output on the
current Linux, macOS, and Windows test backends, while its CNTR axis does
not change output through the current macOS Pango/CoreText/Cairo stack. This
is a fixture-and-renderer compatibility observation, not a general CoreText
limitation. Test variation-dependent output on every platform you support.
result = manimpango.render(
"Smooth weight",
font="Inter",
weight=450,
variations={"wght": 650, "wdth": 90},
)
Custom Fonts¶
register_font() returns a
FontRegistration handle. Use it as a context manager
so the registration closes predictably. Multiple handles for a path are
reference-safe; closing one does not release the font while another remains
open.
with manimpango.register_font("path/to/MyFont.ttf") as registration:
assert not registration.closed
result = manimpango.render("Custom font", font="My Font")
assert registration.closed