Artikel Teknis

Dokumen Rekayasa PDF/E-1 di Delphi dengan PDFlibPas

PDF/E-1 adalah profil arsip untuk dokumen rekayasa, dan PDFlibPas mengimplementasikannya sebagai author mode yang Anda nyalakan dengan SetPDFEMode plus preflight terbatas yang membaca content stream operator demi operator. Profil ini bukan PDF/A dengan label berbeda: ia punya namespace identifikasi sendiri, tuntutan metadata lifecycle sendiri, dan satu aturan yang membuat validasi kontennya lebih ketat daripada profil arsip apa pun yang pernah Anda temui

Deliverable rekayasa adalah alasan profil ini ada. Set gambar yang harus tetap terbaca dan terbukti tak berubah dua puluh tahun ke depan, dengan riwayat revisi yang ikut bertahan, dan dengan warna yang bermakna sama di plotter di gedung sebelah. Tuntutan-tuntutan itu menghasilkan spesifikasi yang tuntutannya sebagian besar berada di luar konten halaman — di metadata dan color management, tepat di tempat PDF writer generik salah menanganinya

Identifikasi sendiri, bukan variasi PDF/A

Hal pertama yang harus benar: identifikasi PDF/E-1 tidak bisa dihasilkan dengan mengadaptasi pola PDF/A atau PDF/X. Ia memakai namespace XMP yang berbeda, http://www.aim.org/pdfe/ns/id/, dan nilai version harus muncul di dua tempat: sebagai entry document information dan sebagai property XMP yang berkualifikasi namespace. Memancarkan hanya property XMP-nya, atau hanya entry information-nya, menghasilkan file yang membawa niat tapi gagal validasi

Output intent-nya punya bentuk yang sama spesifiknya. PDF/E-1 menuntut profile ICC tersemat dengan identifier subtype ISO_PDFE1, dan profile tersebut harus punya jumlah komponen yang cocok dengan keluarga warna device yang benar-benar dipakai dokumen. Klausul terakhir itulah tempat implementasi diam-diam keliru, karena artinya intent tidak bisa dipilih di awal lalu dilupakan

Mengapa warna device butuh sweep satu dokumen penuh?

Karena color space bersembunyi di resource dictionary yang tak pernah terjangkau scan level halaman. PDF/E-1 memperlakukan DeviceRGB dan DeviceCMYK sebagai keluarga yang saling eksklusif dalam satu dokumen, jadi memvalidasi profile berarti mengetahui setiap color space device yang dipakai apa pun di dalam file. Form XObject punya resources sendiri. Pattern juga, image juga. Tiling pattern di dalam form XObject di dalam halaman itu tiga level kedalamannya, dan validator yang hanya memeriksa resources halaman tingkat atas akan meloloskan dokumen yang memakai kedua keluarga

Karena itu sweep mendaftarkan color space sambil menelusuri halaman, form, image dan pattern sebagai satu traversal, dan barulah kemudian memutuskan apakah dokumennya koheren dan apakah output intent-nya cocok. Nalar yang sama mendorong arsitektur preflight secara umum: traversal parsial menghasilkan lolos palsu, dan lolos palsu pada pemeriksaan conformance lebih buruk daripada tidak ada pemeriksaan, karena hasilnya tercatat sebagai bukti

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 menjaga metadata lifecycle tetap sinkron di tiap save.
    // Tanya dulu sebelum save apakah dokumen akan lolos gerbangnya sendiri
    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;

Metadata lifecycle adalah kewajiban tiap save

PDF/E-1 meminta lebih dari sekadar identifier dokumen. Set minimumnya mencakup media management document identifier, version identifier, rendition class, creation time, modification time, metadata time dan sebuah title. Itu kosakata pelacak revisi, dan ada karena deliverable rekayasa diharapkan diterbitkan ulang, bukan ditulis sekali jadi

Konsekuensinya bagi implementasi: field-field ini tidak bisa diatur saat dokumen dibuat. Kalau modification time ditulis ketika Anda menyalakan mode lalu dokumen disunting setelahnya, snapshot XMP dan keadaan dokumen yang sebenarnya sudah menyimpang, dan validator yang membandingkan keduanya melaporkan inkonsistensi yang tidak disengada siapa pun. Karena itu author mode menyinkronkan field-field tepat sebelum setiap save, sehingga metadata mendeskripsikan byte yang akan ditulis, bukan byte yang ada saat mode dinyalakan

Ini prinsip umum untuk metadata conformance dan layak dinyatakan terpisah dari PDF/E: metadata hasil turunan diletakkan di jalur save, bukan jalur sunting. Field apa pun yang dihitung dari keadaan dokumen harus dihitung ulang pada saat keadaan itu dibekukan, kalau tidak ia adalah cache tanpa invalidation

Diagram PDF/E-1 PDFlibPas tentang sweep warna device satu dokumen penuh yang menelusuri dictionary resources halaman, form XObject, tiling pattern dan image sambil mengumpulkan keluarga DeviceRGB dan DeviceCMYK sebelum menilai koherensi, berdampingan dengan field metadata lifecycle yang disinkronkan ulang author mode tepat sebelum tiap save agar snapshot XMP cocok dengan byte yang akan ditulis
Koherensi warna hanya bisa dinilai setelah satu traversal menjangkau setiap resource dictionary, dan metadata lifecycle hasil turunan dihitung ulang pada saat keadaan dokumen dibekukan, bukan saat mode dinyalakan

Aturan yang membuat validasi konten jadi ketat

