Afficher du HTML arabe de droite à gauche
Rends du HTML de droite à gauche (RTL) au format PDF avec writeHtml(). Définis la propriété CSS direction: rtl et enregistre une police compatible avec l’arabe. Le moteur réordonne le texte dans l’ordre visuel avec l’algorithme bidirectionnel Unicode (UAX #9) et met en forme les lettres arabes selon leurs formes contextuelles. Cette recette génère une petite facture en arabe. Le mode RTL s’applique à l’arabe, à l’hébreu, au persan et à l’ourdou. L’hébreu est réordonné, mais pas mis en forme, ce qui est correct pour cette écriture.
Installation
Section intitulée « Installation »composer require nextpdf/coreIl te faut aussi une police TrueType ou OpenType compatible avec l’arabe. Sa table de caractères doit couvrir le bloc Arabic Presentation Forms-B. Noto Naskh Arabic et Amiri sont des polices sous licence ouverte qui conviennent.
Vue d’ensemble conceptuelle
Section intitulée « Vue d’ensemble conceptuelle »Le rendu RTL nécessite deux éléments en entrée : la propriété CSS direction: rtl et une police arabe enregistrée.
direction: rtl indique à la mise en page de placer le texte de droite à gauche. Le moteur utilise ensuite l’algorithme bidirectionnel Unicode (UAX #9) pour résoudre l’ordre visuel. Le contenu mixte est ordonné correctement : les mots latins, les mots arabes et les chiffres conservent chacun leur propre direction. Un nombre qui suit du texte arabe conserve ses chiffres de gauche à droite.
Comme l’arabe est une écriture cursive, chaque lettre utilise un glyphe différent selon ses voisines. Le moteur sélectionne la forme initiale, médiane, finale ou isolée pour chaque lettre et applique la ligature Lam-Alef. Cette mise en forme contextuelle nécessite une police dont la table de caractères couvre le bloc Arabic Presentation Forms-B. Une police uniquement latine, y compris les fontes standard-14, ne peut pas dessiner l’arabe.
Dans un tableau, chaque cellule est réordonnée et mise en forme individuellement, et les cellules s’alignent sur le bord de début : le bord droit sous direction: rtl. Les valeurs logiques start et end de text-align sont résolues selon la direction ; start correspond donc au bord droit pour un contenu RTL.
Définis la direction avec la propriété CSS direction. L’attribut HTML dir n’est pas relié à cette propriété. Consulte RTL — limites actuelles pour connaître les limites actuelles de l’implémentation.
Surface de l’API
Section intitulée « Surface de l’API »| Symbole | Emplacement | Rôle |
|---|---|---|
Document::writeHtml(string $html): static | NextPDF\Core\Concerns\HasTextOutput | Rend le fragment HTML à la position actuelle du curseur. |
FontRegistry::register(string $fontFile, string $alias = '', int $fontIndex = 0): FontInfo | NextPDF\Typography\FontRegistry | Enregistre la police arabe sous un alias. |
DocumentFactory::create(): Document | NextPDF\Core\DocumentFactory | Crée un document qui utilise le registre renseigné. |
L’exemple utilise ces propriétés CSS : direction, font-family, text-align. Fais référence à la police enregistrée dans la propriété CSS font-family via son alias de registre.
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;
$fontRegistry = new FontRegistry();$fontRegistry->register(__DIR__ . '/NotoNaskhArabic-Regular.ttf', alias: 'ArabicFont');
$documentFactory = new DocumentFactory($fontRegistry, new ImageRegistry(maxCacheBytes: 0));$doc = $documentFactory->create();$doc->addPage();
$doc->writeHtml( '<div style="direction: rtl; font-family: \'ArabicFont\';">' . '<h1>فاتورة</h1>' . '<p>المبلغ الإجمالي 380.00</p>' . '</div>');
$doc->save(__DIR__ . '/rtl-arabic.pdf');Le titre s’affiche de droite à gauche, et les chiffres 380.00 restent de gauche à droite dans la phrase en arabe.
Exemple de code — Production
Section intitulée « Exemple de code — Production »Cet exemple autonome génère un tableau de facture en arabe. Chaque cellule déclare direction: rtl et la police arabe enregistrée, afin que le moteur réordonne et mette en forme chaque ligne, puis aligne les cellules sur le bord droit.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\DocumentFactory;use NextPDF\Graphics\ImageRegistry;use NextPDF\Typography\FontRegistry;
// Supply an Arabic-capable face whose cmap covers Arabic Presentation Forms-B.// Embed only fonts you are licensed to embed.$fontPath = __DIR__ . '/NotoNaskhArabic-Regular.ttf';if (!is_file($fontPath)) { fwrite(STDERR, "Arabic font not found at {$fontPath}\n"); exit(1);}
$fontRegistry = new FontRegistry();$fontRegistry->register($fontPath, alias: 'ArabicFont');
$documentFactory = new DocumentFactory($fontRegistry, new ImageRegistry(maxCacheBytes: 0));$doc = $documentFactory->create();$doc->setTitle('Arabic invoice');$doc->addPage();
$html = <<<'HTML'<div style="direction: rtl; font-family: 'ArabicFont'; font-size: 12pt;"> <h1>فاتورة</h1> <table style="width: 100%; border-collapse: collapse;"> <tr> <th style="border: 1px solid #333; padding: 6px;">الوصف</th> <th style="border: 1px solid #333; padding: 6px;">المبلغ</th> </tr> <tr> <td style="border: 1px solid #333; padding: 6px;">خدمات استشارية</td> <td style="border: 1px solid #333; padding: 6px;">380.00</td> </tr> <tr> <td style="border: 1px solid #333; padding: 6px;">الإجمالي</td> <td style="border: 1px solid #333; padding: 6px;">380.00</td> </tr> </table></div>HTML;
$doc->writeHtml($html);
$out = getenv('NEXTPDF_OUT');$doc->save($out !== false ? $out : __DIR__ . '/render-rtl-arabic-html.pdf');
echo "Wrote the Arabic invoice PDF\n";Cas limites et pièges
Section intitulée « Cas limites et pièges »- Enregistre la police avant de construire le document.
Document::createStandalone()construit son propre registre et ne peut pas voir une police que tu as enregistrée ailleurs. Construis le document viaDocumentFactorypour que le moteur d’écriture lise ton registre, comme dans les deux exemples. - Fais correspondre la propriété CSS
font-familyà l’alias de registre. Le nom que tu passes àregister(..., alias: 'ArabicFont')est celui auquel tu fais référence dans le CSS. - Utilise la propriété CSS
direction, pas l’attribut HTMLdir. Seule la propriété CSS bascule la mise en page. - Un nombre placé après du texte arabe reste de gauche à droite. Cela suit UAX #9 : un nombre européen après une lettre arabe se résout en nombre arabe et conserve l’ordre de ses chiffres, donc
380.00n’est pas inversé.
RTL — limites actuelles
Section intitulée « RTL — limites actuelles »L’implémentation actuelle réordonne et met en forme le texte RTL, et aligne les cellules de tableau. Les limites suivantes subsistent. Chacune nécessitera, à l’avenir, une boîte de ligne capable de gérer la mise en forme en ligne, ligne par ligne :
- Alignement de bloc et en ligne hors des tableaux. Le texte de niveau bloc et en ligne situé hors des cellules de tableau est réordonné et mis en forme, mais il s’affiche depuis le bord de début (gauche). L’alignement à droite ou au centre du texte hors des tableaux, ainsi que la distribution
text-align: justify, ne sont pas encore appliqués. Les cellules de tableau, en revanche, s’alignent. - L’attribut HTML
dirn’est pas relié àdirection. Définis la direction avec la propriété CSSdirection. - La résolution bidirectionnelle s’effectue par séquence de texte. Les caractères neutres ne sont pas résolus entre deux éléments en ligne, par exemple un
<span>à côté d’un<b>, sur la même ligne. - Les colonnes arabes étroites sont mesurées sur le texte logique. Les sauts de ligne sont mesurés sur le texte logique, avant la mise en forme, donc une colonne arabe très étroite peut couper une ligne légèrement trop tôt ou trop tard.
- La mise en forme de l’arabe nécessite la couverture Presentation Forms-B. La police doit couvrir le bloc Arabic Presentation Forms-B. Les polices qui reposent uniquement sur la substitution OpenType GSUB, ainsi que le chemin de mise en forme HarfBuzz, restent des travaux futurs. Une police non arabe ne peut pas dessiner l’arabe.
Performance
Section intitulée « Performance »Le rendu évolue linéairement avec le nombre de glyphes. Le réordonnancement bidirectionnel et la mise en forme contextuelle s’exécutent par ligne, avec un petit facteur constant supplémentaire par rapport au texte de gauche à droite. Le budget de cette recette est wall_ms: 1500, peak_mb: 64.
Notes de sécurité
Section intitulée « Notes de sécurité »Valide la longueur des chaînes fournies par l’utilisateur pour borner la taille de sortie. Le moteur rend le texte, ne l’interprète pas et n’exécute aucun script. Si tu charges une police via une source @font-face distante, la politique sécurisée des ressources externes régit la récupération ; privilégie un fichier de police local pour une sortie prévisible.
Conformité
Section intitulée « Conformité »| Énoncé | Spécification | Clause | reference_id |
|---|---|---|---|
| L’ordre visuel est produit en inversant les séquences de caractères depuis le niveau le plus élevé jusqu’au niveau impair le plus bas. | Unicode UAX #9 | §3.3.6 Rule L2 (uax9#3.3.6.p13) | 814977a77019d728dc562a612098a82dc260f6844f5998eca5fe7a3baf3394af |
| Un nombre européen après une lettre arabe se résout en nombre arabe, donc ses chiffres conservent l’ordre de gauche à droite. | Unicode UAX #9 | §3.3.4 Rule W2 (uax9#3.3.4.p9) | 5747405357772797d62b3f4ba79328557fa0c4273a1dd5ffa8d996f24c78e120 |
La mise en forme contextuelle de l’arabe (formes initiale, médiane, finale et isolée, plus la ligature Lam-Alef) est une capacité du moteur, vérifiée et couverte par la suite de tests, et non une revendication de conformité distincte. Elle nécessite une police dont la table de caractères couvre le bloc Arabic Presentation Forms-B.
Contexte commercial
Section intitulée « Contexte commercial »Sans objet.
Voir aussi
Section intitulée « Voir aussi »- HTML : sous-système de rendu HTML+CSS vers PDF — le moteur
writeHtml()et sa prise en charge RTL. - Typographie : registre de polices, sous-ensemble, CMap, encodage, BiDi — le moteur bidirectionnel qui résout UAX #9.
- Matrice de prise en charge des polices et des écritures — quelles écritures chaque classe de police peut afficher.
- Afficher du HTML en page PDF — le point de départ de gauche à droite.