Salta ai contenuti

Font personalizzati: contratto di estensione FontRegistry

FontRegistryInterface è il contratto, valido per l’intera durata del processo, per registrare e cercare i font. Registrare i font da un percorso file, da una directory o da dati binari grezzi, quindi bloccare il registro in modo che i worker di produzione non possano modificarlo.

Terminal window
composer require nextpdf/core:^3

Il registro dei font è un singleton che sopravvive alle singole istanze di Document. Contiene solo dati PHP puri, senza handle di risorse né oggetti di estensione. Per questo può essere condiviso in sicurezza tra più richieste in un worker a esecuzione prolungata.

Il contratto supporta tre percorsi di registrazione:

  • Da un file. register() analizza un file .ttf, .otf, .ttc o .pfb e restituisce i metadati rilevati. Per una TrueType Collection, passare l’indice del sotto-font.
  • Da una directory. addFontDirectory() aggiunge un percorso di ricerca che il motore consulta quando risolve una famiglia per nome.
  • Da dati binari. registerFromBinary() analizza byte grezzi TrueType o OpenType. È il percorso utilizzato dal bridge @font-face per i font recuperati da URI data: o da origini remote.

Per ammortizzare la latenza della prima richiesta, chiamare warmup() all’avvio del worker per pre-analizzare un batch di font. Poi chiamare lock(). Dopo lock(), ogni metodo di mutazione genera LogicException. Questi metodi sono register(), addFontDirectory(), warmup(), registerBase14() e registerFromBinary(). I metodi di ricerca restano disponibili: get(), has(), all() e getSearchDirectories(). Questo blocco è il meccanismo di sicurezza previsto per la produzione. Garantisce che nessuna richiesta possa alterare il set di font condiviso.

Nella maggior parte dei casi non occorre implementare FontRegistryInterface. Il motore fornisce l’implementazione ed è sufficiente richiamarla. Occorre invece implementarla quando serve una strategia personalizzata di risoluzione dei font, ad esempio basata su un archivio indirizzato per contenuto. In entrambi i casi il contratto rappresenta il confine.

NextPDF\Contracts\FontRegistryInterface (stabile, dalla versione 1.7.0):

MetodoValore restituitoScopo
register(string $fontFile, string $alias, int $fontIndex)FontInfoAnalizza e registra un file di font. Genera un’eccezione se il registro è bloccato o se il file non è analizzabile.
registerFromBinary(string $fontData, string $alias)FontInfoRegistra un font a partire da byte TrueType o OpenType grezzi.
registerBase14(string $key, FontInfo $font)voidRegistra un font standard Base 14 predefinito.
addFontDirectory(string $directory)voidAggiunge una directory di ricerca dei font.
warmup(array $fontFiles)voidPre-analizza un batch di font all’avvio del worker.
lock()voidCongela il registro impedendo ulteriori mutazioni.
isLocked()boolIndica se il registro è bloccato.
get(string $family, string $style)FontInfo | nullCerca un font per famiglia e stile.
has(string $key)boolVerifica se esiste una chiave di registrazione.
all()array<string, FontInfo>Restituisce tutti i font registrati.
getSearchDirectories()list<string>Restituisce le directory di ricerca in ordine.
memoryUsage()MemoryReportRiporta l’utilizzo di memoria corrente del registro.
<?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');
}

Questa routine di avvio del worker prepara un set di font, blocca il registro e osserva ogni caricamento ai fini del tracciamento delle licenze. Tutti i tipi usati sono pubblici.

<?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);
}
}
  • Registro bloccato. Qualsiasi mutazione dopo lock() genera LogicException. Verificare sempre isLocked() prima di eseguire un warmup condizionale in un worker riciclato.
  • La registrazione binaria non viene memorizzata nella cache per chiave. registerFromBinary() scrive su un file temporaneo e lo analizza. Considerare come handle il FontInfo restituito.
  • Indice TTC. Per una TrueType Collection, il terzo argomento di register() seleziona il sotto-font. Il valore predefinito 0 seleziona la prima face.
  • Risoluzione della famiglia. get() restituisce null per una coppia famiglia-stile sconosciuta. Non presupporre mai che il risultato sia non null.

warmup() sposta il costo di analisi dalla prima richiesta all’avvio. I metodi del registro operano su dati PHP puri. Le ricerche sono letture di mappa a tempo costante. Chiamare memoryUsage() per dimensionare il set residente di font di un worker in base al budget di memoria.

Un font registrato diventa contenuto PDF incorporabile. Convalidare la provenienza del font prima della registrazione. Non registrare dati binari controllati da un utente malintenzionato senza controlli su dimensione e formato. L’hook FontLoadedEvent è il punto previsto per applicare i controlli di conformità alle licenze dei font e registrare quali face vengono incorporate in un documento.

Non si applica alcuna dichiarazione normativa di firma o archiviazione. L’incorporamento e il subsetting dei font sono conformi al modello dei font di PDF 2.0; tale conformità è di competenza del subsetter interno, non di questo contratto.

NextPDF Enterprise aggiunge l’attestazione delle licenze dei font e una policy di subsetting verificata sullo stesso FontRegistryInterface. Il codice di registrazione resta invariato tra le edizioni, perché il contratto rappresenta il confine.

Il glossario definisce font registry, image registry ed event listener; consultare il glossario pubblicato per la definizione canonica di ciascun termine.