Zum Inhalt springen

Eigene Schriftarten: der Erweiterungsvertrag der FontRegistry

FontRegistryInterface ist ein prozessweit gültiger Vertrag zum Registrieren und Nachschlagen von Schriftarten. Registrieren Sie Schriftarten aus einem Dateipfad, einem Verzeichnis oder rohen Binärdaten und sperren Sie die Registry anschließend, damit Produktions-Worker sie nicht mehr verändern können.

Terminal-Fenster
composer require nextpdf/core:^3

Die Font-Registry ist ein Singleton, der einzelne Document-Instanzen überdauert. Sie enthält ausschließlich reine PHP-Daten und keine Ressourcen-Handles oder Erweiterungsobjekte. Dadurch kann sie in einem langlebigen Worker gefahrlos über mehrere Requests hinweg gemeinsam genutzt werden.

Der Vertrag unterstützt drei Registrierungswege:

  • Aus einer Datei. register() parst eine .ttf-, .otf-, .ttc- oder .pfb-Datei und gibt geparste Metadaten zurück. Übergeben Sie bei einer TrueType Collection den Index der Sub-Schriftart.
  • Aus einem Verzeichnis. addFontDirectory() fügt einen Suchpfad hinzu, den die Engine durchsucht, wenn sie eine Familie anhand ihres Namens auflöst.
  • Aus Binärdaten. registerFromBinary() parst rohe TrueType- oder OpenType-Bytes. Diesen Weg nutzt die @font-face-Brücke für Schriftarten, die aus data:-URIs oder von entfernten Quellen geladen werden.

Um die Latenz des ersten Requests zu verteilen, rufen Sie warmup() beim Worker-Start auf und parsen damit einen Stapel Schriftarten vorab. Rufen Sie danach lock() auf. Nach lock() wirft jede mutierende Methode eine LogicException. Diese Methoden sind register(), addFontDirectory(), warmup(), registerBase14() und registerFromBinary(). Nachschlage-Methoden bleiben verfügbar: get(), has(), all() und getSearchDirectories(). Diese Sperre ist der Sicherheitsmechanismus für die Produktion. Sie garantiert, dass kein Request das gemeinsam genutzte Schriftartenset verändern kann.

In den meisten Fällen implementieren Sie FontRegistryInterface nicht selbst. Die Engine stellt die Implementierung bereit; Sie rufen sie nur auf. Implementieren Sie den Vertrag nur dann, wenn Sie eine eigene Strategie zur Schriftartauflösung benötigen, zum Beispiel eine, die auf einem inhaltsadressierten Speicher basiert. In beiden Fällen ist der Vertrag die Grenze.

NextPDF\Contracts\FontRegistryInterface (stabil, seit 1.7.0):

MethodeRückgabeZweck
register(string $fontFile, string $alias, int $fontIndex)FontInfoParst und registriert eine Schriftartdatei. Wirft bei einer gesperrten Registry oder einer nicht parsbaren Datei eine Exception.
registerFromBinary(string $fontData, string $alias)FontInfoRegistriert eine Schriftart aus rohen TrueType- oder OpenType-Bytes.
registerBase14(string $key, FontInfo $font)voidRegistriert eine vordefinierte Base-14-Standardschriftart.
addFontDirectory(string $directory)voidFügt ein Schriftartensuchverzeichnis hinzu.
warmup(array $fontFiles)voidParst beim Worker-Start einen Stapel Schriftarten vorab.
lock()voidFriert die Registry gegen weitere Mutationen ein.
isLocked()boolMeldet, ob die Registry gesperrt ist.
get(string $family, string $style)FontInfo | nullSchlägt eine Schriftart nach Familie und Stil nach.
has(string $key)boolPrüft, ob ein Registrierungsschlüssel vorhanden ist.
all()array<string, FontInfo>Gibt alle registrierten Schriftarten zurück.
getSearchDirectories()list<string>Gibt die Suchverzeichnisse in ihrer Reihenfolge zurück.
memoryUsage()MemoryReportMeldet die aktuelle Speichernutzung der Registry.
<?php
declare(strict_types=1);
use NextPDF\Contracts\FontRegistryInterface;
/** @var FontRegistryInterface $fonts */
$info = $fonts->register('/srv/fonts/Inter-Regular.ttf', 'Inter');
if (!$fonts->has('inter')) {
throw new RuntimeException('Inter failed to register');
}

