Kiekviena matoma eilutė „HotPDF“ dokumente atsiranda dėl vieno iškvietimo: TextOut(X, Y, angle, Text). „Hello World“ pavyzdyje jis naudojamas paprasčiausiai, šriftas nustatytas kartą, o keturi argumentai palikti su protingomis numatytosiomis reikšmėmis. Peržengus tą pirmąjį puslapį, tie patys keturi argumentai išlaiko visą maketo naštą. Trečiasis argumentas pasuka tekstą. Prieš pat tai nustatytas šriftas lemia dydį ir stilių. O pora X, Y, matuojama taškais nuo puslapio kampo, yra vienintelis dalykas, skiriantis švarią ataskaitą nuo teksto, kuris persidengia, yra nukerpamas arba pasislenka eilute žemiau kieno nors kito spausdintuve. Būtent čia TextOut užsitarnauja savo vardą ir numatytųjų reikšmių nebeužtenka
Prieš darant ką nors kita, verta įsiminti parašą (signature): X ir Y yra Single (taškais), angle yra Extended (laipsniais), o Text yra WideString, todėl „Unicode“ praleidžiamas be atskiro iškvietimo. Antroji perkrova (overload) priima PWORD plius ilgį tiems atvejams, kai jau turite glifų kodus, bet paprastoms eilutėms dažniausiai naudosite formą su WideString
Dydis ir stilius nustatomi per SetFont, o ne TextOut
TextOut neturi dydžio parametro. Dydis, storis, pasvirimas – visa tai yra iškvietime SetFont, einančiame prieš teksto išvedimą, ir tai galioja tol, kol kitas SetFont jį pakeičia. Tai vienintelis faktas, paaiškinantis didžiąją dalį pirmosios dienos painiavos: eilutė atspausdinama pusjuodžiu šriftu, nes prieš tris iškvietimus kažkas nustatė [fsBold] ir niekas to neatšaukė
Pdf.CurrentPage.SetFont('Times New Roman', [], 24);
Pdf.CurrentPage.TextOut(72, 740, 0, 'Quarterly Report'); // 24pt regular
Pdf.CurrentPage.SetFont('Times New Roman', [fsBold], 12);
Pdf.CurrentPage.TextOut(72, 712, 0, 'Revenue'); // 12pt bold
Pdf.CurrentPage.SetFont('Times New Roman', [fsItalic], 11);
Pdf.CurrentPage.TextOut(72, 694, 0, 'figures in thousands'); // 11pt italic
Pdf.CurrentPage.SetFont('Courier New', [fsBold, fsItalic], 10);
Pdf.CurrentPage.TextOut(72, 676, 0, ' +18.4% YoY'); // styles combine
Antrasis argumentas yra aibė TFontStyles, todėl [fsBold, fsItalic] yra pusjuodis kursyvas, o [] yra paprastas. Dydis nurodomas taškais (tais pačiais vienetais kaip ir koordinatės), todėl lengva apgalvoti vertikalius tarpus: 12 taškų eilutei reikia maždaug nuo 14 iki 16 taškų vertikalaus žingsnio, kad ji „kvėpuotų“, todėl Y sumažinimas 14 taškų kiekvienai eilutei yra protingas pradinis atstumas tarp eilučių (leading). Automatinio eilutės perkėlimo nėra. Kiekvieną bazinę liniją (baseline) turite apskaičiuoti patys, kas yra nuobodu rašant pastraipą, bet idealiai tinka formai, kur kiekvienas laukas turi būti išdėstytas pagal nustatytą koordinatę
Dvi praktinės pastabos apie šrifto pavadinimą. Jis susiejamas su šriftais, įdiegtais kompiliavimo mašinoje (build machine), ir tai, ką grąžina operacinė sistema, yra įterpiama į dokumentą, todėl pavadinimas, kuris veikia jūsų darbalaukyje, ir pavadinimas, kuris veikia kompiliavimo serveryje, negarantuoja to paties šrifto išvaizdos. Taip pat šriftas turi apimti eilutėje esančius rašmenis. Kirilicos ar CJK teksto išvedimas naudojant tik lotynišką šriftą rodomas kaip trūkstamų glifų kvadratai be jokios klaidos, todėl „Hello World“ pavyzdyje, kai maišomos kalbos, naudojamas platus „Unicode“ šriftas
Kampo argumentas sukasi aplink inkarą (anchor)
Trečiasis argumentas yra tas, kurį daugelis kodų amžinai palieka lygų nuliui. Perduokite nenulinę reikšmę ir tekstas pasisuks prieš laikrodžio rodyklę aplink savo inkarą (X, Y) – kairįjį apatinį teksto kampą – tiek laipsnių. Pats inkaras nejuda, todėl ta pati koordinatė, kuri padėjo horizontalią etiketę, padės ir jos pasuktą dvynį; keičiasi tik glifų išsidėstymo kryptis
Pdf.CurrentPage.SetFont('Arial', [fsBold], 11);
// A vertical axis label down the left margin: 90 degrees reads bottom-to-top.
Pdf.CurrentPage.TextOut(40, 300, 90, 'Units sold');
// A diagonal DRAFT watermark across the page body.
Pdf.CurrentPage.SetFont('Arial', [fsBold], 60);
Pdf.CurrentPage.TextOut(150, 250, 45, 'DRAFT');
// Column headers tilted 60 degrees so long labels fit a narrow table.
Pdf.CurrentPage.SetFont('Arial', [], 9);
Pdf.CurrentPage.TextOut(120, 600, 60, 'Q1 actual');
Pdf.CurrentPage.TextOut(160, 600, 60, 'Q2 actual');
Devyniasdešimt laipsnių yra dažnas atvejis – tai etiketė, einanti palei diagramos kraštą, arba nugarėlės pavadinimas. Keturiasdešimt penki laipsniai padeda susidoroti su pasvirusiomis stulpelių antraštėmis, tai gudrybė, leidžianti plačiai etiketei tilpti virš siauro stulpelio ir neišlieti ant kaimynų. Pasukimas nekeičia inkaro interpretavimo būdo, o tai sukelia žmonėms problemų: 90 laipsnių kampu pasuktas tekstas vis tiek prasideda nuo (X, Y) ir auga aukštyn, todėl norėdami centruoti pasuktą etiketę, koreguojate inkarą, o ne kampą. Kai keli pasukti tekstai dalijasi bazine linija, priskirkite jiems tą patį Y ir keiskite X, lygiai taip pat, kaip keistumėte Y vertikaliai išdėstytoms horizontalioms eilutėms
Koordinačių išdėstymas be spėliojimų
Koordinatės yra ta dalis, kuri sėkmingai pereina peržiūrą arba tyliai joje žlunga. „HotPDF“ matuoja nuo apatinio kairiojo puslapio kampo, Y didėja į viršų, taškais – po 72 vienam coliui. JAV „Letter“ puslapis yra 612 x 792 taškų dydžio; A4 – 595 x 842 taškų. Todėl vieno colio viršutinė paraštė „Letter“ puslapyje padeda jūsų pirmąją bazinę liniją ties Y = 792 minus 72 minus šrifto dydis, o ne prie kokio nors mažo skaičiaus netoli viršaus. Kiekvienas, pripratęs prie ekrano koordinačių, kur Y didėja žemyn nuo nulio, parašo pirmąją eilutę už apatinio krašto ir dešimt minučių stebisi, kur ji dingo
Elkitės su maketu kaip su aritmetika, paremta pavadintais inkarų taškais, o ne magiškų skaičių stulpeliu. Kairioji paraštė, einanti bazinė linija, kurią mažinate kiekvienai eilutei, ir fiksuotas atstumas tarp eilučių (leading) paverčia etikečių bloką trumpu ciklu, o ne literalų siena:
const
LeftMargin = 72; // 1 inch in
TopBaseline = 720; // first line, ~1 inch down on Letter
Leading = 16; // vertical step between lines
var
Y: Single;
Line: string;
begin
Pdf.CurrentPage.SetFont('Arial', [], 11);
Y := TopBaseline;
for Line in ReportLines do
begin
Pdf.CurrentPage.TextOut(LeftMargin, Y, 0, Line);
Y := Y - Leading;
if Y < 72 then // bottom margin reached
begin
Pdf.AddPage;
Pdf.CurrentPage.SetFont('Arial', [], 11); // font resets on a new page
Y := TopBaseline;
end;
end;
end;
Puslapio lūžio apsauga yra ta eilutė, kurią visi pamiršta pirmiausia, o praktikoje dėl to kyla daugiausia problemų. Po TextOut nėra srauto maketo (flow layout). Sumažinus koordinatę už apatinės paraštės, tekstas toliau piešiamas į paraštę, už puslapio ribų, į niekur, be jokio įspėjimo. Taigi, patys stebite Y, iškviestite AddPage, kai jis peržengia ribą, ir iš naujo nustatote bazinę liniją. SetFont po AddPage nėra pasirenkamas papildymas: dabartinis šriftas neatlaiko puslapio lūžio, ir pirmasis tekstas naujame puslapyje pasirodys su numatytuoju peržiūros programos šriftu, jei jį praleisite
Tarpai tarp simbolių ir žodžių pritaikymui bei lygiavimui
Kartais eilutė yra teisinga, bet netinkamo pločio: antraštė, kuri turi apimti fiksuotą liniją, kodas, kurio skaitmenys turi būti lengviau skaitomi (su didesniais tarpais), stulpelis, kurio reikšmes reikia šiek tiek pastumti, kad jos susilygiuotų. Šiam tikslui PDF turi du teksto būsenos operatorius: tarpus tarp simbolių (Tc, papildoma erdvė pridedama po kiekvieno glifo) ir tarpus tarp žodžių (Tw, papildoma erdvė pridedama ties kiekvienu tarpo simboliu). Abu jie išreiškiami nemastelizuojamais teksto erdvės vienetais, kurie iš esmės yra taškai esant dabartiniam šrifto dydžiui. Tai yra būsena, o ne TextOut argumentai, todėl jūs juos nustatote, piešiate, o po to nustatote atgal
// Letter-space a short heading so it stretches across a rule.
Pdf.CurrentPage.SetCharacterSpacing(4);
Pdf.CurrentPage.SetFont('Arial', [fsBold], 14);
Pdf.CurrentPage.TextOut(72, 740, 0, 'S U M M A R Y');
Pdf.CurrentPage.SetCharacterSpacing(0); // reset before normal body text
// Open up the gaps between words on a single wide line.
Pdf.CurrentPage.SetWordSpacing(6);
Pdf.CurrentPage.SetFont('Arial', [], 11);
Pdf.CurrentPage.TextOut(72, 712, 0, 'Name Department Extension');
Pdf.CurrentPage.SetWordSpacing(0);
Tarpai tarp žodžių veikia tik tarpo simbolį (kodas 32), o tai turi pasekmę, kurią verta žinoti: jis nieko nedaro CJK tekste, kuriame nėra ASCII tarpų, ir keistai sąveikauja su tekstu, užkoduotu kaip glifų indeksai, o ne baitai. Lotyniškiems lentelių išvedimams tai yra pigus būdas praplėsti tarpus neperrenkant eilutės. Tarpai tarp simbolių yra geresnis įrankis antraštei, kuri turi pasiekti nustatytą plotį, nes jis paskirsto korekciją tolygiai kiekvienam glifui, užuot kaupęs ją ties tarpais
Atstatymas (reset) yra visa disciplina. Tarpai, kaip ir šriftas, yra puslapio piešimo būsenos dalis, o būsena išlieka tol, kol ją pakeičiate. Padidinkite tarpus tarp simbolių vienoje antraštėje ir pamirškite ją nunulinti – kiekviena žemiau esanti pastraipa paveldės ištempimą, kas skaitosi kaip subtilus, sunkiai pastebimas trūkumas, kuris išlieka per atsitiktinę peržiūrą, bet nepraeina atidžios. Patikimas įprotis yra nustatyti tarpo reikšmę, nupiešti tekstą, kuriam to reikia, ir kitą eilutę vėl nustatyti jį ties nuliu, kad jokiam vėlesniam kodui nereikėtų žinoti, ką padarė ankstesnė sekcija
Išvesties tikrinimas ten, kur ji iš tikrųjų lūžta
Teksto maketas lūžta antrojoje mašinoje, o ne pirmojoje, todėl svarbiausi patikrinimai vyksta toliau nuo jūsų darbo stalo. Atidarykite sugeneruotą failą sistemoje be įdiegto jūsų kūrėjo šriftų rinkinio ir patvirtinkite, kad įterpti šriftai vis dar atvaizduojami, įskaitant lotyniškus rašmenis su diakritiniais ženklais, bet kokius nelotyniškus rašmenis ir skyrybos ženklus, patikrindami viską vienu kartu, o ne tikrintami tik lengvus simbolius. Pažymėkite ir nukopijuokite kelias eilutes, kad patvirtintumėte, jog tekstas yra tikras tekstas, o ne kontūrai, kas tampa svarbu tą akimirką, kai prireikia paieškos arba teksto ištraukimo. Pateikite maketui reprezentatyvius duomenis, ilgiausią vokišką etiketę ir plačiausią skaičių, o ne tvarkingą rezervuotąją vietą (placeholder), nes tekstas, kuris perpildo lauką, visada yra tas, kurio neįvedėte ranka. O jei puslapis turi atsidurti iš anksto atspausdintoje formoje, atspausdinkite arba rasterizuokite vieną pavyzdį ir pridėkite jį prie originalo; ketvirčio milimetro bazinės linijos poslinkis ekrane nematomas, bet akivaizdus ant popieriaus
Jei dar neparašėte nė vieno puslapio, pradėkite nuo „HotPDF Hello World“ pavyzdžio, kuriame nustatomas dokumentas, šriftas ir apatinio kairiojo kampo koordinačių sistema, nuo kurios priklauso visa tai, kas aprašyta aukščiau. Čia parodyti TextOut, SetFont ir tarpų iškvietimai yra „HotPDF“ komponento dalis, skirtos „Delphi“ ir „C++Builder“