Kirim kalimat Arab يوضح ملف PDF هذا ke TextOut biasa dan halaman yang dikembalikan salah dalam dua cara sekaligus. Kata-kata berjalan dari kiri ke kanan alih-alih kanan ke kiri, dan huruf-huruf berdiri terpisah dalam bentuk terisolasi alih-alih bergabung menjadi kata-kata yang terhubung. Tidak ada error. Delphi berhasil dikompilasi, file terbuka, dan seorang peninjau yang membaca bahasa Arab memberi tahu Anda bahwa keluarannya tidak bisa digunakan. Solusinya adalah satu pemanggilan, bukan penggantian pustaka: HotPDF merutekan teks kanan-ke-kiri melalui metode terpisah, RtLTextOut, yang menangani pengurutan ulang yang tidak dilakukan TextOut biasa. Empat hal tentang metode tersebut menentukan apakah keluarannya dapat digunakan: apa yang dilakukannya pada string, cara argumen charset-nya memilih skrip, perubahan tingkat dokumen yang dibuatnya sebagai efek samping, dan pekerjaan font yang harus dilakukan lebih dulu
RtLTextOut tetap memakai sistem koordinat halaman yang sama, dengan origin kiri-bawah dan Y bertambah ke atas. Method ini mengubah urutan glyph, bukan posisi origin; Text harus diberikan dalam urutan logis, sementara overload buffer menerima data UTF-16 dengan jumlah code unit eksplisit
Mengapa kanan-ke-kiri membutuhkan pemanggilan tersendiri
Aliran konten PDF tidak menyimpan teks yang bisa diedit. Ia menyimpan glyph pada posisi tetap, yang berarti apa pun yang memancarkan aliran memiliki tugas untuk memutuskan urutan penempatan glyph tersebut. Di layar sistem operasi melakukan itu untuk Anda: masukkan bahasa Arab ke TEdit dan tumpukan teks OS menyusun ulang dan menggabungkan sebelum Anda pernah melihat satu piksel pun. Itulah tepatnya mengapa string terlihat sempurna di form Anda dan rusak dalam PDF. Desktop melakukan pekerjaan itu secara diam-diam, dan begitu Anda menulis aliran konten Anda sendiri, pekerjaannya kembali ke sisi Anda
TextOut mengambil Anda pada kata-kata Anda. Ia menggambar codepoint dalam urutan yang Anda berikan, dari kiri ke kanan, yang benar untuk Latin, Sirilik, dan CJK serta salah untuk Arab dan Ibrani. RtLTextOut adalah pemanggilan yang menyusun ulang baris ke urutan visual kanan-ke-kiri terlebih dahulu, lalu menggambar. HotPDF dengan sengaja memisahkan dua metode tersebut daripada menebak arah dari karakter, sehingga pilihan pemanggilan mana yang digunakan adalah pilihan perilaku skrip mana yang Anda dapatkan. Mekanik yang lebih dalam dari pengurutan ulang bidireksional dan penggabungan kontekstual Arab adalah subjek tersendiri, yang dibahas dalam artikel tentang pembentukan teks Arab dan RTL dengan HotPDF; di sini poin praktisnya lebih sempit. Gunakan RtLTextOut untuk run kanan-ke-kiri, gunakan TextOut untuk segalanya yang lain, dan jangan pernah merutekan satu melalui yang lain

