Technical Article

HotPDF crtanje na platnu u Delphiju: Vektorske staze i boja

HotPDF crta vektorsku grafiku tako da izgradi stazu (path) na trenutnoj stranici i zatim zatraži njezino bojanje. Između toga nema koraka pretvorbe u bitmapu. Linija koju nacrtate pomoću MoveTo i LineTo završava kao PDF operator staze u toku sadržaja, tako da ostaje pravi vektor: oštar na 50% zumiranja, oštar na 1600% i predstavlja samo dio veličine koju bi zauzela rasterizirana verzija. Za dijagrame, obrube tablica, osi grafikona i ukrase obrazaca, to je upravo ono što želite, a API koji stoji iza toga dovoljno je jednostavan da se nauči u jednom navratu.

Cijela površina za crtanje nalazi se na objektu THotPDF.CurrentPage. Između poziva BeginDoc i EndDoc postavljate boju i širinu linije na tom objektu stranice, definirate geometriju i pozivate operator crtanja kako biste je primijenili. Četiri osnovna oblika koja ćete najčešće koristiti su MoveTo i LineTo za proizvoljne staze, Rectangle za pravokutnike, Circle za krugove te dva operatora iscrtavanja: Stroke (obrub) i Fill (ispuna).

Koordinatni sustav je dolje-lijevo

Ovo je stvar koja zbunjuje svakoga tko dolazi iz VCL okruženja. TCanvas kojim crtate kontrole postavlja ishodište u gornji lijevi kut s Y koji raste prema dolje. PDF radi suprotno. HotPDF mjeri udaljenost od donjeg lijevog kuta stranice u točkama (1/72 inča), pri čemu se Y povećava prema gore. Točka na Y := 720 nalazi se blizu vrha US Letter stranice, koja je visoka 792 točke, dok se Y := 50 nalazi blizu dna. Ako vaš prvi crtež ispadne okomito zrcaljen, to je razlog: kod prenesen s grafike zaslona pretpostavlja pogrešan smjer i prelazi preko donjeg ruba.

Isto pravilo vrijedi i za TextOut, pa tekst i oblici dijele isti mentalni model nakon što ga jednom usvojite. Planirajte raspored tako da odlučite gdje se nalazi dno svakog elementa, a ne vrh, i sve ostalo dolazi samo po sebi.

Staze: MoveTo, LineTo, Stroke

Obrubljena staza (stroked path) je poput olovke koja se podiže, spušta i povlači. MoveTo podiže olovku i postavlja početnu točku bez ostavljanja traga. Svaki poziv LineTo produžuje trenutnu stazu do nove točke. Ništa se ne pojavljuje na stranici dok ne pozovete Stroke, koji iscrtava nakupljenu stazu koristeći trenutnu boju obruba i širinu linije, a zatim čisti stazu tako da sljedeći MoveTo počinje iznova.

Dva detalja štede stvarno vrijeme za otklanjanje pogrešaka. Širina linije je stanje, a ne argument: SetLineWidth je postavlja jednom i svaki sljedeći Stroke koristi tu vrijednost dok je ponovno ne promijenite, zbog čega je gornja izlomljena linija deblja od obične crte. Također, staza se resetira nakon svakog poziva Stroke, pa zaboravljeni Stroke znači da se geometrija koju ste tako pažljivo rasporedili uopće neće prikazati. Ako oblik nedostaje u izlazu, poziv za iscrtavanje je prvo mjesto koje trebate provjeriti.

Koordinate su točke, a točke mogu biti i decimalni brojevi. MoveTo i LineTo prihvaćaju Single vrijednosti, pa je tanka linija od 0,5 točaka ili položaj na 72,25 dopušten i smislen, a ne zaokružen na najbližu cijelu jedinicu. Ta je preciznost važna u dva suprotna smjera. Širina linije manja od oko 0,5 može se prikazati kao najtanja moguća linija ovisna o uređaju, koja nestaje na zaslonu i ponovno se pojavljuje kada se ispiše, pa vidljiva crta zahtijeva širinu koju ste namjerno postavili, a ne zadani minimum. S druge strane, poravnavanje obruba tablice i mreže na cijele točke sprječava da gusta mreža izgleda neravno na mjestima gdje se susjedne linije različito zaokružuju. Odlučite o razmaku mreže u točkama unaprijed, a ostatak rasporeda će ga naslijediti.

