A HotPDF három hívás segítségével nyomtatja ki a betöltött PDF-et fizikai nyomtatóra, bármely Windows eszköz-kontextusra (device context) vagy a vágólapra: a PrintLoadedDocument egy VCL TPrinter-t vezérel, a RenderLoadedPageToDC közvetlenül egy tetszőleges HDC-be rajzolja az oldalt, a RenderLoadedPageToClipboard pedig bitképként vagy vektoros metafile-ként másolja azt a vágólapra. A HotPDF egy natív VCL PDF komponens Delphihez és C++Builderhez, és ezt a prémium nyomtatási útvonalat a v2.331.0 verzióban vezette be, majd a v2.348.0 verzióban finomította, így többé nem kell kézzel megírnia a bitkép-renderelő köré épülő TPrinter ciklust. Mindhárom hívás közvetlenül oda rajzolja az oldal vektoros tartalmát, ahová kell, így a nyomtatás olyan éles marad, amilyet csak a nyomtató képes előállítani
Miért érdemes a PDF oldalt közvetlenül a nyomtatóra rajzolni bitkép helyett?
Egy PDF oldal vektoros rajzoló operátorok programja – útvonalak, szövegek és képek, amelyek az ISO 32000-1 grafikai modell szerint hajtódnak végre –, nem pedig pixelek rácsa. Nyomtatásának kézenfekvő módja az lenne, ha az oldalt bitképpé rasztereznénk, majd ezt a bitképet átvinnénk a nyomtató vásznára (canvas), ami működik is, de eldobja azt az egyetlen dolgot, amiben a nyomtató jó. Egy modern lézernyomtató 600 vagy 1200 DPI-t képes feloldani; egy 150 vagy 300 DPI-vel raszterezett, majd a mérethez nyújtott bitkép lágyan, életlenül érkezik meg, recés szövegszélekkel és látható interpolációval. A RenderLoadedPageToDC a jobb utat választja: újra lejátsza az oldal tartalomfolyamát közvetlenül a cél eszköz-kontextusba kibocsátott GDI hívásokként, így a vektoros szöveg és vonalas rajz vektorként éri el a nyomtatót, és a nyomtató saját felbontásán, a nyomtató által rasztereződik le egyszer
Hogyan nyomtatható egy betöltött PDF fizikai nyomtatóra Delphiben?
A HotPDF a betöltött dokumentumot a PrintLoadedDocument(Printer, Options) segítségével nyomtatja ki, amely egy hozzárendelt VCL TPrinter-t és egy THPDFPrintOptions rekordot vesz át, kinyomtatja a kiválasztott oldalakat, és visszaadja az elküldött oldalak számát. Először állítsa be a Printer.PrinterIndex-et az eszköz kiválasztásához, töltsön ki egy opciós rekordot – a THPDFPrintOptions.Default osztályfüggvény ésszerű értékeket ad –, és hívja meg egyszer. A könyvtár a nyomtatási feladatot a Printer.BeginDoc hívással nyitja meg, végigmegy az oldaltartományon egy-egy Printer.NewPage hívást kibocsátva az oldalak között, majd a Printer.EndDoc segítségével zárja le azt, így a feladat életciklusát soha nem kell manuálisan kezelnie
uses Printers;
var
Pdf: THotPDF;
Opts: THPDFPrintOptions;
begin
Pdf := THotPDF.Create(nil);
try
if Pdf.LoadFromFile('invoice.pdf') > 0 then
begin
Printer.PrinterIndex := -1; // -1 selects the default printer
Opts := THPDFPrintOptions.Default; // all pages, 300 DPI, FitPage, colour
Opts.PageRange := '1,3-5'; // one-based; empty prints every page
Opts.Copies := 2;
Pdf.PrintLoadedDocument(Printer, Opts);
end;
finally
Pdf.Free;
end;
end;
A PageRange karakterlánc 1-alapú, és úgy olvasható, mint egy nyomtatási párbeszédpanel: a '1,3-5' az 1. oldalt és a 3-5. oldalakat nyomtatja, az üres karakterlánc pedig a teljes dokumentumot. A Copies közvetlenül a Printer.Copies-re képeződik le. Legyen azonban őszinte magához a Collate (szétválogatás) kapcsán: mivel a VCL a szétválogatást inkonzisztensen teszi közzé a Delphi verziók között, a HotPDF beállítja a másolatszámot, a szétválogatást pedig a nyomtató-illesztőprogram alapértelmezésére bízza, így ha garantált szétválogatási sorrendre van szüksége, állítsa azt be a meghajtón a TPrinterSetupDialog segítségével, ahelyett, hogy bízna a jelző átvitelében
Hogyan határozza meg a DPI és a FitPage a nyomtatási méretarányt?
A FitPage és a DPI kölcsönhatását érdemes megérteni a szállítás előtt. Ha a FitPage értéke True – ez az alapértelmezett –, a HotPDF beolvassa az egyes oldalak MediaBox-át, a képarány megtartásával leképezi a Printer.PageWidth és Printer.PageHeight méretekre, és olyan léptékkel rendereli, amellyel az oldal kitölti a papírt. Ebben a módban a Options.DPI értéket gyakorlatilag felülírja az illesztési lépték, mivel a kimenetnek meg kell egyeznie a nyomtató fizikai oldalméreteivel. Ha a FitPage értéke False, a HotPDF minden oldalt 1:1 arányban renderel pontosan az Options.DPI szerint, 72 PDF egységet leképezve DPI eszközpixelre, ami akkor kívánatos, ha a forrásoldal és a papír már eleve azonos méretű, és Önnek a pontos felbontás számít. Válassza a FitPage-et, ha a forrásoldal mérete és a tálca mérete eltér; válassza az 1:1 arányt, ha megegyeznek, és determinisztikus léptékezést szeretne
A v2.348.0 verzióban hozzáadott két opció kijavítja azokat a nyomatokat, amelyek majdnem jól néznek ki. Minden fizikai nyomtatónak van egy kemény margója (hard margin) – egy nem nyomtatható szegély, amelyet a hardver nem ér el –, és alapértelmezés szerint az oldal kezdőpontja ezen belül landol, így a kifutó (full-bleed) oldal elveszít egy csíkot két szélén. Állítsa az IgnoreHardMargin értékét True-ra, és a HotPDF lekérdezi a nyomtató PHYSICALOFFSETX és PHYSICALOFFSETY értékeit, majd eltolja a készülék kezdőpontját az eltolás kiküszöbölésére, hogy az oldal kezdőpontja a papír valódi sarkára képeződjön le. A második opció, az AutoRotate, alapértelmezés szerint be van kapcsolva: beolvassa az egyes oldalak MediaBox-át, és ha egy oldal szélesebb, mint amilyen magas, átváltja a nyomtatót fekvő (landscape) módba, így a széles oldal levágás nélkül nyomtatódik az álló módú csonkítás helyett. Az AutoRotate félreáll abban a pillanatban, amikor az Orientation-t explicit módon beállítja, így a szándékos tájolásválasztás mindig győz
Hogyan renderelhető a PDF oldal bármilyen eszköz-kontextusba?
A RenderLoadedPageToDC(PageIndex, DC, DPI, W, H) a nyomtatási ciklus alatti primitív, és önmagában is hasznos. A PrintLoadedDocument oldalonként egyszer hívja meg ezt a nyomtató vásznán (canvas), de a cél bármilyen Windows HDC lehet: egy képernyőn kívüli memóriabeli DC, egy vezérlő vászna egy egyéni megjelenítőben, vagy egy nyomtatási előnézet felülete. A PageIndex 0-alapú, a W és H a célfelület eszközegységei, a renderelő pedig bejárja az oldal /Contents bejegyzését, és GDI hívásokat bocsát ki a DC-jébe. Egy szándékos viselkedést érdemes tudni: nem rajzol háttérkitöltést. A hívó birtokolja a felületet, így ha fehér papírt szeretne az oldal mögé, a renderelés előtt magának kell kitölteniez a DC-t, ami pontosan lehetővé teszi, hogy egy oldalt egy meglévő vászonra vetítsen, amikor erre van szükség
// Draw page 1 into an off-screen 24-bit surface at 150 DPI
var
Surface: TBitmap;
begin
Surface := TBitmap.Create;
try
Surface.PixelFormat := pf24bit;
Surface.SetSize(1275, 1650); // 8.5 x 11 in at 150 DPI
Surface.Canvas.Brush.Color := clWhite;
Surface.Canvas.FillRect(Surface.Canvas.ClipRect); // caller paints the background
Pdf.RenderLoadedPageToDC(0, Surface.Canvas.Handle, 150, Surface.Width, Surface.Height);
// Surface now holds the composited page, ready to blit or save
finally
Surface.Free;
end;
end;
Ha csak egy kész TBitmap-re van szüksége – egy bélyegképre, egy kép-exportra vagy egy gyorsítótárazott előnézetre –, használja helyette a RenderLoadedPageToBitmap metódust, amelyről a PDF oldalak renderelése bitképpé szóló cikk ír. A különbség az, hogy kié a felület: a bitkép-hívás lefoglal és visszaad egy pixelpuffert, míg a RenderLoadedPageToDC egy már meglévő eszköz-kontextusba rajzol, amit a nyomtatóvászon vagy a rajzkezelő átad Önnek. Mindkettő ugyanazt a tartalomfolyam-értelmezőt és beágyazott glifmotort használja, így a szöveg mindkét esetben a pontos beágyazott körvonalakkal jelenik meg
Hogyan illeszthető be a PDF oldal a Wordbe vagy egy képszerkesztőbe?
A RenderLoadedPageToClipboard(PageIndex, DPI, AsMetafile) egy oldalt helyez el a Windows vágólapján, készen arra, hogy beillesszék Wordbe, PowerPointba, e-mailbe vagy képszerkesztőbe. Az AsMetafile jelző választja ki a formátumot, és a választás többet számít, mint amennyinek látszik. Ha False értéket ad meg, a HotPDF egy 24 bites eszköz-bitképet (CF_BITMAP) helyez el az Ön DPI-jén renderelve – ez egy rögzített pixelrács, amely bárhová beilleszthető, de pixelre esik szét, amikor a fogadó felnagyítja. Ha True értéket ad meg, akkor egy kiterjesztett metafile-t (CF_ENHMETAFILE) helyez el, amelyben az oldal szövege és vektoros grafikája GDI rajzolási parancsokként utazik, így a beillesztett eredmény bármilyen nagyításnál éles marad, és igazodik ahhoz a mérethez, amelyet a céldokumentum ad neki
// Copy page 2 as a scalable vector metafile for pasting into Word
Pdf.RenderLoadedPageToClipboard(1, 300, True);
// Copy the same page as a fixed 300-DPI bitmap instead
Pdf.RenderLoadedPageToClipboard(1, 300, False);
Az aranyszabály egyszerű. Ha egy felhasználó beilleszti az oldalt egy dokumentumba, és átméretezheti azt – egy ábra egy jelentésben, egy szerződési tervezetbe ejtett záradék –, használja a metafile-t, mert a vektoros szöveg élesen nyomtatódik és nagyítódik. Ha a célpont csak raszteres adatokat ért meg, vagy kifejezetten egy rögzített felbontású pillanatképet szeretne, használja a bitképet. A szavak kinyerése az oldalról teljesen más feladat, amelyet a szövegkivonó API kezel, ami a karaktereket és pozícióikat adja vissza a renderelt kép helyett
Ahor a nyomtatási útvonal véget ér
Minden ezen az oldalon lévő dolog csak Windows-on működik, és ezt érdemes nyíltan kimondani. A PrintLoadedDocument, a RenderLoadedPageToDC és a RenderLoadedPageToClipboard a TPrinter-re, a GDI eszköz-kontextus modellre, a Windows vágólapra és a kiterjesztett metafile-okra épülnek – mind Win32 és Win64 konstrukciók. Más célpontokon a HotPDF többi része továbbra is létrehozza, szerkeszti és olvassa a PDF-et, de ez a GDI-alapú nyomtatási és vágólap-felület nem érhető el. A renderelő a szövegek, útvonalak és képek általános dokumentum-részhalmazát is megcélozza, így a színátmenetekben gazdag tervvázlatok és az ICC-kezelt színek hű előnézetként nyomtatódnak, nem pedig kolorimetrikus igazolásként, ami megegyezik a bitkép-renderelő korlátaival
Sok fájlon átnyúló kötegelt nyomtatáshoz töltse be és nyomtassa ki az egyes dokumentumokat sorban, és ügyeljen a memóriaszámlára: a PrintLoadedDocument egyszerre egy oldalt renderel, de maga a betöltött dokumentumgráf a memóriában él a teljes feladat alatt. Ha több száz nagy fájl felett hajt végre nyomtatási sort, a közvetlen fájl API nagy PDF-munkafolyamatokhoz jól párosul a nyomtatási útvonallal – először válassza szét, egyesítse vagy válassza ki a szükséges oldalakat a lemezen, majd csak a karcsúbb eredményt töltse be a nyomtatáshoz. Így érkezik a PrintLoadedDocument, a RenderLoadedPageToDC és a RenderLoadedPageToClipboard a Delphihez és C++Builderhez készült HotPDF Component részeként – egy natív VCL könyvtár külső DLL-függőségek nélkül, amely kiterjed a PDF-készítésre, -szerkesztésre, szövegkivonásra, renderelésre, és most már a közvetlen nyomtatásra is a TPrinter-re, bármely eszköz-kontextusra vagy a vágólapra