fontspec (Xe/Lua)

El mismo preámbulo de tres líneas compila bajo LuaLaTeX y se detiene bajo XeLaTeX con ! Package fontspec Error: The font "TeX Gyre Termes" cannot be found. No hay nada roto: es fontspec funcionando tal como está diseñado. fontspec es el paquete que permite a LaTeX llamar a una fuente por su nombre, de modo que una sola línea \setmainfont cambia la tipografía del cuerpo. Pero a quién se le pregunta por ese nombre varía según el motor, y esa diferencia es lo único que de verdad rompe documentos. Esta página coloca esa divergencia en el centro y recorre desde ahí \setmainfont, \newfontfamily, la selección por archivo y las claves de funciones OpenType, con mediciones en cada paso.

En qué motores funciona fontspec y por qué pdfLaTeX no es uno

fontspec funciona en exactamente dos motores, XeLaTeX y LuaLaTeX; bajo pdfLaTeX falla la propia línea \usepackage{fontspec}. El motivo es histórico. El TeX de los años ochenta solo conoce sus métricas TFM y las fuentes Type 1 / METAFONT. OpenType, y la idea de una base de datos de fuentes de todo el sistema, son cosas que el mundo construyó después de que TeX existiera. XeTeX y LuaTeX son motores reconstruidos desde fuera para ese mundo, capaces de manejar entrada Unicode y fuentes OpenType de forma nativa. fontspec es la capa que traduce esas capacidades nuevas al vocabulario de LaTeX, y pdfTeX no tiene capacidades así que traducir.

Se carga con la única línea \usepackage{fontspec}. Las clases y paquetes pensados para XeLaTeX y LuaLaTeX (bxjsarticle, unicode-math, luatexja-fontspec y similares) suelen cargarlo antes por ti, y escribirlo de nuevo explícitamente no hace daño. Al portar un documento desde pdfLaTeX, recuerda quitar \usepackage[T1]{fontenc} y \usepackage[utf8]{inputenc}: el primero sobra porque fontspec te lleva a la codificación TU, y el segundo no significa nada en un motor Unicode.

Cambiar la fuente del cuerpo con \setmainfont, \setsansfont, \setmonofont

Tres comandos sostienen un documento: \setmainfont{…} (la romana, fuente por defecto del cuerpo), \setsansfont{…} (lo que seleccionan \textsf y \sffamily) y \setmonofont{…} (la monoespaciada tras \texttt y \ttfamily). El argumento es un nombre de tipografía o un nombre de archivo. A partir de él, fontspec rastrea el cuarteto entero —redonda, negrita, itálica, negrita itálica— y lo conecta a \textbf, \textit y \emph, de modo que escribir el cuerpo no cambia en nada. Montar ese cuarteto automáticamente es la tarea central de fontspec, y como veremos, solo se escribe configuración adicional cuando esa automatización falla.

document.tex
% compile with lualatex (or xelatex — see the next section)
\documentclass{article}
\usepackage{fontspec}
\setmainfont{TeX Gyre Termes}   % roman / body
\setsansfont{TeX Gyre Heros}    % sans serif
\setmonofont{TeX Gyre Cursor}   % monospaced
\begin{document}
Body text, \textbf{bold}, \textit{italic}, \textsf{sans}, \texttt{mono}.
\end{document}

Por norma, estos comandos van en el preámbulo, por un motivo: LaTeX congela sus fuentes matemáticas en \begin{document}. Ejecuta \setmainfont en el preámbulo y la misma cara alcanza también las romanas dentro de las matemáticas, como \mathrm; ejecútalo en el cuerpo y solo cambia el texto, dejando atrás la romana matemática. La tipografía matemática en sí queda fuera del ámbito de fontspec: corresponde a \setmathfont de unicode-math. Recuerda que texto y matemáticas los gobiernan dos comandos distintos.

