PDFium Component validerer ISO 19005-1 Annex C-implementasjonsgrensene — 127-byte navne-tokens, 8191 array-elementer, 4095 ordbok-oppføringer og 28 nivåer av container-nøsting — og rapporterer en symbolsk TrueType-skrift som bærer en /Encoding-oppføring. Begge sjekkene kjører på byte-skannings-stien, slik at en Delphi- eller Lazarus-applikasjon får dommet uten å laste PDFium-DLL-en i det hele tatt
Dette er de feilene som forvirrer folk mest, fordi dokumentet ser fint ut. Det renderer, det skrives ut, hver skrift er innebygd, utdata-intent-en er til stede. Så avviser en validator det over en ordbok som har 4096 oppføringer, og ingenting i det synlige dokumentet forklarer hvorfor
Hva beskytter Annex C-grensene faktisk?
Interoperabilitet med implementasjoner som er eldre enn din generator. Annex C fører PDF Reference-implementasjonsgrensene videre inn i hver PDF/A-del, og tallene er ikke vilkårlige — de beskriver hva en konform leser historisk sett var påkrevd å håndtere. En fil som overskrider dem kan åpne perfekt i en moderne leser og feile i den arkiv-leseren et arkivsystem standardiserte på for femten år siden, noe som er nøyaktig scenarioet PDF/A eksisterer for å forhindre
De fire grensene er inklusive. Et navn-token på nøyaktig 127 bytes validerer; 128 gjør ikke det. En array med nøyaktig 8191 elementer validerer; 8192 gjør ikke det. PDFium Component fester begge sider av hver grense i sin test-suite av den grunn, fordi en off-by-one i en grense-sjekk produserer den verste typen validator: en som avviser konforme filer og likevel blir trodd
uses FPdfPdfa;
var
Src: TFileStream;
Res: TPdfAValidationResult;
begin
Src := TFileStream.Create('archive.pdf', fmOpenRead or fmShareDenyWrite);
try
Res := ValidatePdfACompliance(Src);
if pvaiArrayOverLimit in Res.Issues then
Memo1.Lines.Add('An array carries more than 8191 elements');
if pvaiDictOverLimit in Res.Issues then
Memo1.Lines.Add('A dictionary carries more than 4095 entries');
if pvaiNestingOverLimit in Res.Issues then
Memo1.Lines.Add('Containers nest deeper than 28 levels');
if pvaiNameOverLimit in Res.Issues then
Memo1.Lines.Add('A name token is longer than 127 bytes');
finally
Src.Free;
end;
end;
Hvilke generatorer treffer faktisk disse grensene?
Slike som bygger struktur programmatisk, noe som er mesteparten av forretnings-utdata. Et skjema med flere tusen felt produserer en /Annots-array eller en AcroForm /Fields-array som vokser forbi 8191. En side hvis ressurser-ordbok akkumulerer én oppføring per genererte bilde eller skrift-instans krysser 4095. Dypt genererte struktur-trær — et merket dokument bygget ved rekursjon over en nøstet datamodell — går forbi 28 nivåer uten at noen legger merke til det, fordi ingen ser på nøstingsdybde
Lange navn kommer fra en annen vane: å kode data inn i navn-tokens. Et fargeleggs-navn bygget fra en kunde-identifikator, en valgfritt-innholds-gruppe navngitt etter en full filsti, et skjemafelt hvis fullt kvalifiserte navn setter sammen seks nivåer av hierarki. Navn er billige å generere og enkle å gjøre lange, og 127 bytes forsvinner raskere enn du ville forvente når en UTF-8-kodet etikett er involvert
Løsningen er strukturell i hvert tilfelle. Splitt arrayen, splitt ordboken, flat ut nøstingen, kort ned navnet — preflight-anbefalingen for hvert problem navngir den konkrete grensen snarere enn å fortelle deg at filen er ugyldig. Merke-injeksjon kan ikke hjelpe her: dette er ikke metadata-påstander, de er formen på objekt-grafen
Hvorfor må ikke en symbolsk TrueType-skrift bære /Encoding
Fordi ISO 19005-1 §6.3.7 kun innrømmer skriftens innebygde cmap for symbolske TrueType-skrifter, og en /Encoding-oppføring ville motsi det. En symbolsk skift tilordner koder til glyffer på sine egne premisser — det er det symbolsk betyr. Legg til en kodings-tabell og der er nå to svar på spørsmålet «hvilken glyff velger byte 0x41», uten noen regel i filen som sier hvilken som vinner. Ulike lesere løser det ulikt, og et dokument som renderer som tekst i én leser renderer som dingbats i en annen
PDFium Component leser det symbolske flagget fra /FontDescriptor, enten beskriveren er skrevet inline i skrift-ordboken eller referert indirekte. En ikke-symbolsk TrueType-skrift beholder sin påkrevde /WinAnsiEncoding eller /MacRomanEncoding uten å bli flagget, fordi for ikke-symbolske skrifter er kodingen nøyaktig det standarden ber om. Sjekken fyres på selvmotsigelsen, ikke på tilstedeværelsen av en koding
if pvaiSymbolicTrueTypeEncoding in Res.Issues then
Memo1.Lines.Add(
'A symbolic TrueType font carries /Encoding; PDF/A admits only its ' +
'built-in cmap (ISO 19005-1 6.3.7)');
Den praktiske kilden til denne defekten er skriftdelmengde-deling gjort av en produsent som behandler hver TrueType-skrift på samme måte. Symbol, Wingdings, strekkode-skrifter og ikon-skrifter er de vanlige bærerne — nøyaktig de skriftene et forretningsdokument bruker til avkrysningsbokser, logoer og strekkoder, og nøyaktig de ingen undersøker på nytt når et dokument feiler validering over «skrifter»
Hvordan problemene ankommer i en preflight-rapport
De fire container-grensene klassifiseres under struktur; det symbolske TrueType-kodingsproblemet klassifiseres under innhold. Den delingen betyr noe når en rapport går til to forskjellige personer: struktur-funn tilhører vanligvis den som skrev generatoren, og innholds-funn tilhører vanligvis den som leverte ressursene
Hvert problem bærer en anbefaling som navngir middelet i konkrete termer — kort ned navn-tokens til 127 bytes eller færre, splitt arrayer slik at ingen bærer mer enn 8191 elementer, fjern /Encoding fra symbolske TrueType-skrifter. En rapport som sier «ikke PDF/A-konform» starter en undersøkelse. En rapport som sier hvilken grense som ble overskredet og av hva avslutter en
Validering uten DLL-en, og hvorfor det betyr noe her
Alle sjekkene ovenfor kjører mot fil-bytene, så de virker i en tjeneste som ikke har noen PDFium-binær utrullet, i et bygg-trinn, eller på en maskin der å laste en innebygd DLL er et policy-problem. Det er en bevisst designlinje i PDFium Component: sjekkene som kan besvares fra struktur besvares fra struktur, og DLL-en er reservert for de som genuint trenger en rendringsmotor
For den omliggende arbeidsflyten — kjøre validering over en mappe, produsere rapporter, og avgjøre hva som skal gjøres med funnene — se gjennomgangene av PDF/A-preflight-validering i Delphi og batch-preflight-rapport-CLI-en. For arkiv-profilvalget som sitter over alle disse sjekkene, dekker notatene om PDF/A-arkiv-samsvar hvilken del og nivå du bør målrette mot før du begynner å fikse funn
PDFium Component pakker inn PDFium-motoren for Delphi, C++Builder og Lazarus med et høynivå VCL-API og et sett konformans-validatorer som virker med eller uten DLL-en — se PDFium Component-produktsiden for de støttede standardene og plattformene