PDFlibPas tekent Japanse en Chinese tekst langs de pagina naar beneden. SetVerticalWritingMode zet verticaal schrijven aan, gewone DrawText-aanroepen lopen dan naar beneden, en GetVerticalWritingMode rapporteert de huidige staat. Voordat dit bestond, betekende tekst verticaal zetten elk teken met de hand plaatsen en hopen dat de spatiëring goed leek
Verticaal schrijven is geen horizontale tekst die negentig graden is gedraaid. De tekens blijven rechtop, de advance loopt naar beneden in plaats van opzij, en een aantal tekens verandert volledig van vorm — dat is het deel dat een document dat natuurlijk leest scheidt van een dat een Japanse lezer onmiddellijk als machinaal geproduceerd herkent
Wat er binnen de PDF verandert
Tekst die zo wordt getekend, loopt door een Type0-font in vertical writing mode met de eigen verticale metriek van het font. Dat talt in twee richtingen. Een reader advanced elk teken met de afstand die zijn ontwerper bedoelde in plaats van met een uniforme stap, zodat de kolom het ritme krijgt waarvoor het lettertype is getekend. En het kopiëren van de tekst levert de oorspronkelijke tekens op, omdat de verticale run nog steeds echte tekst is met een juiste mapping in plaats van een reeks geplaatste glyphs
Een font dat geen eigen verticale metriek meedraagt, advanced één em per teken, wat een reader met de standaard zou doen. Die fallback is de moeite waard om te kennen, omdat het het verschil is dat je zult zien wanneer een document correct rendert met een goed CJK-font en er mechanisch gespatieerd uitziet met een Latin-font dat toevallig wat kana bevat
var
Lib: TPDFlib;
H: Double;
begin
Lib := TPDFlib.Create;
try
Lib.SetOrigin(1);
Lib.AddTrueTypeFont('MS Mincho', 1); // 1 = embed the face
Lib.SetTextSize(12);
Lib.SetVerticalWritingMode(1); // ordinary DrawText now runs down
H := Lib.GetVerticalTextHeight('MS Mincho', 12, '第三章 保守点検');
Lib.DrawText(480, 72, '第三章 保守点検');
Lib.SetVerticalWritingMode(0); // back to horizontal
Lib.DrawText(72, 72 + H, 'Chapter 3');
Lib.SaveToFile('manual-ja.pdf');
finally
Lib.Free;
end;
end;
Waarom zien haakjes er verkeerd uit in verticale tekst?
Omdat een haak twee vormen heeft en er slechts één in een kolom thuishoort. Haakjes, het lange-klinkteken en de kleine kana worden anders getekend wanneer tekst langs de pagina naar beneden loopt — een ronde haak draait zodat hij langs de kolom loopt in plaats van er dwars doorheen te liggen, en het lange-klinkteken wordt een verticale streep. Teken de horizontale vormen in een verticale kolom en ze liggen allemaal op hun zij
PDFlibPas neemt de vormen uit de eigen vertical-feature van het font, zodat elk font levert wat zijn ontwerper heeft getekend in plaats van een substitutie die uit het teken is geraden. Dat onderscheid talt voor correctheid: een gokkende substitutietabel heeft het bij de gewone gevallen goed en bij de fonts die een teken anders behandelen fout, en een font dat geen verticale vormen benoemt, wordt precies als eerst getekend in plaats van door een tabel te worden gedwongen die het nooit vroeg
GetVerticalTextHeight meet de vormen die daadwerkelijk zullen worden getekend, zodat een kolom waarvan de tekens van vorm veranderen toch correct wordt gemeten. De horizontale vormen meten en de verticale tekenen is de klassieke bron van kolommen die hun kader met een paar tekens overschrijden
Eén run tekenen zonder de mode te wijzigen
DrawVerticalText tekent één run verticaal, neemt de positie, fontnaam, grootte en tekst, en laat de writing-mode met rust. Gebruik het voor de verticale uitzondering binnen een horizontaal document — een rugtitel, een stempel, één kolom met namen — waar het aan en uit zetten van een globale mode rond elke aanroep meer staat is dan de taak verdient
De horizontale en verticale vormen van één font worden intern gescheiden gehouden, zodat een pagina beide kan meedragen zonder dat de een de ander stoort. Dat is wat een gemengde pagina praktisch maakt: een Japans boekspagina met verticale body-tekst en horizontale lopende koppen, of een Chinees certificaat met een verticale titel boven horizontale detailregels
// One vertical run inside an otherwise horizontal page
Lib.DrawVerticalText(520, 96, 'MS Mincho', 14, '保守点検記録');
// The horizontal text around it is unaffected
Lib.DrawText(72, 96, 'Maintenance inspection record');
Het font kloppend krijgen vóór al het andere
Verticaal schrijven hangt volledig af van het font. Een CJK-font met behoorlijke verticale metriek en een vertical-feature produceert correcte uitvoer zonder verdere werk; een font zonder deze produceert rechtopstaande tekens die telkens één em advance en helemaal geen vormveranderingen. Als verticale tekst subtiel verkeerd lijkt, onderzoek het font vóór de code
Insluiten volgt de gebruikelijke regels en de gebruikelijke kosten. Een volledig CJK-font is groot, zodat subsetting geen optie is maar een vereiste voor documenten die ergens heen gaan — de notities over PDF-bestandsgrootte-optimalisatie en font-subsetting behandelen wat je kunt verwachten, en de doorloop van ontbrekende fonts insluiten in een bestaande PDF behandelt het reparatiegeval wanneer een verticaal document aankomt zonder zijn fonts
Waar verticale tekst nog steeds een lay-outbeslissing van jou nodig heeft
Kolomvolgorde. Japanse verticale tekst loopt per kolom van rechts naar links, dus een tweekolomspagina begint aan de rechterrand, en geen writing-mode-instelling kan dat uit de tekst afleiden. Hetzelfde geldt voor de paginavolgorde in een document dat als geheel van rechts naar links leest, en voor waar furigana, voetnoten en figuurbijschriften staan
Wat de bibliotheek garandeert, is dat elke run correct wordt gezet: juiste vormen, juiste advances, extraheerbare tekst. Waar de runs op de pagina belanden is een lay-outprobleem, en voor documenten die uit gegevens worden samengesteld, is de doorloop van tekstzoek en pagina-elementenumeratie nuttig om achteraf te verifiëren dat wat op de pagina belandde is wat je bedoelde
PDFlibPas is een native Pascal PDF-bibliotheek voor Delphi, C++Builder en Lazarus, en verticaal CJK-schrijven is onderdeel van de teken-API in plaats van een add-on — zie de PDFlibPas-productpagina voor de tekst- en fontfunctielijst