The font "…" cannot be found.: XeLaTeX y LuaLaTeX buscan en sitios distintos

Si ! Package fontspec Error: The font "…" cannot be found. aparece solo bajo XeLaTeX, no es una errata en el nombre: es una diferencia sobre a quién se pregunta. XeTeX consulta la base de datos de fuentes del sistema operativo, así que solo ve tipografías que el sistema da por instaladas. LuaTeX construye su propio índice mediante luaotfload, y ese índice abarca también el árbol de TeX. Las fuentes que distribuye TeX Live no están registradas en el sistema, y esa brecha se convierte directamente en la brecha de resultados. En el TeX Live 2024 de esta máquina, un archivo idéntico compiló bajo LuaLaTeX y se detuvo bajo XeLaTeX.

terminal
$ xelatex t1.tex
! Package fontspec Error: The font "TeX Gyre Termes" cannot be found.

$ lualatex t1.tex
Output written on t1.pdf (1 page, 3697 bytes).

$ pdffonts t1.pdf
name                            type          encoding    emb sub uni
NNOCLB+TeXGyreTermes-Regular    CID Type 0C   Identity-H  yes yes yes

La línea se traza entre «fuente distribuida con TeX» y «fuente del sistema». Medido en esta máquina, las tipografías instaladas del lado del sistema —Hiragino Mincho ProN, Hiragino Sans, YuMinchosí se resuelven bajo XeLaTeX. En cambio, las fuentes que TeX Live distribuye bajo texmf-dist/fonts/opentype/public/ son invisibles para XeLaTeX por nombre; en TeX Live 2024 ese directorio contiene 125 paquetes (1.499 archivos .otf reales). La lógica de diseño de los motores corresponde a /learn/engines/xetex y /learn/engines/luatex. Lo que hace falta aquí es la maniobra que devuelve a compilar un documento roto.

Hay dos arreglos. (1) Compilar con lualatex. No exige tocar el fuente, así que suele ser el camino más corto. (2) Escribir el nombre de archivo en lugar del nombre de la tipografía. \setmainfont{texgyretermes-regular.otf} sí funciona bajo XeLaTeX, pero con un precio: nombrada por archivo, fontspec ya no puede adivinar los miembros en negrita e itálica. Al usar \textbf aparece LaTeX Font Warning: Font shape 'TU/texgyretermes-regular.otf(0)/b/n' undefined y el pasaje que querías en negrita sale fino. Es el fallo silencioso clásico: un aviso, no un error, así que pasa desapercibido. Los nombres de archivo distinguen mayúsculas y minúsculas: escribe TeXGyreTermes-Regular.otf y la misma fuente vuelve a dar cannot be found.

Seleccionar por archivo: Path=, Extension=, BoldFont=

La forma completa por archivo asigna los cuatro estilos a mano. Da el directorio con Path= y el sufijo (.otf o .ttf) con Extension=, y luego asocia cada archivo a UprightFont=, BoldFont=, ItalicFont=, BoldItalicFont=. El asterisco * dentro de esos valores es un marcador que se sustituye por el nombre base común del primer argumento. La negrita y la itálica que desaparecieron en la sección anterior vuelven en cuanto escribes estas cuatro: en la medición, la versión con las cuatro produjo cero avisos Font shape … undefined, y pdffonts listó Regular, Bold, Italic y BoldItalic una junto a otra.

document.tex
\usepackage{fontspec}
% XeLaTeX-safe: name the files, and name all four styles
\setmainfont{texgyretermes}[
  Extension      = .otf ,
  UprightFont    = *-regular ,
  BoldFont       = *-bold ,
  ItalicFont     = *-italic ,
  BoldItalicFont = *-bolditalic ,
]

% fonts shipped inside the project directory
\setsansfont{LibreBaskerville}[
  Path        = ./fonts/ ,
  Extension   = .otf ,
  UprightFont = *-Regular ,
  BoldFont    = *-Bold ,
]

