Svaki vidljivi string u HotPDF dokumentu dolazi kroz jedan poziv: TextOut(X, Y, angle, Text). Primer Hello World koristi ga u najjednostavnijem obliku, font podesen jednom i cetiri argumenta ostavljeni na razumnim podrazumevanim vrednostima. Posle te prve stranice isti cetiri argumenta nose celokupan teret rasporeda. Treci argument rotira niz. Font podesen neposredno pre njega odlucuje velicinu i stil. A par X, Y, meren od ugla stranice u tackama, jedina je stvar koja stoji izmedzu cistog izvestaja i teksta koji se preklapa, seche ili klizi liniju nize na tudjim stampacima. Tu TextOut zaradjuje svoju primenu, i tu podrazumevane vrednosti prestaju biti dovoljne
Potpis vredi fiksirati u svesti pre svega ostalog: X i Y su Single u tackama, angle je Extended u stepenima, a Text je WideString, pa Unicode prolazi bez odvojenog poziva. Drugi preoptereceni oblik uzima PWORD plus duzinu za slucajeve kada vec drzite kodove glifova, ali za obicne stringove koristite WideString oblik
Velicina i stil dolaze iz SetFont, ne iz TextOut
TextOut nema parametar velicine. Velicina, tezina, nagib, sve to zivi u pozivu SetFont koji prethodi nizu, i ostaje na snazi dok ga sledeci SetFont ne zameni. To je jedina cinjenica koja objasnjava vecinu zbunjenosti prvog dana: linija izadje podebljana jer je tri poziva ranije nesto podesilo [fsBold] i nista to nije ocistilo
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
Drugi argument je skup TFontStyles, pa je [fsBold, fsItalic] podebljana kurziv, a [] je obicni tekst. Velicina je u tackama, ista jedinica kao koordinate, sto cini vertikalni razmak lakim za razumeti: linija od 12 tacaka zeli otprilike 14 do 16 tacaka vertikalnog koraka da dise, pa je smanjivanje Y za 14 po liniji razumni pocetni prored. Nema automatskog pomaka linije. Sami izracunavate svaku baznu liniju, sto je mukotrpno za paragraf ali tacno za obrazac gde svako polje sedi na fiksnoj koordinati
Dve prakticne napomene o imenu fonta. Razresava se u odnosu na fontove instalirane na masini za izgradnju, i ono sto OS vrati je ono sto se ugradi, pa ime koje se razresava na vasem radnom stolu i ime koje se razresava na serveru za izgradnju nisu garantovano ista lica. I font mora da pokriva skriptove u stringu. Niz ciriljice ili CJK teksta ispod lica koje podrzava samo latinicu renderuje se kao kutije za nedostajuci glif bez greske, sto je razlog zasto primer Hello World poseze za sirokim Unicode licem kada mesa jezike
Argument ugla rotira oko sidra
Treci argument je onaj koji vecina koda zauvek ostavlja na nuli. Prosledite vrednost razlicitu od nule i niz se rotira suprotno od kazaljke sata oko svog sopstvenog sidra (X, Y), donjeg levog dela teksta, za toliko stepeni. Samo sidro se ne pomera, pa ista koordinata koja postavlja horizontalnu oznaku postavlja i njenu rotiranu dvojnicu; menja se samo smer u kome se glifovi krece
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');
Devedeset stepeni je uobicajen slucaj, oznaka koja tece uz stranu grafikona ili naslov na hrptu. Cetrdesetpet stepeni barata nagnutim zaglavljima kolona, trik koji omogucava siroj oznaci da stoji iznad uske kolone ne prelivajuci se u komsijine. Rotacija ne menja kako se sidro tumaci, sto ljude zbunjuje: niz od 90 stepeni i dalje pocinje od (X, Y) i raste od tamo nagore, pa da centirujete rotiranu oznaku menjate sidro, a ne ugao. Kada vise rotiranih nizova dele baznu liniju, dajte im isti Y i koracajte X, tacno kao sto biste koracali Y za poredane horizontalne linije
Postavljanje koordinata bez pogadjanja
Koordinate su deo koji prezivljava pregled ili ga tiho kvari. HotPDF meri od donjeg levog ugla stranice, Y raste nagore, u tackama po 72 po incu. US Letter stranica je 612 puta 792 tacke; A4 je 595 puta 842. Gornja margina od jednog inca na Letter postavlja prvu baznu liniju blizu Y = 792 minus 72 minus velicina fonta, a ne na neki mali broj blizu vrha. Svi koji dolaze iz ekranskih koordinata, gde Y raste nadole od nule, pisu prvu liniju van donje ivice i provode deset minuta pitajuci se gde je otisla
Tretirajte raspored kao aritmetiku prema imenovanim sidrima, a ne kao kolonu magicnih brojeva. Leva margina, tekuca bazna linija koju smanjujete po liniji, i fiksni prored pretvaraju blok oznaka u kratku petlju umesto u zid literala:
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;
Cuvanje od prelaska stranice je linija koju svako prvo zaboravi, a terenska primena najteze pogadja. Ispod TextOut-a ne postoji raspored toka. Smanjite Y ispod donje margine i tekst nastavlja da se crta u marginu, van stranice, u nicosta, bez upozorenja. Stoga sami pratite Y, pozivate AddPage kada predje pod, i resetujete baznu liniju. SetFont posle AddPage nije opcionalno punjenje: trenutni font ne prezivljava prelom stranice, i prvi niz na novoj stranici izlazi u podrazumevanom licu pregledaca ako ga preskocite
Razmak karaktera i reci za uklapanje i poravnanje
Ponekad je string tacan ali pogresne sirine: zaglavlje koje mora da obuhvati fiksno pravilo, kod koji treba da se cita s prostranim ciframa, kolona kojoj vrednosti treba blago poravnati. PDF nosi dva operatora stanja teksta za ovo, razmak karaktera (Tc, dodatni prostor dodat posle svakog glifa) i razmak reci (Tw, dodatni prostor dodat na svakom karakteru razmaka), i oba su izrazena u neskaliranim jedinicama tekstualnog prostora, efektivno tackama pri trenutnoj velicini fonta. Oni su stanje, ne argumenti za TextOut, pa ih podeste, nacrtate, i vratite nazad
// 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);
Razmak reci deluje samo na karakter razmaka (kod 32), sto ima posledicu vrednu znanja: ne cini nista unutar CJK niza koji nema ASCII razmake, i cudan je u interakciji s tekstom kodiranim kao indeksi glifova umesto bajtova. Za latinicni tabelarni izlaz, to je jeftin nacin prosirenja razmaka bez prekucavanja stringa. Razmak karaktera je bolji alat za zaglavlje koje mora da dosegne ciljanu sirinu, jer ravnomerno rasporeduje podesavanje kroz svaki glif umesto da ga gomila na razmacima
Reset je celokupna disciplina. Razmak, poput fonta, deo je stanja crtanja stranice, i stanje se odrzava dok ga ne promenite. Razmak u jednom zaglavlju i zaboravljanje da ga ponistite znaci da svaki paragraf ispod nasledjuje rastezanje, sto se cita kao suptilna, tesko smestiva pogresnost koja prezivljava povrsno korigovanje i pada na pazljivo. Pouzdan obicaj je postavljanje vrednosti razmaka, crtanje niza koji je treba, i vracanje na nulu u sledecem redu, tako da kasniji kod ne mora znati sta je raniji odeljak uradio
Proveravanje izlaza tamo gde zapravo puca
Raspored teksta pada na drugoj masini, a ne na prvoj, pa provere koje su vazne dogadjaju se van vaseg stola. Otvorite generisanu datoteku na sistemu bez vaseg developerskog skupa fontova i potvrdite da se ugradjena lica i dalje renderuju, ukljucujuci akcentovani latinski, sve ne-latinicne skriptove i interpunkciju, u jednom prolazu umesto spot-proveravanja jednostavnih karaktera. Selektujte i kopirajte nekoliko linija da potvrdite da je tekst pravi tekst a ne konture, sto postaje vazno cim pretrazivanje ili ekstrakcija dodju u obzir. Nahranite raspored reprezentativnim podacima, najduzu nemacku oznaku i najsiri broj, a ne uredni placeholder, jer je niz koji prekoracuje polje uvek onaj koji niste rucno uneli. I ako stranica mora da sletii na unapred stampan obrazac, odstampajte ili rasterizujte jedan uzorak i uporediteg s originalom; pomak bazne linije od cetvrt milimetra je nevidljiv na ekranu i ocit na papiru
Ako jos niste napisali ni jednu stranicu, pocnite s primerom HotPDF Hello World, koji podesen dokument, font i koordinatni sistem donjeg levog ugla od koga sve gore zavisi. Pozivi TextOut, SetFont i razmaka prikazani ovde deo su HotPDF Component za Delphi i C++Builder