Argumen charset menentukan skrip
Yang memberi tahu RtLTextOut apakah ia menata Arab atau Ibrani bukan metodenya, melainkan font. SetFont mengambil charset Windows sebagai argumen keempatnya, dan nilai tersebut membawa aturan skrip ke dalam pemanggilan kanan-ke-kiri: 178 memilih Arab, 177 memilih Ibrani. Atur charset, lalu gambar, dan dua baris di bawah ini keluar dalam urutan baca yang benar tanpa konfigurasi lebih lanjut
// Arabic: charset 178 tells RtLTextOut to apply Arabic rules
Pdf.CurrentPage.SetFont('Arial Unicode MS', [], 12, 178);
Pdf.CurrentPage.RtLTextOut(400, 700, 0, 'يوضح ملف PDF هذا');
// Hebrew: charset 177 switches the rules to Hebrew
Pdf.CurrentPage.SetFont('Arial Unicode MS', [], 12, 177);
Pdf.CurrentPage.RtLTextOut(400, 660, 0, 'קובץ PDF זה');
Dua detail tentang koordinat tersebut mudah diabaikan. Posisi yang Anda berikan masih merupakan awal run dalam sistem koordinat halaman sendiri, diukur dari sudut kiri bawah dengan Y tumbuh ke atas, origin yang sama yang digunakan setiap TextOut; RtLTextOut mengubah urutan glyph, bukan tempat halaman mengukur. Dan seperti pemanggilan gambar apa pun, SetFont harus datang lebih dulu dan harus diulang setelah setiap AddPage, karena font saat ini tidak bertahan melewati jeda halaman. Lupa mengulang dan halaman kedua kembali ke font apa pun yang aktif, yang untuk bahasa Arab biasanya berarti kotak kosong
Ini tidak membalik teks yang sudah Anda balik
Kesalahan tunggal yang paling banyak menghabiskan waktu debugging di sini adalah memberi RtLTextOut string yang sudah Anda balik secara manual. Orang mencapai metode ini setelah percobaan pertama dengan TextOut biasa keluar terbalik, dan solusi sementara yang umum adalah membalik karakter dalam kode sebelum menggambar. RtLTextOut membalik secara internal sendiri, sehingga string yang sudah dibalik sebelumnya dibalik kedua kali dan mendarat kembali di tempat semula. Berikan teks dalam urutan logis, urutan yang akan Anda ketik dan baca dengan keras, dan biarkan pemanggilan melakukan pengurutan ulang
Jebakannya lebih buruk dari pembalikan biasa karena string yang dibalik ganda bisa terlihat benar untuk satu frasa uji murni-Arab dan kemudian rusak begitu baris membawa kata Latin atau angka. Di dalam baris kanan-ke-kiri, run yang disematkan tersebut seharusnya terbaca dari kiri ke kanan, dan pembalikan manual merusak nesting itu sementara kasus murni-Arab kebetulan bertahan. Jadi bug itu lolos dari uji asap pertama Anda dan muncul kemudian pada faktur nyata dengan nomor akun di dalamnya. Hapus setiap pembalikan manual begitu Anda beralih ke RtLTextOut
Efek samping Direction yang perlu diketahui
Memanggil RtLTextOut mengubah lebih dari sekadar baris yang sedang Anda gambar. Ini juga membalik preferensi arah baca dokumen ke kanan-ke-kiri, hal yang sama yang akan Anda atur sendiri melalui properti Direction. Setter tersebut menambahkan vpDirection ke ViewerPreferences dokumen, yang memberi tahu penampil cara menyusun spread dua halaman dan sisi mana tata letak halaman berhadapan dimulai. Ketika seluruh dokumen adalah Arab atau Ibrani, ini persis yang Anda inginkan, dan Anda mendapatkannya secara gratis
Ini layak diketahui justru karena tidak terlihat pada satu halaman. Jika dokumennya sebagian besar kiri-ke-kanan dengan satu blok kanan-ke-kiri, pemanggilan RtLTextOut pertama tetap akan membalik preferensi seluruh file, dan tidak ada dalam bukti satu halaman Anda yang akan menunjukkannya. Gejala muncul berminggu-minggu kemudian ketika seseorang mencetak buklet dupleks dan spread keluar terbalik. Jika itu bukan yang Anda inginkan, atur Direction kembali secara eksplisit setelah run kanan-ke-kiri:
// RtLTextOut already set the document direction to RightToLeft;
// restore left-to-right if the document is predominantly LTR
Pdf.Direction := LeftToRight;
Untuk dokumen yang benar-benar dibaca kanan-ke-kiri, biarkan saja. Poinnya adalah mengetahui bahwa pemanggilan memiliki efek seluruh dokumen agar kejutan buklet tidak pernah terjadi
Daftarkan font yang Anda kirim, bukan yang Anda harap sudah terinstal
Tidak ada pengurutan ulang yang berarti jika font tidak memiliki glyph untuk digambar. Kegagalan klasik adalah laporan yang dirender dengan sempurna di mesin pengembang, di mana Arial Unicode MS kebetulan ada, dan keluar sebagai baris kotak kosong di server pelanggan di mana Windows diam-diam mengganti font tanpa cakupan Arab sama sekali. Solusinya adalah berhenti mempercayai font sistem yang terinstal dan mendaftarkan satu yang Anda kirim bersama aplikasi
// Ship a known Arabic font and register it before drawing
Pdf.RegisterUnicodeTTF('C:\Fonts\NotoSansArabic.ttf');
Pdf.CurrentPage.SetFont('NotoSansArabic', [], 12, 178);
Pdf.CurrentPage.RtLTextOut(400, 700, 0, 'يوضح ملف PDF هذا');
Dua batasan menyertai pendaftaran. Font yang dibawa melalui RegisterUnicodeTTF disematkan, dan penanganan Unicode tertanam HotPDF memerlukan dokumen pada PDF 1.5 atau lebih baru; itu hanya menggigit jika sesuatu di hilir bersikeras pada PDF 1.4, tetapi ketika itu terjadi kegagalannya diam. Yang lainnya bersifat legal daripada teknis: file TrueType membawa bit izin penyematan, dan tampilan muka yang terlihat baik di layar bisa dilisensikan dengan cara yang melarang pengirimannya di dalam dokumen pelanggan. Konfirmasikan lisensi sebelum Anda menyematkan, bukan setelah ada keluhan
Contoh konsol lengkap
Menyatukan bagian-bagiannya, berikut adalah program mandiri yang menulis satu halaman dengan baris Arab, baris Ibrani, dan baris campuran yang membawa nama produk Latin. Setiap blok mengatur charset-nya, lalu menggambar dalam urutan logis
program RtLTextOutDemo;
{$APPTYPE CONSOLE}
uses
HPDFDoc; // HotPDF main unit
var
Pdf: THotPDF;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.FileName := 'RtLTextOut.pdf';
Pdf.BeginDoc;
// A Latin heading goes through the ordinary TextOut path
Pdf.CurrentPage.SetFont('Arial', [fsBold], 16);
Pdf.CurrentPage.TextOut(40, 780, 0, 'Right-to-left text with HotPDF');
// Arabic: charset 178, logical order, RtLTextOut does the reordering
Pdf.CurrentPage.SetFont('Arial Unicode MS', [], 12, 178);
Pdf.CurrentPage.RtLTextOut(400, 720, 0,
'يوضح ملف PDF هذا كيفية التعامل مع النص العربي.');
// Hebrew: charset 177
Pdf.CurrentPage.SetFont('Arial Unicode MS', [], 12, 177);
Pdf.CurrentPage.RtLTextOut(400, 680, 0,
'קובץ PDF זה מדגים טקסט עברי הזורם מימין לשמאל.');
// Mixed line: the embedded Latin word still reads left to right
Pdf.CurrentPage.SetFont('Arial Unicode MS', [], 12, 178);
Pdf.CurrentPage.RtLTextOut(400, 640, 0,
'مرحبا بالعالم! تم إنشاؤه بواسطة HotPDF');
Pdf.EndDoc;
Writeln('Wrote RtLTextOut.pdf');
finally
Pdf.Free;
end;
end.
Jalankan dan buka hasilnya. Baris Arab dan Ibrani terbaca dari kanan ke kiri, huruf-huruf bergabung di tempat skrip menggabungkan, dan di baris terakhir token HotPDF duduk dari kiri ke kanan di dalam run Arab, yang merupakan hasil yang benar sesuai spesifikasi meskipun mengejutkan siapa saja yang melihat tata letak bidireksional untuk pertama kalinya. Poin terakhir itu layak ditulis dalam kriteria penerimaan Anda sebelum pembaca asli meninjau keluaran, karena run yang disematkan membaca dengan cara "salah" relatif terhadap skrip sekitarnya adalah satu hal yang paling sering dilaporkan sebagai bug padahal sebenarnya bukan
Memverifikasi keluaran
Halaman yang terlihat benar bukan berarti halaman yang benar, jadi periksa seperti cara sistem hilir akan melakukannya. Salin teks kembali dari penampil dan bandingkan codepoint dengan string sumber Anda; urutan visual yang benar dengan urutan logis yang acak adalah mode kegagalan nyata. Jalankan pencarian dalam dokumen penampil untuk kata yang bisa Anda lihat di halaman. Lalu buka file di mesin yang tidak memiliki font pengembang Anda, yang paling mungkin mengekspos substitusi diam. Tidak ada yang menggantikan pembicara asli membaca satu dokumen asli, yang menangkap masalah yang tidak akan ditangkap string uji sintetis mana pun, jadi jadwalkan tinjauan tersebut di kalender sebelum format dikirim
RtLTextOut menangani pengurutan ulang bidireksional dan penggabungan kontekstual Arab, yang mencakup sebagian besar pekerjaan laporan dan dokumen kanan-ke-kiri. Di mana ia berhenti, skrip yang membutuhkan lebih dari sekadar pengurutan ulang dan penggabungan seperti keluarga Indic, dan fitur OpenType opsional yang melalui substitusi glyph tunggal, dipetakan bersama detail cakupan glyph dan pembentukan dalam artikel pendamping tentang pembentukan teks Arab dan RTL dengan HotPDF
Pemanggilan RtLTextOut, SetFont, dan RegisterUnicodeTTF yang ditampilkan di sini adalah bagian dari HotPDF Component untuk Delphi dan C++Builder