Artikel Teknis

Pembentukan Teks Arab dan RTL dalam PDF Delphi dengan HotPDF

Teruskan frasa bahasa Arab يوضح ملف PDF ke TextOut dan buka hasilnya. Huruf-hurufnya berjalan ke arah yang salah, dan masing-masing berada dalam bentuk terisolasi dengan celah yang terlihat sebelum huruf berikutnya, seolah-olah seseorang mengetik bahasa Inggris secara terbalik dan menekan spasi di antara setiap karakter. Tidak ada pengecualian yang terjadi. Tidak ada peringatan yang dicetak. Keluarannya salah, dan salah karena dua transformasi terpisah yang menjadi sandaran bahasa Arab tidak pernah terjadi. Mengetahui apa kedua transformasi itu, dan panggilan mana yang melakukannya, adalah bagian terbesar dari keluaran PDF skrip kompleks

HotPDF adalah komponen VCL PDF asli untuk Delphi dan C++Builder, dan ini melakukan pekerjaan kanan-ke-kiri untuk Anda melalui panggilan yang berbeda. Ini juga berhenti di beberapa tempat spesifik yang ingin Anda ketahui sebelum melakukan lokal, jadi artikel ini memetakan konsep dan batasan jujurnya; penyiapan langsung untuk panggilan itu sendiri ada di artikel referensi RtLTextOut

Mengapa string yang benar masih dicetak salah

