PDFs mit CJK- und arabischem Text korrekt kopierbar machen
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“Erstellen Sie eine Portable-Document-Format-Datei (PDF) mit chinesischem, japanischem, koreanischem (CJK) und arabischem Text, der als ursprüngliche logische Zeichen kopiert und eingefügt wird. Die Engine bildet jede Glyphe über eine /ToUnicode-CMap auf Unicode ab, kanonisiert das Ergebnis mit Normalization Form Compatibility Composition (NFKC) und schließt geformte oder mit Buchstabenabstand versehene Läufe in einen /Span ein, der /ActualText trägt. Registrieren Sie die Schriftarten und schreiben Sie den Inhalt; die Extraktion bleibt korrekt. Verifizieren Sie die Extraktion mit pdftotext/Poppler, nicht mit PyMuPDF; veraPDF validiert PDF/Universal Accessibility 2 (PDF/UA-2), nicht die Extraktion.
Installation
Abschnitt betitelt „Installation“composer require nextpdf/coreRegistrieren Sie eine CJK-Schriftart, etwa Noto Sans CJK, und eine arabischfähige Schriftart, deren Zeichentabelle den Block Arabic Presentation Forms-B abdeckt, zum Beispiel Noto Naskh Arabic. Betten Sie nur Schriftarten ein, die Sie einbetten dürfen.
Konzeptioneller Überblick
Abschnitt betitelt „Konzeptioneller Überblick“Glyphencodes in einem Content-Stream sind kein Unicode. Eine /ToUnicode-CMap bildet jeden Code wieder auf Unicode ab, damit Reader Text extrahieren können (ISO 32000-2 §9.10). Die Engine kanonisiert diese Werte mit Normalization Form Compatibility Composition (NFKC), wie in Unicode UAX #15 definiert. Ein CJK-Kompatibilitätsideograph und eine arabische Präsentationsform werden jeweils auf ihr Basiszeichen abgebildet, sodass Suchen und Kopieren kanonischen Text statt eines Kompatibilitätscodepunkts zurückgeben.
Zwei Fälle benötigen mehr als /ToUnicode: lateinischen Text mit Buchstabenabstand und geformten arabischen Rechts-nach-links-Text. Die Engine zeichnet diese Inhalte als Glyphen mit zusätzlichem Abstand oder in umgeordneter Reihenfolge, sodass die Glyphenreihenfolge allein die logische Zeichenkette nicht wiederherstellen kann. Dazu umschließt sie jeden Lauf mit einer /Span-Marked-Content-Sequenz, die /ActualText trägt; dieser Wert ist ein exakter Ersatz für den eingeschlossenen Inhalt (ISO 32000-2 §14.9). Extraktoren, die /ActualText beachten, geben die logische Zeichenkette zurück.
API-Oberfläche
Abschnitt betitelt „API-Oberfläche“| Symbol | Speicherort | Rolle |
|---|---|---|
FontRegistry::register(string $fontFile, string $alias = ''): FontInfo | NextPDF\Typography\FontRegistry | Registriert die CJK- und die arabische Schriftart. |
DocumentFactory::create(): Document | NextPDF\Core\DocumentFactory | Erstellt ein Dokument, das Ihr Register nutzt. |
Document::writeHtml(string $html): static | NextPDF\Core\Concerns\HasTextOutput | Rendert mehrsprachigen Inhalt. |
Codebeispiel — Schnellstart
Abschnitt betitelt „Codebeispiel — Schnellstart“<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\DocumentFactory;use NextPDF\Graphics\ImageRegistry;use NextPDF\Typography\FontRegistry;
$fonts = new FontRegistry();$fonts->register(__DIR__ . '/NotoSansCJK-Regular.ttf', alias: 'CJK');$fonts->register(__DIR__ . '/NotoNaskhArabic-Regular.ttf', alias: 'Arabic');
$doc = (new DocumentFactory($fonts, new ImageRegistry(maxCacheBytes: 0)))->create();$doc->addPage();$doc->writeHtml( '<p style="font-family: \'CJK\';">PDF 2.0 引擎 — 量子</p>' . '<p style="direction: rtl; font-family: \'Arabic\';">فاتورة</p>');$doc->save(__DIR__ . '/multilingual.pdf');pdftotext multilingual.pdf - | head# Extracts the logical text: "PDF 2.0 引擎 — 量子" and the logical Arabic "فاتورة",# not compatibility code points or reversed presentation forms.Codebeispiel — Produktion
Abschnitt betitelt „Codebeispiel — Produktion“Dieses eigenständige Beispiel versieht das Dokument mit Tags, fügt eine Überschrift mit Buchstabenabstand hinzu und schreibt die Ausgabe in den Harness-Pfad.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\DocumentFactory;use NextPDF\Graphics\ImageRegistry;use NextPDF\Typography\FontRegistry;
$fonts = new FontRegistry();$fonts->register(__DIR__ . '/NotoSansCJK-Regular.ttf', alias: 'CJK');$fonts->register(__DIR__ . '/NotoNaskhArabic-Regular.ttf', alias: 'Arabic');
$doc = (new DocumentFactory($fonts, new ImageRegistry(maxCacheBytes: 0)))->create();$doc->setTitle('Multilingual extraction');$doc->enableTaggedPdf('en');$doc->addPage();
$html = <<<'HTML'<h1 style="font-family: 'CJK'; letter-spacing: 3px;">CODE WORD</h1><p style="font-family: 'CJK';">中文 · 日本語 · 한국어 · 量子 (compatibility ideograph)</p><p style="direction: rtl; font-family: 'Arabic';">المبلغ الإجمالي 380.00</p>HTML;
$doc->writeHtml($html);
$out = getenv('NEXTPDF_OUT');$doc->save($out !== false ? $out : __DIR__ . '/multilingual-copy-paste-extraction.pdf');
echo "Wrote the multilingual PDF\n";Führen Sie pdftotext für die Ausgabe aus. Die Überschrift mit Buchstabenabstand wird als CODE WORD ohne eingefügte Leerzeichen extrahiert, die CJK-Zeile wird als Basiszeichen extrahiert, und die arabische Zeile wird als logische Zeichenkette extrahiert.
Sonderfälle & Fallstricke
Abschnitt betitelt „Sonderfälle & Fallstricke“- Verifizieren Sie die Extraktion mit pdftotext, nicht mit PyMuPDF. Der Rohtextmodus von PyMuPDF ignoriert inline gesetztes
/ActualTextund gibt visuelle Glyphen zurück, sodass er die Korrektheit unterschätzen kann. Poppler (pdftotext) beachtet/ActualText; veraPDF validiert PDF/UA-2, nicht die Extraktion. - Die Extraktion benötigt
/ToUnicode. Registrieren und betten Sie Schriftarten ein, damit der Writer die/ToUnicode-CMap ausgibt. Eine nicht eingebettete, nicht standardisierte Schriftart kann eine Unicode-Abbildung nicht garantieren. /ActualTextdeckt geformte Läufe und Läufe mit Buchstabenabstand ab. Für einfachen, ungeformten Text ohne Abstand extrahiert/ToUnicodeallein korrekt; der/Span-Wrapper erhält mit Abstand versehene oder umgeordnete Läufe.- Getaggte HTML-Tabellen bestehen die PDF/UA-2-Prüfungen. Die Extraktion ist korrekt, und eine getaggte HTML-
<table>besteht jetztveraPDF --flavour ua2ohne Fehler — siehe Accessibility.
Performance
Abschnitt betitelt „Performance“Der Aufbau der /ToUnicode-CMap und des /Span-Wrappers skaliert linear mit der Glyphenanzahl. Dieses Rezept setzt wall_ms: 1500, peak_mb: 96 an.
Sicherheitshinweise
Abschnitt betitelt „Sicherheitshinweise“Validieren Sie die Länge mehrsprachiger Zeichenketten, die von Benutzern geliefert werden, damit die Ausgabegröße begrenzt bleibt. Der /ToUnicode-Builder weist Surrogathälften und Codes außerhalb des Codespace zurück, sodass eine fehlerhafte Abbildung keine beschädigte Ressource für die Extraktion erzeugen kann. Die Engine führt keine Skripte aus und ruft für lokale Schriftarten keine entfernten Ressourcen ab.
Konformität
Abschnitt betitelt „Konformität“| Aussage | Spezifikation | Klausel |
|---|---|---|
Eine /ToUnicode-CMap bildet Zeichencodes für die Extraktion auf Unicode ab. | ISO 32000-2 | §9.10 |
/ActualText ist ein exakter Ersatz für den eingeschlossenen Inhalt. | ISO 32000-2 | §14.9 |
| NFKC ist Kompatibilitätsdekomposition gefolgt von kanonischer Komposition. | Unicode UAX #15 | §1.2 |
Kommerzieller Kontext
Abschnitt betitelt „Kommerzieller Kontext“Nicht zutreffend.
Siehe auch
Abschnitt betitelt „Siehe auch“- Extrahierbaren Textinhalt erzeugen — die Grundlage für Extraktion aus getaggten Inhalten.
- Arabisches RTL-HTML rendern — arabische Formung und Rechts-nach-links-Text.
- Typografie —
/ToUnicodeund NFKC-Kanonisierung. - Accessibility —
/ActualTextund die Unterstützung getaggter Tabellen.