PDF/E-1 is het archiveringsprofiel voor engineeringdocumenten, en PDFlibPas implementeert het als een author mode die u aanzet met SetPDFEMode, plus een afgebakende preflight die content streams operator voor operator leest. Het profiel is geen PDF/A met een ander etiket: het heeft een eigen identificatienamespace, een eigen lifecycle-metadata-eis, en één regel die contentvalidatie strenger maakt dan elk archiveringsprofiel dat u ooit bent tegengekomen
Engineering deliverables zijn de reden dat het profiel bestaat. Een tekeningenset die over twintig jaar nog leesbaar moet zijn en aantoonbaar onveranderd, met een revisiehistorie die overleeft, en met kleur die op de plotter in het andere gebouw hetzelfde betekent. Die eisen leveren een specificatie op waarvan de eisen grotendeels buiten de pagina-inhoud liggen, in metadata en kleurbeheer, en dat is precies waar een generieke PDF writer het verkeerd doet
Een eigen identificatie, geen variatie op PDF/A
Het eerste wat goed moet zitten: PDF/E-1-identificatie valt niet te maken door het PDF/A- of PDF/X-patroon aan te passen. Het profiel gebruikt een eigen XMP-namespace, http://www.aim.org/pdfe/ns/id/, en de versiewaarde moet op twee plekken staan: als document information entry en als namespace-gekwalificeerde XMP-property. Alleen de XMP-property uitzenden, of alleen de information entry, levert een file op die de intentie draagt en toch door de validatie zakt
De output intent heeft een even specifieke vorm. PDF/E-1 vereist een embedded ICC-profiel met de subtype-identificator ISO_PDFE1, en het profiel moet een componentaantal hebben dat matcht met de device color-familie die het document werkelijk gebruikt. Die laatste clausule is waar implementaties stilletjes de fout in gaan, want het betekent dat de intent niet vooraf gekozen en daarna genegeerd kan worden
Waarom heeft device color een sweep over het hele document nodig?
Omdat color spaces zich verschuilen in resource dictionaries waar een scan op paginaniveau nooit komt. PDF/E-1 behandelt DeviceRGB en DeviceCMYK als onderling exclusieve families voor één document, dus het valideren van het profiel betekent dat u elk device color space moet kennen dat iets in de file gebruikt. Een form XObject heeft zijn eigen resources. Een pattern ook, en een image ook. Een tiling pattern in een form XObject in een pagina zit drie niveaus diep, en een validator die alleen de resources op het bovenste paginaniveau checkt, keurt een document goed dat beide families gebruikt
De sweep registreert daarom color spaces tijdens één traversering die pagina's, forms, images en patterns samen afgaat, en pas daarna wordt besloten of het document coherent is en of de output intent matcht. Hetzelfde redeneren stuurt de preflight-architectuur in het algemeen: partiële traversering levert false passes op, en een false pass op een conformancecheck is erger dan geen check, want hij wordt geregistreerd als bewijs
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');
// Author mode houdt de lifecycle metadata bij elke save in de pas.
// Vraag vóór het opslaan of het document door zijn eigen gate zou komen
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;
Lifecycle metadata is een verplichting per save
PDF/E-1 vraagt meer dan een documentidentificator. De minimale set omvat de media management document identifier, een version identifier, een rendition class, creation time, modification time, metadata time en een title. Dat is een vocabulaire voor revisietracking, en hij bestaat omdat van een engineering deliverable wordt verwacht dat hij opnieuw wordt uitgegeven in plaats van eenmalig geschreven
Het gevolg voor een implementatie is dat deze velden niet bij het aanmaken van het document gezet kunnen worden. Als de modification time wordt weggeschreven op het moment dat u de mode aanzet en het document daarna wordt bewerkt, dan zijn de XMP-snapshot en de werkelijke documentstatus uit elkaar gelopen, en een validator die ze vergelijkt rapporteert een inconsistentie die niemand bedoelde. Author mode synchroniseert de velden daarom onmiddellijk vóór elke save, zodat de metadata de bytes beschrijft die op het punt staan geschreven te worden, in plaats van de bytes die er waren toen de mode werd aangezet
Dit is een algemeen principe voor conformance metadata en het is het apart noemen waard, los van PDF/E: afgeleide metadata hoort op het savepad, niet op het bewerkingspad. Elk veld dat uit de documentstatus is berekend, moet opnieuw berekend worden op het moment dat die status bevroren wordt, anders is het een cache zonder invalidatie
De regel die contentvalidatie streng maakt
PDF/E-1 staat niet toe dat de compatibility section-operators onbekende inhoud absorberen. In gewone PDF zetten BX en EX een regio uit binnen welke een consumer operators die hij niet herkent moet negeren; dat is het luik dat een producer in staat stelt nieuwere constructies uit te zenden zonder oudere readers te breken. Onder PDF/E-1 zit dat luik dicht, dus elke operator die de preflight niet herkent wordt onvoorwaardelijk gerapporteerd, of hij nu in een compatibility section zit of niet
Het effect op een validator is aanzienlijk. Hij kan geen regio's overslaan die hij niet begrijpt, wat betekent dat de operand-parser echt elke operator in elke content stream moet parsen. Daar komen de grenzen om de hoek. De traversering is afgekapt op 128 nestingniveaus, één miljoen objecten en 64 MiB aan inhoud, en die limieten zijn geen performance tuning. Een vijandige of simpelweg kapotte file kan een object graph presenteren met cycles of een nestingsdiepte die een recursieve validator in een stack overflow verandert, en de limieten zijn wat voorkomt dat een validatieronde een denial-of-service-vector wordt. Dezelfde defensieve houding staat beschreven in untrusted PDF's veilig parsen
// Losse validatie van een file die u niet zelf produceerde, zonder
// hem in een documentinstantie te laden
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;
Wat de save gate repareert en wat hij weigert
De gate verdeelt zijn werk in twee fasen, en die splitsing is op zichzelf al een bruikbaar ontwerpinsicht. Eerst normaliseert hij wat veilig repareerbaar is: annotation print flags, de no-zoom- en no-rotate-flags op text annotations, en de appearance-generation flag op de form dictionary. Het zijn instellingen met onder het profiel precies één correcte waarde en zonder informatiewaarde, dus ze stilletjes fixen is juist en ze weigeren zou pedanterie zijn
Daarna checkt hij de beperkingen die niet te repareren zijn zonder te veranderen wat het document betekent: version, identification, encryption, output intent, device color-coherentie en de aanwezigheid van dynamische forminhoud. Een document dat daar één van mist, wordt geweigerd, want een output intent verzinnen of een kleurfamilie kiezen namens de auteur levert een file op die door de validatie komt en de inhoud verkeerd voorstelt
De diagnostics vooraf uitlezen via GetPDFEDiagnostics maakt van die weigering een bruikbare lijst in plaats van een mislukte operatie. Roep het in een batch-pipeline voor elk document aan, log de blockers per file en stuur de failures naar een queue die een mens bekijkt. Dat is een stuk nuttiger dan een save die een exceptie gooit, want blockers clusteren meestal: veertig documenten die vallen op dezelfde ontbrekende output intent is één fix, geen veertig
Kiezen tussen de archiveringsprofielen
PDF/E-1 is het juiste target als het deliverable engineeringdocumentatie is met een revisielevenloop, en vooral als device color-coherentie ertoe doet omdat de output naar plotters en large-format printers gaat. PDF/A is het juiste target als het doel de langetermijnleesbaarheid van documenten in het algemeen is, en het is het profiel met de breedste validatorondersteuning. De twee zijn niet uitwisselbaar, en een document kan aan de ene voldoen en door de andere zakken
Als u moet kiezen, begin dan bij wie de file aan de verre kant valideert. PDF/A-validatietooling is overal te vinden, en de bijbehorende preflight in PDFlibPas staat beschreven in PDF/A- en PDF/UA-preflight. PDF/E-validatie is specialistischer en meestal een contractuele eis in plaats van een default. Als een bestaand archief naar een profiel moet waar het nooit voor geschreven is, is het metadata-reparatiepad in converteren naar PDF/A met metadata-reparatie het patroon om te volgen, en hier geldt dezelfde vorm: identificeren, repareren wat veilig is, de rest weigeren met een lijst
Author mode, de afgebakende content-preflight en de losse compliance check worden allemaal geleverd met de PDFlibPas Delphi PDF library, zodat een document onder het profiel kan worden geproduceerd en daarna onafhankelijk wordt geverifieerd via een aparte coderoute, en dat is de enige opzet die u bij een conformance-claim kunt vertrouwen