Tata letak novel Jepang di atas halaman menunjukkan bahwa teks mengalir ke bawah kolom, bukan melintasi baris, dan kolom-kolom tersebut bergerak dari tepi kanan lembaran menuju kiri. Pembaca yang terbiasa dengan format ini akan merasa teks horizontal terasa agak asing. Masalah teknisnya adalah bahwa PDF, seperti hampir semua sistem teks digital, dibangun di sekitar garis dasar horizontal yang tumbuh dari kiri ke kanan, dan aliran konten tidak memiliki konsep "tulis paragraf ini ke bawah sebagai ganti." Maka ketika aplikasi Delphi harus menghasilkan sertifikat, puisi, papan tanda, atau dokumen hukum berformat tradisional untuk pembaca Taiwan, Jepang, atau Korea, tata letak harus dirakit secara manual: satu karakter di bawah berikutnya, satu kolom di sebelah kiri yang terakhir
HotPDF menyediakan sakelar yang menangani pembukuan per karakter untuk Anda. Font yang Anda atur membawa bendera IsVertical, dan setelah diaktifkan, satu panggilan TextOut menyusun seluruh string menjadi kolom vertikal alih-alih menjalankannya sepanjang garis dasar. Penempatan kolom, urutan kanan-ke-kiri, dan satu substitusi glif yang penting adalah hal-hal yang akan dibahas di halaman ini

