Produire des PDF CJK et arabes fiables au copier-coller
Crée un fichier PDF (Portable Document Format) dont le texte chinois, japonais, coréen (CJK) et arabe se copie-colle sous forme de caractères logiques d’origine. Le moteur associe chaque glyphe à l’Unicode via une CMap /ToUnicode, canonicalise le résultat avec la forme de normalisation de composition de compatibilité (NFKC), et enveloppe les séquences mises en forme ou espacées par lettres dans un /Span doté d’un /ActualText. Enregistre les polices et écris le contenu ; l’extraction reste correcte. Vérifie l’extraction avec pdftotext/Poppler, pas avec PyMuPDF ; veraPDF valide PDF/Universal Accessibility 2 (PDF/UA-2), pas l’extraction.
Installation
Section intitulée « Installation »composer require nextpdf/coreEnregistre une police CJK, par exemple Noto Sans CJK, ainsi qu’une police compatible avec l’arabe dont la table de caractères couvre le bloc Arabic Presentation Forms-B, par exemple Noto Naskh Arabic. N’incorpore que les polices que tu es autorisé à incorporer.
Vue d’ensemble conceptuelle
Section intitulée « Vue d’ensemble conceptuelle »Les codes de glyphes d’un flux de contenu ne sont pas de l’Unicode. Une CMap /ToUnicode associe chaque code à l’Unicode, afin qu’un lecteur puisse extraire le texte (ISO 32000-2 §9.10). Le moteur canonicalise ces valeurs avec la forme de normalisation de composition de compatibilité (NFKC), telle que définie par Unicode UAX #15. Un idéogramme de compatibilité CJK et une forme de présentation arabe sont ramenés à leur caractère de base, si bien que la recherche et la copie renvoient le texte canonique au lieu d’un point de code de compatibilité.
Deux cas nécessitent plus que /ToUnicode : le latin espacé par lettres et l’arabe de droite à gauche mis en forme. Le moteur les dessine comme des glyphes espacés ou réordonnés ; l’ordre des glyphes seul ne suffit donc pas à retrouver la chaîne logique. Il enveloppe chaque séquence dans une séquence de contenu marqué /Span porteuse d’un /ActualText, un remplacement exact du contenu englobé (ISO 32000-2 §14.9). Les outils d’extraction qui respectent /ActualText renvoient la chaîne logique.
Surface de l’API
Section intitulée « Surface de l’API »| Symbole | Emplacement | Rôle |
|---|---|---|
FontRegistry::register(string $fontFile, string $alias = ''): FontInfo | NextPDF\Typography\FontRegistry | Enregistre les polices CJK et arabe. |
DocumentFactory::create(): Document | NextPDF\Core\DocumentFactory | Construit un document qui utilise ton registre. |
Document::writeHtml(string $html): static | NextPDF\Core\Concerns\HasTextOutput | Rend le contenu multilingue. |
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\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.Exemple de code — Production
Section intitulée « Exemple de code — Production »Cet exemple autonome balise le document, ajoute un titre espacé par lettres et écrit la sortie vers le chemin fourni par le harnais.
<?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";Exécute pdftotext sur le fichier de sortie. Le titre espacé par lettres s’extrait en CODE WORD sans espaces insérés, la ligne CJK s’extrait avec ses caractères de base, et la ligne arabe s’extrait sous forme de chaîne logique.
Cas limites et pièges
Section intitulée « Cas limites et pièges »- Vérifie l’extraction avec pdftotext, pas avec PyMuPDF. Le mode texte brut de PyMuPDF ignore
/ActualTexten ligne et renvoie les glyphes visuels, ce qui peut sous-évaluer l’exactitude. Poppler (pdftotext) respecte/ActualText; veraPDF valide PDF/UA-2, pas l’extraction. - L’extraction a besoin de
/ToUnicode. Enregistre et incorpore les polices pour que le moteur d’écriture émette la CMap/ToUnicode. Une police non incorporée et non standard ne permet pas de garantir une correspondance Unicode. /ActualTextcouvre les séquences mises en forme et espacées par lettres. Pour du texte simple, non mis en forme et non espacé, l’extraction fonctionne correctement avec/ToUnicodeseul ; l’enveloppe/Spanpréserve les séquences espacées ou réordonnées.- Les tableaux HTML balisés passent les contrôles PDF/UA-2. L’extraction est correcte, et un
<table>HTML balisé passe désormaisveraPDF --flavour ua2sans aucun échec ; consulte Accessibilité.
Performance
Section intitulée « Performance »La construction de la CMap /ToUnicode et des enveloppes /Span évolue linéairement avec le nombre de glyphes. Le budget de cette recette est wall_ms: 1500, peak_mb: 96.
Notes de sécurité
Section intitulée « Notes de sécurité »Valide la longueur des chaînes multilingues fournies par l’utilisateur afin de garder la taille de sortie bornée. Le constructeur de /ToUnicode rejette les demi-surrogates et les codes hors de l’espace de codes ; une correspondance malformée ne peut donc pas créer une ressource d’extraction corrompue. Le moteur n’exécute aucun script et ne récupère aucune ressource distante pour les polices locales.
Conformité
Section intitulée « Conformité »| Énoncé | Spécification | Clause |
|---|---|---|
Une CMap /ToUnicode associe les codes de caractères à l’Unicode pour l’extraction. | ISO 32000-2 | §9.10 |
/ActualText est un remplacement exact du contenu englobé. | ISO 32000-2 | §14.9 |
| NFKC est une décomposition de compatibilité suivie d’une composition canonique. | Unicode UAX #15 | §1.2 |
Contexte commercial
Section intitulée « Contexte commercial »Sans objet.
Voir aussi
Section intitulée « Voir aussi »- Extraire le contenu textuel — le socle de l’extraction balisée.
- Afficher du HTML arabe de droite à gauche — mise en forme de l’arabe et texte de droite à gauche.
- Typographie —
/ToUnicodeet canonicalisation NFKC. - Accessibilité —
/ActualTextet la prise en charge des tableaux balisés.