Teknik Makale

HotPDF ile Delphi'de PDF Ek Açıklamaları: Türler ve Dikdörtgenler

Bir ek açıklama (annotation) sayfa içeriği değildir. TextOut işlevini çağırdığınızda veya bir dikdörtgen çizdiğinizde, bu işaretler sayfanın içerik akışının bir parçası haline gelir ve bir oluşturucunun (renderer) çizdiği baytlara gömülür. Ek açıklama ise sayfanın /Annots dizisi aracılığıyla sayfaya bağlanan, kendi dikdörtgeni (rect), kendi görünümü ve kendi yaşam döngüsü olan ayrı bir sözlüktür (dictionary). Bir okuyucu, alttaki sayfanın tek bir glifine (glyph) bile dokunmadan onu açabilir, taşıyabilir, gizleyebilir veya kaldırabilir. Bu ayrım, ek açıklamaların var olma nedenidir ve aynı zamanda insanları ilk başta şaşırtan iki şeyin de kaynağıdır: bir ek açıklamanın nereye yerleştiği ve belirli bir görüntüleyici (viewer) onu ele aldığında nasıl göründüğü

HotPDF, ISO 32000 ek açıklama alt türlerini, sayfa nesnesi üzerindeki bir AddXxxAnnotation çağrıları ailesi aracılığıyla sunar. Hepsi aynı yapıyı paylaşır: ek açıklamayı PDF kullanıcı uzayında sayfaya sabitleyen bir dikdörtgen, bir yük (metin, damga adı, bir çift nokta) ve bir renk. Dikdörtgeni doğru ayarlarsanız işin büyük kısmı tamamlanmış olur. Geri kalanı, hangi alt türlerin kendi görünümünü taşıdığını ve hangilerinin çizim için görüntüleyiciye dayandığını bilmektir

Sayfaya yerleştirilmiş metin notu simgelerini, serbest metin kutularını, kare ve çizgi işaretlerini ve onay damgalarını gösteren HotPDF tarafından üretilmiş bir PDF sayfası
Aynı anda çeşitli ek açıklama alt türlerini barındıran tek bir sayfa: metin notları, serbest metin, geometrik işaretlemeler ve damgalar

Dikdörtgen, metnin değil ek açıklamanın kendisidir

Her ek açıklama çağrısı bir TRect alır ve bu dikdörtgen TextOut'a ilettiğiniz koordinatlardan farklı bir anlama gelir. Bir metin notu için bu, tıklanabilir erişim alanıdır (hotspot); not simgesinin oturduğu ve bir tıklamanın yorumu açtığı küçük bölgedir. Bir kare veya serbest metin kutusu için işaretlemenin görünür sınırıdır. Bir damga için, damga çiziminin içine ölçeklendiği kutudur. Sayılar, sayfanın sol alt köşesinden ölçülen ve Y'nin yukarı doğru arttığı PDF kullanıcı uzayı noktalarıdır; bu, HotPDF'in geri kalanının kullandığı aynı kuraldır

Bir metin notu en hafif alt türdür. Ona gövde metnini, simge için bir dikdörtgeni, varsayılan olarak açık olup olmayacağını belirten bir bayrağı (flag), bir simge adını ve bir rengi verirsiniz

Pdf.CurrentPage.AddTextAnnotation(
  'İnceleyici: onay vermeden önce bu satırdaki toplamları doğrulayın.',
  Rect(120, 700, 140, 720),   // simge tıklama alanı, ~20pt kare
  False,                      // okuyucu tıklayana kadar kapalı
  taComment,                  // balon simgesi
  clBlue);

