İşlemsel baskı yapan matbaa, 80.000 sayfalık ekstre işinizi tek satırlık bir reddedişle geri gönderiyor: "PDF/VT değil, RIP önbellekleyemiyor". Dosya masanızdaki her görüntüleyicide düzgün açılıyor, renkler doğru, veriler doğru birleşmiş. Fakat dijital baskı makinesinin istediği şey bunlar değildir. Yüksek hızlı değişken veri baskısı, baskı makinesinin 1. sayfadaki müşteri logosu bloğunun 40.000. sayfadakiyle bayt bayt aynı nesne olduğunu tanıyıp bunu bir kez işleyebilmesine ve yeniden kullanabilmesine bağlıdır. PDF/VT bu vaadi makine tarafından doğrulanabilir kılan standarttır ve "doğru görünüyor" ifadesi tam bir tuzaktır; çünkü RIP'in okuduğu yapı ekranda görünmez
PDFiumPas, bu yapıyı TPdf üzerinde küçük bir yüzeyle açar: SaveAsPdfVT bunu yazar, ValidatePdfVT bunu denetler. Bu makale, bu iki yöntemin diske gerçekte ne yazdığını ve neyi incelediğini, ISO 16612-2'nin ilk bakışta göründüğünden nerede daha katı olduğunu ve hangi parçaların, müşteriye fatura kesebileceğiniz tam bir preflight yerine, dürüst yapısal dayanaklar olduğunu anlatır
PDF/VT neyi standartlaştırır ve PDF/X neden önce gelir
PDF/VT (ISO 16612-2:2010) yeni bir dosya biçimi değildir. PDF/X dosyasının üzerine eklenmiş bir optimizasyon metadata katmanıdır ve bu sıralama taşıyıcı unsurdur. Standart üç uyumluluk seviyesi tanımlar, ancak bunlardan yalnızca ikisi bir PDF dosyasını adlandırır: PDF/VT-1, tek ve kendi kendine yeten belge; ve PDF/VT-2, sayfaların paylaşılan dış kaynaklara başvurduğu dosya kümesi modeli. Görebileceğiniz üçüncü simge olan PDF/VT-2s ise dosya düzeyi bir değer değildir; Annex A'da tanımlanan MIME stream header içinde yaşar. Bir belgenin XMP'sine GTS_PDFVTVersion = "PDF/VT-2s" damgalayan kod görürseniz, o kod yanlıştır
Tek dosya için pazarlık kabul etmeyen kural, PDF/X tabanıdır. ISO 16612-2 §6.2.1, her PDF/VT-1 dosyasının aynı zamanda geçerli bir PDF/X-4 dosyası olmasını ister. PDF/VT-2 dosya kümesi ise §6.2.2 gereği PDF/X-4p, PDF/X-5g veya PDF/X-5pg üzerine oturmalıdır. Bu yüzden PDF/VT yazıcısı sadece birkaç kimlik anahtarı ekleyemez: bütün PDF/X-4 işaret kümesini de taşımak zorundadır; yani bir OutputIntent, gömülü ICC hedef profili, buna uyan XMP ve document Info girdileri, trailer içinde bir /ID ve şifreleme olmaması gerekir. Bunlardan herhangi birini atlarsanız, PDF/VT dediğini iddia eden ama uyumlu bir tüketici tabanı denetlediği anda çöken bir dosya elde edersiniz. PDFiumPas, PDF/X-4 katmanını PDF/VT kaydının parçası sayar; bu yüzden ayrıca SaveAsPdfX çağırmanız gerekmez, enjektör iki katmanı da tek geçişte yazar
SaveAsPdfVT ile dosya yazma
En küçük çağrı, etkin bir belgeden başka bir şey istemez; çünkü TPdfVTSaveOptions.Default yerleşik sRGB ICC profili ile pvc1 uyumluluğunu sağlar. Kaydetme dahili olarak üç adım yürütür: güvenliği kaldırır (şifreli object stream içine düz metin işaretleri enjekte etmek akışı bozar), belgenin mevcut Info dictionary'si ile trailer /ID değerini marker set içine köprüler; böylece XMP ve Info değerleri uyumlu kalır; ardından PDF/X-4 ve PDF/VT nesnelerini incremental update ile ekler
var
Pdf: TPdf;
begin
Pdf := TPdf.Create(nil);
try
if Pdf.LoadFromFile('statements-merged.pdf') then
begin
// Default options: built-in sRGB OutputIntent, PDF/VT-1, synthesised DPart
if Pdf.SaveAsPdfVT('statements-pdfvt.pdf') then
Writeln('PDF/VT-1 written')
else
Writeln('Save failed (document not active?)');
end;
finally
Pdf.Free;
end;
end;
Gerçek üretim çıktısında neredeyse her zaman OutputIntent'i genel sRGB geri dönüşü yerine baskı makinenizin karakterizasyonuyla geçersiz kılmak istersiniz. ICC baytlarını ve koşul tanımlayıcılarını TPdfVTSaveOptions üzerinden sağlayın:
var
Pdf: TPdf;
Opt: TPdfVTSaveOptions;
Icc: TBytes;
begin
Pdf := TPdf.Create(nil);
try
Pdf.LoadFromFile('directmail-merged.pdf');
Icc := LoadIccProfile('GRACoL2013_CRPC6.icc'); // your own loader
Opt := TPdfVTSaveOptions.Default;
Opt.Conformance := pvc1; // pvc2 is normalised to pvc1 on write
Opt.IccProfileData := Icc;
Opt.OutputConditionIdentifier := 'CGATS21_CRPC6';
Opt.OutputCondition := 'Commercial print, coated, CRPC6';
Opt.RegistryName := 'http://www.color.org';
Opt.Title := 'Spring 2026 Direct Mail Run';
Opt.Trapped := ptvFalse; // PDF/X Info /Trapped state
Pdf.SaveAsPdfVT('directmail-pdfvt.pdf', Opt);
finally
Pdf.Free;
end;
end;
Bu parçacıktaki bir ayrıntı, tartışılabilir bir kısıt değil bilinçli bir korkuluktur. Opt.Conformance := pvc2 ayarlamak PDF/VT-2 dosyası üretmez. Yazıcı, pvc1 dışındaki her isteği yeniden pvc1 değerine normalleştirir; çünkü PDF/VT-2 dosya kümesi biçimidir ve tek bir çıktı belgesi ekleyen tek dosyalı yazıcı, §6.2.2'nin istediği dış kaynak kümesini fiziksel olarak oluşturamaz. pvc2 değeri okuma yolu içindir; böylece ValidatePdfVT mevcut bir dosya kümesi belgesini tanıyıp raporlayabilir; yazma hedefi değildir
DPart ağacı: RIP'in gerçekte okuduğu yapı
PDF/VT'nin kalbi Document Part (DPart) hiyerarşisidir. Bu yapı, baskı makinesinin uzun bir çalışmayı kayıtlara bölmesine, kayıtları alıcılar ya da posta paketleri halinde gruplamasına ve aşağı akış ekipmanının her parçayı yönlendirip faturalandırabilmesi için Document Part Metadata eklemesine izin verir. ISO 16612-2 §6.5 bunun kablolamasını tanımlar: catalog bir /DPartRoot taşır, kök DPart düğümü /DPartRootNode ve her hiyerarşi seviyesini adlandıran bir /NodeNameList içerir, yaprak DPart'lar sayfa ağacının aralıklarını kapsar ve bir parçaya ait her sayfa, sayfa düzeyindeki /DPart girdisiyle kendi yaprağına geri işaret eder
Kaynak belgenizde kullanılabilir bir hiyerarşi zaten varsa, SaveAsPdfVT bunu korur. Yoksa yazıcı en küçük işleyen yapıyı sentezler: mevcut sayfa ağacını sırayla kapsayan tek belge düzeyi DPart, her canlı sayfa nesnesine eklenen bir /DPart geri bağlantısı ve tek seviyeli bir /NodeNameList [/Document]. Bu asgari ağacın ne olduğu konusunda kendinize dürüst olun. Bu, §6.5'in şekil gereksinimlerini sağlayan yapısal bir ankordur; iş verisi değildir. Alıcıları, posta parçası sınırlarını veya ürün partilerini icat edemez; çünkü bu bilgi kaynakta hiç yoktur. Alıcı başına veriniz varsa, daha derin DPart ağacını kendiniz kurmanız ve oluşturduğunuz seviyelere uyacak şekilde /NodeNameList yapısını genişletmeniz beklenir
Anahtar varlığı denetiminin ötesine geçen doğrulama
ValidatePdfVT, üç şey taşıyan bir TPdfVTValidationResult kaydı döndürür: algılanan Conformance, bir Issues issue kümesi ve yalnızca uyumluluk gerçek seviye olduğunda ve issue kümesi boş olduğunda true olan IsCompliant yardımcısı. Issue enum'u özellikle ayrıntılı tutulmuştur; böylece başarısız sonuç size sadece "geçersiz" demek yerine hangi maddeyi kaçırdığınızı söyler:
var
Pdf: TPdf;
Res: TPdfVTValidationResult;
begin
Pdf := TPdf.Create(nil);
try
Pdf.LoadFromFile('statements-pdfvt.pdf');
Res := Pdf.ValidatePdfVT;
if Res.IsCompliant then
Writeln('PDF/VT compliant: ', VTLevelName(Res.Conformance))
else
begin
if pvviMissingDPartRoot in Res.Issues then
Writeln('DPart hierarchy missing or unusable');
if pvviMissingPdfXIdentifier in Res.Issues then
Writeln('PDF/X-4 base identifier absent');
if pvviMissingOutputIntent in Res.Issues then
Writeln('OutputIntent / ICC profile missing');
if pvviEncryptionPresent in Res.Issues then
Writeln('Encrypted - PDF/X forbids this');
end;
finally
Pdf.Free;
end;
end;
Derinlemesine anlaşılması gereken iki denetim, uyumluluk eşleştirmesi ile DPart yürüyüşüdür; çünkü ikisi de eskiden fazla gevşekti ve standarda uyacak şekilde sıkılaştırıldı. Eşleştirme tarafında doğrulayıcı yaklaşık eşleşme değil, tam eşleşme yapar: PDF/VT-1 dosyası yalnızca PDF/X-4 tabanı üzerinde kabul edilir, PDF/VT-2 dosyası ise yalnızca PDF/X-4p, PDF/X-5g veya PDF/X-5pg üzerinde kabul edilir. PDF/X-1a tabanı üzerine konmuş PDF/VT-1 işareti sessizce geçirilmez, raporlanır
Asıl titizlik DPart yürüyüşünde yaşar. Catalog içinde /DPartRoot anahtarının bulunması yeterli değildir; çünkü sahte boş nesne ya da sayfa bağlantısı olmayan nesne yine de tüketilemez. HasValidDPartHierarchy ile özyineli ValidateDPartNode, yapının tamamını izler: üst bağlantıları takip eder, yinelemeli çocukları ve döngüleri reddeder, /Start ile /DParts öğelerinin birbirini dışladığını zorlar ve yaprak sayfa aralıklarının, her sayfanın /DPart girdisi kendisini içeren yaprağa işaret edecek şekilde, sayfa ağacını derinlik öncelikli sırada kapsamasını ister. Bütün bu dahili kusurlar, herkese açık enum'u büyütmek yerine tek bir pvviMissingDPartRoot issue biti altında toplanır; dolayısıyla bu bayrağı kelimenin tam anlamıyla "kök anahtar yok" değil, "DPart hiyerarşisi kullanılamaz" diye okuyun
Doğrulayıcının artık zorladığı üç sözdizimsel tuzak
§6.5 Table 4'e karşı yapılan art arda geçişler, önceki sürümlerin kabul ettiği ama standardın kabul etmediği şekilleri ortaya çıkardı. Bunlar özellikle elle kurulmuş DPart ağaçlarında sık görülen hatalardır, bu yüzden açıkça anılmaya değerler:
/DPartsdış dizi içinde dizilerden oluşur, düz dizi değildir Dış dizinin her öğesi, kendi başına dolaylı başvuru dizisi olmalıdır. Düz bir/DParts [9 0 R]reddedilir; uyumlu şekil/DParts [[9 0 R] [10 0 R]]biçimidir. Bu, hiyerarşik olmayan yapının geçerli seviye gibi davranmasını engeller/Endyalnızca gerçekten çok sayfalı aralığı işaretler Yaprak DPart,/Endöğesini yalnızca/Startvarsa taşıyabilir ve/End, sayfa ağacı sıralamasında/Startsonrasına düşmelidir. Artık bozuk bir/Start 3 0 R /End 3 0 R, tek sayfalık parça gibi okunmak yerine hiyerarşiyi kullanılamaz hale getirir/NodeNameListadları, PDF name unescape işleminden sonra XML NMTOKEN olarak hayatta kalmalıdır/Bad#20Namegibi bir ad, açıldığında boşluk içeren bir ada dönüşür ve bu geçerli token değildir. Uygulama hafif bir ASCII denetimi yapar (harfler, rakamlar,.,-,_,:ve ASCII dışı baytlar); bu sayede meşru yerelleştirilmiş ya da üreticiye özgü adları reddetmeden boşluk ve ayraç hataları yakalanır
XMP işaretleri: aynı özelliği yazmanın iki yolu
PDF/VT tanımlaması, pdfvtid ad alanı altındaki XMP içinde yaşar; özellikle GTS_PDFVTVersion ve GTS_PDFVTModDate, ayrıca standart xmp:CreateDate ile xmp:ModifyDate yanında bulunur. Saf okuyucularda sahte "eksik" raporlarına yol açan bir incelik şudur: bunların herhangi biri iki biçimde serileştirilebilir: öğe metni olarak (<pdfvtid:GTS_PDFVTVersion>PDF/VT-1</pdfvtid:GTS_PDFVTVersion>) ya da description öğesi üzerinde RDF özniteliği olarak. PDFiumPas iki biçimi de okur; bu yüzden başka aracın öznitelik tarzında yazdığı dosya cezalandırılmaz. Ayrıca §6.3 tutarlılık kuralını da zorlar: GTS_PDFVTModDate değeri xmp:ModifyDate ile aynı olmalıdır; uyuşmazlık pvviModDateMismatch yükseltir
Aynı maddeden bir başka kural daha: bilinmeyen GTS_PDFVTVersion değeri, yeniden pvcUnknown olarak korunur; pvcNone değerine geri katlanmaz. Bu ayrım işletimsel açıdan önemlidir. pvcNone, "hiç PDF/VT işareti yok, sıradan PDF" anlamına gelir; pvcUnknown ise "bir şeyin damgaladığı ama bu doğrulayıcının tanımadığı bir sürüm var" demektir (bunların arasında PDF/VT-2s durumu da vardır). İkisini aynı kovada toplamak, bozuk dosyayı sıradan belgeyle aynı sepete saklar
Garantinin bittiği yer
Bu yöntemlerin ne vaat ettiğinin sınırını net konuşmaya değer; çünkü değişken veri baskı uyumluluğunun arkasında gerçek para vardır. DPart ve eşleştirme denetimleri bayt düzeyinde yapısal doğrulamadır. Optimizasyon iskeletinin, PDF/X-4 taban işaretlerinin, OutputIntent'in ve XMP'nin mevcut ve iç tutarlı olduğunu doğrular. Bunlar içerik düzeyinde PDF/X-4 preflight değildir: her rengin ilan edilen çıktı koşulu içinde olduğunu, tüm fontların gömülü olduğunu ya da yasaklı saydamlık-karıştırma köşe durumlarından hiçbirinin sızmadığını doğrulamaz. Sözleşmeli baskı makinesine göndereceğiniz iş için PDFiumPas'ın yapısal doğrulamasını özel bir PDF/X preflight motoru ve deneme baskısıyla eşleyin; diğer her uyumluluk iddiasında yapacağınız gibi. Yapısal katman, RIP önbelleğini sessizce bozan arızaları yakalar; tam denetimin bir yarısıdır, bütünü değildir
Bu denetimleri daha geniş bir yayın kapısına yerleştiriyorsanız, aynı bayt düzeyindeki tarama yaklaşımı kütüphanenin diğer standart çalışmalarını da destekler; buna dosya preflight'a gelmeden önce nesne ve cross-reference stream doğrulaması ve belgenin baştan RIP dostu olmasını sağlayan Form XObject ile yeniden kullanılabilir sayfa damgaları arkasındaki paylaşılan nesne disiplini de dahildir. Burada açıklanan PDF/VT ve PDF/X kaydetme ile doğrulama API'leri, PDFium VCL component kapsamında Delphi ve C++Builder için sunulur; ürün sayfası eksiksiz uyumluluk başvurusunu taşır