Fontforge Utility Plugin on References and Selections
This plugin helps finding:
- Glyphs with nested references and flatten such references
- Glyphs with distorted references and unlink references
- Unused glyphs and remove them
Required Python version is:
- 3.9 to 3.11 for limited features
- "Select unused glyphs" menu will be disabled in this case due to possible crash
- 3.12 or later for full features
Details
Glyphs with nested references
Nested references are known to cause problems in certain environments. More information can be found at fontbakery issue 2961 and arrowtype issue 412.
Glyphs with distorted references
While each references can have affine transformation, ttfautohint tool cannot deal with distorted references well. Unlinking such references will be needed if you plan to use ttfautohint.
Unused glyphs (Python ≥ 3.12 only)
When a glyph is expressed as unused or unreachable, such glyphs neither has Unicode encodings nor is referenced from another glyph or a GSUB table. They can be dropped to reduce the file size.
Install
pip3 install fontforge-ref-sel-util
Make sure Fontforge Python module is usable
In interactive mode of Python, run:
import fontforge
If it raises ModuleNotFoundError exception, install Fontforge first. If
installed, make sure the build option set that the Python module gets also
installed. If already so, Python interpreter does not recognize the module
path where the required module.
export PYTHONPATH=/path/to/fontforge/python/module:$PYTHONPATH
Usage
In Fontforge GUI
This plugin adds following items into "Tools" menu:
- Select
- Glyphs with nested references
- Glyphs with distorted references
- Glyphs referring currently selected glyphs
- Direct refs only
- Including indirect refs
- Unused glyphs
- Decompose nested references
In Python script
import fontforge
import fontforge_refsel
font = fontforge.open('path/to/font.sfd')
# Select glyphs with nested references
fontforge_refsel.selectGlyphsWithNestedRefs(font) # set selection
fontforge_refsel.selectGlyphsWithNestedRefs(font, 0) # set selection
fontforge_refsel.selectGlyphsWithNestedRefs(font, 1) # append selection
fontforge_refsel.selectGlyphsWithNestedRefs(font, -1) # deselect
# Select glyphs with distorted references
# (i.e. non-identity linearly transformed references)
fontforge_refsel.selectGlyphsWithDistortedRefs(font) # set selection
fontforge_refsel.selectGlyphsWithDistortedRefs(font, 0) # set selection
fontforge_refsel.selectGlyphsWithDistortedRefs(font, 1) # append selection
fontforge_refsel.selectGlyphsWithDistortedRefs(font, -1) # deselect
# Select unreachable glyphs
fontforge_refsel.selectUnusedGlyphs(font) # set selection
fontforge_refsel.selectUnusedGlyphs(font, 0) # set selection
fontforge_refsel.selectUnusedGlyphs(font, 1) # append selection
fontforge_refsel.selectUnusedGlyphs(font, -1) # deselect
# Check a glyph
glyph = font['foo']
result = fontforge_refsel.glyphHasNestedRefs(glyph)
result = fontforge_refsel.glyphHasDistortedRefs(glyph)
result = glyph.glyphname in fontforge_refsel.unusedGlyphs(font)
# List of glyphs with...
result = [glyph.glyphname for glyph in filter(fontforge_refsel.glyphHasNestedRefs, font.glyphs())]
result = [glyph.glyphname for glyph in filter(fontforge_refsel.glyphHasDistortedRefs, font.glyphs())]
result = list(fontforge_refsel.unusedGlyphs(font)) # unusedGlyphs() returns a frozenset object
# Decompose nested references
fontforge_refsel.decomposeNestedRefs(font) # selected glyphs
fontforge_refsel.decomposeNestedRefs(font, False) # selected glyphs
fontforge_refsel.decomposeNestedRefs(font, True) # all glyphs
# if no glyphs are selected, processes all glyphs
# Unlink distorted references (Python < 3.12 may crash)
fontforge_refsel.selectGlyphsWithDistortedRefs(font)
font.unlinkReferences()
font.removeOverlap() # may or may not needed
# Drop unused glyphs (Python < 3.12 may crash)
for glyph in fontforge_refsel.unusedGlyphs(font):
font.removeGlyph(glyph)
# Check what glyph refers certain glyph
glyph = font['foo']
result = fontforge_refsel.whatRefers(glyph) # direct references only
result = fontforge_refsel.whatRefers(glyph, False) # direct references only
result = fontforge_refsel.whatRefers(glyph, True) # also indirect references
Metadata
Release files for fontforge-ref-sel-util 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fontforge_ref_sel_util-0.2.0.tar.gz | 8.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fontforge_ref_sel_util-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 18.5 kB
Release files / fontforge_ref_sel_util-0.2.0.tar.gz
| Download URL | fontforge_ref_sel_util-0.2.0.tar.gz |
|---|---|
| Size | 8.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
949fe768e5962c1b308be9e74f16de8395751cc5557b3dcc4829be56456560f8
|
|
BLAKE2b-256 checksum How to use checksums |
5ae8a9310187b2df9972d3c66605cc4274f84ee31486f074e5751912f43d7d47
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.
Transparency logRelease files / fontforge_ref_sel_util-0.2.0-py3-none-any.whl
| Download URL | fontforge_ref_sel_util-0.2.0-py3-none-any.whl |
|---|---|
| Size | 9.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6ce5ddc9126d8ac1e46ec5c74b8013319be2c5eede4ab6fd460f141870d1e037
|
|
BLAKE2b-256 checksum How to use checksums |
7adbaefca85b6537ade7a707732b3d7c2676479e6bc06a1e5b64b831f978ba4f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.
Transparency log