Renderovanjem PDF dokumenta čije zaglavlje nosi pozadinu sa gradijentom u stilu Word-a ili Excel-a u sliku, ranije se dobijao prazan beli pravougaonik na mestu gde bi trebalo da bude mešavina boja. HotPDF-ov renderer stranica sada poštuje PDF operator sh (shading - senčenje) za aksijalne gradijente tipa 2 i radijalne gradijente tipa 3: on procenjuje funkciju senčenja duž ose gradijenta i iscrtava mešavinu boja, dok su ranije verzije tiho odbacivale ovaj operator i ostavljale regiju belom kao papir. Dva tipa senčenja koja pokrivaju skoro svaki gradijent u kancelarijskim dokumentima su podržana, dok tipovi mreže (mesh types) nisu, i ovaj članak iskreno govori o tome gde se ta linija nalazi
Zašto se PDF gradijent renderuje kao beli okvir?
PDF gradijent je vektorska struktura, a ne bitmapa koju renderer može da prekopira (blituje). Rečnik senčenja (shading dictionary) (ISO 32000-1 §8.7.4.5) opisuje geometriju — osu ili par krugova u nizu Coords — plus funkciju boje, a operator sh iscrtava to senčenje preko trenutne regije isecanja (clip region). To je isti grafički model koji HotPDF izlaže kada crtate putanje i popunjavanja na platnu stranice. HotPDF-ov renderer stranice prolazi kroz tok sadržaja operator po operator, a svaki operator za koji nema napisanu putanju koda se preskače, tako da se ostatak stranice i dalje renderuje. Pre verzije 2.335.0, sh je živeo u tom preskočenom skupu: gradijent zaglavlja ili cele stranice nije doprinosio ništa izlazu, pa je pozadina sijala belom bojom. Datoteka nikada nije bila oštećena. Renderer jednostavno nije imao hendler za taj jedan operator, a beli okvir je upravo ono kako izgleda nedostajući hendler
Lanac procene funkcije iza senčenja
Senčenje se ne može iscrtati dok se ne proceni njegova funkcija, pa je taj mehanizam morao biti prvo implementiran. Aksijalna senčenja tipa 2 i radijalna senčenja tipa 3 nose /Function koja mapira parametarsku poziciju duž gradijenta u boju (ISO 32000-1 §7.10), a HotPDF-ov evaluator funkcija razrešava FunctionType i vrši raspoređivanje na osnovu njega. Eksponencijalna interpolacija tipa 2 (§7.10.3) izračunava C0 + t^N * (C1 - C0) sa ograničavanjem Domain i Range. Uzorkovane funkcije tipa 0 (§7.10.2) čitaju mrežu 8-, 16- ili 32-bitnih uzoraka i biraju najbliži preko Encode mape, što je slučaj detaljno pokriven u našem pregledu uzorkovanih pretraga boja tipa 0. Spajajuće (stitching) funkcije tipa 3 (§7.10.4) biraju podfunkciju pomoću niza Bounds i rekurzivno ulaze u nju. PostScript računske funkcije tipa 4 (§7.10.5) se ne procenjuju — one graciozno degradiraju na neuspešnu procenu umesto na pogrešnu boju, što odgovara konzervativnoj politici koju HotPDF vodi kroz putanju renderovanja. Ovaj evaluator je isporučen u verziji 2.334.0, jedno izdanje pre samog operatora, jer je crtač senčenja dobar samo onoliko koliko je dobra funkcija ispod njega
Kako HotPDF pretvara neprekidni gradijent u piksele?
HotPDF aproksimira neprekidnu mešavinu boja sa konačnim nizom traka jednobojnih boja. Crtač senčenja prolazi duž ose gradijenta, deli je na do 64 trake — manje kada je osa kratka u pikselima uređaja — procenjuje funkciju na parametarskoj poziciji svake trake i popunjava pravougaonik pravolinijski na osu punom četkicom. Kompromis je u broju traka naspram glatkoće: više traka preciznije prati mešavinu boja, ali košta više popunjavanja, a 64 je namerni plafon. Pošto se ovaj broj takođe skalira sa dužinom ose u pikselima uređaja, rezolucija je važna. Renderovanje iste stranice na višem DPI-ju produžava osu, tako da kratki gradijent dobija više traka i njegove pruge omekšavaju dok se ne dostigne plafon
// The shading discretizer uses up to 64 color bands along the gradient
// axis, but never more than the axis is long in device pixels. Rendering
// the same page at a higher DPI lengthens that axis, so a short gradient
// gains bands and the banding softens until the 64-band ceiling is hit.
Thumb := Pdf.RenderLoadedPageToBitmap(PageIndex, 96); // coarser bands
Proof := Pdf.RenderLoadedPageToBitmap(PageIndex, 300); // up to 64 bands
Renderovanje osenčene stranice u bitmapu
Javna ulazna tačka je nepromenjena: RenderLoadedPageToBitmap uzima indeks stranice u bazi od 0 i vrednost DPI, vraća 24-bitnu bitmapu u vlasništvu pozivaoca i vraća nil u slučaju neuspeha umesto da podiže izuzetak, tako da je podrška za senčenje transparentna za kod koji već imate. Stranica koja je ranije renderovala svoje zaglavlje sa gradijentom kao prazno, sada vraća istu bitmapu sa iscrtanom mešavinom boja, i nije potrebna promena API-ja da bi se to postiglo. Jedina stvar koju vredi zapamtiti je vlasništvo: pozivalac oslobađa vraćenu bitmapu. Kompletan proces renderovanja — interpretacija toka sadržaja, ugrađeni glifovi i keširanje stranica — pokriven je u vodiču za renderovanje PDF stranica u bitmapu u Delphi-ju
var
Pdf: THotPDF;
Bmp: TBitmap;
begin
Pdf := THotPDF.Create(nil);
try
if Pdf.LoadFromFile('quarterly-report.pdf') > 0 then
begin
// Page 1 (zero-based) at 150 DPI. A gradient-filled header that
// used to come back blank now carries its color blend.
Bmp := Pdf.RenderLoadedPageToBitmap(0, 150);
if Assigned(Bmp) then
try
Bmp.SaveToFile('page1.bmp');
finally
Bmp.Free;
end;
end;
finally
Pdf.Free;
end;
end;
Jednostavna provera ispravnosti (regression guard) proizilazi iz istog poziva. Renderujte stranicu, uzorkujte piksel na mestu gde gradijent pripada, i potvrdite da to više nije bela boja papira na koju se renderer ranije vraćao — provera u jednoj liniji koja sprečava tihi povratak na prethodno ponašanje bez operacija:
Bmp := Pdf.RenderLoadedPageToBitmap(0, 150);
if Assigned(Bmp) then
try
// True when the sh operator painted; False if the region fell back to white.
HeaderPainted := Bmp.Canvas.Pixels[Bmp.Width div 2, 8] <> clWhite;
finally
Bmp.Free;
end;
Ono što HotPDF ne crta: mrežasta senčenja i ivice isecanja
Četiri tipa mrežastog senčenja (mesh shading) su van opsega, i to bi trebalo imati na umu. Slobodne Gouraud trouglaste mreže (Tip 4), rešetkaste Gouraud mreže (Tip 5), Coons-ove krpljene mreže (Tip 6) i tenzorske krpljene mreže (Tip 7), definisane u standardu ISO 32000-1 od §8.7.4.5.5 do §8.7.4.5.8, ne renderuju se. Stranica koja koristi neki od njih se i dalje renderuje, ali se ta regija ostavlja kakva jeste. Još dve granične situacije vredi jasno navesti. Pravougaonici traka pokrivaju opseg senčenja umesto da budu precizno isečeni na trenutnu putanju isecanja, pa se gradijent maskiran u zaobljeni ili nepravilan oblik iscrtava kao njegova granična traka dok se ne uvede precizno isecanje regija u kasnijoj fazi razvoja. HotPDF takođe pretpostavlja da je izlaz funkcije RGB ili nijanse sive, tako da se senčenje kreirano u CMYK ili nekom egzotičnom prostoru boja aproksimira umesto da se upravlja bojama. Za dokumente koje većina Delphi i C++Builder timova zapravo obrađuje — izveštaje, fakture, izvode i prezentacije izvezene u PDF — aksijalni i radijalni tipovi pokrivaju praktično svaki gradijent na koji ćete naići, dok su dizajnerski dokazi bogati mrežama slučajevi koje treba tretirati kao vizuelni pregled, a ne kao precizan dokaz
HotPDF-ov renderer stranica, ovde opisana podrška za operator sh i evaluator funkcija tipa 0/2/3 ispod njega isporučuju se kao deo HotPDF komponente za Delphi i C++Builder — izvorne VCL biblioteke bez eksternih DLL zavisnosti, koja pokriva kreiranje, izmenu, ekstrakciju teksta i renderovanje PDF stranica u jednom paketu