> For the complete documentation index, see [llms.txt](https://overleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://overleaf-pro.ayaka.space/latex/es/articulos-en-profundidad/10-an-overview-of-technologies-supporting-the-use-of-colour-emoji-fonts-in-latex.md).

# Resumen de tecnologías que permiten el uso de fuentes de emoji de color en LaTeX

## Introducción

Este artículo ofrece una visión general de diversos [temas de contexto](#which-topics-do-we-cover) relacionados con el uso de fuentes de color OpenType para componer emoji en color en LaTeX. Hemos intentado proporcionar una amplia gama de materiales, destinados a un amplio espectro de intereses y conocimientos. Para mantener el artículo manejable, nuestra cobertura de ciertos temas omite muchos detalles técnicos, pero esperamos que haya material suficiente para orientar su exploración de la composición de emoji en color en LaTeX.

**Actualización (julio de 2023)**: Este artículo se publicó por primera vez en agosto de 2021 y se revisó en julio de 2023 para actualizar la sección sobre [Uso de fuentes de color OpenType basadas en SVG con LuaHBTeX](#using-svg-based-opentype-color-fonts-with-luahbtex).

### ¿Qué temas abordamos?

Este artículo cubre los siguientes temas generales:

* Unicode: el estándar que codifica los emoji como caracteres y especifica su comportamiento esperado en aplicaciones de procesamiento de texto y composición tipográfica.
* Fuentes de color OpenType: fuentes especializadas que proporcionan representaciones coloridas de los caracteres emoji mostrados en su documento LaTeX.
* Conformación de texto: introducción a un componente clave de la composición de idiomas con escrituras complejas y emoji.
* HarfBuzz: el componente de LuaHBTeX que permite la composición tipográfica multilingüe avanzada y el uso de fuentes de color OpenType para componer emoji en LaTeX.
* Diferentes motores TeX: exploración de su compatibilidad con fuentes de color OpenType y selección del motor TeX que se debe utilizar.
* API de HarfBuzz de LuaHBTeX: una introducción a la «magia» detrás de [la conformación de texto](#the-concept-of-text-shaping) en LuaHBTeX.

### Tres formas de componer emoji en color

Los emoji en color se pueden componer con LaTeX mediante tres métodos principales:

1. Usar herramientas gráficas estándar de LaTeX, como TikZ, MetaPost o Asymptote, para dibujar los emoji.
2. Insertar emoji mediante gráficos de emoji preparados previamente y almacenados en archivos externos.
3. Tratar los emoji como texto codificado en Unicode y usar [la conformación de texto](#the-concept-of-text-shaping) con [fuentes de color OpenType](#opentype-color-fonts) para componerlos.

Las opciones prácticas para incluir emoji en color en su documento LaTeX dependen del motor TeX utilizado para compilar dicho documento; es decir, de si está utilizando:

* pdfLaTeX: motor pdfTeX + LaTeX;
* XeLaTeX: motor XeTeX + LaTeX;
* LuaLaTeX: motor LuaHBTeX (a partir de TeX Live 2020) + LaTeX.

Los tres motores TeX pueden utilizar herramientas o paquetes de LaTeX para dibujar emoji o usar `\includegraphics{...}` para insertar emoji almacenados en archivos gráficos externos. Dibujar o importar gráficos son técnicas ideales para componer emoji cuando necesita una solución que no dependa del motor TeX utilizado para compilar el documento LaTeX.

Sin embargo, si su flujo de trabajo ofrece la flexibilidad de elegir un motor TeX particular y prefiere usar fuentes de color OpenType y procesamiento de texto basado en Unicode, necesita la versión más reciente de LuaTeX, llamada LuaHBTeX. A partir de TeX Live 2020, LuaHBTeX se utiliza para compilar documentos LaTeX basados en el formato LuaLaTeX.

## Contexto sobre Unicode y los caracteres emoji

### Codificaciones de caracteres

Las computadoras almacenan, transmiten y procesan texto mediante una secuencia de valores numéricos (enteros) que representan los *caracteres*. El procesamiento fiable de texto requiere que los productores y consumidores de texto acuerden qué valores enteros deben utilizarse para representar caracteres individuales dentro del flujo de texto. En otras palabras, ¿cuál es la *carácter* *codificación?* Una codificación es el conjunto de valores enteros acordados y asignados para representar un determinado conjunto de caracteres: cada carácter se representa mediante un valor entero dentro de la codificación utilizada.

### Entra Unicode

Históricamente, en la era del texto de 8 bits, se usaban muchas codificaciones de caracteres diferentes, lo que siempre planteaba el espectro de *incompatibilidades de codificación*: productores y consumidores de texto que asumen erróneamente codificaciones diferentes, lo que genera errores de procesamiento de texto. Quienes hayan trabajado con TeX/LaTeX durante algunos años probablemente hayan encontrado incompatibilidades de codificación entre el texto de entrada y las fuentes utilizadas para componer un documento. Si las fuentes del documento están configuradas para utilizar una codificación diferente de la del texto, es probable que el PDF compuesto contenga caracteres faltantes o erróneos.

Estos problemas históricos de codificación se pueden resolver utilizando un estándar internacional que codifica todos los caracteres del mundo: Unicode. El estándar Unicode no es estático, sino que se actualiza periódicamente para incluir caracteres y escrituras adicionales dentro de su esquema de codificación. Existe un [proceso formal de revisión para proponer nuevos caracteres](http://www.unicode.org/pending/proposals.html) con un [esquema específico para nuevos caracteres emoji](https://www.unicode.org/emoji/proposals.html).

### ¿Cuántos caracteres Unicode?

Unicode codifica un máximo teórico de 1.114.112 caracteres. Cada uno de los 1.114.112 valores enteros se denomina *punto de código*: el valor entero asignado para identificar cada carácter. Sin embargo, por diversas razones técnicas, solo [1.112.064 puntos de código](https://en.wikipedia.org/wiki/Unicode#Architecture_and_terminology) pueden asignarse a caracteres reales: 2048 puntos de código no son asignables y su uso está prohibido dentro de texto compatible con Unicode.

En el momento de redactar la primera versión de este artículo, la versión 13 del estándar Unicode había asignado un total de 143.859 puntos de código a caracteres reales, incluidos [3304 caracteres ahora codificados como emoji](https://www.unicode.org/L2/L2020/20114r-family-emoji-explor.pdf) (véase la página 2 de ese documento). El crecimiento del número de caracteres codificados por Unicode está bien documentado en el artículo [¿Cuántos caracteres Unicode existen?](https://www.babelstone.co.uk/Unicode/HowMany.html) y en una [entrada de Wikipedia](https://en.wikipedia.org/wiki/Unicode#Versions).

### Planos Unicode

Toda la colección de 1.114.112 puntos de código Unicode se agrupa en 17 denominados planos: del plano 0 al plano 16, cada uno con 65.536 valores de punto de código, lo que da un total de $$17\times2^{16} = 1,114,112$$ caracteres. El plano 0, denominado [Plano Multilingüe Básico](https://en.wikipedia.org/wiki/Plane_\(Unicode\)#Basic_Multilingual_Plane), codifica los caracteres utilizados con mayor frecuencia. Los planos 1–16 se denominan [Planos Suplementarios](http://unicode.org/glossary/#supplementary_planes).

### El auge de los emoji

Surgen nuevos caracteres debido a los cambios en las formas de comunicación humana, y la tecnología de los teléfonos móviles dio lugar a uno de esos conjuntos de caracteres: los emoji, que evolucionaron en Japón a finales de la década de 1990. No es sorprendente que las [preguntas frecuentes de Unicode sobre emoji](https://unicode.org/faq/emoji_dingbats.html) señalen

> «La palabra emoji procede del japonés [絵](http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=%E7%B5%B5) (e ≅ imagen) + [文字](http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=%E6%96%87) (moji ≅ carácter escrito).»

Los lectores interesados en el contexto y el desarrollo histórico de los emoji pueden encontrar interesante esta [introducción de Unicode](https://unicode.org/reports/tr51/#Introduction) o el artículo [Yo apoyo ese emoji: Los estándares, las estructuras y la producción social de los emoji](https://firstmonday.org/ojs/index.php/fm/article/view/9381).

No fue hasta 2010, con la publicación de [la versión 6.0 del estándar Unicode](https://www.unicode.org/versions/Unicode6.0.0/), cuando muchos emoji fueron reconocidos formalmente como *caracteres* por derecho propio. Unicode 13.0 codificó [3304 caracteres como emoji](https://www.unicode.org/L2/L2020/20114r-family-emoji-explor.pdf) (véase la página 2 de ese documento), y Unicode 13.1 enumera [3521 emoji](https://unicode.org/emoji/charts/emoji-counts.html).

### Los emoji viven en un plano superior

Unicode asignó muchos caracteres emoji a puntos de código fuera del Plano Multilingüe Básico (BMP), codificados [en el plano 1](https://en.wikibooks.org/wiki/Unicode/Character_reference/1F000-1FFFF) con puntos de código en el intervalo 1F000–1FFFF, lo cual tiene una consecuencia importante para quienes deseen *copiar y pegar* caracteres emoji en los editores de Overleaf (Editor de código o Editor visual). Los editores de texto de Overleaf solo pueden manejar caracteres del Plano Multilingüe Básico, aunque esperamos que futuras actualizaciones incorporen compatibilidad con caracteres no BMP. Tenga en cuenta que esta limitación afecta únicamente a los caracteres no BMP dentro de texto pegado en archivos destinados a editarse mediante los editores de Overleaf. Hay otras formas de acceder a los caracteres emoji:

* Usar los comandos primitivos `\char"<punto de código>` o `\Uchar"<punto de código>` (véase [esta sección](#optional-detail-luatexluahbtex-char-vs-uchar) del artículo).
* Usar archivos de texto de entrada que contengan caracteres emoji en formato UTF-8.
* Usar comandos de LaTeX (macros) que inserten caracteres emoji.

#### Pegar emoji y otros caracteres no BMP en Overleaf

Si pega un carácter emoji, por ejemplo, 😀, en el Editor de código de Overleaf, por ahora se convertirá en los caracteres ��.

![Error debido a copiar y pegar caracteres no BMP en los editores de Overleaf](/files/ec9d7208a110aaeb585f9f60149306f4ca0c0a22)

El carácter � tiene el punto de código Unicode FFFD y su nombre oficial es CARÁCTER DE SUSTITUCIÓN; se utiliza para «[sustituir un carácter desconocido, no reconocido o no representable](https://en.wikipedia.org/wiki/Specials_\(Unicode_block\))».

### Uso de puntos de código Unicode (U+) en LuaLaTeX

La documentación de Unicode representa los valores de puntos de código utilizando la notación `U+<valor hexadecimal>`—como `U+1F600`, donde `1F600` es el `<valor hexadecimal>` del punto de código Unicode para el carácter emoji 😀. Para utilizar estos valores de puntos de código en LuaLaTeX, elimine el `U+` y escriba `\char"<valor hexadecimal>` o `\Uchar"<valor hexadecimal>`. El `"` El carácter indica a un motor TeX que el número proporcionado se especifica en hexadecimal. Por ejemplo, para utilizar el emoji 😀, escribiría `\char"1F600` o `\Uchar"1F600`—utilizando una fuente capaz de componerlo.

Un ejemplo mínimo de LuaLaTeX que usa `\char` y `\Uchar` para componer el carácter emoji 😀 podría ser:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont[Renderer=Harfbuzz]{NotoColorEmoji.ttf}
%Use \emojifont en un grupo para mantener locales sus efectos
{\emojifont
\Uchar"1F600
\char"1F600}
\end{document}
```

[Abra este ejemplo de LuaLaTeX en Overleaf](https://www.overleaf.com/docs?engine=lualatex\&snip_name=Test+using+LuaLaTeX\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%7Bfontspec%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cnewfontfamily%5Cemojifont%5BRenderer%3DHarfbuzz%5D%7BNotoColorEmoji.ttf%7D%0A%25Use+%5Cemojifont+in+a+group+to+keep+its+effects+local%0A%7B%5Cemojifont+%0A%5CUchar%221F600%0A%5Cchar%221F600%7D%0A%5Cend%7Bdocument%7D)

**(detalle opcional) LuaTeX/LuaHBTeX: \char frente a \Uchar**

Además del comando convencional `\char<código de carácter>` para componer un `<código de carácter>`, utilizando la fuente actual, los motores LuaTeX, LuaHBTeX y XeTeX también proporcionan el comando `\Uchar<código de carácter>` Desde la perspectiva del usuario, el resultado de `\char` y `\Uchar` tiene el mismo aspecto, pero hay una sutil diferencia en el funcionamiento de estos comandos, como señalamos a continuación.

**La diferencia clave: la expansión**

`\Uchar` es un denominado [comando expandible](/latex/es/articulos-en-profundidad/22-how-does-expandafter-work-the-meaning-of-expansion.md#expansion-a-general-term-for-a-set-of-operations) mientras que `\char` no es expandible. Cuando se está «ejecutando» un comando `\char<código de carácter>` o `\Uchar<código de carácter>` —es decir, el comando no se almacena como parte de una macro u otra lista de tokens—, tienen lugar las siguientes acciones dentro del motor TeX:

* **`\char<código de carácter>`** indica al motor TeX que inserte inmediatamente un token de carácter, que representa `<código de carácter>`, en cualquier fragmento de contenido que esté componiendo en ese momento.
* En contraste, **`\Uchar<código de carácter>`** tiene dos pasos de procesamiento distintos:

1. El `\Uchar<código de carácter>` el comando es *expandido*, y el `<código de carácter>` se convierte en una lista temporal de tokens que contiene un único [token de carácter](/latex/es/articulos-en-profundidad/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md#tex-tokens-101-28and-notions-of-expansion29) que representa el `<código de carácter>`.
2. Esa lista de tokens de un solo carácter queda ahora *disponible* para el motor TeX como la fuente de su siguiente entrada. En efecto, el motor TeX «desvía temporalmente su atención» para utilizar esa lista de un solo token como la ubicación de su siguiente elemento de entrada (token). De forma predeterminada, el motor TeX simplemente vuelve a leer (introducir) ese token y compone el carácter correspondiente, reproduciendo el comportamiento de `\char` comando. **Sin embargo**, dado que ese `<código de carácter>` no se compuso inmediatamente, sino que se almacenó temporalmente *almacenados* como un único token, los comandos primitivos de TeX o las macros de LaTeX pueden usar (absorber) ese token; no es necesario componerlo de inmediato, sino que se puede utilizar en procesamiento posterior según sea necesario.

En efecto, `\char<código de carácter>` dice «compón este `<código de carácter>` ahora», mientras que `\Uchar<código de carácter>` tiene una forma de «acción diferida» al crear un token de carácter almacenado y ponerlo a disposición como el siguiente elemento de entrada (un token). Ese token puede ser utilizado (absorbido) por comandos y macros de TeX o vuelto a leer por el motor TeX y compuesto.

### Unicode (codificación) no es toda la historia

La capacidad de utilizar caracteres emoji dentro de texto codificado en Unicode es solo parte de la historia del éxito de los emoji. El aumento en el uso de emoji también fue posible gracias a desarrollos en [tecnología de fuentes OpenType](https://learn.microsoft.com/en-us/typography/opentype/)—fuentes cuyos datos de glifos (diseños de caracteres) pueden contener [datos de color](https://learn.microsoft.com/en-us/typography/opentype/spec/colr): los denominados [fuentes de color OpenType](#opentype-color-fonts).

Además de fuentes adecuadas, el uso de emoji en color requiere componentes de software adicionales cuyas tareas incluyen:

* preprocesar («[conformar](#the-concept-of-text-shaping)») texto codificado en Unicode, *prepararlo* para mostrarlo utilizando una fuente particular;
* *renderizar y mostrar* los emoji coloridos de una fuente *glifos* en la pantalla de un dispositivo.

#### Glifo frente a carácter: ¿no son lo mismo?

Los términos «glifo» y «carácter» se utilizan a menudo como si fueran intercambiables —en referencia al mismo concepto básico—, pero existe una diferencia sutil, aunque importante, en su significado.

Unicode [define el término «carácter»](http://www.unicode.org/glossary/#character) como:

> «El componente más pequeño del lenguaje escrito que posee valor semántico; se refiere al significado y/o forma abstractos, en lugar de a una forma específica…»

En cambio, un «glifo» es un *diseño* *forma* específico para la *representación visual* de un determinado *carácter*.

La cuestión de carácter frente a glifo se observa fácilmente cuando un texto cargado de emoji se visualiza en diversos sistemas/plataformas de software, por ejemplo, al leer el mismo texto en un teléfono móvil basado en iOS o Android, o en una computadora de escritorio con Windows. Independientemente del dispositivo o plataforma utilizados, el texto subyacente (secuencia de caracteres) contendría los mismos *emoji* *caracteres*codificados en Unicode. Son las capacidades específicas del dispositivo involucradas en el *preprocesamiento* de ese texto y después en el *renderizado* y *modo matemático de visualización* de los resultados, quizá utilizando fuentes específicas del dispositivo, las que producen diferentes glifos (diseños de caracteres) para representar los mismos caracteres emoji.

La [lista completa de emoji](https://unicode.org/emoji/charts/full-emoji-list.html) de Unicode proporciona imágenes de muestra que representan cada carácter emoji de Unicode, demostrando diversos glifos utilizados por distintos proveedores tecnológicos. No solo los diseñadores de fuentes adoptan sus propios diseños particulares (glifos) para representar los caracteres emoji, sino que las fuentes individuales también varían en el número de caracteres emoji que admiten (para los que contienen glifos) y pueden contener o no características más avanzadas de procesamiento de texto emoji incluidas en las especificaciones de emoji de Unicode.

La noción y el concepto de los caracteres, su semántica y codificación, forman la base del mundo Unicode: se ocupa de los caracteres. El diseño y la representación visual de los caracteres individuales, como glifos, pertenecen a las tecnologías de fuentes y al oficio del diseño tipográfico.

#### Emoji Unicode: mucho más que codificación de texto

La función principal de Unicode es proporcionar un estándar de codificación global que define qué valor entero, denominado *punto de código,* debe utilizarse para representar cada carácter, incluidos los emoji, dentro de un flujo de texto codificado en Unicode.

La especificación de Unicode para emoji también define *comportamientos de procesamiento* para determinadas *secuencias* de caracteres emoji que aparecen dentro de un flujo de texto codificado en Unicode. Las secuencias definidas de caracteres emoji pueden «fusionarse» mediante un proceso denominado [la conformación de texto](#the-concept-of-text-shaping) para producir un único glifo emoji resultante («compuesto»); ese único glifo sería utilizado por el sistema operativo del dispositivo para representar la secuencia de caracteres original presente en el texto.

El informe técnico de Unicode sobre [emoji Unicode](https://unicode.org/reports/tr51/) documenta el amplio conjunto de funciones disponibles para el software que desee proporcionar procesamiento compatible con Unicode de caracteres emoji. Como ejemplo, Unicode define (codifica) caracteres denominados [modificadores de emoji](http://www.unicode.org/reports/tr51/#Emoji_Modifiers_Table) que se pueden utilizar para generar *variaciones* de caracteres emoji «base», como variaciones en el [tono de piel basado en la escala de Fitzpatrick](http://www.unicode.org/reports/tr51/#Diversity). Tenga en cuenta que el conjunto de caracteres emoji base y los modificadores aplicables se definen como parte del [estándar de emoji Unicode](http://www.unicode.org/reports/tr51).

La página de Unicode [Secuencias de emoji](http://unicode.org/emoji/charts/emoji-sequences.html) proporciona una tabla de las secuencias actualmente contempladas por la especificación Unicode. Coloque el puntero del ratón sobre cualquiera de las imágenes de glifos emoji para ver una pequeña información emergente que indica la secuencia subyacente de caracteres emoji Unicode que produce ese glifo:

![EmojiSequenceChart.png](/files/f40ca34087aff5fcfe1919c78dcec3c240ab12da)

Por ejemplo, el glifo emoji:

![HandMediumSkinTone.png](/files/5ad8932a30fb5a34031af0eafb1ce1c62ac4d80b)

aparece en la [sección de secuencias de modificadores](http://unicode.org/emoji/charts/emoji-sequences.html#modifier_sequences) y se produce mediante la secuencia de dos caracteres U+1F44B U+1F3FD. Esos caracteres componentes son:

U+1F44B:![UnicodeWavingHandDefault.png](/files/fc57bb2ebf3c08a457b0be842a512c58e0f4ac3a) (MANO SALUDANDO)

U+1F3FD:![FitzPatrick3.png](/files/fddad9ea02b4c068cdf269f0a01f68f0ceef29a8) (MODIFICADOR DE EMOJI FITZPATRICK TIPO 4)

**Uso de modificadores de tono de piel en LuaHBTeX**

El siguiente ejemplo utiliza LuaHBTeX para demostrar el uso de modificadores de emoji:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont[Renderer=HarfBuzz,SizeFeatures={Size=20}]{NotoColorEmoji.ttf}
Mano saludando aislada: {\emojifont\Uchar"1F44B}\par
Modificador aislado: {\emojifont\Uchar"1F3FD}\par
Resultado combinado: {\emojifont\Uchar"1F44B\Uchar"1F3FD}
\end{document}
```

[Abra este ejemplo de modificadores de emoji de LuaLaTeX en Overleaf](https://www.overleaf.com/docs?engine=lualatex\&snip_name=Emoji+modifiers+using+LuaLaTeX\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%7Bfontspec%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cnewfontfamily%5Cemojifont%5BRenderer%3DHarfBuzz%2CSizeFeatures%3D%7BSize%3D20%7D%5D%7BNotoColorEmoji.ttf%7D%0AIsolated+waving+hand%3A+%7B%5Cemojifont%5CUchar%221F44B%7D%5Cpar%0AIsolated+modifier%3A+%7B%5Cemojifont%5CUchar%221F3FD%7D%5Cpar+%0ACombined+result%3A+%7B%5Cemojifont%5CUchar%221F44B%5CUchar%221F3FD%7D%0A%5Cend%7Bdocument%7D)

Este ejemplo produce la siguiente salida:

![ModifiersInLuaHBTeX.png](/files/65d0f8213dfc926df97690a5d558c6059e694169)

#### UTF-8: su función en el almacenamiento de texto Unicode

Cualquier texto o código que escriba o pegue en el Editor de código de Overleaf (o Editor visual) se almacenará en formato UTF-8, así que revisaremos brevemente qué significa realmente UTF-8. UTF significa Formato de Transformación Unicode, y la función de UTF-8 en el almacenamiento o transmisión de texto codificado en Unicode está indicada por la frase «Formato de transformación *Formato*».

Los valores de puntos de código de Unicode van de 0 a un máximo de 1.114.111, por lo que es imposible representar todos los valores de caracteres Unicode utilizando un solo byte de 8 bits, que solo puede almacenar hasta 256 valores diferentes: de 0 a 255. Sin embargo, es posible representar cualquier entero de punto de código Unicode utilizando una *secuencia consecutiva* de valores del tamaño de un byte, que es el principio detrás de UTF-8.

UTF-8 proporciona una «receta» para *transformar* (es decir, «codificar» o «convertir») un valor entero de punto de código Unicode en una secuencia única de 1 a 4 enteros consecutivos del tamaño de un byte: el número de bytes consecutivos necesarios depende del valor del entero del punto de código. Por consiguiente, puede leer que UTF-8 almacena los caracteres Unicode como *secuencias multibyte* porque un único carácter Unicode (entero de punto de código) se representa en UTF-8 como una secuencia de 1 a 4 bytes consecutivos.

Naturalmente, el texto almacenado en UTF-8 puede convertirse de nuevo a su secuencia original de valores enteros de puntos de código Unicode; eso es lo que XeTeX o LuaTeX/LuaHBTeX deben hacer al leer un archivo de entrada LaTeX almacenado en formato UTF-8. Esos motores TeX necesitan conocer los valores de puntos de código Unicode (caracteres) de entrada antes de poder componer el texto. Tenga en cuenta que pdfTeX no tiene una capacidad integrada de descodificación UTF-8, por lo que debe recurrir a macros de TeX para procesar (descodificar) texto de entrada formateado en UTF-8.

**Algunos ejemplos de UTF-8**

* El carácter árabe ش («sheen») tiene el punto de código Unicode 0634 en hexadecimal (base 16) o 1588 en decimal (base 10). En UTF-8, ش se representa como 2 valores hexadecimales, D8 y B4, por lo que el carácter ش se almacenaría como los dos bytes consecutivos D8B4 dentro de texto codificado en UTF-8.
* El carácter emoji 😀 tiene el punto de código Unicode 1F600 en hexadecimal (base 16) o 128512 en decimal (base 10). En UTF-8, 😀 se representa como 4 valores hexadecimales: F0, 9F, 98 y 80, por lo que el carácter 😀 se almacenaría como los 4 bytes consecutivos F09F9880 dentro de un archivo de texto UTF-8.

#### Caracteres especiales utilizados en el procesamiento de texto emoji basado en Unicode

No todos los caracteres codificados en Unicode están destinados a una presentación visual mediante los glifos de una fuente: algunos caracteres codificados se designan como *caracteres no imprimibles* cuyo propósito es ayudar a funciones especializadas de procesamiento de texto (dentro del software compatible). Las diferentes aplicaciones de software proporcionan niveles variables de compatibilidad con los caracteres no imprimibles codificados en Unicode, por lo que el resultado dependerá del entorno de software —aplicaciones y fuentes— utilizado.

**Dos caracteres no imprimibles que debe conocer**

* **Unidor de ancho cero (ZWJ)**, punto de código 200D (hexadecimal), está, como su nombre sugiere, diseñado para activar el «comportamiento de unión» de los caracteres de entrada, pero solo si esos caracteres de entrada *poseen* un comportamiento de unión definido.
* **No unidor de ancho cero (ZWNJ)**, punto de código 200C (hexadecimal), está diseñado para *impedir* el «comportamiento de unión» que los caracteres de entrada podrían mostrar de otro modo. Por ejemplo, puede utilizar el ZWNJ para impedir el comportamiento de unión de caracteres árabes consecutivos que normalmente se procesarían (conformarían) en sus formas de unión.

Unicode ha publicado una lista de [secuencias emoji ZWJ recomendadas](https://unicode.org/emoji/charts/emoji-zwj-sequences.html) que utilizan un UNIDOR DE ANCHO CERO (ZWJ) U+200D para combinar secuencias de caracteres emoji en un único glifo emoji compuesto, si está disponible en las fuentes utilizadas.

**Ejemplo de uso del no unidor de ancho cero**

El siguiente fragmento de código mínimo utiliza la fuente OpenType Scheherazade, incluida en TeX Live, para definir una fuente LaTeX llamada `\arabicfont` que podemos utilizar para componer texto árabe. La línea

```latex
{\arabicfont Sin unión:\textdir TRT\Uchar"0644\Uchar"200C\Uchar"0627}
```

utiliza un carácter no unidor de ancho cero, mediante `\Uchar"200C`, para impedir el comportamiento de unión normal de las dos letras árabes ل (lam) y ا (alef). Observe el uso de `\textdir TRT` para establecer la dirección del texto de derecha a izquierda:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\arabicfont[Script=Arabic,Renderer=Harfbuzz,SizeFeatures={Size=40}]{Scheherazade}
{\arabicfont Unión:\textdir TRT\Uchar"0644\Uchar"0627}\par
{\arabicfont Sin unión:\textdir TRT\Uchar"0644\Uchar"200C\Uchar"0627}
\end{document}
```

[Abra este ejemplo de LuaLaTeX en Overleaf](https://www.overleaf.com/docs?engine=lualatex\&snip_name=Zero+width+non-joiner+using+LuaLaTeX\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%7Bfontspec%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cnewfontfamily%5Carabicfont%5BScript%3DArabic%2CRenderer%3DHarfbuzz%2CSizeFeatures%3D%7BSize%3D40%7D%5D%7BScheherazade%7D%0A%7B%5Carabicfont+Joining%3A%5Ctextdir+TRT%5CUchar%220644%5CUchar%220627%7D%5Cpar%0A%7B%5Carabicfont+Non-joining%3A%5Ctextdir+TRT%5CUchar%220644%5CUchar%22200C%5CUchar%220627%7D%0A%5Cend%7Bdocument%7D)

Este ejemplo produce la siguiente salida:

![NonJoiner.png](/files/c6e236cbca498453f16307f8a32d2fb63d3dd8a3)

## El concepto de «conformación de texto»

Comencemos con un ejemplo visual que utiliza una traducción al urdu de la palabra «educativo». El texto de la traducción al urdu podría escribirse en un teclado o dispositivo de pantalla táctil y se crearía como una simple secuencia lineal de caracteres árabes Unicode. Sin embargo, cuando ese texto se compone o se muestra en la pantalla de un dispositivo en el [estilo nastaliq](https://en.wikipedia.org/wiki/Nastaliq), el resultado es una compleja disposición bidimensional de glifos.

Utilizando nuestro ejemplo en urdu, el siguiente gráfico compara la entrada lineal de caracteres árabes Unicode *caracteres* con la salida compuesta en estilo nastaliq, formada por una disposición bidimensional de *glifos* presentes en la fuente (gratuita) [Awami Nastaliq](https://software.sil.org/awami/download/):

![](/files/ae583c20cb05d4911ca78efc9b1f0a9b2a67029f)

El proceso de «traducir» los caracteres de entrada a un conjunto de glifos de salida correctamente posicionados se denomina *la conformación de texto*, y es un componente vital del procesamiento de texto antes de su visualización o composición. Nuestro ejemplo utilizó texto en urdu (escritura árabe) porque el resultado de la conformación es claramente evidente, en contraste con idiomas que utilizan la escritura latina, como el inglés, donde la conformación es mucho menos pronunciada, como en la producción de ligaduras simples.

La conformación de texto es esencial al utilizar escrituras (sistemas de escritura) como [Árabe](https://en.wikipedia.org/wiki/Arabic), [Hebreo](https://en.wikipedia.org/wiki/Hebrew_language), [Devanagari](https://en.wikipedia.org/wiki/Devanagari) o [Malayalam](https://en.wikipedia.org/wiki/Malayalam), solo cuatro ejemplos de las denominadas *escrituras complejas*. Para garantizar la presentación correcta del texto en esas escrituras y los idiomas que las utilizan, el proceso de conformación debe abordar cuidadosamente cualquier regla y matiz de conformación presente en la combinación particular de escritura e idioma. Por ejemplo, algunos idiomas requieren múltiples caracteres de entrada para generar un glifo de salida determinado, o puede haber requisitos complejos para el posicionamiento cuidadoso de marcas diacríticas y reordenamientos entre glifos para garantizar que los glifos individuales se coloquen correctamente (en relación unos con otros).

En general, la conformación de un fragmento de texto requiere varias piezas de información:

* El sistema de escritura o *escritura* en la que está escrito el texto.
* El *idioma* específico que se está usando. Las escrituras individuales pueden usarse para varios idiomas, y cada combinación escritura–idioma tiene sus propias sutilezas/matices de conformación.
* La *dirección de escritura* del texto—como de derecha a izquierda o de izquierda a derecha.
* A *fuente* que proporciona los glifos necesarios para representar el texto conformado y, opcionalmente, contiene “reglas de conformación” adicionales que guían el proceso de conformación del texto.

Los requisitos de la conformación del texto, especialmente para escrituras complejas y sus idiomas asociados, pueden ser extremadamente detallados y matizados, lo que indica la necesidad de software especializado que pueda aplicar “reglas” de conformación del texto potencialmente muy complejas. Como era de esperar, existe dicho software y se conoce como un *motor de conformación del texto*; el que vamos a tratar se llama [Harfbuzz](https://en.wikipedia.org/wiki/HarfBuzz), cuya documentación merece la pena leer; por ejemplo [¿Por qué necesito un motor de conformación?](https://harfbuzz.github.io/why-do-i-need-a-shaping-engine.html).

**Más información sobre la conformación del texto**

Se recomiendan encarecidamente estas breves introducciones:

* [¿Qué es la conformación del texto?](https://harfbuzz.github.io/what-is-harfbuzz.html#what-is-text-shaping)
* [¿Por qué necesito un motor de conformación?](https://harfbuzz.github.io/why-do-i-need-a-shaping-engine.html)

**Nota técnica de TeX: múltiples tecnologías de conformación (modelos)**

El motor de conformación del texto HarfBuzz admite varias “tecnologías de conformación” que difieren en cómo implementan el proceso de conformación; cada implementación se denomina un *conformador*, incluso en `luaotfload` documentación. El tema principal de este artículo es la conformación OpenType, pero una tecnología alternativa y de uso gratuito es [Graphite](https://scripts.sil.org/cms/scripts/page.php?site_id=projects\&item_id=graphite_aboutOT), desarrollada por [SIL International](https://www.sil.org/). Otro modelo de conformación admitido por HarfBuzz es [Apple Advanced Typography (AAT)](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6AATIntro.html)—las fuentes compatibles con AAT suelen usarse en plataformas tecnológicas de Apple.

**Ejemplo usando el conformador Graphite**

El siguiente ejemplo compone texto en urdu usando una fuente llamada [Awami Nastaliq](https://software.sil.org/awami/download/), que admite la conformación Graphite y está disponible en Overleaf. Awami Nastaliq fue creada por [SIL International](https://www.sil.org/), la organización responsable de desarrollar la tecnología Graphite.

El siguiente ejemplo demuestra la capacidad avanzada de conformación de las fuentes basadas en Graphite—observa cómo la `luaotfload` declaración de fuente selecciona la conformación Graphite usando `shaper=graphite2`.

```latex
\documentclass{article}
\usepackage{luaotfload}
\begin{document}

\font\urdutest={file:AwamiNastaliq-Regular.ttf:mode=harf;shaper=graphite2} at 100bp
% Tecnología
\pardir TRT\textdir TRT \urdutest ٹیکنالوجی

\vskip 75bp

% Educativo
\pardir TRT\textdir TRT \urdutest تعلیمی
\end{document}
```

[Abra este ejemplo en Overleaf.](https://www.overleaf.com/docs?engine=lualatex\&snip_name=Typesetting+Urdu+using+the+Graphite+shaper\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%7Bluaotfload%7D%0A%5Cbegin%7Bdocument%7D%0A%0A%5Cfont%5Curdutest%3D%7Bfile%3AAwamiNastaliq-Regular.ttf%3Amode%3Dharf%3Bshaper%3Dgraphite2%7D+at+100bp%0A%25+Technology%0A%5Cpardir+TRT%5Ctextdir+TRT+%5Curdutest+%D9%B9%DB%8C%DA%A9%D9%86%D8%A7%D9%84%D9%88%D8%AC%DB%8C%0A%0A%5Cvskip+75bp%0A%0A%25+Educational%0A%5Cpardir+TRT%5Ctextdir+TRT+%5Curdutest+%D8%AA%D8%B9%D9%84%DB%8C%D9%85%DB%8C%0A%5Cend%7Bdocument%7D)

Este ejemplo produce la siguiente salida:

![](/files/d09fbcd74a7f570954a27167dd55d504236d7bec)

#### Emoji y conformación del texto

La conformación del texto se ha introducido mediante ejemplos de un idioma con escritura compleja, el urdu. Sin embargo, puede sorprender descubrir que representar correctamente los glifos emoji requiere aplicar la conformación del texto a texto Unicode que contiene secuencias de caracteres emoji—[como señaló el desarrollador principal de HarfBuzz](https://github.com/harfbuzz/harfbuzz/issues/2428#issuecomment-639108677):

> ...la conformación de emoji con HarfBuzz entra plenamente en el ámbito y, de hecho, es necesaria para obtener emoji de familia, color de piel, etc.

Veremos ejemplos de esto.

### División de responsabilidades: motor de conformación del texto + fuentes OpenType

En la práctica, la conformación del texto es una “operación conjunta”, o división del trabajo, entre la lógica y las reglas incorporadas en el motor de conformación del texto y las reglas y datos de conformación adicionales incorporados en la(s) fuente(s) utilizada(s)—a partir de ahora cubriremos la conformación basada en OpenType *solo*.

Para realizar la conformación, al motor de conformación del texto normalmente se le proporciona algo de texto Unicode, una escritura y un idioma especificados, posiblemente una dirección de escritura, y, lo más importante, una fuente OpenType para usar durante el proceso de conformación: la fuente proporcionará la salida: un conjunto de glifos y datos de posicionamiento. Si se solicita, el motor de conformación puede aplicar reglas adicionales ([características OpenType](https://en.wikipedia.org/wiki/List_of_typographic_features#OpenType_typographic_features)) contenidas en la fuente OpenType que se esté usando; qué reglas aplicar suele poder seleccionarse por el usuario de la lista de características admitidas por la fuente.

El resultado del proceso de conformación es una *lista de glifos* contenida en la fuente OpenType, junto con *entre glifos* datos de posicionamiento. Esos datos de posicionamiento se refieren a *la colocación relativa de los glifos conformados*; no se refiere al posicionamiento absoluto dentro de la página compuesta ni de otros medios/contenidos como una página web, un tuit, etc. El software de renderizado (motor de composición tipográfica, navegador web, etc.) utiliza la información de posicionamiento entre glifos para garantizar que los glifos se coloquen correctamente unos con respecto a otros después de ser ensamblados e incorporados al resultado final.

#### ¿Qué es una lista de glifos?

Internamente, a cada glifo dentro de una fuente OpenType se le asigna un identificador numérico, un valor entero llamado índice de glifo, también llamado identificador de glifo o GID. Tras completar su tarea de conformación, el motor de conformación del texto devolverá sus resultados como una *lista de identificadores de glifo* más *datos de posicionamiento* para esos glifos.

A los glifos individuales dentro de las fuentes OpenType les asigna índices (identificadores) el creador de la fuente, lo que lo convierte en un valor muy específico de la fuente y arbitrario; también podría variar entre versiones de una fuente concreta. Nunca debes asumir que el mismo valor de GID se aplicará a glifos “similares” en fuentes distintas; casi con toda seguridad no será así. Si tienes una lista de identificadores de glifo proporcionada por un motor de conformación, solo puedes usarlos para acceder a los glifos de la fuente de la que se obtuvieron.

#### ¿Qué son las fuentes OpenType?

La web está *llena* de explicaciones y detalles sobre las fuentes OpenType, así que nos limitaremos a una breve descripción. La [especificación OpenType](https://docs.microsoft.com/en-us/typography/opentype/spec/) es un documento complejo diseñado para desarrolladores, pero, en esencia, define un formato de archivo, o contenedor, para datos de fuentes. Una fuente OpenType contiene datos que describen las formas de los glifos, junto con información sobre la(s) escritura(s) y el/los idioma(s) admitidos, metadatos sobre la fuente y diversas “tablas” que definen [características tipográficas](https://en.wikipedia.org/wiki/List_of_typographic_features#OpenType_typographic_features) admitidas por la fuente.

Normalmente, se puede indicar a un motor de conformación del texto que aplique de forma selectiva (use) las características de una fuente durante el proceso de conformación, aplicando efectos tipográficos específicos (“reglas”) que seleccionan el conjunto adecuado de glifos contenido en la fuente. La fuente elegida deberá admitir y proporcionar los glifos para cualquier característica que se le pida aplicar al motor de conformación del texto.

#### Glifos “codificados” y no codificados

Las fuentes OpenType incluyen una tabla de datos llamada [cmap](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap) (Character to Glyph Index Mapping), que asigna el conjunto de caracteres Unicode admitidos por la fuente al índice de glifo correspondiente en esa fuente. El siguiente video ofrece una breve mirada a la tabla cmap contenida en una fuente llamada `lmmono10-regiular.otf` (incluida en TeX Live).

{% embed url="<https://videos.ctfassets.net/nrgyaltdicpt/2537Y9gOUMWgd0t1guqt0X/482c53a9d8112ecae3d622aa7e00eef8/openType_cmap.mp4>" %}

Sin embargo, las fuentes suelen contener muchos glifos que no representan un carácter Unicode específico y no se incluyen como parte de esa tabla cmap. En consecuencia, el conjunto de glifos presentes en una fuente OpenType puede dividirse en dos conjuntos principales:

* glifos codificados que representan caracteres Unicode;
* glifos no codificados que no representan caracteres Unicode.

A los glifos codificados se puede acceder incluyendo el carácter Unicode apropiado en el texto—pero ¿qué ocurre con los glifos no codificados, cómo se usan/acceden? Esos glifos se usan normalmente para proporcionar la salida de las operaciones de conformación del texto, incluida la aplicación de características de la fuente para producir efectos visuales/tipográficos específicos.

### fuentes de color OpenType

Se espera que los caracteres emoji se muestren/reproduzcan a todo color: los emoji en blanco y negro no ofrecen del todo la “experiencia emoji completa”. Sin embargo, en el momento de la codificación inicial de los emoji por parte de Unicode, la [especificación de fuentes OpenType](https://docs.microsoft.com/en-us/typography/opentype/spec/) no tenía ninguna disposición adecuada para incrustar *colorful*-datos de glifos dentro de las fuentes OpenType. Esta “laguna” en OpenType llevó a los principales proveedores de tecnología/plataformas a buscar soluciones, y la consiguiente “carrera” resultó en [varias propuestas para ampliar OpenType](https://www.fontlab.com/news/color-font-format-proposals/) para dar soporte a las fuentes de color OpenType, no solo para mostrar caracteres emoji de color (glifos), sino para representar cualquier glifo en color.

#### Cuatro variantes de fuentes de color OpenType

[Adobe, Microsoft, Google y Apple presentaron propuestas cada uno](https://www.fontlab.com/news/color-font-format-proposals/) para ampliar OpenType y dar soporte a fuentes OpenType de color completo y, en última instancia, se adoptaron cuatro propuestas y se incluyeron en la especificación formal de OpenType. Para simplificar, podemos agrupar libremente esas cuatro variantes en basadas en vectores y basadas en ráster; sin embargo, como se muestra en este [repositorio de GitHub](https://github.com/simoncozens/test-fonts), la especificación OpenType es lo suficientemente flexible para dar soporte a archivos de fuentes de color OpenType que combinan esas cuatro tecnologías básicas.

* **Fuentes OpenType basadas en vectores:**
* **Microsoft**: las formas de los glifos se describen usando una forma de vectores de color en capas ([COLR](https://docs.microsoft.com/en-us/typography/opentype/spec/colr) y [CPAL](https://docs.microsoft.com/en-us/typography/opentype/spec/cpal) tablas).
* [**Adobe y Mozilla**](https://www.w3.org/2013/10/SVG_in_OpenType/) ([tabla SVG](https://docs.microsoft.com/en-us/typography/opentype/spec/svg)): las formas de los glifos se dibujan usando SVG, que admite glifos construidos a partir de vectores *e imágenes ráster*. Véase también [la guía de usuario de Adobe sobre fuentes SVG](https://helpx.adobe.com/fonts/user-guide.html/fonts/using/ot-svg-color-fonts.ug.html).
* **Fuentes OpenType basadas en ráster:**
* **Google**: los glifos se representan mediante imágenes PNG en color incrustadas en la fuente ([CBDT](https://docs.microsoft.com/en-us/typography/opentype/spec/cbdt) y [CBLC](https://docs.microsoft.com/en-us/typography/opentype/spec/cblc) tablas).
* **Apple**: los glifos también se representan mediante imágenes de color incrustadas en la fuente. Además de PNG, el mecanismo de Apple ([tabla sbix](https://docs.microsoft.com/en-us/typography/opentype/spec/colr)) también admite JPEG y TIFF.

Como consecuencia, los sistemas operativos y el software de aplicación que admiten fuentes de color OpenType deben lidiar con el panorama actual de tecnologías mixtas. Además, debes tener en cuenta que las fuentes individuales de color OpenType —y *versiones* de la misma fuente—

* tendrán una cobertura diferente del conjunto completo de [caracteres emoji Unicode](https://unicode.org/emoji/charts/emoji-list.html)—es decir, para cuántos caracteres emoji proporciona glifos la fuente;
* usararán diseños de glifo distintos para representar caracteres emoji individuales;
* variarán en las características que proporcionan para admitir usos más avanzados de los estándares Unicode, como [modificadores de emoji](https://unicode.org/reports/tr51/#Emoji_Modifiers_Table), y otras capacidades de procesamiento de texto emoji descritas en [Norma técnica Unicode #51: Emoji Unicode](https://unicode.org/reports/tr51/).

#### El revuelo en torno a HarfBuzz

Hemos aludido a la necesidad de un *motor de conformación del texto*motor de conformación del texto: software que toma un texto Unicode de entrada, escrito usando una combinación específica de escritura e idioma, y, usando una fuente designada, conforma ese texto en una secuencia de glifos, junto con datos de posicionamiento, que pueden utilizarse para componer tipográficamente el texto de entrada original.

[HarfBuzz](https://harfbuzz.github.io/) es uno de esos motores de conformación del texto: es [una biblioteca de código abierto](https://github.com/harfbuzz/harfbuzz) y el resultado de más de una década de investigación y desarrollo, y sigue desarrollándose y desplegándose activamente como parte de muchos productos de software. HarfBuzz en sí no realiza “composición tipográfica”, sino que proporciona “servicios de conformación del texto” al software que elige integrarlo, incluyendo XeTeX, LuaHBTeX, [Adobe PhotoShop y Adobe InDesign](https://en.wikipedia.org/wiki/HarfBuzz).

Al incorporar HarfBuzz, los motores TeX pueden aprovechar sus avanzadas capacidades de conformación del texto para ofrecer una composición tipográfica multilingüe muy sofisticada, particularmente para escrituras complejas como árabe, hebreo, devanagari y muchas otras. Observa también que HarfBuzz se usa para procesar y conformar caracteres emoji Unicode, que exploraremos con más detalle.

El siguiente gráfico resume el papel que desempeña HarfBuzz cuando se integra con software, como XeTeX o LuaHBTeX, durante la composición de texto en una escritura compleja, como el árabe:

![Vista general de la conformación del texto árabe con HarfBuzz](/files/919bc3395970eceb47e9916b31016419f2e01dca)

**Explorando HarfBuzz**

Cualquiera que esté interesado en aprender más sobre HarfBuzz y los servicios de conformación OpenType que proporciona a XeTeX y LuaHBTeX puede [descargar una distribución binaria de HarfBuzz](https://github.com/harfbuzz/harfbuzz/releases) que contiene la biblioteca HarfBuzz (para programadores) y utilidades de línea de comandos `hb-view` y `hb-shape`.

**Ejemplo: cómo usar hb-view**

Crea un nuevo archivo en tu editor de texto favorito compatible con UTF-8 y copia y pega los siguientes seis caracteres emoji 👋👋🏻👋🏼👋🏽👋🏾👋🏿 en ese archivo de texto; después guárdalo en formato UTF-8 en un archivo llamado, por ejemplo, `emoji.txt`.

Ten en cuenta que tu editor de texto podría mostrar versiones en blanco y negro de respaldo de los emoji porque no es capaz (o no está programado para) representar glifos de color. Una vez guardados esos 6 emoji, el archivo `emoji.txt` debería contener datos UTF-8 para la siguiente secuencia de caracteres emoji Unicode; hemos separado los modificadores emoji con comas solo por *facilitar la lectura*:

* `1F44B` para producir 👋
* `1F44B`, `1F3FB` para producir 👋🏻
* `1F44B`, `1F3FC` para producir 👋🏼
* `1F44B`, `1F3FD` para producir 👋🏽
* `1F44B`, `1F3FE` para producir 👋🏾
* `1F44B`, `1F3FF` para producir 👋🏿

Debería haber un total de **11** caracteres Unicode, cada uno generando 4 bytes de datos UTF-8, por lo que el resultado `emoji.txt` del archivo debería tener 44 bytes de longitud, excluyendo cualquier marcador de fin de línea utilizado al final de la línea que contiene el emoji.

El `hb-view` la utilidad puede usar el archivo `emoji.txt`, junto con una fuente de color OpenType adecuada de tu elección, como `NotoColorEmoji.ttf`, para generar un archivo SVG de la salida conformada por HarfBuzz. El siguiente ejemplo de línea de comandos, que debe **escribirse en una sola línea** en tu terminal, generará el archivo SVG `emoji.svg`:

```latex
hb-view --font-size=20 --output-file=\"emoji.svg\"
--output-format=svg --text-file=emoji.txt
--font-file=NotoColorEmoji.ttf
```

Al ejecutarse correctamente, el archivo `emoji.svg`, generado por `hb-view`puede abrirse con Inkscape y debería verse algo así:

![Hbvieemoji.png](/files/f4868d3951f22fa1461b46bf7389996dc114b6ce)

`hb-view` puede usarse para explorar la conformación de HarfBuzz para cualquier archivo de texto Unicode y fuente OpenType adecuados: ¡sin duda no se limita al uso con emoji! Escribe

```latex
hb-view --help-all
```

para ver la gran cantidad de opciones de línea de comandos de esta potente y útil utilidad. ¡Feliz conformación!

## Conformación del texto y motores TeX

Aquí revisaremos las capacidades de conformación del texto de XeTeX y de la familia de motores TeX LuaTeX.

### XeTeX

XeTeX se desarrolló a principios de los años 2000 y fue pionero en varias innovaciones en la composición tipográfica basada en TeX, en particular *incorporado* soporte para:

* leer texto Unicode en formato UTF-8;
* usar fuentes OpenType;
* conformación del texto para composición tipográfica multilingüe;
* composición tipográfica matemática basada en OpenType.

La capacidad de XeTeX para componer fácilmente y de forma cómoda idiomas con escritura compleja se debe a sus capacidades integradas de conformación del texto, originalmente basadas en el, ahora obsoleto, [ICU LayoutEngine](http://userguide.icu-project.org/layoutengine). Gracias al trabajo de Khaled Hosny, XeTeX pasó a usar HarfBuzz para la conformación del texto, como se indicó en un anuncio de [marzo de 2013](https://tug.org/pipermail/xetex/2013-March/024118.html). Para cualquiera que desee componer texto multilingüe, XeTeX suele citarse como el motor TeX preferido; pero ahora hay otra opción, LuaHBTeX, que exploraremos.

### LuaTeX y LuaHBTeX

El desarrollo de LuaTeX comenzó alrededor de 2005, pero siguió una filosofía de diseño bastante diferente a la de XeTeX, que incorporó nuevas funciones *directamente en* el software XeTeX. A diferencia de XeTeX, los desarrolladores de LuaTeX optaron por “...proporcionar un conjunto mínimo de herramientas y ninguna solución.” (véase [Reference Manual for LuaTeX](https://www.pragma-ade.com/general/manuals/luatex.pdf)). En lugar de proporcionar un conjunto de funciones adicionales *incorporadas en* los motores basados en LuaTeX, los mecanismos internos de los motores LuaTeX se abren para que los desarrolladores y usuarios expertos puedan aprovechar el lenguaje de scripting Lua integrado para construir sus propias soluciones.

Por ejemplo, a diferencia de XeTeX, el motor LuaTeX no puede *directamente* usar fuentes OpenType; en su lugar, las fuentes OpenType deben cargarse y “prepararse para su uso” mediante funciones de carga de fuentes escritas en código Lua. Esas funciones de carga de fuentes se denominan *callback* funciones: código Lua que LuaTeX llamará (“ejecutará”) cuando se haga una solicitud para cargar una fuente.

Además, el motor LuaTeX no proporciona ninguna *incorporado* capacidad de conformación del texto; eso también debe proporcionarlo código externo al que el motor LuaTeX pueda recurrir para que le proporcione servicios de conformación del texto. De nuevo, esto contrasta con el motor XeTeX, que incorporó capacidades de conformación del texto dentro del software central.

#### luaotfload: esencial para usar fuentes OpenType en LuaTeX/LuaHBTeX

el mecanismo de callback de LuaTeX para la carga de fuentes proporciona una gran flexibilidad, aunque a costa de programación adicional. Afortunadamente para los usuarios de LuaLaTeX, la comunidad TeX ha desarrollado un paquete llamado `luaotfload`luaotfload [la edición anual de TeX Live](https://www.tug.org/texlive/) y, por supuesto, está disponible para los usuarios de Overleaf.

`luaotfload` es [disponible en CTAN](https://ctan.org/pkg/luaotfload?lang=en) y tiene un [repositorio de desarrollo en GitHub](https://github.com/latex3/luaotfload) donde puedes seguir los últimos avances y [las nuevas versiones](https://github.com/latex3/luaotfload/releases).

`luaotfload` puede cargarse directamente en el preámbulo de un documento LaTeX mediante

```latex
\usepackage{luaotfload}
```

Observa que `luaotfload` es el nombre de un paquete de LaTeX *paquete*, lo que significa que tiene el nombre de archivo `luaotfload.sty`. Si quisieras usar `luaotfload` con plain TeX, puedes hacerlo añadiendo la línea

```latex
\input luaotfload.sty
```

a tu documento plain TeX.

Normalmente, los usuarios de LuaLaTeX —es decir, quienes componen LaTeX usando LuaTeX/LuaHBTeX— no necesitan interactuar directamente con `luaotfload` porque el [`fontspec` paquete](https://ctan.org/pkg/fontspec) cargará el `luaotfload` paquete por ti, encargándose de muchos detalles de bajo nivel mediante comandos de nivel de usuario proporcionados por el `fontspec` paquete.

### LuaHBTeX: nuevas opciones para la conformación del texto

`luaotfload` es una biblioteca Lua madura y potente que proporciona el manejo de fuentes OpenType de LuaTeX, junto con la provisión de servicios de conformación del texto para una variedad de idiomas y escrituras. Originalmente, las funciones de conformación del texto de `luaotfload` se implementaban en código Lua puro, pero la versión de TeX Live 2020 trajo otra opción generalizada para la conformación del texto: un nuevo motor basado en LuaTeX llamado LuaHBTeX.

La “HB” en LuaHBTeX significa HarfBuzz; en esencia, LuaHBTeX es el motor LuaTeX original *más* con un motor integrado de conformación del texto HarfBuzz. De acuerdo con la filosofía de diseño de LuaTeX, la disponibilidad de HarfBuzz no *automáticamente* garantiza que el texto será conformado por LuaHBTeX: HarfBuzz es otra herramienta que puede usarse para construir soluciones de conformación del texto.

La integración de HarfBuzz en LuaHBTeX es [programable mediante código Lua](#introduction-to-the-luahbtex-harfbuzz-api), lo que ha permitido `luaotfload`a los desarrolladores de ... añadir soluciones de conformación del texto basadas en HarfBuzz. En consecuencia, [a partir de la versión 3.1, lanzada el 5 de noviembre de 2019](https://github.com/latex3/luaotfload/releases/tag/v3.1), `luaotfload` se mejoró para aprovechar HarfBuzz, haciendo que las capacidades de conformación del texto de HarfBuzz fueran fáciles de acceder para el usuario general.

Los lectores interesados en los detalles técnicos de la integración de HarfBuzz con LuaTeX pueden leer este [artículo de Khaled Hosny](https://www.tug.org/TUGboat/tb40-1/tb124hosny-harfbuzz.pdf).

### luaotfload: dos opciones para la conformación del texto (¿cuándo usar HarfBuzz?)

Los usuarios de LuaLaTeX ahora tienen dos opciones para la conformación del texto:

* `luaotfload`la implementación original (basada en nodos) de ... para la conformación del texto, escrita íntegramente en Lua;
* `luaotfload`la conformación basada en HarfBuzz de ... —accedida mediante código Lua que llama a las funciones de conformación del texto de HarfBuzz.

`luaotfload` proporciona acceso a estos dos sistemas de conformación a través de su “`modo`”, aunque la mayoría de los usuarios usará la opción equivalente `fontspec` “`Renderer`” en lugar de usar directamente las funciones de nivel inferior de `luaotfload`.

Cada una de `luaotfload`las soluciones de conformación del texto de ... tienen sus fortalezas y debilidades (actuales), pero ¿cuál deberías usar y cuándo? Estos son algunos puntos a considerar:

* `luaotfload`el procesamiento nativo basado en nodos de ... puede consumir mucha memoria, especialmente para grandes fuentes OpenType CJK. Usar HarfBuzz para la conformación de texto CJK puede aportar mejoras de velocidad y reducir el uso de memoria.
* Usa HarfBuzz para escrituras complejas porque “...mejora enormemente la representación de las escrituras índicas y árabes y está altamente recomendado para dichas escrituras.” (véase `luaotfload` manual).
* La integración de HarfBuzz en `luaotfload` sigue siendo relativamente nueva y está en desarrollo continuo. En el momento de redactar esto (julio de 2021), es aconsejable usar la conformación integrada de luaotfload (estableciendo `mode=node`) [incidencia de GitHub](https://github.com/latex3/luaotfload/issues/175#issue-801120377), que resume los problemas y debates. Si quieres experimentar, puedes usar `luaotfload` para cargar un archivo de fuente y crear dos fuentes LaTeX: una que utiliza conformación basada en HarfBuzz y otra que utiliza conformación basada en Lua. Overleaf creó un [proyecto de ejemplo](#sample-project-arabic-shaping), que demuestra esto.
* No uses HarfBuzz para manejar fuentes matemáticas. Como comentaron los desarrolladores en tex.stackexchange, HarfBuzz [no está diseñado para manejar fuentes para composición tipográfica matemática](https://tex.stackexchange.com/questions/544881/does-luahbtex-with-harfbuzz-renderer-completely-supports-math-formating) así que no lo uses para ese propósito.

**Proyecto de ejemplo: conformación árabe**

Aquí tienes un proyecto de Overleaf que usa varias tipografías árabes de alta calidad para comparar `luaotfload`los servicios de conformación del texto basados en nodos de ... (`mode=node`) con los de HarfBuzz (`mode=harf`):

* <https://www.overleaf.com/latex/examples/complex-script-shaping-using-luaotfload-and-harfbuzz/gfssprnhfddn>

Este proyecto incluye una salida mostrada en la siguiente imagen:

![Composición tipográfica del árabe](/files/af959dba75977aa914957ca63379ce2d0743416d)

### Elegir el “Renderer” en fontspec

Como se señala en su [documentación](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf), `fontspec` “...permite a los usuarios de XeTeX o LuaTeX cargar fuentes OpenType en un documento LaTeX”. Si usas los motores LuaTeX o LuaHBTeX, `fontspec` cargará el `luaotfload` la biblioteca por ti y, además, proporcionar un conjunto de cómodos comandos de nivel de usuario que alivian la necesidad de interactuar con `luaotfload`la funcionalidad de bajo nivel de ...

Entonces, ¿cómo eliges entre la conformación de HarfBuzz o la conformación integrada proporcionada por `luaotfload`? La respuesta está en el excelente [`fontspec` documentación](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf), específicamente la Parte VI: características de fuente exclusivas de LuaTeX. `fontspec` proporciona un ajuste llamado `Renderer` que puede establecerse cuando la fuente se define mediante `fontspec`. `Renderer` controla el procesamiento de bajo nivel de la fuente. Las dos opciones de interés son

* `Renderer = Node`: el “modo” predeterminado para componer fuentes OpenType: esto usa `luaotfload`las funciones de conformación del texto de ... implementadas íntegramente en Lua.
* `Renderer = Harfbuzz`: este “modo” define/carga la fuente para usarla con el motor de conformación del texto HarfBuzz. `luaotfload` usa la API de LuaHBTeX para llamar funciones en HarfBuzz.

Para más información, consulte el [`fontspec` documentación](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf).

## motores TeX, HarfBuzz y emoji en color

Aunque XeTeX y LuaHBTeX integran ambos HarfBuzz, ofrecen distintos niveles de compatibilidad con algunas de las funciones más avanzadas de HarfBuzz, en particular la carga y el uso de fuentes OpenType en color.

### XeTeX y fuentes OpenType en color

Como se señaló, hay dos categorías de fuentes OpenType en color según el formato de datos utilizado para almacenar los glifos de la fuente: basadas en vectores y basadas en ráster.

#### XeTeX y fuentes OpenType en color basadas en ráster

XeTeX no puede cargar fuentes OpenType en color basadas en ráster, como la de Google [Noto Color Emoji](https://www.google.com/get/noto/help/emoji/) incluida con TeX Live 2020. Por ejemplo, si intenta cargar Noto Color Emoji (NotoColorEmoji.ttf), XeLaTeX fallará con un error potencialmente engañoso que afirma que Noto Color Emoji “no se puede encontrar”. El siguiente código LaTeX, compuesto con XeLaTeX, *no funciona*:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont{NotoColorEmoji.ttf}
\newcommand{\smiley}{{\emojifont\char"1F600}}
\smiley
\end{document}
```

[Abra este código XeLaTeX en Overleaf (no ***no*** funciona).](https://www.overleaf.com/docs?engine=xelatex\&snip_name=XeTeX+failure\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%7Bfontspec%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cnewfontfamily%5Cemojifont%7BNotoColorEmoji.ttf%7D%0A%5Cnewcommand%7B%5Csmiley%7D%7B%7B%5Cemojifont%5Cchar%221F600%7D%7D%0A%5Csmiley%0A%5Cend%7Bdocument%7D)

Falla con el error:

```
! Error de Package fontspec: La fuente "NotoColorEmoji" no se puede encontrar.
```

De manera similar, un ejemplo sencillo de Plain TeX procesado por XeTeX también falla

```latex
\font\emojifont="[NotoColorEmoji.ttf]" at 12pt
\emojifont \char"1F600
\bye
```

[Abra este ejemplo de Plain TeX (XeTeX) en Overleaf (no ***no*** funciona).](https://www.overleaf.com/docs?engine=latex_dvipdf\&snip_name\[]=main.tex\&snip\[]=%25%5Ctitle%7Bdummy+title%7D%0A%5Cfont%5Cemojifont%3D%22%5BNotoColorEmoji.ttf%5D%22+at+12pt%0A%5Cemojifont+%5Cchar%221F600%0A%5Cbye\&snip_name\[]=readme\&snip\[]=This+project+uses+a+latexmkrc+file+to+run+xetex+not+xelatex\&snip_name\[]=latexmkrc\&snip\[]=%24latex+%3D+%27xetex%25O+%25S%27%3B+%23+to+use+the+xetex+engine\&main_document=main.tex)

El ejemplo de Plain TeX informa un mensaje de error similar, pero distinto:

```
! Fuente \emojifont=[NotoColorEmoji.ttf] at 12.0pt no cargable: archivo de métrica (TFM) archiv
o o fuente instalada no encontrada.
l.1 \font\emojifont="[NotoColorEmoji.ttf]" at 12pt

No pude leer los datos de tamaño de esta fuente,
así que ignoraré la especificación de la fuente.
[Los expertos pueden corregir archivos TFM usando TFtoPL/PLtoTF.]
Tal vez podría intentar insertar una especificación de fuente diferente;
p. ej., escriba `I\font<same font id>=<substitute font name>'.
```

**Ejemplo de Plain LuaHBTeX**

A modo de comparación, aquí hay un ejemplo mínimo de Plain TeX compilado con LuaHBTeX

```latex
\input luaotfload.sty
\font\emojifont=NotoColorEmoji.ttf:mode=harf at 12pt
\emojifont \Uchar"1F600
\bye
```

[Abra este ejemplo de Plain TeX (LuaHBTeX) en Overleaf (se compila correctamente).](https://www.overleaf.com/docs?engine=latex_dvipdf\&snip_name\[]=main.tex\&snip\[]=%25%5Ctitle%7BPlain+TeX+with+LuaHBTeX%7D%0A%5Cinput+luaotfload.sty%0A%5Cfont%5Cemojifont%3DNotoColorEmoji.ttf%3Amode%3Dharf+at+12pt%0A%5Cemojifont+%5CUchar%221F600%0A%5Cbye\&snip_name\[]=readme\&snip\[]=This+project+uses+a+latexmkrc+file+to+run+luahbtex+not+lualatex\&snip_name\[]=latexmkrc\&snip\[]=%24latex+%3D+%27luahbtex+%25O+%25S%27%3B+%23+to+use+the+luahbtex+engine\&main_document=main.tex)

#### La verdadera causa del fallo de XeTeX

Los mensajes de error proporcionados por XeTeX oscurecen parcialmente la causa real del problema: las fuentes OpenType en color, en particular las variantes basadas en ráster, no *no* son compatibles con XeTeX. En realidad, XeTeX (Kpathsea) puede *encontrar* la fuente Noto Color Emoji, pero XeTeX no puede *cargarla* por completo y no puede inicializar las tablas internas de datos de fuente necesarias para usar esa fuente en la composición tipográfica. Internamente, XeTeX *comienza* el proceso de carga de la fuente y la prueba por su “escalabilidad” (usando la definición de “escalabilidad” de FreeType), pero esa prueba falla y XeTeX emite un mensaje de error estándar del motor TeX, posiblemente engañoso.

**Nota técnica**

Se investigó el procesamiento que XeTeX hace de NotoColorEmoji.ttf compilando una versión de depuración del ejecutable XeTeX. Se usó el IDE Eclipse para establecer un punto de interrupción en la función de XeTeX `creatFontFromFile(filename, index, pointsize)`, y luego avanzar paso a paso por el código para observar el procesamiento posterior.

#### XeTeX y fuentes OpenType en color basadas en vectores

XeTeX puede *cargarla* usar fuentes OpenType en color basadas en vectores, pero no producirá emoji en color en el PDF resultante, si es que XeTeX produce alguno. A diferencia de LuaTeX, LuaHBTeX y pdfTeX, XeTeX no *directamente* emite documentos compuestos en formato PDF. En cambio, XeTeX genera un `.xdv` (e**x**xten **dv**i) archivo intermedio que se convierte a PDF mediante una utilidad llamada `xdvipdfmx`. En el momento de escribir esto, `xdvipdfmx` no puede incrustar los datos apropiados de glifos emoji en color en el PDF, por lo que, en el mejor de los casos, verá emoji en monocromo —el resultado “de reserva”— en el PDF, o quizás nada en absoluto, dependiendo de la fuente utilizada.

Aquí hay un ejemplo de XeLaTeX que usa la fuente OpenType en color [TwemojiMozilla.ttf](https://ctan.org/tex-archive/fonts/twemoji-colr), disponible en TeX Live. TwemojiMozilla.ttf usa el formato vectorial COLR/CPAL de Microsoft para almacenar glifos en color y se incluye con TeX Live 2020. En este ejemplo, XeTeX puede cargar la fuente, generar un `.xdv` y un archivo PDF, pero el glifo emoji no está presente en el PDF compuesto:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont{TwemojiMozilla.ttf}
\newcommand{\smiley}{{\emojifont\char"1F600}}
Aquí hay una carita sonriente: \smiley
\end{document}
```

[Abra este código XeLaTeX en Overleaf (NO funciona).](https://www.overleaf.com/docs?engine=xelatex\&snip_name=XeTeX+failure\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%7Bfontspec%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cnewfontfamily%5Cemojifont%7BTwemojiMozilla.ttf%7D%0A%5Cnewcommand%7B%5Csmiley%7D%7B%7B%5Cemojifont%5Cchar%221F600%7D%7D%0AHere+is+a+smiley%3A+%5Csmiley%0A%5Cend%7Bdocument%7D)

En cambio, el código anterior funciona con LuaLaTeX si define `\emojifont` usando el `fontspec` ajuste `[Renderer=HarfBuzz]`:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont{TwemojiMozilla.ttf}[Renderer=HarfBuzz]
\newcommand{\smiley}{{\emojifont\char"1F600}}
Aquí hay una carita sonriente: \smiley
\end{document}
```

[Abra este código LuaLaTeX en Overleaf (funciona).](https://www.overleaf.com/docs?engine=lualatex\&snip_name=LuaLaTeX+emoji+example\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%7Bfontspec%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cnewfontfamily%5Cemojifont%7BTwemojiMozilla.ttf%7D%5BRenderer%3DHarfBuzz%5D%0A%5Cnewcommand%7B%5Csmiley%7D%7B%7B%5Cemojifont%5Cchar%221F600%7D%7D%0AHere+is+a+smiley%3A+%5Csmiley%0A%5Cend%7Bdocument%7D)

### LuaHBTeX y fuentes OpenType en color

A través de su motor integrado de composición HarfBuzz y la `luaoftload` biblioteca, LuaHBTeX proporciona compatibilidad con las cuatro variedades de fuente OpenType en color. Los usuarios de LuaLaTeX pueden aprovechar plenamente el procesamiento basado en Unicode de texto que contiene caracteres emoji o simplemente embellecer sus documentos con texto muy colorido usando fuentes OpenType en color.

Como se señaló antes, las cuatro variantes de fuente OpenType en color pueden clasificarse en dos grupos:

* las que contienen glifos en formatos de imagen ráster, como PNG;
* otras que usan formatos vectoriales de SVG o el mecanismo COLR/CPAL de Microsoft.

Los formatos de glifos basados en vectores tienen la ventaja de la escalabilidad: producen gráficos de glifos nítidos a cualquier tamaño de punto.

**Uso de fuentes de color Microsoft COLR/CPAL con LuaHBTeX**

Si desea usar un formato vectorial para sus fuentes emoji OpenType en color, eche un vistazo a la fuente [TwemojiMozilla.ttf](https://ctan.org/tex-archive/fonts/twemoji-colr?lang=en), que se basa en el formato COLR/CPAL de Microsoft. TwemojiMozilla.ttf está incluida con TeX Live, pero puede obtener la versión más reciente desde su [repositorio de GitHub](https://github.com/mozilla/twemoji-colr/releases) y subirla a su proyecto de Overleaf.

Aquí hay un pequeño, `fontspec`-basado, ejemplo que usa `Renderer=Harfbuzz`, que compone un pato emoji grande (vectorial):

```latex
\documentclass{article}
\usepackage{fontspec}
\title{Demostración del pato}
\begin{document}
\newfontfamily\emojifont[Renderer=Harfbuzz,SizeFeatures={Size=400}]{TwemojiMozilla.ttf}
\emojifont\Uchar"1F986
\end{document}
```

[Abra este ejemplo de LuaLaTeX para componer un pato vectorial.](https://www.overleaf.com/docs?engine=lualatex\&snip_name=Typesetting+an+emoji+duck\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%7Bfontspec%7D%0A%5Ctitle%7BDuck+demo%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cnewfontfamily%5Cemojifont%5BRenderer%3DHarfbuzz%2CSizeFeatures%3D%7BSize%3D400%7D%5D%7BTwemojiMozilla.ttf%7D%0A%5Cemojifont%5CUchar%221F986%0A%5Cend%7Bdocument%7D)

Aquí está el pato (vectorial) producido por el ejemplo anterior:

![](/files/d9cd4ba188c0d865ccdfdbf15af3b05f57069197)

#### Uso de fuentes de color OpenType basadas en SVG con LuaHBTeX

En el momento de escribir esta actualización del artículo (julio de 2023), hay poca documentación formal sobre el uso de fuentes OpenType en color con sabor SVG con LuaLaTeX. Algunos [comentarios realizados en discusiones en línea](https://github.com/latex3/luaotfload/issues/96) sugieren usar `fontspec`de `RawFeature`, como se muestra en el pseudocódigo a continuación. Sustituya `*nombre de su archivo de fuente SVG aquí*` por el nombre de un archivo de fuente basado en SVG al que su código LaTeX pueda acceder:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emoji[RawFeature={+svg},SizeFeatures={Size=20}]{nombre de su archivo de fuente SVG aquí}
\emoji Su emoji aquí...
\end{document}
```

Si omite `fontspec` y carga `luaotfload` directamente, puede que necesite declarar y especificar una fuente de la siguiente manera: nuestros experimentos indican que necesita omitir la `mode=harf` opción para que esto funcione:

```latex
\font\emoji=[nombre de su archivo de fuente SVG aquí]:+svg;
```

**Algunas notas de precaución**

Los lectores interesados en usar fuentes OpenType en color con sabor SVG deben tener en cuenta:

* Las fuentes OpenType con sabor SVG que contienen una gran cantidad de glifos pueden ser [computacionalmente costosas para LuaLaTeX](#processing-svg-glyph-data) de procesar, lo que podría provocar [tiempos de espera de Overleaf](/latex/es/base-de-conocimientos/038-fixing-and-preventing-compile-timeouts.md).
* La compatibilidad de LuaLaTeX con estas fuentes podría [considerarse experimental](https://github.com/latex3/luaotfload/issues/96#issuecomment-530317399): los resultados pueden variar según la versión de TeX Live utilizada por su proyecto; por consiguiente, es aconsejable experimentar y proceder con cautela.

**Procesamiento de datos SVG de glifos**

SVG permite a los diseñadores producir diseños complejos y coloridos que representan los glifos de una fuente, sujetos a algunas restricciones de SVG [documentadas en la especificación OpenType](https://docs.microsoft.com/en-us/typography/opentype/spec/svg). Sin embargo, los motores TeX, incluido LuaHBTeX, no pueden importar directamente (usar) archivos o datos SVG, como los datos SVG utilizados para describir las formas de los glifos dentro de las fuentes OpenType en color con sabor SVG. Los datos SVG de un glifo deben convertirse a formato PDF porque LuaHBTeX puede usarlo para componer el glifo y producir el documento PDF final. Esa conversión de SVG a PDF la gestiona código Lua dentro de `luaoftload`: los datos SVG de cada glifo se extraen del archivo de fuente, se guardan en un temporal `.svg` archivo y se convierten a PDF usando Inkscape mediante su línea de comandos. Extraer los datos SVG y convertirlos a PDF conlleva cierta sobrecarga de procesamiento, lo que puede resultar en tiempos de compilación de documentos prolongados, especialmente en documentos que usan grandes fuentes SVG que contienen miles de glifos emoji.

#### Fuentes OpenType en color basadas en ráster

**Uso del formato de fuente OpenType en color CBDT/CBLC de Google con LuaHBTeX**

[Noto Color Emoji](https://fonts.google.com/noto/specimen/Noto+Color+Emoji) es una fuente OpenType en color incluida con TeX Live, lo que facilita su uso en un proyecto de Overleaf. Como Noto Color Emoji usa gráficos en formato PNG para representar los glifos emoji, podemos usarla para componer un pato emoji grande (ráster), como demuestra el siguiente ejemplo. Observe de nuevo que la `fontspec` declaración de fuente (`\emojifont`) usa `Renderer=Harfbuzz`.

```latex
\documentclass{article}
\usepackage{fontspec}
\title{Demostración del pato}
\begin{document}
\newfontfamily\emojifont[Renderer=Harfbuzz,SizeFeatures={Size=400}]{NotoColorEmoji.ttf}
\emojifont\Uchar"1F986
\end{document}
```

[Abra este ejemplo de LuaLaTeX para componer un pato ráster.](https://www.overleaf.com/docs?engine=lualatex\&snip_name=Typesetting+a+large+raster+duck\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%7Bfontspec%7D%0A%5Ctitle%7BDuck+demo%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cnewfontfamily%5Cemojifont%5BRenderer%3DHarfbuzz%2CSizeFeatures%3D%7BSize%3D400%7D%5D%7BNotoColorEmoji.ttf%7D%0A%5Cemojifont%5CUchar%221F986%0A%5Cend%7Bdocument%7D)

Aquí está el pato ráster producido por el ejemplo anterior:

![Un pato emoji ráster compuesto por LaTeX](/files/8ea6e528914ee73abaaa3fc6339b355c5584db56)

Si intenta usar `NotoColorEmoji.ttf` pero omite `[Renderer=Harfbuzz]` del `fontspec` la declaración, LuaHBTeX fallará y emitirá un mensaje de error cuando intente escribir el archivo PDF:

```latex
! error:  (file /usr/local/texlive/2020/texmf-dist/fonts/truetype/google/noto-em
oji/NotoColorEmoji.ttf) (ttf): loca table not found
```

La razón de este error en la [tabla loca](https://docs.microsoft.com/en-us/typography/opentype/spec/loca) es [explicada en GitHub](https://github.com/latex3/luaotfload/issues/98#issuecomment-531610153).

**Uso del formato de fuente OpenType en color sbix de Apple con LuaHBTeX**

Las pruebas fuera de línea demuestran que LuaHBTeX admite la `sbix` variante de fuente OpenType en color, pero, al escribir este artículo, no hemos podido localizar una fuente emoji en color de la `sbix`-variant que tenga una licencia adecuada para demostrar la composición tipográfica de un pato. Por favor, [contactarnos](https://www.overleaf.com/contact) si conoce una, y actualizaremos rápidamente este artículo para usarla.

## Introducción a la API HarfBuzz de LuaHBTeX

![Db.gif](/files/97ebad5801b425b36578eacc0a23b5765b7758c4) ![Db.gif](/files/97ebad5801b425b36578eacc0a23b5765b7758c4)

La composición de texto, especialmente para lenguajes con escrituras complejas, e incluso para emoji, es una tarea intrínsecamente difícil, así que, como era de esperar, HarfBuzz es una biblioteca sofisticada con la que puede ser complicado trabajar, a menos que ya esté familiarizado con operaciones de composición de texto. En esta sección final, analizamos la integración de HarfBuzz en LuaHBTeX y cómo acceder a ella mediante código Lua dentro de `\directlua`.

Nuestro ejemplo usa un código bastante básico para demostrar la API HarfBuzz de LuaHBTeX. Está algo forzado, no es de calidad de producción ni muy práctico porque su único propósito es introducir algunas ideas clave. Hemos dividido el código Lua en dos `\directlua` bloques: el primero carga la `luaharfbuzz` biblioteca y crea algunas variables globales que usaremos en nuestro segundo `\directlua` bloque, donde definimos una macro llamada `\codestoemoji`.

Parece apropiado reproducir el uso que hizo Knuth de los dobles signos de doble curva peligrosa (imagen cortesía de [este sitio](http://www.truetex.com/db.htm)) porque el contenido es algo de bajo nivel y “mira bajo el capó”, aunque esperamos que pueda ser de interés para el lector más intrépido. La integración de HarfBuzz en LuaHBTeX se deriva del [proyecto luaharfbuzz en GitHub](https://github.com/ufyTeX/luaharfbuzz/wiki#projects-using-luaharfbuzz) donde puede encontrar una [introducción al proyecto](https://github.com/ufyTeX/luaharfbuzz/wiki) junto con una [lista de la API de luaharfbuzz](http://ufytex.github.io/luaharfbuzz/).

### Primeros pasos: cargar la biblioteca luaharfbuzz y encontrar una fuente

Para usar la API HarfBuzz de LuaHBTeX primero necesitamos cargar la biblioteca (módulo) llamada `luaharfbuzz`, incorporada en LuaHBTeX, y guardar la tabla devuelta en una variable (global) que llamaremos `hblib`:

```latex
hblib=require("luaharfbuzz")
```

A continuación, necesitamos localizar una fuente emoji OpenType en color adecuada: usaremos Noto Color Emoji —obsérvese que estamos siendo muy perezosos y no hacemos ninguna comprobación de errores en caso de no encontrarla—. Para encontrarla, usaremos la `kpse` biblioteca (Kpathsea), que también forma parte de LuaTeX/LuaHBTeX:

```latex
pathtofontfile=kpse.find_file("NotoColorEmoji.ttf","truetype fonts")
```

Ahora que tenemos acceso a la biblioteca HarfBuzz, a través de nuestra variable `hblib`, y la ruta a una fuente adecuada (`pathtofontfile`), podemos empezar a usar `hblib`. Para empezar, crearemos una fuente HarfBuzz y una cara HarfBuzz para usar en el segundo `\directlua` bloque de código donde definimos nuestra macro.

```latex
% Crear la cara HarfBuzz y la fuente HarfBuzz a partir de Noto Color Emoji
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)
```

#### Fuente HarfBuzz y cara HarfBuzz: ¿qué son?

A [objeto de cara HarfBuzz](https://harfbuzz.github.io/fonts-and-faces.html) representa una tipografía cargada desde un archivo de fuente, pero sin establecer parámetros específicos (como el tamaño). Un [objeto de fuente HarfBuzz](https://harfbuzz.github.io/fonts-and-faces.html) representa una *instancia específica* de una cara HarfBuzz; en consecuencia, se pueden derivar diferentes objetos de fuente HarfBuzz de una sola cara HarfBuzz: cada fuente HarfBuzz puede tener sus propiedades, como el tamaño, establecidas en valores diferentes. Una cara HarfBuzz es un nivel de abstracción superior a una fuente HarfBuzz.

### Uso de los glifos de una fuente para crear archivos PNG

La parte final de nuestro primer `\directlua` bloque es una función llamada `writePNGglyph(hbfontobject, glyphID)` que usamos para demostrar que algunas fuentes OpenType en color, como Noto Color Emoji, usan gráficos PNG para representar los glifos emoji que contienen.

Esta función usa la API HarfBuzz de LuaHBTeX para extraer datos PNG de los glifos y escribir esos datos en un `.png` archivo llamado `Graphics<glyphID>.png`. El nombre de ese `.png` archivo se devuelve para usarlo en `\includegraphics` para incrustar imágenes PNG de glifos en nuestro PDF compuesto.

Con el `writePNGglyph(hbfontobject, glyphID)` código en su lugar, nuestro primer `\directlua` bloque de código se ve así:

```latex
\directlua{

% Cargar la biblioteca luaharfbuzz desde LuaHBTeX
hblib=require("luaharfbuzz")

% Localizar la fuente Noto Color Emoji en el servidor de Overleaf
pathtofontfile=kpse.find_file("NotoColorEmoji.ttf","truetype fonts")

% Crear la cara HarfBuzz y la fuente HarfBuzz a partir de Noto Color Emoji
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)

% Esta función acepta una fuente y un ID de glifo:
% extrae los datos PNG de los glifos y los escribe
% en un archivo .png

function writePNGglyph(hbfontobject, glyphID)

    % Obtener datos PNG del glifo
    local pngblob=hbfontobject:ot_color_glyph_get_png(glyphID)
    local pngdata=pngblob:get_data()

    % Construir un nombre de archivo para nuestro archivo .png
    local fname="Glyph"..glyphID..".png"

    % Escribir el archivo .png y devolver el nombre del archivo
    local output = assert(io.open(fname, "wb"))
    output:write(pngdata)
    output:close()

    % Devolver el nombre del archivo para que lo use \includegraphics
    return fname
end
}
```

### Segundo bloque \directlua: crear la macro \codestoemoji

El objetivo es definir una macro `\codestoemoji` que podamos llamar con un fragmento de texto que contenga códigos de caracteres emoji que queremos que HarfBuzz componga. En concreto, usaremos `\Uchar<código de carácter>` para representar cada carácter emoji; por ejemplo:

```latex
\codestoemoji{\Uchar"1F3F4\Uchar"E0067\Uchar"E0062\Uchar"E0065\Uchar"E006E\Uchar"E0067\Uchar"E007F}
```

Sucede mucho dentro de la definición de `\codestoemoji` que explicaremos a continuación, pero la definición se ve así:

```latex
\newcommand{\codestoemoji}[1]{%
\directlua{

local str="#1"
local hbbuffer = hblib.Buffer.new()
hbbuffer:add_utf8(str)

hbbuffer:set_direction(hblib.Direction.new("ltr"))
local res = hblib.shape_full(hbfont, hbbuffer, {},{})

if (res) then
    local hbglyphs=hbbuffer:get_glyphs()
    % La tabla de glifos, hbglyphs, es indexada desde 1
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Reducir el tamaño de nuestras imágenes PNG importadas
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
}}
```

#### Comprender la definición de la macro \codestoemoji

El `\codestoemoji` macro es principalmente código Lua contenido dentro de `\directlua`, así que si desea saber más sobre cómo *cómo* `\directlua` funciona, consulte el artículo de Overleaf [Comprender `\directlua`](/latex/es/articulos-en-profundidad/09-an-introduction-to-luatex-part-2-understanding-directlua.md). Explica cómo LuaTeX y LuaHBTeX procesan `\directlua` cuando se incluyen comandos TeX/LaTeX en el código Lua y, en particular, la necesidad de usar `\noexpand` y `\unexpanded`.

**Tratamiento del parámetro de macro: "#1"**

La macro comienza con estas tres líneas:

```latex
local str="#1"
local hbbuffer = hblib.Buffer.new()
hbbuffer:add_utf8(str)
```

que realizan las siguientes tareas:

* `local str="#1"`: esto crea una cadena Lua a partir de la entrada pasada por la macro;
* `local hbbuffer = hblib.Buffer.new()`: esto usa la API HarfBuzz para crear un búfer que contenga el texto que queremos que HarfBuzz componga;
* `hbbuffer:add_utf8(str)`: esto añade al búfer HarfBuzz una cadena en formato UTF-8, creada a partir de la entrada de nuestra macro.

La primera línea de código

```latex
local str="#1"
```

parece bastante sencilla, pero su funcionamiento implica bastante complejidad, que conviene explorar con un poco más de detalle.

Si consideramos la tercera línea de código

```latex
hbbuffer:add_utf8(str)
```

vemos que usa nuestra `str` variable para proporcionar al búfer HarfBuzz una cadena Unicode con formato UTF-8. Para que eso funcione, la variable `str` debe contener a su vez texto Unicode con formato UTF-8; así que surge la pregunta: *cómo* ¿convirtió LuaHBTeX el argumento de macro `"#1"`, que contiene `\Uchar` comandos, en la variable de cadena Lua `str` que contiene texto UTF-8 para HarfBuzz?

Si miramos el uso previsto de la `\codestoemoji` macro:

```latex
\codestoemoji{\Uchar"1F3F4\Uchar"E0067\Uchar"E0062\Uchar"E0065\Uchar"E006E\Uchar"E0067\Uchar"E007F}
```

la entrada, como `\Uchar"1F3F4\Uchar"E0067\Uchar"E0062\Uchar"E0065...`, no se parece en nada a una secuencia de caracteres emoji codificados en UTF-8. Además, HarfBuzz no sabe nada sobre comandos TeX. De alguna manera, la entrada TeX en bruto compuesta por `\Uchar` comandos se transforma en caracteres Unicode codificados en UTF-8 que HarfBuzz puede usar, pero *cómo*?

La respuesta está en el comportamiento del `\Uchar` comando: intentar llamar a `\codestoemoji` usando `\char` en lugar de `\Uchar` fallará, pero *por qué*?

**\Uchar: expansión en \directlua**

Cuando se llama a la `\codestoemoji` macro, el `\directlua` comando, almacenado dentro de la definición de la macro, tiene que preparar el código Lua para enviarlo al intérprete Lua integrado de LuaHBTeX. Parte de ese proceso de preparación del código es la expansión de cualquier comando TeX/LaTeX presente en el código Lua original de la definición de la macro, junto con la expansión de cualquier argumento de macro proporcionado por el usuario. Ese proceso de expansión produce una lista de tokens que luego se convierte de nuevo en texto, generando el código Lua que se pasará al intérprete Lua. Para mayor comodidad, reproducimos un diagrama del artículo de Overleaf [Comprender `\directlua`](/latex/es/articulos-en-profundidad/09-an-introduction-to-luatex-part-2-understanding-directlua.md):

![La mecánica de \directlua](/files/1553c5a9756329acd0adf456ff06de06f8074c99)

La macro `\codestoemoji` está pensada para ser llamada usando `\Uchar` comandos y,  [como se señaló antes en el artículo](#the-key-difference-expansion), `\Uchar` es un comando expandible cuya expansión genera un token de carácter. Dentro de las actividades de procesamiento de `\directlua`, LuaHBTeX expande cada `\Uchar<código de carácter>` comando donde *elimina* cada `\Uchar<código de carácter>` de la entrada y *lo reemplaza* lo reemplaza por el valor de expansión correspondiente: un token de carácter que representa el `<código de carácter>`.

En la etapa final del procesamiento, la lista inicial de tokens generada por `\directlua` se convierte *de vuelta a texto* para convertirse en el código Lua destinado al intérprete de Lua (véase el diagrama anterior). Todos los tokens de caracteres producidos por la expansión de `\Uchar` también son *convertidos de nuevo a texto*: esa conversión de tokens de caracteres a texto genera las representaciones UTF-8 de los originales `<código de carácter>` valores.

En nuestro ejemplo, para cuando el código Lua se genera y está listo para el intérprete de Lua, la entrada de la macro para "#1" se ha convertido en una secuencia de texto UTF-8: la `str` variable es ahora una cadena de texto UTF-8 que puede añadirse de forma segura al búfer de HarfBuzz.

**¿Por qué no funciona \char?**

La respuesta directa es porque `\char` es *no* un comando expandible. A diferencia de `\Uchar` los comandos, `\char` comandos *no se eliminan* de la entrada durante `\directlua`el procesamiento inicial de ’s para generar una lista de tokens, sino que “pasan a través” para incorporarse a la lista de tokens que está siendo construida por `\directlua`. Por ejemplo, si el argumento de `\codestoemoji` contenía `\char"1F3F4` LuaHBTeX convertiría eso en una secuencia de tokens y los almacenaría como parte de la lista total de tokens que se está generando.

En la siguiente etapa del procesamiento, al convertir los tokens de vuelta a texto, el código Lua resultante contendría la *cadena literal* `\char"1F3F4` dentro del texto usado para definir nuestra variable `str`. Cuando el contenido de `str` se añade al búfer de HarfBuzz, no contendrá una secuencia codificada en UTF-8 que represente el carácter emoji "1F3F4; contendrá la cadena literal `\char"1F3F4`, que HarfBuzz intentará componer y que, para nuestros propósitos, no produciría un glifo de emoji. Por cierto, la cadena `\char"1F3F4` también generaría errores de sintaxis de Lua a menos que se creara como una “cadena de corchetes largos”—véase [Qué son las secuencias de escape de Lua](/latex/es/articulos-en-profundidad/09-an-introduction-to-luatex-part-2-understanding-directlua.md#what-are-e2809clua-escape-sequencese2809d3f) para más contexto sobre ese problema.

Si intentamos usar `\codestoemoji` con un `\char` comando, así:

```latex
\codestoemoji{\Uchar"1F3F4\Uchar"E0067\Uchar"E0062\Uchar"E0065\Uchar"E006E\Uchar"E0067\Uchar"E007F}
```

LuaHBTeX fallará e informará de un error de sintaxis algo como esto:

```latex
[\directlua]:1: secuencia de escape no válida cerca de '\"\\c'.
\codestoemoji ...ing \includegraphics }.}]]) end }

l.75 ...r"E0065\Uchar"E006E\Uchar"E0067\Uchar"E007F}

El intérprete de Lua encontró un problema, así que el
el resto de este fragmento de Lua será ignorado.
```

#### Llamando a la función de composición de HarfBuzz

**Configuración de los parámetros del búfer**

A veces HarfBuzz requiere información adicional sobre el texto que se le pide componer. Puedes proporcionar esa información configurando tu `<buffer variable>` usando *métodos del búfer*, como:

* `<buffer variable>:set_direction(*HarfBuzz direction*)`;
* `<buffer variable>:set_language(*HarfBuzz language*)`;
* `<buffer variable>:set_script(*HarfBuzz script*)`.

Por ejemplo, necesitamos informar a HarfBuzz de que la dirección de nuestro texto de emoji será de izquierda a derecha. Para ello, usamos el `set_direction()` método en nuestro `<buffer variable>` (llamado `hbbuffer`) escribiendo:

```latex
hbbuffer:set_direction(hblib.Direction.new("ltr"))
```

donde `hblib.Direction.new("ltr")` crea un “objeto de dirección” adecuado para pasarlo al motor de HarfBuzz a través de Lua.

**Realizar la composición**

Después de inicializar adecuadamente el búfer, podemos pedirle a HarfBuzz que realice la composición propiamente dicha mediante la función `shape_full()`. En nuestro ejemplo escribimos:

```latex
local res = hblib.shape_full(hbfont, hbbuffer, {},{})
```

Los 3.º y 4.º parámetros de la `shape_full()` función deben ser tablas de Lua; hemos usado tablas vacías “`{}`” para ambos parámetros. La forma general de `shape_full()` es:

```latex
shape_full(fuente Harfbuzz, búfer Harfbuzz, {características tipográficas}, {"shaper"}
```

* **`{"shaper"}`**: Normalmente no necesita establecerse, pero las opciones son `{"ot"}` o `{"graphite2"}`. Puede encontrarse más información sobre el concepto de un “shaper” en [la documentación de HarfBuzz](https://harfbuzz.github.io/shaping-and-shape-plans.html)—ten en cuenta que esto documenta la API de C de bajo nivel, no la `luaharfbuzz` interfaz (implementación) basada en Lua.
* **`{características tipográficas}`**: Esta es una tabla que enumera las [características OpenType](https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist)—compatibles con la fuente— que quieres que HarfBuzz aplique durante la composición.

Cualquier característica tipográfica que quieras usar debe crearse usando una `luaharfbuzz` función de la biblioteca

```latex
library_instance.Feature.new(feature_string)
```

donde

* `library_instance` es tu `luaharfbuzz` variable de instancia de la biblioteca (`hblib` en nuestro ejemplo);
* `feature_string` usa una [sintaxis para definir características](https://github.com/ufytex/luaharfbuzz/wiki/Feature-Strings). Ejemplos de ello son `+smcp` para activar versalitas o `-kern` para desactivar el kerning.

Por ejemplo:

```latex
local dosmcp = hblib.Feature.new("+smcp")
local nokern = hblib.Feature.new("-kern")
% Usa las características tipográficas así
local res = hblib.shape_full(hbfont, hbbuffer, {dosmcp,nokern},{})
```

#### Accediendo al resultado: obteniendo los glifos

Y por último, si la operación de composición tiene éxito, los glifos compuestos se devuelven en la variable de búfer `hbbuffer` que creamos antes en el código.

Accedemos a los glifos mediante el método del búfer `get_glyphs()` y usamos un bucle para obtener cada glifo individual. Ten en cuenta que la tabla de Lua que contiene los glifos, `hbglyphs` en nuestro ejemplo, está indexada empezando en 1, no en 0.

De cada glifo, *identificador de glifo* (llamado confusamente `punto de código`), y la fuente de HarfBuzz (`hbfont`), se pasa a la `writePNGglyph()` función, que crea un archivo PNG usando la representación de imagen rasterizada de la fuente de ese glifo.

`writePNGglyph()` escribe un archivo PNG y devuelve el nombre del archivo PNG, que se usa para importar el archivo PNG (escalado) en nuestro documento LaTeX mediante `\includegraphics[scale=0.75]{<fname>}`. Observa cómo podemos usar `\includegraphics` directamente dentro del código Lua.

```latex
if (res) then
    local hbglyphs=hbbuffer:get_glyphs()
    % La tabla de glifos, hbglyphs, es indexada desde 1
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Reducir el tamaño de nuestras imágenes PNG importadas
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
```

### El código completo que puedes abrir en Overleaf

```latex
\documentclass{article}
\usepackage{graphicx}
\begin{document}
\directlua{

% Cargar la biblioteca luaharfbuzz desde LuaHBTeX
hblib=require("luaharfbuzz")

% Localiza la fuente Noto Color Emoji en el servidor de Overleaf
pathtofontfile=kpse.find_file("NotoColorEmoji.ttf","truetype fonts")

% Crear la cara HarfBuzz y la fuente HarfBuzz a partir de Noto Color Emoji
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)

% Esta función acepta una fuente y un ID de glifo:
% extrae los datos PNG de los glifos y escribe
% en un archivo .png

function writePNGglyph(hbfontobject, glyphID)

    % Obtener datos PNG del glifo
    local pngblob=hbfontobject:ot_color_glyph_get_png(glyphID)
    local pngdata=pngblob:get_data()

    % Construir un nombre de archivo para nuestro archivo .png
    local fname="Glyph"..glyphID..".png"

    % Escribir el archivo .png y devolver el nombre del archivo
    local output = assert(io.open(fname, "wb"))
    output:write(pngdata)
    output:close()

    % Devolver el nombre del archivo para que lo use \includegraphics
    return fname
end
}

\newcommand{\codestoemoji}[1]{%
\directlua{

local str="#1"
local hbbuffer = hblib.Buffer.new()
hbbuffer:add_utf8(str)

hbbuffer:set_direction(hblib.Direction.new("ltr"))
local res = hblib.shape_full(hbfont, hbbuffer, {},{})

if (res) then
    local hbglyphs=hbbuffer:get_glyphs()
    % La tabla de glifos, hbglyphs, está indexada desde 1.
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Reducir el tamaño de nuestras imágenes PNG importadas
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
}}

Un pato: \codestoemoji{\Uchar"1F986}

Una bandera: \codestoemoji{\Uchar"1F3F4\Uchar"E0067\Uchar"E0062\Uchar"E0065\Uchar"E006E\Uchar"E0067\Uchar"E007F}
\end{document}
```

[Abre este ejemplo de la API de luaharfbuzz en Overleaf.](/latex/es/articulos-en-profundidad/10-an-overview-of-technologies-supporting-the-use-of-colour-emoji-fonts-in-latex.md)

Este ejemplo produce la siguiente salida:

![Harfbuzzexample.png](/files/9b3c4b47da205aa1446a59d63f7d4f51289d064e)

## Sección extra: diversión con matemáticas de emoji

Para terminar con una nota ligera, un miembro del equipo de Overleaf usó el [`emoji` paquete de LaTeX](https://ctan.org/pkg/emoji?lang=en) para crear un ejemplo divertido:

```latex
\documentclass{article}
\usepackage{emoji}
\usepackage{unicode-math,fontspec}
\setmainfont{STIX}
\setmathfont{STIX Two Math}
\begin{document}
\newcommand{\emomath}[1]{\text{\emoji{#1}}}
\[
e^{\emomath{droplet} \ln\emomath{smile}}=\emomath{sweat-smile}
\]
\[
e^{\emomath{eye}\emomath{pie}}=-1
\]
\end{document}
```

[Abre este ejemplo divertido en Overleaf](https://www.overleaf.com/docs?engine=lualatex\&snip_name=Fun+with+emoji+math\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%7Bemoji%7D%0A%5Cusepackage%7Bunicode-math%2Cfontspec%7D%0A%5Csetmainfont%7BSTIX%7D%0A%5Csetmathfont%7BSTIX+Two+Math%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cnewcommand%7B%5Cemomath%7D%5B1%5D%7B%5Ctext%7B%5Cemoji%7B%231%7D%7D%7D%0A%5C%5B%0Ae%5E%7B%5Cemomath%7Bdroplet%7D+%5Cln%5Cemomath%7Bsmile%7D%7D%3D%5Cemomath%7Bsweat-smile%7D%0A%5C%5D%0A%5C%5B%0Ae%5E%7B%5Cemomath%7Beye%7D%5Cemomath%7Bpie%7D%7D%3D-1%0A%5C%5D%0A%5Cend%7Bdocument%7D)

Este ejemplo produce la siguiente salida:

![Emojimath2.png](/files/51a30153a82131fde66d92c694a2c159704f21f5)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://overleaf-pro.ayaka.space/latex/es/articulos-en-profundidad/10-an-overview-of-technologies-supporting-the-use-of-colour-emoji-fonts-in-latex.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
