HotPDF tulostaa ladatun PDF:n fyysiselle tulostimelle, mihin tahansa Windowsin laitekontekstiin (device context) tai leikepöydälle kolmella kutsulla: PrintLoadedDocument ohjaa VCL:n TPrinter-ohjainta, RenderLoadedPageToDC maalaa sivun suoraan mihin tahansa HDC-laitekontekstiin ja RenderLoadedPageToClipboard kopioi sivun bittikarttana tai vektorimetatiedostona. HotPDF on natiivi VCL PDF -komponentti Delphille ja C++Builderille, ja se lisäsi tämän ensiluokkaisen tulostuspolun versiossa v2.331.0 ja viimeisteli sen versiossa v2.348.0, joten sinun ei enää tarvitse itse koodata TPrinter-silmukkaa bittikarttaviejän ympärille. Kaikki kolme kutsua piirtävät sivun vektorisisällön suoraan sinne, missä sillä on merkitystä, joten tuloste säilyy niin terävänä kuin tulostin pystyy sen renderöimään
Miksi PDF-sivu piirretään suoraan tulostimeen bittikartan sijasta?
PDF-sivu on vektoripiirtotoimintojen — standardin ISO 32000-1 grafiikkamallin mukaan suoritettavien polkujen, tekstien ja kuvien — ohjelma, ei pikseliruudukko. Ilmeinen tapa tulostaa se on rasteroida sivu bittikartaksi ja siirtää (blit) se tulostimen kankaalle (printer canvas). Se toimii, mutta heittää hukkaan sen, missä tulostin on hyvä. Nykyaikainen lasertulostin kykenee 600 tai 1200 DPI:n tarkkuuteen. Jos bittikartta rasteroidaan 150 tai 300 DPI:llä ja venytetään sitten sopivaksi, tulos on pehmeä, tekstin reunat ovat rosoiset ja interpolointi on näkyvää. RenderLoadedPageToDC valitsee paremman tien: se toistaa sivun sisältövirran GDI-kutsuina suoraan kohdelaitekontekstiin, joten vektoriteksti ja viivagrafiikka saavuttavat tulostimen vektoreina ja ne rasteroidaan vasta kerran, tulostimen toimesta sen omalla resoluutiolla
Miten ladattu PDF tulostetaan fyysiselle tulostimelle Delphissä?
HotPDF tulostaa ladatun asiakirjan PrintLoadedDocument(Printer, Options) -kutsulla, joka ottaa vastaan määritetyn VCL TPrinter-ohjaimen ja THPDFPrintOptions-tietueen, tulostaa valitut sivut ja palauttaa lähetettyjen sivujen määrän. Aseta ensin Printer.PrinterIndex, jotta laite valitaan, täytä asetustietue — luokkafunkio THPDFPrintOptions.Default antaa jaetut arvot — ja kutsu sitä kerran. Kirjasto avaa työn Printer.BeginDoc-kutsulla, käy sivualueen läpi lisäten Printer.NewPage-kutsun sivujen välille ja sulkee sen Printer.EndDoc-kutsulla, joten et koskaan hallitse tulostustyön elinkaarta käsin
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 valitsee oletustulostimen
Opts := THPDFPrintOptions.Default; // kaikki sivut, 300 DPI, FitPage, väri
Opts.PageRange := '1,3-5'; // 1-perusteinen; tyhjä tulostaa jokaisen sivun
Opts.Copies := 2;
Pdf.PrintLoadedDocument(Printer, Opts);
end;
finally
Pdf.Free;
end;
end;
PageRange-merkkijono on 1-perusteinen ja sitä luetaan samalla tavalla kuin tulostusikkunaa: '1,3-5' tulostaa sivun 1 ja sivut 3–5, ja tyhjä merkkijono tulostaa koko asiakirjan. Copies ohjaa suoraan Printer.Copies-ominaisuutta. Ole kuitenkin rehellinen itsellesi Collate-ominaisuuden suhteen: koska VCL välittää sivujen lajittelun (collation) epäjohdonmukaisesti eri Delphi-versioissa, HotPDF asettaa kopioiden määrän ja jättää lajittelun tulostinajurin oletukseksi. Kun tarvitset taatun lajittelujärjestyksen, aseta se ajurista TPrinterSetupDialog-dialogin kautta sen sijaan, että luottaisit pelkkään lippuun
Miten DPI ja FitPage määräävät tulostusskaalan?
FitPage- ja DPI-asetukset vaikuttavat toisiinsa tavalla, joka on syytä ymmärtää ennen julkaisua. Kun FitPage on True (oletus), HotPDF lukee kunkin sivun MediaBox-laatikon, skaalaa sen arvoihin Printer.PageWidth ja Printer.PageHeight säilyttäen kuvasuhteen ja renderöi skaalassa, joka saa sivun täyttämään paperin. Tässä tilassa Options.DPI korvautuu sovitusskaalauksella, koska tulosteen on vastattava tulostimen fyysisiä sivumittoja. Kun FitPage on False, HotPDF renderöi jokaisen sivun suhteessa 1:1 tarkalleen Options.DPI-arvolla, mäpäten 72 PDF-yksikköä DPI-laitepikseliksi. Tätä halutaan silloin, kun lähdesivu ja paperi ovat jo saman kokoisia ja välität tarkasta resoluutiosta. Turvaudu FitPageen, kun lähdesivun koko ja lokeron koko eroavat; valitse 1:1, kun ne täsmäävät ja haluat dynaamisen skaalauksen
Kaksi versiossa v2.348.0 lisättyä vaihtoehtoa korjaa tulosteet, jotka näyttävät melkein oikeilta. Jokaisella fyysisellä tulostimella on kova marginaali (hard margin) — tulostuskelvoton reunus, jota laitteisto ei saavuta — ja oletusarvoisesti sivun alkupiste laskeutuu sen sisään, jolloin reunasta reunaan ulottuva sivu menettää kaistaleen kahdesta reunasta. Aseta IgnoreHardMargin arvoon True, niin HotPDF kysyy tulostimen arvoja PHYSICALOFFSETX ja PHYSICALOFFSETY ja siirtää laitteen alkupistettä tämän siirtymän kumoamiseksi, jolloin sivun alkupiste mäppäytyy paperin todelliseen kulmaan. Toinen vaihtoehto, AutoRotate, on oletuksena käytössä: se lukee kunkin sivun MediaBox-tietueen ja kääntää tulostimen vaaka-asentoon (landscape), jos sivu on leveämpi kuin korkea, jotta leveä sivu tulostuu leikkautumatta pystysuunnan (portrait) sijaan. AutoRotate siirtyy syrjään heti, kun asetat Orientation-asetuksen eksplisiittisesti, joten tietoinen suunnanvalinta voittaa aina
Miten PDF-sivu renderöidään mihin tahansa laitekontekstiin?
RenderLoadedPageToDC(PageIndex, DC, DPI, W, H) on tulostussilmukan alla oleva primitiivi, ja se on hyödyllinen sellaisenaan. PrintLoadedDocument kutsuu sitä kerran sivua kohden tulostimen kangasta vasten, mutta kohteena voi olla mikä tahansa Windowsin HDC: taustamuistin HDC (off-screen memory DC), ohjausobjektin kangas mukautetussa katseluohjelmassa tai tulostuksen esikatselupinta. PageIndex on 0-perusteinen, W ja H ovat kohdepinnan laiteyksiköt, ja renderöijä käy läpi sivun /Contents-tietueen ja tuottaa GDI-kutsuja laitekontekstiisi (DC). Yksi tietoinen toimintatapa on syytä tietää: se ei piirrä taustaväriä. Kutsuja omistaa pinnan, joten jos haluat valkoisen paperin sivun taakse, täytät laitekontekstin itse ennen renderöintiä, mikä mahdollistaa sivun yhdistämisen olemassa olevan kankaan päälle, kun niin halutaan
// Piirrä sivu 1 taustamuistin 24-bittiselle pinnalle 150 DPI:n tarkkuudella
var
Surface: TBitmap;
begin
Surface := TBitmap.Create;
try
Surface.PixelFormat := pf24bit;
Surface.SetSize(1275, 1650); // 8,5 x 11 tuumaa 150 DPI:n tarkkuudella
Surface.Canvas.Brush.Color := clWhite;
Surface.Canvas.FillRect(Surface.Canvas.ClipRect); // kutsuja maalaa taustan
Pdf.RenderLoadedPageToDC(0, Surface.Canvas.Handle, 150, Surface.Width, Surface.Height);
// Pinta sisältää nyt yhdistetyn sivun, valmiina siirrettäväksi tai tallennettavaksi
finally
Surface.Free;
end;
end;
Kun tarvitset vain valmiin TBitmap-kuvan — pikkukuvan, kuva-avauksen tai esikatselun, jonka aiot välimuistittaa —, käytä sen sijaan RenderLoadedPageToBitmap-funktiota, jota käsitellään artikkelissa PDF-sivujen renderöiminen bittikartaksi. Ero on siinä, kuka omistaa pinnan: bittikarttakutsu varaa ja palauttaa pikselipuskurin, kun taas RenderLoadedPageToDC piirtää laitekontekstiin, jota pidät jo hallussasi (kuten tulostimen kangas tai piirtokäsittelijä antaa sinulle). Molemmat jakavat saman sisältövirran tulkin ja upotetun fontin moottorin, joten teksti tulee ulos täsmälleen samoilla upotetuilla ääriviivoilla kummassakin tapauksessa
Miten PDF-sivu liitetään Wordiin tai kuvankäsittelyohjelmaan?
RenderLoadedPageToClipboard(PageIndex, DPI, AsMetafile) asettaa yhden sivun Windowsin leikepöydälle, valmiina liitettäväksi Wordiin, PowerPointiin, sähköpostiin tai kuvankäsittelyohjelmaan. AsMetafile-lippu valitsee muodon, ja valinnalla on suurempi merkitys kuin miltä se näyttää. Välitä False, niin HotPDF asettaa leikepöydälle 24-bittisen laiteriippuvaisen bittikartan (CF_BITMAP) renderöitynä antamallasi DPI-arvolla — kiinteän pikseliruudukon, joka voidaan liittää minne tahansa, mutta joka muuttuu pikselöityneeksi, kun vastaanottaja skaalaa sitä ylöspäin. Välitä True, niin se asettaa leikepöydälle laajennetun metatiedoston (CF_ENHMETAFILE), jossa sivun teksti ja viivagrafiikka kulkevat GDI-piirtokomentoina. Tällöin liitetty tulos säilyy terävänä millä tahansa zoomauksella ja mukautuu mihin tahansa kokoon, jonka kohdeasiakirja sille antaa
// Kopioi sivu 2 skaalautuvana vektorimetatiedostona Wordiin liittämistä varten
Pdf.RenderLoadedPageToClipboard(1, 300, True);
// Kopioi sama sivu sen sijaan kiinteänä 300 DPI:n bittikarttana
Pdf.RenderLoadedPageToClipboard(1, 300, False);
Nyrkkisääntö on yksinkertainen. Jos ihminen liittää sivun asiakirjaan ja saattaa muuttaa sen kokoa — kuten kuva raportissa tai lauseke sopimusluonnoksessa —, käytä metatiedostoa, koska vektoriteksti tulostuu ja zoomaa siististi. Jos kohde ymmärtää vain rasteridataa tai haluat nimenomaan jäädytetyn snapshotin tietyllä resoluutiolla, käytä bittikarttaa. Sanojen poimiminen sivulta niiden kuvan sijaan on kokonaan eri työ, josta vastaa tekstinpoisto-API, joka palauttaa merkit ja niiden sijainnit renderöidyn kuvan sijaan
Mihin tulostuspolku pysähtyy
Kaikki tällä sivulla on vain Windowsille, ja se on syytä sanoa suoraan. PrintLoadedDocument, RenderLoadedPageToDC ja RenderLoadedPageToClipboard perustuvat TPrinter-ohjaimeen, GDI-laitekontekstimalliin, Windowsin leikepöytään ja laajennettuihin metatiedostoihin — jotka ovat kaikki Win32- ja Win64-rakenteita. Muilla alustoilla muu osa HotPDF:ää luo, muokkaa ja lukee edelleen PDF:ää, mutta tämä GDI-tuettu tulostus- ja leikepöytäpinta ei ole käytettävissä. Renderöijä kohdistuu myös yleiseen asiakirjojen osajoukkoon (teksti, polut ja kuvat), joten liukuväripainotteiset vedokset ja ICC-hallitut värit tulostuvat uskollisena esikatseluna pikemminkin kuin kolorimetrisenä vedoksena, mikä on sama raja kuin bittikarttarenderöijällä
Monien tiedostojen erätulostusta varten lataa ja tulosta kukin asiakirja vuorotellen ja tarkkaile muistikulutusta: PrintLoadedDocument renderöi yhden sivun kerrallaan, mutta itse ladattu asiakirjagraafi elää muistissa koko työn ajan. Kun ohjaat tulostusjonoa satojen suurten tiedostojen yli, artikkelissa Direct File API suurten PDF-tiedostojen työnkuluissa esitelty suoratoistava API sopii hyvin tulostuspolun pariksi — jaa, yhdistä tai valitse tarvitsemasi sivut levyllä ensin ja lataa vain kapea tulos tulostettavaksi. Näin PrintLoadedDocument, RenderLoadedPageToDC ja RenderLoadedPageToClipboard toimitetaan osana Delphille ja C++Builderille tarkoitettua HotPDF-komponenttia — natiivia VCL-kirjastoa ilman ulkoisia DLL-riippuvuuksia, joka kattaa PDF-luonnin, muokkauksen, tekstinpoiston, renderöinnin ja nyt myös tulostuksen suoraan TPrinter-ohjaimelle, mihin tahansa laitekontekstiin tai leikepöydälle