Pourquoi le texte d'un PDF n'est pas vraiment du texte
Quand tu lis un PDF, tu vois des mots. Le fichier ne contient pas de mots. Il contient des instructions pour peindre des formes à des coordonnées, et ces formes se trouvent ressembler à des lettres. L’écart entre ce qu’un PDF dessine et ce qu’il signifie est la raison pour laquelle une page peut paraître impeccable et pourtant se copier en charabia. Cette page traite de cet écart, et de la petite correspondance distincte qui le comble.
Pourquoi c’est important
Section intitulée « Pourquoi c’est important »Tout ce que tu fais d’un PDF en tant que texte — le sélectionner, le copier, le rechercher,
l’indexer pour la récupération, le lire à voix haute avec un lecteur d’écran — dépend de
la reconstitution de caractères que le fichier n’a jamais directement stockés. Si cette reconstitution
échoue, l’échec est invisible. La page s’affiche toujours. Personne ne s’en aperçoit
tant que quelqu’un ne copie pas un paragraphe dans un courriel et n’obtient □□□□, ou
ne cherche dans un contrat de 400 pages une clause qui s’y trouve manifestement et ne trouve rien.
C’est une catégorie de bogue coûteuse précisément parce qu’elle survit à tout contrôle visuel. Il n’y a rien à voir. Le document a l’air faisant autorité et est, du point de vue des machines, muet.
La version courte
Section intitulée « La version courte »- Un PDF dessine des glyphes — des formes visuelles choisies par des codes numériques dans une police — et non des caractères Unicode.
- La même forme peut signifier des caractères différents, et le même caractère peut être dessiné par des glyphes différents. Apparence et signification sont découplées par conception.
- Pour récupérer le texte, un lecteur parcourt le chemin d’affichage à l’envers : du code au
caractère. La CMap
/ToUnicodede la police est la table de correspondance de cette étape inverse (Spec: ISO 32000-2, §9.10ISO 32000-2 §9.10). - Pas de
/ToUnicode, ou une mauvaise, signifie copier-coller illisible et recherche infructueuse — avec la page toujours parfaite au pixel près. - C’est le problème de la signification. Savoir si le glyphe a la bonne apparence est le
problème distinct de l’apparence traité dans
Fonts: the hard part. NextPDF émet une
CMap
/ToUnicodecorrecte pour que l’aller-retour soit fidèle.
Comment NextPDF l’aborde
Section intitulée « Comment NextPDF l’aborde »Commence par la façon dont le texte arrive sur la page. Un flux de contenu ne dit pas
« écris le mot file. » Il sélectionne une police, puis transmet une chaîne de codes à
un opérateur d’affichage de texte (Spec: ISO 32000-2, §9ISO 32000-2 §9). Chaque
code est un index — une position dans un programme de police — et la police transforme cet index
en un contour de glyphe et le peint. Le code 70 n’est pas le caractère F. C’est
« l’emplacement 70 dans cette police », et l’emplacement 70 se trouve contenir une courbe en
forme de F. Choisis une autre police et l’emplacement 70 pourrait être un flocon de neige.
Un code ne signifie donc quelque chose que relativement à l’encodage de sa police. Pour une police simple, cet encodage est en gros d’un octet par glyphe. Pour les écritures qui nécessitent des milliers de glyphes — le CJK, ou tout document en Unicode complet — ce n’est pas assez de place, et le PDF recourt à une police composite (Type 0) (Spec: ISO 32000-2, §9.7ISO 32000-2 §9.7). Une police composite lit des codes multi-octets via une CMap, les transforme en CID (identifiants de caractères), et associe les CID à des glyphes. C’est une indirection élégante qui permet à une seule police d’adresser un ensemble de glyphes énorme. C’est aussi un endroit de plus où la piste de « ce qui est montré » vers « ce que cela signifie » peut se perdre.
Maintenant, exécute le processus à l’envers. Pour extraire le texte, un lecteur prend les codes qu’il trouve dans le flux de contenu et doit reconstituer des caractères (Spec: ISO 32000-2, §9.10ISO 32000-2 §9.10). L’encodage qui a dessiné le glyphe allait du caractère au glyphe ; l’extraction a besoin du code de glyphe au caractère, et cette direction n’est pas garantie inversible. Une police sous-ensemble peut avoir renuméroté ses glyphes. Les CID d’une police composite peuvent être privés. La forme sur la page ne porte aucune signification Unicode intrinsèque.
Le remède est de livrer la correspondance inverse aux côtés de la police. Cette correspondance est la
CMap /ToUnicode : pour chaque code que le document utilise, elle consigne la valeur
Unicode (ou les valeurs) que ce code représente. Avec elle, l’extraction est une simple recherche.
Sans elle, un lecteur en est réduit à deviner à partir des encodages de police et d’heuristiques — et
deviner est exactement là où fi devient un point d’interrogation.
- 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 écrit la correspondance inverse par principe. Lorsqu’il intègre une
police composite, il émet le descendant CIDFontType2, le parent Type0, et
une CMap /ToUnicode pour que les codes se résolvent à nouveau en Unicode — le travail d’encodage
décrit dans Fonts: the hard part. Le
point qu’il vaut la peine de distinguer ici, c’est le pourquoi : le flux /ToUnicode ne sert pas à
donner la bonne apparence à la page. Les glyphes ont déjà la bonne apparence sans lui. C’est l’
unique artefact qui maintient le texte extractible.
Exemple concret
Section intitulée « Exemple concret »L’endroit le plus célèbre où cela apparaît est la ligature fi. Beaucoup de polices dessinent
f et i comme un seul glyphe combiné, parce que le point du i entre en collision avec le
crochet du f. Sur la page, c’est une seule forme, dessinée par un seul code. La question
est de savoir ce qui se passe quand tu la copies.
% 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'endbfcharCette unique entrée fait la différence entre une recherche de « file » qui aboutit et une
recherche de « file » qui manque silencieusement chaque occurrence rendue avec la ligature.
Associe le code de la ligature à la séquence de deux caractères f + i, et le mot est
recherchable et copiable. Laisse-le non associé, et la page affiche toujours file
parfaitement tandis que le texte ne dit discrètement rien qu’une machine puisse lire.
C’est pourquoi « fi » peut s’extraire en un caractère ou deux, et pourquoi la différence n’est
pas aléatoire — c’est ce que la correspondance /ToUnicode a reçu l’ordre de dire. Une correspondance correcte
décompose la ligature en ses caractères. NextPDF émet exactement ce
genre d’entrée, si bien qu’une ligature sur la page devient deux lettres ordinaires dans le
presse-papiers.
Idée fausse courante
Section intitulée « Idée fausse courante »Le piège, nommé : « le texte s’affiche, donc le texte est bon. » Le rendu et
l’extraction sont des mécanismes différents lisant des données différentes. Le rendu suit le
chemin code-vers-glyphe et c’est ce que tes yeux vérifient. L’extraction suit le
chemin code-vers-caractère via /ToUnicode et c’est ce que vérifie tout consommateur
machine. Un document peut réussir le premier haut la main et échouer complètement au second, parce que
par construction il n’y a rien de visuel pour le révéler.
Un second piège, plus subtil : supposer qu’un glyphe « sait évidemment » quel caractère il est. Ce n’est pas le cas. Un glyphe est une forme avec un index. La correspondance vers un caractère est une information supplémentaire que le producteur doit fournir. Si le producteur ne l’a jamais écrite, aucun lecteur ne peut la reconstituer fidèlement — il ne peut que deviner.
Limites et frontières
Section intitulée « Limites et frontières »| 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 |
Une correspondance /ToUnicode ne peut transporter que l’information que la police source expose réellement.
Là où un glyphe n’a aucun caractère déterminable — une marque purement décorative, un
symbole à usage privé sans attribution Unicode — aucune correspondance ne peut inventer une signification qui
n’a jamais été là. NextPDF émet la correspondance véridique qu’il peut dériver ; il ne
fabrique pas de caractères pour combler un vide.
Cette page traite des documents que NextPDF écrit. Ce n’est pas un outil de réparation pour
des PDF entrants arbitraires dont le /ToUnicode est déjà absent ou erroné ; récupérer le
texte de ceux-là est un problème distinct, heuristique. Et une extraction fidèle est
nécessaire pour l’accessibilité, mais n’en est pas la totalité — l’ordre de lecture, les balises,
et le texte de remplacement sont traités dans
What makes a PDF accessible.
Mini-FAQ
Section intitulée « Mini-FAQ »Pourquoi le même PDF se copie-t-il bien dans un lecteur et mal dans un autre ?
Les différents lecteurs se rabattent différemment lorsque /ToUnicode est absent. Certains devinent
à partir de l’encodage intégré de la police et tombent juste sur du texte latin courant ; d’autres
non. Un /ToUnicode correct supprime la loterie — chaque lecteur conforme obtient
les mêmes caractères.
Est-ce la même chose que la police non intégrée ?
Non. L’intégration concerne l’apparence — si le glyphe se peint sans la police
installée. /ToUnicode concerne la signification — si le code se ramène à un
caractère. Une police peut être parfaitement intégrée et n’avoir tout de même aucun
/ToUnicode exploitable, ce qui est l’échec joli-mais-non-recherchable.
L’extraction a-t-elle parfois besoin de plus d’un caractère par code ?
Oui — le cas de la ligature en est exactement un : un code correspond à deux caractères. Une
entrée /ToUnicode peut associer un seul code à une courte séquence, et c’est ainsi que les
ligatures, et certaines formes composées, reviennent sous la forme de leurs lettres constitutives.
Documentation associée
Section intitulée « Documentation associée »- Fonts: the hard part — la pièce compagne sur le versant de l’apparence : intégration, sous-ensemble, et comment l’encodage est construit. Cette page est le versant de la signification de la même pièce de monnaie.
- What makes a PDF accessible — un texte fidèle est un ingrédient ; l’ordre de lecture, les balises et le texte alternatif sont le reste.
- What a PDF actually is — le modèle
d’objets dans lequel vivent les polices, les encodages et les flux
/ToUnicode.
Glossaire
Section intitulée « Glossaire »- Glyphe — une forme visuelle dans une police (un contour). Ce qu’un PDF peint réellement. Un glyphe a un index mais aucune signification de caractère intrinsèque.
- Caractère — une unité de langage écrit, identifiée par un point de code Unicode. Ce que tu veux dire, et ce que l’extraction tente de reconstituer.
- Code — la valeur numérique dans un flux de contenu qui sélectionne un glyphe dans la police courante. Pas un caractère Unicode ; significative uniquement relativement à la police.
- CID — un identifiant de caractère utilisé par une police composite pour adresser un glyphe au sein d’un grand ensemble ; une étape intermédiaire entre le code et le glyphe.
- Police composite (Type 0) — une police qui lit des codes multi-octets via une CMap pour atteindre des CID et des glyphes, utilisée quand une police doit adresser des milliers de glyphes.
/ToUnicode— le flux CMap qui associe les codes qu’un document utilise aux valeurs Unicode ; ce qui rend le texte PDF recherchable, copiable et accessible.- Ligature — un glyphe unique qui dessine deux lettres ou plus comme une seule forme (par
exemple
fi) ; son entrée/ToUnicodela décompose en ses caractères.