บทความเทคนิค

การจัดรูปแบบข้อความภาษาอาหรับและ RTL ใน Delphi PDF ด้วย HotPDF

ส่งผ่านวลีภาษาอาหรับ يوضح ملف PDF ไปยัง TextOut และเปิดดูผลลัพธ์ ตัวอักษรจะวิ่งไปในทิศทางที่ผิด และแต่ละตัวอักษรจะอยู่ในรูปแบบแยกเดี่ยวโดยมีช่องว่างที่มองเห็นได้ก่อนตัวถัดไป ราวกับว่ามีคนพิมพ์ภาษาอังกฤษกลับหลังและกดสเปซบาร์ระหว่างทุกตัวอักษร ไม่มีข้อยกเว้นเกิดขึ้น ไม่มีการพิมพ์คำเตือน ผลลัพธ์ผิดพลาดอย่างเห็นได้ชัด และที่ผิดพลาดเพราะการแปลงสองรูปแบบที่ภาษาอาหรับต้องพึ่งพานั้นไม่เคยเกิดขึ้น การรู้ว่าการแปลงสองรูปแบบนั้นคืออะไร และการเรียกใช้ใดที่เป็นผู้ดำเนินการ เป็นส่วนสำคัญที่สุดของการส่งออก PDF สำหรับสคริปต์ที่ซับซ้อน

HotPDF เป็นคอมโพเนนต์ VCL PDF แบบเนทีฟสำหรับ Delphi และ C++Builder และมันทำงานจากขวาไปซ้ายให้คุณผ่านการเรียกใช้ที่แยกจากกัน นอกจากนี้ยังหยุดทำงานในจุดเฉพาะบางแห่งที่คุณต้องการทราบก่อนที่จะตกลงใช้ภาษาท้องถิ่น ดังนั้นบทความนี้จึงแสดงแผนที่แนวคิดและขอบเขตที่แท้จริง สำหรับการตั้งค่าเชิงปฏิบัติสำหรับการเรียกใช้เองนั้นอยู่ใน บทความอ้างอิง RtLTextOut

ทำไมสตริงที่ถูกต้องถึงยังพิมพ์ออกมาผิด

