PDF, jehož záhlaví neslo pozadí s přechodem ve stylu Wordu nebo Excelu, se při vykreslení do obrázku vracelo s prázdným bílým obdélníkem v místech, kde měla být barevná směs. Vykreslovač stránek HotPDF nyní respektuje operátor PDF `sh` (shading/stínování) pro axiální přechody typu 2 (axial) a radiální přechody typu 3 (radial): vyhodnocuje funkci stínování podél osy přechodu a vykresluje barevnou směs, zatímco dřívější verze operátor potichu ignorovaly a ponechávaly oblast bílou jako papír. Dva typy stínování, které pokrývají téměř všechny přechody kancelářských dokumentů, jsou podporovány; síťové typy (mesh) nikoli, a tento článek upřímně popisuje, kde tato hranice leží
Proč se přechod PDF vykresluje jako bílý obdélník?
Přechod PDF je vektorový konstrukt, nikoli bitmapa, kterou by vykreslovač mohl blitovat. Slovník stínování (ISO 32000-1 §8.7.4.5) popisuje geometrii — osu nebo dvojici kružnic v poli `Coords` — a barevnou funkci, přičemž operátor `sh` vykresluje toto stínování napříč aktuální oblastí ořezu. Jde o stejný grafický model, jaký HotPDF vystavuje, když kreslíte cesty a výplně na plátno stránky. Vykreslovač stránek HotPDF prochází tok obsahu operátor po operátoru a jakýkoli operátor, pro který nemá kódovou cestu, přeskočí, takže se zbytek stránky stále vykreslí. Před verzí 2.335.0 patřil `sh` do této přeskočené sady: přechod v záhlaví nebo na celé stránce nepřispíval k výstupu ničím, takže pozadí prosvítalo jako bílé. Soubor nebyl nikdy poškozen. Vykreslovač jednoduše neměl obsluhu pro tento jeden operátor a bílý box je přesně to, jak chybějící obsluha vypadá
Řetězec vyhodnocování funkcí za stínováním
Stínování nelze vykreslit, dokud není vyhodnocena jeho funkce, takže tato mašinérie musela dorazit jako první. Axiální stínování typu 2 a radiální stínování typu 3 nesou `/Function`, která mapuje parametrickou pozici podél přechodu na barvu (ISO 32000-1 §7.10), a vyhodnocovač funkcí HotPDF tuto hodnotu `FunctionType` rozliší a provede. Typ 2 exponenciální interpolace (§7.10.3) počítá `C0 + t^N * (C1 - C0)` s ořezáním `Domain` a `Range`; vzorkované funkce typu 0 (§7.10.2) čtou mřížku 8-, 16- nebo 32bitových vzorků a vybírají nejbližší prostřednictvím mapy `Encode`, což je případ podrobně popsaný v našem průvodci vzorkovaným vyhledáváním barev typu 0; skládané (stitching) funkce typu 3 (§7.10.4) vybírají podfunkci podle pole `Bounds` a rekurzivně do ní vstupují. PostScriptové kalkulační funkce typu 4 (§7.10.5) se nevyhodnocují — degradují elegantně na selhání vyhodnocení namísto nesprávné barvy, což odpovídá konzervativní politice, kterou HotPDF uplatňuje napříč celou cestou vykreslování. Tento vyhodnocovač byl dodán ve verzi 2.334.0, o jedno vydání dříve než samotný operátor, protože vykreslovač stínování je jen tak dobrý, jak dobrá je funkce pod ním
Jak HotPDF převádí spojitý přechod na pixely?
HotPDF aproximuje spojitou směs konečnou řadou pásů plných barev. Vykreslovač stínování prochází osu přechodu, rozděluje ji až na 64 pásů — méně, když je osa v pixelech zařízení krátká —, vyhodnocuje funkci v parametrické pozici každého pásu a vyplňuje obdélník kolmý k ose plným štětcem. Kompromisem je počet pásů vůči hladkosti: více pásů sleduje směs přesněji, ale stojí více výplní, a 64 je záměrný strop. Protože se počet také škáluje s délkou osy v pixelech zařízení, na rozlišení záleží. Vykreslení stejné stránky při vyšším DPI prodlužuje osu, takže krátký přechod získá více pásů a jeho pruhy se zjemní, dokud není dosaženo stropu
// Vykreslovač stínování používá až 64 barevných pásů podél osy přechodu
// ale nikdy ne více, než kolik pixelů zařízení osa měří. Vykreslení
// stejné stránky při vyšším DPI prodlužuje tuto osu, takže krátký přechod
// získá více pásů a pruhování se zjemní, dokud nenarazí na strop 64 pásů.
Thumb := Pdf.RenderLoadedPageToBitmap(PageIndex, 96); // hrubší pásy
Proof := Pdf.RenderLoadedPageToBitmap(PageIndex, 300); // až 64 pásů
Vykreslení stínované stránky do bitmapy
Veřejný vstupní bod se nemění: `RenderLoadedPageToBitmap` přijímá od nuly indexovaný index stránky a hodnotu DPI, vrací bitmapu vlastněnou volajícím a při selhání vrací `nil`, namísto vyvolání výjimky, takže podpora stínování je transparentní pro kód, který již máte. Stránka, která dříve vykreslovala záhlaví s přechodem jako prázdné, nyní vrací stejnou bitmapu s vykreslenou barevnou směsí a pro její získání není nutná žádná změna API. Jedinou věcí, kterou stojí za to si pamatovat, je vlastnictví: volající uvolňuje vrácenou bitmapu. Celý vykreslovací proces — interpretace toku obsahu, vložené znaky a mezipaměť stránek — je popsán v průvodci vykreslováním stránek PDF do bitmapy v Delphi
var
Pdf: THotPDF;
Bmp: TBitmap;
begin
Pdf := THotPDF.Create(nil);
try
if Pdf.LoadFromFile('quarterly-report.pdf') > 0 then
begin
// Stránka 1 (indexovaná od 0) při 150 DPI. Záhlaví s výplní přechodu, které
// dříve vycházelo prázdné, nyní nese svou barevnou směs.
Bmp := Pdf.RenderLoadedPageToBitmap(0, 150);
if Assigned(Bmp) then
try
Bmp.SaveToFile('page1.bmp');
finally
Bmp.Free;
end;
end;
finally
Pdf.Free;
end;
end;
Levný strážce regrese vyplývá ze stejného volání. Vykreslete stránku, odeberte vzorek pixelu v místě, kam pás přechodu patří, a potvrďte, že již není bílý jako papír, což byl původní fallback vykreslovače — jednořádková kontrola, která zachytí tichý návrat k dřívějšímu prázdnému chování
Bmp := Pdf.RenderLoadedPageToBitmap(0, 150);
if Assigned(Bmp) then
try
// True, pokud operátor sh maloval; False, pokud region spadl do bílé.
HeaderPainted := Bmp.Canvas.Pixels[Bmp.Width div 2, 8] <> clWhite;
finally
Bmp.Free;
end;
Co HotPDF nemaluje: stínování mřížky (mesh) a ořezové hrany
Čtyři síťové typy stínování jsou mimo rozsah a měli byste to vědět. Volné sítě trojúhelníků Gouraud (typ 4), mřížkové sítě Gouraud (typ 5), sítě plátů Coons (typ 6) a sítě plátů s tenzorovým součinem (typ 7), definované v normě ISO 32000-1 §8.7.4.5.5 až §8.7.4.5.8, se nevykreslují; stránka, která je používá, se přesto vykreslí, avšak tato oblast zůstane v původním stavu. Dvě další okrajové situace stojí za to uvést na rovinu. Obdélníky pásů pokrývají pruh stínování, namísto toho, aby byly oříznuty přesně podle aktuální ořezové cesty, takže přechod maskovaný do zaobleného nebo nepravidelného tvaru se vykresluje jako jeho ohraničující pruh, dokud v pozdějším kole nedorazí přesné ořezávání regionů. HotPDF také předpokládá, že výstupem funkce je RGB nebo odstíny šedi, takže stínování vytvořené v CMYK nebo exotickém barevném prostoru se aproximuje, spíše než aby bylo spravováno barevným profilem. Pro dokumenty, které většina vývojových týmů Delphi a C++Builder skutečně zpracovává — reporty, faktury, výpisy a prezentace exportované do PDF —, axiální a radiální stínování pokrývá v podstatě každý přechod, se kterým se setkáte, a síťově náročné designové nátisky jsou případem, se kterým je třeba zacházet jako s náhledem, nikoli jako s finálním tiskem
Vykreslovač stránek HotPDF, zde popsaná podpora operátoru `sh` a vyhodnocovač funkcí typu 0/2/3 pod ním se dodávají jako součást HotPDF Component pro Delphi a C++Builder — nativní knihovny VCL bez externích závislostí na DLL, která v jednom balíčku pokrývá vytváření, úpravy, extrakci textu a vykreslování stránek PDF