PDFlibPas, Delphi ve C++Builder geliştiricilerine mevcut sayfayı geride bırakan gezinme için üç eylem türü verir: GoToR (Go To Remote), başka bir PDF dosyasında belirli bir sayfayı açar, GoToE (Go To Embedded), mevcut belgenin içine gömülü bir PDF dosyasını açar ve Launch, işletim sistemi kabuğu aracılığıyla harici bir programı çalıştırır veya bir dosyayı açar. Üçü de ISO 32000-1 §12.6.4'te yaşar, sıradan GoTo eylemini de tanımlayan Action Types bölümü ve her biri dikkatsiz olan için kendi tuzağını taşır: hangi çağrının onu kurduğuna bağlı olarak farklı bir anlama gelen bir sayfa numarası, bir dosya yolu yerine bir ad olan bir hedef ve aynı görünen ama iki farklı görüntüleyiciye hizmet eden bir çift dize parametresi
Bunların hiçbiri varsayımsal değildir. Bir teknik referans paketi -bir ana kılavuz, bir distribütörün kendi programına göre güncellediği bir spesifikasyonlar PDF'i, ikisinin yanında kurulu bir kalibrasyon aracı- tam olarak bu tür çapraz-belge bağlantısına dayanır: spesifikasyonlar dosyasının 5. sayfasına inmesi gereken bir çapraz referans, yanına değil kılavuzun içine gönderilmeye değer bir veri sayfası, doğrudan kalibrasyon aracına devreden bir bağlantı. Bu makale, mevcut bir PDF'ten bir yer imi ve açıklama eylemini geri okuma makalesinin ayna görüntüsüdür: o parça, başka bir üreticinin zaten bir dosyaya yazdığı bir GoToR, Launch veya GoToE eylemini tüketmeyi ele alır; bu ise aynı üç eylem türünü, PDFlibPas'ın tek bir bayt işlemeden önce uyguladığı alan düzeyinde kurallar dahil, sıfırdan kurmayı ele alır
Bir PDF eylemi mevcut sayfayı terk etmenin üç yolu
PDFlibPas, yerel gezinmeyi eylemin /S anahtarında her şeyden ayırır ve GoToR, GoToE ve Launch, hedefi mevcut sayfanın dışında oturan üç alt türdür: ISO 32000-1 §12.6.4.3 altında GoToR, §12.6.4.4 altında GoToE ve §12.6.4.5 altında Launch, hepsi sıradan GoTo eylemini de tanımlayan daha geniş §12.6.4 Action Types bölümünün içinde. Düz bir GoTo eyleminin hedefi, belge içinde zaten var olan bir sayfa nesnesini adlandırır; bu yüzden PDFlibPas onu hemen doğrulayabilir; GoToR ve GoToE aynı şekilde bunu yapamaz, çünkü dış dosya bu makinede hiç var olmayabilir ve gömülü bir dosyanın sayfa sayısı, ana bilgisayar belgesinin takip ettiği bir şey değildir; bu yüzden ikisi de sert bir bağlantı yerine çözülmemiş bir referans taşır -GoToR için bir dosya spesifikasyonu artı bir hedef, GoToE için gömülü-dosya adı artı bir hedef sayfa- Launch ise hedef kavramını tamamen bırakır ve yalnızca işletim sisteminin çalıştıracağı veya açacağı bir şeyi adlandırır. Bu ayrım, yazma tarafında iki çağrı ailesi olarak ortaya çıkar: AddLinkToFile, AddLinkToFileEx, AddLinkToEmbeddedPDF ve AddLinkToLocalFile gibi yüksek düzey, tek seferlik kurucular, bir sayfa-etkin bölgesi bağlantı açıklaması ve eylemini birlikte oluşturur; çoğu gerçek düzeni kapsar -bir okuyucunun tıkladığı bir metin satırı veya bir simge- SetActionRemoteDestinationEx, SetActionLaunchOptions gibi daha düşük düzey ayarlayıcılar ve bunların AddActionNext* karşılıkları ise, zaten bir tutamacınız olan bir şeye -mevcut bir yer imi, bir form-alanı tetikleyicisi veya bir belge- veya sayfa düzeyi yaşam döngüsü olayı- bir eylemi bağlar veya değiştirir. İki aile de aynı sözlük şekillerini yazmakla sonuçlanır; fark, onları çağırdığınızda nerede durduğunuz ve bir sonraki bölümün ele aldığı gibi, o an bir sayfa numarasının ne anlama geldiğidir
Başka bir PDF dosyasında bir sayfayı açan bir GoToR bağlantısını nasıl kurarsınız?
Bir GoToR eylemi iki şeye ihtiyaç duyar -bir dosya spesifikasyonu ve o dosya içinde bir hedef- ve PDFlibPas ikinci parçayı sağlamak için iki farklı çağrı sunar, her birinin kendi sayfa-numaralandırma kuralı vardır. AddLinkToFile ve AddLinkToFileEx, yüksek düzey sayfa-etkin bölgesi kurucuları, Page veya DestPage argümanlarının sıfırdan büyük olduğunu doğrular, SelectPage dahil PDFlibPas'ın başka her yerde kullandığı aynı 1-tabanlı numaralandırma. Zaten bir tutamacınız olan bir şeye bir GoToR eylemini bağlamak veya değiştirmek için kullanılan daha düşük düzey ayarlayıcı olan SetActionRemoteDestinationEx, bunun yerine DestPage'i sıfıra eşit veya büyük olarak doğrular ve onu hiçbir ayarlama olmadan doğrudan eylemin açık hedef dizisine yazar: hedef belgenin ham, sıfır-tabanlı sayfa indeksini ister, ISO 32000-1'in uzak bir açık hedef için belirttiği numaralandırma. Düşük düzey ayarlayıcıyı yüksek düzey kurucuya vereceğiniz aynı sayıyla çağırın ve bağlantı bir sayfa erken açılır
var
Lib: TPDFlib;
ActionID: Integer;
begin
Lib := TPDFlib.Create;
try
if Lib.LoadFromFile('manual.pdf', '') = 1 then
begin
Lib.SelectPage(12);
// Page is 1-based here, same as SelectPage above: this opens
// the fifth page of specs.pdf.
Lib.AddLinkToFile(72, 700, 200, 16, 'specs.pdf', 5, 0, 0, 0);
// A later maintenance pass repoints the same link at a
// reorganized file. SetActionRemoteDestinationEx edits the
// action directly, and DestPage here is the zero-based index
// PDF itself uses for a remote explicit destination -- "the
// fifth page" is now 4, not 5.
ActionID := Lib.GetAnnotActionID(1);
Lib.SetActionRemoteDestinationEx(ActionID, 'specs-2026.pdf',
4, Ord(dkFit), 0, 0, 0, 0, 0, 0, -1);
end;
finally
Lib.Free;
end;
end;
SetActionRemoteDestinationEx'in geri kalan argümanları da tam olarak aynı derecede tam anlamıyladır. ValueMask, bir bit kümesidir -sol için 1, üst için 2, sağ için 4, alt için 8, yakınlaştırma için 16- ve PDFlibPas herhangi bir şey yazmadan önce onu DestType'a karşı kontrol eder: bir dkFitR hedefi tam olarak 15'i (dört kenarın tümü, yakınlaştırma yok) sağlamalıdır, dkFit ve dkFitB 0 sağlamalıdır ve dkFitH/dkFitV yalnızca kendi ilgili tek koordinatını kabul eder. Aksi halde geçerli bir maske içinde ayarlanmadan bıraktığınız bitler, diziden atlanmaz; ISO 32000-1'in o koordinat için "görüntüleyicinin zaten sahip olduğu değeri koru" olarak ele aldığı açık bir PDF null'u olarak yazılırlar -bir gözden kaçırma değil, "bu sayfaya atla, yakınlaştırmayı olduğu gibi bırak" demenin meşru bir yolu. Yakınlaştırmanın kendisi geçirdiğiniz değerin bir kesri olarak saklanır; bu yüzden yüzde 150 isteyen bir çağrı, diziye 1,5'lik saklanan bir değer verir ve geçerli girdi aralığı 0'dan 6400'e kadardır
Kendi belgenizin içine gömülü bir PDF'e nasıl bağlarsınız?
AddLinkToEmbeddedPDF, GoToE eylemini kurar ve hedef argümanı, EmbeddedFileName, bir yol yerine bir addır: ek yapıldığında EmbedFile'a zaten geçirilen Title dizesiyle eşleşmek zorundadır, çünkü o başlık, PDFlibPas'ın belgenin /EmbeddedFiles ad ağacında sakladığı gerçek anahtardır ve GoToE, dosya sistemine tekrar dokunarak değil, o adı arayarak çözer. Fonksiyon yalnızca EmbeddedFileName'in boş olmadığını ve TargetPage'in en az 1 olduğunu kontrol eder -gerçekte hiç gömülmemiş bir ad geçirin ve çağrı yine de başarı döndürür, eylem yine de yazılır ve bağlantı ona tıklayan her okuyucu için basitçe çözülemez
var
Lib: TPDFlib;
begin
Lib := TPDFlib.Create;
try
Lib.NewDocument;
Lib.NewPage;
// The Title argument becomes the key PDFlibPas stores in the
// document's EmbeddedFiles name tree -- that string, not
// "datasheet.pdf", is the target GoToE resolves against.
if Lib.EmbedFile('Datasheet', 'datasheet.pdf', 'application/pdf') = 1 then
Lib.AddLinkToEmbeddedPDF(72, 700, 200, 16, 'Datasheet', 3, 0, 0);
Lib.SaveToFile('manual.pdf');
finally
Lib.Free;
end;
end;
Burada bir değil iki sürüm tabanı yığılır. EmbedFile, /EmbeddedFiles ad ağacı için PDF 1.4'e ihtiyaç duyar ve AddLinkToEmbeddedPDF ayrı olarak tabanı GoToE eylem türünün kendisi için PDF 1.6'ya yükseltir; bu yüzden bu özelliği kullanan herhangi bir belge için etkin minimum 1.4 değil 1.6'dır. Ayrıca buradaki TargetPage'in 1-tabanlı olduğunu, sıradan PDFlibPas kuralını, dikkat edin -önceki bölümün az önce ele aldığı sıfır-tabanlı DestPage ile kasıtlı bir zıtlık ve hangi sayfa-numarası şemasının uygulandığının tek bir genel kurala değil, eylem türüne ve belirli çağrıya bağlı olduğunun bir hatırlatıcısı. Eylemin hedef sözlüğü ayrıca, gömülü bir dosyaya iki-sıçramalı bir zincir veya kapsayıcısına geri dönmeyi destekleyen, çocuk için C veya ebeveyn için P'lik bir /R girdisi taşıyabilir, ancak AddLinkToEmbeddedPDF hiçbir zaman yalnızca çocuk yönünü kurar, çünkü gömülmekten çok gömme yapan bir belge için mantıklı olan budur
Launch eylemleri: tek bir FileName, birbirinin yerine geçmeyen iki dize hedefi
SetActionLaunchOptions, bir Launch eyleminin dosya hedefini tek bir FileName argümanından iki farklı anahtara yazar ve iki anahtar iki farklı türde dize tutar. Üst düzey /F anahtarı, PDFlibPas'ın GoToR için kullandığı aynı yol-dönüştürme ile kurulan bir dosya-spesifikasyonu sözlüğü alır ki bu, ISO 32000-1 §7.11.3'ün bir dosya spesifikasyonu sözlüğü için tanımladığı taşınabilir formdur. PDFlibPas bir tane yazdığında /Win alt sözlüğü, ham FileName değerine hiçbir dönüştürme olmadan tam olarak geçirildiği gibi ayarlanmış kendi /F anahtarını alır, çünkü /Win /F, ISO 32000-1 §12.6.4.5'te yalnızca bir Windows görüntüleyicisinin okuması için düz bir Windows yol dizesi olarak belgelenmiştir. İki anahtarın da özdeş sonuçlanmasını bekleyerek taşınabilir, zaten dönüştürülmüş bir yol geçirin ve /Win kopyası, fonksiyona verdiğiniz her ne ise onu, dokunulmamış olarak taşıyacaktır
var
Lib: TPDFlib;
ActionID: Integer;
begin
Lib := TPDFlib.Create;
try
if Lib.LoadFromFile('manual.pdf', '') = 1 then
begin
Lib.SelectPage(1);
Lib.AddLinkToLocalFile(72, 660, 220, 16, 'calibrate.exe', 0);
ActionID := Lib.GetAnnotActionID(1);
// Operation 0 leaves this as a normal open -- pass 1 to ask a
// Windows viewer to print instead. Parameters and
// DefaultDirectory only ever reach /Win /P and /Win /D, never
// the top-level /F.
Lib.SetActionLaunchOptions(ActionID, 'calibrate.exe',
'/silent /profile:default', 'C:\Tools\Calibration', 0, -1);
end;
finally
Lib.Free;
end;
end;
Launch'ı üçünün en yüksek sürtünmeli eylemi olarak ele alın, çünkü tüm amacı PDF korumalı alanının dışında bir program çalıştırmak veya bir dosya açmaktır ve her ana akım görüntüleyici ona buna göre davranır. Adobe Acrobat'ın Enhanced Security'si, hedef açıkça güvenilen bir konumda oturmadıkça, varsayılan olarak Launch eylemlerini engeller veya sorar ve çoğu kurumsal Acrobat dağıtımı o korumayı açık bırakır. Bu yüzden halka verilen bir belgede bir Launch eylemi güvenilir bir tetikleyici değildir: dosyayı açan görüntüleyici tarafından engellenmesini, sorulmasını veya sessizce göz ardı edilmesini planlayın ve onu, görüntüleyicinin güven ayarlarını da kontrol ettiğiniz kapalı ortamlar için saklayın -dahili bir kiosk, kontrollü bir kurumsal dağıtım, hiçbir zaman yönettiğiniz bir makineden çıkmayan bir belge
PDF/A kapısı: GoToR ve Launch çağrıları neden sıfır döndürebilir
SetActionRemoteDestinationEx ve SetActionLaunchOptions, hedef belge herhangi bir PDF/A uyumluluk modundayken tamamen reddeder: her ikisi de belgenin PDF/A modunu ilk koşulları olarak kontrol eder ve eyleme hiç dokunmadan, hiçbir istisna fırlatmadan, 0 sonucuyla çıkar. Bu kasıtlıdır. PDF/A'nın etkileşimli eylemler üzerindeki kısıtlamaları özellikle Launch'ı dışlar, çünkü bir arşiv dosyasına keyfi bir program çalıştırma yeteneği vermek, tam olarak uzun vadeli arşivleme formatlarının önlemek için var olduğu türden ortama bağımlı davranıştır ve PDFlibPas aynı muhafazakâr kapıyı aynı kod yolunda uzak-gitme ayarlayıcısına da uygular. Pratik sonuç, geliştirme sırasında gözden kaçırılması kolaydır: sıradan bir PDF'te çalışan özdeş çağrı, bir PDF/A uyumluluk düzeyi ayarlanmış bir belgede derlenecek, çalışacak ve sessizce hiçbir şey yapmayacaktır; bu yüzden başarıyı varsaymak yerine dönüş değerini kontrol edin -buradaki bir 0, bozuk bir girdi hatası değildir, kütüphanenin belgenin kendi uyumluluk iddiasıyla çelişen bir isteği reddetmesidir
GoToR, GoToE ve Launch daha büyük bir PDFlibPas iş akışına nereye oturur
Bu makaledeki üç eylem türü hepsi aynı yerlere ulaşmaz. Belge ve sayfa yaşam döngüsü eylem tetikleyicileri üzerine tamamlayıcı makale, SetDocumentAction ve SetPageAction'ı ele alır; bunlar, paylaşılan PDF_ACTION_BUILDER_REMOTE_DESTINATION ve PDF_ACTION_BUILDER_LAUNCH sabitleri aracılığıyla bir GoToR veya bir Launch eylemini WillClose gibi bir tetikleyiciye bağlayabilir -düz bir URI veya JavaScript tetikleyicisini de kapsayan aynı kurucu. GoToE'nin böyle bir sabiti ve o genel kurucuya hiçbir yolu yoktur; AddLinkToEmbeddedPDF, PDFlibPas'ın bir tane kurduğu tek yoldur ki bu onu kesinlikle bir sayfa-etkin bölgesi eylemi yapar, hiçbir zaman bir belge- veya sayfa-düzeyi tetikleyicisi değil. GoToR ve Launch'ın genel kurucuya ulaştığı yerde, ödünleşim kontroldür: yalnızca adlandırılmış bir uzak hedefe işaret eden bir GoToR ve yalnızca bir dosya adı ve parametreleri olan bir Launch eylemi kurar, oysa bu makalede ele alınan açık sayfa-ve-sığdırma-türü adresleme ve Windows'a özgü başlatma seçenekleri yalnızca SetActionRemoteDestinationEx ve SetActionLaunchOptions doğrudan aracılığıyla ulaşılır
Bu ayarlayıcıların etrafında bir bakım aracı kurmadan önce bilinmeye değer bir güvenlik özelliği vardır. SetActionRemoteDestinationEx ve SetActionLaunchOptions, tüm yedek eylemi önce bir taslak sözlükte kurar ve yalnızca o taslak kopya doğrulandıktan sonra /F, /D veya /Win ve /NewWindow anahtarlarını canlı eyleme siler ve kopyalar -bu yüzden doğrulamayı başaramayan bir çağrı, ister aralık dışı bir ValueMask'ten ister boş bir FileName'den olsun, orijinal eylemi ve onun üzerine zaten asılı olan herhangi bir /Next zincirini, yarı üzerine yazılmış yerine tamamen dokunulmamış bırakır. Bu önemlidir çünkü GoToR ve Launch eylemleri ikisi de AddActionNextRemoteDestinationEx, AddActionNextLaunchEx veya daha genel AddActionNextEx ile kurulan bir /Next zincirinin içinde oturabilir; bu, tek bir tetikleyicinin sırayla bir JavaScript günlük girdisini ve ardından bir uzak sıçramayı ateşlemesine izin verir. Burada açıklanan GoToR, GoToE ve Launch kurulumu, Delphi ve C++Builder için yerel PDF kütüphanesi olan PDFlibPas'ın bir parçasıdır