Rule-driven anchor placement for UFO fonts
Project description
AnchorsFactory
Rule-driven anchor placement for UFO fonts. You describe, in a compact text file, where anchors should sit on your glyphs; AnchorsFactory computes the coordinates from each glyph's own geometry and writes the anchors into the font.
It does the pre-marking step of accent handling: place top/bottom/_top/…
anchors consistently across hundreds of glyphs, so a tool like
GlyphConstruction can then
assemble composite glyphs by snapping mark anchors to base anchors.
Install
pip install anchorsfactory # once published
# or, from a checkout:
pip install -e .
Requires Python 3.10+, fontParts and fontTools.
Quick start
# place anchors using the bundled default ruleset, save to font_anchored.ufo
anchorsfactory MyFont.ufo --rules default
# your own rules, overwrite in place, with a backup of existing anchors
anchorsfactory MyFont.ufo --rules my-rules.af --in-place --backup-dir backups/
# a whole folder of UFOs
anchorsfactory masters/ --rules default
By default the source UFO is never overwritten — output goes to
*_anchored.ufo unless you pass --in-place.
The rule language
Rules are stacked: define reusable labels, then mark glyphs with them,
mixing labels and one-off anchors. An anchor is a name and a parenthesised
X Y placement.
# a label
@ = top (box.center capHeight), bottom (box.center 0)
# apply it, by name / unicode / range
A = @, ogonek (outline.right 0)
U+0410..U+044F = @ # all Russian Cyrillic
U+0413 += desc (outline.right 0) # Г also gets a descender anchor
- X is
frame.position:width.*(advance),box.*(bounding box) oroutline.*(the contour at height Y, with.first/.lastto pick a stem). - Y is a number, a font metric (
capHeight,xHeight,ascender, …), or a reference glyph ($H,$H.bottom,$H*5/6). - Selectors: name,
U+XXXX, rangeU+A..U+B, glob*.sc, category{Lu}. =replace ·+=add ·-=remove;!extends defaultinherits a ruleset.
Full reference: docs/anchor-rules.md.
Presets and migration
Bundled rulesets default and default-italics are usable by name in
--rules or !extends. Old .txt rule files (see examples/) convert to the
new syntax — verified lossless:
anchorsfactory-convert examples/default-anchors-list.txt -o my-rules.af
Library API
from anchorsfactory import process_ufo, load_document, apply_document
process_ufo("MyFont.ufo", "default") # high-level: open, apply, save
from fontParts.world import OpenFont
font = OpenFont("MyFont.ufo")
apply_document(font, load_document("my-rules.af"))
font.save()
Development
make venv # create .venv, install the package (editable) + dev deps, via uv
make test # run the test suite
make build # build sdist + wheel into dist/
License
See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file anchorsfactory-0.2.0.tar.gz.
File metadata
- Download URL: anchorsfactory-0.2.0.tar.gz
- Upload date:
- Size: 35.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.9 {"installer":{"name":"uv","version":"0.9.9"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Fedora Linux","version":"44","id":"","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8c15d229a2df9e6ce0c0c8e07baa40bbf480908743ba7537fd59c18a4adbc105
|
|
| MD5 |
f34bfb949bd35c584f2337b21648a3c5
|
|
| BLAKE2b-256 |
3caa8f504f567d303f2a9beb438cec9a1c86e632c98580917a7b2d8f8bb6eb82
|
File details
Details for the file anchorsfactory-0.2.0-py3-none-any.whl.
File metadata
- Download URL: anchorsfactory-0.2.0-py3-none-any.whl
- Upload date:
- Size: 29.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.9 {"installer":{"name":"uv","version":"0.9.9"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Fedora Linux","version":"44","id":"","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
429e3e28d18926bdee85ca592a6264d62ff219063d34ca58d5dd92d7f83ddb84
|
|
| MD5 |
4f45ccad689e604164ab3c600e345147
|
|
| BLAKE2b-256 |
094c0b9c0fa91b20bef05e28d65e64c6d7174ba975fdb62b66829d953035f15b
|