stabilność: Eksperymentalna
Obsługa kształtowania pism złożonych
W skrócie
Dział zatytułowany „W skrócie”Opcjonalny podgląd. Kształtowanie pism złożonych jest domyślnie wyłączone. Gdy jest wyłączone, silnik renderuje istniejącą ścieżką codepoint-to-cmap — bajtowo identycznie z kompilacją bez tej funkcji. Włączaj je tylko wtedy, gdy masz libharfbuzz i czcionkę zdolną do kształtowania, i waliduj wynik.
Renderer HTML dodaje opcjonalny shaper pism złożonych dla tybetańskiego i mongolskiego. Gdy shaper jest włączony, wykryty ciąg tybetański lub mongolski w zakresie jest kształtowany przez libharfbuzz i emitowany jako kody glifów Identity-H. Shaper obejmuje poziomy tybetański w krojach TrueType i CFF/OTTO, łącznie z zawijaniem, oraz pionowy mongolski składany z góry na dół (TTB).
Instalacja
Dział zatytułowany „Instalacja”composer require nextpdf/core:^3Shaper jest dostarczany w pakiecie core. Opcja
CssFeatureFlags::$complexTextShaping to @since 6.1.0. libharfbuzz jest
wymaganiem czasu wykonania, gdy flaga jest włączona — shaper wywołuje
libharfbuzz przez rozszerzenie FFI PHP. Gdy flaga jest wyłączona, biblioteka nie
ma zależności od libharfbuzz.
Przegląd koncepcyjny
Dział zatytułowany „Przegląd koncepcyjny”Pisma złożone zmieniają kolejność glifów, podstawiają je i zmieniają ich położenie zależnie od kontekstu. Naiwne mapowanie codepoint-na-glif renderuje je w widoczny sposób błędnie. Shaper przekazuje ciąg w zakresie do libharfbuzz, która stosuje tablice kształtowania OpenType czcionki, a silnik emituje wynikową sekwencję glifów jako złożoną czcionkę Type 0 z kodowaniem Identity-H (ISO 32000-2 §9.7.4 — pokazany łańcuch to dwubajtowe CID-y).
Zakres jest celowy. Shaper rozpoznaje ciągi tybetańskie i mongolskie oraz je kształtuje; nie twierdzi, że obejmuje pisma złożone ogólnie. Poziomy tybetański jest kształtowany w krojach TrueType i CFF/OTTO, z zawijaniem wierszy. Mongolski jest kształtowany pionowo, z góry na dół.
Granica fail-closed — twarda i typowana
Dział zatytułowany „Granica fail-closed — twarda i typowana”Shaper nigdy nie emituje niekształtowanych, wizualnie zepsutych glifów jako wycofania. Ciąg, którego nie da się skształtować wiernie, zgłasza zamiast tego typowany wyjątek:
ComplexScriptShapingException— ciągu nie da się skształtować wiernie: czcionce brakuje potrzebnych glifów (powstałby.notdef), krój CFF jest proszony o kształtowanie ścieżką pionową, ciąg zawiera łącze lub kolumna mongolska wymaga zawijania (przypadek poza zakresem).HarfBuzzUnavailableException— flaga jest włączona, ale libharfbuzz nie jest osiągalny przez FFI w czasie wykonania.
Przy wyłączonej fladze ciąg w zakresie renderuje się istniejącą ścieżką codepoint-to-cmap. To udokumentowane ograniczenie, a nie twierdzenie o kształtowaniu: ścieżka wyłączona nie stosuje kształtowania OpenType, więc formy kontekstowe nie są gwarantowane. Nie opisuj wyniku ścieżki wyłączonej jako „kształtowanego”.
Granica uczciwości — obiektywna równoważność, a nie estetyczna akceptacja
Dział zatytułowany „Granica uczciwości — obiektywna równoważność, a nie estetyczna akceptacja”Wierność kształtowania jest walidowana obiektywnie względem HarfBuzz: emitowane identyfikatory glifów, mapowanie klastrów i pozycje glifów odpowiadają referencyjnemu wynikowi HarfBuzz (równoważność glifu, klastra i pozycji). Przegląd estetyczny przez rodzimego użytkownika języka — ocena, czy wynik czyta się naturalnie dla biegłego czytelnika — jest śledzonym działaniem następczym po wydaniu. NextPDF nie wysuwa żadnego twierdzenia o jakości językowej w tym API ani w tej dokumentacji. Obiektywna równoważność jest deklarowana; jakość estetyczna nie.
Powierzchnia API
Dział zatytułowany „Powierzchnia API”| Symbol | Lokalizacja | Rola |
|---|---|---|
CssFeatureFlags::$complexTextShaping | src/Html/CssFeatureFlags.php | Opcjonalna flaga shapera tybetańsko-mongolskiego (domyślnie false). |
Config::withCssFeatureFlags(CssFeatureFlags $flags): self | src/Core/Config.php | Dołącza zestaw flag do konfiguracji dokumentu. |
ComplexScriptShapingException | src/Font/Shaper/ComplexScriptShapingException.php | Zgłaszany, gdy ciągu w zakresie nie da się skształtować wiernie. |
HarfBuzzUnavailableException | src/Font/Shaper/HarfBuzzUnavailableException.php | Zgłaszany, gdy flaga jest włączona, ale libharfbuzz jest niedostępny. |
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\Core\Config;use NextPDF\Core\Document;use NextPDF\Html\Css\CssFeatureFlags;
$config = (new Config())->withCssFeatureFlags( new CssFeatureFlags(complexTextShaping: true),);
$doc = Document::createStandalone($config);$doc->addPage();$doc->writeHtml( '<div style="font-family: NotoSerifTibetan;">བོད་སྐད་</div>',);$doc->save(__DIR__ . '/tibetan.pdf');Przykład kodu — produkcja
Dział zatytułowany „Przykład kodu — produkcja”Zarejestruj czcionkę zdolną do kształtowania, włącz shaper i obsłuż dwa typowane tryby awarii jawnie. Wierny render albo jasny wyjątek — nigdy po cichu zepsuty ciąg glifów.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Config;use NextPDF\Core\DocumentFactory;use NextPDF\Exception\ComplexScriptShapingException;use NextPDF\Exception\HarfBuzzUnavailableException;use NextPDF\Graphics\ImageRegistry;use NextPDF\Html\Css\CssFeatureFlags;use NextPDF\Typography\FontRegistry;
$fontRegistry = new FontRegistry();$fontRegistry->register('/path/to/NotoSerifTibetan-Regular.ttf', alias: 'NotoSerifTibetan');
$config = (new Config())->withCssFeatureFlags( new CssFeatureFlags(complexTextShaping: true),);
$factory = new DocumentFactory($fontRegistry, new ImageRegistry(maxCacheBytes: 0));$doc = $factory->create($config);$doc->setLanguage('bo');$doc->addPage();
try { $doc->writeHtml('<div style="font-family: NotoSerifTibetan;">བོད་སྐད་</div>');} catch (HarfBuzzUnavailableException $e) { // The flag is on but libharfbuzz is not reachable. Install it, or turn the // flag off to fall back to the unshaped cmap path. throw $e;} catch (ComplexScriptShapingException $e) { // The run cannot be shaped faithfully (missing glyphs, link in run, // out-of-scope case). Fix the font or the content; do not ship broken glyphs. throw $e;}
$doc->save($out);Przypadki brzegowe i pułapki
Dział zatytułowany „Przypadki brzegowe i pułapki”- libharfbuzz jest wymagany, gdy włączony. Przy włączonej fladze i braku
libharfbuzz silnik zgłasza
HarfBuzzUnavailableException. Nie degraduje się po cichu. - Wyłączony to nie „kształtowany”. Przy wyłączonej fladze ciąg w zakresie renderuje się ścieżką cmap bez kształtowania OpenType. To udokumentowane ograniczenie; nie nazywaj go wynikiem kształtowanym.
- Zakres to tybetański i mongolski. Inne pisma złożone są poza zakresem tej warstwy.
- Łącze w ciągu kończy się niepowodzeniem fail-closed. Ciąg zawierający
adnotację łącza zgłasza
ComplexScriptShapingException, ponieważ prostokąt łącza nie może podążać za zmianą kolejności wynikającą z kształtowania. - Brak twierdzenia o jakości językowej. Równoważność z HarfBuzz jest deklarowana; estetyczna jakość w ocenie rodzimego użytkownika to śledzone działanie następcze i nie jest deklarowana.
Wydajność
Dział zatytułowany „Wydajność”Kształtowanie dodaje jedno wywołanie libharfbuzz na ciąg w zakresie, plus
przebieg emisji glifów, liniowo względem liczby glifów. Budżet (wall_ms: 2000,
peak_mb: 128) podąża za profilem CJK/pism złożonych, ponieważ czcionki do
kształtowania są duże, a obsługa czcionek dominuje w koszcie.
Uwagi dotyczące bezpieczeństwa
Dział zatytułowany „Uwagi dotyczące bezpieczeństwa”Włączenie shapera wprowadza wywołanie FFI do libharfbuzz, biblioteki natywnej. Pliki czcionek pozostają niezaufanym wejściem binarnym obsługiwanym przez istniejącą walidację warstwy typografii, zanim dotrą do shapera. Shaper konsumuje już zarejestrowane, już zweryfikowane kroje. Traktuj pochodzenie czcionek dostarczonych przez użytkownika końcowego jako niezaufane i dostarczaj libharfbuzz z zaufanego źródła.
Zgodność
Dział zatytułowany „Zgodność”| Twierdzenie | Norma | Klauzula |
|---|---|---|
| Kształtowane ciągi są emitowane jako dwubajtowe CID-y Identity-H w złożonej czcionce Type 0. | ISO 32000-2 | §9.7.4 |
| Shaper stosuje czcionkowe podstawianie i pozycjonowanie glifów OpenType. | OpenType Specification | GSUB / GPOS |
| Formowanie klastrów podąża za właściwościami pism dla tybetańskiego i mongolskiego. | Unicode Standard Annex | Tibetan and Mongolian |
To podglądowa implementacja zawężona do tybetańskiego i mongolskiego, walidowana pod kątem obiektywnej równoważności z HarfBuzz. Nie wysuwa żadnego twierdzenia o jakości językowej i nie deklaruje zgodności end-to-end z PDF dla wytworzonego pliku. Nie odtwarza się żadnego tekstu normatywnego.