Tehnični članak

HotPDF TextOut v Delphi: Velikost, slog, rotacija in razmiki

Vsak viden niz v dokumentu HotPDF prispe prek enega samega klica: TextOut(X, Y, angle, Text). Primer Hello World ga uporablja v najenostavnejši obliki - pisava je nastavljena enkrat, štirje argumenti pa so prepuščeni razumnim privzetim vrednostim. Po tisti prvi strani pa isti štirje argumenti nosijo vso težo postavitve. Tretji argument zavrti besedilo. Pisava, nastavljena tik pred tem, določa velikost in slog. Par X, Y, merjen od kota strani v točkah, pa je edina stvar, ki ločuje urejeno poročilo od besedila, ki se prekriva, odreže ali pa se na tiskalniku nekoga drugega premakne vrstico nižje. Tu se metoda TextOut izkaže, in tu privzete nastavitve prenehajo zadostovati

Preden karkoli drugega, si je vredno zapomniti podpis metode: X in Y sta tipa Single v točkah, angle je Extended v stopinjah, Text pa je WideString, tako da gre Unicode skozi brez ločenega klica. Druga preobremenitev sprejme PWORD in dolžino za primere, ko že imate kode glifov, za navadne nize pa boste uporabili obliko WideString

Velikost in slog izhajata iz SetFont in ne iz TextOut

Metoda TextOut nima parametra za velikost. Velikost, debelina, nagib - vse to živi v klicu SetFont, ki je pred izpisom, in ostane v veljavi, dokler ga naslednji klic SetFont ne nadomesti. To je edino dejstvo, ki pojasnjuje večino zmede na začetku: vrstica se izpiše krepko, ker je tri klice prej koda nastavila slog [fsBold] in ga nič ni počistilo

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 množica TFontStyles, zato [fsBold, fsItalic] pomeni krepko ležeče, [] pa navadno. Velikost je v točkah, enaka enota kot koordinate, kar olajša razmišljanje o navpičnih razmikih: 12-točkovna vrstica potrebuje približno 14 do 16 točk navpičnega koraka, da ima dovolj prostora, zato je zmanjšanje koordinate Y za 14 na vrstico razumen začetni razmik med vrsticami. Samodejnega pomika v novo vrstico ni. Vsako izhodiščno črto izračunate sami, kar je zamudno za odstavek, a izjemno natančno za obrazec, kjer vsako polje sedi na fiksni koordinati

Dve praktični opombi glede imena pisave. Ime se razreši glede na pisave, nameščene na računalniku za gradnjo, in tisto, kar vrne operacijski sistem, se vgradi - zato ni zagotovila, da bosta ime, ki se razreši na vašem namizju, in ime na strežniku za gradnjo, pomenili isto pisavo. Pisava mora prav tako pokrivati pisave v nizu. Izpis cirilice ali znakov CJK s pisavo, ki podpira le latinico, se izpiše kot kvadratki za manjkajoče glife brez kakršne koli napake - to je razlog, da se v primeru Hello World pri mešanju jezikov poseže po pisavi z obsežno pokritostjo Unicode

Stran TextOut HotPDF, kjer so Arial, Times New Roman in Courier New upodobljeni v navadnem, krepkem in ležečem slogu čez več naborov znakov

Argument kota zavrti besedilo okoli sidra

Tretji argument je tisti, ki ga večina kode za vedno pusti pri nič. Podajte vrednost, ki ni nič, in izpis se zavrti v nasprotni smeri urinega kazalca okoli svojega sidra (X, Y) - spodnjega levega kota besedila - za toliko stopinj. Sidro se ne premakne, zato ista koordinata, ki je postavila vodoravno oznako, postavi njeno zavrteno dvojnico; spremenita se le smer in potek glifov

Diagram geometrije vrtenja TextOut HotPDF: teki pod 0, 45 in 90 stopinj, zasukani v nasprotni smeri urinega kazalca okrog nespremenljivega sidra spodaj levo, z zgledi klicev Delphi TextOut za oznake hrbtov, vodne žige in nagnjene glave stolpcev
Neničelni kot obrne teko v nasprotni smeri urinega kazalca okoli mirujočega sidra spodaj levo, skupne osnovne črte pa stopijo X točno tako, kot vodoravne vrstice stopijo Y
Pdf.CurrentPage.SetFont('Arial', [fsBold], 11);

