Komponent PDFium pre Delphi validuje tlačovo pripravené dokumenty PDF/X prostredníctvom metódy TPdf.ValidatePdfX, ktorá implementuje kontrolu ISO 15930 v dvoch vrstvách: osem kontrol obsahu na úrovni bajtov (zakázaná kompresia LZW, JavaScript, polia formulárov, referencie OPI, chýbajúci TrimBox, nenastavený kľúč Trapped a ďalšie) plus prechod objektovým modelom PDFium, ktorý používa FPDFFont_GetIsEmbedded na overenie vloženia písiem pri každom textovom objekte na každej stránke. Výsledkom je záznam TPdfXValidationResult, ktorý menuje zistenú úroveň zhody a uvádza každé porušenie ako typovaný enum, takže vaša delphijská aplikácia môže zákazníkovi presne povedať, prečo bude súbor v tlačiarni odmietnutý ešte predtým, ako niekto vyrobí tlačovú platňu
Ak ste niekedy posielali zákazku do komerčnej tlačiarne a dostali ju späť s jednoradkovým odmietnutím — „no TrimBox“, „fonts not embedded“, „Trapped not set“ — poznáte cenu neskorého zistenia. PDF/X je tlačový náprotivok k archivačnému formátu PDF/A: kým archivačné PDF/A zaručuje, že sa dokument vykreslí rovnako aj o desiatky rokov, PDF/X zaručuje, že sa dokument zajtra ráno správne separuje, vykreslí a oreže na cudzom RIPe. Tieto dva štandardy zdieľajú rovnaké mechanizmy (identifikácia XMP, OutputIntents, vložené ICC profily), ale odpovedajú na rôzne otázky, preto komponent dodáva samostatné validátory pre každý z nich — strana PDF/A je popísaná v preflight validácii PDF/A s komponentom PDFium
Čo v skutočnosti ISO 15930 vyžaduje od tlačovo pripraveného PDF?
Norma ISO 15930 existuje na to, aby umožnila výmenu naslepo (blind exchange): grafik odovzdá súbor tlačiarni, s ktorou nikdy nehovoril, a tlačiareň dokáže vyrobiť správny výstup bez telefonátov, bez e-mailov o chýbajúcich písmach a bez prepojených obrázkov, ktoré zostali na notebooku grafika. Každé pravidlo v norme slúži tomuto cieľu. Písma musia byť vložené (embedded), pretože nemožno predpokladať, že prímací RIP ich vlastní. Externé odkazy sú zakázané, pretože súbor musí byť kompletný sám o sebe. Interaktívne funkcie sú zakázané, pretože atrament nemá handler udalosti onclick
Komponent PDFium rozpoznáva tri rodiny zhody a uvádza ich prostredníctvom enumu TPdfXConformance vo výsledku validácie: pxc1a pre PDF/X-1a:2001 (ISO 15930-1, prísny základ CMYK a priamych farieb nad PDF 1.3/1.4), pxc3 pre PDF/X-3:2002 (ISO 15930-3, ktorý pripúšťa RGB, Lab a farby spravované pomocou ICC) a pxc4 pre PDF/X-4:2010 (ISO 15930-7, ktorý konečne povoľuje živú priehľadnosť a vrstvy nad základom PDF 1.6). Súbor, ktorý nenesie vôbec žiadnu identifikáciu PDF/X, sa vráti ako pxcNone, čo je samo o sebe užitočná odpoveď: dokument nikdy netvrdil, že je pripravený na tlač, a všetko ostatné, čo validátor nahlási, vysvetľuje, čo by bolo potrebné na dosiahnutie tohto stavu
Tieto zákazy dávajú zmysel, akonáhle začnete uvažovať ako dodávateľ RIPov. Filter /LZWDecode je zakázaný vo všetkých variantoch PDF/X, takže vyhovujúci čítač nikdy nezávisí od filtra s históriou licenčných sporov a kompatibility; filter Flate robí rovnakú prácu bez tejto záťaže. JavaScript, polia AcroForm a slovníky /AA pre dodatočné akcie sú zakázané, pretože tlačový súbor musí byť fixným popisom značiek na papieri — čokoľvek, čo môže zmeniť vzhľad pri otvorení, ruší záruku, že to, čo bolo schválené na náhľade, sa aj vytlačí. Zástupné objekty OPI (Open Prepress Interface) sú zakázané, pretože sú z princípu odkazmi na obrázky s vysokým rozlíšením uložené niekde inde, a „niekde inde“ je presne to, čo výmena naslepo zakazuje
Prečo tlačiarne odmietajú PDF súbory bez TrimBoxu?
TrimBox (čistý formát) je hotová stránka — obdĺžnik, ktorý zostane po orezaní rezačkou. MediaBox (rozmer média), ktorý má každá stránka PDF, je len samotný list papiera: zahŕňa spadávku (bleed), orezové značky, registračné terčíky a farebné škály. Vyraďovací softvér (imposition software) umiestňuje stránky na tlačový hárok podľa ich TrimBoxov; bez neho musí operátor hádať, kde vaša vizitka reálne končí, a nesprávny odhad odfikne spadávku alebo zanechá biely prúžok na jednom okraji. Preto norma ISO 15930 vyžaduje TrimBox (alebo ArtBox) na každej stránke a preto ValidatePdfX vyvolá pvxiMissingTrimBox, keď sa na žiadnej stránke dokumentu nenájde kľúč /TrimBox
Kľúč /Trapped odpovedá na inú produkčnú otázku. Trapping (presah) je predprípravná technika mierneho prekrytia susediacich farieb, aby drobné nepresnosti tlače neotvárali biele medzery medzi nimi. Tlačiareň potrebuje vedieť, či táto práca už bola vykonaná: trapping nad už upraveným súborom zdvojnásobuje prekrytia, zatiaľ čo preskočenie trappingu pri neupravenom súbore riskuje viditeľné medzery. PDF/X preto vyžaduje, aby slovník Info explicitne uvádzal /Trapped /True alebo /Trapped /False — chýbajúci kľúč alebo hodnota /Unknown núti človeka súbor skontrolovať, čo je presne tá komunikácia, ktorú mala výmena naslepo odstrániť. Komponent to označuje ako pvxiTrappedNotSet
Spustenie dvojvrstvovej validácie pomocou TPdf.ValidatePdfX
Metóda TPdf.ValidatePdfX nepreberá žiadne argumenty a vracia záznam TPdfXValidationResult s tromi členmi: Conformance (zistená verzia PDF/X), Issues (pascalská množina hodnôt TPdfXValidationIssue) a pomocnú vlastnosť IsCompliant. Interne zoserializuje načítaný dokument do pamäťového toku, spustí nad ním kontrolu na úrovni bajtov a potom prechádza objektový model PDFium kvôli kontrole vloženia jednotlivých písiem. Minimálna brána preflightu vyzerá takto:
uses PDFium, FPdfPdfx;
procedure CheckPrintReadiness(const FileName: string);
var
Pdf: TPdf;
Res: TPdfXValidationResult;
begin
Pdf := TPdf.Create(nil);
try
Pdf.FileName := FileName;
Pdf.Active := True;
Res := Pdf.ValidatePdfX;
Writeln('Detected conformance: ',
Ord(Res.Conformance)); // pxc1a, pxc3, pxc4, pxcNone...
if Res.IsCompliant then
Writeln('PDF/X checks passed')
else
begin
if pvxiMissingTrimBox in Res.Issues then
Writeln('REJECT: no /TrimBox on the pages');
if pvxiTrappedNotSet in Res.Issues then
Writeln('REJECT: /Trapped missing or /Unknown');
if pvxiPdfiumFontNotEmbedded in Res.Issues then
Writeln('REJECT: a page uses a non-embedded font');
if pvxiLzwForbidden in Res.Issues then
Writeln('REJECT: LZWDecode filter present');
end;
finally
Pdf.Free;
end;
end;
Keďže Issues je obyčajná pascalská množina, môžete ju rozdeliť podľa potrieb vášho spracovania — pristupovať k štrukturálnym problémom ako k okamžitému odmietnutiu, pristupovať k pvxiMissingTitle (čo je v norme označené ako SHOULD, nie MUST) ako k varovaniu a zvyšok zaznamenať do logu. Rovnaký typ záznamu slúži aj pre generátor správ komponentu, takže ak by ste radšej vygenerovali dokument čitateľný pre človeka než sa vetvili na enumoch, vzor v zostavení CLI pre hromadné preflight správy s komponentom PDFium sa aplikuje na PDF/X nezmenený
Čo zachytí vrstva na úrovni bajtov — a čo jej uniká
Vrstva na úrovni bajtov je skenovaním tokenov nad štrukturálnymi bajtmi dokumentu s vynechaním tiel tokov (streams), takže JPEG, ktorý náhodou obsahuje bajtový vzor /JavaScript, nemôže spustiť falošný poplach. Okrem kontrol značiek (XMP pdfxid:GTS_PDFXVersion, OutputIntent s vloženým ICC profilom, trailer /ID, zákaz šifrovania) pridáva prechod obsahom osem kontrol, z ktorých každá má svoju vlastnú hodnotu enumu:
pvxiLzwForbidden— filter/LZWDecodesa nachádza kdekoľvek v súbore (zakázaný vo všetkých verziách PDF/X)pvxiJavaScriptForbidden— je prítomná akcia alebo strom názvov/JavaScriptpvxiFormFieldsForbidden— existuje slovník/AcroFormalebo položka/XFApvxiAdditionalActions— je prítomný slovník dodatočných akcií/AApvxiEmbeddedFilesForbidden— je prítomná anotácia/EmbeddedFilesalebo/FileAttachmentpvxiOpiForbidden— položka/OPIalebo/Alternatesodkazuje na nahraditeľný obsah obrázkapvxiMissingTrimBox— na žiadnej stránke sa nenašiel/TrimBoxpvxiTrappedNotSet— položka/Trappedchýba alebo je nastavená na/Unknown
Bajtové skenovanie je rýchle a nepotrebuje vykresľovacie jadro, ale má inherentné slepé miesto pri písmach: na tejto úrovni môže inšpektor použiť len hrubú heuristiku — označí dokument, ak v ňom vôbec nenájde žiadny program pre vložené písma. Súbor s deviatimi vloženými písmami a jedným systémovým písmom prejde bajtovým skenovaním bez povšimnutia. Táto jediná medzera je dôvodom, prečo existuje druhá vrstva
Overenie vloženia písiem cez objektový model PDFium
Vrstva objektového modelu komponentu PDFium odpovedá na otázku písiem presne. Po prechode na úrovni bajtov metóda TPdf.ValidatePdfX prechádza každú stránku, získa zoznam objektov cez FPDFPage_CountObjects a pre každý textový objekt zistí ukazovateľ písma pomocou FPDFTextObj_GetFont a dotáže sa na FPDFFont_GetIsEmbedded. Jedno nevložené písmo kdekoľvek v dokumente pridá do množiny problémov pvxiPdfiumFontNotEmbedded. Prechod sa skracuje na dvoch úrovniach — zastaví skenovanie objektov na stránke a zastaví načítavanie ďalších stránok v momente, keď sa problém potvrdí — takže pri chybnom 300-stranovom katalógu verdikt často prichádza hneď po prvej stránke
Dve poznámky k ohraničeniu, ktoré stojí za to poznať. Po prvé, táto vrstva vyžaduje načítanú knižnicu PDFium a verzie, ktoré exportujú FPDFFont_GetIsEmbedded; ak export chýba, kontrola sa preskočí a nezlyhá, takže staršia DLL nikdy nevytvorí vymyslené odmietnutia. Po druhé, kontrola odpovedá iba na otázku „vložené alebo nie“ a nič viac — nerozlišuje plné vloženie od podmnožiny (subsetting) ani neskúma pokrytie glyfmi. Keď súbor zlyhá a vy potrebujete vedieť, ktoré písmo na ktorej stránke zlyhalo, techniky prechádzania v analýze vlastností písiem PDF s PDFium v Delphi nadväzujú presne tam, kde boolean hodnota validátora končí
Validácia prúdov bez načítania dokumentu — alebo DLL
Inšpektor na úrovni bajtov je sprístupnený aj ako samostatná funkcia ValidatePdfXCompliance(Source: TStream) v jednotke FPdfPdfx a ide o čistý Object Pascal bez akejkoľvek závislosti na DLL PDFium. Vďaka tomu ho možno nasadiť na miestach, kde vykresľovacie jadro nie je vítané: ľahká vstupná brána pre nahrávanie na webovom serveri, úloha CI, ktorá preveruje vygenerovanú grafiku, alebo lazaruská služba na platforme, kde by ste radšej nechceli distribuovať natívne binárne súbory. Pošlite jej akýkoľvek prúd s podporou vyhľadávania (seekable stream):
uses Classes, FPdfPdfx;
function QuickPdfXGate(const FileName: string): Boolean;
var
Fs: TFileStream;
Res: TPdfXValidationResult;
begin
Fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
Res := ValidatePdfXCompliance(Fs);
Result := Res.IsCompliant and (Res.Conformance <> pxcNone);
finally
Fs.Free;
end;
end;
Pri nástrojoch preflightu záleží na úprimnosti, preto uvádzame limity. Metóda ValidatePdfX overuje identifikačné značky, štrukturálne zákazy, kľúče geometrie stránky, deklaráciu Trapped a vloženie písiem až na úroveň jednotlivých textových objektov. Nemerá však celkové pokrytie farbami, neoveruje, či je každý farebný priestor legálny pre deklarovaný variant (napríklad pravidlo len pre CMYK vo verzii X-1a), nekontroluje rozlíšenie obrázkov voči rastru, ani nevyhodnocuje pretlač a sploštenie priehľadnosti — to vyžaduje plnohodnotný preflight nástroj so správou farieb, pričom vlastná dokumentácia jednotky odporúča pre finálnu certifikáciu kombináciu s ním. Dvojvrstvová kontrola vám poskytne 80 % odmietnutí, ktoré sú štrukturálne a ľahko zistiteľné vopred, zachytené v milisekundách priamo vo vašom delphijskom kóde namiesto zajtrajšieho e-mailu z tlačiarne
Obe validačné vrstvy, rozhrania API na vkladanie značiek PDF/X pre vytváranie kompatibilného výstupu, a validátory PDF/A, PDF/UA, PDF/E aj PDF/VT, ktoré zdieľajú rovnakú architektúru, sa dodávajú v komponente PDFium pre Delphi a C++Builder — jeden komponent, od vykresľovania až po tlačové brány
Domov · Hľadať · losLab.com