Sakelar ada pada SetFont
Tata letak vertikal bukan merupakan properti halaman atau dokumen. Ini adalah properti font yang Anda gunakan untuk menggambar, dan Anda mengaktifkannya dengan argumen kelima dari SetFont:
// SetFont(FontName, FontStyle, Size, FontCharset, IsVertical)
// The 5th argument flips the current font into vertical mode.
Pdf.CurrentPage.SetFont('Arial Unicode MS', [], 12, DEFAULT_CHARSET, False); // horizontal
Pdf.CurrentPage.SetFont('Arial Unicode MS', [], 12, DEFAULT_CHARSET, True); // vertical
Karena bendera tersebut melekat pada font, Anda beralih antara penulisan horizontal dan vertikal cukup dengan memanggil SetFont lagi dengan argumen terakhir yang berbeda. Sebuah halaman dapat memuat judul horizontal di bagian atas dan teks isi vertikal di bawahnya, dan HotPDF memisahkan kedua mode tersebut per objek font daripada per halaman. Itulah yang membuat tata letak campuran menjadi mungkin tanpa penanganan mode khusus di pihak Anda: setiap TextOut setelah SetFont vertikal akan menumpuk, setiap TextOut setelah yang horizontal akan berjalan sepanjang garis dasar, dan SetFont terakhir yang berlaku
Argumen keempat adalah set karakter Windows, sama seperti yang digunakan panggilan horizontal. Meneruskan DEFAULT_CHARSET membiarkan sistem menyelesaikan glif per string, yang penting di sini karena dokumen vertikal sering mencampur skrip. Semua hal lain tentang font tetap berlaku: font harus terpasang di mesin build, dan Anda hampir selalu menginginkan FontEmbedding := True agar file merender glif CJK yang sama pada pembaca yang tidak pernah memiliki Arial Unicode MS
Satu panggilan TextOut adalah satu kolom
Dengan font vertikal aktif, panggilan TextOut tidak lagi menyebarkan stringnya ke samping dari titik yang diberikan. Ia menempatkan karakter pertama di bagian atas dan menjalankan sisanya lurus ke bawah, maju sebesar tinggi baris font untuk setiap glif. X yang Anda teruskan menetapkan kolom; Y yang Anda teruskan menetapkan tempat bagian atas kolom dimulai. Untuk menata letak sebuah teks sungguhan, Anda menerbitkan satu TextOut per kolom dan melangkah X ke kiri di antara panggilan, karena kolom CJK dibaca dari kanan ke kiri
var
Pdf: THotPDF;
const
ColTop = 760; // y of the first glyph in every column (points)
ColGap = 28; // horizontal distance between columns
begin
Pdf := THotPDF.Create(nil);
try
Pdf.FileName := 'VerticalText.pdf';
Pdf.FontEmbedding := True; // embed the CJK face for portable rendering
Pdf.BeginDoc;
Pdf.CurrentPage.Size := psA4;
// A horizontal heading first, in the ordinary writing mode.
Pdf.CurrentPage.SetFont('Arial Unicode MS', [], 16, DEFAULT_CHARSET, False);
Pdf.CurrentPage.TextOut(60, 800, 0, 'Tang poem, vertical layout');
// Switch the font into vertical mode; every TextOut below now stacks.
Pdf.CurrentPage.SetFont('Arial Unicode MS', [], 18, DEFAULT_CHARSET, True);
// Columns advance right to left, so X decreases with each call.
Pdf.CurrentPage.TextOut(520, ColTop, 0, '床前明月光');
Pdf.CurrentPage.TextOut(520 - ColGap, ColTop, 0, '疑是地上霜');
Pdf.CurrentPage.TextOut(520 - ColGap * 2, ColTop, 0, '舉頭望明月');
Pdf.CurrentPage.TextOut(520 - ColGap * 3, ColTop, 0, '低頭思故鄉');
Pdf.EndDoc;
finally
Pdf.Free;
end;
end;
Puisi tersebut terbaca sebagaimana mestinya: kolom paling kanan terlebih dahulu, dari atas ke bawah, kemudian mata bergerak ke kiri ke kolom berikutnya. Tidak ada yang di dalam string itu sendiri yang mengodekan urutan tersebut. Anda mengodekannya dalam koordinat X, menurunkannya dari panggilan ke panggilan. Membalik arah dan bait puisi akan keluar terbalik, yang merupakan kesalahan paling umum saat memindahkan tata letak horizontal ke vertikal
Koordinat: turun halaman, kanan ke kiri
Dua sumbu berperan dan keduanya menarik ke arah yang berlawanan, jadi ada baiknya untuk bersikap tepat. HotPDF mengukur dari sudut kiri bawah halaman, dengan Y bertambah ke atas, dalam poin. Oleh karena itu kolom vertikal dimulai pada Y yang tinggi (dekat bagian atas lembar) dan karakter-karakter turun dari sana saat HotPDF mengurangi tinggi baris untuk masing-masing karakter. Anda menetapkan Y awal tersebut sekali per kolom dan komponen menangani penurunannya
Sumbu horizontal adalah yang Anda kendalikan secara manual. Setiap kolom berada pada X-nya sendiri, dan kolom-kolom berikutnya melangkah ke nilai X yang lebih kecil karena urutan membaca adalah dari kanan ke kiri. Irama yang masuk akal adalah memilih X kolom paling kanan, kemudian mengurangi jarak kolom tetap untuk setiap panggilan berikutnya, seperti yang dilakukan contoh dengan ColGap. Jarak tersebut terserah Anda; terlalu sempit dan kolom yang berdekatan akan bersentuhan, terlalu lebar dan blok akan terlihat jarang. Untuk teks isi pada 12 hingga 18 poin, jarak sedikit lebih besar dari ukuran font terasa nyaman dibaca
Glif yang harus mengubah bentuk
Beberapa karakter tidak sekadar salinan berputar dari bentuk horizontalnya; karakter tersebut harus disubstitusi ketika teks berubah menjadi vertikal. Yang ditangani HotPDF untuk Anda adalah tanda suara panjang bahasa Jepang ー (U+30FC), bilah vokal panjang yang muncul dalam kata katakana seperti コーヒー. Digambar secara horizontal, tanda ini berupa garis pendek pada garis dasar. Jika glif yang sama ditumpuk ke dalam kolom, ia akan berbaring melintang di kolom, yang tidak benar: dalam bahasa Jepang vertikal, tanda ini menjadi goresan vertikal yang menghubungkan dua karakter di sekitarnya. HotPDF mendeteksi U+30FC di jalur vertikal dan merender sebagai bilah vertikal (U+007C) sehingga tanda vokal panjang menunjuk ke arah yang benar tanpa kerja tambahan dari Anda
Substitusi tunggal tersebut mencakup kasus yang memecahkan sebagian besar implementasi naif, tetapi ada baiknya mengetahui seberapa jauh masalah umum ini berlanjut. Tipografi vertikal penuh juga memutar huruf Latin dan tanda baca Barat sembilan puluh derajat, menggeser kana kecil, dan memposisikan ulang tanda kurung dan koma ke bentuk vertikalnya, dan implementasi lengkap dari hal itu terletak pada fitur vertikal OpenType font daripada aturan tetap. HotPDF dapat memanfaatkan fitur-fitur tersebut ketika font mendukungnya: alternat vertikal (fitur GSUB vert dan vrt2) dan kerning vertikal (lookup GPOS vkrn dan vpal) bersifat opt-in, diterapkan di sepanjang jalur vertikal hanya ketika font aktif benar-benar mendefinisikannya. Untuk teks CJK campuran dalam font dengan cakupan luas seperti Arial Unicode MS, penanganan U+30FC bawaan ditambah langkah tinggi baris yang seragam sudah cukup untuk menghasilkan kolom yang benar dan mudah dibaca; fitur OpenType penting ketika Anda beralih ke font yang dirancang untuk pengaturan vertikal yang halus dan menginginkan posisi kana asli serta jarak antar glif
Mencampur skrip dan orientasi dalam satu halaman
Dokumen nyata jarang bersifat murni. Halaman Jepang vertikal mungkin memuat keterangan gambar dalam bahasa Inggris horizontal, nomor halaman di bagian bawah, atau blok bahasa Korea yang diatur secara vertikal di sebelah Jepang. Karena bendera vertikal adalah sakelar tingkat font, Anda menyusunnya dengan bergantian memanggil SetFont alih-alih mengelola status lebar halaman. Atur font horizontal, tulis header dan folio yang sedang berjalan, atur font vertikal, susun kolom, atur font horizontal lagi untuk footer. Setiap wilayah mengambil mode dari SetFont terbaru, sehingga satu-satunya disiplin yang diperlukan adalah memanggilnya setiap kali Anda mengubah arah
Satu detail yang perlu direncanakan saat skrip bercampur: ideograf Tionghoa, Jepang, dan Korea hampir berbentuk persegi dan tersusun dengan langkah yang sama, tetapi teks Latin yang disematkan dalam kolom vertikal tidak memiliki kemajuan yang seragam tersebut. Jika Anda memerlukan beberapa kata Latin di dalam teks yang sebagian besar vertikal, putuskan secara sengaja apakah kata tersebut harus diputar untuk mengalir ke bawah kolom atau diatur tegak sebagai sisipan horizontal pendek, dan posisikan fragmen tersebut dengan TextOut-nya sendiri daripada membiarkannya mengikuti langkah vertikal yang dimaksudkan untuk ideograf. Memperlakukan teks campuran sebagai masalah penempatan tersendiri menjaga ritme kolom tetap utuh
Dari contoh ke produksi
Bagian-bagiannya kecil dan tersusun secara dapat diprediksi. Aktifkan bendera vertikal di SetFont, terbitkan satu TextOut per kolom dari Y atas yang tetap, dan kurangi X antar panggilan agar kolom dibaca dari kanan ke kiri. Sematkan font agar glif CJK bertahan hingga ke mesin pembaca, dan biarkan komponen menangani tanda vokal panjang U+30FC dan, jika font mendukungnya, fitur vertikal OpenType. Dari sana, memproduksi tata letak menjadi sebagian besar aritmetika: menurunkan posisi X kolom dari lebar blok yang diukur, memecah bagian panjang menjadi kolom yang sesuai dengan tinggi halaman, dan menyisihkan ruang untuk header dan folio horizontal
Untuk permukaan teks dan font yang lebih luas yang menjadi fondasi ini, termasuk konvensi TextOut horizontal dan pendaftaran font Unicode, lihat contoh Hello World multibahasa dan contoh TextOut. Sakelar vertikal SetFont dan panggilan TextOut yang ditunjukkan di sini adalah bagian dari HotPDF Component untuk Delphi dan C++Builder