// Navpična oznaka osi ob levem robu: pri 90 stopinjah se bere od spodaj navzgor
Pdf.CurrentPage.TextOut(40, 300, 90, 'Units sold');

// Diagonalni vodni žig DRAFT čez telo strani
Pdf.CurrentPage.SetFont('Arial', [fsBold], 60);
Pdf.CurrentPage.TextOut(150, 250, 45, 'DRAFT');

// Glave stolpcev, nagnjene za 60 stopinj, da se dolge oznake prilegajo ozki tabeli
Pdf.CurrentPage.SetFont('Arial', [], 9);
Pdf.CurrentPage.TextOut(120, 600, 60, 'Q1 actual');
Pdf.CurrentPage.TextOut(160, 600, 60, 'Q2 actual');

Devetdeset stopinj je najpogostejši primer - oznaka, ki poteka ob strani grafikona ali na hrbtu knjige. Štirideset pet stopinj je primerno za nagnjene glave stolpcev, kar je trik, ki omogoča, da široka oznaka stoji nad ozkim stolpcem, ne da bi se prelivala v sosednje. Rotacija ne spremeni načina interpretacije sidra, kar ljudi zmede: 90-stopinjski izpis se še vedno začne pri (X, Y) in raste navzgor od tam, zato za centriranje zavrtene oznake prilagodite sidro in ne kota. Ko si več zavrtenih izpisov deli izhodiščno črto, jim določite enak Y in korakajte po X - natanko tako kot bi korakali po Y za navpično zložene vodoravne vrstice

Postavitev koordinat brez ugibanja

Koordinate so tisti del, ki uspešno prestane pregled ali pa tiho spodleti. HotPDF meri od spodnjega levega kota strani, pri čemer Y narašča navzgor, v točkah (72 točk na palec). Stran US Letter meri 612 x 792 točk, A4 pa 595 x 842 točk. En palec zgornjega roba na formatu Letter torej postavi vašo prvo izhodiščno črto blizu Y = 792 minus 72 minus velikost pisave - ne pri majhni številki blizu vrha. Vsakdo, ki prihaja iz sveta zaslonskih koordinat, kjer Y narašča navzdol od nič, bo prvo vrstico izpisal pod spodnjim robom in preživel deset minut ugibanja, kam je izginila

HotPDF: diagram strani US Letter z aritmetiko osnovne črte: LeftMargin 72, TopBaseline 720 in nespremenljivi Leading, ki koraka proti dnu roba na Y 72, poleg zanke postavitve s poimenovanimi konstantami z ročnim varovalom AddPage in ponastavitvijo SetFont
Poimenovana sidra spremenijo stolpec magičnih števil v aritmetiko: odštejte Leading od tekoče osnovne črte vsako vrstico in sami varujte dno z AddPage

Obravnavajte postavitev kot aritmetiko na podlagi poimenovanih sider in ne kot stolpec magičnih številk. Levi rob, tekoča izhodiščna črta, ki jo zmanjšujete za vsako vrstico, in fiksni razmik spremenijo blok oznak v kratko zanko namesto v vrsto literalnih vrednosti:

const
  LeftMargin = 72;        // 1 inch in
  TopBaseline = 720;       // prva vrstica, približno 1 palec nižje na Letter
  Leading = 16;            // navpični razmik med vrsticami
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            // dosežen spodnji rob
    begin
      Pdf.AddPage;
      Pdf.CurrentPage.SetFont('Arial', [], 11);  // pisava se na novi strani ponastavi
      Y := TopBaseline;
    end;
  end;
end;

Varovalo za prehod na novo stran je tisto, kar vsakdo najprej pozabi in kar v praksi povzroči največ težav. Pod metodo TextOut ni samodejne postavitve toka. Če zmanjšate koordinato pod spodnji rob, bo besedilo brez opozorila nadaljevalo izrisovanje v rob, zunaj strani, v prazno. Zato sami spremljate Y, pokličete AddPage, ko doseže dno, in ponastavite izhodiščno črto. Klic SetFont po AddPage ni neobvezen: trenutna pisava ne preživi prehoda na novo stran, in prvi izpis na novi strani se prikaže v privzeti pisavi pregledovalnika, če ta korak preskočite

Razmiki med znaki in besedami za prileganje in poravnavo

