PDF/E-1 er arkiveringsprofilen for tekniske dokumenter, og PDFlibPas implementerer den som en forfattermodus du slår på med SetPDFEMode, pluss en avgrenset preflight som leser innholdsstrømmer operator for operator. Profilen er ikke PDF/A med en annen etikett: den har sitt eget identifikasjonsnavnerom, sitt eget krav om livssyklusmetadata, og én regel som gjør innholdsvalidering strengere enn noen arkiveringsprofil du har møtt
Tekniske leveranser er grunnen til at profilen finnes. Et tegningssett som må være lesbart og bevist uendret om tjue år, med en revisjonshistorikk som overlever, og med farger som betyr det samme på plotteren i den andre bygningen. Disse kravene gir en spesifikasjon der kravene stort sett ligger utenfor sideinnholdet, i metadata og fargehåndtering, noe som er nøyaktig der en generisk PDF-skriver tar feil
Egen identifikasjon, ikke en variant av PDF/A
Det første som må bli riktig, er at PDF/E-1-identifikasjon ikke kan produseres ved å tilpasse PDF/A- eller PDF/X-mønsteret. Den bruker et eget XMP-navnerom, http://www.aim.org/pdfe/ns/id/, og versjonsverdien må opp i to steder: som en dokumentinformasjonspost og som den navneromskvalifiserte XMP-egenskapen. Å skrive bare XMP-egenskapen, eller bare informasjonsposten, gir en fil som bærer intensjonen, men som feiler valideringen
Output intent har en like spesifikk form. PDF/E-1 krever en innebygd ICC-profil med subtype-identifikatoren ISO_PDFE1, og profilen må ha et komponentantall som matcher enhetsfargefamilien dokumentet faktisk bruker. Den siste klausulen er der implementasjoner tar stille feil, fordi den betyr at output intenten ikke kan velges på forhånd og deretter ignoreres
Hvorfor trenger enhetsfarge en gjennomgang av hele dokumentet?
Fordi fargerom gjemmer seg i ressursordbøker en skanning på sidennivå aldri når. PDF/E-1 behandler DeviceRGB og DeviceCMYK som gjensidig utelukkende familier for et dokument, så å validere profilen betyr å kjenne hvert enhetsfargerom noe som helst i filen bruker. Et form XObject har egne ressurser. Det har et mønster også, og et bilde også. Et tiling-mønster inne i et form XObject inne i en side ligger tre nivåer dypt, og en validator som bare sjekker toppnivåressursene på siden, vil godkjenne et dokument som bruker begge familiene
Gjennomgangen registrerer derfor fargerom mens den går gjennom sider, form XObjects, bilder og mønstre som én traversering, og bestemmer først deretter om dokumentet er koherent og om output intenten matcher. Samme resonnement driver preflight-arkitekturen generelt: delvis traversering gir falske godkjenninger, og en falsk godkjenning på en samsvarskontroll er verre enn ingen kontroll, fordi den registreres som bevis
var
Lib: TPDFlib;
Diag: WideString;
begin
Lib := TPDFlib.Create(nil);
try
Lib.LoadFromFile('assembly-drawings.pdf');
if Lib.SetPDFEMode(1) = 0 then
raise Exception.Create('PDF/E author mode was refused');
// Forfattermodus holder livssyklusmetadataene i takt ved hver lagring.
// Spør før lagring om dokumentet ville passert sin egen port
if not Lib.PDFEReadyForSave then
begin
Diag := Lib.GetPDFEDiagnostics;
Writeln('PDF/E blockers: ', Diag);
Exit;
end;
Lib.SaveToFile('assembly-drawings-pdfe.pdf');
finally
Lib.Free;
end;
end;
Livssyklusmetadata er en forpliktelse ved hver lagring
PDF/E-1 ber om mer enn en dokumentidentifikator. Minimumssettet inkluderer identifikatoren for mediehåndteringsdokumentet, en versjonsidentifikator, en rendition-klasse, opprettingstidspunkt, endringstidspunkt, metadata-tidspunkt og en tittel. Det er et revisjonssporingsvokabular, og det finnes fordi en teknisk leveranse forventes å bli gjenutgitt snarere enn skrevet én gang
Konsekvensen for en implementasjon er at disse feltene ikke kan settes ved dokumentoppretting. Hvis endringstidspunktet skrives når du slår på modusen og dokumentet redigeres etterpå, har XMP-øyeblikksbildet og den faktiske dokumenttilstanden drevet fra hverandre, og en validator som sammenligner dem, rapporterer en inkonsistens ingen hadde tenkt seg. Forfattermodus synkroniserer derfor feltene umiddelbart før hver lagring, slik at metadataene beskriver bytene som skal skrives, snarere enn bytene som fantes da modusen ble slått på
Dette er et generelt prinsipp for samsvarsmetadata, og det er verdt å si separat fra PDF/E: avledede metadata hører hjemme på lagringsveien, ikke redigeringsveien. Ethvert felt beregnet fra dokumenttilstand må beregnes på nytt i det øyeblikket tilstanden fryses, ellers er det en cache uten ugyldiggjøring
Regelen som gjør innholdsvalidering streng
PDF/E-1 tillater ikke at operatorene i kompatibilitetsseksjonen absorberer ukjent innhold. I vanlig PDF rammer BX og EX inn et område der en konsument må ignorere operatorer den ikke gjenkjenner, noe som er fluktlukken som lar en produsent skrive nyere konstruksjoner uten å ødelegge for eldre lesere. Under PDF/E-1 er den flukten stengt, så enhver operator preflighten ikke gjenkjenner, rapporteres betingelsesløst, enten den ligger inne i en kompatibilitetsseksjon eller ikke
Effekten på en validator er betydelig. Den kan ikke hoppe over områder den ikke forstår, noe som betyr at operand-parseren faktisk må parse hver operator i hver innholdsstrøm. Det er der grensene kommer inn. Traverseringen takseres til 128 hekkingsnivåer, én million objekter og 64 MiB innhold, og de grensene er ikke ytelsestuning. En fiendtlig eller bare ødelagt fil kan presentere en objektgraf med sykluser eller en hekkingsdybde som gjør en rekursiv validator om til en stack overflow, og grensene er det som hindrer en valideringsrunde i å bli en denial-of-service-vektor. Den samme defensive holdningen er beskrevet i trygg parsing av utiltrodde PDF-er
// Fristående validering av en fil du ikke produserte, uten å laste den
// inn i en dokumentinstans
var
Issues: TStringList;
Stream: TFileStream;
I: Integer;
begin
Issues := TStringList.Create;
Stream := TFileStream.Create('incoming.pdf', fmOpenRead or fmShareDenyWrite);
try
if CheckCompliancePDFE(Stream, '', 0, Issues) = 0 then
for I := 0 to Issues.Count - 1 do
Writeln('PDF/E: ', Issues[I]);
finally
Stream.Free;
Issues.Free;
end;
end;
Hva lagringsporten reparerer og hva den nekter
Porten deler arbeidet sitt i to etapper, og delingen er en brukbar designidé i seg selv. Først normaliserer den tingene som trygt kan repareres: utskriftsflaggene på annotasjoner, ingen-zoom- og ingen-roter-flaggene på tekstannotasjoner, og appearance-genereringsflagget i formordboken. Dette er innstillinger med én korrekt verdi under profilen og uten informasjonsinnhold, så å fikse dem i stillhet er riktig, og å nekte på dem ville vært pirk
Deretter sjekker den begrensningene som ikke kan repareres uten å endre hva dokumentet betyr: versjon, identifikasjon, kryptering, output intent, enhetsfargekoherens og tilstedeværelse av dynamisk skjemainnhold. Et dokument som feiler på noe av dette, nektes, fordi å finne på en output intent eller velge en fargefamilie på forfatterens vegne ville gitt en fil som passerer valideringen og feilrepresenterer innholdet
Å lese diagnostikken tilbake gjennom GetPDFEDiagnostics før lagring gjør avslaget om til en handlingsbar liste i stedet for en mislykket operasjon. I en batch-rørledning: kall den på hvert dokument, logg blokkeringene per fil, og rute feilene til en kø et menneske ser på. Det er langt mer nyttig enn en lagring som kaster unntak, fordi blokkeringene vanligvis klumper seg: førti dokumenter som feiler på samme manglende output intent, er én fiks, ikke førti
Valget mellom arkiveringsprofilene
PDF/E-1 er riktig mål når leveransen er teknisk dokumentasjon med en revisjonssyklus, og spesielt når enhetsfargekoherens betyr noe fordi utdataene går til plottere og storformatprintere. PDF/A er riktig mål når målet er langsiktig lesbarhet av dokumenter generelt, og det er profilen med bredeste validatorstøtte. De to er ikke utskiftbare, og et dokument kan tilfredsstille den ene og feile den andre
Hvis du skal velge, start med hvem som validerer filen i den andre enden. PDF/A-valideringsverktøy finnes overalt, og den tilhørende preflighten i PDFlibPas er beskrevet i PDF/A- og PDF/UA-preflight. PDF/E-validering er mer spesialisert og er vanligvis et kontraktskrav snarere enn et standardvalg. Når et eksisterende arkiv må bringes opp til en profil det aldri ble skrevet for, er metadatareparasjonsveien i konvertering til PDF/A med metadatareparasjon mønsteret å følge, og samme form gjelder her: identifiser, reparer det som er trygt, nekt resten med en liste
Forfattermodus, den avgrensede innholdspreflighten og den fristående samsvarskontrollen følger alle med PDFlibPas Delphi PDF-bibliotek, så et dokument kan produseres under profilen og verifiseres uavhengig etterpå gjennom en separat kodevei, noe som er den eneste ordningen verdt å stole på for et samsvarskrav