عرض HTML عربي من اليمين إلى اليسار
لمحة سريعة
قسم بعنوان «لمحة سريعة»اعرض HTML من اليمين إلى اليسار (RTL) في PDF باستخدام writeHtml(). اضبط خاصية CSS direction: rtl وسجّل خطًا يدعم العربية. يعيد المحرك ترتيب النص بصريًا باستخدام خوارزمية Unicode ثنائية الاتجاه (UAX #9)، ويشكّل الحروف العربية بحسب مواضعها السياقية. تعرض هذه الوصفة فاتورة عربية صغيرة. ينطبق RTL على العربية والعبرية والفارسية والأردية. أما العبرية فتُعاد ترتيبها فقط دون تشكيل، وهذا هو السلوك الصحيح لهذه الكتابة.
التثبيت
قسم بعنوان «التثبيت»composer require nextpdf/coreتحتاج أيضًا إلى خط TrueType أو OpenType يدعم العربية. يجب أن يغطي جدول رموزه كتلة Arabic Presentation Forms-B. ويُعد Noto Naskh Arabic وAmiri خطين مناسبين ومفتوحي الترخيص.
نظرة مفاهيمية عامة
قسم بعنوان «نظرة مفاهيمية عامة»لتمكين عرض RTL، تحتاج إلى مدخلين: خاصية CSS direction: rtl وخط عربي مُسجَّل.
توجّه direction: rtl التخطيط إلى وضع النص من اليمين إلى اليسار. ثم يستخدم المحرك خوارزمية Unicode ثنائية الاتجاه (UAX #9) لحل الترتيب البصري. يُرتَّب المحتوى المختلط ترتيبًا صحيحًا: تحتفظ الكلمات اللاتينية والكلمات العربية والأرقام باتجاهاتها الخاصة. والرقم الذي يلي نصًا عربيًا يحتفظ بترتيب أرقامه من اليسار إلى اليمين.
العربية كتابة متصلة، لذلك يتخذ كل حرف شكلًا رسوميًا مختلفًا بحسب الأحرف المجاورة له. يختار المحرك الشكل الابتدائي أو الوسطي أو الختامي أو المنفرد لكل حرف، ويطبّق رابطة Lam-Alef. يتطلب هذا التشكيل السياقي خطًا يغطي جدول رموزه كتلة Arabic Presentation Forms-B. ولا يستطيع خط لاتيني فقط، بما في ذلك وجوه الخطوط الأربعة عشر القياسية، رسم العربية.
داخل الجدول، يُعاد ترتيب محتوى كل خلية ويُشكَّل مستقلًا، وتُحاذى الخلايا إلى حافة البداية: الحافة اليمنى تحت direction: rtl. وتُحلّ قيمتا text-align المنطقيتان start وend وفق الاتجاه، فتشير start إلى الحافة اليمنى لمحتوى RTL.
اضبط الاتجاه بخاصية CSS direction. ولا تُترجَم سمة HTML dir إليها. راجع RTL — القيود الحالية لمعرفة حدود التنفيذ الحالية.
واجهة API
قسم بعنوان «واجهة API»| الرمز | الموضع | الدور |
|---|---|---|
Document::writeHtml(string $html): static | NextPDF\Core\Concerns\HasTextOutput | اعرض مقطع HTML عند موضع المؤشر الحالي. |
FontRegistry::register(string $fontFile, string $alias = '', int $fontIndex = 0): FontInfo | NextPDF\Typography\FontRegistry | سجّل وجه الخط العربي باسم مستعار. |
DocumentFactory::create(): Document | NextPDF\Core\DocumentFactory | أنشئ مستندًا يقرأ السجل الذي ملأته. |
يستخدم المثال خصائص CSS التالية: direction وfont-family وtext-align. أشِر في CSS font-family إلى الخط المُسجَّل باستخدام اسمه المستعار في السجل.
نموذج الكود — البدء السريع
قسم بعنوان «نموذج الكود — البدء السريع»<?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');يظهر العنوان من اليمين إلى اليسار، وتبقى الأرقام 380.00 من اليسار إلى اليمين داخل الجملة العربية.
نموذج الكود — للإنتاج
قسم بعنوان «نموذج الكود — للإنتاج»يعرض هذا المثال المستقل جدول فاتورة عربية. تستخدم كل خلية direction: rtl والخط العربي المُسجَّل، فيعيد المحرك ترتيب كل سطر ويُشكّله، ثم يحاذي الخلايا إلى الحافة اليمنى.
<?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";الحالات الحدّية والمزالق
قسم بعنوان «الحالات الحدّية والمزالق»- سجّل الخط قبل بناء المستند. تُنشئ
Document::createStandalone()سجلها الخاص ولا يمكنها رؤية وجه خط سجّلته في موضع آخر. ابنِ المستند عبرDocumentFactoryحتى يقرأ الكاتب سجلك، كما في النموذجين. - طابِق CSS
font-familyمع الاسم المستعار في السجل. الاسم الذي تمرره إلىregister(..., alias: 'ArabicFont')هو الاسم الذي تشير إليه في CSS. - استخدم CSS
direction، لا سمة HTMLdir. خاصية CSS وحدها هي التي تبدّل التخطيط. - الرقم الذي يلي العربية يبقى من اليسار إلى اليمين. يتبع هذا UAX #9: الرقم الأوروبي بعد حرف عربي يُحلّ إلى رقم عربي ويحتفظ بترتيب أرقامه، لذلك لا تُعكس
380.00.
RTL — القيود الحالية
قسم بعنوان «RTL — القيود الحالية»يدعم التنفيذ الحالي إعادة ترتيب نص RTL وتشكيله ومحاذاة خلايا الجدول. وتظل هذه الحدود قائمة. ويحتاج كلٌّ منها مستقبلًا إلى صندوق سطر للتنسيق المضمّن لكل سطر:
- محاذاة الكتل والمحتوى المضمّن خارج الجداول. يُعاد ترتيب النص الكتلي والمضمّن خارج خلايا الجدول ويُشكَّل، لكنه يُعرض من حافة البداية (اليسرى). ولم تُطبَّق بعد المحاذاة إلى اليمين أو الوسط للنص غير الجدولي، ولا توزيع
text-align: justify. أما خلايا الجدول فتُحاذى فعلًا. - لا تُترجَم سمة HTML
dirإلىdirection. اضبط الاتجاه بخاصية CSSdirection. - يُحلّ الاتجاه الثنائي لكل مقطع نص على حدة. لا تُحلّ المحارف المحايدة عبر عنصرَين مضمّنَين، مثل
<span>بجوار<b>، على السطر نفسه. - تُقاس الأعمدة العربية الضيقة على النص المنطقي. تُقاس فواصل الأسطر على النص المنطقي السابق للتشكيل، لذلك قد يكسر عمود عربي ضيق جدًا السطر مبكرًا أو متأخرًا قليلًا.
- يحتاج النص العربي المُشكَّل إلى تغطية Presentation Forms-B. يجب أن يغطي الوجه كتلة Arabic Presentation Forms-B. أما دعم الخطوط التي تعتمد فقط على استبدالات OpenType GSUB، ودعم مسار التشكيل HarfBuzz، فهما عمل مستقبلي. ولا يمكن لخط غير عربي رسم العربية.
الأداء
قسم بعنوان «الأداء»يتناسب زمن العرض خطيًا مع عدد المحارف الرسومية. تُنفَّذ إعادة الترتيب الثنائي الاتجاه والتشكيل السياقي لكل سطر، وتضيف عاملًا ثابتًا صغيرًا مقارنة بالنص من اليسار إلى اليمين. وميزانية هذه الوصفة هي wall_ms: 1500, peak_mb: 64.
ملاحظات أمنية
قسم بعنوان «ملاحظات أمنية»تحقّق من طول السلاسل النصية المُدخَلة من المستخدم لإبقاء حجم المُخرَج محدودًا. يعرض المحرك النص ولا يفسّره، ولا يشغّل أي سكربت. وإذا حمّلت خطًا من مصدر بعيد عبر @font-face، فإن سياسة الموارد الخارجية الآمنة تحكم عملية الجلب؛ ويُفضَّل استخدام ملف خط محلي للحصول على مُخرَج متوقَّع.
المطابقة
قسم بعنوان «المطابقة»| البيان | المواصفة | البند | reference_id |
|---|---|---|---|
| يُنتَج الترتيب البصري بعكس مقاطع المحارف من أعلى مستوى نزولًا إلى أدنى مستوى فردي. | Unicode UAX #9 | §3.3.6 Rule L2 (uax9#3.3.6.p13) | 814977a77019d728dc562a612098a82dc260f6844f5998eca5fe7a3baf3394af |
| الرقم الأوروبي بعد حرف عربي يُحلّ إلى رقم عربي، فتحتفظ أرقامه بالترتيب من اليسار إلى اليمين. | Unicode UAX #9 | §3.3.4 Rule W2 (uax9#3.3.4.p9) | 5747405357772797d62b3f4ba79328557fa0c4273a1dd5ffa8d996f24c78e120 |
التشكيل السياقي للعربية (الأشكال الابتدائية والوسطية والختامية والمنفردة إضافةً إلى رابطة Lam-Alef) قدرة تم التحقق منها في المحرك وتغطّيها مجموعة الاختبارات، وليس ادعاء مطابقة مستقلًا. ويتطلب خطًا يغطي جدول رموزه كتلة Arabic Presentation Forms-B.
السياق التجاري
قسم بعنوان «السياق التجاري»غير منطبق.
انظر أيضًا
قسم بعنوان «انظر أيضًا»- HTML: نظام HTML+CSS الفرعي للعرض إلى PDF — محرك
writeHtml()ودعمه لـ RTL. - الطباعة: سجل الخطوط، والاختزال، وCMap، والترميز، والاتجاه الثنائي — المحرك الثنائي الاتجاه الذي يحل UAX #9.
- مصفوفة دعم الخطوط والكتابات — الكتابات التي يمكن لكل فئة خط عرضها.
- عرض HTML إلى صفحة PDF — نقطة الانطلاق من اليسار إلى اليمين.