ufo-tdkit-tools
PS hints extraction, optimization, and preserve-mode compilation for UFO fonts.
Features
- extraction -- Convert binary fonts (OTF/TTF/WOFF/WOFF2) to UFO with full PS hint preservation (multi-entry
hintSetList, counter tripletshstem3/vstem3, font-level Private dict includingStdHW/StdVW) and FEA post-processing (one feature block per tag, inlinedaaltfor spec compliance). - glyphs -- Convert Glyphs.app sources (
.glyphs/.glyphspackage) to UFO masters +.designspacethrough glyphsLib, with preflight repairs for real-world sources, PS hints translated tocom.adobe.type.autohint.v2and an experimental Glyphs 4 reader. See docs/GLYPHS_IMPORT.md. - ps_hints -- Parse, optimize, analyze, and validate PostScript hints in UFO fonts; move hints between processedglyphs / glyph lib / default layers.
- compilation -- Compile UFO back to OTF preserving PS hints (via AFDKO
makeotf+ per-glyph charstring merge, then production glyph names +cffsubrsubroutinization). Parallel batch viaProcessPoolExecutor.
Installation
pip install ufo-tdkit-tools # core (constants, ps_hints parser)
pip install ufo-tdkit-tools[extraction] # + binary font conversion
pip install ufo-tdkit-tools[compilation] # + OTF compilation with hints
pip install ufo-tdkit-tools[glyphs] # + Glyphs.app source conversion
pip install ufo-tdkit-tools[all] # everything
The extraction and compilation extras pull in AFDKO (>=5,<6), whose wheels ship the tx and makeotf executables the compiler runs — nothing needs to be installed separately.
Quick start
The simplest path is the process_font pipeline — any input (binary or
UFO, hinted or not) becomes a hinted OTF + a clean UFO:
from ufo_tdkit_tools import process_font
result = process_font(
"input.otf", # OTF / TTF / WOFF / WOFF2 / UFO
"out.otf",
"out.ufo",
hint_source="auto", # priority: processed > v2 > public_ps
autohint="fill", # "fill" | "all" | "off"
optimize=False, # set True to run the ps_hints optimizer
)
assert result.success
print(result.glyphs_with_hints, "/", result.glyphs_total,
"autohinted=", result.autohinted_count,
"in otf=", result.otf_glyphs_hinted)
Glyphs the chosen source does not hint are autohinted individually with
afdko.otfautohint — a partially hinted master (base forms hinted,
composites not) comes out fully hinted, with the authored hints kept.
autohint="all" re-hints everything instead, autohint="off" leaves the
gaps alone.
For the lower-level entry points (extraction.convert_binary_to_ufo,
compilation.compile_otf_preserve_optimized, the ps_hints parser /
optimizer / validator / batch wrappers), see docs/API.md.
Legacy kern table for Word
Modern build tools emit kerning only as GPOS, which Microsoft Word ignores.
add_legacy_kern regenerates the old-style kern table from the font's own
GPOS kern feature, rewriting the binary so that nothing but kern changes:
from ufo_tdkit_tools import add_legacy_kern
pairs = add_legacy_kern("Sans-Regular.ttf") # 0 if the font has no GPOS kerning
It needs only fontTools — no extras required.
Command line
Installing the package (uv sync / pip install) provides the
ufo-tdkit-tools console script (also runnable as
python -m ufo_tdkit_tools). It wraps process_font for batch builds:
# Re-hint/optimize a batch of OTFs in place (temp UFO created & discarded)
ufo-tdkit-tools optimize-otf --in-place *.otf
# Or write fresh <stem>.otf + <stem>.ufo pairs into a directory
ufo-tdkit-tools optimize-otf -o build/ Sans-Regular.otf Sans-Bold.otf
# Skip the ps_hints optimizer (autohint + compile only)
ufo-tdkit-tools optimize-otf --in-place --no-optimize *.otf
# Keep only the authored hints, never call the autohinter
ufo-tdkit-tools optimize-otf -o build/ --autohint off Src.ufo
Every run prints one machine-parseable summary line and exits non-zero if any input failed — convenient inside a build log:
optimized=36 autohinted=0 failed=0
--in-place only rewrites .otf inputs (atomically, so a mid-pipeline
failure never corrupts the source). UFO and other binary inputs use -o DIR.
Glyphs.app sources → UFO
glyphs2ufo (needs the glyphs extra) converts .glyphs / .glyphspackage
sources to UFO masters, plus a .designspace when a source has more than one
master:
# Writes Family/<master>.ufo + Family/Family.designspace beside the source
ufo-tdkit-tools glyphs2ufo Family.glyphs
# Several sources into one directory: build/<source stem>/...
ufo-tdkit-tools glyphs2ufo -o build/ Sans.glyphspackage Serif.glyphs
# What would be written, and what already exists there -- converts nothing
ufo-tdkit-tools glyphs2ufo --dry-run Family.glyphs
It refuses to replace UFOs or a .designspace already at the destination
unless given --force (glyphsLib deletes an existing UFO before writing it).
Corner and cap components are baked into the outlines by default, so the UFO
is complete without glyphsLib; --keep-corners leaves them as components. glyphsLib's
warnings — often thousands per source — are grouped into one line per kind,
repairs first; -v adds progress and example glyph names, -q keeps only the
summary line (converted=N failed=K). Ctrl-C cancels cleanly: the conversion
stops at its next checkpoint and removes what it had written (exit code 130).
Round-trip fidelity
OTF → UFO → OTF preserves declared hstem/vstem positions and widths byte-for-byte, hint substitution between drawing operations, counter-mask grouping, and font-level Private dict scalars. The one structural exception is hint substitution that fires between subpaths (a hintmask immediately before a moveto, common on disconnected glyphs like i, j, dieresis-bearing letters): the autohint.v2 format has no anchor for these and AFDKO's own autohint produces the same flattening.
Metadata (OS/2, head, name) also round-trips: fsType, weight/width class, vendor ID, Unicode/code-page ranges, PANOSE, typo/win/hhea metrics, sub/superscript and strikeout, head.macStyle/head.flags, and all name records. The OS/2.fsSelection flags USE_TYPO_METRICS (bit 7), WWS (bit 8) and OBLIQUE (bit 9) are restored during extraction — ufo-extractor (≤ 0.8.1) drops them, so they are re-read straight from the source OS/2 table.
License
Apache-2.0
Metadata
Release files for ufo-tdkit-tools 0.4.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| ufo_tdkit_tools-0.4.5.tar.gz | 178.9 kB | Without provenance | Details for ufo_tdkit_tools-0.4.5.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| ufo_tdkit_tools-0.4.5-py3-none-any.whl | Python 3 | none | any | Details for ufo_tdkit_tools-0.4.5-py3-none-any.whl |
Total release size: 308.5 kB
Release files / ufo_tdkit_tools-0.4.5.tar.gz
| Download URL | ufo_tdkit_tools-0.4.5.tar.gz |
|---|---|
| Size | 178.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c417f2767466d5f52c8fc0063e90f19c6d46f8e4022dfca63980161de3ebf056
|
|
BLAKE2b-256 checksum How to use checksums |
c1585a775a7c60e9d4251f96609c08e649f666e261c42495ecd070437554837a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / ufo_tdkit_tools-0.4.5-py3-none-any.whl
| Download URL | ufo_tdkit_tools-0.4.5-py3-none-any.whl |
|---|---|
| Size | 129.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
44883b95dd48486eaab377a9edf6b228abdbf327f9ef2efe3499eb7f83e2dd45
|
|
BLAKE2b-256 checksum How to use checksums |
d5cd07bdf3b0ac0e56333ef77cce33c8e4b11dce11d8e002d2b2963736eac450
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for ufo-tdkit-tools 0.4.5
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.