Technical Article

HotPDF TextOut u Delphiju: Veličina, stil, rotacija i razmak

Svaki vidljivi niz znakova u HotPDF dokumentu stiže kroz jedan poziv: TextOut(X, Y, kut, tekst). Hello World primjer koristi ga u njegovom najjednostavnijem obliku, s jednom postavljenim fontom i četiri argumenta ostavljena na razumnim zadanim vrijednostima. Nakon te prve stranice, ista četiri argumenta nose cijeli teret rasporeda. Treći argument rotira tekst. Font postavljen neposredno prije njega određuje veličinu i stil. A par X, Y, mjeren od kuta stranice u točkama, jedina je stvar koja stoji između čistog izvještaja i teksta koji se preklapa, odsijeca ili se ispisuje red niže na tuđem pisaču. Ovdje TextOut dokazuje svoju vrijednost, i ovdje zadane postavke prestaju biti dovoljne.

Potpis funkcije vrijedi zapamtiti prije svega: X i Y su tipa Single u točkama, angle je tipa Extended u stupnjevima, a Text je tipa WideString, pa Unicode prolazi bez zasebnog poziva. Drugo preopterećenje prima PWORD i duljinu za slučajeve kada već imate kodove glifova, no za obične nizove znakova oblik WideString je onaj koji koristite.

Veličina i stil dolaze iz SetFont, a ne iz TextOut

TextOut nema parametar veličine. Veličina, težina, nagib, sve to živi u pozivu SetFont koji prethodi ispisivanju i ostaje na snazi dok ga sljedeći SetFont ne zamijeni. To je jedna činjenica koja objašnjava većinu zabuna na početku rada: linija ispadne podebljana jer je tri poziva ranije nešto postavilo [fsBold], a ništa ga nije očistilo.

Drugi argument je skup TFontStyles, pa je [fsBold, fsItalic] podebljano i koso, a [] je obično. Veličina je u točkama, istoj jedinici kao i koordinate, što olakšava razmišljanje o okomitom razmaku: linija od 12 točaka zahtijeva otprilike 14 do 16 točaka okomitog koraka za disanje, pa je smanjivanje Y za 14 po liniji razuman početni prored (leading). Nema automatskog prijelaza u novi red. Svaku osnovnu liniju (baseline) izračunavate sami, što je zamorno za odlomak, ali točno za obrazac gdje svako polje leži na fiksnoj koordinati.

Dvije praktične napomene o nazivu fonta. On se razrješava u odnosu na fontove instalirane na računalu na kojem se vrši izgradnja, a ono što operacijski sustav vrati je ono što se ugrađuje, tako da naziv koji se razrješava na vašoj radnoj površini i naziv koji se razrješava na poslužitelju za izgradnju nisu nužno isti. Također, font mora pokrivati pisma u nizu znakova. Niz ćirilice ili CJK teksta pod fontom koji podržava samo latinicu prikazat će se kao prazni okviri bez ikakve pogreške, što je razlog zašto Hello World stranica poseže za širokim Unicode fontom kada miješa jezike.

Argument angle rotira oko sidrišta (anchor)

Treći argument je onaj koji većina koda zauvijek ostavlja na nuli. Proslijedite vrijednost različitu od nule i tekst će se rotirati u smjeru suprotnom od kazaljke na satu oko vlastitog (X, Y) sidrišta (donji lijevi kut teksta) za toliko stupnjeva. Samo sidrište se ne pomiče, pa ista koordinata koja je postavila vodoravni natpis postavlja i njegov rotirani blizanac; mijenja se samo smjer u kojem se glifovi nižu.

Devedeset stupnjeva je uobičajen slučaj – natpis koji ide uz bočnu stranu grafikona ili naslov na hrbatu. Četrdeset i pet stupnjeva rješava nagnuta zaglavlja stupaca, trik koji omogućuje da široki natpis stoji iznad uskog stupca bez prelijevanja u susjedne. Rotacija ne mijenja način tumačenja sidrišta, što zbunjuje ljude: rotacija od 90 stupnjeva i dalje počinje na (X, Y) i raste prema gore odatle, pa za centriranje rotiranog natpisa prilagođavate sidrište, a ne kut. Kada nekoliko rotiranih natpisa dijeli osnovnu liniju, dodijelite im isti Y i mijenjajte X, točno onako kako biste mijenjali Y za naslagane vodoravne linije.

Postavljanje koordinata bez nagađanja

Koordinate su dio koji prolazi pregled koda ili na njemu tiho pada. HotPDF mjeri udaljenost od donjeg lijevog kuta stranice, pri čemu Y raste prema gore, u točkama (72 točke po inču). Stranica US Letter formata ima dimenzije 612 sa 792 točke; A4 ima 595 sa 842. Margina od jednog inča na vrhu Letter formata stoga postavlja vašu prvu osnovnu liniju blizu Y = 792 minus 72 minus veličina fonta, a ne na neki mali broj blizu vrha. Svatko tko dolazi s koordinata zaslona, gdje Y raste prema dolje od nule, ispisat će prvu liniju izvan donjeg ruba i provesti deset minuta pitajući se kamo je nestala.

