Padėkite japonišką romaną puslapyje ir pirmas dalykas, kurį pastebėsite, yra tai, kad tekstas eina žemyn stulpelyje, o ne išilgai eilutės, ir kad stulpeliai slenka nuo dešiniojo lapo krašto į kairę. Ant to užaugusiam skaitytojui horizontalus tekstas atrodo šiek tiek šaltas. Inžinerinė problema yra ta, kad PDF, kaip ir beveik kiekviena skaitmeninio teksto sistema, buvo sukurta aplink horizontalią bazinę liniją, kuri auga iš kairės į dešinę, ir turinio srautas neturi supratimo „rašyti šią pastraipą žemyn“. Taigi, kai „Delphi“ programa turi sukurti sertifikatą, eilėraštį, iškabą ar tradicinio formato teisinį dokumentą Taivano, Japonijos ar Korėjos skaitytojui, išdėstymą tenka surinkti rankomis: vieną simbolį po kito, vieną stulpelį į kairę nuo ankstesnio
„HotPDF“ suteikia jums jungiklį, kuris už jus atlieka kiekvieno simbolio apskaitą. Jūsų nustatytas šriftas turi IsVertical vėliavėlę, ir kai ji įjungta, vienas TextOut iškvietimas sudeda visą eilutę į vertikalų stulpelį, o ne veda ją išilgai bazinės linijos. Stulpelio vieta, tvarka iš dešinės į kairę ir vienas tyliai svarbus glifų pakeitimas yra tai, ką toliau nagrinėjama šiame puslapyje

