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

HotPDF TextOut page showing Arial, Times New Roman, and Courier New rendered with regular, bold, and italic styles across several character sets

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

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');

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

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;       // 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;

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

// 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);

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

HotPDF TextOut page comparing horizontal text scaling, character spacing, word spacing, and fill versus stroke rendering modes

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 Component za Delphi in C++Builder