Tretirajte raspored kao aritmetiku u odnosu na imenovana sidrišta, a ne kao stupac čarobnih brojeva. Lijeva margina, tekuća osnovna linija koju smanjujete po retku i fiksni prored pretvaraju blok natpisa u kratku petlju umjesto gomile fiksnih vrijednosti:

Zaštita od prijeloma stranice je linija koju svi najprije zaborave, a koja u praksi stvara najveće probleme. Ispod TextOut-a nema automatskog rasporeda toka teksta. Smanjite li Y ispod donje margine, tekst će se nastaviti crtati izvan stranice, u ništa, i to bez ikakvog upozorenja. Zato sami pratite Y, pozovite AddPage kada prijeđe donju granicu i ponovno postavite osnovnu liniju. Poziv SetFont nakon AddPage nije opcionalan: trenutni font ne preživljava prijelom stranice, pa će se prvi tekst na novoj stranici prikazati u zadanom fontu preglednika ako to preskočite.

Razmak između znakova i riječi za prilagodbu i poravnanje

Ponekad je niz znakova točan, ali pogrešne širine: zaglavlje koje mora premostiti fiksnu liniju, šifra čije bi znamenke trebale biti razmaknutije ili stupac čije vrijednosti treba malo pomaknuti radi poravnanja. PDF za to sadrži dva operatora stanja teksta, razmak između znakova (Tc, dodatni prostor dodan nakon svakog glifa) i razmak između riječi (Tw, dodatni prostor dodan na svakom praznom znaku), a oba su izražena u neskaliranim jedinicama tekstualnog prostora, zapravo u točkama pri trenutnoj veličini fonta. Oni su stanje, a ne argumenti metode TextOut, pa ih postavljate, crtate i zatim vraćate na staro.

Razmak između riječi utječe samo na prazan znak (kod 32), što ima važnu posljedicu: ne čini ništa unutar CJK teksta koji nema ASCII razmake, a ponaša se čudno s tekstom kodiranim kao indeksi glifova umjesto bajtova. Za latinični tablični izlaz, to je jednostavan način za proširenje razmaka bez ponovnog pisanja niza. Razmak između znakova je bolji alat za zaglavlje koje mora doseći ciljnu širinu, jer raspoređuje prilagodbu ravnomjerno na svaki glif umjesto da je nakuplja samo na razmacima.

Resetiranje je ključna disciplina. Razmak je, baš kao i font, dio stanja crtanja stranice, a stanje ostaje dok ga ne promijenite. Ako razmaknete znakove u jednom zaglavlju i zaboravite to vratiti na nulu, svaki odlomak ispod naslijedit će to širenje, što se doživljava kao suptilna, teško uočljiva pogreška koja prolazi ležeran pregled, ali pada na pažljivom. Pouzdana navika je postaviti vrijednost razmaka, nacrtati tekst kojem je potreban i vratiti je na nulu u sljedećoj liniji, tako da kasniji kod ne mora znati što je raniji dio radio.

Provjera izlaza tamo gdje stvarno puca

Raspored teksta ne uspijeva na drugom računalu, a ne na prvom, pa se provjere koje su važne provode izvan vašeg stola. Otvorite generiranu datoteku na sustavu koji nema instaliran vaš razvojni skup fontova i potvrdite da se ugrađeni fontovi i dalje ispravno prikazuju, uključujući latinicu s kvačicama, sva pisma koja nisu latinična i interpunkciju, i to u jednom prolazu umjesto provjere samo jednostavnih znakova. Označite i kopirajte nekoliko redaka kako biste potvrdili da je tekst stvarni tekst, a ne obrubi oblika, što je važno čim su pretraga ili izdvajanje u planu. Unesite reprezentativne podatke u raspored, najdulji njemački natpis i najširi broj, a ne uredan ogledni tekst, jer je podatak koji prepuni polje uvijek onaj koji niste ručno utipkali. Ako stranica mora ležati na unaprijed tiskanom obrascu, ispišite ili rasterizirajte jedan uzorak i položite ga preko originala; odstupanje osnovne linije od četvrtine milimetra nevidljivo je na zaslonu, a očito na papiru.

Ako još niste napisali niti jednu stranicu, započnite s HotPDF Hello World primjerom koji postavlja dokument, font i koordinatni sustav s ishodištem dolje-lijevo o kojem sve gore navedeno ovisi. Pozivi TextOut, SetFont i razmaci prikazani ovdje dio su HotPDF komponente za Delphi i C++Builder.