Filen åpner seg feilfritt på maskinen din. Acrobat viser den, forhåndsvisningen for utskrift ser riktig ut, hver side er der. Så går den til trykkeriet, eller inn i arkivsystemet som tar imot den månedlige batchen din, og den kommer tilbake avvist: RGB-bilder i en CMYK-jobb, ingen /Trapped-nøkkel, en output intent som ikke stemmer med trykkeriet. Ingenting var galt med dokumentet som noen kunne se. Det var galt mot en profil, og profilen ble sjekket et sted du ikke var. Preflight er prepress-navnet på den sjekken, og det egentlige spørsmålet er hvor den hører hjemme når PDF-ene kommer ut av din egen Delphi-kode i stedet for fra en designers skrivebord
HotPDF gir deg ikke en preflight-funksjon å kalle. Komponenten har et preflight-rapportvindu i sin GUI-demo, men det finnes ikke noe API bak det som en tjeneste eller et byggeskript kan påkalle, og å late som noe annet ville sendt deg på jakt etter en metode som ikke finnes. Det høres ut som et hull inntil du legger merke til at for filer du selv genererer, er det å kalle en validator på din egen output uansett feil form. Du kontrollerer allerede hver eneste egenskap en validator ville inspisert. Den nyttige oppdelingen er å gjøre generatoren ute av stand til å sende ut en dårlig fil, og deretter bevise det med et verktøy du ikke selv skrev
Hvorfor du sjekker din egen output annerledes
Tradisjonell preflight forutsetter en fremmed fil. En eller annen designer, en annen applikasjon, en ukjent kjede av redigeringer produserte den, og du inspiserer den fordi du ikke har peiling på hva som er inni. Et dokument koden din produserte, er ingen fremmed. Skriftinnbygging, fargerom, output intent, metadatablokken: programmet ditt bestemte alt sammen noen millisekunder før filen traff disken. Å inspisere den etterpå for å oppdage valg du nettopp gjorde, er unødvendig ekstraarbeid. Det billigere grepet er å begrense disse valgene, slik at en ikke-samsvarende fil aldri kommer til å eksistere for å bli fanget
Det finnes også en troverdighetsgrunn til å holde verifiseringen ekstern. Et bibliotek som velsigner sin egen output, sensurerer sin egen eksamen. Når en kundes arkivsystem eller et trykkeris RIP avviser filen din, veier «komponenten vår sier den er grei» ingenting. En dom fra veraPDF eller Acrobat gjør det, fordi den andre siden kjører de samme verktøyene
Gjør samsvar til en innstilling, ikke en sjekkliste
Forebyggingslaget er bare konfigurasjon. Sett PDFACompliance eller PDFXCompliance før BeginDoc, så holder HotPDF de tilsvarende reglene gjennom hele genereringspasset: den bygger inn skrifter, følger med på bruken av DeviceRGB og DeviceCMYK mot output intent-en du erklærte, og nekter funksjoner profilen forbyr. Motsigelsene kommer til syne ved EndDoc, hvor samsvarsportene kaster unntak i stedet for å stille sende ut noe som vil feile nedstrøms. Når filen er lagret, leser de samme egenskapene tilbake hva som faktisk ble håndhevet, noe som er det ene faktumet pipeline-loggen din trenger mest:
// Etter EndDoc: registrer de håndhevede profilene sammen med kjøremetadataen
if Pdf.PDFACompliance <> '' then
Log('Generated as PDF/A level ' + Pdf.PDFACompliance);
if Pdf.PDFXCompliance <> '' then
Log('Generated as PDF/X profile ' + Pdf.PDFXCompliance);
Legg disse flaggene på samme loggling som hashen for inndataene og HotPDF-versjonen. Den dagen en validator og generatoren din er uenige om en fil, forteller den linjen deg hvilken mal som produserte den, og hvilket build av biblioteket som var lastet inn, og diskusjonen som ellers ville spist en ettermiddag, blir en grep. Output intents, ICC-profiler og tagging som ligger bak disse flaggene, er forklart i detalj i guiden til PDF/A-, PDF/X- og PDF/UA-output med HotPDF
En billig førstegangssjekk for filer du ikke selv genererte
Ikke alle pipeliner er rent generative. Kunder laster opp PDF-er, skannere slipper dem i en mappe, partnere legger dem ved e-post. Å presse hver eneste av dem gjennom en full strukturell validator sløser bort køtid på filer som ikke engang vil åpne seg. HotPDFs Direct File API leser nok av en fils struktur til å svare på «er dette i det hele tatt en brukbar PDF» uten å laste inn hele objekttreet, noe som gjør det til et godt sted å feile raskt:
function TriagePdf(Pdf: THotPDF; const FileName: string): Boolean;
var
Handle, Pages: Integer;
begin
Result := False;
Handle := Pdf.DAOpenFileReadOnly(FileName, '');
if Handle <= 0 then
Exit; // strukturelt uleselig: sett i karantene, ikke valider
try
Pages := Pdf.DAGetPageCount(Handle);
Result := Pages > 0;
finally
Pdf.DACloseFile(Handle);
end;
end;
To fakta om dette API-et avgjør hvordan du pakker det inn. Snarveien for flatt minneforbruk holder bare for ukrypterte inndata; gir du DAOpenFileReadOnly et passord, faller den stille tilbake til en full parsing, så en fil du vet er kryptert, bør gå gjennom DecryptFile og bli en ren arbeidskopi før triage. Og DAGetPageCount betyr ingenting på et handle som ikke åpnet seg feilfritt, så handle-sjekken forblir streng, og et ikke-positivt resultat er en avvisning, ikke et nytt forsøk. Flere av disse mønstrene finnes i artikkelen om Direct File API-et for store PDF-arbeidsflyter
veraPDF, kjørt som en del av builden
For alt du hevder er PDF/A eller PDF/UA, er veraPDF validatoren å koble inn. Den kjører headless, tar en batch, gir ut XML eller JSON, og navngir hver feil etter ISO-klausulen, så en regelfeil mot ISO 19005-1 klausul 6.2.2 peker rett tilbake på en generatorinnstilling i stedet for å la deg gjette. Å styre den fra Delphi er ren prosesskontroll:
function RunVeraPdf(const PdfFile, ReportFile: string): Cardinal;
var
Cmd: string;
SI: TStartupInfo;
PI: TProcessInformation;
begin
Cmd := Format('cmd /c verapdf.bat --format xml "%s" > "%s"',
[PdfFile, ReportFile]);
FillChar(SI, SizeOf(SI), 0);
SI.cb := SizeOf(SI);
if not CreateProcess(nil, PChar(Cmd), nil, nil, False,
CREATE_NO_WINDOW, nil, nil, SI, PI) then
RaiseLastOSError;
try
WaitForSingleObject(PI.hProcess, 120000); // avgrens ventetiden per fil
GetExitCodeProcess(PI.hProcess, Result);
finally
CloseHandle(PI.hThread);
CloseHandle(PI.hProcess);
end;
end;
Den timeouten fortjener plassen sin. En feilformet fil kan drive en hvilken som helst parser inn i et hjørne den aldri kommer ut av igjen, og en åpen ventetid inne i en køarbeidsprosess drar resten av køen ned med seg. Avgrens ventetiden, gi en timeout sin egen feilkode, og legg filen til side for et menneske. Når du leser resultatet, parse XML-en etter regelidentifikatorer, ikke etter den menneskelesbare teksten. Regel-ID-er overlever validatoroppgraderinger; ordlyden i meldingene gjør det ikke, og en stabil kode er noe en supportingeniør kan søke gamle saker mot
Hvordan du kjører batchen, betyr like mye som om hver fil består. Én prosess per fil, ikke én per batch, så en giftig inndata koster deg bare den filens timeout og ikke noe mer. Sett et tak på antall validatorprosesser lik kjernetallet, fordi det å bygge XML-rapporten er CPU-bundet, og overtegning bare gir trashing. Og sett et størrelsestak ved inntak, fordi en to-gigabyte skannet bok vil eie køen uansett hvor tålmodig parseren er. Ingenting av dette er preflight i streng forstand. Det er forskjellen mellom en port som overlever månedsslutt-volumet, og en som blir slått av den første natten den stopper opp pipelinen klokken to om natten
PDF/X er der dette kommer til kort. veraPDF validerer det ikke, så den fungerende sjekken er fortsatt Acrobats Preflight med ISO 15930-profilen trykkeriet ditt navnga. Acrobat vil ha et menneske, noe som betyr utvalgssjekking snarere enn full dekning: den første filen fra en ny mal, pluss et lite tilfeldig utvalg fra hver batch, mens den automatiserte porten håndterer alt som kan håndteres uten et menneske. En utvalgssjekk som faktisk kjører, slår en komplett automatisering som forblir halvferdig for alltid
En rapport du fortsatt vil ha bruk for om et år
En preflight-port lønner seg to ganger. Én gang når den stopper en dårlig fil ved døren, og igjen mye senere når noen spør hvorfor en bestemt fil slapp gjennom. Det andre øyeblikket er det som bør diktere formatet, fordi det er der en tynn rapport lar deg stå fast. For hver fil som sjekkes, ta vare på inndata-hashen, generatorens samsvarsflagg og biblioteksversjon fra loggraden ovenfor, validatorens navn og versjon, profilen den ble sjekket mot, bestått eller feilet, og de mislykkede regel-ID-ene med sidetall der validatoren gir dem. Lagre den rapporten ved siden av filen den beskriver. Legg den i et separat system, og det systemet vil bli lagt ned før arkivet det dokumenterer
Unntak må også skrives ned. Når en kunde insisterer på å sende en fil porten misliker, er svaret ikke å løsne opp regelen for alle. Registrer hvem som godkjente denne filen, på hvilket grunnlag, og frem til hvilken dato, og fest deretter det unntaket til rapporten dens. Et unntak med et navn og en utløpsdato er en beslutning noen eier. En sjekk som er kommentert ut «midlertidig», er en hendelse som venter på sin dato
Enda en vane betaler for seg selv: når en fil feiler, kopier den inn i en navngitt regresjonsmappe før noen rører den. Nesten hvert preflight-problem verdt å feilsøke, spores tilbake til én bestemt inndata, og teamene som tar vare på disse inndataene, fikser gjentakelsen på en time i stedet for å vente på at den dukker opp igjen i produksjon. Samsvarsegenskapene og Direct File API-et vist her, er en del av HotPDF Delphi Component for Delphi og C++Builder, hvis dokumentasjon dekker hvert kall i sin helhet