Včasih je niz pravilen, a napačne širine: glava, ki mora segati čez določeno ravnilo, koda, ki bi morala imeti prezračene cifre, ali stolpec, ki potrebuje premik vrednosti za poravnavo. PDF za to nosi dva operatorja stanja besedila - razmik med znaki (Tc, dodaten prostor za vsakim glifom) in razmik med besedami (Tw, dodaten prostor pri vsakem znaku presledka) - oba izražena v neprevedenih enotah besedilnega prostora, dejansko v točkah pri trenutni velikosti pisave. Ker sta stanji in ne argumenta metode TextOut, ju nastavite, izrišete besedilo in nato ponastavite

HotPDF: razmik znakov Tc, ki dodatni prostor enakomerno razporedi za vsakim glifom besede SUMMARY, proti razmiku besed Tw, ki ga zbere le pri presledkih, vpleten v cikel nastavi, nariši, ponastavi, ki preprečuje, da bi stanje razmikov prestopilo v poznejše odstavke
Tc razprostira svoj prilagodek čez vsak glif, Tw pa deluje le na presledkovni znak, ponastavitev v naslednji vrstici pa drži stanje risanja čisto
// Razmakni črke kratkega naslova, da se raztegne čez črto
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);   // ponastavi pred običajnim besedilom telesa

// Povečaj razmike med besedami v eni široki vrstici
Pdf.CurrentPage.SetWordSpacing(6);
Pdf.CurrentPage.SetFont('Arial', [], 11);
Pdf.CurrentPage.TextOut(72, 712, 0, 'Name        Department        Extension');
Pdf.CurrentPage.SetWordSpacing(0);

Razmik med besedami vpliva le na znak presledka (koda 32), kar ima pomembno posledico: ne deluje znotraj zapisov CJK, ki nimajo presledkov ASCII, in se nenavadno vede pri besedilu, kodiranem z indeksi glifov namesto z bajti. Za latinski tablični izpis je to enostaven način za razširitev vrzeli brez ponovnega tipkanja niza. Razmik med znaki je boljše orodje za glavo, ki mora doseči ciljno širino, saj prilagoditev porazdeli enakomerno med vse glife namesto kopičenja le na presledkih

Ponastavitev zahteva disciplino. Razmiki so - tako kot pisava - del risalnega stanja strani, in stanje ostane nespremenjeno, dokler ga ne spremenite. Če dodate razmik med znaki eni glavi in pozabite vrednost vrniti na nič, bo vsak odstavek spodaj podedoval to razširitev, kar deluje kot komaj zaznavna napaka, ki uide površnemu pregledu, a ne natančnemu. Zanesljiva navada je: nastavite vrednost razmika, izrišete besedilo in ga v naslednji vrstici vrnete na nič, tako da poznejši kodi ni treba vedeti, kaj je počela prejšnja sekcija

Stran TextOut HotPDF, ki primerja vodoravno merjenje besedila, razmik znakov, razmik besed ter načina upodabljanja polnilo proti potezi

Preverjanje izhoda tam, kjer se dejansko zalomi

Postavitev besedila spodleti na drugem računalniku, ne na prvem, zato se ključna preverjanja izvajajo stran od vaše mize. Odprite generirano datoteko v sistemu brez nameščenih razvijalskih pisav in se v enem koraku - ne z iskanjem le enostavnih znakov - prepričajte, da se vgrajene pisave pravilno izrišejo, vključno z latinskimi znaki z diakritiki, vsemi ne-latinskimi pisavami in ločili. Označite in kopirajte nekaj vrstic, da potrdite, da gre za dejansko besedilo in ne za orise - kar postane važno takoj, ko je v igri iskanje ali pridobivanje besedila. V postavitev vstavite reprezentativne podatke - najdaljšo nemško oznako in najširšo številko, ne pa urejenih začasnih vrednosti - ker polje, ki se prelije, je vedno tisto, ki ga niste vnesli ročno. Če mora stran pristati na že natisnjeni obrazec, natisnite ali rasterizirajte en vzorec in ga primerjajte z izvirnikom; četrtmilimetrski odklon izhodiščne črte je na zaslonu neviden, na papirju pa očiten

Če še niste napisali niti ene strani, začnite s primerom HotPDF Hello World, ki nastavi dokument, pisavo in koordinatni sistem spodaj-levo, od katerega je odvisno vse zgoraj opisano. Klici TextOut, SetFont in nastavitve razmikov, prikazani tukaj, so del komponente HotPDF Delphi Component za Delphi in C++Builder