Python Extension Technical Details¶
This document covers the technical details of FontForge’s Python extension module, including building wheels for PyPI distribution.
Modules¶
FontForge provides two Python modules:
fontforge- Main font manipulation APIpsMat- PostScript matrix operations
Build Scenarios¶
Scenario |
Detection |
GUI |
Install Location |
|---|---|---|---|
Wheel (pip) |
|
OFF |
Wheel root |
System install |
Manual cmake |
ON/OFF |
site-packages |
Dependencies¶
- Required (always linked):
libxml2, zlib, libiconv
- Bundled in wheels:
FreeType, libpng, libjpeg, libtiff, libspiro, woff2
- Not needed for wheels (GUI-only):
GLIB, Gettext/Intl, Readline
Versioning¶
The source uses PROJECT_VERSION = 20251009 (YYYYMMDD format).
Wheels use CalVer format 2025.10.9.
fontforge.version() returns:
CalVer when imported as a module (from site-packages or wheel)
Numeric format when Python is embedded in the running FontForge application
CMake transformation:
string(SUBSTRING "${PROJECT_VERSION}" 0 4 _FF_YEAR)
string(SUBSTRING "${PROJECT_VERSION}" 4 2 _FF_MONTH)
string(SUBSTRING "${PROJECT_VERSION}" 6 2 _FF_DAY)
math(EXPR _FF_MONTH_INT "${_FF_MONTH}")
math(EXPR _FF_DAY_INT "${_FF_DAY}")
set(FONTFORGE_PYTHON_VERSION "${_FF_YEAR}.${_FF_MONTH_INT}.${_FF_DAY_INT}")
Windows MSVC Build¶
Windows wheels require MSVC because Python.org’s Windows Python is built with MSVC. The MinGW build continues for the GUI application.
MSVC compatibility patterns:
// UNUSED macro
#ifdef _MSC_VER
# define UNUSED(x) x
#elif defined(__GNUC__)
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
#endif
DLL exports: MinGW uses --export-all-symbols. MSVC needs explicit
__declspec(dllexport) or a DEF file.
vcpkg provides dependencies:
{
"name": "fontforge",
"dependencies": ["freetype", "libxml2", "glib", "gettext", "libiconv", "zlib"]
}
Build Configuration¶
Wheels are built using scikit-build-core. See pyproject.toml for the
current configuration.
[build-system]
requires = ["scikit-build-core>=0.5"]
build-backend = "scikit_build_core.build"
[project]
name = "fontforge"
dynamic = ["version"]
[tool.scikit-build]
cmake.args = ["-DENABLE_GUI=OFF", "-DENABLE_PYTHON_EXTENSION=ON"]
wheel.install-dir = "."
Wheel Target Platforms¶
The project builds wheels for:
Linux: x86_64, aarch64 (manylinux_2_28)
macOS: x86_64, arm64 (separate wheels, macOS 11.0+)
Windows: x64 (MSVC)
Install Conflict Handling¶
App installs create fontforge-{version}.dist-info/ with
INSTALLER = fontforge-app. This allows pip list to show the install
and pip uninstall to work.
If a pip-installed version exists, app install skips and suggests
pip uninstall fontforge.