Technický článek

Srovnání knihoven losLab PDF pro Delphi: HotPDF, PDFium Component a PDFlibPas

Tři knihovny. Tři odlišné úkoly. Výběr té špatné vás bude stát týdny hledání obezliček (workarounds) a výběr všech tří, když potřebujete jen jednu, vás bude stát režii na údržbu, se kterou jste ve svém rozpočtu nepočítali. Zde je přímý výčet toho, co jednotlivé PDF knihovny od losLab skutečně dělají, kam se hodí a kde předávají štafetu svým sourozencům

HotPDF: zápis PDF od nuly v Delphi

HotPDF je nativní komponenta VCL pro generování dokumentů PDF. Její model je imperativní a zaměřený na stránky (page-centric): sestrojíte instanci THotPDF, nastavíte vlastnosti dokumentu, zavoláte BeginDoc, kreslíte do CurrentPage, podle potřeby přidáváte stránky a uzavřete pomocí EndDoc. Na pořadí záleží, protože BeginDoc v okamžiku svého spuštění potvrzuje (commits) šifrovací slovník a nastavení komprese; cokoliv přiřazené po tomto bodě je spíše tiše ignorováno, než aby to bylo aplikováno zpětně

Kreslicí plocha (drawing surface) pokrývá kompletní sadu operátorů PDF na úrovni Delphi: TextOut pro pozicovaný text v kódování Unicode, SetFont se vkládáním písem TrueType, vektorová primitiva (čáry, Bézierovy křivky, elipsy, obdélníky), umisťování obrázků ze souboru nebo paměti a generování čárových kódů. Souřadnice jsou v bodech od levého dolního rohu, přičemž Y roste směrem nahoru, což alespoň jednou zaskočí každého. Stav písma nepřežije AddPage, takže po každém zlomu stránky je vyžadováno volání SetFont

Pole AcroForm jsou zde prvořadými občany (first-class citizens). Textová pole, zaškrtávací políčka, přepínače (radio buttons), rozbalovací seznamy (combo boxes), seznamy (list boxes) a tlačítka (push buttons) můžete přidávat přímo do objektu stránky, a to každé jediným voláním. HotPDF dokáže také načíst existující PDF prostřednictvím LoadFromFile a vyplnit nebo přečíst hodnoty polí, což z něj činí užitečný nástroj ve dvou samostatných pracovních postupech: při sestavování formulářů a automatizaci jejich vyplňování

Šifrování se rovněž řeší na úrovni dokumentu. CryptKeyLength vybírá schéma (od 40bitového RC4 až po AES-256), ActivateProtection jej aktivuje a ProtectOptions nastavuje příznaky oprávnění (permission flags) ISO. Dva režimy revizí AES-256 (R5 a R6, řízené pomocí UseAES256R6) existují proto, že revize 6 opravuje známou slabinu v revizi 5, ale vyžaduje prohlížeč s podporou PDF 2.0; volba mezi nimi je rozhodnutím o kompatibilitě, nikoliv o pohodlí

Podpora digitálního podpisu v HotPDF pokrývá základní profily (baseline profiles) PAdES, takže je vhodná pro pracovní postupy, kde musí podpis splňovat požadavky ETSI EN 319 142. Pokud je vaší jedinou potřebou generování výstupu, HotPDF je knihovna, po které byste měli sáhnout jako po první

PDFium Component: vykreslování, prohlížení a čtení stávajících PDF

PDFium Component obaluje (wraps) jádro PDFium od Googlu jako komponentu VCL, což jí dává zásadně odlišnou roli než HotPDF. Zatímco HotPDF zapisuje, PDFium Component čte a vykresluje. Stěžejním objektem je TPdf, správce dokumentů (document manager), který otevře soubor nastavením FileName a následně Active := True. Selhání při načítání se nevyvolávají jako výjimky; Active jednoduše zůstane na hodnotě False, takže jeho kontrola po přiřazení není volitelná

Vykreslování probíhá přes TPdfView, vizuální komponentu, kterou vložíte (drop) na formulář a propojíte s instancí TPdf pomocí PdfView.Pdf := Pdf. Zvětšení (zoom) a režim přizpůsobení (fit mode) žijí na zobrazení (view), nikoli na dokumentu. Jedna záludnost, do které se lidé občas chytí: Pdf.PageNumber a PdfView.PageNumber jsou nezávislé vlastnosti. Nastavení jedné neaktualizuje druhou a API pro extrakci založená na zobrazení (word boxes, reading units) používají aktuální stránku zobrazení (view), nikoliv tu z dokumentu