Buradaki dikdörtgen bilerek küçüktür, her bir kenarı yaklaşık yirmi noktadır, çünkü bir metin notu birisi tıklayana kadar yalnızca bir simgedir. Dikdörtgeni büyük yaparsanız büyük bir not elde etmezsiniz; simgenin bir köşeye sabitlendiği aşırı büyük bir tıklama hedefi elde edersiniz. Open bayrağı, belge yüklendiğinde açılır pencerenin (popup) görünüp görünmeyeceğini denetler. Bir avuç notu True olarak ayarlarsanız, bunlar birbirlerinin ve içeriğin üzerinde yığılır; bu yüzden bunu yalnızca okuyucunun hemen görmesini gerçekten istediğiniz tek bir not için ayırın

Simge adı, standart not simgeleriyle eşleşen THPDFTextAnnotationType türünden gelir: taComment, taKey, taNote, taHelp, taParagraph, taNewParagraph ve taInsert. Türün değiştirdiği tek şey simgedir. Davranışı değiştirmez ve her görüntüleyicinin bu yedisinin tamamını çizmediğini bilmekte fayda vardır; hem eski hem de yeni okuyucularda güvenli olanlar taComment, taNote ve taHelp'tir

Serbest metin sayfaya yazılır, ancak bir ek açıklama olarak kalır

Bir serbest metin ek açıklaması (free text annotation) içerik gibi görünür çünkü metin bir tıklama olmadan görünür durumdadır ve dikdörtgeninin içinde bir başlık (caption) gibi oturur. Ancak getirdiği tüm ayrılabilirlik özelliğiyle birlikte hâlâ bir ek açıklamadır; bu, birisinin daha sonra kaldırabilmesi gereken bir inceleme damgası veya taslak etiketi için tam olarak istediğiniz şeydir. Yöntem imzası (signature), simge ve açılış bayrağını bir hizalama (justification) değeriyle değiştirir

Pdf.CurrentPage.AddFreeTextAnnotation(
  'TASLAK - dağıtım için değildir',
  Rect(200, 210, 400, 235),   // metnin içine yerleştirildiği kutu
  ftCenter,                   // ftLeftJust / ftCenter / ftRightJust
  clRed);

Burada dikdörtgen bir metin notu için olduğundan daha fazla önem taşır, çünkü metin bunun içinde kaydırılır ve hizalanır. Kutuyu çok kısa boyutlandırırsanız metin alt kenardan kırpılır; çok dar yaparsanız amaçlamadığınız yerlerde alt satıra geçer. Hizalama THPDFFreeTextAnnotationJust enum'ından gelir ve yalnızca üç değere sahiptir. Serbest metin bir işaretleme ek açıklaması (markup annotation) olduğundan, dosyayı bir düzenleyicide (editor) açan bir okuyucu onu seçebilir, taşıyabilir veya bir bütün olarak silebilir; serbest metne mi başvuracağınıza yoksa kelimeleri sadece TextOut ile mi çizeceğinize karar veren fark da budur. Etiketin kalıcı olması gerekiyorsa, çizin. Editöryel ise ve çıkarılması amaçlanıyorsa, onu bir ek açıklama yapın

Nesneleri işaret etmek için geometrik ve çizgi işaretlemeleri

Kareler, daireler ve çizgiler, bir bölgeyi kelimelerle tanımlamak yerine işaret etmek için kullandığınız işaretlemelerdir. AddCircleSquareAnnotation, csCircle veya csSquare değerine sahip THPDFCSAnnotationType aracılığıyla iki kutu şeklini kapsar ve dikdörtgen şeklin sınırlarını verir

// Dikkat gerektiren bir şeklin etrafına çizilen bir kutu
Pdf.CurrentPage.AddCircleSquareAnnotation(
  'Bu bölgeyi kaynak verilere karşı kontrol edin',
  Rect(50, 300, 120, 360),
  csSquare,
  clGreen);

// Bir dikdörtgen yerine iki nokta verilen bir çizgi
var
  StartPt, EndPt: THPDFCurrPoint;
begin
  StartPt.X := 130; StartPt.Y := 360;
  EndPt.X   := 250; EndPt.Y   := 320;
  Pdf.CurrentPage.AddLineAnnotation(
    'Notdan şekle doğru işaret eder',
    StartPt, EndPt,
    clBlue);
