PDFium Component memvalidasi batas implementasi ISO 19005-1 Annex C — token nama 127 byte, 8191 elemen array, 4095 entri dictionary dan 28 level bersarang kontainer — dan melaporkan font TrueType simbolik yang membawa entri /Encoding. Kedua pemeriksaan berjalan pada jalur byte-scan, sehingga aplikasi Delphi atau Lazarus mendapatkan vonis tanpa memuat DLL PDFium sama sekali
Inilah kegagalan yang paling membingungkan orang, karena dokumen terlihat baik-baik saja. Ia merender, ia mencetak, setiap font tertanam, output intent hadir. Lalu validator menolaknya karena dictionary yang memiliki 4096 entri, dan tidak ada apa pun dalam dokumen yang terlihat menjelaskan mengapa
Apa yang sebenarnya dilindungi batas Annex C?
Interoperabilitas dengan implementasi yang mendahului generator Anda. Annex C meneruskan batas implementasi PDF Reference ke setiap bagian PDF/A, dan angka itu tidak acak — mereka menggambarkan apa yang secara historis diharuskan ditangani oleh reader yang patuh. File yang melampaui batas itu mungkin terbuka dengan sempurna di viewer modern dan gagal di reader arsip yang menjadi standar sistem rekord lima belas tahun lalu, yang persis skenario yang PDF/A ada untuk cegah
Keempat batas itu inklusif. Token nama tepat 127 byte valid; 128 tidak. Array dengan tepat 8191 elemen valid; 8192 tidak. PDFium Component menyematkan kedua sisi setiap batas dalam test suite-nya karena alasan itu, karena off-by-one dalam pemeriksaan batas menghasilkan jenis validator terburuk: yang menolak file patuh dan tetap dipercaya
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;
Generator mana yang sebenarnya mengenai batas ini?
Yang membangun struktur secara programatik, yang merupakan sebagian besar output line-of-business. Formulir dengan beberapa ribu field menghasilkan array /Annots atau array /Fields AcroForm yang tumbuh melewati 8191. Halaman yang resources dictionary-nya mengakumulasi satu entri per gambar atau instance font yang dihasilkan melampaui 4095. Pohon struktur yang dihasilkan dalam-dalam — dokumen tagged yang dibangun dengan rekursi atas model data bersarang — berjalan melewati 28 level tanpa seorang pun menyadarinya, karena tidak ada yang melihat kedalaman bersarang
Nama panjang datang dari kebiasaan berbeda: mengkodekan data ke token nama. Nama colorant yang dibangun dari pengenal pelanggan, optional-content group yang dinamai setelah path file lengkap, field formulir yang nama terkalifikasinya penuh menggabungkan enam level hierarki. Nama murah untuk dihasilkan dan mudah dibuat panjang, dan 127 byte menghilang lebih cepat dari yang Anda kira begitu label terkodekan UTF-8 terlibat
Perbaikannya struktural dalam setiap kasus. Pisahkan array, pisahkan dictionary, ratakan bersarang, persingkat nama — rekomendasi preflight untuk setiap issue menamai batas konkret alih-alih memberitahu Anda file tidak valid. Injeksi marker tidak bisa membantu di sini: ini bukan klaim metadata, ini adalah bentuk object graph
Kenapa font TrueType simbolik tidak boleh membawa /Encoding
Karena ISO 19005-1 §6.3.7 hanya mengizinkan cmap bawaan font untuk font TrueType simbolik, dan entri /Encoding akan bertentangan dengannya. Font simbolik memetakan kode ke glyph dengan syaratnya sendiri — itulah artinya simbolik. Tambahkan tabel encoding dan sekarang ada dua jawaban untuk pertanyaan "glyph mana yang dipilih byte 0x41", tanpa aturan dalam file yang mengatakan mana yang menang. Reader berbeda menyelesaikannya secara berbeda, dan dokumen yang merender sebagai teks di satu viewer merender sebagai dingbat di yang lain
PDFium Component membaca flag simbolik dari /FontDescriptor, apakah descriptor ditulis inline di dictionary font atau direferensikan secara tidak langsung. Font TrueType non-simbolik mempertahankan /WinAnsiEncoding atau /MacRomanEncoding yang dipersyaratkan tanpa ditandai, karena untuk font non-simbolik encoding persis seperti yang diminta standar. Pemeriksaan muncul pada kontradiksi, bukan pada kehadiran encoding
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)');
Sumber praktis cacat ini adalah subsetting font yang dilakukan oleh producer yang memperlakukan setiap font TrueType dengan cara yang sama. Symbol, Wingdings, font barcode dan font ikon adalah pembawa biasanya — persis font yang dokumen bisnis gunakan untuk checkbox, logo, dan barcode, dan persis yang tidak ada yang memeriksa ulang ketika dokumen gagal validasi atas "font"
Bagaimana issue tiba dalam laporan preflight
Empat batas kontainer diklasifikasikan di bawah struktur; issue encoding TrueType simbolik diklasifikasikan di bawah konten. Pembagian itu penting ketika laporan pergi ke dua orang berbeda: temuan struktur biasanya milik siapa pun yang menulis generator, dan temuan konten biasanya milik siapa pun yang menyediakan aset
Setiap issue membawa rekomendasi yang menamai penanganan dalam istilah konkret — persingkatkan token nama menjadi 127 byte atau kurang, pisahkan array sehingga tidak ada yang membawa lebih dari 8191 elemen, hapus /Encoding dari font TrueType simbolik. Laporan yang mengatakan "tidak patuh PDF/A" memulai penyelidikan. Laporan yang mengatakan batas mana yang dilampaui dan oleh apa mengakhiri satu
Memvalidasi tanpa DLL, dan kenapa itu penting di sini
Semua pemeriksaan di atas berjalan terhadap byte file, jadi mereka bekerja dalam layanan yang tidak punya biner PDFium yang dideploy, dalam langkah build, atau pada mesin di mana memuat DLL native adalah masalah kebijakan. Itu adalah garis desain yang disengaja di PDFium Component: pemeriksaan yang dapat dijawab dari struktur dijawab dari struktur, dan DLL dicadangkan untuk yang benar-benar membutuhkan engine rendering
Untuk workflow di sekitarnya — menjalankan validasi atas folder, menghasilkan laporan, dan memutuskan apa yang harus dilakukan dengan temuan — lihat panduan validasi preflight PDF/A di Delphi dan CLI laporan preflight batch. Untuk pilihan profil arsip yang berada di atas semua pemeriksaan ini, catatan tentang kepatuhan arsip PDF/A membahas bagian dan level mana yang ditargetkan sebelum Anda mulai memperbaiki temuan
PDFium Component membungkus engine PDFium untuk Delphi, C++Builder dan Lazarus dengan API VCL tingkat tinggi dan serangkaian validator kepatuhan yang berjalan dengan atau tanpa DLL — lihat halaman produk PDFium Component untuk standar dan platform yang didukung