/IC rengi olmadan çizilmiş bir karartma işareti, uygulama adımından şeffaf bir boşluk ya da içi boş bir kontur olarak çıkabilir; üstündeki gözden geçiren yorumu ise dosyada kalır. PDFlibPas, Redact annotationlarını ApplyRedactions ile uygular: kapsanan içerik önce gider, katman /ROdan ya da yedeği siyah olan /ICden gelir ve işaretin sözlüğü boşaltılır
İşaretlemek geri alınabilir, uygulamak alınamaz
ISO 32000-1 §12.5.6.23, karartmayı içerik tanımlama ile içerik silme olarak ikiye ayırır. Tanımlama sırasında bir Redact annotationı, kullanıcıların hâlâ görebileceği, taşıyabileceği ve yeniden tanımlayabileceği yalnızca bir tekliftir; bir inceleme turunu mümkün kılan da budur. Silme uygulamaya bırakılmıştır ve sıkı gereksinimlerle gelir: annotationın tanımladığı her şey gider, annotation gider ve kapsanan görüntü kısmının verisi yok edilir; çünkü piksellerin üstündeki bir kırpma yolu ya da görüntü maskesi yeterli sayılmaz. Anahtarlar ISO 32000-1in tablo 192sinde (ISO 32000-2de tablo 195) listelenir ve çoğu, neyin silineceğinden çok silme sonrası sayfanın nasıl görünmesi gerektiğini tanımlar
| Anahtar | Şemadaki rolü | ApplyRedactions ona ne yapar |
|---|---|---|
QuadPoints | Kaldırılacak bölge, n adet dörtgen olarak; var olduğunda bölge olarak Rectin yerine geçer | Her dörtgenin sınırlayıcı kutusunu ayrı ayrı siler; uzunluğu 8in katı olmayan bir dizi Recte döner |
Rect | QuadPoints yokken kaldırılacak bölge | Ters köşeler normalize edilerek kullanılır |
IC | Silme sonrası DeviceRGB dolgu; yokluğu şeffaf demektir; RO varken yok sayılır | Var olduğunda korunur, yokken siyah olarak eklenir |
RO | Form XObject katmanı; IC, OverlayText, DA ile Qdan öncelik alır | Normal görünüm olarak kurulur ve sayfaya düzleştirilir |
OverlayText, Repeat | Bölgenin üzerine çizilen etiket, istenirse döşenir | Üretilen katmana çizilir; Repeat doğru olduğunda döşenir |
DA, Q | Etiketin fontu, boyu ve rengi; hizalama | Boy ile renk DAdan, hizalama Qdan okunur |
AddRedactAnnotation ile işaret oluşturmak
TPDFlib.AddRedactAnnotation(Left, Top, Width, Height, FillR, FillG, FillB, OverlayText, RepeatOverlay), seçili sayfaya bir işaret ekler ve sayfanın yeni annotation sayısını döndürür; bu aynı zamanda işaretin 1 tabanlı indeksidir, hiçbir şey eklenmediğinde 0 döner. Koordinatlar geçerli kökeni ve birimleri izler; örnek bu yüzden sol üst kökene geçer ve orada Top üst kenardır. Çağrı /Rect ile, dolgu bileşenlerinden türlenmiş bir /ICi ve 10 puntolu beyaz metin için sabit bir /DA yazar: /F0 10 Tf 1 1 1 rg. Dolu bir OverlayText, ortalanmış bir etiket için /OverlayText, /Repeat ile /Q 1 ekler. Redact annotationları bir PDF 1.7 özelliğidir; daha eski bir başlık 1.7e yükseltilir. Henüz bir görünüm akışı yazılmaz; bekleyen işaret, gözden geçiren uygulamasının çizdiği gibi görünür. Etiket beyaza sabitlenmişken OverlayTexti koyu bir dolguyla eşleştirin; çünkü açık sarıda etiket kaybolur. İşaretler her PDFlibPas sürümünde oluşturulabilir
uses
System.SysUtils, PDFlibrary;
procedure MarkForReview(const SourceFile, ReviewFile: string);
var
Pdf: TPDFlib;
Index: Integer;
begin
Pdf := TPDFlib.Create;
try
if Pdf.LoadFromFile(SourceFile, '') <> 1 then
raise Exception.CreateFmt('Cannot open %s', [SourceFile]);
Pdf.SetOrigin(1); // sol üst köken: Top üst kenardır
Pdf.SetMeasurementUnits(0); // punto
if Pdf.SelectPage(1) <> 1 then
raise Exception.Create('Page 1 not found');
// Tanık adı: siyah dolgu, ortalanmış beyaz etiket
Index := Pdf.AddRedactAnnotation(72, 180, 220, 14, 0, 0, 0, 'REDACTED');
if Index = 0 then
raise Exception.Create('Mark was not added');
// Hesap bloğu: muafiyet kodunu daha yüksek bir kutuya döşe
Pdf.AddRedactAnnotation(72, 410, 300, 40, 0, 0, 0, '(b)(6)', 1);
// Yalnızca işaretler; özgün içeriğin her baytı hâlâ duruyor
Pdf.SaveToFile(ReviewFile);
finally
Pdf.Free;
end;
end;
QuadPoints kaldırma alanına karar verir; yanıtlar metnini korur
Bir işaret bir kez /QuadPoints taşıdığında, o dörtgenler ApplyRedactionsun ne kaldıracağına karar verir ve Rect onları yalnızca gösterim için sınırlar. Metin seçme araçlarıyla yapılan işaretler genellikle seçilen satır başına bir dörtgen taşır; böyle bir işareti SetAnnotRectle boyutlandırmak çerçevesini ekranda oynatır ve kaldırma alanını yerinde bırakır. Bölgeyi oynatan çağrı SetAnnotQuadPointstır ve GetAnnotQuadCount, yalnızca Recte dayanan bir işaret için 0 döndürür. İşarete bağlı metin başka bir kuralı izler. İnceleme araçları notu /Contentste, yazarı /Tde tutar ve bir karartma işaretinin üstündeki not, silinen şeyin kendisini tanımlama eğilimindedir ("müşteri TCKN, hukuki onayla"). ApplyRedactions işaretin kendi sözlüğünü boşaltır; ama /IRT üzerinden altına dizilen yanıtlar ayrı annotationlardır ve yalnızca dikdörtgenleri bir karartma bölgesiyle çakıştığında silinir; kenar boşluğuna park edilmiş bir yanıt metnini korur. Aşağıdaki liste, her işareti dörtgen sayısıyla ve altına dizilmiş yanıtlarıyla basar
procedure ListPendingMarks(Pdf: TPDFlib);
var
P, I, Parent: Integer;
begin
for P := 1 to Pdf.PageCount do
begin
if Pdf.SelectPage(P) <> 1 then
Continue;
for I := 1 to Pdf.AnnotationCount do
if Pdf.GetAnnotType(I) = 'Redact' then
Writeln(Format('p%d #%d by %s, quads=%d: %s',
[P, I, Pdf.GetAnnotTitle(I), Pdf.GetAnnotQuadCount(I),
Pdf.GetAnnotContentsEx(I)]))
else
begin
Parent := Pdf.GetAnnotReplyTo(I); // /IRT yokken 0
if (Parent > 0) and (Pdf.GetAnnotType(Parent) = 'Redact') then
Writeln(Format(' reply #%d to #%d: %s',
[I, Parent, Pdf.GetAnnotContentsEx(I)]));
end;
end;
end;
ApplyRedactions sonrası hangi katman görünür?
/RO girdisi, var olduğunda her zaman kazanır; tablo 192nin öncelik kuralı bunu gerektirir. ApplyRedactions o Form XObjectı annotationın normal görünümü (/AP /N) olarak kurar, varsa görünüm durumunu düşürür ve düzleştirir; /IC, /OverlayText, /DA ile /Q o işarette etkisiz kalır. Yerleşim, incelikli olan tek kısımdır. Şema, katmanın kökeninin Rectin sol alt köşesiyle hizalanacağını söyler; düzleştirme ise Formun BBoxını Matrixiyle Recte eşler — yani düzleştirmenin form field widgetlarına uyguladığı BBox ve Matrix yerleşimi. BBoxu [0 0 w h] olan, dikdörtgene boyanmış ve birim Matrixli bir katman iki okumada da aynı görünür; kendi araçlarınız /RO işareti üretirken o biçimi isteyin
/ROsuzken ApplyRedactions sözlüğü normalleştirir ve görünümü kendisi kurar. /C ile /BSi siler ve /Borderi [0 0 0]e kurar: bu girdiler, genellikle renkli bir kontur olan bekleyen işareti tanımlar ve onu son sayfaya yakmak, bitmiş bir karartmayı bitmemiş gösterirdi. Kontur gittikten sonra dolgu bütün dikdörtgeni kaplar. Etiket, üretilen Formun içinde çizilir; boyu ve rengi /DAdan, hizası /Qdan, döşemesi /Repeatten gelir ve F0 font adı, o Formun kendi kaynaklarında standart Helveticaya bağlanır. O bağ, dosyalar araçlar arasında gezerken önemlidir: ISO 32000-1 §12.7.3.3, bir DA font adını etkileşimli formun varsayılan kaynaklarındaki (/DR) bir girdi olarak tanımlar; form fieldı olmayan bir belgede öyle bir kaynak yoktur ve aynı işareti uygulayan başka bir uygulama bir yedek fonta geçebilir. PDFlibPas o aramayı atlar ve Helvetica ile etiket, REDACTED gibi ya da bir muafiyet kodu gibi Latin yazılı metne yakışır
Eksik /IC siyah bir kutuya döner
Şemanın yok bir /IC için varsayılanı şeffaf bir iç yüzdür ve PDFlibPas bundan bilerek sapar. Silme sonrasında şeffaf bir iç yüz kâğıdı gösterir; bir zamanlar bir adın durduğu beyaz bir boşluk. O boşluk, hiçbir zaman orada bir şey olmamış bir düzenden ayırt edilemez. Okuyucu karartılanı boştan ayıramaz ve gözden geçiren, çıkarılan metni karşılaştırmadan karartmanın yapıldığını doğrulayamaz. Yalnızca konturlu bir işaretin bekleyen görünümünü düzleştiren bir uygulama adımının üreteceği içi boş çerçeve ise başka türlü düşer: kimse üzerine işlem yapmamış bir teklif gibi okunur. Varsayılanı harfi harfine izlemeyi tarttık ve siyah kutuyu seçtik; çünkü bir şeyin saklandığının görünür işareti, karartılmış bir belgenin okuyucusuna söylediğinin parçasıdır ve seçim, yalnızca yazarı hiç dolgu bildirmemiş işaretleri etkiler. Sözlükte zaten var olan bir /IC, değeri ne olursa olsun kullanılır; beyaz isteyen bir üretici beyazı alır
Katman çizilmeden önce ne gitmiştir?
ApplyRedactions sayfa sayfa çalışır ve hiçbir katmanı düzleştirmeden önce bütün silmeyi tamamlar; dolayısıyla bir katman kendi bölgesine asla yakalanamaz. Her sayfa için dörtgen başına bir dikdörtgen, dörtgeni olmayan işaretler için Rect toplar ve her içerik katmanını bunların her birine karşı siler:
- Metin glif glif kesilir; sayfa fontlarından ve tam metin durumundan ölçülür ve kısmen kapsanan bir dizgenin gerisi özgün konumunda kalır
- Bölgenin içine boyayan vektör yolları, satır içi görüntüler ve renk geçişleri içerik akışından silinir
- Form XObjectlarına özyinelemeli girilir; öbür sayfaların ya da yerleşimlerin de çizdiği bir Form, özel bir kopya üzerinden karartılır, böylece o sayfalar özgünü korur
- Görüntü XObjectları yalnızca kapsanan pikselleri yitirir; siyahla (CMYK için tam K mürekkebi) üzerine yazılır. JPEG, JPEG 2000, JBIG2 ve CCITT görüntüleri çözülür ve kayıpsız Flate akışları olarak geri saklanır
- Etiketli PDFte, silinen işaretli içeriğe bağlı
/Altile/ActualText, sayfa içeriğinde ve yapı ağacında temizlenir - Dikdörtgeni bölgeye değen öbür annotationlar silinir ve widgetları orada duran form fieldları değerlerini yitirir
Piksel adımı, şemanın görüntü maddesinin uygulamadaki hâlidir. Taranan bir pasaportun üstüne boyanmış siyah bir dikdörtgen gözü doyurur ve yine de §12.5.6.23e takılır; çünkü özgün örnekler, birisi görüntüyü çıkarır çıkarmaz çözülür. Aynı motor, hiçbir annotation okumadan, doğrudan geçtiğiniz bir dikdörtgenin içeriğini temizleyen ve SanitizeDocument ile eşleşen RedactRegionin de arkasındadır. İçerik gittikten sonra her işaret düzleştirilir ve sözlüğü /Type ile /Subtypea dek temizlenir. Düzleştirme, annotationı sayfanın /Annots dizisinden çıkarır; ama sözlük hâlâ belgenin içinde bir nesnedir ve onu yazan bir kaydetme, /Contents, /RC, /T ile inceleme izinin gerisini alıcıya teslim eder
Karartılmamış revizyonla kaydetmemek
Artımlı bir kaydetme, yukarıdakilerin hepsini geri alır. §7.5.6 altında (ISO 32000-1 ile ISO 32000-2de aynı numara), artımlı bir güncelleme değişen nesneleri dosyanın sonuna ekler ve özgün baytları olduğu gibi bırakır; dolayısıyla özgün revizyon — sayfa içeriği, görüntüleri ve işaretlenmiş annotationlarıyla — dosyayı eski %%EOFten kesen herkes tarafından okunabilir kalır. PDFlibPas Small Business sürümündeki ExtractDocumentRevision bunu tek çağrıda yapar. ApplyRedactions sonrasında yeni bir dosyayı SaveToFile ile yazın; asla ekleyen SaveChanges ile değil. Kaydetmeden önce GarbageCollectObjects, nesne tablosunu tarar ve artık hiçbir şeyin başvurmadığı nesneleri düşürür; uygulama adımından önce işaretlerin taşıdığı görünüm akışları gibi. Tam bir kaydetme, SetGarbageCollect açmadıkça ya da SaveToFileOptionsa geçtiğiniz TPDFlibSaveOptions kaydının GarbageCollect alanını kurmadıkça o taramayı atlar. Meta veri kalan boşluktur. SanitizeDocument(SANITIZE_METADATA or SANITIZE_XMP_PACKET), Author, Subject, Keywords, Creator ile Produceri boşaltır ve XMP akışını kaldırır; Titleı denetlemeniz için bırakır. Burada SANITIZE_ALLden kaçının: SANITIZE_ANNOTATIONSi içerir ve belgede kalan her annotationı siler; aralarında saklamak istediğiniz notlar da vardır
ApplyRedactions, RedactRegion gibi Enterprise sürümünde bulunur. Sıradan bir TPDFlib üzerinde 0 döndürür ve LastErrorCodeu PDFLIB_ERROR_ENTERPRISE_REQUIRED (900)e kurar; dolayısıyla sürüm adımı, PDFlibEnterprise biriminden TPDFlibEnterprise kullanır
uses
System.SysUtils, PDFlibrary, PDFlibEnterprise;
procedure ApplyAndRelease(const ReviewFile, ReleaseFile: string);
var
Pdf: TPDFlibEnterprise;
Applied, Orphans: Integer;
begin
Pdf := TPDFlibEnterprise.Create;
try
if Pdf.LoadFromFile(ReviewFile, '') <> 1 then
raise Exception.CreateFmt('Cannot open %s', [ReviewFile]);
Applied := Pdf.ApplyRedactions; // her sayfadaki her Redact işareti
if Applied = 0 then
raise Exception.CreateFmt('No marks applied (error %d)',
[Pdf.LastErrorCode]);
// Info ve XMP, sayfaların artık göstermediğini hâlâ yazabilir
Pdf.SanitizeDocument(SANITIZE_METADATA or SANITIZE_XMP_PACKET);
Orphans := Pdf.GarbageCollectObjects;
// Yeni dosyaya tam yeniden yazım; karartmadan sonra asla SaveChanges
if Pdf.SaveToFile(ReleaseFile) <> 1 then
raise Exception.Create('Save failed');
Writeln(Format('%d marks applied, %d unreferenced objects dropped',
[Applied, Orphans]));
finally
Pdf.Free;
end;
end;
Beklenen: ApplyRedactions, bütün sayfalara düzleştirdiği Redact işaretlerinin sayısını döndürür — MarkForReviewin yazdığı inceleme kopyası için 2 — ve GarbageCollectObjects, taramanın düşürdüğü başvurulmayan nesne sayısını döndürür
Hangi araç bir işareti çizmiş olursa olsun, onun /RO ile /ICsi alıcının sayfada ne göreceğine karar verir; PDFlibPas Enterprise for Delphideki uygulama adımı ise altında neyin gittiğine karar verir