end;

Çizgi ek açıklamasının dikdörtgen kuralını bozduğuna dikkat edin: bir başlangıç ve bir bitiş olmak üzere iki THPDFCurrPoint kaydı alır, çünkü bir çizgi sınırlayıcı bir kutu (bounding box) ile değil, uç noktalarıyla tanımlanır. Renk, vuruşu (stroke) ayarlar. Eğer ok uçları istiyorsanız, HotPDF'in çizgi sonu (line-ending) stillerini kabul eden aşırı yüklenmiş (overload) AddLineAnnotation sürümleri vardır; ancak düz üç argümanlı form, genellikle bir belirtmenin (callout) ihtiyaç duyduğu şey olan yalın bir çizgi çizer

Metin işaretleme (text-markup) alt türleri, önceden yerleştirdiğiniz bir bölge üzerinde çalışır. AddHighlightAnnotation bir dikdörtgen, isteğe bağlı içerikler ve varsayılanı sarı olan bir renk alır ve alanı bir fosforlu kalemin yapacağı gibi renklendirir. Gerçek metnin üzerine oturması amaçlanmıştır, bu nedenle dikdörtgen çizdiğiniz kelimelerin sınırlarıyla eşleşmelidir; bu, onu genel olarak tahmin etmek yerine TextOut'a geçirdiğiniz aynı koordinatlardan hesapladığınız anlamına gelir

Damgaların oluşturulması görüntüleyiciye bağlıdır

Bir damga (stamp) ek açıklaması, bir okuyucudan diğerine en çok farklı görünme ihtimali olan türdür ve bunun nedeni anlaşılmaya değerdir. AddStampAnnotation, satApproved, satConfidential, satFinal, satDraft ve satForComment gibi değerlere sahip THPDFStampAnnotationType aracılığıyla standart bir damgayı adlandırır

Pdf.CurrentPage.AddStampAnnotation(
  'İnceleme üzerine yayın için onaylandı',
  Rect(50, 400, 200, 440),
  satApproved,
  clGreen);

Damga adı bir istektir. PDF standart damga adları kümesini tanımlar ancak bunların arkasındaki çizimi tanımlamaz, bu nedenle her görüntüleyici kendi "APPROVED" (ONAYLANDI) veya "CONFIDENTIAL" (GİZLİ) oluşturmasını birlikte sunar ve birkaçı, tanımadıkları isimler için hiçbir şey oluşturmaz. Dikdörtgen, çizimin içine ölçeklendiği kutuyu denetler ve renk, görüntüleyicinin dikkate alabileceği veya almayabileceği bir ipucudur. Bir damganın her yerde aynı görünmesi gerekiyorsa, güvenilir yol standart bir damga değildir: işareti kendiniz TextOut ve çizim çağrılarıyla çizin veya görünümünü sizin denetlediğiniz serbest bir metin ek açıklaması olarak yerleştirin. Görüntüleyicinin tanıdık görünümünü istediğinizde ve farklılıklara tolerans gösterebildiğinizde standart damgaya başvurun

Dosya ekleri (file attachments) de aynı dikdörtgen ve yük (payload) yapısını izler. AddFileAttachmentAnnotation; açıklamayı, gömülecek dosyanın yolunu, ataş simgesi için bir dikdörtgeni ve bir rengi alır. Dosya PDF'in içinde taşınır ve simge, bir okuyucunun dosyayı çıkarmak için kullandığı araçtır (handle)

Ek açıklamaların AcroForm alanlarından farkı