PDF/E-1 tidak mengizinkan operator compatibility section menyerap konten yang tak dikenal. Di PDF biasa, BX dan EX mengapit wilayah tempat consumer harus mengabaikan operator yang tidak dikenalinya — pintu darurat yang memungkinkan produsen memancarkan konstruk lebih baru tanpa merusak pembaca lama. Di bawah PDF/E-1 pintu itu ditutup, jadi operator mana pun yang tidak dikenali preflight dilaporkan tanpa syarat, entah ia berada di dalam compatibility section atau tidak

Efeknya pada validator signifikan. Ia tidak bisa melewati wilayah yang tidak dipahaminya, artinya parser operand benar-benar harus mem-parsing setiap operator di setiap content stream. Di situlah batas-batas itu berperan. Traversalnya di-cap pada 128 level nesting, satu juta objek dan 64 MiB konten, dan batasan-batasan itu bukan tuning performa. File yang hosil atau sekadar rusak bisa menyajikan object graph berisi siklus atau kedalaman nesting yang mengubah validator rekursif menjadi stack overflow, dan batasan itulah yang menjaga pass validasi dari menjadi vektor denial-of-service. Sikap defensif yang sama dibahas di mem-parsing PDF tak terpercaya dengan aman

// Validasi standalone atas file yang bukan produksi Anda, tanpa memuatnya
// ke dalam instance dokumen
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;

Apa yang diperbaiki save gate dan apa yang ditolaknya

Gerbang itu membagi kerjanya menjadi dua tahap, dan pembagiannya sendiri adalah ide desain yang layak dipinjam. Pertama ia menormalkan hal-hal yang aman diperbaiki: print flag anotasi, flag no-zoom dan no-rotate pada text annotation, dan flag appearance-generation pada dictionary form. Ini setting yang punya satu nilai benar di bawah profil dan tidak membawa informasi apa pun, jadi memperbaikinya diam-diam itu tepat dan menolak karena hal semacam itu hanya pedantisme

Kemudian ia memeriksa constraint yang tidak bisa diperbaiki tanpa mengubah makna dokumen: version, identification, encryption, output intent, koherensi warna device, dan keberadaan konten form dinamis. Dokumen yang gagal di salah satu saja ditolak, karena mengarang output intent atau memilih keluarga warna atas nama penulisnya akan menghasilkan file yang lolos validasi sambil salah menggambarkan kontennya

Diagram save gate PDF/E-1 PDFlibPas untuk Delphi yang menampilkan preflight terbatas yang memindai setiap operator content stream di bawah cap nesting 128 level, satu juta objek dan 64 MiB, memperbaiki diam-diam print flag anotasi serta flag zoom dan rotate, menolak version, identification, encryption, output intent, warna device atau konten form dinamis yang salah, dan melaporkan blocker lewat GetPDFEDiagnostics
Gerbang itu hanya memperbaiki diam-diam yang tidak membawa informasi, menolak setiap constraint yang akan terdistorsi oleh perbaikan, dan mengubah penolakan menjadi daftar blocker lewat GetPDFEDiagnostics sebelum satu byte pun sampai ke disk

Membaca diagnostik kembali lewat GetPDFEDiagnostics sebelum menyimpan mengubah penolakan itu menjadi daftar yang bisa ditindaklanjuti, bukan operasi yang gagal. Di pipeline batch, panggil ia di setiap dokumen, catat blocker per file, dan arahkan kegagalan ke antrean yang dilihat manusia. Jauh lebih berguna daripada save yang raise, karena blocker biasanya mengelompok: empat puluh dokumen yang gagal karena output intent yang hilang sama adalah satu perbaikan, bukan empat puluh

Memilih di antara profil arsip

PDF/E-1 adalah target yang tepat ketika deliverable-nya dokumentasi rekayasa dengan lifecycle revisi, khususnya ketika koherensi warna device penting karena output menuju plotter dan printer large-format. PDF/A adalah target yang tepat ketika tujuannya keterbacaan jangka panjang dokumen pada umumnya, dan ia profil dengan dukungan validator terluas. Keduanya tidak saling menggantikan, dan sebuah dokumen bisa memenuhi salah satu sambil gagal di yang lain

Diagram keputusan PDFlibPas yang membandingkan profil arsip PDF/E-1 dan PDF/A untuk Delphi: PDF/E-1 untuk deliverable rekayasa dengan lifecycle revisi, warna plotter dan validasi kontraktual di bawah namespace XMP miliknya dengan output intent ISO_PDFE1, PDF/A untuk keterbacaan jangka panjang umum dengan dukungan validator terluas
Mulai dari siapa yang memvalidasi file di ujung sana: kedua profil menuntut jaminan identification, metadata dan warna yang berbeda, dan sebuah dokumen bisa memenuhi satu sambil gagal di yang lain

Kalau Anda sedang memilih, mulailah dari siapa yang memvalidasi file di ujung sana. Tooling validasi PDF/A ada di mana-mana, dan preflight yang bersesuaian di PDFlibPas dibahas di preflight PDF/A dan PDF/UA. Validasi PDF/E lebih terspesialisasi dan biasanya muncul sebagai tuntutan kontraktual, bukan bawaan. Ketika arsip yang sudah ada harus dinaikkan ke profil yang tak pernah dituju penulisnya, jalur perbaikan metadata di konversi ke PDF/A dengan perbaikan metadata adalah polanya, dan bentuk yang sama berlaku di sini: identifikasi, perbaiki yang aman, tolak sisanya lengkap dengan daftar

Author mode, preflight konten terbatas, dan compliance check standalone semuanya tersedia dalam pustaka PDF Delphi PDFlibPas, sehingga dokumen bisa diproduksi di bawah profil lalu diverifikasi secara independen setelahnya lewat jalur kode terpisah — satu-satunya susunan yang layak dipercaya untuk klaim conformance