Perché il testo in un PDF non è davvero testo
In breve
Sezione intitolata “In breve”Quando leggi un PDF, vedi parole. Il file non contiene parole. Contiene istruzioni per dipingere forme a delle coordinate, e le forme capita che assomiglino a lettere. Il divario tra ciò che un PDF disegna e ciò che significa è il motivo per cui una pagina può apparire impeccabile e comunque copiarsi come una sequenza priva di senso. Questa pagina parla di quel divario, e della piccola mappa separata che lo colma.
Perché è importante
Sezione intitolata “Perché è importante”Tutto ciò che fai a un PDF in quanto testo — selezionarlo, copiarlo, cercarlo,
indicizzarlo per il recupero, leggerlo ad alta voce con uno screen reader —
dipende dal recuperare caratteri che il file non ha mai memorizzato
direttamente. Se quel recupero fallisce, il fallimento è invisibile. La pagina si
renderizza comunque. Nessuno se ne accorge finché qualcuno non copia un paragrafo
in un’email e ottiene □□□□, o cerca in un contratto di 400 pagine una clausola
che è palesemente lì e non trova nulla.
È una classe di bug costosa proprio perché sopravvive a ogni revisione visiva. Non c’è niente da vedere. Il documento appare autorevole ed è, ai fini delle macchine, muto.
La versione breve
Sezione intitolata “La versione breve”- Un PDF disegna glifi — forme visive scelte da codici numerici dentro un font — non caratteri Unicode.
- La stessa forma può significare caratteri diversi, e lo stesso carattere può essere disegnato da glifi diversi. Apparenza e significato sono disaccoppiati per progettazione.
- Per riottenere il testo, un lettore esegue il percorso di disegno al
contrario: da codice a carattere. La CMap
/ToUnicodedel font è la tabella di ricerca per quel passo inverso (Spec: ISO 32000-2, §9.10ISO 32000-2 §9.10). - Nessuna
/ToUnicode, o una sbagliata, significa copia-incolla illeggibile e ricerca fallita — con la pagina comunque perfetta al pixel. - Questo è il problema del significato. Se il glifo abbia l’aspetto giusto è il
problema separato dell’apparenza trattato in
Fonts: the hard part. NextPDF emette una
/ToUnicodecorretta affinché l’andata e ritorno sia fedele.
Come NextPDF lo affronta
Sezione intitolata “Come NextPDF lo affronta”Parti da come il testo finisce sulla pagina, anzitutto. Un content stream non
dice «scrivi la parola file». Seleziona un font, poi consegna una stringa di
codici a un operatore di visualizzazione del testo
(Spec: ISO 32000-2, §9ISO 32000-2 §9). Ogni codice è un indice — una
posizione in un programma di font — e il font trasforma quell’indice nel
contorno di un glifo e lo dipinge. Il codice 70 non è il carattere F. È
«slot 70 in questo font», e lo slot 70 capita che contenga una curva a forma di
F. Scegli un font diverso e lo slot 70 potrebbe essere un fiocco di neve.
Quindi un codice significa qualcosa solo rispetto alla codifica del suo font. Per un font semplice quella codifica è all’incirca un byte per glifo. Per le scritture che hanno bisogno di migliaia di glifi — CJK, o qualunque documento a Unicode completo — non c’è spazio a sufficienza, e il PDF ricorre a un font composito (Type 0) (Spec: ISO 32000-2, §9.7ISO 32000-2 §9.7). Un font composito legge codici multi-byte attraverso una CMap, li trasforma in CID (identificatori di carattere) e mappa i CID ai glifi. È un’indirezione elegante che permette a un solo font di indirizzare un insieme di glifi enorme. È anche un posto in più in cui la traccia da «ciò che è mostrato» a «ciò che significa» può raffreddarsi.
Ora eseguilo al contrario. Per estrarre il testo, un lettore prende i codici che trova nel content stream e deve recuperare i caratteri (Spec: ISO 32000-2, §9.10ISO 32000-2 §9.10). La codifica che ha disegnato il glifo andava da carattere a glifo; l’estrazione ha bisogno del percorso da codice di glifo a carattere, e quella direzione non è garantita essere invertibile. Un font in sottoinsieme può aver rinumerato i suoi glifi. I CID di un font composito possono essere privati. La forma sulla pagina non porta con sé alcun significato Unicode intrinseco.
La soluzione è spedire la mappa inversa insieme al font. Quella mappa è la CMap
/ToUnicode: per ogni codice che il documento usa, registra il valore (o i
valori) Unicode per cui quel codice sta. Con essa, l’estrazione è una ricerca
pulita. Senza, un lettore è costretto a indovinare a partire dalle codifiche del
font e da euristiche — e indovinare è esattamente il punto in cui fi diventa un
punto interrogativo.
- I tuoi caratteriIl testo Unicode che imposti, per esempio la parola 'file'.
- Codifica → codiciLa codifica del font trasforma i caratteri in codici numerici; un font composito li instrada attraverso una CMap fino ai CID.
- Codici → glifiOgni codice seleziona il contorno di un glifo, che viene dipinto sulla pagina. È la parte che vedi.
- L'estrazione la inverteUn lettore rilegge i codici e cerca ciascuno in /ToUnicode per recuperare Unicode.
- Di nuovo testoCon una /ToUnicode corretta, copia, ricerca, indicizzazione e screen reader riottengono tutti i caratteri originali.
NextPDF scrive la mappa inversa come prassi. Quando incorpora un font composito
emette il discendente CIDFontType2, il genitore Type0 e una CMap
/ToUnicode affinché i codici si risolvano di nuovo in Unicode — il lavoro di
codifica descritto in
Fonts: the hard part. Il punto che vale la
pena separare qui è il perché: lo stream /ToUnicode non serve a far apparire
giusta la pagina. I glifi appaiono già giusti senza di esso. È il singolo
artefatto che mantiene il testo estraibile.
Esempio pratico
Sezione intitolata “Esempio pratico”Il posto più famoso in cui questo emerge è la legatura fi. Molti font
disegnano f e i come un unico glifo combinato, perché il puntino della i
collide con l’uncino della f. Sulla pagina è una sola forma, disegnata da un
solo codice. La domanda è cosa succede quando la copi.
% 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'endbfcharQuella singola voce è la differenza tra una ricerca di «file» che corrisponde e
una ricerca di «file» che silenziosamente manca ogni occorrenza renderizzata con
la legatura. Mappa il codice della legatura alla sequenza di due caratteri f +
i, e la parola è ricercabile e copiabile. Lasciala non mappata, e la pagina
mostra comunque file alla perfezione mentre il testo dice in sordina nulla che
una macchina possa leggere.
Ecco perché «fi» può estrarsi come un carattere o due, e perché la differenza
non è casuale — è qualunque cosa alla mappa /ToUnicode sia stato detto di dire.
Una mappa corretta scompone la legatura nei suoi caratteri. NextPDF emette
esattamente quel tipo di voce, così che una legatura sulla pagina sia due
normali lettere negli appunti.
Equivoco frequente
Sezione intitolata “Equivoco frequente”La trappola, nominata: «il testo si renderizza, quindi il testo va bene».
Rendering ed estrazione sono meccanismi diversi che leggono dati diversi. Il
rendering segue il percorso da codice a glifo ed è ciò che i tuoi occhi
controllano. L’estrazione segue il percorso da codice a carattere attraverso
/ToUnicode ed è ciò che ogni consumatore macchina controlla. Un documento può
superare a pieni voti il primo e fallire completamente il secondo, perché per
costruzione non c’è nulla di visivo a rivelarlo.
Una seconda trappola, più sottile: presumere che un glifo «ovviamente» sappia quale carattere sia. Non lo sa. Un glifo è una forma con un indice. La mappatura verso un carattere è informazione aggiuntiva che il produttore deve fornire. Se il produttore non l’ha mai scritta, nessun lettore può recuperarla fedelmente — può solo indovinare.
Limiti e confini
Sezione intitolata “Limiti e confini”| Edition | Availability |
|---|---|
| Core | NextPDF emette una CMap /ToUnicode corretta per i font che incorpora, inclusi i casi della legatura e del font composito, così che i documenti che produce siano ricercabili e copiabili. |
| Pro | Not in this edition |
| Enterprise | Not in this edition |
Una mappa /ToUnicode può portare solo l’informazione che il font di origine
effettivamente espone. Dove un glifo non ha un carattere determinabile — un segno
puramente decorativo, un simbolo a uso privato senza assegnazione Unicode —
nessuna mappa può inventare un significato che non c’è mai stato. NextPDF emette
la mappatura veritiera che può derivare; non fabbrica caratteri per riempire un
vuoto.
Questa pagina riguarda i documenti che NextPDF scrive. Non è uno strumento di
riparazione per PDF in ingresso arbitrari la cui /ToUnicode è già assente o
sbagliata; recuperare il testo da quelli è un problema separato e euristico. E
l’estrazione fedele è necessaria per l’accessibilità ma non è il tutto — l’ordine
di lettura, i tag e il testo alternativo sono trattati in
What makes a PDF accessible.
Mini-FAQ
Sezione intitolata “Mini-FAQ”Perché lo stesso PDF si copia bene in un lettore e male in un altro?
Lettori diversi ripiegano diversamente quando /ToUnicode è assente. Alcuni
indovinano dalla codifica integrata del font e sono fortunati sul testo latino
comune; altri no. Una /ToUnicode corretta elimina la lotteria — ogni lettore
conforme ottiene gli stessi caratteri.
È la stessa cosa del font non incorporato?
No. L’incorporamento riguarda l’apparenza — se il glifo si dipinge senza il
font installato. /ToUnicode riguarda il significato — se il codice si rimappa
a un carattere. Un font può essere incorporato alla perfezione e avere comunque
una /ToUnicode inutilizzabile, che è il guasto pagina-bella-ma-non-cercabile.
L’estrazione ha mai bisogno di più di un carattere per codice?
Sì — il caso della legatura è esattamente questo: un codice si mappa a due
caratteri. Una voce /ToUnicode può mappare un singolo codice a una breve
sequenza, ed è così che le legature, e alcune forme composte, ritornano come le
loro lettere costituenti.
Documenti correlati
Sezione intitolata “Documenti correlati”- Fonts: the hard part — il pezzo complementare sul lato dell’apparenza: incorporamento, sottoinsieme e come la codifica viene costruita. Questa pagina è il lato del significato della stessa medaglia.
- What makes a PDF accessible — il testo fedele è un ingrediente; l’ordine di lettura, i tag e il testo alternativo sono il resto.
- What a PDF actually is — il modello a
oggetti dentro cui vivono i font, le codifiche e gli stream
/ToUnicode.
Glossario
Sezione intitolata “Glossario”- Glifo — una forma visiva in un font (un contorno). Ciò che un PDF effettivamente dipinge. Un glifo ha un indice ma nessun significato di carattere intrinseco.
- Carattere — un’unità di linguaggio scritto, identificata da un code point Unicode. Ciò che intendi, e ciò che l’estrazione cerca di recuperare.
- Codice — il valore numerico in un content stream che seleziona un glifo dal font corrente. Non un carattere Unicode; significativo solo rispetto al font.
- CID — un identificatore di carattere usato da un font composito per indirizzare un glifo dentro un grande insieme; un passo intermedio tra codice e glifo.
- Font composito (Type 0) — un font che legge codici multi-byte attraverso una CMap per raggiungere CID e glifi, usato quando un solo font deve indirizzare migliaia di glifi.
/ToUnicode— lo stream CMap che mappa i codici che un documento usa di nuovo a valori Unicode; ciò che rende il testo PDF ricercabile, copiabile e accessibile.- Legatura — un singolo glifo che disegna due o più lettere come un’unica
forma (per esempio
fi); la sua voce/ToUnicodela scompone nei suoi caratteri.