Write a WOFF2 file
Choose a Brotli compressor for writing. Reading WOFF2 detects the PHP Brotli extension or executable automatically; writing uses the adapter you provide.
With the PHP Brotli extension
Use this when the PHP runtime running your script provides brotli_compress()
and BROTLI_FONT. Create output first and use a new destination filename.
<?php
require __DIR__.'/vendor/autoload.php';
use Alto\Font\Compression\BrotliExtensionCompressor;
use Alto\Font\Font;
use Alto\Font\Writer\Woff2Writer;
$font = Font::fromFile(__DIR__.'/fonts/Inter-Regular.ttf');
$destination = __DIR__.'/output/inter.woff2';
new Woff2Writer(new BrotliExtensionCompressor())->write($font, $destination);
printf("Saved inter.woff2 (%d bytes)\n", filesize($destination));This writes output/inter.woff2 and prints its actual byte size.
To write a subset, pass $result->font from the subset workflow
to the same writer.
With the Brotli executable
Use this as a separate script if brotli is on the process PATH:
<?php
require __DIR__.'/vendor/autoload.php';
use Alto\Font\Compression\BrotliProcessCompressor;
use Alto\Font\Font;
use Alto\Font\Writer\Woff2Writer;
$font = Font::fromFile(__DIR__.'/fonts/Inter-Regular.ttf');
$destination = __DIR__.'/output/inter.woff2';
new Woff2Writer(new BrotliProcessCompressor())->write($font, $destination);
printf("Saved inter.woff2 (%d bytes)\n", filesize($destination));Set binary: '/path/to/brotli' in the compressor constructor if needed.
The process adapter requires proc_open(), a writable temporary directory,
and enough temporary disk space. Missing dependencies and compression failures
raise CompressionException; see runtime requirements.
Choose compression speed
Both adapters default to BrotliCompressionProfile::Maximum (quality 11).
For faster iterative builds, pass profile: BrotliCompressionProfile::Fast
(quality 5). Import Alto\Font\Compression\BrotliCompressionProfile when using
these constants. Compare the resulting sizes for your own fonts.
Files, bytes, and memory
Use write() for a new file or dump() to obtain a complete WOFF2 string for
a storage API. Existing files are never replaced.
With the process adapter, write() streams at the compression boundary using
temporary resources. The parsed font and transforms still occupy memory.
The extension adapter materializes the compressed data for both methods.
Neither promises constant memory for the whole operation.
Custom compressors
Implement BrotliCompressorInterface::compress() to return a raw Brotli stream,
without a WOFF2 header, length prefix, or padding.
An optional BrotliStreamCompressorInterface::compressStream() implementation
reads from the current input position to EOF, writes at the current output
position, leaves both resources open, and does not rewind them.
Check the runtime
Reading WOFF2 detects the PHP Brotli extension or the brotli executable.
Writing needs an explicit compressor passed to Woff2Writer, even when Brotli
is installed. Check the PHP runtime executing your script: a web worker may
have different extensions and an executable PATH unlike your terminal.
The process adapter needs proc_open() and writable temporary storage. Configure
an explicit executable path when it is unavailable through the worker's PATH.