Stabilität: Experimentell
Unterstützung für Komplexschrift-Shaping
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“Per Opt-in aktivierbare Vorschau. Das Komplexschrift-Shaping ist standardmäßig aus. Ist es aus, rendert die Engine über den bestehenden Codepoint-zu-cmap-Pfad — byte-identisch zu einem Build ohne die Funktion. Schalten Sie es nur ein, wenn Sie libharfbuzz und eine shaping-fähige Schrift haben, und validieren Sie das Ergebnis.
Der HTML-Renderer ergänzt einen per Opt-in aktivierbaren Komplexschrift-Shaper für Tibetisch und Mongolisch. Ist der Shaper aktiv, wird ein erkannter, im Umfang liegender tibetischer oder mongolischer Run über libharfbuzz geshaped und als Identity-H-Glyphencodes ausgegeben. Der Shaper deckt horizontales Tibetisch in TrueType- und CFF/OTTO-Schriften einschließlich Umbruch sowie vertikales Mongolisch, von oben nach unten gesetzt (TTB), ab.
Installation
Abschnitt betitelt „Installation“composer require nextpdf/core:^3Der Shaper wird im Core-Paket ausgeliefert. Das Opt-in
CssFeatureFlags::$complexTextShaping ist @since 6.1.0. libharfbuzz ist eine
Laufzeitvoraussetzung, wenn das Flag aktiv ist — der Shaper ruft über die
FFI-Erweiterung von PHP in libharfbuzz hinein. Ist das Flag aus, hat die Bibliothek
keine libharfbuzz-Abhängigkeit.
Konzeptioneller Überblick
Abschnitt betitelt „Konzeptioneller Überblick“Komplexe Schriften ordnen Glyphen kontextabhängig um, ersetzen und positionieren sie neu. Ein naives Codepoint-zu-Glyphe-Mapping rendert sie sichtbar falsch. Der Shaper übergibt einen im Umfang liegenden Run an libharfbuzz, das die OpenType-Shaping-Tabellen der Schrift anwendet, und die Engine gibt die resultierende Glyphensequenz als Composite-Type-0-Schrift mit Identity-H-Encoding aus (ISO 32000-2 §9.7.4 — die gezeigte Zeichenkette besteht aus Zwei-Byte-CIDs).
Der Umfang ist bewusst gewählt. Der Shaper erkennt tibetische und mongolische Runs und shaped sie; er beansprucht keine allgemeine Komplexschrift-Abdeckung. Horizontales Tibetisch wird in TrueType- und CFF/OTTO-Schriften mit Zeilenumbruch geshaped. Mongolisch wird vertikal von oben nach unten geshaped.
Fail-closed-Grenze — hart und typisiert
Abschnitt betitelt „Fail-closed-Grenze — hart und typisiert“Der Shaper gibt nie ungeshapte, visuell defekte Glyphen als Fallback aus. Ein Run, der nicht originalgetreu geshaped werden kann, löst stattdessen eine typisierte Ausnahme aus:
ComplexScriptShapingException— der Run kann nicht originalgetreu geshaped werden: der Schrift fehlen die benötigten Glyphen (es würde ein.notdefresultieren), eine CFF-Schrift soll im vertikalen Pfad shaped werden, der Run enthält einen Link oder eine mongolische Spalte benötigt Umbruch (ein außerhalb des Umfangs liegender Fall).HarfBuzzUnavailableException— das Flag ist aktiv, aber libharfbuzz ist zur Laufzeit nicht über FFI erreichbar.
Ist das Flag aus, rendert ein im Umfang liegender Run über den bestehenden Codepoint-zu-cmap-Pfad. Das ist eine dokumentierte Einschränkung, keine Shaping-Aussage: Der Aus-Pfad wendet kein OpenType-Shaping an, sodass kontextuelle Formen nicht garantiert sind. Beschreiben Sie die Ausgabe des Aus-Pfads nicht als „geshaped”.
Ehrlichkeitsgrenze — objektive Parität, kein ästhetisches Plazet
Abschnitt betitelt „Ehrlichkeitsgrenze — objektive Parität, kein ästhetisches Plazet“Die Shaping-Treue wird objektiv gegen HarfBuzz validiert: Die ausgegebenen Glyphenbezeichner, das Cluster-Mapping und die Glyphenpositionen stimmen mit der HarfBuzz-Referenzausgabe überein (Glyphen-, Cluster- und Positions-Parität). Eine ästhetische Prüfung durch Muttersprachler — die beurteilt, ob das Ergebnis sich für einen fließend lesenden Leser natürlich liest — ist ein nachgehaltenes Post-Ship-Follow-up. NextPDF macht in dieser API oder in dieser Dokumentation keine Aussage zur sprachlichen Qualität. Objektive Parität wird zugesichert; ästhetische Qualität nicht.
API-Oberfläche
Abschnitt betitelt „API-Oberfläche“| Symbol | Ort | Rolle |
|---|---|---|
CssFeatureFlags::$complexTextShaping | src/Html/CssFeatureFlags.php | Opt-in-Flag für den Tibetisch/Mongolisch-Shaper (Standard false). |
Config::withCssFeatureFlags(CssFeatureFlags $flags): self | src/Core/Config.php | Hängt das Flag-Set an eine Dokumentkonfiguration an. |
ComplexScriptShapingException | src/Font/Shaper/ComplexScriptShapingException.php | Wird geworfen, wenn ein im Umfang liegender Run nicht originalgetreu geshaped werden kann. |
HarfBuzzUnavailableException | src/Font/Shaper/HarfBuzzUnavailableException.php | Wird geworfen, wenn das Flag aktiv ist, aber libharfbuzz nicht verfügbar ist. |
Codebeispiel — Schnellstart
Abschnitt betitelt „Codebeispiel — Schnellstart“<?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');Codebeispiel — Produktion
Abschnitt betitelt „Codebeispiel — Produktion“Registrieren Sie eine shaping-fähige Schrift, aktivieren Sie den Shaper und behandeln Sie die zwei typisierten Fehlermodi explizit. Ein originalgetreues Rendering oder eine klare Ausnahme — niemals ein stillschweigend defekter Glyphen-Run.
<?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);Randfälle & Fallstricke
Abschnitt betitelt „Randfälle & Fallstricke“- libharfbuzz ist erforderlich, wenn aktiv. Bei aktivem Flag und fehlendem
libharfbuzz wirft die Engine
HarfBuzzUnavailableException. Sie degradiert nicht stillschweigend. - Aus ist nicht „geshaped”. Ist das Flag aus, rendert ein im Umfang liegender Run über den cmap-Pfad ohne OpenType-Shaping. Das ist eine dokumentierte Einschränkung; nennen Sie es nicht geshapte Ausgabe.
- Der Umfang ist Tibetisch und Mongolisch. Andere komplexe Schriften liegen außerhalb des Umfangs dieser Teilmenge.
- Ein Link im Run schlägt fail-closed fehl. Ein Run, der eine Link-Annotation
enthält, löst
ComplexScriptShapingExceptionaus, weil das Link-Rechteck der geshapten Umordnung nicht folgen kann. - Keine Aussage zur sprachlichen Qualität. Parität mit HarfBuzz wird zugesichert; die ästhetische Qualität nach Muttersprachler-Urteil ist ein nachgehaltenes Follow-up und wird nicht beansprucht.
Performance
Abschnitt betitelt „Performance“Das Shaping fügt einen libharfbuzz-Aufruf pro im Umfang liegendem Run plus den
Glyphen-Ausgabe-Durchlauf hinzu, linear in der Glyphenzahl. Das Budget
(wall_ms: 2000, peak_mb: 128) folgt dem CJK-/Komplexschrift-Profil, da
Shaping-Schriften groß sind und die Schriftverarbeitung die Kosten dominiert.
Sicherheitshinweise
Abschnitt betitelt „Sicherheitshinweise“Die Aktivierung des Shapers führt einen FFI-Aufruf in libharfbuzz ein, eine native Bibliothek. Schriftdateien bleiben nicht vertrauenswürdige Binäreingabe, die von der bestehenden Validierung der Typografieschicht verarbeitet wird, bevor sie den Shaper erreichen. Der Shaper verarbeitet bereits registrierte, bereits validierte Schriften. Behandeln Sie die Herkunft von Endbenutzer-bereitgestellten Schriften als nicht vertrauenswürdig und beziehen Sie libharfbuzz aus einer vertrauenswürdigen Quelle.
Konformität
Abschnitt betitelt „Konformität“| Aussage | Standard | Klausel |
|---|---|---|
| Geshapte Runs werden als Identity-H-Zwei-Byte-CIDs in einer Composite-Type-0-Schrift ausgegeben. | ISO 32000-2 | §9.7.4 |
| Der Shaper wendet die OpenType-Glyphensubstitution und -positionierung der Schrift an. | OpenType Specification | GSUB / GPOS |
| Die Cluster-Bildung folgt den Schrifteigenschaften für Tibetisch und Mongolisch. | Unicode Standard Annex | Tibetan and Mongolian |
Dies ist eine Vorschau-Implementierung, beschränkt auf Tibetisch und Mongolisch, validiert auf objektive HarfBuzz-Parität. Sie macht keine Aussage zur sprachlichen Qualität und beansprucht keine Ende-zu-Ende-PDF-Konformität für die erzeugte Datei. Es wird kein Standardtext wiedergegeben.