Outils de polices

Les consignes de soumission exigent que « toutes les polices soient incorporées », et vous ignorez si votre PDF s’y conforme. Un passage censé être en italique refuse de pencher. Vous avez écrit Numbers=OldStyle dans fontspec et rien n’a bougé. Ce qui tranche ces situations, ce n’est pas l’intuition mais les outils d’inspection. Cette page aligne les utilitaires de vérification de fontes autour de LaTeX, chacun avec une sortie réellement relevée : pdffonts, fc-list, otfinfo, \fontname\font, nfssfont pour imprimer une table de glyphes, et vftovp pour ouvrir une police virtuelle (.vf) en texte lisible. Au passage, on décode pourquoi une fonte TeX s’appelle phvbc8t.

Quelle fonte au juste ? \fontname et \showthe\font

En n’importe quel point d’un document, \fontname\font répond par le nom de fichier réel et \showthe\font par les cinq coordonnées NFSS. Le premier renvoie le nom de la métrique que TeX a effectivement chargéecmr10, cmbx10, cmti10 — et le second inscrit > \OT1/cmr/m/n/10 . dans le journal. Les deux ne se contredisent jamais : le second est la demande, le premier le résultat. En regardant les deux, on voit d’un coup d’œil si la fonte demandée est bien arrivée ou si une substitution a eu lieu en chemin.

log
% \typeout{fontname = \fontname\font} in a default article
fontname = cmr10
bf fontname = cmbx10
it fontname = cmti10

% \showthe\font stops the run and prints the NFSS name
> \OT1/cmr/m/n/10 .

% \showfont is NOT a LaTeX command; it belongs to ConTeXt.
% In LaTeX it fails with:
! Undefined control sequence.

Une correction s’impose ici. \showfont n’est pas une commande LaTeX. On la cite souvent comme moyen d’afficher la fonte courante, mais elle n’existe ni dans le noyau LaTeX2e ni dans aucun paquet, et son exécution donne ! Undefined control sequence. (ConTeXt possède une commande de ce nom). Pour faire la même chose en LaTeX, ajoutez aux deux moyens ci-dessus la lecture directe des macros internes : dans \makeatletter, \f@encoding, \f@family, \f@series, \f@shape et \f@size permettent de \typeout les cinq coordonnées au format de votre choix.

Pour suivre le chargement des fontes lui-même, il y a le paquet tracefnt. Avec \tracingfonts=2, à chaque chargement d’une fonte réelle le journal note quelle fonte externe a été chargée sous quel nom NFSS. Pour remonter à l’origine d’une substitution, c’est plus instructif que l’avertissement. La sortie est toutefois volumineuse : en pratique, on extrait d’abord la \section fautive dans un document minimal.

log
% \usepackage{tracefnt} + \tracingfonts=2, document set in T1
LaTeX Font Info:    External font `ecbx1000 at10.0pt' loaded as
(Font)              T1/cmr/bx/n/10  on input line 6.
LaTeX Font Info:    External font `ecti1000 at10.0pt' loaded as
(Font)              T1/cmr/m/it/10  on input line 6.

Vérifier les polices incorporées au PDF — pdffonts

pdffonts (fourni avec Poppler et Xpdf) dresse le tableau des polices présentes dans un PDF fini, de leur format et de leur incorporation — une ligne par police. Trois colonnes comptent : emb pour l’incorporation, sub pour le sous-ensemble (seuls les glyphes réellement utilisés ont été conservés) et uni pour la correspondance inverse vers Unicode (peut-on copier le texte depuis le PDF). La vérification avant soumission tient à cette seule commande ; si toute la colonne emb affiche yes, aucun comité ne renverra le fichier pour polices non incorporées.

terminal
# a document compiled with pdfLaTeX and \usepackage[T1]{fontenc}
$ pdffonts pf.pdf
name                                 type              encoding         emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
OSZFFG+SFRM1000                      Type 1            Custom           yes yes yes      4  0
PCDLRW+SFBX1000                      Type 1            Custom           yes yes yes      5  0
IEKZWO+SFTI1000                      Type 1            Custom           yes yes yes      6  0
GFIBPT+CMMI10                        Type 1            Builtin          yes yes yes      8  0

# the same document via XeLaTeX + fontspec with an OpenType face
$ pdffonts pfx.pdf
PPMQXL+TeXGyrePagella-Regular-Identity-H CID Type 0C   Identity-H       yes yes yes      4  0
AXDTQU+TeXGyrePagella-Bold-Identity-H    CID Type 0C   Identity-H       yes yes yes      6  0

