A zkusil jste vanilkový GhostScript + RedMon?
Spousta "virtuálních PDF tiskáren" jsou jenom hezké klikací kabátky, které třeba i nutí uživatele komusi cosi zaplatit (pokud nechcete v PDFku otravný vodoznak apod.), přitom rendering engine je starý dobrý GhostScript, jenom více či méně zdařile zamaskovaný uvnitř instalátoru a runtime binárek. Viz např
heslo na wikipedii ohledně "virtual printers".
Konkrétně k instalaci vanilkového GhostScriptu jako PDF tiskárny potřebujete
GhostScript,
GhostScript Fonts a
RedMon. Hmm přemejšlím, jestli jsem to už instaloval někde pod desítkama...
Není od věci, vědět něco o fungování
tiskového subsystému Windows. Řetězec vypadá cca takto:
Aplikace
GDI print API
[job v generickém formátu MS EMF = Enhanced MetaFile]
spooler = tyhle joby se řadí do fronty
EMF job uvolněný z fronty je předán HW-specifickému DLL driveru, např. UNIDRV.DLL + PCL5ERES.DLL
User-mode DLL "driver" zkonvertuje EMF job na (například) PCL job
Nyní je job již v HW-specific formátu pro danou tiskárnu poslán na tiskový port
Ovšem zdá se, že v případě PostScriptu je celý řetězec
trochu jinak: totiž "specifický driver" (pscript5.DLL) je zřejmě volán přímo GDI subsystémem a spooler tedy frontuje už job ve formátu PS.
Každopádně "virtuální PDF tiskárna" na bázi GhostScriptu pod Windows má tyto důležité součástky:
- aplikace tiskne patrně přes GDI API
- někde cestou (možná hned za GDI) je ve hře obecný Microsoftí pscript5.DLL,
ze kterého vypadne job ve formátu PS
- pak je zřejmě ve hře spooler
- spooler předává jednotlivé joby na virtuální tiskový port, tvořený softwarem RedMon.
RedMon je vlastně jenom DLLko. Jím vytvářený virtuální port je příbuzný klasického fyzického LPT1
(co do pozice v potravním řetězci printing subsystému)
- RedMon převezme job a předá ho nakonfigurovanému executable programu.
V našem případě Ghostscriptu, se všemi jeho command-line parametry které si usmyslíme.
Konkrétně ten job do Ghostscriptu pošle pípou = nacpe mu job do "stdin".
- GhostScript schroupe vstupní postscript na výstupní PDF.
Možná s tím nemá ani moc práce, protože oba formáty jsou příbuzné.
GhostScript má přibalený někde v instalačním adresáři jenom parametrizační .PPD soubor (PostScript Printer Definition), snad pohromadě s .INF souborem (skriptem) pro Windows Installer. Hledejte v Program Files\gs podadresář se soubory lib\ghostpdf.* . Sem nasměrujte instalátor tiskárny. Samotný engine pro konverzi GDI/PS se použije Microsoftí standardní příbalový (pscript5.DLL a kamarádi).
RedMon spustí program, který mu zadáte včetně celé cesty, např. C:\Program Files\gs\gs9.18\bin\gswin64c.exe a počká na jeho ukončení. Dokud běžící instance GhostScriptu neskončí, nesnaží se spustit další (pro zpracování dalšího jobu). Tady se nabízí jedna možnost optimalizace, vrátím se k ní níže.
RedMon si umí říct o jméno souboru (v konfiguračním dialogu, tzn. ve "vlastnostech portu", je na to fajfka) a následně se lze odkázat na proměnnou %1 v argumentech programu:
-I"C:\Program Files\gs\gs9.18";"C:\Program Files\gs\fonts" -sDEVICE=pdfwrite -dSAFER -dPDFSETTINGS=/printer -dAutoRotatePages=/PageByPage -sOutputFile="%1" -
Pokud Vám jde o průchodnost, máte možnost spekulovat o následujících bodech v řetězci:
- jak rychlý je standardní windowsí/microsoftí pscript5.dll, který renderuje GDI úlohu do formátu PS.
- o spooler bych se nebál, ten jenom kopíruje soubory, to běhá celkem rychle.
- totéž RedMon, jenom kopíruje soubory.
- jak rychlý je GhostScript. Toť otázka. Záleží na jobu. Případně by šlo zvážit, zda si nenapsat vlastní prográmek nebo skript, který GhostScript jenom forkne, předá mu soubor.PS a okamžitě se vrátí, aby převzal od RedMonu pípou další job. Na multi-core procesoru by díky tomu mohlo běžet víc instancí GhostScriptu paralelně (nikdy jsem to nezkoušel, ale nevidím důvod, proč by to nešlo).
No a vedle standardní cesty GDI->EMF->spooler->PCL->tiskárna, resp. GDI->PS->spooler->tiskárna, existuje nově také alternativní cesta, která jako formát jobů používá MS XPS. A existuje GhostXPS (s výstupem mj. do PDF). Nikdy jsem to nezkoumal, ale možná by XPS cesta měla vyšší výkon než klasická GDI cesta.
A pořád je to celé hrozně dlouhé a zašmodrchané. Do výsledného PDF se nedají generovat interní odkazy z obsahu dále do textu apod. Prostě je to jenom tisková úloha konvertovaná do PDF. (Pravda je, že GhostScript umí orientovat stránky automaticky podle převažující orientace textu, a všiml jsem si, že mi i ze starého wordu skrz GhostScript do Adobe Readeru nějak záhadně probublaly klikatelné HTTP URL.) Chci říct, že tento způsob generování PDF skrz virtuální tiskárnu a GhostScript je dost sešněrovaný a konfiguračně zašmodrchaný. Třeba jenom předat GhostScriptu skrz RedMon jména souborů je při "prostém skriptování" potenciálně dost oříšek. Budete řešit, pod jakým uživatelem má GhostScript běhat, potažmo do jakých adresářů bude mít přístup (třeba Vám to ve výchozí konfiguraci nepojede na síťové disky) apod. A pokud použijete konfiguraci RedMonu "zeptej se vyskakovacím oknem na jméno souboru", býval problém, že tohle okno vyskakovalo prvnímu přihlášenému uživateli...
Chci říct: pokud na tu virtuální tiskárnu nepotřebujete tisknout z libovolné aplikace pod Windows, ale ve skutečnosti máte nějaký svůj soft, ze kterého potřebujete fofrem generovat PDFka, tak se spíš zaměřte na hledání nějaké knihovny, kterou byste ke svému softu přilinkoval, a PDFka byste exportoval přímo. Bez celé té taškařice s "windows printing". Našel jsem třeba libharu.org.
Vedle "nativní knihovny pro PDF export" mě ještě napadá, použít nějaký XML-based framework pro práci s dokumenty. Sám jsem kdysi držel v ruce docbook. S takovou věcí by mohly jít dělat psí kusy, a přitom jako export z Vašeho softu potřebujete jenom validní XML. Formátování by se dalo svěřit zčásti nebo úplně externímu XSLT.
Obecně ohledně průchodnosti: vyrobit několik PDF za sekundu asi není problém, pokud ta PDFka budou štíhlá. Pokud štíhlá nejsou a v jednom vlákně se to nestíhá, tak se to pokusit paralelizovat, rozložit mezi více CPU jader.