Diese Worker-Start-Routine führt ein Warmup für ein Schriftartenset durch, sperrt die Registry und beobachtet jeden Ladevorgang zur Lizenznachverfolgung. Alle verwendeten Typen sind öffentlich.

<?php
declare(strict_types=1);
use NextPDF\Contracts\FontRegistryInterface;
use NextPDF\Event\Content\FontLoadedEvent;
use NextPDF\Event\EventDispatcher;
use NextPDF\Event\ListenerProvider;
use Psr\Log\LoggerInterface;
final class FontWarmup
{
/** @param list<string> $fontFiles */
public function __construct(
private readonly FontRegistryInterface $fonts,
private readonly LoggerInterface $logger,
private readonly array $fontFiles,
) {}
public function boot(): EventDispatcher
{
$listeners = new ListenerProvider();
$listeners->addListener(
FontLoadedEvent::class,
function (FontLoadedEvent $event): void {
$this->logger->info('font.loaded', [
'family' => $event->family,
'style' => $event->style,
'type' => $event->fontType->name,
]);
},
);
if (!$this->fonts->isLocked()) {
$this->fonts->warmup($this->fontFiles);
$this->fonts->lock();
}
return new EventDispatcher($listeners);
}
}
  • Gesperrte Registry. Jede Mutation nach lock() wirft eine LogicException. Prüfen Sie in einem wiederverwendeten Worker immer isLocked(), bevor Sie ein bedingtes Warmup durchführen.
  • Binäre Registrierung wird nicht über einen Schlüssel gecacht. registerFromBinary() schreibt in eine temporäre Datei und parst diese. Behandeln Sie das zurückgegebene FontInfo als Handle.
  • TTC-Index. Bei einer TrueType Collection wählt das dritte Argument von register() die Sub-Schriftart aus. Der Standardwert 0 wählt die erste Sub-Schriftart aus.
  • Familienauflösung. get() gibt für ein unbekanntes Paar aus Familie und Stil null zurück. Gehen Sie niemals von einem Nicht-null-Ergebnis aus.

warmup() verschiebt die Parsing-Kosten vom ersten Request zum Start. Registry-Methoden arbeiten mit reinen PHP-Daten. Nachschlagevorgänge sind Map-Lesezugriffe mit konstanter Laufzeit. Rufen Sie memoryUsage() auf, um das im Speicher gehaltene Schriftartenset eines Workers an Ihrem Speicherbudget auszurichten.

Eine registrierte Schriftart wird zu einbettbarem PDF-Inhalt. Validieren Sie die Herkunft einer Schriftart vor der Registrierung. Registrieren Sie keine von Angreifern kontrollierten Binärdaten ohne Größen- und Formatprüfungen. Der Hook FontLoadedEvent ist die unterstützte Stelle, um die Einhaltung von Schriftartlizenzen durchzusetzen und festzuhalten, welche Schriftschnitte ein Dokument einbettet.

Es gelten keine normativen Aussagen zu Signaturen oder Archivierung. Das Einbetten und Subsetting von Schriftarten entspricht dem Schriftartmodell von PDF 2.0; diese Konformität liegt beim internen Subsetter, nicht bei diesem Vertrag.

NextPDF Enterprise ergänzt dasselbe FontRegistryInterface um Schriftart-Lizenzattestierung und eine auditierte Subsetting-Richtlinie. Ihr Registrierungscode bleibt über alle Editionen hinweg unverändert, weil der Vertrag die Grenze ist.

Das Glossar definiert Font-Registry, Image-Registry und Event-Listener; die kanonischen Definitionen finden Sie auf der veröffentlichten Glossarseite.