Jungiklis veikia „SetFont“
Vertikalus išdėstymas nėra puslapio ar dokumento savybė. Tai šrifto, su kuriuo piešiate, savybė, ir jūs ją įjungiate penktuoju SetFont argumentu:
// 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
Kadangi vėliavėlė priklauso nuo šrifto, tarp horizontalaus ir vertikalaus rašymo galite perjungti tiesiog vėl iškviesdami SetFont su kitu paskutiniu argumentu. Puslapis gali turėti horizontalų pavadinimą viršuje ir vertikalų pagrindinį tekstą po juo, o „HotPDF“ šiuos du režimus atskiria kiekvienam šrifto objektui, o ne puslapiui. Būtent tai įgalina mišrius išdėstymus be jokio specialaus režimo valdymo iš jūsų pusės: kiekvienas TextOut po vertikalaus SetFont kraunamas žemyn, kiekvienas TextOut po horizontalaus eina išilgai bazinės linijos, ir laimi paskutinis SetFont
Ketvirtasis argumentas yra „Windows“ simbolių rinkinys, tas pats, kurį priima horizontalus iškvietimas. Perduodant DEFAULT_CHARSET, sistema leidžia nustatyti glifus kiekvienai eilutei, o tai čia svarbu, nes vertikaliame dokumente dažnai maišomi rašmenys. Visa kita apie šriftą vis dar galioja: jis turi būti įdiegtas kūrimo įrenginyje, ir beveik visada norėsite FontEmbedding := True, kad failas atvaizduotų tuos pačius CJK glifus skaitytojui, kuris niekada neturėjo „Arial Unicode MS“
Vienas „TextOut“ iškvietimas yra vienas stulpelis
Kai aktyvus vertikalus šriftas, TextOut iškvietimas nebeskleidžia eilutės į šoną nuo nurodyto taško. Jis pasodina pirmąjį simbolį viršuje ir perkelia likusius tiesiai žemyn, su kiekvienu glifu žengdamas pagal šrifto eilutės aukštį. Jūsų perduodamas X nustato stulpelį; Jūsų perduodamas Y nustato, kur prasideda stulpelio viršus. Taigi, norėdami išdėstyti tikrą ištrauką, iškviečiate po vieną TextOut stulpeliui ir tarp iškvietimų žengiate su X į kairę, nes CJK stulpeliai skaitomi iš dešinės į kairę
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;
Eilėraštis skaitomas taip, kaip turėtų: pirmiausia dešiniausias stulpelis, iš viršaus į apačią, tada akis peršoka į kairę prie kito stulpelio. Pati eilutė tos tvarkos nešifruoja. Ją užkoduojate X koordinatėse, mažindami jas iškvietimas po iškvietimo. Supainiokite kryptį, ir eilės išeis atvirkštinės – tai yra pati dažniausia klaida, perkeliant horizontalų išdėstymą į vertikalų
Koordinatės: žemyn puslapiu, iš dešinės į kairę
Veikia dvi ašys, kurios traukia priešingomis kryptimis, todėl verta būti tiksliems. „HotPDF“ matuoja nuo apatinio kairiojo puslapio kampo, o Y didėja į viršų, taškais. Taigi vertikalus stulpelis prasideda nuo aukšto Y (netoli lapo viršaus), ir simboliai leidžiasi nuo ten, nes „HotPDF“ atima eilutės aukštį kiekvienam iš jų. Nustatote tą pradinį Y kartą stulpeliui, o komponentas susitvarko su nusileidimu
Horizontaliąją ašį valdote rankiniu būdu. Kiekvienas stulpelis yra ant savo X, o paskesni stulpeliai žengia prie mažesnių X reikšmių, nes skaitymo tvarka yra iš dešinės į kairę. Protingas ritmas yra pasirinkti dešiniausio stulpelio X, tada iš kiekvieno paskesnio iškvietimo atimti fiksuotą stulpelių tarpą, kaip pavyzdyje su ColGap. Tarpą galite pasirinkti patys; per siauras, ir gretimi stulpeliai susilies, per laisvas, ir blokas atrodys retas. Pagrindiniam 12–18 taškų tekstui patogiai skaitomas tarpas, kuris yra šiek tiek didesnis už šrifto dydį
Glifai, kurie turi pakeisti formą
Keli simboliai nėra tiesiog pasuktos jų horizontalių versijų kopijos; jie turi būti pakeisti, kai tekstas tampa vertikalus. Vienas iš jų, kurį „HotPDF“ apdoroja už jus, yra japonų prailginto garso ženklas ー (U+30FC), ilgojo balsio brūkšnelis, kuris atsiranda tokiuose katakanos žodžiuose kaip コーヒー. Nubrėžtas horizontaliai, tai trumpas brūkšnys ant bazinės linijos. Jei tą patį glifą sukrautumėte į stulpelį, jis gulėtų horizontaliai per stulpelį, kas yra neteisinga: vertikalioje japonų kalboje ženklas tampa vertikaliu brūkšniu, jungiančiu du simbolius, tarp kurių jis stovi. „HotPDF“ aptinka U+30FC vertikaliame kelyje ir atvaizduoja jį kaip vertikalų brūkšnį (U+007C), todėl ilgojo balsio ženklas rodo į teisingą pusę be jokio jūsų įsikišimo
Šis vienas pakeitimas apima atvejį, kuris sulaužo daugumą naivių realizacijų, bet verta žinoti, kur bendroji problema yra gilesnė. Pilna vertikali tipografija taip pat pasuka lotyniškas raides ir vakarietišką skyrybą devyniasdešimt laipsnių kampu, perkelia mažas kanas, ir perkelia skliaustus bei kablelius į jų vertikalias formas, ir visiškas to įgyvendinimas slypi šrifto „OpenType“ vertikaliose ypatybėse, o ne fiksuotose taisyklėse. „HotPDF“ gali naudoti šias ypatybes, kai šriftas jas turi: vertikalios alternatyvos (vert ir vrt2 GSUB ypatybės) ir vertikalus kerningas (vkrn ir vpal GPOS paieškos) pasirenkami savanoriškai, pritaikomi palei vertikalų kelią tik tada, kai aktyvus šriftas jas faktiškai apibrėžia. Mišriam CJK tekstui, turinčiam vieną plataus aprėpimo šriftą, pvz., „Arial Unicode MS“, integruotas U+30FC tvarkymas ir tolygus eilutės aukščio žingsnis yra pakankami, kad būtų gauti teisingi, skaitomi stulpeliai; „OpenType“ ypatybės tampa svarbios tada, kai pereinate prie šrifto, sukurto smulkiam vertikaliam nustatymui ir norite, kad jo vietinė kana pozicionuotų ir būtų tarpai tarp glifų
Skirtingų rašmenų ir orientacijų maišymas viename puslapyje
Tikri dokumentai retai būna gryni. Vertikaliame japonų puslapyje gali būti horizontali angliška antraštė, puslapio numeris apačioje arba korėjietiškas tekstas, išdėstytas vertikaliai šalia japoniško. Kadangi vertikali vėliavėlė yra šrifto lygio jungiklis, šiuos elementus sukomponuojate pakaitomis iškviesdami SetFont, o ne valdydami kokią nors viso puslapio būseną. Nustatykite horizontalų šriftą, įrašykite puslapio antraštę ir puslapio numerį, nustatykite vertikalų šriftą, išdėstykite stulpelius, vėl nustatykite horizontalų šriftą poraštei. Kiekvienas regionas paima paskutinio SetFont režimą, todėl vienintelė reikalinga disciplina yra iškviesti jį kaskart pakeitus kryptį
Viena detalė, kurią reikia suplanuoti sumaišius rašmenis: kinų, japonų ir korėjiečių ideogramos yra artimos kvadratui ir kraunamos vienodu žingsniu, tačiau lotyniškas tekstas, įterptas vertikaliame stulpelyje, neturi to vienodo poslinkio. Jei kitaip vertikaliame tekste jums reikia kelių lotyniškų žodžių, sąmoningai nuspręskite, ar jie turėtų būti pasukti, kad eitų stulpeliu žemyn, ar išdėstyti vertikaliai kaip trumpas horizontalus įdėklas, ir padėkite tą fragmentą su atskiru TextOut, užuot leidę jam vykti kartu su ideogramoms skirtu vertikaliu žingsniu. Jei mišrų tekstą traktuosite kaip atskirą vietos nustatymo problemą, stulpelio ritmas išliks nepakitęs
Nuo pavyzdžio iki gamybos
Dalys yra mažos ir susideda nuspėjamai. Įjunkite vertikalią vėliavėlę SetFont, iškvieskite vieną TextOut stulpeliui nuo fiksuoto viršutinio Y ir mažinkite X tarp iškvietimų, kad stulpeliai būtų skaitomi iš dešinės į kairę. Įterpkite šriftą, kad CJK glifai išgyventų kelionę į skaitytojo įrenginį, ir leiskite komponentui tvarkyti U+30FC ilgojo balsio ženklą ir, kur šriftas jas palaiko, „OpenType“ vertikalias ypatybes. Nuo ten išdėstymo gamyba daugiausia yra aritmetika: stulpelių X padėties išvedimas iš išmatuoto bloko pločio, ilgų ištraukų skaidymas į stulpelius, kurie atitinka puslapio aukštį, ir vietos rezervavimas horizontalioms antraštėms ir puslapių numeriams
Apie platesnį teksto ir šrifto paviršių, kuriuo tai remiasi, įskaitant horizontalių TextOut taisykles ir „Unicode“ šriftų registraciją, žr. daugiakalbį „Hello World“ pavyzdį ir „TextOut“ pavyzdį. Vertikalus SetFont jungiklis ir čia rodomi TextOut iškvietimai yra „HotPDF“ komponento, skirto „Delphi“ ir „C++Builder“, dalis