Cette sortie fait aussi office d’empreinte du moteur. pdfLaTeX incorpore des fontes Type 1 avec des encodages Custom ou Builtin, tandis que XeLaTeX et LuaLaTeX pilotant une fonte OpenType via fontspec produisent CID Type 0C et Identity-H — de quoi deviner avec quoi a été fabriqué un PDF reçu. Les six lettres préfixées à chaque nom (OSZFFG+ et consorts) sont des étiquettes de sous-ensemble ; sous-ensemblez deux fois la même fonte et vous obtenez deux préfixes distincts. À l’inverse, une ligne dont emb vaut no signifie que cette fonte est laissée à la machine du lecteur — sans gravité pour les quatorze fontes PostScript standard, mais rédhibitoire à la soumission.

Savoir quelles polices possède le système — fc-list et otfinfo

Le nom que l’on passe à fontspec doit être le nom propre de la fonte ; en inventer un ne marche pas. Pour lister ce qui est installé, avec la correspondance noms/fichiers, il y a fc-list (partie de fontconfig). Sans argument il affiche tout, fc-list : family seulement les noms de famille, un motif restreint la liste. Du côté LuaTeX, l’équivalent est luaotfload-tool : --find résout un nom, --update reconstruit la base des noms de fontes. À noter : fontconfig est standard sous Linux mais n’est pas installé par défaut sous macOS — on l’ajoute à part, par Homebrew ou équivalent.

terminal
# every installed font, one line each (this machine reports 2799 lines)
$ fc-list | wc -l
2799

# narrow to one family: file, then all its names, then the style
$ fc-list "Hiragino Mincho ProN" file family style
/System/Library/Fonts/HiraginoMinchoProN.ttc: Hiragino Mincho ProN,\
  Hiragino Mincho ProN W6:style=W6,Regular

# what would fontconfig pick for a generic request?
$ fc-match sans
Verdana.ttf: "Verdana" "Regular"

Ce qu’une fonte sait réellement faire relève d’otfinfo (issu de lcdf-typetools, fourni avec TeX Live). -i donne noms, version et copyright ; -f liste les balises de fonctionnalités OpenType ; -s les écritures et langues prises en charge ; -t les tables. C’est -f qui a le plus de valeur pratique : vérifier ici la présence de onum ou de smcp avant d’écrire Numbers=OldStyle ou Letters=SmallCaps dans fontspec évite l’essentiel des cas « je l’ai écrit et rien ne se passe ». Nommer une fonctionnalité que la fonte n’a pas est tout simplement ignoré, en silence.

terminal
$ otfinfo -i $(kpsewhich texgyrepagella-regular.otf)
Family:              TeX Gyre Pagella
Subfamily:           Regular
PostScript name:     TeXGyrePagella-Regular
Version:             Version 2.501;PS 2.501;ffdkm 0.1
Copyright:           Copyright 2006-2018 for TeX Gyre extensions by B. Jackowski,
                     J.M. Nowacki, et al. Vietnamese characters were added by Han The Thanh.

$ otfinfo -f $(kpsewhich texgyrepagella-regular.otf)
c2sc	Small Capitals From Capitals
dlig	Discretionary Ligatures
kern	Kerning
liga	Standard Ligatures
lnum	Lining Figures
onum	Oldstyle Figures
size	Optical Size
smcp	Small Capitals
ss01	Stylistic Set 1

Cette sortie -i conserve aussi un petit lien. Les caractères vietnamiens de TeX Gyre Pagella ont été ajoutés par Hàn Thế Thành — l’auteur de pdfTeX, celui dont la thèse a apporté la microtypographie à TeX, sujet de la page microtype de ce site. Les mentions de copyright des fontes gardent plus d’histoire qu’on ne croit.

Imprimer tous les glyphes d’une fonte — nfssfont.tex et fonttable

Pour voir de ses propres yeux quels glyphes une fonte contient, on imprime une table de glyphes. L’outil interactif livré avec TeX depuis des décennies est nfssfont.tex : au lancement, il demande Input external font name, e.g., cmr10 ; répondez cmr10, tapez \table pour la table et \bye pour terminer. Une correction ici : l’invocation souvent reprise tex nfssfont ne fonctionne pas. La ligne 48 de nfssfont.tex est \documentclass{article} ; c’est un document LaTeX, et sous plain TeX il s’arrête sur ! Emergency stop. La bonne commande est latex nfssfont ou pdflatex nfssfont.

terminal
$ pdflatex nfssfont
Input external font name, e.g., cmr10
(or <enter> for NFSS classification of font): cmr10
Now type a test command or \help for help [ \table \bye ]: \table
...
Output written on nfssfont.pdf (1 page, 71803 bytes).

# \help lists the whole repertoire:
#   \init switches to another font;  \stop or \bye finishes the run;
#   \table prints the font layout in tabular format;
#   \text prints a sample text, assuming TeX text font conventions;
#   \sample combines \table and \text;
#   \lowers \uppers \digits \math \punct \names \bigtest ...

