Thirteen original Apache-2.0 examples for FontLab 9. Each entry verifies a
fixture SHA-256, copies its VFJ to a new temporary directory, opens that copy
and closes exactly that package in finally. Copy paths are resolved before opening
so macOS /var and /private/var refer to the same owned document. Successful cleanup removes the
working directory; failed close retains it. Nothing saves over testdata.
Font attribution and licences remain in the fixture manifest.
All modules import outside FontLab. Entry functions need FontLab's fontlab,
fontgate objects and fontpr bridge. The pen/export entries additionally need
FontTools installed in FontLab's Python 3.11 interpreter. TypeRig and Fontport
are not required for these thirteen scripts. Run edits in a dedicated no-document
FontLab session through the workspace native runner. Native status: 13/13 passed
on 2026-10-16, FontLab 9.0.9783 (workspace receipt: verification/issue-106/evidence/getgo/examples3-all/receipt.json).
The receipt covers run(), declared assertions, owned cleanup and unchanged fixtures; host-free tests remain separate.
These are repository-checkout demos, not standalone Scripts-folder installations.
Keep the checkout (including testdata/getgo) together and put its root on
sys.path once, then import an example:
import sys
sys.path.insert(0, "/path/to/fontlab-python-examples")
from examples.getgo import font_audit
print(font_audit.run())Each script also has a MenuTitle and prints its result when executed from the
Scripting panel as __main__; keep that root on sys.path for this route too.
No script chooses the current font. The UI returns an explicitly owned handle;
all other results are dictionaries. Mutation entries enforce the no-document
requirement before reading fixtures or creating a working directory and name any
open documents in the error. Read-only examples may coexist with other fonts.
font_audit.py uses GG Baar
(CC0-1.0). Measured: 96 glyphs, 95 encoded scalars, 2048 UPM, and no anchors.
The report also covers vertical metrics, unencoded names and Unicode collisions.
GG Baar has zero anchors: both counts make that explicit, alongside missing A/H
top anchors. The explicit
anchor policy demonstrates a check; an absent anchor is not automatically a font defect.
unicode_coverage.py uses
Zoto Kufi Arabic
(Apache-2.0). run(text="مرحبا بالعالم 123") compares native encodings against
unique scalars through a Unicode-only reader. Measured: eight covered code points;
U+0031/U+0032/U+0033 are missing. U+0627 is covered; no layer/anchor lookup is needed.
Encoding coverage does not prove contextual shaping.
outline_pens.py uses GG Hint
(Apache-2.0). A/B/O contours pass through FontTools BoundsPen/AreaPen for exact
curve bounds and signed areas. Measured A/B/O: 2/3/2 contours, 11/55/42 points;
winding labels and FontLab hasIntersPoints boundary-intersection index pairs.
Contained counters and self-intersections are outside the pairwise test;
this is not filled-region boolean overlap detection or overlap removal. Each native
recording converts QPointF operands to tuples before segment-pen validation; open paths
require endPath, closed paths closePath. This receipt validates closed native
contours; native open-path coverage remains a follow-up.
naming.py uses GG Baar
(CC0-1.0). Measured: assigned family, style, preferred and PostScript names read back;
family becomes Scripting Sample, PS name ScriptingSample-Regular.
Copyright/licence stay intact. The small policy accepts ASCII letters, digits
and spaces and enforces the 63-character PS limit. Changes are discarded on close.
kerning_classes.py uses
GG Stroke Chan OFL Italic
(OFL-1.1). Measured on the Italic master: default-master pair count, typed pair sides,
explicit zero values, class members/modes and dangling member names. The default
run(limit=5) returns totals (619 pairs across 79 left sides, 233 classes) and up to five pairs, classes
and members per class; run(limit=None) returns complete data. Opaque native
modes become text for JSON. No class expansion or OFL font renaming occurs.
designspace.py uses GG Cosm
(CC0-1.0). Measured: three masters, one wght axis, separate user/design ranges,
master and eight export-instance coordinates in axis order. valueWeight reads design
coordinates. The selected master stays unchanged; no interpolation is implied.
master_compatibility.py uses
GG Plum (CC0-1.0).
Measured: A/V/a match across all three masters; reports include closed flags, compatible
and missing_layers. Missing layers differ from empty layers. Equal topology
does not prove component compatibility, contour correspondence or interpolation quality.
spacing.py uses GG Baar
(CC0-1.0). It plans I's shift/new width, moves direct nodes and anchors and
reads bearings back. Measured: I's bearings [128, 0], shift 48, new width 416, plus
plan and resulting sidebearings. The fixed H/I inputs have direct outlines;
only I on the owned font's default master changes. The basic node/anchor move
follows the existing sidebearing recipe;
this demo adds an owned real input, an RSB-aware plan and bounds from re-read nodes
of the straight-line I outline; native cached boundingBox/contourRect remain stale.
batch_transform.py uses GG Baar
(CC0-1.0). run(scale=1.1) preflights both glyphs and scales direct node/anchor
x coordinates and advances, retaining y coordinates. Expected: A/V point counts
Measured A/V widths: 640 → 704. Readback re-fetches the layer
and contours instead of inspecting the wrappers just assigned; anchors and
advance widths are checked too. Scaling about x=0 also scales both sidebearings.
Only the disposable default master changes; source data stays intact.
export_ttf.py uses GG Baar
(CC0-1.0). Native contour pens capture .notdef, space, A, V; the font
closes before Cu2QuPen/TTGlyphPen and FontBuilder create a TTF geometry subset.
The native pen adapter detaches QPointF coordinates into ordinary tuples for both exports.
Measured: verified: true, format: glyf, retained binary path, exact glyph
order/cmap/advances/UPM and full licence name record. Reopened bounds must agree
within two units for curve conversion and coordinate rounding. Every contour
is also measured with AreaPen after binary reopening: TTF signs must reverse
the source signs, and CFF signs must match. winding_verified and per-contour
winding reports expose those checks without assuming absolute source winding.
export_otf.py uses GG Baar
(CC0-1.0). T2CharStringPen builds the same subset as CFF OpenType.
Measured: verified: true, format: CFF and the same readback checks.
Both exports accept run(destination="/absolute/new-sample.otf") (use .ttf
for TTF); the default retains a new temporary export directory. Existing files
and symlinks are refused. Outputs are named Scripting Sample, with complete
CC0 text, copyright and public source URL. These geometry subsets omit native
hints, features, kerning, axes and other layers. They demonstrate pen interchange,
not FontLab's export profiles.
font_info_ui.py uses
GG Stroke Chan OFL Italic
(OFL-1.1). It closes the font before showing a QtGui QDialog with a plain text
QLabel. Measured: GG Stroke Chan OFL, 106 glyphs, 1000 UPM, Italic master. Retain the handle:
tool = font_info_ui.run(), inspect tool.report/tool.widget, call
tool.close() in finally, then drain deferred deletion events in the native
runner. The Scripting-panel __main__ route calls canonical-module show(),
which retains font_info_ui.TOOL even when panel globals are discarded; a second
launch closes the predecessor. Native acceptance must exercise this route and
verify the plain-text enum, visibility and deferred deletion. Cleanup is idempotent. No signals, QApplication or second loop are created.
compare_fonts.py uses GG Baar (CC0-1.0) and GG Hint (Apache-2.0). Measured: 96 common glyphs, 274 Hint-only glyphs, none Baar-only; width differences in em units (right minus left), using each font's own UPM. Nested owned contexts close both documents even if opening or inspecting the second fails.
native_manifest.json lists all entries, fonts, dependencies, observable checks, cleanup and measured native passes from the linked receipt.
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 uv run --no-project --with pytest python -m pytest -q testsFontLab's run_python has a fixed 5-second deadline. Never execute a complete
run() synchronously through it: file opening, import cold starts and compilation
can exceed it. Use the Scripting panel or an event-loop callback outside the
request, keeping run_python calls to short setup/enqueue/poll operations. Preserve
a detached result/error receipt and poll it; a client timeout is not a native pass.
Manifest expected entries are machine assertions (path plus exactly one of
equals, len, contains, gt), executed by _checks.assert_expected(result, row["expected"]). Paths include dictionary keys, list indices and UI handle
attributes. UI cleanup is explicitly handle.close. The manifest's
native_followups retain save-prompt, metadata-renormalization, refreshed-bounds,
segment-pen and Scripting-panel UI checks for the native worker.
Add --with fonttools to uv run and target tests/test_getgo_scripts.py for
real pens, binary and winding-tamper checks. No Fontport dependency or legacy
scripts.py API remains; the needed master-report helper now lives in designspace.py.