Jokainen HotPDF-asiakirjan näkyvä merkkijono piirretään kutsulla TextOut(X, Y, angle, Text). Hello World -esimerkissä fontti asetetaan kerran ja neljä argumenttia saavat yksinkertaiset arvot, mutta myöhemmässä asettelussa kolmas argumentti kiertää tekstijaksoa, edeltävä SetFont määrää koon ja tyylin ja pisteinä mitattu X/Y-pari ratkaisee, pysyykö raportti kohdallaan myös toisella tulostimella. Tässä vaiheessa oletusarvot eivät enää riitä
Allekirjoitus (signature) on syytä painaa mieleen ennen mitään muuta: X ja Y ovat Single-tyyppisiä pisteinä, angle on Extended asteina ja Text on WideString, joten Unicode menee läpi ilman erillistä kutsua. Toinen ylikuormitus (overload) ottaa vastaan PWORD-osoittimen plus pituuden silloin, kun pidät jo hallussasi glyyfikoodit, mutta tavallisille merkkijonoille WideString-muoto on se, johon tartut
Koko ja tyyli tulevat SetFont-kutsusta, ei TextOutista
TextOutilla ei ole kokoparametria. Koko, paksuus, kallistus, kaikki tuo asuu ajoa edeltävässä SetFont-kutsussa, ja se pysyy voimassa, kunnes seuraava SetFont korvaa sen. Tuo on se ainoa tosiasia, joka selittää suurimman osan ensimmäisen päivän hämmennyksestä: rivi tulee ulos lihavoituna, koska kolme kutsua aiemmin jokin asetti [fsBold] eikä mikään tyhjentänyt sitä
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
Toinen argumentti on TFontStyles-joukko, joten [fsBold, fsItalic] on lihavoitu kursiivi ja [] on tavallinen. Koko on pisteinä, samassa yksikössä kuin koordinaatit, mikä tekee pystysuorasta välistyksestä helpon järkeillä: 12 pisteen rivi haluaa karkeasti 14–16 pistettä pystysuoraa askelta hengittääkseen, joten Y:n pudottaminen 14:llä riviä kohden on kohtuullinen aloitusriviväli (leading). Automaattista rivinsiirtoa ei ole. Lasket jokaisen perusviivan itse, mikä on työlästä kappaleelle, mutta tarkkaa lomakkeelle, jossa jokainen kenttä istuu kiinteässä koordinaatissa
Kaksi käytännön huomiota fontin nimestä. Se ratkaistaan käännöskoneelle asennettuja fontteja vasten, ja mitä tahansa käyttöjärjestelmä antaa takaisin, se on se, mikä upotetaan, joten työpöydälläsi ratkeava nimi ja käännöspalvelimella (build server) ratkeava nimi eivät takuulla ole sama kirjasin (face). Ja fontin on katettava merkkijonon kirjoitusjärjestelmät (scripts). Kyrillisen tai CJK-tekstin ajo vain latinalaisia merkkejä tukevalla kirjasimella renderöityy puuttuvan glyyfin laatikoiksi ilman virhettä, mikä on syy, miksi Hello World -sivu tarttuu laajaan Unicode-kirjasimeen kieliä sekoittaessaan
Kulma-argumentti (angle) kiertää ankkurin ympäri
Kolmas argumentti on se, jonka suurin osa koodista jättää nollaan ikuisesti. Välitä nollasta poikkeava arvo, ja ajo kiertyy vastapäivään oman (X, Y) -ankkurinsa – tekstin vasemman alakulman – ympäri kyseisen astemäärän verran. Itse ankkuri ei liiku, joten sama koordinaatti, joka asetti vaakasuoran nimikkeen, asettaa sen kierretyn kaksosen; vain suunta, johon glyyfit marssivat, muuttuu
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');
Yhdeksänkymmentä astetta on yleinen tapaus, kaavion kylkeä ylös kulkeva nimike tai selkämyksen otsikko. Neljäkymmentäviisi astetta käsittelee kallistetut sarakkeiden otsikot, tempun, joka antaa leveän nimikkeen istua kapean sarakkeen päällä läikkymättä naapureihinsa. Kierto ei muuta sitä, miten ankkuria tulkitaan, mikä kaataa ihmisiä: 90 asteen ajo alkaa yhä koordinaatista (X, Y) ja kasvaa siitä ylöspäin, joten kierretyn nimikkeen keskittämiseksi säädät ankkuria, et kulmaa. Kun useat kierretyt ajot jakavat perusviivan, anna niille sama Y ja askeleta X:ää, täsmälleen samalla tavalla kuin askeltaisit Y:tä pinotuille vaakasuorille riville
Koordinaattien sijoittaminen arvailematta
Koordinaatit ovat se osa, joka selviää katselmoinnista (review) tai hiljaisesti reputtaa sen. HotPDF mittaa sivun vasemmasta alakulmasta, Y:n kasvaessa ylöspäin, pisteinä 72 tuumaa kohden. US Letter -sivu on 612 kertaa 792 pistettä; A4 on 595 kertaa 842. Tuuman ylämarginaali Letterissä asettaa siten ensimmäisen perusviivasi lähelle arvoa Y = 792 miinus 72 miinus fontin koko, ei johonkin pieneen lukuun yläosan lähellä. Kuka tahansa, joka saapuu ruutukoordinaateista, missä Y kasvaa alaspäin nollasta, kirjoittaa ensimmäisen rivin alareunan yli ja viettää kymmenen minuuttia ihmetellen, minne se meni
Käsittele asettelua (layout) aritmetiikkana nimettyjä ankkureita vasten ennemmin kuin sarakkeena taikanumeroita. Vasen marginaali, juokseva perusviiva, jota vähennät riviä kohden, ja kiinteä riviväli (leading) muuttavat nimikkeiden lohkon lyhyeksi silmukaksi literaalien seinän sijaan:
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;
Sivunvaihdon suoja (page-break guard) on se rivi, jonka kaikki unohtavat ensimmäisenä ja johon kenttä (field) osuu kovimmin. TextOutin alla ei ole virtauksen asettelua (flow layout). Vähennä alareunan marginaalin ohi, ja teksti jatkaa piirtymistä kouruun, sivun ulkopuolelle, tyhjyyteen, ilman varoitusta. Joten vahdit Y:tä itse, kutsut menetelmää AddPage, kun se ylittää lattian, ja nollaat perusviivan. SetFont menetelmän AddPage jälkeen ei ole valinnaista pehmustetta: nykyinen fontti ei selviä sivunvaihdosta, ja uuden sivun ensimmäinen ajo tulee ulos katseluohjelman oletuskirjasimella, jos ohitat sen
Merkkien ja sanojen välistys istuvuutta ja kohdistusta varten
Toisinaan merkkijono on oikea mutta väärän levyinen: otsikko, jonka on ulotuttava kiinteän viivan yli, koodi, jota pitäisi lukea ilmavammilla numeroilla, sarake, joka tarvitsee arvojaan tönäistäväksi asettuakseen linjaan. PDF kantaa kaksi tekstitilan operaattoria tätä varten, merkkivälistys (character spacing, Tc, jokaisen glyyfin jälkeen lisätty ylimääräinen tila) ja sanavälistys (word spacing, Tw, jokaiseen välilyöntiin lisätty ylimääräinen tila), ja molemmat ilmaistaan skaalaamattomina tekstitilan yksikköinä, käytännössä pisteinä nykyisessä fonttikoossa. Ne ovat tilaa, eivät argumentteja TextOutille, joten asetat ne, piirrät, ja asetat ne takaisin
// 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);
Sanavälistys toimii vain välilyöntimerkkiin (koodi 32), millä on tietämisen arvoinen seuraus: se ei tee mitään CJK-ajon sisällä, jossa ei ole ASCII-välilyöntejä, ja se vuorovaikuttaa oudosti tekstin kanssa, joka on koodattu glyyfi-indekseinä tavujen sijaan. Latinalaiselle taulukkotulosteelle se on halpa tapa leventää aukkoja kirjoittamatta merkkijonoa uudelleen. Merkkivälistys on parempi työkalu otsikolle, jonka täytyy saavuttaa tavoiteleveys, koska se jakaa säädön tasaisesti jokaisen glyyfin yli sen sijaan, että se kerääntyisi välilyönteihin
Nollaus on koko kuri. Välistys, kuten fonttikin, on osa sivun piirtotilaa (drawing state), ja tila jatkuu, kunnes muutat sitä. Laita kirjainvälistys yhteen otsikkoon ja unohda nollata se, ja jokainen alla oleva kappale perii venytyksen, mikä luetaan hienovaraisena, vaikeasti paikannettavana vääryytenä, joka selviää rennosta oikoluvusta ja reputtaa huolellisen. Luotettava tapa on asettaa välistysarvo, piirtää sitä tarvitseva ajo, ja asettaa se takaisin nollaan seuraavalla rivillä, jotta minkään myöhemmän koodin ei tarvitse tietää, mitä aiempi osio teki
Tulosteen tarkistaminen siellä, missä se oikeasti menee rikki
Tekstin asettelu epäonnistuu toisella koneella, ei ensimmäisellä, joten merkitykselliset tarkistukset tapahtuvat poissa työpöytäsi äärestä. Avaa generoitu tiedosto järjestelmässä, johon ei ole asennettu kehittäjän fonttijoukkoa, ja vahvista, että upotetut kirjasimet renderöityvät edelleen, mukaan lukien aksentillinen latina, kaikki ei-latinalaiset kirjoitusjärjestelmät ja välimerkit, yhdellä läpikäynnillä mieluummin kuin helpot merkit pistokoetarkistamalla. Valitse ja kopioi muutama rivi vahvistaaksesi, että teksti on aitoa tekstiä eikä ääriviivoja, millä on väliä sillä hetkellä, kun haku tai purku on kuvassa. Syötä asettelulle edustavaa dataa, pisin saksalainen nimike ja levein numero, ei siisti paikanvaraaja (placeholder), koska ajo, joka valuu kentän yli, on aina se, jota et kirjoittanut käsin. Ja jos sivun on laskeuduttava esipainetulle lomakkeelle, tulosta tai rasteroi yksi näyte ja aseta se alkuperäistä vasten; neljännesmillimetrin perusviivan ajelehtiminen on näkymätön näytöllä ja ilmiselvä paperilla
Jos et ole vielä kirjoittanut yhtäkään sivua, aloita HotPDF Hello World -esimerkistä, joka pystyttää asiakirjan, fontin ja vasemman alakulman koordinaatiston, johon kaikki yllä oleva nojaa. Tässä näytetyt TextOut-, SetFont- ja välistyskutsut ovat osa HotPDF-komponenttia Delphille ja C++Builderille