Cuál elegir se reduce a una pregunta práctica: ¿quién va a componer este documento? Para un borrador que solo leerás tú, el nombre de la tipografía es más rápido. Cuando el mismo PDF tiene que salir en la máquina de otra persona —coautores, envío a revista, CI, Docker—, empaquetar las fuentes dentro del proyecto y apuntar Path= hacia ellas es prácticamente la única respuesta fiable. Con Path=, fontspec mira directamente esa ruta relativa en vez de la ruta de búsqueda de TeX, y el repositorio entero viaja junto.

MétodoCómoCuándo conviene¿Alcanza fuentes distribuidas en XeLaTeX?
By name\setmainfont{TeX Gyre Termes}Borradores y documentos personales; negrita e itálica se emparejan solasNo, solo tipografías registradas en el sistema
By file, upright only\setmainfont{texgyretermes-regular.otf}Cuando solo necesitas que compile; pierdes la negritaSí, pero \textbf se queda fino en silencio
By file, all fourPath / Extension / UprightFont / BoldFont / ItalicFont / BoldItalicFontColaboración, envío, CI, fuentes propias: cuando manda la reproducibilidadSí, y sin avisos Font shape … undefined

Añadir una cuarta y quinta tipografía con \newfontfamily

Una tipografía que no cabe en el trío romana/sans/mono se añade creando tu propio conmutador con \newfontfamily. El primer argumento es el nombre de comando que quieres, el segundo la fuente, y admite las mismas opciones que \setmainfont. El comando resultante es declarativo, como \rmfamily: se aplica a todo lo que sigue. Limita su alcance envolviéndolo entre llaves, {\titlefont …}.

document.tex
\usepackage{fontspec}
\newfontfamily\titlefont{TeX Gyre Bonum}
\newfontfamily\quotefont{TeX Gyre Schola}[Scale = MatchLowercase]
% ...
\titlefont A heading in Bonum

{\quotefont A quoted passage in Schola.}

Para una cara usada una sola vez, puedes omitir la definición y aplicar \fontspec{Nombre de fuente} como declaración en el sitio. Pero \fontspec recarga la fuente en cada llamada, así que usarlo para algo recurrente —títulos de capítulo, por ejemplo— infla el tiempo de compilación sin que se note. A partir de dos usos, defínela con \newfontfamily. Ten en cuenta además que \newfontfamily falla si ya existe un comando con ese nombre: evita nombres cortos que LaTeX ya usa, como \sc o \it, y elige uno que diga para qué sirve, como \titlefont.

Activar funciones OpenType: Ligatures, Numbers, Scale

