Czcionka: typy wartości, osadzanie i mechanizm zastępczy
W skrócie
Dział zatytułowany „W skrócie”W systemie NextPDF czcionka jest reprezentowana przez niezmienny obiekt wartości FontInfo oraz typ technologii, który wskazuje silnikowi sposób jej osadzenia. Silnik osadza każdą używaną czcionkę. Odwołanie do starszej czcionki Base 14 jest zastępowane dołączonym zamiennikiem zgodnym metrycznie.
Instalacja
Dział zatytułowany „Instalacja”composer require nextpdf/core:^3Przegląd koncepcyjny
Dział zatytułowany „Przegląd koncepcyjny”FontInfo to niezmienny obiekt wartości, który przekazuje silnikowi wszystko, czego potrzeba do osadzenia czcionki: rodzinę i styl, nazwę PostScript, flagi deskryptora, metryki przeskalowane do jednostki em o wartości 1000, szerokości znaków, mapę glif-Unicode, mapę znaków w przód (cmap, z Unicode na identyfikator glifu), surowe bajty czcionki oraz, jeśli są obecne, osie wariacji, nazwane instancje, selektory wariacji, pary kerningu i metryki pionowe. Jest oznaczony jako final readonly. Sygnatura jego konstruktora i publiczne właściwości są zamrożone, więc sparsowana czcionka stanowi stabilny fakt nadający się do współdzielenia. FontInfo::encodeText() to jedyna metoda definiująca zachowanie. Korzysta z resolvera kodowania i zwraca obiekt EncodedGlyphRun.
FontType wylicza technologie osadzane przez silnik: TrueType (kodowanie jednobajtowe), TrueTypeUnicode (wielobajtowe kodowanie z identyfikatorem znaku (CID) dla pism bogatych w Unicode), OpenType (kontury w formacie Compact Font Format), Type1 (PostScript Type 1, rejestrowany z pary Printer Font Binary (PFB) i Adobe Font Metrics (AFM)) oraz CidFont0 (czcionka CID oparta na PostScript). Typ przypisany przez parser określa kształt słownika czcionki emitowanego przez komponent zapisujący.
Aby renderowanie nie zależało od zainstalowanych czcionek systemowych, silnik osadza program czcionki — ISO 32000-2 §9. Program TrueType jest osadzany przez wpis deskryptora czcionki FontFile2 i musi zawierać tabele glyf, head, hhea, hmtx, loca oraz maxp — ISO 32000-2 §9.6.5 (skrót RAG obcięty przez limit licencyjny; odnotowano w _downgraded-claims-o3.md). Program OpenType z tabelą konturów w formacie Compact Font Format jest osadzany przez FontFile3 — ISO 32000-2 §9.6.5 (skrót RAG obcięty; zob. ten sam dziennik). Mechanizm tworzenia podzbioru odtwarza dokładnie ten wymagany zestaw tabel, więc osadzony podzbiór pozostaje zgodnym programem.
Mechanizm zastępczy obsługuje przypadek starszych czcionek Base 14. Base14SubstituteFonts mapuje znormalizowany klucz Base 14 — helvetica, helveticab, times, courier i pozostałe — na dołączony plik Liberation Fonts. Liberation Sans, Serif i Mono są zgodne metrycznie z Helvetica lub Arial, Times Roman oraz Courier. Każdy z nich jest osadzonym krojem TrueType, więc renderuje pełny łaciński repertuar WinAnsiEncoding (Windows-1252), którego wymaga punkt odniesienia standardowych 14 czcionek — łacinę z diakrytykami, znak euro oraz typowe znaki interpunkcyjne typograficzne (ISO 32000-2 Annex D.2). Symbol i ZapfDingbats nie mają zamiennika zgodnego metrycznie na liberalnej licencji, więc NextPDF celowo ich nie zastępuje; dokument, który potrzebuje którejś z tych czcionek, musi zarejestrować czcionkę nadającą się do osadzenia. Resolver nie ma żadnych efektów ubocznych: odpowiada wyłącznie na pytanie, na który plik mapuje się dany klucz, i nic więcej. Za rejestrację w rejestrze nadal odpowiada kod wywołujący, co zachowuje semantykę blokady oraz potok rozgrzewania.
Powierzchnia API
Dział zatytułowany „Powierzchnia API”| Typ | Rodzaj | Kluczowe składowe | Stabilność | Od wersji |
|---|---|---|---|---|
FontInfo | klasa final readonly | $family, $style, $type, $unitsPerEm, $widths, $unicodeMap, $cmapForward, $fileData, $variationAxes, $kernPairs, getKey(), encodeText() | stabilny | 1.0.0 |
FontType | typ wyliczeniowy (string) | TrueType, TrueTypeUnicode, OpenType, Type1, CidFont0 | stabilny | 1.0.0 |
Base14SubstituteFonts | klasa final (wewnętrzna) | mapowanie znormalizowanego klucza Base 14 na ścieżkę dołączonego pliku Liberation | stabilny | 2.7.0 |
ShaperFactory | klasa final | default(), create(), wouldUseRealShaper() | stabilny | 3.2.0 |
ShapingResult | klasa final readonly | $glyphRuns, $originalText, $script, $direction, $shaperImpl | stabilny | 3.2.0 |
Base14SubstituteFonts ma adnotację @internal: wyłącznie do użytku wewnętrznego frameworka, bez gwarancji zgodności wstecznej tej powierzchni.
Przykład kodu — szybki start
Dział zatytułowany „Przykład kodu — szybki start”<?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);Parser uzupełnia FontInfo i przypisuje FontType. Krój TrueType z mapą znaków Unicode staje się TrueTypeUnicode, który komponent zapisujący emituje jako czcionkę złożoną Type 0.
Przykład kodu — produkcja
Dział zatytułowany „Przykład kodu — produkcja”<?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); } }}Resolver nie ma żadnych efektów ubocznych. Rejestracja pozostaje jawna, więc kontrakty blokady i rozgrzewania rejestru są zachowane. Symbol i ZapfDingbats z założenia nie zwracają żadnej ścieżki.
Przypadki brzegowe i pułapki
Dział zatytułowany „Przypadki brzegowe i pułapki”SymboliZapfDingbatscelowo nie są zastępowane. Wynik null dla tych kluczy to udokumentowane zachowanie, a nie błąd polegający na braku czcionki.FontInfojest oznaczony jakofinal readonly. Traktuj sparsowaną czcionkę jak wartość: nie zakładaj, że można zmodyfikować szerokości lub metryki w miejscu; zarejestruj ją ponownie, jeśli źródło ulegnie zmianie.- Czcionka Type 1 wymaga zarówno konturów PFB, jak i metryk AFM.
FontRegistry::registerType1()przyjmuje tę parę; automatyczne wykrywanie wyprowadza ścieżkę AFM ze ścieżki PFB na podstawie rozszerzenia. FontType::TrueTypeiFontType::TrueTypeUnicodeoznaczają rozróżnienie między wersją jednobajtową a wielobajtową. Resolver kodowania korzysta z wypełnionej mapy znaków w przód, a nie z nazwy rodziny, więc krój TrueType z Unicode jest automatycznie kierowany na ścieżkę Identity-H.- Osie czcionek wariacyjnych i nazwane instancje są wczytywane do
FontInfo, gdy są obecne, ale przykład dla języków chińskiego, japońskiego i koreańskiego (CJK) celowo używa kroju statycznego, aby zachować deterministyczny sparsowany obiektFontInfo.
Wydajność
Dział zatytułowany „Wydajność”Rejestr alokuje FontInfo raz na czcionkę w ramach procesu, a następnie współdzieli go przez referencję. Surowe bajty czcionki dominują w koszcie pamięci. Rozgrzewaj tylko te czcionki, których potrzebuje proces roboczy, i śledź memoryUsage(). Resolver zamienników Base 14 wykonuje wyszukiwanie w mapie o stałym czasie bez operacji wejścia/wyjścia (I/O), dopóki kod wywołujący nie zarejestruje rozwiązanego pliku. Wartość performance_budget wynosząca 1500 ms czasu zegarowego i 64 MB szczytowego zużycia obejmuje rozgrzanie typowego zestawu czcionek oraz renderowanie. Do czasu uruchomienia mechanizmu tworzenia podzbioru zużycie pamięci przez każdą czcionkę rośnie wraz z rozmiarem pliku czcionki, a nie z liczbą glifów.
Uwagi dotyczące bezpieczeństwa
Dział zatytułowany „Uwagi dotyczące bezpieczeństwa”Sam obiekt FontInfo jest bierny: to sparsowane dane bez żadnego zachowania poza czystą transformacją encodeText(). Powierzchnia ataku pojawia się wcześniej, w fazie parsowania, gdy dowolne bajty czcionki trafiają do parsera TrueType lub Type 1. Parsery sprawdzają zakres każdego binarnego przesunięcia oraz odrzucają opakowania strumieni i bajty null w ścieżkach. Przed rejestracją niezaufane dane czcionki muszą przejść zasady dotyczące zasobów zewnętrznych, które ograniczają rozmiar i liczbę glifów. Dołączone zamienniki Liberation to zaufane zasoby dostarczane wraz z pakietem, więc ścieżka zastępcza nie wprowadza żadnych nowych niezaufanych danych.
Zgodność
Dział zatytułowany „Zgodność”| Twierdzenie | Norma | Punkt | Dowód |
|---|---|---|---|
| Każda czcionka używana przez dokument jest osadzana, więc dokument renderuje się bez polegania na czcionkach systemowych. | ISO 32000-2 | §9 | |
Program TrueType jest osadzany przez FontFile2 z tabelami glyf, head, hhea, hmtx, loca, maxp. | ISO 32000-2 | §9.6.5 | Skrót RAG obcięty przez limit licencyjny; prefiks 7b26f37996239b2a, zob. _downgraded-claims-o3.md |
Program OpenType (CFF) jest osadzany przez FontFile3. | ISO 32000-2 | §9.6.5 | Skrót RAG obcięty przez limit licencyjny; prefiks 801549ee00623baf, zob. _downgraded-claims-o3.md |
Pierwszy punkt jest oparty na skrócie i potwierdzony przez B1. Punkty dotyczące FontFile2 i FontFile3 to parafrazy. Pełne skróty RAG dla tych punktów nie zostały zwrócone (obcięcie z powodu limitu licencyjnego), więc dowód jest również potwierdzony przez FontSubsetter (który odtwarza dokładnie zestaw glyf/head/hhea/hmtx/loca/maxp) oraz przez typ wyliczeniowy FontType. NextPDF nie odtwarza tekstu normatywnego. W kodzie źródłowym Base14SubstituteFonts przywołuje ISO 32000-2 §9.6.2.2 (standardowa obsługa czcionek Type 1), ISO 14289-2:2024 §8.4.5.5.1 (osadzanie czcionek PDF/UA-2) oraz ISO 19005-4:2020 §6.3.5 (osadzanie czcionek PDF/A-4). Strony dotyczące dostępności i zgodności zawierają pełne omówienie zgodności z profilem.
Kontekst komercyjny
Dział zatytułowany „Kontekst komercyjny”Komercyjny pakiet licencjonowania czcionek oraz usługa dynamicznego tworzenia podzbiorów opierają się na FontInfo z modułu Core oraz na rejestrze. Moduł czcionek Core obsługuje osadzanie, tworzenie podzbiorów i mechanizm zastępczy bez dodatkowej licencji. Pominięcie odnośnika konwersji jest zamierzone.
Zobacz też
Dział zatytułowany „Zobacz też”- Typografia: rejestr, tworzenie podzbiorów, CMap, kodowanie, BiDi — przepływ pracy rejestru i tworzenia podzbiorów, który tworzy i wykorzystuje
FontInfo. - Tekst: kształtowanie, łamanie, BiDi — warstwa kształtowania, która wykorzystuje zakodowany ciąg znaków.
- Kontrakty / Typografia — kontrakt
FontRegistryInterface.