PDFlibPas, Delphi tarafından tek bir çağrıyla, TPDFlib.SetPDFXMode üzerinden PDF/X baskı dosyaları üretir; bu çağrı PDF/X-1a:2003, PDF/X-3:2003 ya da PDF/X-4 seçer. Çağrı, XMP pdfxid kimliklendirmesini yazar, bir GTS_PDFX output intent ekler, /Trapped /False bildirir, PDF sürümünü sabitler ve o andan itibaren seçilen parçanın yasakladığı çizim çağrılarını reddeder. Test 3 ile CheckFileCompliance, kaydedilen dosyayı denetler
Kısa cevap bu. Uzunu ise şundan önemlidir: baskı atölyeleri dosyaları çirkin olduğu için reddetmez, preflight'ta reddederler; genellikle bir Cuma günü ve genellikle üreten kodun yakalayabileceği bir şey için: bir X-1a işinde RGB logo, gömülmesi yerine referans verilen bir font, kırpma boyutu olmayan bir sayfa. PDF/X, bu tür başarısızlıkları görsel değil yapısal hâle getirmek için vardır ve işin kütüphane tarafı, onları en baştan üretmenizi engellemektir
Bir Delphi uygulaması hangi PDF/X parçasını hedeflemeli?
Alıcı iş akışı başka bir şey söylemiyorsa PDF/X-4'ü seçin; söylüyorsa PDF/X-1a'yı seçin. Üç parça tam olarak üç eksen boyunca ayrışır: renk, saydamlık ve temel PDF sürümü; ve her eksen PDFlibPas içindeki bir kapıya karşılık gelir:
- PDF/X-1a:2003 (ISO 15930-4): PDF 1.4 sözdizimi, yalnızca CMYK, gri ve spot renkler; ICC tabanlı renk yok, saydamlık yok. Dosya baskı renklerine çoktan ayrıştırılmıştır; bu yüzden yazıcı hiç renk dönüşümü yapmaz
- PDF/X-3:2003 (ISO 15930-6): yine PDF 1.4 ve yine saydamlık yok, ama renk yönetimli renk uzaylarına izin verilir ve output intent'in kendisi bir RGB koşulunu betimliyorsa cihaz RGB'si kabul edilir
- PDF/X-4 (ISO 15930-7): PDF 1.6 sözdizimi, canlı saydamlık ve optional content (katmanlar) ile. Modern RIP'ler bu parça için inşa edilir; çünkü eski X-1a acısının büyük kısmı, çıkış yolunda saydamlığı düzleştirmekten gelir
X-1a, reklam teslimatında ve dosyayı düşünmeden görüntüleyebilecekleri bir şey isteyen eski baskı iş akışlarında hâlâ her yerde. Atölye kabul ettiği sürece X-4 daha iyi mühendislik tercihidir: saydamlık bozulmadan hayatta kalır ve renk kararları sizin kodunuzda değil, gerçek baskı profiliyle RIP'te verilir. Mod numaraları sırasıyla 1, 2 ve 3'tür ve GetInformation(203) etkin modu geri bildirir. PDFlibPas ayrıca PDF 2.0 üzerindeki PDF/X-6 ailesi için daha yüksek mod numaraları tanımlar; bunlar farklı sürüm ve output intent kurallarına uyar ve bu yazının kapsamı dışındadır
SetPDFXMode dosyaya ne yazar?
TPDFlib.SetPDFXMode, bir PDF/X okuyucusunun önce denetlediği kimliklendirme ve kalıp metinleri halleder; böylece uygulama kodu yalnızca gerçek baskı profilini ve içeriği sağlamakla kalır. Somut olarak, başarılı bir çağrı dört şey yapar:
- XMP içine
pdfxid:GTS_PDFXVersionolarak sürüm metnini yazar (PDF/X-1a:2003,PDF/X-3:2003veyaPDF/X-4). 2003 sürümleri parçayı o metinle tam olarak tanımladığı için ayrı bir uyumluluk özelliği yazılmaz - Belgenin output intent'i yoksa bir tane ekler ve alt türünü, PDF/X okuyucularının aradığı alt tür olan
/S /GTS_PDFXyapar (output intent sözlüğünü ISO 32000-1 §14.11.5 tanımlar) - Belge bilgi sözlüğünde
/Trapped /Falseayarlar; çünkü yazan taraf asla trapping yapmaz ve PDF/X, trapping durumunun bilinmez bırakmak yerine bildirilmesini zorunlu kılar - Sürüm tabanını sabitler: X-1a ve X-3 için 1.4, X-4 için 1.6
Kaydetme anında iki onarım daha gerçekleşir. TrimBox olmayan her sayfa, MediaBox'ına eşit bir TrimBox alır; çünkü PDF/X her sayfada bildirilmiş bir bitmiş boyut ister (sayfa sınırlarını ISO 32000-1 §14.11.2 kapsar) ve ek açıklamalar standardın beklediği baskı bayrağını alır. TrimBox geri dönüşü bir güvenlik ağıdır, yerleşim kararı değil. Tam bleed'li bir iş, daha büyük bir media box içinde gerçek bir trim box ister ve PDFlibPas'ta TrimBox, BleedBox ve CropBox varsayılanları rehberi bu kutuların nasıl ayarlanacağını ve kalıtımın sizi nasıl şaşırtabileceğini anlatır
uses
PDFlibrary;
procedure BuildX1aAd(const OutFile, PressProfile: string);
var
Pdf: TPDFlib;
begin
Pdf := TPDFlib.Create;
try
if Pdf.SetPDFXMode(1) <> 1 then // 1 = PDF/X-1a:2003
raise Exception.CreateFmt('PDF/X mode refused (error %d)',
[Pdf.LastErrorCode]);
// Varsayılan profili gerçek baskı koşuluyla değiştirin
if Pdf.LoadOutputIntentProfile(PressProfile, 'DeviceCMYK') <> 1 then
raise Exception.Create('Could not load the CMYK output profile');
// Embed = 1 tam font programını gömer; PDF/X 0 kabul etmez
if Pdf.AddTrueTypeFont('Arial {1252}', 1) = 0 then
raise Exception.Create('Font could not be loaded for embedding');
Pdf.SetTextSize(24);
Pdf.SetFillColorCMYK(0, 1, 1, 0); // proses kırmızısı, RGB yok
Pdf.DrawText(72, 720, 'Spring catalog, page 1');
Pdf.SaveToFile(OutFile);
finally
Pdf.Free;
end;
end;
O taslaktaki sıra bilinçli. LoadOutputIntentProfile, hâlihazırda var olan bir output intent'in profilini değiştirir; bu yüzden SetPDFXMode bir tane oluşturduktan sonra çalışmak zorundadır. Çağrı ayrıca yoktan bir intent var edemez: output intent'i olmayan bir belgede düpedüz 0 döndürür
Varsayılan output intent neden değiştirilmeli?
SetPDFXModeun 1-3 arası modlar için eklediği output intent DeviceCMYK bildirir; ama arkasındaki ICC baytları, bileşen sayısı 4'e yeniden yazılmış kütüphanenin paketli sRGB profilidir. O varsayılan geriye dönük uyumluluk için vardır ve dosyayı yapısal olarak PDF/X yapmak için yeterlidir; yine de gömülü profil hiçbir baskı koşulunu betimlemez. Profil başlığını inceleyen bir preflight aracı, CMYK etiketi takmış bir RGB profili görür ve proofing için intent'e güvenen bir baskıcı anlamsızlıkla karşılaşır
Bu yüzden gerçek baskı işinde LoadOutputIntentProfile(FileName, 'DeviceCMYK') çağrısını zorunlu sayın ve baskı sağlayıcınızın kâğıt ile baskı için adlandırdığı ICC profilini geçirin. TPDFlib.LoadOutputIntentProfile, DestOutputProfile akışını değiştirir ve /N'yi günceller; intent sözlüğünün geri kalanını yazıldığı gibi bırakır. Özellikle varsayılan intent'in output condition identifier'ı ve betimleyici metinleri hâlâ sRGB tarzı değerler taşır; bu yüzden atölyeniz gömülü profile değil identifier'a eşleştirme yapıyorsa, göndermeden önce neyi denetlediklerini onlarla teyit edin. Bu, 2003 dönemi varsayılanlarındaki gerçek bir boşluktur; kodunuzun yanlış yaptığı bir şey değil
Tuzak bir: seçmediğiniz sürüm
Yeni bir PDFlibPas belgesi, PDF/X-1a ve PDF/X-3'ün gerektirdiği 1.4 tabanının üzerinde olan yazıcı varsayılanı PDF 1.5 ile başlar. TPDFlib.SetPDFXMode, yaygın durumda bunu sessizce çözer: kayıt sürümü kilitlenmemişse belge sürümünü parça tabanına düşürür ve devam eder. İlk uygulamada bunun yerine reddediyordu ve taze bir belgede her SetPDFXMode(1) 0 döndürüyordu; kâğıt üstünde doğru, pratikte işe yaramaz bir kuralın güzel bir örneği
Reddetme, doğru olduğu tek durum için hâlâ duruyor. Daha önce bir şey, tabanın üzerinde bir sürümle LockSaveVersion çağırdıysa SetPDFXMode, LastErrorCode 601 ile 0 döndürür; çünkü çağıran sürümü bilinçli olarak sabitlemiştir ve kütüphane bunu ezmez. Bir yardımcının ilgisiz nedenlerle sürümü kilitlediği paylaşılan belge-kurulum kodunda, bir X-1a işinin öldüğü yer tam olarak burasıdır:
Pdf := TPDFlib.Create;
try
Pdf.LockSaveVersion('1.7'); // genel bir "kurum varsayılanları" yardımcısı ayarladı
if Pdf.SetPDFXMode(1) = 0 then
// LastErrorCode = 601: 1.7 kilitli, PDF/X-1a 1.4 istiyor.
// Baskı işlerinde kilidi atlayın. PDF/X-4 burada bir çıkış değil:
// onun 1.6 tabanı da 1.7 kilidinin altında ve aynı şekilde başarısız olur.
LogError('PDF/X refused, error %d', [Pdf.LastErrorCode]);
finally
Pdf.Free;
end;
Aynı kapı, ilgili bir sınırı da açıklar. PDF/X modu bir belge oluşturma anahtarıdır: SetPDFXMode yeni bir belgede çalışır ve dosyadan yüklenmiş bir belgede 0 döndürür; çünkü kütüphane, yazmadığı içeriğin kefil olamaz. Mevcut bir PDF'yi PDF/X'e dönüştürmek, inceleme ve onarım isteyen başka bir iştir; bir bayrak değil
Tuzak iki: sessizce reddeden kapılar
Bir PDF/X modu etkinleştiğinde PDFlibPas, seçilen parçanın yasakladığı her içerik çağrısını, yaptığınız anda reddeder; dosyanın daha sonra preflight'ta başarısız olmasına izin vermek yerine. Reddetmeler şunları kapsar: cihaz RGB dolgu ve konturları (X-1a'nın tamamı; output intent RGB değilse X-3 ve X-4), X-1a'da ICC tabanlı renkler, X-1a ve X-3'te saydamlık ve blend modları, X-1a ve X-3'te optional content, JavaScript aksiyonları, gömülü dosya ekleri, LZW görüntü filtresi, gömülmeyeceği için sorun olan Standard 14 fontları ve public-key şifrelemesi. Encrypt ile parola şifrelemesi oluşturma zamanında kapıya takılmaz, ama doğrulayıcı şifreli her dosyayı işaretler; bu yüzden baskı işlerini şifresiz tutun
Reddetmelerin paylaşmadığı şey bir hata kodudur ve tuzak tam olarak budur. SetFillColor ve SetLineColor içindeki renk uzayı kapıları, ICC tabanlı renk çağrıları ve EncryptPublicKey, PDF/A kapılarının da kullandığı kütüphane uyumluluk kodu olan LastErrorCode değerini 601 yapar. Saydamlık, JavaScript, eklenti, LZW ve AddStandardFont kapıları ise yalnızca 0 döndürür ve LastErrorCode'a dokunmaz; bu da onun hâlâ önceki bir çağrıdan kalma bir değer tutabileceği anlamına gelir. Bir dizi çizim çağrısından sonra yalnızca LastErrorCode'u denetleyen kod, reddetmelerin yarısını kaçırır; bu yüzden her dönüş değerini denetleyin:
procedure Require(Ok: Integer; const What: string);
begin
if Ok = 0 then
raise EPrintConformance.CreateFmt('%s refused under PDF/X', [What]);
end;
Require(Pdf.SetFillColorCMYK(0, 0, 0, 1), 'CMYK fill');
Require(Pdf.SetTransparency(40), 'transparency'); // X-1a / X-3'te 0
Require(Pdf.AddLinkToJavaScript(72, 72, 120, 20,
'app.alert(1)', 0), 'JavaScript link'); // her parçada 0
Fontlar kendi uyarısını hak ediyor. AddStandardFont, PDF/X altında 0 döndürür; çünkü kütüphane Standard 14 outline'larını paketlemez ve bu yüzden onları gömemez. AddTrueTypeFont farklıdır: PDF/A modunda Embed = 0 değerini sizin adınıza tam gömmeye çevirir, ama PDF/X modunda çevirmez; bu yüzden referans verilmiş bir sistem fontu dosyaya girer ve onu yalnızca doğrulayıcı yakalar. 1 (tam) ya da 2 (alt küme) değerini kendiniz geçirin ya da kurulum sırasında bir kez SetEmbedAllFonts(1) çağırın; böylece başıboş bir 0 sızamaz
Bir PDF/X dosyası yazıcıya gitmeden önce nasıl doğrulanır?
Kaydedilen dosyada ComplianceTest = 3 ile CheckFileCompliance çalıştırın. TPDFlib.CheckFileCompliance, bulgu kaydetmediğinde 0 döndürür; aksi hâlde öğeleri PDFX- önekli satırlar olan bir string list handle döndürür. PDF/X denetimi, dosyayı PDFlibPas'ta PDF/A ve PDF/UA preflight ile aynı akış okuyucusu üzerinden okur ve bir baskı preflight'ının önce denetlediği kuralları denetler:
- Dosya şifreli değildir, XMP bilinen bir
GTS_PDFXVersiontaşır ve PDF sürümü parça tabanını aşmaz - Tam olarak bir output intent vardır, alt türü
GTS_PDFX'tir ve bir hedef profil ile bir output condition identifier taşır - Bilgi sözlüğü
/Trappedbildirir - Her sayfada MediaBox içinde duran bir TrimBox vardır ve var olduğunda BleedBox, TrimBox'ı sarar
- Bir sayfada kullanılan her fontun gömülü bir programı vardır; Type0 fontlar, onların soyundan gelen font üzerinden denetlenir
- Yasaklı ek açıklama türü yok (RichMedia, Screen, 3D, Movie, Sound, FileAttachment), JavaScript açılış aksiyonu ya da belge seviyesi JavaScript yok, gömülü dosya yok ve nesne grafiğinin hiçbir yerinde LZWDecode filtresi yok
function PreflightPDFX(Pdf: TPDFlib; const FileName: string;
Report: TStrings): Boolean;
var
ListId, I: Integer;
begin
ListId := Pdf.CheckFileCompliance(FileName, '', 3, 0); // 3 = PDF/X
Result := ListId = 0;
if Result then
Exit;
try
for I := 1 to Pdf.GetStringListCount(ListId) do // öğeler 1 tabanlıdır
Report.Add(Pdf.GetStringListItem(ListId, I));
finally
Pdf.ReleaseStringList(ListId);
end;
end;
O geçişin ne anlama geldiğini net kurun. PDFlibPas doğrulayıcısı, yukarıda listelenen yapısal kuralları denetler ve üretici hatalarını yakalayanlar da bunlardır. Renk açısından hassas bir preflight değildir: toplam mürekkep kapsamını, görüntü çözünürlüğünü ya da gömülü profilin baskıcınızın çalıştırdığı koşulla eşleşip eşleşmediğini denetlemez. Onu derleme ya da dışa aktarma hattınızdaki kapı olarak kullanın ve baskıya özgü denetimleri atölyenin preflight profiline bırakın; onlar zaten ne olursa olsun onu çalıştıracaktır
FAQ
PDFlibPas PDF/X-4 saydamlığını destekliyor mu?
Evet. SetPDFXMode(3) içinde PDFlibPas, saydamlığa, blend modlarına ve optional content gruplarına izin verir ve bir PDF 1.6 dosyası yazar. Aynı çağrılar PDF/X-1a ve PDF/X-3 altında 0 döndürür
PDFlibPas mevcut bir PDF'yi PDF/X'e dönüştürebilir mi?
Hayır. SetPDFXMode yalnızca geçerli TPDFlib oturumunda oluşturulan belgelere uygulanır ve yüklenmiş bir dosya için 0 döndürür. Yine de mevcut herhangi bir PDF'yi CheckFileCompliance ve test 3 ile denetleyebilirsiniz
Reddedilen bir PDF/X çağrısı hangi hata kodunu döndürür?
Renk uzayı ve public-key şifrelemesi reddetmeleri LastErrorCode değerini 601 yapar. Saydamlık, JavaScript ve Standard 14 fontları gibi diğer kapılar yalnızca 0 döndürür; bu yüzden her zaman fonksiyon sonucunu test edin
PDF/X çıktısı, PDF/X doğrulayıcısı ve baskı ile arşivleme araç setinin geri kalanı, Delphi için losLab'ın yerel Object Pascal PDF kütüphanesi olan PDFlibPas'ın parçasıdır. Sürümler, platformlar ve eksiksiz API referansı için PDFlibPas Delphi PDF Library ürün sayfasına bakın