OTFeatureFreezer GUI app and pyftfeatfreeze commandline tool in Python to permanently "apply" OpenType features to fonts, by remapping their Unicode assignments
View the Project on GitHub twardoch/fonttools-opentype-feature-freezer
OpenType Feature Freezer is a powerful tool designed to make sophisticated typographic features, like small caps or old-style numerals, accessible by default in your fonts. This means you can use these features even in applications with limited or no OpenType support.
Many professional fonts come with “OpenType features” – special typographic effects such as true small capitals, alternative character shapes, ligatures, or figures (numbers) that align differently with text. Normally, you need specific software that allows you to turn these features on.
OpenType Feature Freezer modifies a font file so that selected OpenType features are “frozen” into it. The characters that were previously only accessible via these features become the default characters in the modified font.
For example, if you freeze the “small caps” (smcp) feature, typing lowercase letters will directly produce small capitals.
This tool is for anyone who wants to use advanced typographic features in applications that don’t provide easy access to OpenType controls. This includes:
OpenType Feature Freezer is available in two forms:
OTFeatureFreezer.app icon to your /Applications folder.OTFeatureFreezer.app icon in /Applications, choose “Open” from the menu, and then click “Open” in the dialog box.setup_featfreeze.exe to install the application.This requires Python 3.6 or newer. If you don’t have Python, get it from python.org or your system’s package manager.
Recommended Method (using pipx): Pipx installs Python command-line tools in isolated environments, which is clean and convenient.
pipx install opentype-feature-freezer
To upgrade later:
pipx upgrade opentype-feature-freezer
Alternative Method (using pip):
It’s generally recommended to run pip via python3 -m pip to ensure you’re using pip associated with the correct Python installation, especially if you have multiple Python versions.
It’s best to do this inside a Python virtual environment:
python3 -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
python3 -m pip install --upgrade opentype-feature-freezer
If the above fails, or for a user-specific installation (avoids needing admin rights):
python3 -m pip install --user --upgrade opentype-feature-freezer
Development Version (from GitHub - for testing latest changes):
python3 -m pip install --upgrade git+https://github.com/twardoch/fonttools-opentype-feature-freezer
The GUI provides an easy-to-use interface for all the freezing and renaming options:
.otf or .ttf font file.[input_filename].featfreeze.otf by default).smcp,c2sc,onum). These are the features you want to “freeze.”cyrl, latn) to apply features only for that script. If blank, features are applied across all relevant scripts.SRB for Serbian) to apply features for that specific language system.search1/replace1,search2/replace2.The GUI includes a “Help” menu with links to “About” information and the project’s online documentation.
The basic command structure is:
pyftfeatfreeze [OPTIONS] INPATH [OUTPATH]
INPATH: Path to the input .otf or .ttf font file.OUTPATH: Optional path for the output font file. If omitted, it defaults to INPATH.featfreeze.otf.Common CLI Options:
-f TAGS, --features TAGS: Comma-separated OpenType feature tags (e.g., 'smcp,c2sc').-s SCRIPT, --script SCRIPT: OpenType script tag (e.g., cyrl). If omitted, processing applies to all relevant scripts.-l LANG, --lang LANG: OpenType language tag (e.g., SRB ).-S, --suffix: Add a suffix to font family name (derived from feature tags).-U SUFFIX, --usesuffix SUFFIX: Use a custom suffix (e.g., SC) when -S is active.-R 'S/R,...', --replacenames 'S/R,...': Search and replace strings in font names (e.g., 'MyFont/MyFontNew,Regular/Reg').-z, --zapnames: Zap glyph names from TTF fonts.-i, --info: Update font version string.-r, --report: Report font’s features, scripts, languages instead of processing.-n, --names: Output names of remapped glyphs.-v, --verbose: Print detailed processing information.-V, --version: Show program version.-h, --help: Show help message with all options.CLI Examples:
pyftfeatfreeze -f 'c2sc,smcp,onum' -S -U "SC OS" -R 'OpenSans/OpenSansSO' OpenSans-Regular.ttf OpenSansSO-Regular.ttf
locl for Cyrillic script, Bulgarian language), add “BG” suffix:
pyftfeatfreeze -f 'locl' -s 'cyrl' -l 'BGR ' -S -U BG MyFont.otf MyFontBG.otf
Note: To remap features for multiple script/language combinations, run the tool multiple times, using the output of one run as the input for the next. Apply renaming options (-S, -U, -R) typically on the final run.
pyftfeatfreeze -R 'Lato/Otal,Regular/Rg' Lato-Regular.ttf Otal-Rg.ttf
The core logic resides in the RemapByOTL class within src/opentype_feature_freezer/__init__.py. The process flow is as follows:
fontTools.ttLib.TTFont.--features), script tag (--script), and language tag (--lang).LangSysRecord, the DefaultLangSys for that script is used.a.alt1 from [a.alt1, a.alt2]).cmap Remapping:
cmap table) is modified. Existing Unicode codepoints that pointed to original glyphs are updated to point to the new glyphs resulting from the applied substitutions. This is what makes the features “default.”--suffix, --usesuffix, or --replacenames, the tool modifies various name records in the name table (e.g., Family Name (ID 1), Full Name (ID 4), PostScript Name (ID 6), Version String (ID 5), Unique ID (ID 3), WWS Family/Subfamily (ID 16, 17))..otf), it also updates FamilyName, FullName, and the main font name in the CFF table..ttf), the --zapnames option sets the post table format to 3.0. This removes glyph names from the font, which can sometimes reduce file size but makes debugging harder.fontTools.ttLib.TTFont.save().Key Modules:
src/opentype_feature_freezer/__init__.py: Contains the RemapByOTL class with the primary font processing logic.src/opentype_feature_freezer/cli.py: Implements the pyftfeatfreeze command-line interface using Python’s argparse module. It parses arguments and passes them to RemapByOTL.app/OTFeatureFreezer.py: Uses ezgooey to wrap the argparse definitions from cli.py, creating the OTFeatureFreezer GUI application for macOS and Windows.Limitations:
cmap Dependency: The tool works by remapping existing cmap entries. If a glyph involved in a substitution (either the original or the replacement) does not have a Unicode value assigned in any cmap table, that specific remapping might not have a visible effect through standard character input. A warning is issued in such cases.typing module usage.logging module is used for outputting informational messages, warnings, and errors. Verbosity is controlled by the -v flag.pyproject.toml.mypy.ini.tests/ directory.pyproject.toml apart from MyPy, contributions should generally follow PEP 8 guidelines and maintain consistency with the existing codebase.Contributions are welcome! Whether it’s reporting a bug, suggesting an improvement, or submitting code changes.
Reporting Issues:
Development Setup:
git clone https://github.com/twardoch/fonttools-opentype-feature-freezer.git
cd fonttools-opentype-feature-freezer
pytest and mypy, in a virtual environment using Poetry:
poetry install
poetry shell
Building:
poetry build
The distributable files will be in the dist/ directory.
app/ subdirectory.cd app
./macdeploy all
Running Tests:
poetry install).pytest from the project root directory:
pytest
Or, if your environment is not yet active:
poetry run pytest
This tool is licensed “as is” under the Apache License, Version 2.0. By using the tool, you accept all conditions of the license, including Disclaimer of Warranty and Limitation of Liability.
Important: When modifying fonts, please ensure you comply with the font’s End User License Agreement (EULA). If the font is licensed under the SIL Open Font License (OFL) and uses Reserved Font Name(s), you must use the -R (rename) option to change the font’s name if you plan to distribute the modified version.
-s (script) option: if not provided, remapping attempts to apply to all relevant scripts.-S (suffix) option: if not provided, no suffix is added. Introduced GUI apps.For older history, this tool was previously part of the fonttools-utils repository.
AUTHORS and CONTRIBUTORS files, and GitHub commit history).fontTools library.