Skip to main content

unsubsetter

Re-embed full (non-subset) versions of fonts in PDFs.

PDF generators often subset embedded fonts, keeping only the glyphs a document uses and marking the font's PostScript name with a six-letter ABCDEF+ prefix. Some preflight checkers treat subsetted fonts as "not embedded" even though they are. unsubsetter swaps each subset for the complete font found on disk. It was built to get a book past Amazon KDP's preflight check, but applies to any PDF that needs non-subsetted embedded fonts.

It handles CID TrueType and CID CFF fonts. Other font types are detected and reported, but left unchanged — see Limitations.

Install

Install the unsubsetter command into an isolated environment on your PATH:

uv tool install unsubsetter

Or with pipx:

pipx install unsubsetter

From source

git clone https://github.com/saggingmeniscus/unsubsetter
cd unsubsetter
uv tool install .

Usage

Inspect (default — no writes):

unsubsetter book.pdf

Fix (writes book.unsubset.pdf by default):

unsubsetter --fix book.pdf

Filter to specific fonts:

unsubsetter --fix --only Garamond,Helvetica book.pdf

With visual verification (renders N random pages and pixel-diffs them):

unsubsetter --fix --verify-visual 10 book.pdf

Example: preparing a PDF for Amazon KDP

KDP's preflight check is the use case this tool was built for — it can reject a PDF whose fonts look un-embedded, which subsetting may trigger. A careful pre-upload pass:

  1. Inspect (default mode, no writes):

    unsubsetter interior.pdf
    

    Confirm the plan covers the font KDP flagged. Resolve any surprising SKIP lines — e.g. a font that can't be found on disk — first.

  2. Fix with visual sampling:

    unsubsetter --fix --verify-visual 10 interior.pdf
    

    This writes interior.unsubset.pdf and pixel-diffs 10 random pages against the original.

  3. Independent structural check:

    pdffonts interior.unsubset.pdf
    

    Confirm sub=no on every previously-subset CID TrueType or CID CFF font.

  4. Spot-check a few pages in a PDF viewer, paying attention to pages that use fonts the tool reported as skipped — those pass through unchanged and should look identical.

  5. Upload to KDP. If it flags a different font, re-run with --only THAT_FONT to test it in isolation, or report the issue.

Troubleshooting exit code 4

If unsubsetter --fix exits with code 4, the disk font on your system doesn't match the subset embedded in the PDF for one or more CFF fonts. The report names the offending fonts. Either:

  • Locate the matching font version and supply it via --font-path /path/to/font/dir; or
  • Re-run with --exclude FONT_NAME to leave that font alone (it'll stay subset in the output).

Limitations

V2 handles CID TrueType (CIDFontType2) and CID CFF (CIDFontType0) subsetted fonts. Simple Type 1 (/FontFile) and Type 1C (/FontFile3 /Subtype Type1C) are detected and reported, but left unchanged. If a preflight checker flags one of those, outlining (converting the affected glyphs to vector paths) is the usual workaround until those types are supported.

For CFF fonts, unsubsetter runs a glyph-correspondence check between the embedded subset and the disk full font. If they don't agree on glyph identity (e.g., your disk font is a different version than the one originally embedded), the run exits with code 4 and writes no output. Either supply the matching font via --font-path or skip that font with --exclude.

Development

Set up the project and run the test suite:

uv sync --extra dev
uv run pytest

Metadata

Release files for unsubsetter 0.1.0

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

Source distribution (sdist)

Source distribution for unsubsetter 0.1.0
File Size Uploaded Provenance
unsubsetter-0.1.0.tar.gz 89.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for unsubsetter 0.1.0
File Interpreter ABI Platform
unsubsetter-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 110.6 kB

Release files / unsubsetter-0.1.0.tar.gz

Download URL unsubsetter-0.1.0.tar.gz
Size 89.3 kB
Tags Source
SHA-256 checksum
How to use checksums
0b5a6236d9654a309bae8bd616159862e30b3bb9492a4d87c9966d1dc0f4b76a
BLAKE2b-256 checksum
How to use checksums
83a80746a4ef43596bc4b3b7ec5a10a21ec2085b9ed7063c6c53754f5eeb8d05
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Release files / unsubsetter-0.1.0-py3-none-any.whl

Download URL unsubsetter-0.1.0-py3-none-any.whl
Size 21.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7ca757729e8369a1ee12233101f12f2d442f3851658317aecf5d7b982650d4e3
BLAKE2b-256 checksum
How to use checksums
a35a4b7f0b6c9dd8bcfcc77d8ab6d55f89bfe5d9f4ee1c71b663e1b28ce1d02a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Security for unsubsetter 0.1.0

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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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