Tehnični članak

Omejitve implementacije PDF/A in preverjanje kodiranja pisav

PDFium Component preverja implementacijske omejitve ISO 19005-1 Annex C — žetoni imen do 127 bajtov, elementi polja do 8191, vnosi slovarja do 4095 in 28 ravni vgnezdenja vsebnikov — in poroča o simbolni pisavi TrueType, ki nosi vnos /Encoding. Obe preverbi tečeta po poti bajtnega pregleda, tako aplikacija Delphi ali Lazarus dobi verdikt, ne da bi sploh naložila DLL PDFium

To sta odpovedi, ki ljudi najbolj zbujata, ker dokument izgleda v redu. Izriše se, natisne se, vse pisave so vdelane, namen izhoda je prisoten. Nato ga validator zavrne zaradi slovarja, ki ima 4096 vnosov, v vidnem dokumentu pa ni ničesar, kar bi razložilo zakaj

Kaj omejitve Annex C dejansko varujejo?

Interoperabilnost z implementacijami, ki so starejše od vašega generatorja. Annex C nosi implementacijske omejitve referenco PDF naprej v vsak del PDF/A in številke niso poljubne — opisujejo, kaj je moral skladni bralec zgodovinsko obdelati. Datoteka, ki jih presega, se lahko popolnoma odpre v sodobnem bralniku in odpove v arhivskem bralniku, na katerega se je sistem zapisov standardiziral pred petnajstimi leti, kar je natanko scenarij, ki naj bi ga PDF/A preprečeval

Štiri omejitve so vključujoče. Žeton imena natanko 127 bajtov velja; 128 ne. Polje z natanko 8191 elementi velja; 8192 ne. PDFium Component v svoji preizkusni zbirki pripne obe strani vsake meje iz tega razloga, ker napaka pri ena v preverjanju omejitve proizvede najslabšo vrsto validatorja: takega, ki zavrne skladne datoteke in mu kljub temu verjamemo

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;

Kateri generatorji dejansko zadenejo te omejitve?

Tisti, ki strukturo gradijo programsko, kar je večina poslovnega izhoda. Obrazec z več tisoč polji proizvede polje /Annots ali polje AcroForm /Fields, ki zrase čez 8191. Stran, katere slovar sredstev nabira en vnos na generirano sliko ali primerek pisave, prečka 4095. Globoko generirana drevesa strukture — označeni dokument, zgrajen z rekurzijo čez vgnezdeni model podatkov — prehajajo čez 28 ravni, ne da bi to kdo opazil, ker nihče ne gleda globine vgnezdenja

Dolga imena prihajajo iz druge navade: kodiranje podatkov v žetone imen. Ime barvila, zgrajeno iz identifikatorja stranke, izbirna-skupina vsebine, poimenovana po polni poti datoteke, polje obrazca, katerega popolnoma kvalificirano ime spoji šest ravni hierarhije. Imena so poceni za generiranje in jih je lahko narediti dolga, 127 bajtov pa izgine hitreje, kot bi pričakovali, ko je vpletena UTF-8 kodirana oznaka

Popravek je v vsakem primeru strukturnen. Razcepi polje, razcepi slovar, splošči vgnezdenje, skrajšaj ime — priporočilo predleta za vsako težavo poimenuje konkretno omejitev namesto da bi vam govorilo, da je datoteka neveljavna. Injiciranje oznak tukaj ne more pomagati: to niso zahteve metapodatkov, to je oblika grafa objektov

Zakaj simbolna pisava TrueType ne sme nositi /Encoding

Ker ISO 19005-1 §6.3.7 za simbolne pisave TrueType dopušča samo vgrajeni cmap pisave, vnos /Encoding pa bi mu nasprotoval. Simbolna pisava preslika kode v glasove po svojih lastnih pravilih — to pomeni simbolna. Dodajte kodno tabelo in sta zdaj dva odgovora na vprašanje "kateri glif izbere bajt 0x41", brez pravila v datoteki, ki bi reklo, kateri zmaga. Različni bralci to razrešijo različno in dokument, ki se v enem bralniku izriše kot besedilo, se v drugem izriše kot činki

PDFium Component prebere zastavico simbolne iz /FontDescriptor, ne glede na to, ali je opisnik zapisan vzporedno v slovarju pisave ali referenciran posredno. Nesimbolna pisava TrueType obdrži svojo zahtevano /WinAnsiEncoding ali /MacRomanEncoding brez oznake, ker je za nesimbolne pisave kodiranje natanko tisto, kar zahteva standard. Preverjanje se sproži na protislovju in ne na prisotnosti kodiranja

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)');

Praktični vir te napake je podmnožičenje pisav, ki ga izvaja producent, ki obravnava vsako pisavo TrueType enako. Symbol, Wingdings, črtne kode in ikonske pisave so običajni nosilci — natanko pisave, ki jih poslovni dokument uporablja za potrditvena polja, logotipe in črtne kode, in natanko tiste, ki jih nihče ne preverja, ko dokument odpove pri validaciji zaradi "pisav"

Kako težave prispejo v poročilo predleta

Štiri omejitve vsebnikov so razvrščene pod strukturo; težava kodiranja simbolne TrueType je razvrščena pod vsebino. Ta razcep šteje, ko poročilo gre k dvema različnima osebama: ugotovitve strukture običajno pripadajo tistemu, ki je napisal generator, ugotovitve vsebine pa tistemu, ki je dobavil sredstva

Vsaka težava nosi priporočilo, ki zdravilo poimenuje v konkretnih izrazih — skrajšajte žetone imen na 127 bajtov ali manj, razcepite polja tako, da nobeno ne nosi več kot 8191 elementov, odstranite /Encoding iz simbolnih pisav TrueType. Poročilo, ki pravi "ni skladno s PDF/A", začne preiskavo. Poročilo, ki pravi, katera omejitev je bila presežena in s čim, eno konča

Preverjanje brez DLL in zakaj to tu šteje

Vse zgornje preverbe tečejo proti bajtom datoteke, tako delujejo v storitvi, ki nima nameščenega binarnega PDFium, v koraku gradnje ali na stroju, kjer je nalaganje izvornega DLL problem politike. To je namerna oblikovna črta v PDFium Component: preverbe, ki se jih da odgovoriti iz strukture, se odgovorijo iz strukture, DLL pa je pridržan za tiste, ki resnično potrebujejo pogon upodabljanja

Za okoliški delovni tok — izvajanje validacije čez mapo, proizvajanje poročil in odločanje, kaj storiti z ugotovitvami — glejte sprehode skozi validacijo predleta PDF/A v Delphiju in CLI paketnega poročila predleta. Za izbiro arhivskega profila, ki sedi nad vsemi těmi preverbami, zapiski o arhirski skladnosti PDF/A obravnavajo, kateri del in raven ciljati, preden začnete popravljati ugotovitve

PDFium Component ovije pogon PDFium za Delphi, C++Builder in Lazarus z visokonivojskim API VCL in naborom validatorjev skladnosti, ki tečejo z DLL ali brez njega — glejte stran izdelka PDFium Component za podprte standarde in platforme