Unicode menyimpan teks dalam urutan logis, urutan Anda mengetiknya dan membacanya dengan lantang. Sebuah perender harus meletakkan mesin terbang dalam urutan visual. Untuk skrip kiri-ke-kanan pesanan tersebut bertepatan dan tidak ada yang memikirkannya. Untuk bahasa Arab dan Ibrani tidak, dan ketika satu baris mencampur arah, katakanlah kalimat bahasa Arab yang membawa token Latin "PDF" atau harga yang ditulis dalam angka, Algoritme Dua Arah Unicode (UAX #9) memutuskan dengan tepat bagaimana fragmen kiri-ke-kanan bersarang di dalam garis kanan-ke-kiri. Itu adalah transformasi pertama, penataan ulang, dan melewatkannya adalah hal yang membalikkan garis

Yang kedua adalah pembentukan kontekstual. Huruf Arab digambar secara berbeda tergantung di mana letaknya dalam sebuah kata: awal, tengah, akhir, atau berdiri sendiri. Titik kode tetap sama di seluruh bagian; hanya mesin terbang yang berubah. Sebuah alur yang menyerahkan setiap titik kode langsung ke mesin terbang bawaannya akan menghasilkan keluaran terputus dan berbentuk terisolasi secara tepat dari paragraf pembuka. Bahasa Ibrani melewati langkah ini, karena huruf-hurufnya tidak menyambung, tetapi masih memerlukan penataan ulang. Bahasa Arab membutuhkan keduanya, dan itulah mengapa bahasa Arab, bukan bahasa Ibrani, yang merupakan string pengujian Anda

Di desktop, semua ini bukanlah masalah Anda. Saat formulir VCL melukis bahasa Arab ke dalam TEdit, tumpukan teks sistem operasi secara diam-diam menyusun ulang dan membentuknya, yang merupakan alasan utama mengapa string yang terlihat sempurna di layar menjadi rusak di PDF naif. Aliran konten tidak menyimpan teks yang dapat diedit. Ia menyimpan mesin terbang yang diposisikan, sehingga siapa pun yang memancarkan aliran mewarisi pekerjaan pembentukan yang biasa ditangani OS. RtLTextOut adalah panggilan yang mengambil kembali pekerjaan tersebut

Apa yang dibentuk RtLTextOut untuk Anda

HotPDF menjaga jalur Latin dan jalur skrip kompleks sebagai dua metode berbeda. TextOut mencetak apa yang Anda berikan dalam urutan yang Anda berikan. RtLTextOut melakukan kedua transformasi terlebih dahulu — penataan ulang dua arah di seluruh baris, analisis kontekstual untuk skrip yang menggabungkan — lalu mencetak. Aturan skrip mana yang berlaku berjalan masuk melalui charset font alih-alih melalui panggilan itu sendiri, jadi arah adalah pilihan eksplisit di setiap situs panggilan, bukan tebakan yang dibuat dari karakter. Penyiapan parameter demi parameter, nilai charset, langkah pendaftaran font, dan contoh kompilasi lengkap semuanya ada di artikel referensi RtLTextOut; bagian ini tetap pada arti transformasi, di mana mereka berhenti, dan bagaimana membuktikan bahwa mereka berhasil

Satu aturan penggunaan penting bahkan pada ketinggian ini: masukan harus dalam urutan logis, karena RtLTextOut melakukan pembalikan itu sendiri, dan string yang telah Anda balikkan dengan tangan menjadi dibalik ganda — artikel referensi berjalan melalui jebakan itu dan pembersihannya. Apa yang membuat jebakan ini disebutkan di sini adalah mengapa jebakan itu lolos dari pengujian. String bahasa Arab murni yang dibalik ganda dapat terlihat sangat benar, dan hanya berantakan ketika sebuah baris membawa kata atau angka Latin, karena lintasan yang tertanam itu tidak lagi bersarang seperti yang ditentukan oleh UAX #9. Bugnya bukan pada rendering; bugnya ada pada saat memberikan teks algoritme yang sudah setengah diproses

Perilaku arah campuran yang sama membuat pengulas tersandung lebih dari sekadar membuat kode tersandung. Di dalam garis kanan-ke-kiri, angka dan kata-kata Latin yang disematkan masih dibaca dari kiri ke kanan. Seseorang yang belum bekerja dengan tata letak dua arah akan melihat faktur yang dirender, melihat nomor akun yang terbaca "salah" relatif terhadap bahasa Arab di sekitarnya, dan menuliskannya sebagai bug. Ini adalah hasil yang sesuai spesifikasi. Catatan singkat dalam kriteria penerimaan Anda, yang ditulis sebelum peninjauan penutur asli pertama, menghemat perjalanan bolak-balik tersebut

Kapan penataan ulang dan penggabungan sudah cukup, dan kapan tidak

Untuk teks berjalan bahasa Arab dan Ibrani — laporan, faktur, kontrak, surat — menata ulang plus penggabungan kontekstual adalah keseluruhan pekerjaan, dan RtLTextOut membawanya sendiri. Batas tersebut muncul ketika tipografi meminta lebih dari sekadar menggabungkan. Jawaban HotPDF pada sisi bahasa Arab adalah pembentuk sisi produsen keikutsertaan: tetapkan AutoShapeArabic := True dan komponen akan menulis ulang lintasan urutan logis ke Formulir Presentasi Unicode sebelum lintasan dua arah, jadi bentuk penyambung dihitung terhadap tetangga logis dan lipatan pengikat di-bake ke titik kode yang sebenarnya dibawa oleh PDF, alih-alih dibiarkan untuk diselesaikan oleh penampil. Sakelar tersebut default ke nonaktif dan keluaran menjadi byte-stable saat ia tetap nonaktif, jadi menyalakannya adalah keputusan yang disengaja per alur dokumen, bukan pemutakhiran global. Model opt-in yang sama meluas ke skrip penyambung kanan-ke-kiri lain yang dibentuk HotPDF: Suriah, N'Ko, Adlam, dan Hanifi Rohingya yang masing-masing memiliki bendera pembentuk otomatis sendiri yang mencerminkan bahasa Arab

Fitur OpenType opsional adalah mekanisme lain yang berbeda. Pengikat bebas dan fitur penggantian tunggal serupa melalui GetSingleSubstituteGlyph(GID, 'liga'), yang menyelesaikan satu substitusi dalam satu waktu — ID mesin terbang masukan pertama, tanda fitur kedua — dan mengembalikan mesin terbang masukan tidak berubah ketika fitur tidak berlaku. Ini cukup untuk menggerakkan daftar pengikat yang diketahui, terbatas yang Anda kelola sendiri. Ini bukan mesin GSUB penuh, dan perbedaannya adalah di mana rencana lokal yang ambisius salah: alur pembentukan yang menangani bahasa Arab dengan sempurna telah menunjukkan penataan ulang dan penggabungan, tidak lebih

Cakupan di seluruh skrip

Bahasa Arab menjalankan kedua transformasi, yang menjadikannya string yang digunakan untuk menguji, dan yang membuat lintasan bahasa Arab menjadi satu bagian bukti terkuat bahwa alur tersebut berfungsi. Bahasa Ibrani memerlukan penataan ulang tetapi bukan penyambungan, karena hurufnya berdiri sendiri; jika bahasa Ibrani ter-render dengan benar tetapi bahasa Arab muncul terputus, setengah bagian dua arahnya baik dan setengah bagian kontekstual tidak pernah berjalan. Persia dan Urdu mengendarai skrip Arab dan mewarisi perilakunya, meskipun preferensi Urdu untuk gaya Nastaliq adalah keputusan font dengan konsekuensi keterbacaan yang harus dinilai oleh pembaca asli

Thailand duduk di sisi lain garis sepenuhnya. Ia berjalan dari kiri ke kanan, jadi tidak memerlukan penataan ulang dua arah, dan huruf-hurufnya tidak menyambung, jadi tidak memerlukan analisis kontekstual; String Thailand melalui jalur TextOut biasa seperti Latin. Apa yang Thailand miliki adalah tanda bertumpuk — huruf vokal dan nada di atas dan di bawah konsonan dasar — dan apakah mereka duduk dengan benar bergantung pada font yang membangun tanda penggabungnya untuk ditumpuk tanpa bantuan mesin pembentuk. Kebanyakan font khusus Thailand melakukannya. Uji dengan font persis yang akan Anda sematkan, bukan yang mirip

Dewanagari dan keluarga India lainnya sejujurnya merupakan pemberhentian yang sulit. Tanda vokal mereka disusun ulang di sekitar kluster konsonan dan konjungsinya terbentuk melalui rantai substitusi yang bergantung pada konteks, yang merupakan wilayah GSUB penuh, di luar penataan ulang dan penggabungan. Jika lokal Indic ada di peta jalan, jalankan pilot nyata di string pelanggan asli sebelum Anda menjanjikannya — bahasa Arab berfungsi bukan merupakan bukti bahwa Dewanagari akan berfungsi. String CJK, bahasa Vietnam dengan diakritik bertumpuknya, dan campuran teks Eropa semuanya mengambil jalur biasa tanpa analisis dua arah, dan ada untungnya untuk memisahkan kedua jalur tersebut secara fisik dalam kode laporan, satu rutinitas untuk jalan RTL dan satu lagi untuk yang lainnya, sehingga logika lokal terlihat di tempat panggilan alih-alih disembunyikan di balik bendera yang seseorang lupa tetapkan

Cakupan mesin terbang diputuskan bahkan sebelum pembentukan berjalan

Pembentukan mengambil mesin terbang dari font. Jika font tidak membawanya, tidak ada yang bisa diambil, yang mana ini adalah alasan mengapa kegagalan penyebaran klasik — tanpa cela di mesin pengembang, kotak kosong di server pelanggan setelah penggantian font tanpa suara — merupakan masalah cakupan, bukan masalah pembentukan. Pengobatan praktis, mendaftarkan font yang Anda kirim alih-alih memercayai apa yang telah diinstal mesin, ditelusuri selangkah demi selangkah di artikel referensi. Poin konseptualnya adalah cakupan harus dibuat sebelum pertanyaan pembentukan bahkan bermakna, dan itu dapat dibuat secara terprogram alih-alih dengan mengamati keluaran

// Setelah RegisterUnicodeTTF, audit cakupan untuk
// codepoint yang sebenarnya digunakan data Anda
GID := Pdf.GetUnicodeGlyphForCodepoint($0628);  // U+0628 ARABIC LETTER BEH
LogGlyphAudit($0628, GID);

Pendaftaran itu sendiri membawa dua kendala — dasar PDF 1.5 untuk penanganan Unicode sematan dan bit izin penyematan font — keduanya dibahas bersama langkah penyiapan dalam artikel referensi RtLTextOut. Apa yang ada di sini adalah kebiasaan audit: GetUnicodeGlyphForCodepoint adalah sistem peringatan dini Anda. Berjalan di rentang titik kode yang sebenarnya digunakan oleh data Anda saat layanan dimulai dan catat ID mesin terbang apa yang kembali. Celah cakupan kemudian muncul sebagai garis dalam log startup selama peluncuran, bukan sebagai karakter yang hilang di dalam faktur yang sudah sampai ke pelanggan

Urutan pembacaan milik dokumen, bukan mesin terbang

Mendapatkan setiap mesin terbang yang benar masih menyisakan satu hal yang belum selesai. ISO 32000-1 §12.2 mendefinisikan preferensi penampil yang dipanggil /Direction yang menyatakan urutan pembacaan keseluruhan dokumen. Itu tidak menyentuh mesin terbang apa pun. Apa yang dilakukannya adalah memberi tahu penampil cara mengatur bentangan dua ke atas, sisi mana yang harus menjadi awal tata letak halaman berhadapan, dan ke arah mana UI membaca harus condong. Tak satu pun dari itu muncul pada satu halaman, yang merupakan alasan utama ia dilupakan

// Deklarasikan urutan bacaan kanan-ke-kiri di tingkat dokumen
Pdf.Direction := RightToLeft;  // menambahkan vpDirection ke ViewerPreferences

Mengatur Direction adalah seluruh pekerjaan: penyetel properti menambahkan vpDirection ke ViewerPreferences dokumen, sehingga satu baris membawa preferensi tersebut ke file. Jika teks tersebut keluar melalui RtLTextOut, Anda akan mendapatkannya secara gratis, karena panggilan membalik arah dokumen sebagai efek samping — artikel referensi mencakup kapan campuran dokumen mengharuskan tindakan itu dibatalkan. Kasus di mana Anda harus menyetelnya sendiri adalah ketika menghasilkan dokumen dari kanan-ke-kiri dengan cara apa pun, misalnya dari masukan yang sudah Anda bentuk sebelumnya dan Anda gambar melalui jalur biasa. Biarkan saja di luar sana dan hasil cetak percobaan satu halaman yang sedang Anda tatap tampak sama dengan dua cara; lalu seseorang mencetak buklet dupleks, bentangannya tampak tercerminkan, dan penyebabnya adalah hilangnya sebaris teks dari minggu lalu

Memverifikasi keluaran yang dibentuk

Verifikasi ujung ke ujung, karena sebuah halaman bisa terlihat benar dan tetap tidak berguna bagi segala sesuatu di hilirnya. Tiga pemeriksaan akan menemukan sebagian besar masalah. Salin teksnya kembali dari Acrobat dan bandingkan titik kode dengan string sumber Anda. Jalankan pencarian di dalam dokumen pada penampil untuk kata yang bisa Anda lihat di halaman. Dan buka keluaran pada mesin yang tidak memiliki font pengembangan Anda, yang kemungkinan besar akan menyingkap substitusi. Tak satu pun dari itu menggantikan pembaca asli yang melihat satu dokumen asli, yang dapat mendeteksi berbagai hal dengan corpus sintetik mana pun tak akan mampu mendeteksinya. Letakkan pratinjau itu pada kalender sebelum memformat rilis

Pilihlah rangkaian pengujian secara sengaja ketimbang memakai lagi apa pun yang dikirim penerjemah tahun lalu. Nilai minimal yang dapat dikerjakan di setiap lokal: kalimat skrip yang sesungguhnya, kalimat dengan sematan nama dagang Latin, sebaris kalimat berisikan bilangan dan mata uang, dan berbagai nama dengan tanda diakritik atau penggabung. Berbagai nama pelanggan asli menerobos batasan yang diandaikan yang tak terjamah oleh teks pengisi, maka biarkan seperangkat aturan itu perlahan bertumbuh mengikuti serangkaian kata setiap kali satu kasus rujukan beranjak ke pola yang belum terlihat sebelumnya

Pendaftaran font, setingkat demi setingkat, serta API penarikan teks sehari-hari dicakup dalam artikel tentang laporan keluaran, font, dan gambar-gambar dengan HotPDF. Kala mana dokumen yang sama juga harus memenuhi persyaratan profil aksesibilitas, pelabelan bahasa dan pembuatan kerangka aturan dalam artikel PDF/A dan divalidasi PDF/UA berpijak pada karya pengerjaan di sini

API tulisan tangan kanan-ke-kiri dan font Unicode yang diuraikan di atas dirilis bersamaan dengan Komponen HotPDF untuk Delphi dan C++Builder; halaman produk ini menautkan referensi laporan penarikan hasil cetak secara keseluruhan