# Knuth's original is plain TeX and does start under tex:
$ tex testfont
Name of the font to test = cmr10
Now type a test command (\help for help): \table

Si le dialogue paraît fastidieux, le paquet fonttable fait la même chose depuis un document. \fonttable{cmr10} prend un nom de fonte (à proprement parler un nom de .tfm) et compose un tableau de tous les glyphes — \fonttable{pzdr} pour jeter un œil dans Zapf Dingbats ; \xfonttable{T1}{cmr}{m}{n} le spécifie via les quatre attributs NFSS. \fontrange{<low>}{<high>} restreint le tableau à des blocs de 16 glyphes, jusqu’à 256. Et si l’on veut un texte d’exemple composé dans la fonte plutôt qu’une grille, c’est \fonttext{cmr10}. Une bonne part du code du paquet est un nfssfont.tex remanié, et ses commandes de test réimplémentent le testfont.tex de Knuth — trois visages d’un même outil. Au passage : appuyer sur entrée à la première invite de nfssfont sans saisir de nom bascule vers la désignation de la fonte par ses cinq attributs NFSS.

Polices virtuelles (.vf) — une couche qui fabrique des glyphes inexistants

Une police virtuelle (.vf) est une couche qui traduit la fonte logique unique vue par TeX en glyphes réels et en opérations de composition de bas niveau. Selon la TeX FAQ, les polices virtuelles sont « a means of collecting bits and pieces together to make the glyphs of a font », ces morceaux venant d’autres fontes, de filets et de commandes de composition avec positionnement. Cela reste abstrait jusqu’à ce qu’on en ouvre une. Décortiquez le Times encodé en T1 (ptmr8t) avec vftovp et l’emplacement de la ligature ff dit : poser un f, reculer de 0,025 em, poser un autre f. Le Times brut n’a pas de glyphe ff : la police virtuelle la fabrique sur place.

terminal
$ vftovp $(kpsewhich ptmr8t.vf) $(kpsewhich ptmr8t.tfm) ptmr8t.vpl
$ head -5 ptmr8t.vpl
(VTITLE )
(FAMILY UNSPECIFIED)
(CODINGSCHEME EXTENDED TEX FONT ENCODING - LATIN)
(DESIGNSIZE R 10.0)
(MAPFONT D 0 (FONTNAME ptmr8r) ...)

# slot O 33 (octal) is the ff ligature of T1 - assembled from two f glyphs
(CHARACTER O 33
   (CHARWD R 0.640991)
   (CHARHT R 0.677991)
   (MAP
      (SETCHAR C f)
      (MOVERIGHT R -0.025)
      (SETCHAR C f)
      )
   )

Le mécanisme répartit le travail. TeX n’a besoin que des dimensions — largeur, hauteur, profondeur — qu’il lit dans le fichier compagnon .tfm (TeX Font Metric). La manière dont chaque glyphe est réellement dessiné réside dans le .vf, et c’est le pilote DVI qui le lit (dvips, dvipdfmx). Une police virtuelle est donc toujours une paire : un .tfm et un .vf. Les binaires étant illisibles, toute distribution fournit deux programmes de conversion vers et depuis le format lisible .vpl (Virtual Property List). Les métriques simples ont le même arrangement avec le format .pl (Property List) : ouvert avec tftopl, il livre les sept paramètres FONTDIMEN et la LIGTABLE des ligatures et crénages.

  • vftovp.vf + .tfm (binaire) → .vpl (texte). Ordre des arguments : police virtuelle, métrique, sortie. C’est l’outil pour démonter une police virtuelle existante.
  • vptovf.vpl (texte) → .vf + .tfm (binaire). Ordre des arguments : description, police virtuelle, métrique. Recompile une description modifiée.
  • tftopl / pltotf — le même aller-retour pour une métrique occidentale simple. À utiliser pour lire le contenu d’un .tfm (FONTDIMEN, LIGTABLE).
  • ppltotf / ptftopl — les équivalents japonais de la paire précédente, pour les JFM binaires de la famille pTeX.
  • Dans tous les cas l’extension peut être omise : .vf, .tfm et .vpl sont ajoutés automatiquement.

Placez le .tfm obtenu sous .../fonts/tfm/<supplier>/ et le .vf sous .../fonts/vf/<supplier>/ dans l’arbre texmf, rafraîchissez la base des noms avec mktexlsr, et kpsewhich ptmr8t.vf les trouvera. Les tables qui associent un nom de TFM au fichier de fonte réel — les font maps — sont gérées par updmap. Dans la pratique actuelle, personne n’écrit toutefois un .vpl à la main : produire métriques TeX et polices virtuelles à partir de fontes PostScript ou OpenType est l’affaire de fontinst. Une police virtuelle se lit et se retouche après génération plutôt qu’elle ne s’écrit de zéro.

Pourquoi les noms de fontes TeX ressemblent à des codes — texdoc fontname

