Bir PDF'deki metnin neden gerçekte metin olmadığı
Bir bakışta
“Bir bakışta” başlıklı bölümBir PDF okuduğunuzda sözcükler görürsünüz. Dosya sözcükler içermez. Koordinatlara şekiller boyamaya yönelik yönergeler içerir ve bu şekiller tesadüfen harfler gibi görünür. Bir PDF’in çizdiği ile kastettiği arasındaki uçurum, bir sayfanın kusursuz görünüp yine de saçma sapan kopyalanmasının nedenidir. Bu sayfa, işte o uçurumu ve onu kapatan o küçük, ayrı eşlemeyi konu alır.
Bunun neden önemli olduğu
“Bunun neden önemli olduğu” başlıklı bölümBir PDF’e metin olarak yaptığınız her şey — onu seçmek, kopyalamak, aramak,
geri getirme için dizinlemek, bir ekran okuyucuyla sesli okumak — dosyanın hiçbir
zaman doğrudan saklamadığı karakterleri kurtarmaya dayanır. Bu kurtarma başarısız
olursa, başarısızlık görünmezdir. Sayfa yine de işlenir. Biri bir paragrafı bir
e-postaya kopyalayıp □□□□ alana ya da 400 sayfalık bir sözleşmede apaçık orada
duran bir maddeyi arayıp hiçbir şey bulamayana dek kimse fark etmez.
Bu, tam da her görsel incelemeden sağ çıktığı için pahalı bir hata sınıfıdır. Görülecek hiçbir şey yoktur. Belge yetkili görünür ve makine açısından suskundur.
Kısa özet
“Kısa özet” başlıklı bölüm- Bir PDF, Unicode karakterlerini değil, bir yazı tipindeki sayısal kodlarla seçilen görsel şekilleri — glifleri — çizer.
- Aynı şekil farklı karakterler anlamına gelebilir ve aynı karakter farklı gliflerle çizilebilir. Görünüm ile anlam, tasarım gereği ayrıştırılmıştır.
- Metni geri almak için bir okuyucu, gösterme yolunu tersine çalıştırır: koddan
karaktere. Yazı tipinin
/ToUnicodeCMap’i, bu ters adım için arama tablosudur (Spec: ISO 32000-2, §9.10ISO 32000-2 §9.10). /ToUnicode’un olmaması ya da yanlış olması, sayfa hâlâ piksel kusursuz dururken, bozuk kopyala-yapıştır ve başarısız arama demektir.- Bu, anlam sorunudur. Glifin doğru görünüp görünmediği,
Yazı tipleri: en zor kısım bölümünde
ele alınan ayrı görünüm sorunudur. NextPDF, gidiş-dönüş sadık olsun diye
doğru bir
/ToUnicodeyayar.
NextPDF buna nasıl yaklaşır
“NextPDF buna nasıl yaklaşır” başlıklı bölümMetnin sayfaya nasıl geldiğiyle başlayın. Bir içerik akışı “dosya sözcüğünü
yaz” demez. Bir yazı tipi seçer, sonra bir metin gösterme işlecine bir kodlar
dizesi verir (Spec: ISO 32000-2, §9ISO 32000-2 §9). Her kod bir dizindir
— bir yazı tipi programındaki bir konum — ve yazı tipi o dizini bir glif anahattına
çevirip boyar. 70 kodu, F karakteri değildir. “Bu yazı tipindeki 70 numaralı
yuva”dır ve 70 numaralı yuva tesadüfen F biçiminde bir eğri tutar. Farklı bir
yazı tipi seçin, 70 numaralı yuva bir kar tanesi olabilir.
Yani bir kod ancak yazı tipinin kodlamasına göre bir şey ifade eder. Basit bir yazı tipi için bu kodlama kabaca glif başına bir bayttır. Binlerce glif gerektiren betikler için — CJK ya da herhangi bir tam Unicode belgesi — bu kadar yer yeterli değildir ve PDF, birleşik (Type 0) bir yazı tipine uzanır (Spec: ISO 32000-2, §9.7ISO 32000-2 §9.7). Bir birleşik yazı tipi, çok baytlı kodları bir CMap aracılığıyla okur, bunları CID’lere (karakter tanımlayıcılarına) çevirir ve CID’leri gliflere eşler. Bu, tek bir yazı tipinin muazzam bir glif kümesini adresleyebilmesini sağlayan zarif bir dolaylamadır. Aynı zamanda “gösterilen” ile “kastedilen” arasındaki izin soğuyabileceği bir yer daha demektir.
Şimdi onu tersine çalıştırın. Metni çıkarmak için bir okuyucu, içerik akışında bulduğu kodları alır ve karakterleri kurtarmak zorundadır (Spec: ISO 32000-2, §9.10ISO 32000-2 §9.10). Glifi çizen kodlama karakterden glife gitti; çıkarmaysa glif kodundan karaktere ihtiyaç duyar ve bu yön tersine çevrilebilir olmak zorunda değildir. Bir alt küme yazı tipi gliflerini yeniden numaralandırmış olabilir. Bir birleşik yazı tipinin CID’leri özel olabilir. Sayfadaki şekil, kendinde hiçbir Unicode anlamı taşımaz.
Çözüm, ters eşlemeyi yazı tipiyle birlikte göndermektir. O eşleme,
/ToUnicode CMap’idir: belgenin kullandığı her kod için, o kodun temsil
ettiği Unicode değerini (ya da değerlerini) kaydeder. Onunla birlikte çıkarma,
temiz bir aramadır. Onsuz bir okuyucu, yazı tipi kodlamalarından ve sezgisel
yöntemlerden tahmin etmeye kalır — ve fi’nin bir soru işaretine dönüştüğü yer
tam da tahmin etmektir.
- Your charactersThe Unicode text you set, for example the word 'file'.
- Encoding → codesThe font's encoding turns characters into numeric codes; a composite font routes them through a CMap to CIDs.
- Codes → glyphsEach code selects a glyph outline, which is painted to the page. This is the part you see.
- Extraction reverses itA reader reads the codes back and looks each one up in /ToUnicode to recover Unicode.
- Text againWith a correct /ToUnicode, copy, search, indexing, and screen readers all get the original characters back.
NextPDF, ters eşlemeyi rutin olarak yazar. Bir birleşik yazı tipi gömdüğünde,
CIDFontType2 torununu, Type0 ebeveynini ve kodların Unicode’a geri çözülmesi
için bir /ToUnicode CMap’ini yayar — bu, Yazı tipleri: en zor
kısım bölümünde anlatılan kodlama işidir.
Burada ayrı tutmaya değer nokta, nedendir: /ToUnicode akışı, sayfanın doğru
görünmesini sağlamakla ilgili değildir. Glifler onsuz da zaten doğru görünür.
Metni çıkarılabilir tutan tek yapı odur.
Pratik örnek
“Pratik örnek” başlıklı bölümBunun en ünlü ortaya çıktığı yer, fi bitişik harfidir. Birçok yazı tipi,
i’nin noktası f’nin kancasıyla çakıştığı için f ile i’yi tek bir
birleşik glif olarak çizer. Sayfada bu, tek bir kodla çizilen tek bir şekildir.
Asıl soru, onu kopyaladığınızda ne olduğudur.
% A /ToUnicode entry that maps the single ligature code to TWO characters,% so selecting the 'fi' glyph copies out as 'f' then 'i' — not one mystery box.1 beginbfchar<0085> <00660069> % code 0x85 -> U+0066 'f' U+0069 'i'endbfcharİşte o tek girdi, “file” araması eşleşmesiyle, bitişik harfle işlenmiş her
geçişin sessizce ıskalandığı bir “file” araması arasındaki farktır. Bitişik harf
kodunu iki karakterli f + i dizisine eşleyin, sözcük aranabilir ve
kopyalanabilir olur. Onu eşlenmemiş bırakın, sayfa hâlâ file’ı kusursuz
gösterirken metin sessizce bir makinenin okuyabileceği hiçbir şey söylemez.
“fi”nin neden bir karakter ya da iki karakter olarak çıkarılabildiği ve farkın
neden rastgele olmadığı işte budur — bu, /ToUnicode eşlemesine ne söylemesi
söylendiyse odur. Doğru bir eşleme, bitişik harfi karakterlerine ayrıştırır.
NextPDF tam olarak bu türden bir girdi yayar; böylece sayfadaki bir bitişik harf,
panodaki iki sıradan harftir.
Yaygın yanlış anlama
“Yaygın yanlış anlama” başlıklı bölümTuzak, adıyla: “metin işleniyor, demek ki metin yolunda.” İşleme ve çıkarma,
farklı verileri okuyan farklı mekanizmalardır. İşleme, koddan glife yolunu
izler ve gözlerinizin denetlediği şeydir. Çıkarma, /ToUnicode aracılığıyla
koddan karaktere yolunu izler ve her makine tüketicisinin denetlediği şeydir.
Bir belge birincisinde mükemmel olup ikincisinde tamamen başarısız olabilir;
çünkü yapısı gereği bunu açığa çıkaracak görsel hiçbir şey yoktur.
İkinci, daha incelikli bir tuzak: bir glifin hangi karakter olduğunu “besbelli” bildiğini varsaymak. Bilmez. Bir glif, bir dizine sahip bir şekildir. Bir karaktere geri eşleme, üreticinin sağlaması gereken ek bilgidir. Üretici onu hiç yazmadıysa, hiçbir okuyucu onu sadık biçimde kurtaramaz — yalnızca tahmin edebilir.
Sınırlar ve kapsam
“Sınırlar ve kapsam” başlıklı bölüm| Edition | Availability |
|---|---|
| Core | NextPDF, gömdüğü yazı tipleri için, bitişik harf ve birleşik yazı tipi durumları dâhil, doğru bir /ToUnicode CMap’i yayar; böylece ürettiği belgeler aranabilir ve kopyalanabilir. |
| Pro | Not in this edition |
| Enterprise | Not in this edition |
Bir /ToUnicode eşlemesi yalnızca kaynak yazı tipinin gerçekten ortaya koyduğu
bilgiyi taşıyabilir. Bir glifin belirlenebilir bir karakteri olmadığı yerde —
salt süsleme amaçlı bir işaret, Unicode ataması olmayan özel kullanımlı bir
simge — hiçbir eşleme, hiç var olmamış bir anlamı icat edemez. NextPDF,
türetebildiği doğru eşlemeyi yayar; bir boşluğu doldurmak için karakter uydurmaz.
Bu sayfa, NextPDF’in yazdığı belgelerle ilgilidir. /ToUnicode’u zaten eksik
ya da yanlış olan keyfi gelen PDF’ler için bir onarım aracı değildir; bunlardan
metin kurtarmak ayrı, sezgisel bir sorundur. Ve sadık çıkarma, erişilebilirlik
için gereklidir ama onun tamamı değildir — okuma sırası, etiketler ve alternatif
metin, Bir PDF’i erişilebilir kılan
nedir bölümünde ele alınır.
Mini SSS
“Mini SSS” başlıklı bölümAynı PDF neden bir okuyucuda iyi, başka bir okuyucuda kötü kopyalanır?
Farklı okuyucular, /ToUnicode eksik olduğunda farklı geri çekilir. Bazıları
yazı tipinin yerleşik kodlamasından tahmin eder ve yaygın Latin metinde şansı
yaver gider; bazıları gitmez. Doğru bir /ToUnicode, piyangoyu ortadan kaldırır
— uyumlu her okuyucu aynı karakterleri alır.
Bu, yazı tipinin gömülü olmamasıyla aynı şey mi?
Hayır. Gömme, görünümle ilgilidir — glif, yazı tipi kurulu olmadan boyanır mı.
/ToUnicode ise anlamla ilgilidir — kod bir karaktere geri eşlenir mi. Bir
yazı tipi kusursuz gömülü olup yine de kullanılabilir bir /ToUnicode’a sahip
olmayabilir; aranamaz-ama-güzel başarısızlığı budur.
Çıkarma hiç kod başına birden fazla karaktere ihtiyaç duyar mı?
Evet — bitişik harf durumu tam olarak budur: bir kod, iki karaktere eşlenir. Bir
/ToUnicode girdisi, tek bir kodu kısa bir diziye eşleyebilir; bitişik harfler ve
bazı bileşik biçimler bu sayede kendi bileşen harfleri olarak geri gelir.
İlgili belgeler
“İlgili belgeler” başlıklı bölüm- Yazı tipleri: en zor kısım — görünüm tarafındaki tamamlayıcı parça: gömme, alt kümeleme ve kodlamanın nasıl oluşturulduğu. Bu sayfa, aynı madalyonun anlam tarafıdır.
- Bir PDF’i erişilebilir kılan nedir — sadık metin bileşenlerden biridir; okuma sırası, etiketler ve alternatif metin geri kalanıdır.
- Bir PDF gerçekte nedir — yazı tiplerinin,
kodlamaların ve
/ToUnicodeakışlarının içinde yaşadığı nesne modeli.
Sözlük
“Sözlük” başlıklı bölüm- Glif — bir yazı tipindeki görsel bir şekil (bir anahat). Bir PDF’in gerçekte boyadığı şey. Bir glifin bir dizini vardır ama kendinde bir karakter anlamı yoktur.
- Karakter — bir Unicode kod noktasıyla tanımlanan bir yazı dili birimi. Kastettiğiniz şey ve çıkarmanın kurtarmaya çalıştığı şey.
- Kod — bir içerik akışında, geçerli yazı tipinden bir glif seçen sayısal değer. Bir Unicode karakteri değildir; yalnızca yazı tipine göre anlamlıdır.
- CID — büyük bir küme içinde bir glifi adreslemek için bir birleşik yazı tipinin kullandığı bir karakter tanımlayıcı; kod ile glif arasındaki bir ara adım.
- Birleşik (Type 0) yazı tipi — bir yazı tipinin binlerce glifi adreslemesi gerektiğinde kullanılan, çok baytlı kodları bir CMap aracılığıyla okuyup CID’lere ve gliflere ulaşan bir yazı tipi.
/ToUnicode— bir belgenin kullandığı kodları Unicode değerlerine geri eşleyen CMap akışı; PDF metnini aranabilir, kopyalanabilir ve erişilebilir kılan şey.- Bitişik harf — iki veya daha fazla harfi tek bir şekil olarak çizen tek bir
glif (örneğin
fi);/ToUnicodegirdisi onu karakterlerine geri ayrıştırır.