Una fuente OpenType ya trae glifos alternativos dentro —ligaduras, variantes de cifras, versalitas— y fontspec los extrae mediante opciones key=value. Los efectos se miden más rápido de lo que se juzgan a ojo, así que aquí van cifras tomadas de TeX Gyre Pagella a 10 pt. Aplica Numbers=OldStyle y la profundidad de 0123456789 crece de 0.19998pt a 2.37999pt: que las cifras de estilo antiguo den descendente al 3 y al 9 aparece directamente en la medición.

  • Ligatures= — ligaduras y conversión de entrada. Ligatures=TeX activa la forma TeX de teclear: -- pasa a raya ene, --- a raya eme, y ` y '' a comillas curvas. (Medido: --- va de 9,99 pt de «tres guiones» a exactamente 10,0 pt —un cuadratín— como raya eme de verdad.) Otros valores son Common (las fi, fl estándar), NoCommon para apagarlas (medido: fi se ensancha de 6,05 pt a 6,35 pt), Rare/Discretionary e Historic`.
  • Numbers= — estilo de cifras. Combina OldStyle (cifras de texto, que viven dentro de la prosa) o Lining (cifras modernas de altura uniforme) con Proportional o Monospaced. Las cifras de una tabla se alinean verticalmente en cuanto pones Lining,Monospaced.
  • Letters=SmallCaps — versalitas de verdad. Medido en Libertinus Serif, Abc baja de 6,98 pt a 6,58 pt de alto y crece de 16,26 pt a 16,94 pt de ancho. Ojo: si la fuente no tiene tabla smcp, fontspec no hace nada y no avisa de nada; en TeX Gyre Pagella el ancho se quedó en 17,6 pt. También existen valores como Letters=Uppercase.
  • SmallCapsFeatures= — un paquete de funciones que solo se aplica en versalitas, por ejemplo SmallCapsFeatures={Numbers=OldStyle}. Con el mismo patrón están UprightFeatures=, BoldFeatures= e ItalicFeatures=, de modo que cada estilo puede configurarse por separado.
  • Scale= — factor de escala: un número, o bien Scale=MatchLowercase (igualar la altura x de la fuente principal) o Scale=MatchUppercase (igualar la altura de mayúsculas). Medido, la altura x de TeX Gyre Heros, 5,24 pt, bajó a 4,68999 pt frente al texto en Pagella: exactamente los 4,69 pt de Pagella.
  • StylisticSet= — selecciona por número un conjunto estilístico de alternativas que ofrece la fuente. RawFeature= es la vía de escape para funciones sin clave propia, pasando una etiqueta OpenType directamente; RawFeature={+onum} da el mismo resultado que Numbers=OldStyle (medido: la misma profundidad de 2,37999 pt).
  • Script= / Language= — eligen el sistema de escritura y la lengua (Script=Arabic, Language=Turkish, etc.). Renderer= designa el motor de conformación; bajo XeTeX puedes elegir AAT, OpenType o Graphite. Bajo LuaTeX el trabajo lo hace luaotfload, así que la clave casi nunca hace falta.
document.tex
\usepackage{fontspec}
\setmainfont{TeX Gyre Pagella}[
  Ligatures = TeX ,
  Numbers   = OldStyle ,
  SmallCapsFeatures = {Numbers = Lining} ,
]
% match the sans to the body x-height
\setsansfont{TeX Gyre Heros}[Scale = MatchLowercase]

Para añadir una función en un solo punto y no en todo el documento, usa \addfontfeature{…} (o \addfontfeatures{…} para varias). El comando sobrescribe localmente la fuente actual con la función indicada y solo actúa dentro de las llaves que la envuelven. El caso típico: un documento compuesto con cifras de estilo antiguo en el que los números de una tabla deben alinearse.

latex
Set in old-style figures, but this column
{\addfontfeature{Numbers={Lining,Monospaced}} 01234 56789}
lines up digit by digit.

De qué no se ocupa fontspec: matemáticas y japonés

fontspec se ocupa solo del texto latino del cuerpo; las matemáticas y el japonés van por vías aparte. Para las matemáticas, carga unicode-math y entrega a \setmathfont{…} una fuente matemática OpenType: Latin Modern Math, STIX Two Math, NewCM Math. Cambiar \setmainfont no mueve las matemáticas en absoluto, así que un documento cuyo texto y fórmulas no casan no es un problema exclusivo de pdfLaTeX. Qué fuente matemática elegir corresponde a la página de fuentes matemáticas.

El japonés presenta la misma figura. \setmainfont cambia solo la cara latina; kanji y kana no se mueven. En LuaLaTeX se carga luatexja-fontspec, en la práctica la contraparte japonesa de fontspec, y se usan sus comandos con «j»: \setmainjfont{…} (Mincho, la cara japonesa del cuerpo), \setsansjfont{…} (Gothic), \newjfontfamily. La sintaxis de opciones es esencialmente la misma, así que lo que sabes de Scale= y Path= se traslada tal cual. Componer japonés en un motor Unicode significa, por tanto, llevar dos vías en paralelo. Qué fuentes japonesas hay disponibles se trata en la página de fuentes japonesas.