PDF'te Metin Düzenleme Nasıl Çalışır: İçerik Akışları, Yazı Tipi Kodlamaları ve Neden Bir Seferde Yalnızca Bir Satır Düzenlenir
PDF sayfasında paragraf ya da metin kutusu yoktur; yalnızca bir yazı tipiyle belirli bir konuma glif çizen komutlar vardır. Bir satırı düzenlemek eski komutları silip aynı yere yenilerini yazmaktır ve nelerin düzenlenebileceğini bu belirler.

PDF sayfasında paragraf ve metin kutusu yoktur. Elinizdeki şey bir komut listesidir: bu konumda, bu yazı tipiyle ve bu boyutta, şu glifleri çiz. Metni değiştirmek, o satırı çizen komutları silip aynı konuma, aynı yazı tipi, boyut ve renkle yenilerini yazmak demektir. PDF düzenle aracının bir seferde yalnızca bir satırı düzenlemesi ve metni alt satıra kaydıramaması bu yüzdendir: metnin dosyada nasıl saklandığından kaynaklanır.
Bir metin satırı dosyada nasıl görünür
Sayfanın içeriği, operatörlerden oluşan küçük bir program olan içerik akışında durur. Metin işinin çoğunu dört operatör yapar: BT ve ET bir metin bloğunu çevreler, Tf yazı tipini ve boyutu seçer, Td sonraki konuma gider, Tj bir dizgeyi çizer. Standart bir yazı tipiyle en basit durum şöyledir:
BT /F1 18 Tf 20 150 Td (Hello World) Tj ET
Anlamı: F1 yazı tipini 18 punto seç, x 20, y 150 konumuna git ve Hello World çiz. Chrome'dan yazdırılan bir PDF genellikle farklı görünür: parantezlerin içinde artık karakterler değil, yazı tipinin glif numaraları bulunur ve konumu bir kez Tm ayarlar. Aşağıda, Chrome'un dışa aktardığı bir sayfadaki Hello World from Georgia satırı var; her dört onaltılık hane bir glif numarasıdır:
BT /F4 24 Tf 1 0 0 -1 30 52 Tm <002b0048004f004f00520003003a00520055004f0047000300490055005200500003002a004800520055004a004c0044> Tj ET
002b H, 0048 e, 004f l, 0003 boşluk, 003a W demektir ve böyle sürer. Bu numaralar yalnızca bu tek yazı tipinin içinde anlam taşır; Unicode değildir. Metni kopyaladığınızda görüntüleyici numaraları, dosyanın başka bir yerinde saklanan bir arama tablosuyla yeniden karakterlere çevirir.
Bundan iki sonuç çıkar. Birincisi, içerik akışında hiçbir şey "bu bir paragraftır" demez: satır sonu, konumu sonraki satıra taşıyan bir Td ya da Tm'den ibarettir ve bir paragrafın kaç satırı olduğu konumlardan çıkarsanmak zorundadır. İkincisi, bir satıra yeni bir karakter yazmak için o karakterin o yazı tipindeki numarasını bilmeniz gerekir; yazı tipi ise çoğu zaman yalnızca dosya yazılırken kullanılan glifleri taşır. Bu, yazı tipi alt kümelemenin sonucudur.
Akışları qpdf ile açabilirsiniz:
qpdf --qdf --object-streams=disable in.pdf out.pdf
out.pdf dosyasını bir metin düzenleyicide açıp Tj arayın; sayfada çizilen her dizge karşınıza çıkar. Bir PDF'nin içinde başka neler olduğu için Bir PDF’nin içinde ne var: nesneler, akışlar ve çapraz başvuru tablosu yazısına bakın.
Düzenleyici glifleri nasıl yeniden "satır" yapar
Düzenleyici önce dağınık glifleri kullanıcının tıklayabileceği bir satırda toplamalıdır. Yazı tipi, boyut ve rengi aynı olan ve bir önceki glifle arasındaki boşluk bir yazı tipi boyutunu geçmeyen glifler aynı öbeğe, yani tek parça sayılan glif grubuna girer; satır sonu, yeni bir yazı tipi ya da yeni bir renk öbeği bitirir. Sağdan sola akan ya da dikey metin gruplanmaz ve düzenlemeye açılamaz.
İki sonuç doğrudan gözlemlenebilir. İki yazı tipini karıştıran bir satır, örneğin içinde İngilizce bir sözcük geçen Çince bir satır, ayrı ayrı tıklanan iki bitişik öbeğe bölünür. Düzenlemeden sonra da aynısı olur: yeni metin başka bir yazı tipi kullanıyorsa satır iki öbek olur ve birini düzenlemek öbür öbeği olduğu gibi bırakır.
Bir satırı düzenlemek: önce eski metni sil, sonra yenisini yaz
Silme, "Metin karart" aracının yalnızca metne uygulanan biçimini kullanır: satırın alanındaki glifler içerik akışından çıkarılır, görüntülere ve çizgilere dokunulmaz ve eski metnin üzerine renkli bir kutu çizilmez; bu yüzden kopyalama ve arama artık onu bulamaz. Yalnızca sayfa içeriğini değiştirir; aynı metin bir ek açıklamada ya da belge özelliklerinde de geçiyorsa bunlar etkilenmez.
Yazma, sayfanın içerik akışının sonuna yeni bir metin komutu ekler; başlangıç noktası özgün satırın taban çizgisidir ve boyut ile renk yeniden kullanılır. Yukarıdaki satırı Hello World 2 olarak değiştirdikten sonra sayfanın sonuna eklenen şey şudur:
q 1 0 0 1 22.5 148.92 cm 0 0 0 rg
/Span <</ActualText <feff00480065006c006c006f00200057006f0072006c006400200032>>> BDC
BT /F4 18 Tf 0 0 Td <002b0048004f004f00520003003a00520055004f00470003> Tj ET
BT /F9 18 Tf 102.18 0 Td (2) Tj ET
EMC
Q
İlk BT özgün F4 yazı tipini ve özgün glif numaralarını kullanır; böylece Hello World olduğu gibi yeniden kullanılır. "2" özgün yazı tipi alt kümesinde yoktur; bu yüzden ikinci BT, onu çizmek için standart Helvetica yazı tipini (F9) başlatır. q ve Q, bu bloğun koordinat dönüşümünü ve rengini kendi içinde tutar; düzenleyici özgün içeriği de bir q/Q çiftiyle sarar, böylece özgün sayfanın sonunda dengelenmemiş bir grafik durumu yeni metni etkileyemez. Burada bir öbeğin nasıl göründüğü gösterildi; sayılar dosyaya göre değişir.
Sona eklemenin üç sonucu vardır:
- Yeni metin en son, sayfadaki her şeyin üstüne boyanır. Bir görüntünün ya da renkli bir bloğun altında duran metin, düzenlemeden sonra onun üstünde görünür.
- İçerik akışı sırasına göre metin çıkaran bir araç (
pdftotext -rawgibi) düzenlenmiş satırı o sayfada en son okur; konuma göre çıkarma (pdftotext -layout) ise bir değişiklik göstermez. Sayfa aynı görünür ama okuma sırası değişmiştir. - Düzenleyici yeni metne bir ActualText ekler; bu, görüntüleyiciye glifler hangi gerçek karakterleri temsil ediyor, onu söyler. Bir glif birden çok karaktere karşılık gelebilir ve glif numarasına bakarak karakteri bulmak bazen bir uyumluluk karakteri döndürür (örneğin 文 karakterini Kangxi radikali ⽂ olarak okumak); ActualText kopyaladığınızın yazdığınız olmasını sağlar.
Yeni metni hangi yazı tipi çizer
Özgün yazı tipini yeniden kullanmak en güvenli yoldur, çünkü glif biçimleri, ağırlık ve genişlik yanındakilerle uyuşur. Yeniden kullanılıp kullanılamayacağı, düzenleyicinin bir karakterin o yazı tipinde hangi koda sahip olduğunu söyleyip söyleyemeyeceğine bağlıdır:
- Yukarıdaki gibi bileşik bir yazı tipi (Type0, iki baytlık glif numaraları, Identity-H kodlaması): karakter yazı tipinde aranır, glif numarası bulunursa kullanılır. Bulunmazsa karakter alt kümede yoktur.
- Tek baytlık basit bir yazı tipi (TrueType, Type1), WinAnsi ya da MacRoman kodlamasıyla: karakterden bayta eşleme sabittir ve genişlikler dosyadaki genişlik tablosundan gelir.
- Özelleştirilmiş kodlamalı (Differences) ya da yazı tipinin yerleşik kodlamasına dayanan bir yazı tipi: güvenilir bir eşleme yoktur; bu yüzden düzenleyici tahmin yürütmez ve yedek yazı tipine geçer, aksi hâlde metin bozuk çıkardı.
Bir karakter özgün yazı tipinde yoksa yedek yazı tipi kullanılır. Düz Latin harfleri, her görüntüleyicide bulunan standart yazı tipleri Helvetica, Times ve Courier arasından en yakın olanı kullanır; bu yüzden hiçbir şey gömmek gerekmez. Geri kalan her şey, örneğin Çince karakterler, kana, Hangul, Tayca, aksanlı Latin harfleri, Kiril ve Yunan harfleri, açık kaynaklı bir Noto yazı tipini kullanır: sunucu istekteki karakterleri alır, açık kaynaklı HarfBuzz alt kümeleme kitaplığıyla yalnızca o glifleri tam yazı tipinden keser, bu genellikle birkaç KB tutar ve tarayıcı bunları dosyanıza gömer. Çince karakterin bölgesel biçimi arayüz diline göre seçilir: Basitleştirilmiş, Geleneksel, Japonca ya da Korece.
Glifler yalnızca bir yazı tipi adı yazmak yerine gömülür; çünkü yalnızca adla başvurulan bir yazı tipi, her görüntüleyicinin seçtiği yedekle değiştirilir ve ağırlık görüntüleyiciler arasında farklı olabilir; gömüldüğünde her görüntüleyici aynı biçimleri gösterir.
Neden bir seferde yalnızca bir satır
Düzenleyicinin bir yerleşim motoru yoktur. Her glif konumu dosyada sabittir; yeni metin başlangıç noktasından yazı tipinin genişlikleriyle sağa doğru dizilir, "kenarda satır kaydır" mantığı yoktur ve ondan sonra gelen hiçbir şey taşınmaz. Bir satırı uzatırsanız fazla karakterler sağa doğru akar ve sayfa kenarını aşan kısım görünmez. Bir paragrafı yeniden yazmak ya da bir tabloya satır eklemek yeni bir yerleşim gerektirir; bu da PDF'nin üretildiği kaynak dosyaya dönmek demektir.
Genişlikler de yalnızca yazı tipinin kendi ilerleme genişlikleridir, yani her glifin ardından imlecin ne kadar ilerleyeceğidir; kerning ya da glif ikamesi yoktur. Şekillendirme, yani glifleri bağlama göre seçip konumlandırma, gerektirmeyen metin (Latin, Kiril, Yunan alfabesi ve Çince karakterler) doğru dizilir. Taycadaki ton işaretlerinin doğru yere oturması glif konumlandırması gerektirir ve düzenleyici bunu yapmaz; bu yüzden yerleri kayabilir. Arapça bağlama göre değişen glif biçimlerine ve sağdan sola yerleşime, İbranice sağdan sola yerleşime, Hint yazıları ise ünsüzlerle ünlü işaretlerinin glifler hâlinde birleştirilmesine ihtiyaç duyar; bunların hepsi tam metin şekillendirmesi gerektirir ve düzenleyici bunu şu an yapmaz; bu yüzden yanlış karakter üretmek yerine bunları yazmayı reddeder.
İki sınır daha dosyanın kendisinden gelir. Taranmış bir sayfanın içeriği, metin operatörü olmayan tek bir görüntüdür; bu yüzden silinecek ya da değiştirilecek bir şey yoktur. Dijital imzalı bir dosya düzenlendikten sonra imzanın koruduğu özgün içerik değişmiş olur ve imza artık geçerli değildir.
Kendiniz doğrulayın
Yukarıda anlatılan değişiklikleri indirdiğiniz bir dosyada üç komutla görebilirsiniz:
pdftotext -raw edited.pdf - # içerik akışı sırasına göre çıkar: eski metin gitmiş, düzenlenen satır en sonda
pdffonts edited.pdf # yazı tipi listesi: yeniden kullanılan özgün yazı tipleri ve yeni gömülen yazı tipi alt kümesi
qpdf --qdf --object-streams=disable edited.pdf edited.qdf # içerik akışını aç; eklenen BT ... ET bloğu en sondadır
Okumaya devam edin
- Yazı tipi alt kümeleme neden düzenlemeyi bozar da okumayı bozmaz: özgün yazı tipinde neden bir karakterin bulunmayabileceği ve bulunmadığında ne olduğu.
- Bir PDF’nin içinde ne var: nesneler, akışlar ve çapraz başvuru tablosu: içerik akışlarının, nesnelerin ve dosya yapısının bütün resmi.
- PDF'teki Metni Çevrimiçi Düzenleme: Kaynak Dosya Olmadan Düzeltin: nasıl kullanılacağı, neye uyduğu ve ne zaman kaynak dosyaya dönülmesi gerektiği.