Mengapa teks dalam sebuah PDF bukan benar-benar teks
Sekilas
Bagian berjudul “Sekilas”Ketika Anda membaca sebuah PDF, Anda melihat kata-kata. Berkas itu tidak memuat kata-kata. Ia memuat instruksi untuk menggambar bentuk pada koordinat, dan bentuk-bentuk itu kebetulan tampak seperti huruf. Celah antara apa yang digambar sebuah PDF dan apa yang dimaksudkannya adalah alasan sebuah halaman bisa tampak sempurna namun tetap tersalin sebagai omong kosong. Halaman ini membahas celah itu, dan tentang peta kecil dan terpisah yang menutupnya.
Mengapa ini penting
Bagian berjudul “Mengapa ini penting”Segala yang Anda lakukan pada sebuah PDF sebagai teks — menyeleksinya,
menyalinnya, mencarinya, mengindeksnya untuk pengambilan, membacakannya dengan
screen reader — bergantung pada pemulihan karakter yang tidak pernah disimpan
secara langsung oleh berkas. Jika pemulihan itu gagal, kegagalannya tak terlihat.
Halaman tetap dirender. Tidak ada yang menyadarinya sampai seseorang menyalin
sebuah paragraf ke dalam email dan mendapatkan □□□□, atau mencari sebuah klausa
yang jelas-jelas ada dalam kontrak 400 halaman dan tidak menemukan apa-apa.
Itu adalah kelas bug yang mahal justru karena ia lolos dari setiap peninjauan visual. Tidak ada yang bisa dilihat. Dokumen itu tampak otoritatif dan, untuk keperluan mesin, bisu.
Versi singkatnya
Bagian berjudul “Versi singkatnya”- Sebuah PDF menggambar glyph — bentuk visual yang dipilih oleh kode numerik ke dalam sebuah font — bukan karakter Unicode.
- Bentuk yang sama dapat berarti karakter yang berbeda, dan karakter yang sama dapat digambar oleh glyph yang berbeda. Tampilan dan makna sengaja dipisahkan.
- Untuk mengeluarkan teks kembali, sebuah reader menjalankan jalur penggambaran
secara terbalik: kode ke karakter. CMap
/ToUnicodefont adalah tabel pencarian untuk langkah balik itu (Spec: ISO 32000-2, §9.10ISO 32000-2 §9.10). - Tanpa
/ToUnicode, atau dengan yang salah, salin-tempel menjadi kacau dan pencarian gagal — sementara halaman tetap sempurna piksel demi piksel. - Ini adalah persoalan makna. Apakah glyph tampak benar adalah persoalan
tampilan yang terpisah, yang dibahas di
Font: bagian yang sulit. NextPDF
menghasilkan
/ToUnicodeyang benar sehingga perjalanan bolak-baliknya setia.
Bagaimana NextPDF menanganinya
Bagian berjudul “Bagaimana NextPDF menanganinya”Mulailah dari bagaimana teks sampai ke halaman sama sekali. Sebuah content stream
tidak mengatakan “tulis kata file.” Ia memilih sebuah font, lalu menyerahkan
sederet kode ke sebuah text-showing operator (Spec: ISO 32000-2, §9ISO 32000-2 §9). Setiap
kode adalah sebuah indeks — sebuah posisi dalam program font — dan font mengubah
indeks itu menjadi outline glyph dan menggambarnya. Kode 70 bukan karakter F.
Ia adalah “slot 70 dalam font ini,” dan slot 70 kebetulan berisi sebuah kurva
berbentuk F. Pilih font yang berbeda dan slot 70 bisa jadi adalah kepingan
salju.
Jadi sebuah kode hanya bermakna relatif terhadap encoding fontnya. Untuk font sederhana, encoding itu kira-kira satu byte per glyph. Untuk aksara yang membutuhkan ribuan glyph — CJK, atau dokumen full-Unicode mana pun — itu tidak cukup ruang, dan PDF beralih ke composite (Type 0) font (Spec: ISO 32000-2, §9.7ISO 32000-2 §9.7). Sebuah composite font membaca kode multi-byte melalui sebuah CMap, mengubahnya menjadi CID (character identifier), dan memetakan CID ke glyph. Itu adalah indireksi elegan yang memungkinkan satu font mengalamati himpunan glyph yang sangat besar. Itu juga satu tempat lagi di mana jejak dari “apa yang ditampilkan” ke “apa yang dimaksudkan” bisa menjadi buntu.
Sekarang jalankan secara terbalik. Untuk mengekstrak teks, sebuah reader mengambil kode yang ditemukannya dalam content stream dan harus memulihkan karakter (Spec: ISO 32000-2, §9.10ISO 32000-2 §9.10). Encoding yang menggambar glyph berjalan karakter ke glyph; ekstraksi membutuhkan kode glyph ke karakter, dan arah itu tidak dijamin dapat dibalik. Sebuah subset font mungkin telah menomori ulang glyph-nya. CID sebuah composite font mungkin bersifat privat. Bentuk di halaman tidak membawa makna Unicode yang melekat.
Solusinya adalah mengirim peta balik bersama font. Peta itu adalah CMap
/ToUnicode: untuk setiap kode yang digunakan dokumen, ia mencatat nilai
Unicode (atau nilai-nilai) yang diwakili kode tersebut. Dengannya, ekstraksi
menjadi pencarian yang bersih. Tanpanya, sebuah reader terpaksa menebak dari
encoding font dan heuristik — dan menebak adalah persis tempat di mana fi
menjadi tanda tanya.
- 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 menuliskan peta balik itu sebagai hal yang lumrah. Ketika ia menyematkan
sebuah composite font, ia menghasilkan turunan CIDFontType2, induk Type0, dan
sebuah CMap /ToUnicode sehingga kode dipetakan kembali ke Unicode — pekerjaan
encoding yang dijelaskan di Font: bagian yang sulit. Hal
yang patut dibedakan di sini adalah mengapa: stream /ToUnicode bukan tentang
membuat halaman tampak benar. Glyph-nya sudah tampak benar tanpanya. Ia adalah
satu-satunya artefak yang menjaga teks tetap dapat diekstrak.
Contoh praktis
Bagian berjudul “Contoh praktis”Tempat paling terkenal di mana ini muncul adalah ligatur fi. Banyak font
menggambar f dan i sebagai satu glyph gabungan, karena titik pada i
bertabrakan dengan kait pada f. Di halaman, ia adalah satu bentuk, digambar
oleh satu kode. Pertanyaannya adalah apa yang terjadi ketika Anda menyalinnya.
% 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'endbfcharSatu entri itu adalah perbedaan antara pencarian “file” yang cocok dan pencarian
“file” yang diam-diam meleset dari setiap kemunculan yang dirender dengan
ligatur. Petakan kode ligatur ke urutan dua karakter f + i, dan kata itu
dapat dicari dan disalin. Biarkan ia tak terpetakan, dan halaman tetap menampilkan
file dengan sempurna sementara teksnya diam-diam tidak menyatakan apa pun yang
dapat dibaca mesin.
Inilah mengapa “fi” bisa terekstrak sebagai satu karakter atau dua, dan mengapa
perbedaannya bukan acak — ia adalah apa pun yang diperintahkan untuk dinyatakan
oleh peta /ToUnicode. Sebuah peta yang benar menguraikan ligatur kembali
menjadi karakter-karakternya. NextPDF menghasilkan persis entri jenis itu,
sehingga sebuah ligatur di halaman menjadi dua huruf biasa di clipboard.
Kesalahpahaman umum
Bagian berjudul “Kesalahpahaman umum”Jebakannya, dinamai: “teksnya dirender, jadi teksnya baik-baik saja.”
Rendering dan ekstraksi adalah mekanisme berbeda yang membaca data berbeda.
Rendering mengikuti jalur kode-ke-glyph dan itulah yang diperiksa mata Anda.
Ekstraksi mengikuti jalur kode-ke-karakter melalui /ToUnicode dan itulah yang
diperiksa setiap konsumen mesin. Sebuah dokumen bisa unggul pada yang pertama dan
gagal total pada yang kedua, karena secara konstruksi tidak ada apa pun secara
visual yang mengungkapnya.
Jebakan kedua yang lebih halus: mengasumsikan sebuah glyph “jelas-jelas” tahu ia karakter yang mana. Ia tidak tahu. Sebuah glyph adalah bentuk dengan sebuah indeks. Pemetaan kembali ke sebuah karakter adalah informasi tambahan yang harus disediakan penghasilnya. Jika penghasil tidak pernah menuliskannya, tidak ada reader yang dapat memulihkannya dengan setia — ia hanya bisa menebak.
Batas dan ruang lingkup
Bagian berjudul “Batas dan ruang lingkup”| Edition | Availability |
|---|---|
| Core | NextPDF emits a correct /ToUnicode CMap for the fonts it embeds, including the ligature and composite-font cases, so the documents it produces are searchable and copyable. |
| Pro | Not in this edition |
| Enterprise | Not in this edition |
Sebuah peta /ToUnicode hanya dapat membawa informasi yang memang diekspos oleh
font sumber. Di mana sebuah glyph tidak memiliki karakter yang dapat ditentukan —
sebuah tanda murni dekoratif, sebuah simbol private-use tanpa penetapan Unicode —
tidak ada peta yang dapat menciptakan makna yang sejak awal tidak ada. NextPDF
menghasilkan pemetaan yang jujur yang dapat diturunkannya; ia tidak mengarang
karakter untuk mengisi sebuah celah.
Halaman ini membahas dokumen yang ditulis NextPDF. Ia bukan alat perbaikan
untuk PDF masukan sembarang yang /ToUnicode-nya sudah hilang atau salah;
memulihkan teks dari yang seperti itu adalah persoalan heuristik yang terpisah.
Dan ekstraksi yang setia memang perlu untuk aksesibilitas namun bukan
keseluruhannya — urutan baca, tag, dan teks alternatif dibahas di
Apa yang membuat sebuah PDF dapat diakses.
Mini-FAQ
Bagian berjudul “Mini-FAQ”Mengapa PDF yang sama tersalin baik di satu reader dan buruk di reader lain?
Reader yang berbeda melakukan fallback secara berbeda ketika /ToUnicode hilang.
Sebagian menebak dari encoding bawaan font dan beruntung pada teks Latin umum;
sebagian lain tidak. Sebuah /ToUnicode yang benar menghilangkan undian itu —
setiap reader yang konforman mendapatkan karakter yang sama.
Apakah ini hal yang sama dengan font yang tidak disematkan?
Tidak. Penyematan adalah tentang tampilan — apakah glyph tergambar tanpa font
terpasang. /ToUnicode adalah tentang makna — apakah kode dipetakan kembali ke
sebuah karakter. Sebuah font bisa tersemat dengan sempurna namun tetap tidak
memiliki /ToUnicode yang dapat dipakai, yang merupakan kegagalan tak-dapat-dicari-tetapi-cantik.
Apakah ekstraksi pernah membutuhkan lebih dari satu karakter per kode?
Ya — kasus ligatur adalah persis itu: satu kode dipetakan ke dua karakter. Sebuah
entri /ToUnicode dapat memetakan satu kode ke sebuah urutan pendek, dan itulah
cara ligatur, serta sebagian bentuk komposit, kembali sebagai huruf-huruf
penyusunnya.
Dokumen terkait
Bagian berjudul “Dokumen terkait”- Font: bagian yang sulit — bagian pendamping di sisi tampilan: penyematan, subsetting, dan bagaimana encoding dibangun. Halaman ini adalah sisi makna dari koin yang sama.
- Apa yang membuat sebuah PDF dapat diakses — teks yang setia adalah satu bahan; urutan baca, tag, dan teks alt adalah selebihnya.
- Apa sebenarnya PDF itu — model objek
tempat font, encoding, dan stream
/ToUnicodeini berada.
Glosarium
Bagian berjudul “Glosarium”- Glyph — sebuah bentuk visual dalam sebuah font (sebuah outline). Apa yang sebenarnya digambar sebuah PDF. Sebuah glyph memiliki indeks tetapi tidak ada makna karakter yang melekat.
- Karakter — sebuah unit bahasa tertulis, diidentifikasi oleh sebuah code point Unicode. Apa yang Anda maksudkan, dan apa yang coba dipulihkan ekstraksi.
- Kode — nilai numerik dalam sebuah content stream yang memilih sebuah glyph dari font saat ini. Bukan karakter Unicode; bermakna hanya relatif terhadap fontnya.
- CID — sebuah character identifier yang digunakan oleh composite font untuk mengalamati sebuah glyph dalam himpunan besar; sebuah langkah antara antara kode dan glyph.
- Composite (Type 0) font — sebuah font yang membaca kode multi-byte melalui sebuah CMap untuk mencapai CID dan glyph, digunakan ketika satu font harus mengalamati ribuan glyph.
/ToUnicode— stream CMap yang memetakan kode yang digunakan sebuah dokumen kembali ke nilai Unicode; yang membuat teks PDF dapat dicari, disalin, dan diakses.- Ligatur — sebuah glyph tunggal yang menggambar dua huruf atau lebih sebagai
satu bentuk (misalnya
fi); entri/ToUnicode-nya menguraikannya kembali menjadi karakter-karakternya.