Unicode เก็บข้อความในลำดับตรรกะ ซึ่งเป็นลำดับที่คุณพิมพ์และอ่านออกเสียง ตัวเรนเดอร์จะต้องวาง glyph ในลำดับการมองเห็น สำหรับสคริปต์แบบซ้ายไปขวา ลำดับเหล่านั้นจะตรงกันและไม่มีใครคิดถึงเรื่องนี้ สำหรับภาษาอาหรับและฮีบรูนั้นไม่ตรงกัน และเมื่อบรรทัดเดียวผสมหลายทิศทาง เช่น ประโยคภาษาอาหรับที่มีโทเค็นละติน "PDF" หรือราคาที่เขียนด้วยตัวเลข อัลกอริทึมสองทิศทางของ Unicode (UAX #9) จะตัดสินว่าส่วนที่อ่านจากซ้ายไปขวาจะซ้อนกันอย่างไรภายในบรรทัดที่อ่านจากขวาไปซ้าย นั่นคือการแปลงครั้งแรก การจัดเรียงใหม่ และการข้ามขั้นตอนนี้ไปคือสิ่งที่ทำให้บรรทัดกลับด้าน

อย่างที่สองคือการจัดรูปแบบตามบริบท ตัวอักษรภาษาอาหรับจะถูกวาดแตกต่างกันไปขึ้นอยู่กับว่ามันอยู่ตำแหน่งใดในคำ: เริ่มต้น กลาง ท้าย หรือแยกเดี่ยว รหัสจุด (codepoint) ยังคงเหมือนเดิมตลอด มีเพียง glyph เท่านั้นที่เปลี่ยนไป ไปป์ไลน์ที่ส่งรหัสจุดแต่ละอันตรงไปยัง glyph เริ่มต้น จะสร้างผลลัพธ์ที่เป็นรูปแบบแยกเดี่ยวไม่เชื่อมต่อกันแบบเดียวกับในย่อหน้าเปิด ภาษาฮีบรูข้ามขั้นตอนนี้ไป เนื่องจากตัวอักษรไม่เชื่อมต่อกัน แต่ก็ยังต้องการการจัดเรียงใหม่ ภาษาอาหรับต้องการทั้งสองอย่าง และนั่นคือเหตุผลที่ภาษาอาหรับ ไม่ใช่ฮีบรู เป็นสตริงที่คุณใช้ทดสอบ

บนเดสก์ท็อป ทั้งหมดนี้ไม่ใช่ปัญหาของคุณ เมื่อฟอร์ม VCL วาดภาษาอาหรับลงใน TEdit สแต็กข้อความของระบบปฏิบัติการจะจัดเรียงและจัดรูปแบบอย่างเงียบๆ ซึ่งเป็นเหตุผลที่สตริงที่ดูสมบูรณ์แบบบนหน้าจอกลับออกมาแตกหักใน PDF แบบเรียบง่าย สตรีมเนื้อหาไม่ได้เก็บข้อความที่แก้ไขได้ มันเก็บ glyph ที่มีตำแหน่ง ดังนั้นใครก็ตามที่ปล่อยสตรีมออกมาย่อมสืบทอดงานจัดรูปแบบที่ระบบปฏิบัติการเคยจัดการ RtLTextOut เป็นการเรียกที่นำงานนั้นกลับคืนมา

สิ่งที่ RtLTextOut จัดรูปแบบให้คุณ

HotPDF เก็บเส้นทางภาษาละตินและเส้นทางสคริปต์ที่ซับซ้อนไว้เป็นสองวิธีที่แตกต่างกัน TextOut พิมพ์สิ่งที่คุณให้ตามลำดับที่คุณให้ RtLTextOut ทำการแปลงทั้งสองอย่างก่อน — การจัดเรียงสองทิศทางตลอดทั้งบรรทัด การวิเคราะห์ตามบริบทสำหรับสคริปต์ที่เชื่อมต่อกัน — แล้วจึงพิมพ์ กฎของสคริปต์ใดที่ใช้จะถูกส่งผ่านชุดตัวอักษรของฟอนต์แทนที่จะส่งผ่านการเรียกเอง ดังนั้นทิศทางจึงเป็นทางเลือกที่ชัดเจนในทุกไซต์ที่เรียกใช้งานแทนที่จะเป็นการคาดเดาจากอักขระ การตั้งค่าทีละพารามิเตอร์ ค่าชุดตัวอักษร ขั้นตอนการลงทะเบียนฟอนต์ และตัวอย่างที่สามารถคอมไพล์ได้ทั้งหมดอยู่ใน บทความอ้างอิง RtLTextOut บทความนี้จะคงอยู่กับสิ่งที่การแปลงหมายถึง จุดที่หยุดทำงาน และวิธีพิสูจน์ว่าพวกมันทำงานได้จริง

กฎการใช้งานข้อหนึ่งที่สำคัญแม้ในระดับนี้: อินพุตต้องอยู่ในลำดับตรรกะ เนื่องจาก RtLTextOut จะทำการกลับด้านด้วยตัวมันเอง และสตริงที่คุณกลับด้านด้วยมืออยู่แล้วจะออกมาเป็นแบบกลับด้านสองครั้ง — บทความอ้างอิงจะอธิบายถึงกับดักนั้นและการแก้ไข สิ่งที่ทำให้กับดักนี้ควรค่าแก่การกล่าวถึงที่นี่คือเหตุผลที่มันรอดจากการทดสอบ สตริงภาษาอาหรับล้วนที่กลับด้านสองครั้งอาจดูถูกต้องสมบูรณ์ และจะแตกหักก็ต่อเมื่อบรรทัดนั้นมีคำภาษาละตินหรือตัวเลข เนื่องจากส่วนที่ฝังเหล่านั้นจะไม่ซ้อนกันตามที่ UAX #9 กำหนดไว้อีกต่อไป ข้อบกพร่องไม่ได้อยู่ที่การเรนเดอร์ แต่อยู่ที่การป้อนข้อความที่ประมวลผลไปแล้วครึ่งหนึ่งให้กับอัลกอริทึม

พฤติกรรมสองทิศทางแบบผสมเดียวกันนี้ทำให้ผู้ทบทวนสะดุดมากกว่าที่ทำให้โค้ดสะดุด ภายในบรรทัดที่อ่านจากขวาไปซ้าย ตัวเลขและคำภาษาละตินที่ฝังอยู่ยังคงอ่านจากซ้ายไปขวา คนที่ไม่เคยทำงานกับเลย์เอาต์สองทิศทางจะมองไปที่ใบแจ้งหนี้ที่เรนเดอร์แล้ว เห็นหมายเลขบัญชีอ่านในทางที่ "ผิด" เมื่อเทียบกับภาษาอาหรับรอบๆ และเขียนว่าเป็นบั๊ก มันเป็นผลลัพธ์ที่ถูกต้องตามข้อกำหนด บันทึกสั้นๆ ในเกณฑ์การยอมรับของคุณ ซึ่งเขียนขึ้นก่อนการตรวจสอบโดยเจ้าของภาษาครั้งแรก จะช่วยประหยัดเวลาในการวนกลับมาแก้ปัญหานี้

เมื่อการจัดเรียงและการเชื่อมต่อก็เพียงพอ และเมื่อใดที่ไม่เพียงพอ

สำหรับข้อความต่อเนื่องภาษาอาหรับและฮีบรู — รายงาน ใบแจ้งหนี้ สัญญา จดหมาย — การจัดเรียงร่วมกับการเชื่อมต่อตามบริบทคืองานทั้งหมด และ RtLTextOut สามารถจัดการได้ด้วยตัวมันเอง ขอบเขตจะปรากฏขึ้นเมื่อการจัดทำตัวพิมพ์ต้องการมากกว่าการเชื่อมต่อ คำตอบของ HotPDF ในฝั่งภาษาอาหรับคือตัวจัดรูปแบบฝั่งผู้ผลิตแบบเลือกรับ (opt-in): ตั้งค่า AutoShapeArabic := True และคอมโพเนนต์จะเขียนการรันตามลำดับตรรกะใหม่ให้เป็น Unicode Presentation Forms ก่อนที่จะผ่านขั้นตอนสองทิศทาง ดังนั้นรูปแบบการเชื่อมต่อจะถูกคำนวณจากบริบทตรรกะที่อยู่ใกล้เคียง และการพับตัวเชื่อม (ligature) จะถูกอบเข้าในรหัสจุดที่ PDF พกพาไปจริงๆ แทนที่จะปล่อยให้โปรแกรมดูไฟล์เป็นผู้แก้ไข สวิตช์นี้มีค่าเริ่มต้นเป็นปิดและผลลัพธ์จะเสถียรในระดับไบต์เมื่อมันถูกปิดไว้ ดังนั้นการเปิดใช้งานจึงเป็นการตัดสินใจโดยเจตนาต่อไปป์ไลน์เอกสาร ไม่ใช่การอัปเกรดระดับโลก โมเดลแบบเลือกรับเดียวกันนี้ยังขยายไปยังสคริปต์เชื่อมต่อขวาไปซ้ายอื่นๆ ที่ HotPDF จัดรูปแบบ: Syriac, N'Ko, Adlam และ Hanifi Rohingya แต่ละตัวมีแฟล็กจัดรูปแบบอัตโนมัติของตัวเองที่ทำงานเหมือนกับของภาษาอาหรับ

ฟีเจอร์ OpenType เสริมเป็นกลไกที่แตกต่างออกไปอีก ดิสครีชันนารีลิเกเจอร์ (Discretionary ligatures) และฟีเจอร์การแทนที่แบบเดี่ยวที่คล้ายกันจะผ่าน GetSingleSubstituteGlyph(GID, 'liga') ซึ่งแก้ไขการแทนที่ครั้งละหนึ่งอัน — รหัส glyph อินพุตมาก่อน ตามด้วยแท็กฟีเจอร์ — และคืนค่า glyph อินพุตโดยไม่เปลี่ยนแปลงเมื่อฟีเจอร์นั้นไม่มีผล นั่นเพียงพอที่จะขับเคลื่อนรายการลิเกเจอร์ที่รู้จักและมีขอบเขตจำกัดที่คุณดูแลด้วยตนเอง มันไม่ใช่เอนจิน GSUB แบบเต็มรูปแบบ และความแตกต่างนี้เป็นจุดที่ทำให้แผนพัฒนาภาษาท้องถิ่นที่ทะเยอทะยานผิดพลาด: ไปป์ไลน์การจัดรูปแบบที่จัดการภาษาอาหรับได้อย่างไร้ที่ติได้แสดงให้เห็นถึงการจัดเรียงและการเชื่อมต่อเท่านั้น ไม่มีอะไรมากไปกว่านี้

ความครอบคลุมทั่วสคริปต์

ภาษาอาหรับใช้การแปลงทั้งสองอย่าง ซึ่งเป็นเหตุผลว่าทำไมมันถึงเป็นสตริงที่ใช้ทดสอบ และทำไมการผ่านภาษาอาหรับจึงเป็นหลักฐานชิ้นเดียวที่แข็งแกร่งที่สุดว่าไปป์ไลน์ทำงานได้ ภาษาฮีบรูต้องการการจัดเรียงแต่ไม่ต้องเชื่อมต่อ เนื่องจากตัวอักษรตั้งอยู่เดี่ยวๆ ถ้าภาษาฮีบรูเรนเดอร์ได้ถูกต้องแต่ภาษาอาหรับออกมาแบบไม่เชื่อมต่อกัน แสดงว่าครึ่งหลังของทิศทางคู่ทำงานได้ดี แต่การเชื่อมต่อตามบริบทไม่เคยทำงาน ภาษาเปอร์เซียและภาษาอูรดูใช้สคริปต์ภาษาอาหรับและสืบทอดพฤติกรรมของมัน แม้ว่าความชอบของภาษาอูรดูที่มีต่อรูปแบบ Nastaliq จะเป็นการตัดสินใจเรื่องฟอนต์ที่มีผลต่อความสามารถในการอ่าน ซึ่งผู้อ่านเจ้าของภาษาควรเป็นผู้ตัดสิน

ภาษาไทยอยู่คนละฝั่งอย่างสิ้นเชิง มันอ่านจากซ้ายไปขวา ดังนั้นจึงไม่ต้องทำงานสองทิศทาง และตัวอักษรไม่เชื่อมต่อกัน ดังนั้นจึงไม่ต้องวิเคราะห์ตามบริบท สตริงภาษาไทยผ่านเส้นทาง TextOut ธรรมดาเหมือนภาษาละติน สิ่งที่ภาษาไทยมีคือเครื่องหมายซ้อนทับ — สระและเครื่องหมายวรรณยุกต์ด้านบนและด้านล่างของพยัญชนะฐาน — และเครื่องหมายเหล่านั้นจะวางอย่างถูกต้องหรือไม่ขึ้นอยู่กับการสร้างฟอนต์ให้เครื่องหมายที่รวมกันสามารถซ้อนทับได้โดยไม่ต้องใช้เอนจินจัดรูปแบบช่วยเหลือ ฟอนต์ภาษาไทยเฉพาะส่วนใหญ่ทำได้ ทดสอบด้วยฟอนต์จริงที่คุณจะฝัง ไม่ใช่ฟอนต์ที่ดูคล้ายกัน

เทวนาครีและตระกูลสคริปต์อินเดียอื่นๆ คือจุดหยุดที่แท้จริง เครื่องหมายสระของพวกมันจะจัดเรียงใหม่รอบกลุ่มพยัญชนะและอักษรควบของพวกมันก่อตัวผ่านสายโซ่ของการแทนที่ตามบริบท ซึ่งเป็นดินแดน GSUB เต็มรูปแบบ นอกเหนือไปจากการจัดเรียงและการเชื่อมต่อ หากภาษาท้องถิ่นของอินเดียอยู่ในแผนงาน ให้ดำเนินการนำร่องจริงด้วยสตริงลูกค้าของแท้ก่อนที่คุณจะให้คำสัญญา — การที่ภาษาอาหรับทำงานได้ไม่ใช่หลักฐานว่าเทวนาครีจะทำงานได้ สตริง CJK ภาษาเวียดนามที่มีเครื่องหมายกำกับการออกเสียงซ้อนทับ และข้อความยุโรปผสมทั้งหมดใช้เส้นทางปกติที่ไม่มีการวิเคราะห์สองทิศทาง และมันคุ้มค่าที่จะแยกเส้นทางทั้งสองทางออกจากกันทางกายภาพในโค้ดรายงาน รูทีนหนึ่งสำหรับการรัน RTL และอีกรูทีนหนึ่งสำหรับอย่างอื่นทั้งหมด เพื่อให้ตรรกะของภาษาท้องถิ่นมองเห็นได้ที่ไซต์เรียกใช้งาน แทนที่จะซ่อนอยู่หลังแฟล็กที่ใครบางคนลืมตั้งค่า

ความครอบคลุมของ Glyph จะถูกตัดสินก่อนที่การจัดรูปแบบจะทำงานด้วยซ้ำ

การจัดรูปแบบจะเลือก glyph ออกจากฟอนต์ หากฟอนต์ไม่มี มันก็จะไม่มีอะไรให้เลือก ซึ่งเป็นสาเหตุที่ความล้มเหลวของการปรับใช้คลาสสิก — ไร้ที่ติบนเครื่องของนักพัฒนา กล่องเปล่าบนเซิร์ฟเวอร์ของลูกค้าหลังจากการแทนที่ฟอนต์อย่างเงียบๆ — เป็นปัญหาเรื่องความครอบคลุม ไม่ใช่ปัญหาการจัดรูปแบบ วิธีแก้ปัญหาในทางปฏิบัติ การลงทะเบียนฟอนต์ที่คุณจัดส่งมาให้แทนที่จะเชื่อถือฟอนต์ใดก็ตามที่เครื่องติดตั้งไว้ จะมีการอธิบายทีละขั้นตอนในบทความอ้างอิง ประเด็นทางแนวคิดคือความครอบคลุมจะต้องถูกกำหนดให้ชัดเจนก่อนที่คำถามเรื่องการจัดรูปแบบจะมีความหมาย และมันสามารถถูกกำหนดโดยใช้โปรแกรมได้แทนที่จะเป็นการกะด้วยสายตาจากผลลัพธ์

// After RegisterUnicodeTTF, audit coverage for the
// codepoints your data actually uses
GID := Pdf.GetUnicodeGlyphForCodepoint($0628);  // U+0628 ARABIC LETTER BEH
LogGlyphAudit($0628, GID);

การลงทะเบียนเองมีข้อจำกัดสองประการ — ขั้นต่ำ PDF 1.5 สำหรับการจัดการ Unicode ที่ฝังอยู่ และบิตอนุญาตการฝังของฟอนต์ — ทั้งคู่ครอบคลุมควบคู่กับขั้นตอนการตั้งค่าใน บทความอ้างอิง RtLTextOut สิ่งที่อยู่ในนี้คือพฤติกรรมการตรวจสอบ: GetUnicodeGlyphForCodepoint คือระบบเตือนล่วงหน้าของคุณ ตรวจสอบช่วงรหัสจุด (codepoint) ที่ข้อมูลของคุณใช้จริงเมื่อเริ่มต้นบริการ และบันทึกว่ารหัส glyph ใดส่งคืนมา ช่องว่างของความครอบคลุมจะแสดงเป็นบรรทัดในบันทึกการเริ่มต้นใช้งานระหว่างการเปิดตัว แทนที่จะเป็นตัวอักษรที่ขาดหายไปในใบแจ้งหนี้ที่ส่งถึงมือลูกค้าแล้ว

ลำดับการอ่านเป็นของเอกสาร ไม่ใช่ glyph

การทำให้ทุก glyph ถูกต้องยังคงเหลืออีกหนึ่งสิ่งที่ยังทำไม่เสร็จ ISO 32000-1 §12.2 กำหนดค่าการแสดงผลของโปรแกรมดูเอกสารที่เรียกว่า /Direction ซึ่งระบุลำดับการอ่านโดยรวมของเอกสาร มันไม่เกี่ยวกับ glyph เลย สิ่งที่มันทำคือบอกโปรแกรมดูว่าควรจัดรูปแบบการวางหน้าคู่ (two-up spread) อย่างไร เลย์เอาต์หน้าที่หันเข้าหากันควรเริ่มต้นจากด้านใด และ UI การอ่านควรเอียงไปทางไหน ทั้งหมดนี้ไม่แสดงบนหน้าเดียว ซึ่งเป็นเหตุผลที่มันมักถูกลืม

// Declare right-to-left reading order at the document level
Pdf.Direction := RightToLeft;  // adds vpDirection to ViewerPreferences

การตั้งค่า Direction คืองานทั้งหมด: ตัวตั้งค่าคุณสมบัติเพิ่ม vpDirection ไปยัง ViewerPreferences ของเอกสาร ดังนั้นรหัสบรรทัดเดียวก็จะนำความต้องการเข้าไปในไฟล์ หากข้อความถูกส่งออกผ่าน RtLTextOut คุณจะได้สิ่งนี้มาฟรีๆ เพราะการเรียกใช้จะพลิกทิศทางของเอกสารเป็นผลข้างเคียง — บทความอ้างอิงครอบคลุมถึงเวลาที่เอกสารแบบผสมจำเป็นต้องยกเลิกสิ่งนั้น กรณีที่คุณต้องตั้งค่าด้วยตนเองคือเอกสารขวาไปซ้ายที่ผลิตด้วยวิธีอื่น เช่น จากอินพุตที่คุณจัดรูปร่างไว้ก่อนล่วงหน้าต้นทาง และวาดผ่านเส้นทางปกติ ปล่อยมันทิ้งไว้และหลักฐานหน้าเดียวที่คุณจ้องมองจะดูเหมือนกันทั้งสองแบบ จากนั้นใครบางคนจะพิมพ์สมุดเล็กแบบหน้าหลัง และหน้าคู่ก็จะออกมาสลับซ้ายขวาแบบกระจกเงา และสาเหตุก็มาจากโค้ดบรรทัดเดียวที่หายไปตั้งแต่หลายสัปดาห์ก่อน

การตรวจสอบผลลัพธ์ที่จัดรูปแบบ

ตรวจสอบตั้งแต่ต้นจนจบ เพราะหน้าเอกสารอาจดูถูกต้องแต่ก็ยังใช้งานไม่ได้กับขั้นตอนหลังจากนั้น การตรวจสอบสามอย่างจะพบปัญหาส่วนใหญ่ คัดลอกข้อความกลับออกมาจาก Acrobat และเปรียบเทียบรหัสจุดกับสตริงต้นฉบับของคุณ เรียกใช้การค้นหาในเอกสารของโปรแกรมดูเอกสารสำหรับคำที่คุณมองเห็นบนหน้า และเปิดผลลัพธ์บนเครื่องที่ไม่มีฟอนต์สำหรับการพัฒนาของคุณ ซึ่งเป็นวิธีที่น่าจะเปิดเผยการทดแทนฟอนต์มากที่สุด ไม่มีสิ่งใดสามารถทดแทนการที่ผู้อ่านเจ้าของภาษาดูเอกสารจริงเพียงหนึ่งฉบับ ซึ่งจะจับข้อผิดพลาดที่ไม่มีคอร์ปัสสังเคราะห์ใดสามารถจับได้ นำการตรวจสอบนั้นลงปฏิทินก่อนที่รูปแบบจะถูกนำไปใช้งานจริง

เลือกสตริงทดสอบโดยตั้งใจแทนที่จะรีไซเคิลสิ่งที่นักแปลส่งมาเมื่อปีที่แล้ว สิ่งขั้นต่ำที่ใช้งานได้ต่อภาษาท้องถิ่น: ประโยคสคริปต์บริสุทธิ์ ประโยคที่ฝังชื่อแบรนด์ภาษาละติน บรรทัดที่มีตัวเลขและสกุลเงิน และชื่อที่มีเครื่องหมายกำกับการออกเสียงหรือเครื่องหมายผสม ชื่อลูกค้าจริงทำลายข้อสันนิษฐานที่ข้อความเติมเต็ม (filler text) ละทิ้งไว้ ดังนั้นปล่อยให้ชุดการทดสอบการถดถอย (regression set) เติบโตขึ้นทีละหนึ่งสตริงทุกครั้งที่กรณีสนับสนุนพบรูปแบบที่คุณไม่เคยเห็นมาก่อน

การลงทะเบียนฟอนต์ การจัดทำเซ็ตย่อย (subsetting) และ API การวาดข้อความทั่วไป ครอบคลุมอยู่ใน บทความเกี่ยวกับการส่งออกรายงาน ฟอนต์ และรูปภาพด้วย HotPDF เมื่อเอกสารเดียวกันต้องตรงตามโปรไฟล์การช่วยการเข้าถึง กฎการติดแท็กภาษาและโครงสร้างใน บทความการตรวจสอบความถูกต้อง PDF/A และ PDF/UA จะอยู่บนสุดของงานจัดรูปแบบที่นี่

API ฟอนต์แบบขวาไปซ้ายและ Unicode ที่อธิบายไว้ข้างต้นมีจัดส่งมาพร้อมกับ คอมโพเนนต์ HotPDF สำหรับ Delphi และ C++Builder; หน้าผลิตภัณฑ์มีลิงก์ไปยังอ้างอิงการส่งออกข้อความแบบเต็ม