Load font files, inspect their data, convert formats, compress webfont output, and create Unicode subsets from PHP.
ALTO Font loads individual font files and discovers matching files in local or system directories. It exposes names, licensing metadata, face dimensions, character maps, glyph metrics, outlines, and variable-font axes. It also converts supported faces between containers, compresses webfont output, and creates conservative Unicode subsets. It does not shape text, apply kerning, or render glyphs.
use Alto\Font\Font;
$font = Font::fromFile(__DIR__.'/fonts/Inter.ttf');
echo $font->metadata()->family;
echo $font->face()->unitsPerEm;
echo $font->metrics('A')->advanceWidth;Unsupported containers and font features fail with typed exceptions instead of returning partial data.
Install ALTO Font with Composer:
composer require alto/fontALTO Font requires PHP 8.4 or later with Iconv and Zlib. WOFF2 additionally
requires the Brotli PHP extension or the brotli executable. Writing WOFF2
uses an explicit compressor adapter.
Load a font and inspect its face, descriptor, and one glyph:
use Alto\Font\Font;
$font = Font::fromFile(__DIR__.'/fonts/Inter-Regular.ttf');
$descriptor = $font->descriptor();
printf(
"%s %s, %d units per em\n",
$descriptor->family,
$descriptor->subfamily,
$font->face()->unitsPerEm,
);
$metrics = $font->metrics('A');
$outline = $font->glyphOutline($metrics->glyphId);Metrics and outlines use the font's design units. Read Getting started for scaling and outline inspection.
A family groups related faces. A face is one selectable design stored in a standalone file or collection. The file container and the glyph outline technology are separate concerns.
Read Font basics for the vocabulary used by the package.
| Format | Reading | Conversion and subsetting |
|---|---|---|
TrueType and OpenType with glyf outlines |
Supported | Supported |
| WOFF 1 | Supported | Supported |
| WOFF2 | Supported, including transformed glyf, loca, and hmtx |
Supported with an injected Brotli compressor |
| TTC and OTC collections | Supported with faceIndex |
Selected faces can be extracted |
Variable glyf fonts |
Supported through fvar, avar, gvar, and HVAR |
Axes can be preserved while subsetting |
| CFF/CFF2 outlines, WOFF2 collections, and color glyphs | Not supported | Not supported |
Read Font formats for requirements, boundaries, and failure types.
Load a known font path with Font::fromFile(), or use FontFinder to select a
matching file by family, weight, style, and stretch.
Find the closest face for a family, weight, style, and stretch query:
use Alto\Font\FontFinder;
use Alto\Font\FontQuery;
$finder = FontFinder::fromDirectories(__DIR__.'/fonts');
$font = $finder->get(FontQuery::family('Inter')->weight(700)->italic());ALTO Font can search application directories, system fonts, or a custom locator. Start with Font files, then read Font discovery for matching and absence policies.
FontFace exposes structural metrics and table tags. FontDescriptor provides
names and CSS-like matching values, while FontMetadata includes optional
manufacturer, designer, vendor URL, and licensing fields.
Character lookup returns a font-specific glyph identifier. From it, retrieve metrics or neutral contour geometry made of move, line, quadratic-curve, and close commands.
Start with Font data, then continue with Font metadata or Glyphs.
Inspect axes and select immutable coordinates:
$boldCondensed = $font->withVariations([
'wght' => 700,
'wdth' => 85,
]);Selected coordinates affect supported glyph metrics and outlines. Read Variable fonts for axes, named instances, clamping, and observable results.
Write a complete face or subset as standalone SFNT, WOFF, or WOFF2:
use Alto\Font\Writer\WoffWriter;
new WoffWriter()->write(
$font,
__DIR__.'/fonts/inter.woff',
);Writers create new destinations and refuse to replace existing files. Read Convert fonts before choosing a writer and output format.
WOFF applies Zlib automatically when it reduces a table. WOFF2 output requires an explicit Brotli adapter:
use Alto\Font\Compression\BrotliExtensionCompressor;
use Alto\Font\Writer\Woff2Writer;
new Woff2Writer(new BrotliExtensionCompressor())->write(
$font,
__DIR__.'/fonts/inter.woff2',
);Read Compress fonts for the overall model, then WOFF2 compression for adapters and profiles.
Create an immutable subset with conservative defaults:
use Alto\Font\Subset\SubsetOptions;
use Alto\Font\Subset\UnicodeSet;
$subset = $font->subset(new SubsetOptions(
UnicodeSet::fromText('ALTO Font 0123456789'),
));
echo $subset->retainedGlyphCount;Read Create a subset before enabling compact glyph IDs, hint removal, or layout removal.
The complete guide links every topic.
Contributions of all kinds are welcome. Visit the project on GitHub to report a bug, suggest a feature, or open a pull request.
Before submitting code, run:
# Runs PHP CS Fixer, PHPStan, and PHPUnit
composer qaChanges to public behavior should include tests and documentation.
ALTO Font is open source. You can support its continued development through GitHub Sponsors.
Sharing this package with others or starring it on GitHub is also much appreciated.
ALTO Font is released by ALTO PHP under the MIT License.