เรนเดอร์ HTML ภาษาอาหรับแบบขวาไปซ้าย
ภาพรวมโดยย่อ
หัวข้อที่มีชื่อว่า “ภาพรวมโดยย่อ”เรนเดอร์ HTML แบบขวาไปซ้าย (RTL) ให้เป็น PDF ด้วย writeHtml() โดยกำหนดพร็อพเพอร์ตี CSS direction: rtl และลงทะเบียนฟอนต์ที่รองรับภาษาอาหรับ เอนจินจะจัดเรียงข้อความเป็นลำดับเชิงภาพตามอัลกอริทึมข้อความสองทิศทางของ Unicode (UAX #9) และขึ้นรูปอักษรอาหรับตามบริบท สูตรนี้แสดงวิธีเรนเดอร์ใบแจ้งหนี้ภาษาอาหรับขนาดเล็กแบบ RTL โดย 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 ฟอนต์ที่รองรับเฉพาะภาษาละติน รวมถึงฟอนต์มาตรฐาน 14 รายการ ไม่สามารถวาดอักษรอาหรับได้
ในตาราง แต่ละเซลล์จะถูกจัดลำดับและขึ้นรูปแยกกัน แล้วจัดแนวชิดขอบเริ่มต้น ซึ่งคือขอบขวาภายใต้ 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 - Typography: รีจิสทรีฟอนต์ การสร้างซับเซต CMap การเข้ารหัส BiDi — เอนจินสองทิศทางที่ใช้แก้ค่า UAX #9
- เมทริกซ์การรองรับฟอนต์และสคริปต์ — คลาสฟอนต์แต่ละประเภทเรนเดอร์สคริปต์ใดได้บ้าง
- เรนเดอร์ HTML เป็นหน้า PDF — จุดเริ่มต้นแบบซ้ายไปขวา