Skip to main content

ufo-tdkit-tools

PyPI CI

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 triplets hstem3/vstem3, font-level Private dict including StdHW/StdVW) and FEA post-processing (one feature block per tag, inlined aalt for spec compliance).
  • 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 + cffsubr subroutinization). Parallel batch via ProcessPoolExecutor.

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[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.

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.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ufo-tdkit-tools 0.2.1
File Size Uploaded Provenance
ufo_tdkit_tools-0.2.1.tar.gz 109.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for ufo-tdkit-tools 0.2.1
File Interpreter ABI Platform
ufo_tdkit_tools-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 197.3 kB

Release files / ufo_tdkit_tools-0.2.1.tar.gz

Download URL ufo_tdkit_tools-0.2.1.tar.gz
Size 109.7 kB
Tags Source
SHA-256 checksum
How to use checksums
d4bec8ae36434e39e11f9c92348331f3b5e63e1fe620c9fe0f1e0d9b757eab85
BLAKE2b-256 checksum
How to use checksums
0eef4b383bacf444af53a2a26a256031c154a680807e9171b1ee466b422d1070
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","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.2.1-py3-none-any.whl

Download URL ufo_tdkit_tools-0.2.1-py3-none-any.whl
Size 87.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
41fcae83d724293a6c83ddce3ec20ad51132245a8148da795100eb5ae15b78ba
BLAKE2b-256 checksum
How to use checksums
42a73ad959b8a51e16f0eefe2a856fd6c015e4868c56eebae5f59b4553687318
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","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.2.1

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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page