HotPDF gjengir en innlastet PDF-side til en Delphi TBitmap gjennom ett enkelt kall: RenderLoadedPageToBitmap(PageIndex, DPI). Funksjonen tolker sidens innholdsstrøm og returnerer et 24-biters RGB-bitmap som den som kaller funksjonen eier, i den oppløsningen du velger, noe som er akkurat det en miniatyrbildestripe, en utskriftsforhåndsvisning eller en PDF-til-bilde-eksportpipeline trenger. Denne artikkelen går gjennom API-et, og deretter gjennom den delen som skiller en brukbar gjengivelsesmotor fra et leketøy: å tegne tekst fra selve de innebygde fontprogrammene i stedet for fra systemfonter som bare ligner
Hvorfor er det vanskeligere å gjengi en PDF-side enn å tegne et bilde?
En PDF-side er ikke et bilde. Det er et program: en strøm av operatorer som bygger baner, velger fonter, angir farger og plasserer glyffer, kjørt mot grafikkmodellen definert i ISO 32000-1 §8. Ingenting i filen sier hvordan en gitt piksel skal se ut. For å produsere et bitmap må du kjøre dette programmet — vedlikeholde en gjeldende transformasjonsmatrise, en grafikktilstandsstakk for q/Q, en klippebane, fyll- og strekfargerom — og rasterisere resultatet. Det er derfor "bare vis side 3 som et bilde" er en innholdsstrøm-tolker, ikke en filformatkonvertering
HotPDFs gjengivelsesmotor, introdusert i v2.253.0, er bygget som seks frikoblede enheter som gjenspeiler denne modellen: en affin-matrisekjerne for PDF-ens [a b c d e f]-transformasjonsalgebra, en grafikktilstandsstakk, en fargeromsløser (DeviceRGB, DeviceGray, DeviceCMYK, Indexed), en banebygger som knytter PDF-ens baneoperatorer til GDI, et fontmetrikk-lag som leser /Widths-tabeller for korrekte forskyvninger, og tolkeren som dispatcher operatorer og driver de fem andre. Bilde-XObjects går gjennom den samme dekodingsstakken biblioteket bruker for utpakking, så alle bildefiltre HotPDF kan dekode for utpakking — inkludert JPXDecode-komprimerte JPEG 2000-bilder — vises også i gjengitt utdata
Å gjengi en innlastet side til et TBitmap
RenderLoadedPageToBitmap tar en nullbasert sideindeks og en DPI-verdi, der 72 DPI tilsvarer at én PDF-brukerromsenhet blir til én piksel. Den returnerer nil ved feil (indeks utenfor gyldig område, manglende ressurser) i stedet for å kaste et unntak, slik at en fremviser kan hoppe over en defekt side og fortsette. Den som kaller funksjonen eier det returnerte bitmapet og må frigjøre det
var
Pdf: THotPDF;
Bmp: TBitmap;
begin
Pdf := THotPDF.Create(nil);
try
if Pdf.LoadFromFile('report.pdf') > 0 then
begin
Bmp := Pdf.RenderLoadedPageToBitmap(0, 144); // side 1 ved 144 DPI
if Bmp <> nil then
try
Image1.Picture.Assign(Bmp);
finally
Bmp.Free; // den som kaller funksjonen eier bitmapet
end;
end;
finally
Pdf.Free;
end;
end;
DPI-argumentet gjør skaleringsarbeidet for alle vanlige scenarioer. En miniatyrbildestripe gjengis ved 36 eller 48 DPI og gir små, raske bitmap; en forhåndsvisning på skjerm ved 96 eller 144 DPI matcher typisk skjermtetthet; en eksportbane ved 300 DPI produserer bilder i utskriftskvalitet. Siderotasjon fra /Rotate-oppføringen og origo-vendingen i /MediaBox (PDF plasserer origo nede til venstre, GDI oppe til venstre) håndteres inne i side-til-enhet-matrisen, slik at en US Letter-side ved 72 DPI kommer tilbake som nøyaktig 612×792 piksler med riktig vei opp
Hvorfor viser gjengitte PDF-miniatyrbilder feil glyffer?
Feil eller tilnærmede glyffer i gjengitt PDF-utdata betyr nesten alltid at gjengivelsesmotoren erstatter med en systemfont i stedet for å bruke fonten som er innebygd i filen. Den første HotPDF-gjengivelsesmotoren gjorde nettopp det: den fjernet undersett-prefikset fra /BaseFont (slik at ABCDEF+Arial ble til Arial), ba GDI om en systemfont med det navnet, og tegnet teksten med den. For et dokument som bruker Arial eller Times New Roman med standard koding, ser resultatet noenlunde riktig ut. Men det er en tilnærming, og den bryter sammen på veldefinerte måter
Undersett-innebygde fonter er verstefallet. En undersett-font inneholder kanskje bare de førti glyffene et dokument faktisk bruker, med tegnkoder tildelt i en rekkefølge som er privat for den filen — kode 1 kan være "T", kode 2 "h", og så videre. En systemfont vet ingenting om denne private tildelingen, så teksten forsvinner enten eller kommer ut som helt feil tegn. Egendefinerte kodinger, symbolfonter, strekkodefonter og enhver font som ikke er installert på gjengivelsesmaskinen feiler på samme måte. En gjengivelsesmotor som stopper ved systemfont-erstatning produserer miniatyrbilder som er gjenkjennelige som siden — helt til siden bruker fontene som gjorde innebygging nødvendig i utgangspunktet
Gjengivelse av innebygde glyffer: å tegne fra selve fontprogrammet
HotPDF tettet dette gapet gjennom fem utgivelser (v2.268.0 til v2.272.0) ved å tolke de innebygde fontprogrammene og gjenskape glyff-konturene deres som fylte GDI-vektorbaner. Tekst i en gjengitt side kommer nå fra de samme kontur-dataene en spesifikasjonstro fremviser bruker, noe som betyr at undersett-fonter, egendefinerte kodinger og ikke-installerte fonter gjengis med sine eksakte former. Dekningen ble bygget opp etter fonttype:
For Type0/CIDFontType2-fonter med et innebygd TrueType-program (FontFile2), tolker gjengivelsesmotoren glyf- og loca-tabellene direkte: kvadratiske konturer konverteres til de kubiske Bézier-kurvene GDI forstår, underforståtte på-kurve-punkter mellom påfølgende av-kurve-punkter rekonstrueres, og sammensatte glyffer gjenskapes rekursivt. Både Identity- og eksplisitte strøm-CIDToGIDMap-oppsett støttes, og CID-forskyvninger følger /W- og /DW-breddeoppføringene, slik at to-bytes Identity-H-tekst steppes korrekt
CFF-programmer (FontFile3, enten CIDFontType0C, Type1C, eller en OpenType-wrapper) får en fullstendig Type 2-charstring-tolker: linjer, kurver, flex-familien, hint-masker, og lokale/globale subrutinekall med korrekt subrutine-bias. CID-nøklede CFF-programmer mapper tegnkoder gjennom fontens charset, noe som er viktig for undersett-fonter der glyff-rekkefølgen skiller seg fra CID-rekkefølgen, og per-glyff font-DICT-valg gjennom FDArray/FDSelect respekteres. Enkle (ikke-CID) TrueType-fonter løser en-bytes koder gjennom den innebygde fontens egen cmap-tabell med en robust kjede av undertabeller — Unicode-formatene 4 og 12 først, deretter symbol-undertabeller med F000-privatbruksspeilet, så eldre Macintosh-formater — mens enkle Type1-fonter løses gjennom CFF-programmets innebygde koding
To finpussinger fullfører bildet. For det første løses /Encoding-ordbøker for enkle fonter etter prioriteringen ISO 32000-1 §9.6.6 foreskriver: /Differences-tabeller overstyrer basiskodingen, som igjen overstyrer fontprogrammets eget map — samme sti som TeX- og PostScript-avledede verktøykjeder er avhengige av, der glyffnavn løses gjennom Adobe Glyph List, CFF-charsettet, eller TrueType-cmap-en. For det andre gjenskapes Type3-fonter, der glyffene selv er små innholdsstrømmer, gjennom gjengivelsesmotoren med fontmatrisen, fontstørrelsen og tekstmatrisen sammensatt; /Widths i glyff-rom tolkes gjennom /FontMatrix slik ISO 32000-1 §9.6.5 krever, og glyff-prosedyrer som erklærer en d1-avgrensningsboks klippes til den, slik at en feilformet strekkodeglyff ikke kan male utenfor sin celle. Når en kode ikke kan mappes — et skadet program, et umappet tegn — faller gjengivelsesmotoren tilbake til systemfont-tegning for den glyffen i stedet for å droppe hele tekstlinjen
Hvordan gjør man gjentatte gjengivelser raske?
Svaret HotPDF leverer er en cache for sist brukte sider: RenderLoadedPageToBitmapCached holder opptil RenderCacheCapacity gjengitte sider (standard 8) nøkket på sideindeks og DPI, og et cache-treff returnerer en fersk kopi som den som kaller funksjonen eier, uten å røre innholdsstrømmen — typisk tusenvis av ganger raskere enn å tolke siden på nytt. Dette mønsteret passer fremvisere perfekt: en bruker som bytter mellom to sider, eller en resize-hendelse som ber om den samme siden ved samme DPI på nytt, treffer cachen hver gang
// Miniatyrbildestripe: første gjennomgang gjengir, tilbakescrolling treffer cachen
for I := 0 to ThumbCount - 1 do
begin
Bmp := Pdf.RenderLoadedPageToBitmapCached(I, 48);
if Bmp <> nil then
try
ThumbList.AddThumbnail(I, Bmp);
finally
Bmp.Free;
end;
end;
// Etter redigering av en innlastet side direkte:
Pdf.InvalidateRenderedPageCache; // neste gjengivelse reflekterer endringen
Vær ærlig med deg selv om minneregningen før du øker kapasiteten. En US Letter-side ved 300 DPI er 2550×3300 piksler, omtrent 25 MB som et 24-biters bitmap, så åtte cachede sider ved eksportoppløsning tar omtrent 200 MB. Ved miniatyrbilde-DPI koster de samme åtte oppføringene godt under en megabyte. Dimensjoner RenderCacheCapacity for DPI-en du faktisk cacher på, og kall InvalidateRenderedPageCache etter enhver direkte redigering — cachen er kun nøklet på side og DPI, og den kan ikke se at det underliggende innholdet er endret. Å laste inn et nytt dokument tømmer den automatisk
En annen cache jobber under sidecachen: dekodede bilde-XObjects holdes i et byte-budsjettert lager avgrenset av ImageCacheMaxBytes (standard 32 MB) med utkasting av minst nylig brukte. Et logo- eller brevhode-bilde som gjentas på hver side dekodes én gang per dokumentlasting i stedet for én gang per Do-operator, noe som omtrent halverer gjengivelsestiden for sider med delte bilder og gir tilsvarende fartsøkning for eksport av flersides TIFF. InvalidateRenderedPageCache tømmer også denne cachen
Hva som fortsatt gjengis tilnærmet
Gjengivelsesmotoren retter seg mot den vanlige dokument-PDF-undermengden, og det er verdt å vite hvor grensene går. CalRGB-, Lab- og ICC-baserte fargerom tilnærmes i stedet for å fargestyres — enhetsfargerom, indekserte paletter og samplede Type 0-funksjons-fargeoppslag håndteres, men en trykkeriproduksjonsfil som er avhengig av ICC-gjengivelsesintensjoner vil ikke være fargemessig eksakt. Skyggeleggingsmønstre (sh) og blandingsmoduser utover enkel alfa er likeledes utenfor omfanget, og Form-XObject-rekursjon er dybdebegrenset som en syklusvakt. For fakturaer, rapporter, kontrakter og skjemaer — sider bestående av tekst, baner og bilder — er utdataet trofast; for en designkorrektur full av gradienter og transparensgrupper, bør du behandle bitmapet som en forhåndsvisning, ikke en korrektur
Den praktiske lesningen: hvis pipelinen din genererer dokumenter med HotPDF eller konsumerer typiske forretnings-PDF-er, gjengir RenderLoadedPageToBitmap dem tur-retur med de eksakte innebygde glyff-formene, korrekte CID-forskyvninger og korrekt sidegeometri. Tilnærmingene finnes i de hjørnene av grafikkmodellen som forretningsdokumenter sjelden besøker
RenderLoadedPageToBitmap, den cachede varianten, og gjengivelsespipelinen for innebygde glyffer som er beskrevet her, leveres som en del av HotPDF Delphi Component for Delphi og C++Builder — et nativt VCL-bibliotek uten eksterne DLL-avhengigheter, som dekker PDF-opprettelse, redigering, tekstuttrekk og sidegjengivelse i én pakke