En çok zaman kaybına mal olan kafa karışıklığı, bir ek açıklamaya sanki bir form alanıymış gibi davranmaktır. Her ikisi de /Annots aracılığıyla sayfaya eklenir ve bir form alanı aslında özel bir ek açıklama alt türüdür (bir widget/araç); bu nedenle birbiriyle ilişkili görünürler. Ancak birbirlerinin yerine geçemezler. Bir form alanı bir değer tutar, bir ada sahiptir, sekme sırasına (tab order) katılır ve gönderilebilir, sıfırlanabilir veya betiklenebilir (scripted); bunları bu sayfadaki ek açıklama çağrılarıyla değil, AddTextField, AddCheckBox ve AddPushButton çağrılarıyla oluşturursunuz. Bir işaretleme ek açıklaması (markup annotation) ise bir yorum veya bir şekil tutar, gönderilecek hiçbir değeri yoktur ve girdi toplamanız gerektiği anda yanlış araçtır

Pratik test basittir. Eğer bir kullanıcının yazması, seçmesi veya tıklaması ve belgenin bunu hatırlaması amaçlanıyorsa, istediğiniz şey bir AcroForm alanıdır. Dosyayla birlikte seyahat eden ancak veri olmayan bir not bırakıyor, bir bölgeyi işaretliyor veya bir durumu damgalıyorsanız, istediğiniz şey bir ek açıklamadır. Bunları birbirine karıştırmak, doğru görünen ancak yanlış davranan belgeler üretir: kimsenin dolduramayacağı bir "alan" veya form sıfırlandığında kaybolan bir yorum. Alan türleri, doğrulama (validation) ve gönderme eylemleri ile etkileşimli kısım, AcroForm alanları ve eylemleri kılavuzu'nda ele alınan başlı başına bir konudur

Bir sayfayı bir araya getirmek

Parçalar, HotPDF'in geri kalanının yaptığı şekilde birleştirilir. Belge özelliklerini ayarlayın, BeginDoc'u çağırın, metin ve grafik çağrılarıyla ihtiyaç duyduğunuz sayfa içeriğini çizin, en üste ek açıklamaları ekleyin ve EndDoc ile kapatın. Ek açıklamalar CurrentPage'e (geçerli sayfa) eklenir, bu nedenle bir AddPage işleminden sonra yeni sayfaya düşerler ve eğer sayfa kesmesinden (break) sonra eklerseniz, birinci sayfa için düşündüğünüz bir not sessizce ikinci sayfada belirecektir

Pdf := THotPDF.Create(nil);
try
  Pdf.FileName := 'annotated.pdf';
  Pdf.Compression := cmFlateDecode;
  Pdf.FontEmbedding := True;
  Pdf.BeginDoc;

  Pdf.CurrentPage.SetFont('Arial', [], 11);
  Pdf.CurrentPage.TextOut(50, 740, 0, 'Üç aylık rakamlar, inceleme için taslak');

  Pdf.CurrentPage.AddTextAnnotation(
    'Onay vermeden önce toplamları doğrulayın.',
    Rect(50, 720, 70, 740), False, taComment, clBlue);
  Pdf.CurrentPage.AddFreeTextAnnotation(
    'TASLAK', Rect(450, 720, 540, 745), ftCenter, clRed);
  Pdf.CurrentPage.AddStampAnnotation(
    'Yorum için', Rect(50, 660, 180, 695), satForComment, clGreen);

  Pdf.EndDoc;
finally
  Pdf.Free;
end;

Çıktı yanlış göründüğünde geliştirilmesi gereken son bir refleks: kodun bozuk olduğuna karar vermeden önce dosyayı birden fazla görüntüleyicide açın. Damgalar ve daha nadir bulunan not simgeleri genellikle olağan şüphelilerdir ve ek açıklama boyanmış piksellerden çok okuyucuya yönelik bir istek olduğundan, Acrobat ile hafif bir görüntüleyici arasındaki fark genellikle çağrınızdaki bir hata (bug) değil, belirtimlerin (spec) tasarlandığı gibi çalışmasıdır

Burada gösterilen ek açıklama çağrıları, Delphi ve C++Builder için HotPDF Component'in bir parçasıdır