Police : types de valeurs, intégration et repli
Dans NextPDF, une police correspond à l’objet-valeur immuable FontInfo, auquel s’ajoute le type de technologie qui détermine la manière dont le moteur l’intègre. Chaque police utilisée par le moteur est intégrée. Toute référence Base 14 héritée utilise en repli un substitut à métriques compatibles fourni avec le paquet.
Installation
Section intitulée « Installation »composer require nextpdf/core:^3Vue d’ensemble conceptuelle
Section intitulée « Vue d’ensemble conceptuelle »FontInfo est l’unique objet-valeur immuable qui contient tout ce dont le moteur a besoin pour intégrer une police : la famille et le style, le nom PostScript, les indicateurs du descripteur, les métriques mises à l’échelle sur un em de 1000 unités, les largeurs de caractères, la table glyphe-vers-Unicode, la cmap directe (Unicode vers identifiant de glyphe), les octets bruts de la police et, lorsqu’ils sont présents, les axes de variation, les instances nommées, les sélecteurs de variation, les paires de crénage et les métriques verticales. Elle est final readonly. La signature du constructeur et les propriétés publiques sont figées ; une police analysée est donc un fait stable et partageable. FontInfo::encodeText() est la seule méthode qui effectue un traitement. Elle passe par le résolveur d’encodage et renvoie un EncodedGlyphRun.
FontType énumère les technologies intégrées par le moteur : TrueType (encodage sur un seul octet), TrueTypeUnicode (encodage CID multi-octets pour les écritures riches en Unicode), OpenType (contours Compact Font Format), Type1 (PostScript Type 1, enregistrée à partir d’une paire PFB et AFM) et CidFont0 (une police CID basée sur PostScript). Le type attribué par l’analyseur détermine la forme du dictionnaire de police émis par l’enregistreur.
Le moteur intègre le programme de police afin que le document s’affiche de la même manière dans n’importe quel lecteur, indépendamment des polices système installées — ISO 32000-2 §9. Un programme TrueType est intégré via l’entrée FontFile2 du descripteur de police et doit inclure les tables glyf, head, hhea, hmtx, loca et maxp — ISO 32000-2 §9.6.5 (digest RAG tronqué par le plafond de licence ; consigné dans _downgraded-claims-o3.md). Un programme OpenType doté d’une table de contours Compact Font Format est intégré via FontFile3 — ISO 32000-2 §9.6.5 (digest RAG tronqué ; voir le même journal). Le sous-ensembleur reconstruit exactement l’ensemble de tables requis ; le sous-ensemble intégré reste donc un programme conforme.
Le repli couvre le cas hérité des Base 14. Base14SubstituteFonts associe une clé Base 14 normalisée — helvetica, helveticab, times, courier et les autres — à un fichier Liberation Fonts fourni avec le paquet. Liberation Sans, Serif et Mono ont des métriques compatibles avec Helvetica ou Arial, Times Roman et Courier. Chacune est une fonte TrueType incorporée, qui restitue donc l’intégralité du répertoire latin WinAnsiEncoding (Windows-1252) qu’exige une référence standard-14 — latin accentué, signe euro et ponctuation typographique courante (ISO 32000-2 Annex D.2). Symbol et ZapfDingbats ne disposent d’aucun substitut permissif à métriques compatibles et ne sont délibérément pas substituées ; un document qui en a besoin doit enregistrer une police intégrable. Le résolveur est sans effet de bord : il indique le fichier correspondant à une clé, et rien d’autre. L’enregistrement auprès du registre reste à la charge de l’appelant, ce qui préserve la sémantique de verrouillage et le pipeline de préchauffage.
Surface d’API
Section intitulée « Surface d’API »| Type | Nature | Membres clés | Stabilité | Depuis |
|---|---|---|---|---|
FontInfo | classe final readonly | $family, $style, $type, $unitsPerEm, $widths, $unicodeMap, $cmapForward, $fileData, $variationAxes, $kernPairs, getKey(), encodeText() | stable | 1.0.0 |
FontType | enum (string) | TrueType, TrueTypeUnicode, OpenType, Type1, CidFont0 | stable | 1.0.0 |
Base14SubstituteFonts | classe final (interne) | correspondance entre clé Base 14 normalisée et chemin du fichier Liberation fourni | stable | 2.7.0 |
ShaperFactory | classe final | default(), create(), wouldUseRealShaper() | stable | 3.2.0 |
ShapingResult | classe final readonly | $glyphRuns, $originalText, $script, $direction, $shaperImpl | stable | 3.2.0 |
Base14SubstituteFonts est @internal — réservée au framework, sans garantie de rétrocompatibilité sur sa surface.
Exemple de code — Démarrage rapide
Section intitulée « Exemple de code — Démarrage rapide »<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Typography\FontRegistry;use NextPDF\Typography\FontType;
$registry = new FontRegistry();$font = $registry->register('/path/to/NotoSansTC-Regular.ttf', alias: 'NotoSansTC');
// FontInfo is the immutable parsed fact about the face.echo $font->family, ' / ', $font->type->value, "\n"; // e.g. "Noto Sans TC / TrueTypeUnicode"assert($font->type === FontType::TrueTypeUnicode);L’analyseur remplit FontInfo et attribue le FontType. Une police TrueType à cmap Unicode devient TrueTypeUnicode ; l’enregistreur l’émet alors comme une police composite Type 0.
Exemple de code — Production
Section intitulée « Exemple de code — Production »<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Typography\Base14SubstituteFonts;use NextPDF\Typography\FontRegistry;
final readonly class Base14EmbeddingResolver{ public function __construct(private FontRegistry $registry) {}
/** * Register an embeddable substitute for a legacy Base 14 key so the * output document embeds every font (PDF/A-4 and PDF/UA-2 require it). */ public function ensureEmbeddable(string $base14Key): void { $path = Base14SubstituteFonts::resolve($base14Key);
if ($path === null) { // Symbol / ZapfDingbats have no permissive substitute — the // caller must supply its own embeddable font. throw new \RuntimeException("No bundled substitute for {$base14Key}"); }
if (!$this->registry->has($base14Key)) { $this->registry->register($path, alias: $base14Key); } }}Le résolveur est sans effet de bord. L’enregistrement reste explicite afin que le verrou et les contrats de préchauffage du registre restent valides. Symbol et ZapfDingbats ne renvoient aucun chemin, par conception.
Cas limites et pièges
Section intitulée « Cas limites et pièges »SymboletZapfDingbatsne sont intentionnellement pas substituées. Un résultat null pour ces clés est le comportement documenté, et non un bug de police manquante.FontInfoestfinal readonly. Traite une police analysée comme une valeur : ne t’attends jamais à muter les largeurs ou les métriques sur place ; réenregistre-la si la source change.- Une police Type 1 nécessite à la fois le contour PFB et les métriques AFM.
FontRegistry::registerType1()prend la paire ; la découverte automatique dérive le chemin AFM du chemin PFB à partir de l’extension. - La différence entre
FontType::TrueTypeetFontType::TrueTypeUnicodecorrespond à la distinction entre un encodage sur un seul octet et un encodage multi-octets. Le résolveur d’encodage s’appuie sur la cmap directe renseignée, et non sur le nom de famille ; une police TrueType Unicode est donc automatiquement orientée vers le chemin Identity-H. - Les axes des polices variables et les instances nommées sont analysés dans
FontInfolorsqu’ils sont présents, mais l’exemple CJK détaillé utilise délibérément la police statique afin que leFontInfoanalysé reste déterministe.
Performance
Section intitulée « Performance »Le registre alloue FontInfo une seule fois par police et par processus, puis le partage par référence. Il conserve les octets bruts de la police, ce qui constitue le coût mémoire dominant. Un worker ne devrait préchauffer que les polices dont il a besoin et surveiller memoryUsage(). Le résolveur de substituts Base 14 effectue une recherche dans une table en temps constant, sans aucune E/S tant que l’appelant n’enregistre pas le fichier résolu. Le performance_budget de 1500 ms en temps réel et de 64 Mo en pic couvre le préchauffage classique d’un jeu de polices, ainsi que le rendu. L’empreinte mémoire par police évolue avec la taille du fichier de police, et non avec le nombre de glyphes, jusqu’à l’exécution du sous-ensembleur.
Notes de sécurité
Section intitulée « Notes de sécurité »FontInfo est lui-même inerte : ce sont des données analysées, sans aucun comportement au-delà de la transformation pure encodeText(). La surface d’attaque se situe en amont, au moment de l’analyse : des octets de police arbitraires atteignent alors l’analyseur TrueType ou Type 1. Les analyseurs vérifient les bornes de chaque décalage binaire et rejettent les wrappers de flux ainsi que les octets nuls dans les chemins. Une entrée de police non fiable doit passer par une politique de ressources externes qui borne la taille et le nombre de glyphes avant l’enregistrement. Les substituts Liberation fournis sont des actifs de confiance livrés avec le paquet ; le chemin de repli n’introduit donc aucune nouvelle entrée non fiable.
Conformité
Section intitulée « Conformité »| Affirmation | Norme | Article | Preuve |
|---|---|---|---|
| Chaque police utilisée par le document est intégrée pour que le document s’affiche sans dépendre des polices système. | ISO 32000-2 | §9 | |
Un programme TrueType est intégré via FontFile2 avec les tables glyf, head, hhea, hmtx, loca, maxp. | ISO 32000-2 | §9.6.5 | Digest RAG tronqué par le plafond de licence ; préfixe 7b26f37996239b2a, voir _downgraded-claims-o3.md |
Un programme OpenType (CFF) est intégré via FontFile3. | ISO 32000-2 | §9.6.5 | Digest RAG tronqué par le plafond de licence ; préfixe 801549ee00623baf, voir _downgraded-claims-o3.md |
La première affirmation est épinglée par digest et corroborée par B1. Les affirmations FontFile2 et FontFile3 sont paraphrasées. Leurs digests RAG complets n’ont pas été renvoyés (troncature par le plafond de licence) et sont corroborés par FontSubsetter (qui reconstruit exactement l’ensemble glyf/head/hhea/hmtx/loca/maxp) et l’enum FontType. NextPDF ne reproduit pas le texte normatif. Base14SubstituteFonts cite ISO 32000-2 §9.6.2.2 (gestion des polices Type 1 standard), ISO 14289-2:2024 §8.4.5.5.1 (intégration des polices PDF/UA-2) et ISO 19005-4:2020 §6.3.5 (intégration des polices PDF/A-4) dans le code source. Les pages accessibilité et conformité couvrent la conformité complète des profils.
Contexte commercial
Section intitulée « Contexte commercial »Un pack commercial de licences de polices et un service de sous-ensemblage dynamique s’appuient sur le FontInfo et le registre du Core. Le module de police du Core assure l’intégration, le sous-ensemblage et le repli sans licence. L’absence de lien de conversion est intentionnelle.
Voir aussi
Section intitulée « Voir aussi »- Typographie : registre, sous-ensemblage, CMap, encodage, BiDi — le registre et le sous-ensemblage qui produisent et consomment
FontInfo. - Texte : shaping, césure, BiDi — le point d’intégration du shaping qui consomme le run encodé.
- Contrats / Typographie — le contrat
FontRegistryInterface.