La réponse : on ne disposait que de huit caractères. Le schéma Fontname, qu’ouvre texdoc fontname, ne cache pas la raison : il précise que les noms sont limités à huit caractères pour rester compatibles avec les systèmes de fichiers DOS et avec ISO 9660, la norme utilisée pour la distribution sur CD-ROM. Les caractères admis sont les minuscules a–z, les chiffres et le tiret bas. Ces huit caractères se répartissent en S TT W [V...] [N] [E] [DD] — fournisseur, œil, graisse, variantes, encodage, chasse, taille de dessin — et c’est tout le schéma.

Partie de phvbc8tPosition dans le schémaSignification
pfournisseur (S)Adobe — la note de supplier.map dit « p pour PostScript »
hvœil (TT)Helvetica (hv helvetic dans typeface.map)
bgraisse (W)gras (weight.map donne b Bold)
cchasse (E)étroit — côté NFSS, cela fusionne avec b en bc
8tencodage (N)variant.map porte 8t ECEncoding CorkEncoding — donc T1

Lisez ce tableau une fois et les noms de vos fichiers .fd et de votre journal se mettent soudain à parler. ptmr8t, c’est le Times regular d’Adobe en T1 ; pcrr8t, le Courier regular en T1 ; ptmb8c, le Times gras en TS1 (8c étant Text Companion). 7t signifie « TeX text encoding », soit OT1, et 8r est TeX Base 1, l’encodage qui accueille un Type 1 brut — la fonte réelle sur laquelle repose une police virtuelle T1. C’est précisément ce qu’on a vu plus haut, où ptmr8t.vf portait ptmr8r dans son MAPFONT. Fontname reconnaît d’ailleurs l’étroitesse des huit caractères et consacre une section distincte aux noms longs.

Les métriques japonaises — le JFM et ses classes de caractères

La composition japonaise a besoin de ce qu’un .tfm occidental ne peut fournir. Kanji et kana reposent par défaut dans une boîte carrée (pleine chasse), et l’espace entre eux n’est pas l’espace inter-mots : les blancs s’ouvrent et se ferment seulement autour de la ponctuation — parenthèses et signes d’arrêt. La structure qui porte cela est le JFM (Japanese Font Metric). pTeX et upTeX utilisent un JFM binaire proche d’un .tfm ; LuaTeX-ja exprime le même rôle sous forme de table Lua. Le premier se convertit vers et depuis le texte avec ppltotf et ptftopl ; le second est déjà du texte et se lit tel quel.

La principale différence avec une TFM occidentale est qu’un JFM regroupe les caractères en « character classes ». Comme le précise le manuel LuaTeX-ja, toutes les longueurs d’un JFM sont des nombres flottants en unités de taille de dessin, ancrés sur zw (pleine chasse) et zh (pleine hauteur, height + depth) ; chaque classe porte ensuite ses propres width, height, depth et italic (correction italique). La classe 0 existe toujours et contient la grande majorité des caractères japonais, ceux qui ne relèvent d’aucune autre classe. La ponctuation va dans des classes distinctes, et une table du glue ou du crénage à insérer entre une classe et une autre produit l’espacement autour des signes et des parenthèses.

jfm.lua
-- A LuaTeX-ja JFM (excerpt); all lengths are in design-size units
luatexja.jfont.define_jfm {
  version = 3,
  dir = 'yoko',            -- horizontal writing
  zw = 1.0, zh = 1.0,       -- full width, full height
  [0] = {                  -- class 0: most kanji and kana
    chars = { '漢' },
    width = 1.0, height = 0.88, depth = 0.12, italic = 0.0,
  },
  [1] = {                  -- a class for stops and commas
    chars = { '。', '、' },
    width = 0.5, height = 0.88, depth = 0.12, italic = 0.0,
  },
}

Dans la famille pTeX, le JAglue — l’espace inséré entre deux caractères japonais, et entre un caractère japonais et du texte occidental — est ajouté automatiquement à la composition. Le JFM fixe l’écart entre classes ; entre caractères japonais non classés s’applique le kanjiskip par défaut, et à une frontière japonais/occidental, xkanjiskip. Avec le kinsoku, les règles interdisant certains caractères en début ou en fin de ligne, ils portent l’aspect de la composition japonaise. LuaTeX-ja fournit des JFM standard selon les besoins : jfm-ujis.lua est le défaut, fondé sur upnmlminr-h.tfm, une métrique utilisée dans upTeX (la plupart des caractères sont carrés) ; jfm-jis.lua correspond à jis.tfm, très répandu dans pTeX ; jfm-min.lua correspond au min10.tfm par défaut de pTeX. Dans une définition de fonte, on en choisit un avec jfm=, comme dans \jfont\F=HaranoAjiMincho-Regular:jfm=ujis.