HotPDF skriver ut en laddad PDF till en fysisk skrivare, valfri Windows-enhetskontext eller urklipp genom tre anrop: PrintLoadedDocument styr en VCL TPrinter, RenderLoadedPageToDC ritar en sida direkt i valfri HDC, och RenderLoadedPageToClipboard kopierar en sida som en bitmap eller en vektormetafil. HotPDF är en inbyggd VCL PDF-komponent för Delphi och C++Builder, och den lade till denna förstklassiga utskriftsbana i v2.331.0 och förfinade den i v2.348.0, så du behöver inte längre själv koda en TPrinter-loop runt en bitmaprenderare. Alla tre anrop ritar sidans vektorinnehåll direkt där det behövs, så utskriften förblir så skarp som skrivaren kan rendera den
Varför rita en PDF-sida direkt i skrivaren istället för en bitmap?
En PDF-sida är ett program av vektorritningsoperatörer — banor, text och bilder som körs mot grafikmodellen i ISO 32000-1 — inte ett rutnät av pixlar. Det uppenbara sättet att skriva ut en är att rasterisera sidan till en bitmap och överföra den till skrivarens rityta, vilket fungerar, men kastar bort det som en skrivare är bäst på. En modern laserskrivare har en upplösning på 600 eller 1200 DPI; en bitmap som rasteriserats i 150 eller 300 DPI och sedan sträckts ut för att passa blir oskarp, med taggiga textkanter och synlig interpolation. RenderLoadedPageToDC väljer den bättre vägen: den spelar upp sidans innehållsström som GDI-anrop direkt i målenhetskontexten, så att vektor-text och linjegrafik når skrivaren som vektorer och rasteriseras en gång, av skrivaren, med skrivarens egen upplösning
Hur skriver du ut en laddad PDF till en fysisk skrivare i Delphi?
HotPDF skriver ut ett laddat dokument med PrintLoadedDocument(Printer, Options), som tar en tilldelad VCL TPrinter och en THPDFPrintOptions-post, skriver ut de valda sidorna och returnerar antalet skickade sidor. Ställ in Printer.PrinterIndex först så att en enhet väljs, fyll i en alternativpost — klassfunktionen THPDFPrintOptions.Default ger dig rimliga värden — och anropa den en gång. Detta bibliotek öppnar jobbet med Printer.BeginDoc, går igenom sidintervallet och skickar en Printer.NewPage mellan sidorna, och stänger det med Printer.EndDoc, så du behöver aldrig hantera utskriftsjobbets livscykel manuellt
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;
Strängen PageRange är ett-baserad och läses på samma sätt som en utskriftsdialogruta: '1,3-5' skriver ut sida 1 och sidorna 3 till 5, och en tom sträng skriver ut hela dokumentet. Copies mappar direkt till Printer.Copies. Var dock ärlig med Collate: eftersom VCL exponerar sortering inkonsekvent över Delphi-versioner ställer HotPDF in kopieantalet och överlåter sorteringen till skrivardrivrutinens standard, så när du behöver en garanterad sorteringsordning bör du ställa in den i drivrutinen via TPrinterSetupDialog istället för att lita på att flaggan bär fram den
Hur avgör DPI och FitPage utskriftsskalan?
FitPage och DPI samverkar på ett sätt som är värt att förstå innan du levererar. Med FitPage satt till True — standardinställningen — läser HotPDF varje sidas MediaBox, skalar den till Printer.PageWidth och Printer.PageHeight med bibehållet bildförhållande, och renderar i den skala som gör att sidan fyller papperet. I det läget åsidosätts Options.DPI i praktiken av anpassningsskalan eftersom utdata måste matcha skrivarens fysiska siddimensioner. Med FitPage satt till False renderar HotPDF varje sida 1:1 med exakt Options.DPI, vilket mappar 72 PDF-enheter till DPI-enhetspixlar, vilket är vad du vill ha när källsidan och papperet redan har samma storlek och du bryr dig om en exakt upplösning. Välj FitPage när källsidan och pappersfackets storlek skiljer sig; välj 1:1 när de matchar och du vill ha deterministisk skalning
Två alternativ som lades till i v2.348.0 åtgärdar utskrifter som ser nästan rätt ut. Varje fysisk skrivare har en hård marginal — en icke-utskrivbar kant som hårdvaran inte kan nå — och som standard hamnar sidans startpunkt inuti den, så en sida med utfallande tryck förlorar en remsa i två kanter. Sätt IgnoreHardMargin till True så frågar HotPDF efter skrivarens PHYSICALOFFSETX och PHYSICALOFFSETY och förskjuter sedan enhetens startpunkt för att upphäva den förskjutningen så att sidans startpunkt mappar till papperets sanna hörn. Det andra alternativet, AutoRotate, är aktiverat som standard: det läser varje sidas MediaBox och om en sida är bredare än den är hög växlar det skrivaren till liggande format så att en bred sida skrivs ut utan att beskäras till stående. AutoRotate träder åt sidan så fort du ställer in Orientation explicit, så ett medvetet val av orientering vinner alltid
Hur renderar du en PDF-sida i valfri enhetskontext?
RenderLoadedPageToDC(PageIndex, DC, DPI, W, H) är primitiven under utskriftsloopen, och den är användbar i sig. PrintLoadedDocument anropar den en gång per sida mot skrivarens rityta, men målet kan vara valfri Windows HDC: en off-screen minnes-DC, en kontrolls rityta i en anpassad visare eller en förhandsgranskningsyta. PageIndex är nollbaserat, W och H är enhetsenheterna för målytan, och renderaren går igenom sidans /Contents och skickar GDI-anrop till din DC. Ett medvetet beteende är värt att känna till: den ritar ingen bakgrundsfyllning. Anroparen äger ytan, så om du vill ha vitt papper bakom sidan fyller du själv din DC före rendering, vilket är precis det som gör att du kan lägga en sida ovanpå en befintlig rityta om du vill
// 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;
När du bara behöver en färdig TBitmap — en miniatyrbild, en bildexport, en förhandsgranskning du vill cacha — kan du använda RenderLoadedPageToBitmap istället, vilket beskrivs i den tillhörande artikeln om att rendera PDF-sidor till en bitmap. Skillnaden är vem som äger ytan: bitmapanropet allokerar och returnerar en pixelbuffert, medan RenderLoadedPageToDC ritar i en enhetskontext du redan har, vilket är precis vad en skrivares rityta eller en målningshanterare ger dig. Båda delar samma innehållsströmstolk och motor för inbäddade tecken, så texten kommer ut med exakt samma inbäddade konturer i båda fallen
Hur klistrar du in en PDF-sida i Word eller en bildredigerare?
RenderLoadedPageToClipboard(PageIndex, DPI, AsMetafile) placerar en sida på Windows urklipp, redo att klistras in i Word, PowerPoint, ett e-postmeddelande eller en bildredigerare. Flaggan AsMetafile väljer formatet, och valet spelar större roll än det verkar. Skicka False så placerar HotPDF en 24-bitars enhetsbitmap (CF_BITMAP) renderad i din DPI — ett fast rutnät av pixlar som kan klistras in var som helst men blir pixligt när mottagaren förstorar det. Skicka True så placerar den en utökad metafil (CF_ENHMETAFILE) där sidans text och vektorgrafik färdas som GDI-ritkommandon, så att det inklistrade resultatet förblir skarpt vid valfri zoom och anpassar sig till vilken storlek som helst som måldokumentet ger det
// 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);
Tumregeln är enkel. Om en människa ska klistra in sidan i ett dokument och kan komma att ändra storlek på den — en figur i en rapport, en klausul i ett avtalsutkast — använd metafilen, eftersom vektor-text skrivs ut och zoomas rent. Om målet bara förstår rasterdata, eller om du specifikt vill ha en fryst ögonblicksbild med en känd upplösning, använd bitmappen. För att dra ut orden ur en sida snarare än en bild av dem är det ett helt annat jobb som hanteras av API:et för textextraktion, vilket returnerar tecknen och deras positioner istället för en renderad bild
Var utskriftsbanan upphör
Allt på denna sida är endast för Windows, och det är värd att säga rent ut. PrintLoadedDocument, RenderLoadedPageToDC och RenderLoadedPageToClipboard är byggda på TPrinter, GDI-enhetskontextmodellen, Windows urklipp och utökade metafiler — alla konstruktioner för Win32 och Win64. På andra plattformar skapar, redigerar och läser resten av HotPDF stilla PDF, men denna GDI-stödda utskrifts- och urklippsyta är inte tillgänglig. Renderaren riktar också in sig på den vanliga dokumentdelmängden av text, banor och bilder, så gradienttunga designkorrektur och ICC-hanterade färger skrivs ut som en trogen förhandsgranskning snarare än ett färgäkta korrektur, vilket är samma gräns som bitmaprenderaren har
För batch-utskrift av många filer, ladda och skriv ut varje dokument i tur och ordning och håll ögonen på minnesanvändningen: PrintLoadedDocument renderar en sida i taget, men själva det laddade dokumentträdet lever i minnet under hela jobbet. När du kör en utskriftskö över hundratals stora filer fungerar det strömmande Direct File API:et för stora PDF-arbetsflöden väl ihop med utskriftsbanan — dela, slå ihop eller välj de sidor du behöver på disken först, ladda sedan endast det slimmade resultatet för att skriva ut. Det är så PrintLoadedDocument, RenderLoadedPageToDC och RenderLoadedPageToClipboard levereras som en del av HotPDF Component för Delphi och C++Builder — ett inbyggt VCL-bibliotek utan externa DLL-beroenden som täcker PDF-skapande, redigering, textextraktion, rendering och nu utskrift direkt till TPrinter, valfri enhetskontext eller urklipp