Pokud jde o extrakci textu, nemá PDFium Component v nabídce losLab přímého konkurenta. ReadablePageContent vrací strukturovaný text s ohledem na pořadí čtení (reading-order awareness), PageWordBoxes poskytuje ohraničující obdélníky (bounding rectangles) na úrovni slov a DocumentReadingUnits projde celý dokument. Pro práci s přístupností vám IsTagged řekne, zda je přítomen strom struktury, a ValidatePdfUa spustí kontrolu shody (conformance check) s normou UA. Tato API činí z PDFium Component přirozenou volbu pro jakýkoliv pracovní postup, který spíše potřebuje porozumět tomu, co se skrývá uvnitř existujícího PDF, než vyprodukovat nové

Vyplňování formulářů (form filling) funguje i na straně PDFium, a to přes stejnou vrstvu AcroForm, kterou vystavuje (exposes) základní jádro. Je to vhodné, pokud zdrojový dokument již existuje a vy pouze automatizujete jeho doplňování (completion), než abyste pole formuláře konstruovali sami

PDFlibPas: manipulace, compliance podepisování a přímý přístup k souborům (direct-file access)

PDFlibPas (verze 3.73.0) sedí na druhém konci spektra složitosti. Vystavuje (exposes) tři vrstvy API nad stejným modelem dokumentu: plochou fasádu založenou na handle (flat handle-based facade) (TPDFlib) kompatibilní s konvencí volání (calling convention) Quick-PDF, vrstvu plnohodnotného stromu objektů (full object-tree layer) (TPDFDocument) a streamovací parser (TSmartPDFReader / TSmartPDFWriter), který pracuje přímo s bajty souboru bez načtení kompletního grafu objektů

Je to právě streamovací vrstva, která činí z PDFlibPas správnou volbu pro velké dokumenty. TSmartPDFWriter může připojit přírůstkovou aktualizaci k souboru na disku, aniž by rekonstruoval celou tabulku křížových odkazů, což je mechanismus, který je základem jak efektivního opětovného uložení (efficient resaving), tak razítek dlouhodobé platnosti PAdES (PAdES long-term validation stamps). Pro pracovní postupy podepisování na úrovni compliance (compliance-grade signing workflows), kde podepsaný hash musí pokrýt konkrétní rozsah bajtů a podpis se aplikuje bez přepsání dokumentu, je tato vrstva jedinou schůdnou (viable) cestou

Manipulace s dokumenty na úrovni TPDFDocument zahrnuje slučování pomocí Merge, selektivní kopírování stránek přes CopyPagesFromDoc s řetězcem určujícím rozsah (range string) a řízení verzí prostřednictvím SetMinimumVersion a LockSaveVersion. Zámek verze (version lock) vyvolá chybu 602, pokud se pokusíte uložit funkci, která by posunula výstup nad zamčenou verzi, což je užitečné, když potřebujete zaručit, že výstup zůstane v rámci konkrétní revize PDF kvůli shodě s předpisy o archivaci (archival compliance)

Podpora PDF/A (ISO 19005) sídlí v dílně pro shodu s normami (conformance workbench) PDFlibPas. Upozorňujeme, že šifrování a PDF/A se podle specifikace vzájemně vylučují: nemůžete mít obojí v jednom souboru. Pracovní postupy, které potřebují šifrovanou distribuční kopii a archivní kopii PDF/A, musí vytvořit dva samostatné artefakty

Jak mezi nimi vybírat

Typický rozhodovací strom (decision tree) je krátký. Pokud generujete nový dokument z dat, použijte HotPDF. Pokud vykreslujete nebo extrahujete text z existujícího dokumentu v aplikaci Delphi VCL, použijte PDFium Component. Pokud ve velkém (at scale) nebo se sémantikou přírůstkového ukládání (incremental-save semantics) manipulujete s existujícími PDF, slučujete je nebo je podepisujete za účelem compliance, použijte PDFlibPas. Mnoho produkčních systémů používá dvě ze tří jmenovaných komponent: například HotPDF ke generování výstupu a PDFlibPas k aplikaci razítka dlouhodobé platnosti před archivací, nebo PDFium Component k náhledu toho, co vyprodukoval HotPDF, před odesláním dále v řetězci (downstream)

Všechny tři knihovny se dodávají jako nativní zdrojové kódy v Pascalu pro Delphi a C++Builder bez jakýchkoli běhových závislostí (runtime dependencies) kromě knihovny VCL. PDFium Component navíc přibaluje (bundles) knihovnu PDFium DLL, která pokrývá práci jádra (engine) s vykreslováním a parsováním. Produktová stránka každé z knihoven nese její úplnou referenci k API a historii aktuálních verzí

Podrobnosti k jednotlivým knihovnám: HotPDF Component, PDFium Component a PDFlibPas