Ispunjeni oblici i boja

Zatvoreni primitivni oblici mogu se ispuniti umjesto da im se samo iscrta obrub. Rectangle prima položaj i veličinu, Circle prima središte i polumjer, a oba se primjenjuju s Fill, što boji unutrašnjost trenutnom bojom ispune, ili s Stroke za samo obrub. Boja ispune i boja obruba odvojeni su dijelovi stanja, a postavljaju se pomoću SetRGBFillColor i SetRGBStrokeColor, koji primaju jedan TColor. To znači da možete izravno ponovno koristiti Delphi konstante boja i pomoćnu funkciju RGB.

Pripazite na format argumenata u Rectangle. To je položaj-plus-veličina (X, Y, širina, visina), a ne dva suprotna kuta. Metoda TCanvas.Rectangle koju Delphi programeri dobro poznaju prima (Left, Top, Right, Bottom), pa će po navici proslijediti drugi kut tamo gdje HotPDF očekuje širinu i visinu, pa će okvir ispasti pogrešne veličine. Par (X, Y) predstavlja donji lijevi kut, u skladu s ishodištem stranice. Za krug, (X, Y) je središte, a treći argument je polumjer u točkama.

Jedan izbor boja u kojem je izvorni primjer pogriješio

Starija verzija ovog primjera postavljala je boje pomoću Random($FFFFFF) za svaki oblik. To izgleda šareno, ali to je kriva navika za generirane dokumente. PDF koji gradite iz koda obično je nešto što želite i testirati, a nasumične boje ispune onemogućuju usporedbu izlaza od pokretanja do pokretanja: usporedba bajt-po-bajt s poznatom ispravnom datotekom neće uspjeti svaki put, bez ikakvog stvarnog razloga. Odaberite eksplicitne boje. Kada želite raznolikost kroz niz oblika, vodite se svojim podacima ili fiksnim nizom palete boja, tako da isti unos uvijek proizvodi istu datoteku. Determinizam vrijedi više od noviteta kada se datoteka kreće kroz sustav za provjeru izdanja.

Gdje se vektorsko crtanje isplati, a gdje ne

Posegnite za ovim pozivima staza i oblika kada se geometrija generira: mreže i stupci grafikona, obrube tablice na računu, okviri s objašnjenjima na dijagramu ili logotip prikazan kroz nekoliko staza. Sve se to skalira bez zamućenja i ne dodaje gotovo ništa veličini datoteke, jer je pravokutnik samo nekoliko brojeva umjesto tisuća piksela. Naravno, vrijedi i obrnuto. Ako zapravo imate fotografiju ili snimku zaslona, radije je prikažite kao sliku pomoću AddImage i ShowImage; iscrtavanje bitmape vektorskim pozivima ne donosi nikakvu korist. Složene krivulje također su izvan ovog opsega. Gore navedeni oblici su ravni segmenti, pravokutnici i krugovi, što pokriva veliku većinu stvarnog rada na izvještajima; sve što zahtijeva slobodne Bezierove krivulje dio je drugog API-ja.

Preostala navika koju vrijedi zadržati je provjera. Generirana geometrija može raditi na vašem računalu, a zakazati na klijentovom, obično zbog zamjene fonta u tekstu koji miješate ili pretpostavke o veličini stranice koja ne stoji. Otvorite gotovu datoteku na nekoliko razina zumiranja kako biste potvrdili da rubovi ostaju čisti i provjerite leži li svaki oblik unutar okvira margina koji ste zamislili. Uz determinističku shemu boja, ta se provjera može automatizirati u odnosu na referentni PDF umjesto pukog vizualnog pregleda.

Pozivi MoveTo, LineTo, Stroke, Fill i postavke boja prikazani ovdje dio su HotPDF komponente za Delphi i C++Builder.