> 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/fr/articles-approfondis/10-an-overview-of-technologies-supporting-the-use-of-colour-emoji-fonts-in-latex.md).

# Un aperçu des technologies permettant l'utilisation de polices d'émojis colorés en LaTeX

## Introduction

Cet article donne un aperçu de divers [sujets de contexte](#which-topics-do-we-cover) liés à l’utilisation des polices de couleur OpenType pour la composition d’émojis en couleur en LaTeX. Nous avons tenté de proposer un large éventail de նյութ, couvrant un vaste spectre d’intérêts et de niveaux d’expertise. Pour garder l’article gérable, notre traitement de certains sujets omet beaucoup de détails techniques, mais nous espérons qu’il y a suffisamment de matière pour orienter votre exploration de la composition d’émojis en couleur en LaTeX.

**Mise à jour (juillet 2023)** : Cet article a été publié pour la première fois en août 2021 et révisé en juillet 2023 afin de mettre à jour la section sur [Utilisation de polices de couleur OpenType basées sur SVG avec LuaHBTeX](#using-svg-based-opentype-color-fonts-with-luahbtex).

### Quels sujets abordons-nous ?

Cet article couvre les sujets généraux suivants :

* Unicode : la norme qui encode les emoji en tant que caractères et codifie leur comportement attendu dans les applications de traitement de texte et de composition.
* Polices de couleur OpenType : polices spécialisées qui fournissent des représentations colorées des caractères emoji affichés dans votre document LaTeX.
* Mise en forme du texte : présentation d’un composant clé de la composition des langues à écriture complexe et des emoji.
* HarfBuzz : le composant de LuaHBTeX qui permet une composition multilingue avancée et l’utilisation de polices de couleur OpenType pour composer des emoji en LaTeX.
* Différents moteurs TeX : explorer leur prise en charge des polices de couleur OpenType et choisir quel moteur TeX utiliser.
* L’API HarfBuzz de LuaHBTeX : une introduction à la « magie » derrière [la mise en forme du texte](#the-concept-of-text-shaping) dans LuaHBTeX.

### Trois façons de composer des emoji en couleur

Les emoji en couleur peuvent être composés avec LaTeX de trois manières principales :

1. Utiliser des outils graphiques LaTeX standard tels que TikZ, MetaPost ou Asymptote pour dessiner l’emoji.
2. Insérer des emoji à l’aide de graphiques d’emoji préalablement préparés et stockés dans des fichiers externes.
3. Traiter les emoji comme du texte encodé en Unicode et utiliser [la mise en forme du texte](#the-concept-of-text-shaping) avec [les polices de couleur OpenType](#opentype-color-fonts) pour les composer.

Les options pratiques pour inclure des emoji en couleur dans votre document LaTeX dépendent du moteur TeX utilisé pour compiler ce document : c’est-à-dire, selon que vous utilisez :

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

Ces trois moteurs TeX peuvent utiliser des outils ou paquets LaTeX pour dessiner des emoji ou utiliser `\includegraphics{...}` pour insérer des emoji stockés dans des fichiers graphiques externes. Le dessin ou l’importation de graphiques est une technique idéale pour composer des emoji lorsque vous avez besoin d’une solution qui ne dépend pas du moteur TeX utilisé pour compiler le document LaTeX.

Cependant, si votre flux de travail vous offre la flexibilité de choisir un moteur TeX particulier, et que vous préférez utiliser des polices de couleur OpenType et un traitement de texte fondé sur Unicode, la version la plus récente de LuaTeX, appelée LuaHBTeX, est ce qu’il vous faut. À partir de TeX Live 2020, LuaHBTeX est utilisé pour compiler les documents LaTeX basés sur le format LuaLaTeX.

## Contexte sur Unicode et les caractères emoji

### Encodages de caractères

Les ordinateurs stockent, transmettent et traitent le texte à l’aide d’une suite de valeurs numériques (entières) qui représentent les *caractères*. Un traitement de texte fiable exige que les producteurs et les consommateurs de texte s’accordent sur les valeurs entières à utiliser pour représenter les caractères individuels au sein du flux de texte. En d’autres termes, quel est l’ *suivant* *encodage ?* Un encodage est l’ensemble des valeurs entières convenues, attribuées pour représenter un certain ensemble de caractères : chaque caractère est représenté par une valeur entière dans l’encodage utilisé.

### Entre en scène Unicode

Historiquement, à l’époque du texte 8 bits, de nombreux encodages de caractères différents étaient utilisés, suscitant toujours le spectre des *discordances d’encodage* : les producteurs et les consommateurs de texte supposant à tort des encodages différents, ce qui entraînait des erreurs de traitement du texte. Toute personne ayant travaillé pendant plusieurs années avec TeX/LaTeX a probablement rencontré des discordances d’encodage entre le texte d’entrée et les polices utilisées pour composer un document. Si les polices du document sont configurées pour utiliser un encodage différent de celui du texte, cela entraîne probablement des caractères manquants ou erronés dans le PDF composé.

Ces problèmes historiques d’encodage peuvent être résolus à l’aide d’une norme internationale qui encode tous les caractères du monde : Unicode. La norme Unicode n’est pas statique, mais est périodiquement mise à jour pour inclure des caractères et des systèmes d’écriture supplémentaires dans son schéma d’encodage. Il existe un [processus d’examen formel pour proposer de nouveaux caractères](http://www.unicode.org/pending/proposals.html) avec un [schéma spécifique pour les nouveaux caractères emoji](https://www.unicode.org/emoji/proposals.html).

### Combien de caractères Unicode ?

Unicode encode un maximum théorique de 1 114 112 caractères. Chacune des 1 114 112 valeurs entières est appelée un *point de code* : la valeur entière attribuée pour identifier chaque caractère. Cependant, pour diverses raisons techniques, seuls [1 112 064 points de code](https://en.wikipedia.org/wiki/Unicode#Architecture_and_terminology) peuvent être attribués à des caractères réels : 2048 points de code ne sont pas attribuables et sont interdits pour l’utilisation dans un texte conforme à Unicode.

Au moment de la rédaction (la première version de cet article), la version 13 de la norme Unicode avait attribué un total de 143 859 points de code à des caractères réels, y compris [3304 caractères désormais encodés comme emoji](https://www.unicode.org/L2/L2020/20114r-family-emoji-explor.pdf) (voir la page 2 de ce document). La croissance du nombre de caractères encodés par Unicode est bien documentée dans l’article [Combien y a-t-il de caractères Unicode ?](https://www.babelstone.co.uk/Unicode/HowMany.html) et dans une [entrée Wikipédia](https://en.wikipedia.org/wiki/Unicode#Versions).

### Plans Unicode

L’ensemble des 1 114 112 points de code Unicode est regroupé en 17 soi-disant Plans : le Plan 0 à Plan 16, chacun contenant 65 536 valeurs de points de code, ce qui donne un total de $$17\times2^{16} = 1,114,112$$ caractères. Le Plan 0, appelé le [Plan multilingue de base](https://en.wikipedia.org/wiki/Plane_\(Unicode\)#Basic_Multilingual_Plane), encode les caractères les plus couramment utilisés. Les plans 1 à 16 sont appelés [plans supplémentaires](http://unicode.org/glossary/#supplementary_planes).

### L’essor des emoji

De nouveaux caractères apparaissent avec l’évolution des modes de communication humaine, et la technologie des téléphones mobiles a donné naissance à l’un de ces ensembles de caractères : les emoji, qui ont évolué au Japon à la fin des années 1990. Il n’est pas surprenant que la [FAQ Unicode sur les emoji](https://unicode.org/faq/emoji_dingbats.html) indique

> « Le mot emoji vient du japonais [絵](http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=%E7%B5%B5) (e ≅ image) + [文字](http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=%E6%96%87) (moji ≅ caractère écrit). »

Les lecteurs intéressés par le contexte et le développement historique des emoji pourront trouver un intérêt dans cette [introduction à Unicode](https://unicode.org/reports/tr51/#Introduction) ou dans l’article [Je partage cet emoji : les normes, les structures et la production sociale des emoji](https://firstmonday.org/ojs/index.php/fm/article/view/9381).

Ce n’est qu’en 2010, avec la sortie de [la version 6.0 de la norme Unicode](https://www.unicode.org/versions/Unicode6.0.0/), que de nombreux emoji ont été officiellement reconnus comme *caractères* à part entière. Unicode 13.0 a encodé [3304 caractères en tant qu’emoji](https://www.unicode.org/L2/L2020/20114r-family-emoji-explor.pdf) (voir la page 2 de ce document), et Unicode 13.1 répertorie [énumère 3521 emoji](https://unicode.org/emoji/charts/emoji-counts.html).

### Les emoji vivent sur un plan plus élevé

Unicode a attribué de nombreux caractères emoji à des points de code en dehors du Plan multilingue de base (BMP), encodés [dans le Plan 1](https://en.wikibooks.org/wiki/Unicode/Character_reference/1F000-1FFFF) avec des points de code dans la plage 1F000–1FFFF — ce qui a une conséquence importante pour toute personne souhaitant *copier-coller* des caractères emoji dans les éditeurs Overleaf (éditeur de code ou éditeur visuel). Les éditeurs de texte d’Overleaf ne peuvent gérer que les caractères du Plan multilingue de base, bien que nous espérions que de futures mises à jour introduiront la prise en charge des caractères hors BMP. Notez que cette limitation n’affecte que les caractères hors BMP à l’intérieur du texte collé dans des fichiers destinés à être modifiés via les éditeurs Overleaf. Il existe d’autres moyens d’accéder aux caractères emoji :

* Utiliser les commandes primitives `\char"<code point>` ou `\Uchar"<code point>` (voir [cette section](#optional-detail-luatexluahbtex-char-vs-uchar) de l’article).
* Utiliser des fichiers texte d’entrée contenant des caractères emoji au format UTF-8.
* Utiliser des commandes LaTeX (macros) qui insèrent des caractères emoji.

#### Coller des emoji et d’autres caractères hors BMP dans Overleaf

Si vous collez un caractère emoji, par exemple 😀, dans l’éditeur de code Overleaf, il sera actuellement converti en les caractères ��.

![Erreur due au copier-coller de caractères hors BMP dans les éditeurs Overleaf](/files/a7c4be8b61f5175d2baf0a9ebac7e1b30141c75b)

Le caractère � a pour point de code Unicode FFFD et son nom officiel est le REPLACEMENT CHARACTER et il est utilisé pour «[remplacer un caractère inconnu, non reconnu ou non représentable](https://en.wikipedia.org/wiki/Specials_\(Unicode_block\)) ».

### Utilisation des points de code Unicode (U+) dans LuaLaTeX

La documentation Unicode représente les valeurs de point de code à l’aide de la notation `U+<valeur hexadécimale>`—comme `U+1F600`, où `1F600` est la `<valeur hexadécimale>` du point de code Unicode pour le caractère emoji 😀. Pour utiliser ces valeurs de point de code dans LuaLaTeX, vous supprimez le `U+` et écrivez `\char"<valeur hexadécimale>` ou `\Uchar"<valeur hexadécimale>`. Le `"` caractère indique à un moteur TeX que le nombre fourni est spécifié en hexadécimal. Par exemple, pour utiliser l’emoji 😀, vous écririez `\char"1F600` ou `\Uchar"1F600`—en utilisant une police capable de le composer.

Un exemple minimal LuaLaTeX utilisant `\char` et `\Uchar` pour composer le caractère emoji 😀 pourrait être :

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont[Renderer=Harfbuzz]{NotoColorEmoji.ttf}
%Utilisez \emojifont dans un groupe pour conserver ses effets locaux
{\emojifont
\Uchar"1F600
\char"1F600}
\end{document}
```

[Ouvrez cet exemple LuaLaTeX dans 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)

**(détail facultatif) LuaTeX/LuaHBTeX : \char contre \Uchar**

En plus de la `\char<code de caractère>` commande conventionnelle pour composer un `<code de caractère>`, en utilisant la police actuelle, les moteurs LuaTeX, LuaHBTeX et XeTeX fournissent également la `\Uchar<code de caractère>` Du point de vue de l’utilisateur, le résultat de `\char` et `\Uchar` semblent identiques, mais il existe une subtile différence dans leur fonctionnement, comme nous le notons ci-dessous.

**La différence clé : l’expansion**

`\Uchar` est une commande dite [expansible](/latex/fr/articles-approfondis/22-how-does-expandafter-work-the-meaning-of-expansion.md#expansion-a-general-term-for-a-set-of-operations) tandis que `\char` n’est pas expansible. Lorsqu’une `\char<code de caractère>` ou `\Uchar<code de caractère>` commande est « exécutée » — c’est-à-dire que la commande n’est pas stockée dans le cadre d’une macro ou d’une autre liste de jetons — les actions suivantes se déroulent dans le moteur TeX :

* **`\char<code de caractère>`** ordonne au moteur TeX d’insérer immédiatement un jeton de caractère, représentant `<code de caractère>`, dans toute portion de contenu qu’il est en train de composer.
* En revanche, **`\Uchar<code de caractère>`** comporte deux étapes de traitement distinctes :

1. Le `\Uchar<code de caractère>` la commande est *développé*, et le `<code de caractère>` est converti en une liste temporaire de jetons contenant un seul [jeton de caractère](/latex/fr/articles-approfondis/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md#tex-tokens-101-28and-notions-of-expansion29) qui représente le `<code de caractère>`.
2. Cette liste de jetons à un seul caractère est maintenant *mise à disposition* pour le moteur TeX comme source de sa prochaine entrée. En effet, le moteur TeX « détourne temporairement son regard » pour utiliser cette liste à un seul jeton comme emplacement de son prochain élément d’entrée (jeton). Par défaut, le moteur TeX revient simplement lire (en entrée) ce jeton et composer le caractère correspondant, reproduisant le comportement de la `\char` commande. **Cependant**, car ce `<code de caractère>` n’a pas été composé immédiatement, mais temporairement *simplement stockées* (enregistré) sous forme d’un seul jeton, les commandes primitives TeX ou les macros LaTeX peuvent utiliser (absorber) ce jeton — il n’a pas besoin d’être composé tout de suite, mais peut être utilisé dans un traitement ultérieur selon les besoins.

En pratique, `\char<code de caractère>` dit « composez ce `<code de caractère>` maintenant », tandis que `\Uchar<code de caractère>` a une forme « d’action différée » en créant un jeton de caractère stocké et en le rendant disponible comme prochain élément d’entrée (un jeton). Ce jeton peut soit être utilisé (absorbé) par des commandes et macros TeX, soit être relu par le moteur TeX et composé.

### Unicode (l’encodage) ne dit pas tout

La capacité d’utiliser des caractères emoji dans du texte encodé en Unicode n’est qu’une partie de l’histoire du succès des emoji. La montée en puissance de l’usage des emoji a aussi été rendue possible par des զարգissements de [la technologie des polices OpenType](https://learn.microsoft.com/en-us/typography/opentype/)—des polices dont les données de glyphes (dessins de caractères) peuvent contenir [des données de couleur](https://learn.microsoft.com/en-us/typography/opentype/spec/colr) : appelées [les polices de couleur OpenType](#opentype-color-fonts).

Outre des polices adaptées, l’utilisation d’emoji en couleur nécessite des composants logiciels supplémentaires dont les tâches comprennent :

* le prétraitement («[mise en forme](#the-concept-of-text-shaping) ») du texte encodé en Unicode, *préparer* pour son affichage à l’aide d’une police particulière ;
* *rendu et affichage* des emoji colorés d’une police *glyphes* sur l’écran d’un appareil.

#### Glyphe contre caractère : n’est-ce pas la même chose ?

Les termes « glyphe » et « caractère » sont souvent utilisés comme s’ils étaient interchangeables — pour désigner le même concept de base — mais il existe une différence subtile, bien que importante, dans leur signification.

Unicode [définit le terme « caractère »](http://www.unicode.org/glossary/#character) comme :

> « Le plus petit composant du langage écrit ayant une valeur sémantique ; il renvoie au sens abstrait et/ou à la forme, plutôt qu’à une forme spécifique… »

En revanche, un « glyphe » est une *spécifique* *forme* (conception) de la *représentation visuelle* d’un caractère particulier *suivant*.

La question caractère contre glyphe s’observe facilement lorsque du texte contenant des emoji est affiché sur divers systèmes ou plateformes logicielles, par exemple en lisant le même texte sur votre téléphone mobile iOS ou Android ou sur un ordinateur de bureau Windows. Quel que soit l’appareil ou la plateforme utilisé, le texte sous-jacent (la suite de caractères) contiendrait le même *emoji* *caractères*. Ce sont les capacités propres à l’appareil qui interviennent dans *le prétraitement* de ce texte, puis *le rendu* et *affiché* des résultats, éventuellement à l’aide de polices spécifiques à l’appareil, ce qui produit différents glyphes (dessins de caractères) pour représenter les mêmes caractères emoji.

La [Liste complète des emoji](https://unicode.org/emoji/charts/full-emoji-list.html) fournit des images d’exemple représentant chaque caractère emoji Unicode — démontrant les divers glyphes utilisés par différents éditeurs de technologies. Non seulement les concepteurs de polices adoptent leurs propres dessins particuliers (glyphes) pour représenter les caractères emoji, mais les polices individuelles varient aussi dans le nombre de caractères emoji qu’elles prennent en charge (pour lesquels elles contiennent des glyphes) et peuvent ou non contenir des fonctionnalités plus avancées de traitement du texte emoji incluses dans les spécifications Unicode des emoji.

La notion et le concept de caractères, leur sémantique et leur encodage, constituent la base du monde d’Unicode : il traite des caractères. La conception et la représentation visuelle des caractères individuels, sous forme de glyphes, relèvent des technologies de polices et de l’art de la conception typographique.

#### Emoji Unicode : bien plus qu’un encodage de texte

Le rôle central d’Unicode est de fournir une norme d’encodage globale qui définit quelle valeur entière, appelée un *point de code,* doit être utilisée pour représenter chaque caractère, y compris les emoji, dans un flux de texte encodé en Unicode.

La spécification Unicode pour les emoji définit également *des comportements de traitement* pour certains *séquences* de caractères emoji apparaissant dans un flux de texte encodé en Unicode. Des séquences définies de caractères emoji peuvent être « fusionnées » au moyen d’un processus appelé [la mise en forme du texte](#the-concept-of-text-shaping) pour produire un seul glyphe emoji résultant (« composite ») — ce glyphe unique serait utilisé par le système d’exploitation de l’appareil pour représenter la séquence de caractères d’origine présente dans le texte.

Le rapport technique d’Unicode sur [Unicode Emoji](https://unicode.org/reports/tr51/) documente le riche ensemble de fonctionnalités disponibles pour les logiciels souhaitant fournir un traitement des caractères emoji conforme à Unicode. À titre d’exemple, Unicode définit (encode) des caractères appelés [modificateurs d’emoji](http://www.unicode.org/reports/tr51/#Emoji_Modifiers_Table) qui peuvent être utilisés pour générer *des variations* de caractères emoji « de base », telles que des variations de [teint de peau fondées sur l’échelle de Fitzpatrick](http://www.unicode.org/reports/tr51/#Diversity). Notez que l’ensemble des caractères emoji de base et les modificateurs applicables sont définis dans le cadre de la [norme Unicode des emoji](http://www.unicode.org/reports/tr51).

La page Unicode [Séquences d’emoji](http://unicode.org/emoji/charts/emoji-sequences.html) fournit un tableau des séquences actuellement fournies par la spécification Unicode. Placez le pointeur de la souris sur l’une des images de glyphe emoji pour voir une petite info-bulle indiquant la séquence sous-jacente de caractères emoji Unicode qui produit ce glyphe :

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

Par exemple, le glyphe emoji :

![HandMediumSkinTone.png](/files/154d437be2e07a162fec9c12bc3d1aabe5fb6cf8)

est répertorié dans la [section des séquences de modificateurs](http://unicode.org/emoji/charts/emoji-sequences.html#modifier_sequences) et est produit par la séquence de deux caractères U+1F44B U+1F3FD. Ces caractères composants sont :

U+1F44B :![UnicodeWavingHandDefault.png](/files/a7bf88a264ce6576e7dfc1414b91a93b19f6e754) (MAIN QUI AGITE)

U+1F3FD :![FitzPatrick3.png](/files/3282b716130409bd22336bbb3a5ec84d14b239e2) (MODIFICATEUR D’EMOJI FITZPATRICK TYPE 4)

**Utilisation des modificateurs de teint de peau dans LuaHBTeX**

L’exemple suivant utilise LuaHBTeX pour démontrer l’utilisation des modificateurs d’emoji :

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont[Renderer=HarfBuzz,SizeFeatures={Size=20}]{NotoColorEmoji.ttf}
Main qui agite isolée : {\emojifont\Uchar"1F44B}\par
Modificateur isolé : {\emojifont\Uchar"1F3FD}\par
Résultat combiné : {\emojifont\Uchar"1F44B\Uchar"1F3FD}
\end{document}
```

[Ouvrez cet exemple de modificateurs d’emoji LuaLaTeX dans 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)

Cet exemple produit le résultat suivant :

![ModifiersInLuaHBTeX.png](/files/a22c1a5ff5f897b51cd86b2655e8668c507cb2b6)

#### UTF-8 : son rôle dans le stockage du texte Unicode

Tout texte ou code que vous tapez ou collez dans l’éditeur de code d’Overleaf (ou l’éditeur visuel) sera stocké au format UTF-8 ; nous allons donc brièvement revoir ce que signifie réellement UTF-8. UTF signifie Unicode Transformation Format, et le rôle de UTF-8 dans le stockage ou la transmission de texte encodé en Unicode est indiqué par l’expression « Transformation *Format* ».

Les valeurs de point de code Unicode vont de 0 à un maximum de 1 114 111, il est donc impossible de représenter toutes les valeurs de caractères Unicode à l’aide d’un seul octet de 8 bits, qui ne peut stocker que 256 valeurs différentes : de 0 à 255. Cependant, il est possible de représenter n’importe quel entier de point de code Unicode à l’aide d’une *séquence consécutive* de valeurs de taille octet — c’est le principe derrière UTF-8.

UTF-8 fournit une « recette » pour *transformer* (c’est-à-dire « encoder » ou « convertir ») une valeur entière de point de code Unicode en une séquence unique de 1 à 4 entiers consécutifs de taille octet : le nombre d’octets consécutifs requis dépend de la valeur entière du point de code. Par conséquent, vous pouvez lire que UTF-8 stocke les caractères Unicode sous forme de *séquences multioctets* car un seul caractère Unicode (entier de point de code) est représenté en UTF-8 par une séquence de 1 à 4 octets consécutifs.

Naturellement, le texte stocké en UTF-8 peut être reconverti en sa suite d’origine de valeurs entières de points de code Unicode — c’est ce que XeTeX ou LuaTeX/LuaHBTeX doivent faire lorsqu’ils lisent un fichier d’entrée LaTeX stocké au format UTF-8. Ces moteurs TeX doivent connaître les valeurs Unicode d’entrée des points de code (caractères) avant de pouvoir composer le texte. Notez que pdfTeX n’a pas de capacité intégrée de décodage UTF-8 ; il doit donc s’appuyer sur des macros TeX pour traiter (décoder) le texte d’entrée formaté en UTF-8.

**Quelques exemples d’UTF-8**

* Le caractère arabe ش (« sheen ») a pour point de code Unicode 0634 en hexadécimal (base 16) ou 1588 en décimal (base 10). En UTF-8, ش est représenté par 2 valeurs (hexadécimales) D8 et B4, donc le caractère ش serait stocké sous forme des deux octets consécutifs D8B4 dans un texte encodé en UTF-8.
* Le caractère emoji 😀 a pour point de code Unicode 1F600 en hexadécimal (base 16) ou 128512 en décimal (base 10). En UTF-8, 😀 est représenté par 4 valeurs (hexadécimales) F0, 9F, 98 et 80, donc le caractère 😀 serait stocké sous forme des 4 octets consécutifs F09F9880 dans un fichier texte UTF-8.

#### Caractères spéciaux utilisés dans le traitement de texte emoji basé sur Unicode

Tous les caractères encodés dans Unicode ne sont pas destinés à une présentation visuelle via les glyphes d’une police : certains caractères encodés sont désignés comme *caractères non imprimables* dont le but est d’aider des fonctions spécialisées de traitement de texte (dans les logiciels qui les prennent en charge). Différentes applications logicielles offrent des niveaux variables de prise en charge des caractères non imprimables encodés dans Unicode, de sorte que le résultat dépendra de l’environnement logiciel — applications et polices — utilisé.

**Deux caractères non imprimables à connaître**

* **caractère de jonction à largeur nulle (ZWJ)**, code point 200D (hexadécimal), est, comme son nom l’indique, conçu pour déclencher le « comportement de jonction » des caractères d’entrée — mais seulement si ces caractères d’entrée *possèdent* un comportement de jonction défini.
* **caractère de non-jonction à largeur nulle (ZWNJ)**, code point 200C (hexadécimal), est conçu pour *empêcher* le « comportement de jonction » que les caractères d’entrée pourraient autrement manifester. Par exemple, vous pouvez utiliser le ZWNJ pour empêcher le comportement de jonction de caractères arabes consécutifs qui seraient normalement traités (mis en forme) dans leurs formes de jonction.

Unicode a publié une liste de [séquences ZWJ d’emoji recommandées](https://unicode.org/emoji/charts/emoji-zwj-sequences.html) qui utilisent un ZERO WIDTH JOINER (ZWJ) U+200D pour combiner des séquences de caractères emoji en un seul glyphe emoji composite — s’il est disponible dans la ou les polices utilisées.

**Exemple d’utilisation du caractère de non-jonction à largeur nulle**

Le fragment de code minimal suivant utilise la police OpenType Scheherazade, incluse dans TeX Live, pour définir une police LaTeX appelée `\arabicfont` que nous pouvons utiliser pour composer de l’arabe. La ligne

```latex
{\arabicfont Non-joining:\textdir TRT\Uchar"0644\Uchar"200C\Uchar"0627}
```

utilise un caractère de non-jonction à largeur nulle, via `\Uchar"200C`, pour empêcher le comportement de jonction normal des deux lettres arabes ل (lam) et ا (alef). Notez l’utilisation de `\textdir TRT` pour définir la direction du texte de droite à gauche :

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

[Ouvrez cet exemple LuaLaTeX dans 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)

Cet exemple produit le résultat suivant :

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

## Le concept de « mise en forme du texte »

Commençons par un exemple visuel utilisant une traduction ourdou du mot « éducatif ». Le texte de la traduction ourdoue pourrait être saisi sur un clavier ou un appareil à écran tactile, et serait créé sous la forme d’une simple suite linéaire de caractères arabes Unicode. Cependant, lorsque ce texte est composé ou affiché sur l’écran d’un appareil dans le [style nastaliq](https://en.wikipedia.org/wiki/Nastaliq), le résultat est une composition bidimensionnelle complexe de glyphes.

À partir de notre exemple ourdou, le graphique suivant compare l’entrée linéaire d’arabe Unicode *caractères* au résultat composé en style nastaliq, comprenant une disposition bidimensionnelle de *glyphes* présents dans la police (gratuite) [Awami Nastaliq](https://software.sil.org/awami/download/):

![](/files/7b81f61cd9652b01a5f97134a51d7ea075380331)

Le processus consistant à « traduire » des caractères d’entrée en un ensemble de glyphes de sortie correctement positionnés s’appelle *la mise en forme du texte*et constitue un composant vital du traitement du texte avant son affichage ou sa composition. Notre exemple utilisait du texte en langue ourdoue (écriture arabe) parce que le résultat de la mise en forme est clairement visible, contrairement aux langues utilisant l’écriture latine, comme l’anglais, où la mise en forme est beaucoup moins marquée — par exemple par la production de simples ligatures.

La mise en forme du texte est essentielle lorsqu’on utilise des écritures (systèmes d’écriture) telles que [Arabe](https://en.wikipedia.org/wiki/Arabic), [Hébreu](https://en.wikipedia.org/wiki/Hebrew_language), [Devanagari](https://en.wikipedia.org/wiki/Devanagari) ou [Malayalam](https://en.wikipedia.org/wiki/Malayalam), seulement quatre exemples de ce qu’on appelle *écritures complexes*. Pour garantir une présentation correcte du texte dans ces écritures, et dans les langues qui les utilisent, le processus de mise en forme doit traiter avec soin toutes les règles et nuances de mise en forme présentes dans la combinaison écriture-langue particulière. Par exemple, certaines langues exigent que plusieurs caractères d’entrée génèrent un glyphe de sortie particulier, ou il peut exister des exigences complexes pour le positionnement minutieux des signes diacritiques, ainsi que des réarrangements entre glyphes pour garantir que les glyphes individuels sont correctement positionnés les uns par rapport aux autres.

En général, la mise en forme d’un morceau de texte nécessite plusieurs informations :

* Le système d’écriture ou *script* dans lequel le texte est écrit.
* La *langue* utilisée. Des scripts individuels peuvent être utilisés pour plusieurs langues, chaque combinaison script–langue ayant ses propres subtilités/nuances de mise en forme.
* La *direction d’écriture* du texte — par exemple de droite à gauche ou de gauche à droite.
* A *police* qui fournit les glyphes nécessaires pour représenter le texte mis en forme et, éventuellement, contient des « règles de mise en forme » supplémentaires qui guident le processus de mise en forme du texte.

Les exigences de la mise en forme du texte, en particulier pour les scripts complexes et les langues qui leur sont associées, peuvent être extrêmement détaillées et nuancées, ce qui indique la nécessité d’un logiciel spécialisé capable d’appliquer des « règles » de mise en forme du texte potentiellement très complexes. Sans surprise, un tel logiciel existe et est appelé *moteur de mise en forme du texte*; celui que nous allons examiner s’appelle [HarfBuzz](https://en.wikipedia.org/wiki/HarfBuzz), dont la documentation mérite d’être lue — par exemple [Pourquoi ai-je besoin d’un moteur de mise en forme ?](https://harfbuzz.github.io/why-do-i-need-a-shaping-engine.html).

**Pour aller plus loin sur la mise en forme du texte**

Ces brèves introductions sont vivement recommandées :

* [Qu’est-ce que la mise en forme du texte ?](https://harfbuzz.github.io/what-is-harfbuzz.html#what-is-text-shaping)
* [Pourquoi ai-je besoin d’un moteur de mise en forme ?](https://harfbuzz.github.io/why-do-i-need-a-shaping-engine.html)

**Note technique TeX : plusieurs technologies (modèles) de mise en forme**

Le moteur de mise en forme du texte HarfBuzz prend en charge plusieurs "technologies de mise en forme" qui diffèrent par la manière dont elles implémentent le processus de mise en forme — chaque implémentation est appelée un *composeur*, y compris dans `luaotfload` documentation. Le principal sujet de cet article est la mise en forme OpenType, mais une technologie alternative, libre d’utilisation, est [Graphite](https://scripts.sil.org/cms/scripts/page.php?site_id=projects\&item_id=graphite_aboutOT), développée par [SIL International](https://www.sil.org/). Un autre modèle de mise en forme pris en charge par HarfBuzz est [Apple Advanced Typography (AAT)](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6AATIntro.html)— les polices prenant en charge AAT sont généralement utilisées sur les plateformes technologiques d’Apple.

**Exemple utilisant le composeur Graphite**

L’exemple suivant compose un texte ourdou à l’aide d’une police appelée [Awami Nastaliq](https://software.sil.org/awami/download/), qui prend en charge la mise en forme Graphite et est disponible sur Overleaf. Awami Nastaliq est créée par [SIL International](https://www.sil.org/), l’organisation responsable du développement de la technologie Graphite.

L’exemple suivant démontre la capacité avancée de mise en forme des polices basées sur Graphite — notez comment la `luaotfload` déclaration de police sélectionne la mise en forme Graphite à l’aide de `shaper=graphite2`.

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

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

\vskip 75bp

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

[Ouvrez cet exemple dans 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)

Cet exemple produit le résultat suivant :

![](/files/c0f2ffcbb1b64d5cb17b64b13cad4535461860aa)

#### Emoji et mise en forme du texte

La mise en forme du texte a été introduite à l’aide d’exemples tirés d’une langue à script complexe, l’ourdou. Toutefois, il peut être surprenant d’apprendre que le rendu du ou des bons glyphes emoji nécessite l’application de la mise en forme du texte à un texte Unicode contenant des séquences de caractères emoji —[comme l’a noté le développeur principal de HarfBuzz](https://github.com/harfbuzz/harfbuzz/issues/2428#issuecomment-639108677):

> ... la mise en forme des emoji avec HarfBuzz entre tout à fait dans le champ et est en réalité nécessaire pour obtenir les emoji de famille, les couleurs de peau, etc.

Nous en verrons des exemples.

### Répartition des responsabilités : moteur de mise en forme du texte + polices OpenType

En pratique, la mise en forme du texte est une « opération conjointe », ou une répartition des tâches, entre la logique et les règles intégrées au moteur de mise en forme du texte et des règles et données de mise en forme supplémentaires intégrées à la ou aux polices utilisées — à partir de maintenant, nous abordons la mise en forme basée sur OpenType *uniquement*.

Pour effectuer la mise en forme, le moteur de mise en forme du texte reçoit généralement un certain texte Unicode, un script et une langue spécifiés, éventuellement une direction d’écriture, et, surtout, une police OpenType à utiliser pendant le processus de mise en forme — la police fournira le résultat : un ensemble de glyphes et des données de positionnement. Si demandé, le moteur de mise en forme peut appliquer des règles supplémentaires ([fonctionnalités OpenType](https://en.wikipedia.org/wiki/List_of_typographic_features#OpenType_typographic_features)) contenues dans la police OpenType utilisée — les règles à appliquer sont généralement sélectionnables par l’utilisateur dans la liste des fonctionnalités prises en charge par la police.

Le résultat du processus de mise en forme est une *liste de glyphes* contenue dans la police OpenType, ainsi que *inter-glyphes* des données de positionnement. Ces données de positionnement se rapportent au *placement relatif des glyphes mis en forme*; elles ne se réfèrent pas au positionnement absolu sur la page composée ou dans d’autres supports/contenus tels qu’une page web, un tweet, etc. Le logiciel de rendu (moteur de composition, navigateur web, etc.) utilise les informations de positionnement inter-glyphes pour s’assurer que les glyphes sont correctement positionnés les uns par rapport aux autres après avoir été assemblés et intégrés dans la sortie finale.

#### Qu’est-ce qu’une liste de glyphes ?

En interne, chaque glyphe d’une police OpenType se voit attribuer un identifiant numérique, une valeur entière appelée indice de glyphe — également appelée identifiant de glyphe ou GID. Une fois sa tâche de mise en forme terminée, le moteur de mise en forme du texte renverra ses résultats sous forme de *liste d’identifiants de glyphes* plus *des données de positionnement* pour ces glyphes.

Les glyphes individuels au sein des polices OpenType se voient attribuer des indices (identifiants) par le créateur de la police, ce qui en fait une valeur très spécifique à la police et arbitraire — elle peut aussi varier d’une version à l’autre d’une police particulière. Vous ne devez jamais supposer que la même valeur de GID s’appliquera à des glyphes « similaires » dans différentes polices ; ce ne sera presque certainement pas le cas. Si vous disposez d’une liste d’identifiants de glyphes fournie par un moteur de mise en forme, vous ne pouvez les utiliser que pour accéder aux glyphes de la police dont ils proviennent.

#### Que sont les polices OpenType ?

Le web est *inondé* d’explications et de détails sur les polices OpenType, nous nous limiterons donc à une brève description. La [spécification OpenType](https://docs.microsoft.com/en-us/typography/opentype/spec/) est un document complexe conçu pour les développeurs, mais, en substance, elle définit un format de fichier, ou conteneur, pour les données de police. Une police OpenType contient des données qui décrivent les formes des glyphes, ainsi que des informations sur les scripts et les langues pris en charge, des métadonnées sur la police, et diverses « tables » qui définissent [des caractéristiques typographiques](https://en.wikipedia.org/wiki/List_of_typographic_features#OpenType_typographic_features) prises en charge par la police.

Un moteur de mise en forme du texte peut généralement être invité à appliquer sélectivement (utiliser) les fonctionnalités d’une police pendant le processus de mise en forme, en appliquant des effets typographiques spécifiques (« règles ») qui sélectionnent l’ensemble approprié de glyphes contenus dans la police. La police choisie devra prendre en charge, et fournir les glyphes pour, toutes les fonctionnalités que le moteur de mise en forme du texte est invité à appliquer.

#### Glyphes « codés » et « non codés »

Les polices OpenType incluent une table de données appelée [cmap](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap) (Character to Glyph Index Mapping) qui associe l’ensemble des caractères Unicode pris en charge par la police à l’indice de glyphe correspondant dans cette police. La vidéo suivante offre un bref aperçu de la table cmap contenue dans une police appelée `lmmono10-regiular.otf` (incluse dans TeX Live).

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

Cependant, les polices contiennent généralement de nombreux glyphes qui ne représentent pas un caractère Unicode spécifique et ne sont pas inclus dans cette table cmap. Par conséquent, l’ensemble des glyphes présents dans une police OpenType peut être divisé en deux ensembles principaux :

* des glyphes codés qui représentent des caractères Unicode ;
* des glyphes non codés qui ne représentent pas de caractères Unicode.

Les glyphes codés peuvent être accessibles en incluant le caractère Unicode approprié dans le texte — mais qu’en est-il des glyphes non codés, comment sont-ils utilisés/accessibles ? Ces glyphes sont généralement utilisés pour fournir le résultat des opérations de mise en forme du texte, y compris l’application de fonctionnalités de police pour produire des effets visuels/typographiques spécifiques.

### les polices de couleur OpenType

Les caractères emoji sont censés s’afficher/rendre en couleur — les emoji en noir et blanc ne procurent pas tout à fait la « pleine expérience emoji ». Cependant, au moment du codage initial des emoji par Unicode, la [spécification des polices OpenType](https://docs.microsoft.com/en-us/typography/opentype/spec/) ne prévoyait aucune disposition adéquate pour incorporer *colorful*-les données de glyphe dans les polices OpenType. Cette « lacune » dans OpenType a poussé les principaux fournisseurs de technologies/plates-formes à chercher des solutions, et la course qui s’ensuivit a abouti à [diverses propositions visant à étendre OpenType](https://www.fontlab.com/news/color-font-format-proposals/) pour prendre en charge les polices couleur OpenType — non seulement pour afficher des caractères emoji colorés (glyphes), mais pour rendre n’importe quel glyphe en couleur.

#### Quatre variantes de police couleur OpenType

[Adobe, Microsoft, Google et Apple ont chacun soumis des propositions](https://www.fontlab.com/news/color-font-format-proposals/) pour étendre OpenType afin de prendre en charge des polices OpenType en couleur et, finalement, quatre propositions ont été adoptées et incluses dans la spécification formelle d’OpenType. Pour plus de commodité, nous pouvons regrouper grossièrement ces quatre variantes en basées sur des vecteurs et matricielles — mais, comme le montre ce [dépôt GitHub](https://github.com/simoncozens/test-fonts), la spécification OpenType est suffisamment flexible pour prendre en charge des fichiers de polices couleur OpenType qui combinent ces quatre technologies de base.

* **Polices OpenType basées sur des vecteurs :**
* **Microsoft**: les formes des glyphes sont décrites à l’aide d’une forme de vecteurs de couleur superposés ([COLR](https://docs.microsoft.com/en-us/typography/opentype/spec/colr) et [CPAL](https://docs.microsoft.com/en-us/typography/opentype/spec/cpal) tables).
* [**Adobe et Mozilla**](https://www.w3.org/2013/10/SVG_in_OpenType/) ([table SVG](https://docs.microsoft.com/en-us/typography/opentype/spec/svg)) : les formes des glyphes sont dessinées à l’aide de SVG, qui prend en charge les glyphes construits à partir de vecteurs *et d’images raster*. Voir aussi [le guide d’Adobe sur les polices SVG](https://helpx.adobe.com/fonts/user-guide.html/fonts/using/ot-svg-color-fonts.ug.html).
* **Polices OpenType basées sur des raster :**
* **Google**: les glyphes sont représentés par des images PNG en couleur intégrées à la police ([CBDT](https://docs.microsoft.com/en-us/typography/opentype/spec/cbdt) et [CBLC](https://docs.microsoft.com/en-us/typography/opentype/spec/cblc) tables).
* **Apple**: les glyphes sont également représentés par des images couleur intégrées à la police. En plus de PNG, le mécanisme d’Apple ([table sbix](https://docs.microsoft.com/en-us/typography/opentype/spec/colr)) prend également en charge JPEG et TIFF.

Par conséquent, les systèmes d’exploitation et les logiciels applicatifs prenant en charge les polices couleur OpenType doivent composer avec le paysage technologique mixte d’aujourd’hui. De plus, vous devez savoir que les polices couleur OpenType individuelles — et *les versions* d’une même police — vont :

* avoir une couverture différente de l’ensemble complet des [caractères emoji Unicode](https://unicode.org/emoji/charts/emoji-list.html)— c’est-à-dire combien de caractères emoji la police prend en charge ;
* utiliser des conceptions de glyphes différentes pour représenter des caractères emoji individuels ;
* varier dans les fonctionnalités qu’elles fournissent pour prendre en charge des usages plus avancés des normes Unicode, tels que [modificateurs d’emoji](https://unicode.org/reports/tr51/#Emoji_Modifiers_Table)l’orientation des séquences de caractères emoji ZWJ [la norme technique Unicode n° 51 : Unicode Emoji](https://unicode.org/reports/tr51/).

#### Le buzz autour de HarfBuzz

Nous avons fait allusion au besoin d’un *moteur de mise en forme du texte*: un logiciel qui prend un texte Unicode en entrée, écrit dans une combinaison script–langue spécifique, et, à l’aide d’une police désignée, transforme ce texte en une séquence de glyphes, avec des données de positionnement, qui peuvent être utilisées pour composer le texte source.

[HarfBuzz](https://harfbuzz.github.io/) est un tel moteur de mise en forme du texte : c’est [une bibliothèque de code open source](https://github.com/harfbuzz/harfbuzz) et le résultat de plus d’une décennie de recherche et développement — toujours activement développé et déployé dans le cadre de nombreux produits logiciels. HarfBuzz lui-même ne réalise pas la « composition » mais fournit des « services de mise en forme du texte » aux logiciels qui choisissent de l’intégrer, notamment XeTeX, LuaHBTeX, [Adobe PhotoShop et Adobe InDesign](https://en.wikipedia.org/wiki/HarfBuzz).

En intégrant HarfBuzz, les moteurs TeX peuvent tirer parti de ses capacités avancées de mise en forme du texte pour produire une composition multilingue très sophistiquée, en particulier pour des scripts complexes tels que l’arabe, l’hébreu, le devanagari et bien d’autres. Notez également qu’HarfBuzz est utilisé pour traiter et mettre en forme des caractères emoji Unicode, que nous explorerons en détail.

Le graphique suivant résume le rôle joué par HarfBuzz lorsqu’il est intégré à des logiciels tels que XeTeX ou LuaHBTeX, lors de la composition de texte dans un script complexe comme l’arabe :

![Vue d’ensemble de la mise en forme du texte arabe avec HarfBuzz](/files/e4ae29d4d8daf4c3f5583bb737a277697600e7f5)

**Explorer HarfBuzz**

Toute personne souhaitant en savoir plus sur HarfBuzz et les services de mise en forme OpenType qu’il fournit à XeTeX et LuaHBTeX peut [télécharger une distribution binaire de HarfBuzz](https://github.com/harfbuzz/harfbuzz/releases) qui contient la bibliothèque HarfBuzz (pour les programmeurs) et des utilitaires en ligne de commande `hb-view` et `hb-shape`.

**Exemple : comment utiliser hb-view**

Créez un nouveau fichier dans votre éditeur de texte préféré compatible UTF-8 et copiez/collez les six caractères emoji suivants 👋👋🏻👋🏼👋🏽👋🏾👋🏿 dans ce fichier texte, puis enregistrez-le au format UTF-8 dans un fichier appelé, par exemple, `emoji.txt`.

Notez que votre éditeur de texte peut afficher des versions noir et blanc de secours des emoji parce qu’il n’est pas capable (programmé) de rendre des glyphes en couleur. Une fois ces 6 emoji enregistrés, le fichier `emoji.txt` devrait contenir des données UTF-8 pour la séquence suivante de caractères emoji Unicode — nous avons séparé les modificateurs d’emoji par des virgules pour *faciliter la lecture uniquement*:

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

Il devrait y avoir un total de **11** caractères Unicode, chacun générant 4 octets de données UTF-8, donc le `emoji.txt` fichier résultant devrait mesurer 44 octets, hors éventuels marqueurs de fin de ligne utilisés à la fin de la ligne contenant l’emoji.

Le `hb-view` l’utilitaire peut utiliser le fichier `emoji.txt`, avec une police couleur OpenType appropriée de votre choix, telle que `NotoColorEmoji.ttf`, pour générer un fichier SVG de la sortie mise en forme par HarfBuzz. L’exemple de ligne de commande suivant, qui doit être **tapé sur une seule ligne** dans votre terminal, générera le fichier SVG `emoji.svg`:

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

En cas d’exécution réussie, le fichier `emoji.svg`, généré par `hb-view`, peut être ouvert dans Inkscape et devrait ressembler à ceci :

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

`hb-view` peut être utilisé pour explorer la mise en forme HarfBuzz pour n’importe quel fichier texte Unicode et police OpenType appropriés — il n’est certainement pas limité à une utilisation avec des emoji ! Tapez

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

pour voir la richesse des options de ligne de commande de cet utilitaire puissant et pratique. Bonne mise en forme !

## Mise en forme du texte et moteurs TeX

Ici, nous passerons en revue les capacités de mise en forme du texte de XeTeX et de la famille des moteurs TeX LuaTeX.

### XeTeX

XeTeX a été développé au début des années 2000 et a été pionnier de plusieurs innovations dans la composition basée sur TeX, notamment *la prise en charge intégrée* de :

* la lecture de texte Unicode au format UTF-8 ;
* l’utilisation de polices OpenType ;
* la mise en forme du texte pour une composition multilingue ;
* la composition mathématique basée sur OpenType.

La capacité de XeTeX à composer facilement et commodément des langues à script complexe est due à ses capacités intégrées de mise en forme du texte — à l’origine basées sur le, désormais obsolète, [ICU LayoutEngine](http://userguide.icu-project.org/layoutengine). Grâce au travail de Khaled Hosny, XeTeX est passé à l’utilisation de HarfBuzz pour la mise en forme du texte, comme indiqué dans une annonce de [mars 2013](https://tug.org/pipermail/xetex/2013-March/024118.html). Pour toute personne souhaitant composer du texte multilingue, XeTeX est généralement cité comme le moteur TeX de choix — mais il existe désormais une autre option, LuaHBTeX, que nous allons explorer.

### LuaTeX et LuaHBTeX

Le développement de LuaTeX a commencé vers 2005, mais a suivi une philosophie de conception assez différente de celle de XeTeX, qui incorporait de nouvelles fonctionnalités *directement dans* le logiciel XeTeX. Contrairement à XeTeX, les développeurs de LuaTeX ont choisi de « ... fournir un ensemble minimal d’outils et aucune solution. » (voir [le manuel de référence de LuaTeX](https://www.pragma-ade.com/general/manuals/luatex.pdf)). Plutôt que de fournir une suite de fonctionnalités supplémentaires *intégrées dans* les moteurs basés sur LuaTeX, les mécanismes internes des moteurs LuaTeX sont ouverts afin que les développeurs et les utilisateurs expérimentés puissent exploiter le langage de script Lua intégré pour construire leurs propres solutions.

Par exemple, contrairement à XeTeX, le moteur LuaTeX ne peut pas *directement* utiliser des polices OpenType ; à la place, les polices OpenType doivent être chargées et « préparées à l’emploi » par des fonctions de chargement de polices écrites en code Lua. Ces fonctions de chargement de polices sont appelées *de rappel* fonctions : du code Lua que LuaTeX appellera (« exécutera ») lorsqu’une demande de chargement de police est effectuée.

De plus, le moteur LuaTeX ne fournit aucune *la prise en charge intégrée* capacité de mise en forme du texte — celles-ci doivent également être fournies par du code externe que le moteur LuaTeX peut appeler pour lui fournir des services de mise en forme du texte. Là encore, cela contraste avec le moteur XeTeX, qui a intégré des capacités de mise en forme du texte dans le logiciel de base.

#### luaotfload : essentiel pour utiliser des polices OpenType dans LuaTeX/LuaHBTeX

Le mécanisme de rappel de LuaTeX pour le chargement des polices offre une grande flexibilité, au prix toutefois d’une programmation supplémentaire. Heureusement pour les utilisateurs de LuaLaTeX, la communauté TeX a développé un package appelé `luaotfload`, qui fait partie de la [version annuelle de TeX Live](https://www.tug.org/texlive/) et est, bien sûr, disponible pour les utilisateurs d’Overleaf.

`luaotfload` est [disponible sur CTAN](https://ctan.org/pkg/luaotfload?lang=en) et dispose d’un [dépôt de développement sur GitHub](https://github.com/latex3/luaotfload) où vous pouvez suivre les derniers développements et [les nouvelles versions](https://github.com/latex3/luaotfload/releases).

`luaotfload` peut être chargé directement dans le préambule d’un document LaTeX via

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

Notez que `luaotfload` est le nom d’un *package*, ce qui signifie qu’il a pour nom de fichier `luaotfload.sty`. Si vous vouliez utiliser `luaotfload` avec plain TeX, vous pouvez le faire en ajoutant la ligne

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

à votre document plain TeX.

Normalement, les utilisateurs de LuaLaTeX — c’est-à-dire ceux qui composent du LaTeX en utilisant LuaTeX/LuaHBTeX — n’ont pas besoin d’interagir directement avec `luaotfload` parce que la [`fontspec` package](https://ctan.org/pkg/fontspec) chargera le `luaotfload` package pour vous, en prenant en charge de nombreux détails de bas niveau grâce aux commandes de niveau utilisateur fournies par `fontspec` package.

### LuaHBTeX : nouvelles options pour la mise en forme du texte

`luaotfload` est une bibliothèque Lua mature et puissante qui fournit la gestion des polices OpenType par LuaTeX — ainsi que la fourniture de services de mise en forme du texte pour un éventail de langues et de scripts. À l’origine, les fonctions de mise en forme du texte de `luaotfload` étaient implémentées en pur code Lua, mais la sortie de TeX Live 2020 a apporté une autre option grand public pour la mise en forme du texte — un nouveau moteur basé sur LuaTeX appelé LuaHBTeX.

Le « HB » de LuaHBTeX signifie HarfBuzz — en substance, LuaHBTeX est le moteur LuaTeX d’origine *plus* avec un moteur intégré de mise en forme du texte HarfBuzz. Conformément à la philosophie de conception de LuaTeX, la disponibilité de HarfBuzz ne *automatiquement* garantit pas que le texte sera mis en forme par LuaHBTeX : HarfBuzz est un autre outil pouvant être utilisé pour élaborer des solutions de mise en forme du texte.

L’intégration de HarfBuzz dans LuaHBTeX est [programmable via du code Lua](#introduction-to-the-luahbtex-harfbuzz-api), ce qui a permis à `luaotfload`les développeurs d’ajouter des solutions de mise en forme du texte basées sur HarfBuzz. Par conséquent, [à partir de la version 3.1, publiée le 5 novembre 2019](https://github.com/latex3/luaotfload/releases/tag/v3.1), `luaotfload` a été amélioré pour tirer parti de HarfBuzz — rendant les capacités de mise en forme du texte de HarfBuzz faciles d’accès pour l’utilisateur général.

Les lecteurs intéressés par les détails techniques de l’intégration de HarfBuzz avec LuaTeX peuvent lire cet [article de Khaled Hosny](https://www.tug.org/TUGboat/tb40-1/tb124hosny-harfbuzz.pdf).

### luaotfload : deux options pour la mise en forme du texte (quand utiliser HarfBuzz ?)

Les utilisateurs de LuaLaTeX disposent désormais de deux options pour la mise en forme du texte :

* `luaotfload`l’implémentation originale (basée sur des nœuds) de la mise en forme du texte, écrite entièrement en Lua ;
* `luaotfload`la mise en forme de HarfBuzz basée sur HarfBuzz — accessible par du code Lua qui appelle les fonctions de mise en forme du texte de HarfBuzz.

`luaotfload` fournit l’accès à ces deux systèmes de mise en forme via son paramètre «`mode`» — bien que la plupart des utilisateurs utiliseront l’option équivalente `fontspec` «`Renderer`» plutôt que d’utiliser directement les fonctions de bas niveau de `luaotfload`.

Chacune des `luaotfload`solutions de mise en forme du texte de possède ses forces et ses faiblesses (actuelles), mais laquelle devriez-vous utiliser, et quand ? Voici quelques points à considérer :

* `luaotfload`Le traitement natif de basé sur des nœuds peut être gourmand en mémoire, en particulier pour les grandes polices OpenType CJK. Utiliser HarfBuzz pour la mise en forme de texte CJK peut apporter des améliorations de vitesse et une réduction de l’utilisation mémoire.
* Utilisez HarfBuzz pour les scripts complexes car il « ... améliore considérablement le rendu des scripts indic et arabes et est fortement recommandé pour ces scripts. » (voir `luaotfload` le manuel).
* L’intégration de HarfBuzz dans `luaotfload` est encore relativement récente et en cours de développement. Au moment de la rédaction (juillet 2021), il est conseillé d’utiliser la mise en forme intégrée de luaotfload (en réglant `mode=node`) pour les polices principales de votre document, en particulier si votre document utilise le script latin. Voir ce [problème GitHub](https://github.com/latex3/luaotfload/issues/175#issue-801120377), qui résume les problèmes et les discussions. Si vous souhaitez expérimenter, vous pouvez utiliser `luaotfload` pour charger un fichier de police et créer deux polices LaTeX : l’une qui utilise une mise en forme basée sur HarfBuzz et l’autre utilisant une mise en forme basée sur Lua. Overleaf a créé un [projet d’exemple](#sample-project-arabic-shaping), qui le démontre.
* N’utilisez pas HarfBuzz pour gérer les polices mathématiques. Comme l’ont expliqué des développeurs sur tex.stackexchange, HarfBuzz n’est [pas conçu pour gérer des polices destinées à la composition mathématique](https://tex.stackexchange.com/questions/544881/does-luahbtex-with-harfbuzz-renderer-completely-supports-math-formating) donc ne l’utilisez pas à cette fin.

**Projet d’exemple : mise en forme de l’arabe**

Voici un projet Overleaf qui utilise plusieurs polices arabes de haute qualité pour comparer `luaotfload`les services de mise en forme du texte basés sur des nœuds de (`mode=node`) avec ceux de HarfBuzz (`mode=harf`):

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

Ce projet inclut une sortie montrée dans l’image suivante :

![Composition de l’arabe](/files/c548607808e31c525287b0faec5732d588b82d05)

### Choisir le « Renderer » dans fontspec

Comme indiqué dans sa [documentation](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf), `fontspec` « ... permet aux utilisateurs de XeTeX ou LuaTeX de charger des polices OpenType dans un document LaTeX ». Si vous utilisez les moteurs LuaTeX ou LuaHBTeX, `fontspec` chargera le `luaotfload` bibliothèque pour vous et, de plus, fournissent une suite de commandes pratiques de niveau utilisateur qui évitent d’avoir à manipuler `luaotfload`les fonctionnalités de bas niveau de.

Alors, comment choisir entre la mise en forme d’HarfBuzz ou la mise en forme intégrée fournie par `luaotfload`? La réponse se trouve dans l’excellent [`fontspec` documentation](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf), en particulier la partie VI : fonctionnalités de police propres à LuaTeX. `fontspec` fournit un réglage appelé `Renderer` qui peut être défini lorsque la police est déclarée via `fontspec`. `Renderer` contrôle le traitement de bas niveau de la police. Les deux options qui nous intéressent sont

* `Renderer = Node`: le « mode » par défaut pour composer des polices OpenType — cela utilise `luaotfload`les fonctions de mise en forme du texte implémentées entièrement en Lua.
* `Renderer = Harfbuzz`: ce « mode » définit/charge la police à utiliser avec le moteur de composition de texte HarfBuzz. `luaotfload` utilise l’API de LuaHBTeX pour appeler des fonctions de HarfBuzz.

Pour plus d’informations, voir le [`fontspec` documentation](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf).

## moteurs TeX, HarfBuzz et les émojis couleur

Bien que XeTeX et LuaHBTeX intègrent tous deux HarfBuzz, ils offrent différents niveaux de prise en charge de certaines des fonctionnalités les plus avancées de HarfBuzz — notamment le chargement et l’utilisation des polices OpenType couleur.

### XeTeX et les polices OpenType couleur

Comme indiqué, il existe deux catégories de police OpenType couleur selon le format de données utilisé pour stocker les glyphes de la police : à base de vecteurs et à base de raster.

#### XeTeX et les polices OpenType couleur raster

XeTeX ne peut pas charger les polices OpenType couleur raster — comme celles de Google [Noto Color Emoji](https://www.google.com/get/noto/help/emoji/) fournies avec TeX Live 2020. Par exemple, si vous essayez de charger Noto Color Emoji (NotoColorEmoji.ttf), XeLaTeX échouera avec un message d’erreur potentiellement trompeur affirmant que Noto Color Emoji « est introuvable ». Le code LaTeX suivant, composé avec XeLaTeX, *ne fonctionne pas*:

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

[Ouvrez ce code XeLaTeX dans Overleaf (il ***ne déclenche pas*** fonctionne).](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)

Il échoue avec l’erreur :

```
! Package fontspec Error: The font "NotoColorEmoji" cannot be found.
```

De même, un exemple simple en Plain TeX traité par XeTeX échoue également

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

[Ouvrez cet exemple Plain TeX (XeTeX) dans Overleaf (il ***ne déclenche pas*** fonctionne).](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)

L’exemple Plain TeX affiche un message d’erreur similaire, mais différent :

```
! Font \emojifont=[NotoColorEmoji.ttf] at 12.0pt not loadable: Metric (TFM) fil
e or installed font not found.
l.1 \font\emojifont="[NotoColorEmoji.ttf]" at 12pt

Je n’ai pas pu lire les données de taille de cette police,
donc j’ignorerai la spécification de police.
[Les experts peuvent corriger les fichiers TFM à l’aide de TFtoPL/PLtoTF.]
Vous pourriez essayer d’insérer une autre spécification de police ;
par exemple, tapez `I\font<same font id>=<substitute font name>'.
```

**Exemple simple en Plain LuaHBTeX**

À titre de comparaison, voici un exemple minimal en Plain TeX compilé avec LuaHBTeX

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

[Ouvrez cet exemple Plain TeX (LuaHBTeX) dans Overleaf (il se compile avec succès).](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 véritable cause de l’échec de XeTeX

Les messages d’erreur fournis par XeTeX masquent en partie la cause réelle du problème : les polices OpenType couleur, en particulier les variantes raster, ne sont *ne* prises en charge par XeTeX. En réalité, XeTeX (Kpathsea) peut *trouver* la police Noto Color Emoji, mais XeTeX ne peut pas la *charger* complètement et est incapable d’initialiser les tables internes de données de police requises pour utiliser cette police à des fins de composition. En interne, XeTeX *démarre* le processus de chargement de la police et la teste pour sa « scalabilité » (en utilisant la définition de « scalabilité » de FreeType), mais ce test échoue, et XeTeX émet un message d’erreur standard du moteur TeX, sans doute trompeur.

**Note technique TeX**

Le traitement de NotoColorEmoji.ttf par XeTeX a été étudié en compilant une version de débogage de l’exécutable XeTeX. L’IDE Eclipse a été utilisé pour placer un point d’arrêt sur la fonction XeTeX `creatFontFromFile(filename, index, pointsize)`, puis parcourir le code pas à pas pour observer le traitement ultérieur.

#### XeTeX et les polices OpenType couleur basées sur des vecteurs

XeTeX peut *charger* charger les polices OpenType couleur à base de vecteurs mais ne produira pas d’émoji couleur dans le PDF résultant — si XeTeX en produit un du tout. Contrairement à LuaTeX, LuaHBTeX et pdfTeX, XeTeX ne *directement* produit pas de documents composés au format PDF. À la place, XeTeX produit un format intermédiaire `.xdv` (e**x**xten **dv**i) qui est converti en PDF par un utilitaire appelé `xdvipdfmx`. Au moment de la rédaction, `xdvipdfmx` est incapable d’intégrer les données appropriées des glyphes d’émojis couleur dans le PDF, donc, au mieux, vous verrez des émojis en monochrome — le résultat de « repli » — dans le PDF, ou peut-être rien du tout, selon la police utilisée.

Voici un exemple XeLaTeX qui utilise la police OpenType couleur [TwemojiMozilla.ttf](https://ctan.org/tex-archive/fonts/twemoji-colr), disponible dans TeX Live. TwemojiMozilla.ttf utilise le format vectoriel COLR/CPAL de Microsoft pour stocker les glyphes couleur et est fournie avec TeX Live 2020. Dans cet exemple, XeTeX est capable de charger la police, de générer un `.xdv` et un fichier PDF, mais le glyphe de l’émoji n’est pas présent dans le PDF composé :

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

[Ouvrez ce code XeLaTeX dans Overleaf (il NE fonctionne PAS).](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 revanche, le code ci-dessus fonctionne avec LuaLaTeX si l’on définit `\emojifont` en utilisant le `fontspec` paramètre `[Renderer=HarfBuzz]`:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont{TwemojiMozilla.ttf}[Renderer=HarfBuzz]
\newcommand{\smiley}{{\emojifont\char"1F600}}
Voici un smiley : \smiley
\end{document}
```

[Ouvrez ce code LuaLaTeX dans Overleaf (il fonctionne).](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 et les polices OpenType couleur

Grâce à son moteur de composition HarfBuzz intégré et à la bibliothèque `luaoftload` LuaHBTeX prend en charge les quatre variantes de police OpenType couleur. Les utilisateurs de LuaLaTeX peuvent tirer pleinement parti du traitement Unicode du texte contenant des caractères émoji ou simplement embellir leurs documents avec un texte très coloré à l’aide de polices OpenType couleur.

Comme indiqué précédemment, les quatre variantes de police OpenType couleur peuvent être classées en deux groupes :

* celles contenant des glyphes dans des formats d’image raster, comme PNG ;
* les autres qui utilisent des formats vectoriels SVG ou le mécanisme COLR/CPAL de Microsoft.

Les formats vectoriels de glyphes ont l’avantage de la scalabilité : produire des graphismes de glyphes nets à n’importe quelle taille en points.

**Utilisation des polices couleur Microsoft COLR/CPAL avec LuaHBTeX**

Si vous souhaitez utiliser un format vectoriel pour vos polices d’émojis couleur OpenType, découvrez la police [TwemojiMozilla.ttf](https://ctan.org/tex-archive/fonts/twemoji-colr?lang=en), qui est basée sur le format COLR/CPAL de Microsoft. TwemojiMozilla.ttf est incluse avec TeX Live, mais vous pouvez obtenir la dernière version sur son [dépôt GitHub](https://github.com/mozilla/twemoji-colr/releases) et la téléverser dans votre projet Overleaf.

Voici un petit exemple, `fontspec`-basé, `Renderer=Harfbuzz`, qui compose un gros canard émoji (vectoriel) :

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

[Ouvrez cet exemple LuaLaTeX pour composer un canard vectoriel.](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)

Voici le canard (vectoriel) produit par l’exemple ci-dessus :

![](/files/a99b27e156395fffee70c6d85d058c89f22970b5)

#### Utilisation de polices de couleur OpenType basées sur SVG avec LuaHBTeX

Au moment de la rédaction de cette mise à jour de l’article (juillet 2023), il existe peu de documentation officielle sur l’utilisation des polices OpenType couleur au rendu SVG avec LuaLaTeX. Certains [commentaires faits dans des discussions en ligne](https://github.com/latex3/luaotfload/issues/96) suggèrent d’utiliser `fontspec`de `RawFeature`, comme indiqué dans le pseudo-code ci-dessous. Remplacez `*nom de votre fichier de police SVG ici*` par le nom d’un fichier de police à base de SVG accessible à votre code LaTeX :

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emoji[RawFeature={+svg},SizeFeatures={Size=20}]{your SVG font file name here}
\emoji Votre émoji ici...
\end{document}
```

Si vous omettez `fontspec` et chargez `luaotfload` directement, vous devrez peut-être déclarer et spécifier une police de la manière suivante — nos expériences indiquent qu’il faut omettre le `mode=harf` option pour que cela fonctionne :

```latex
\font\emoji=[your SVG font file name here]:+svg;
```

**Quelques précautions**

Les lecteurs souhaitant utiliser les polices OpenType couleur au format SVG doivent noter :

* les polices OpenType au format SVG contenant un grand nombre de glyphes peuvent être [coûteuses en calcul pour LuaLaTeX](#processing-svg-glyph-data) à traiter, ce qui peut entraîner des [timeouts Overleaf](/latex/fr/base-de-connaissances/038-fixing-and-preventing-compile-timeouts.md).
* la prise en charge de ces polices par LuaLaTeX pourrait être [considérée comme expérimentale](https://github.com/latex3/luaotfload/issues/96#issuecomment-530317399) : les résultats peuvent varier selon la version de TeX Live utilisée par votre projet ; il est donc conseillé d’expérimenter et d’avancer avec prudence.

**Traitement des données SVG des glyphes**

SVG permet aux concepteurs de produire des designs complexes et colorés représentant les glyphes d’une police — sous réserve de certaines restrictions SVG [documentées dans la spécification OpenType](https://docs.microsoft.com/en-us/typography/opentype/spec/svg). Cependant, les moteurs TeX, y compris LuaHBTeX, ne peuvent pas importer directement (utiliser) des fichiers ou des données SVG — telles que les données SVG utilisées pour décrire les formes des glyphes dans les polices OpenType couleur au format SVG. Les données SVG d’un glyphe doivent être converties au format PDF parce que LuaHBTeX peut s’en servir pour composer le glyphe et produire le document PDF final. Cette conversion SVG vers PDF est gérée par du code Lua au sein de `luaoftload`: les données SVG de chaque glyphe sont extraites du fichier de police, enregistrées dans un fichier temporaire `.svg` et converties en PDF à l’aide d’Inkscape via son interface en ligne de commande. L’extraction des données SVG et leur conversion en PDF entraînent une certaine surcharge de traitement, ce qui peut se traduire par des temps de compilation de document potentiellement longs — en particulier pour les documents utilisant de grandes polices SVG contenant des milliers de glyphes d’émoji.

#### Polices OpenType couleur raster

**Utilisation du format de police couleur OpenType CBDT/CBLC de Google avec LuaHBTeX**

[Noto Color Emoji](https://fonts.google.com/noto/specimen/Noto+Color+Emoji) est une police OpenType couleur incluse avec TeX Live, ce qui la rend facile à utiliser dans un projet Overleaf. Comme Noto Color Emoji utilise des graphiques au format PNG pour représenter les glyphes d’émoji, nous pouvons l’utiliser pour composer un gros canard émoji (raster), comme le montre l’exemple suivant. Remarquez encore que la `fontspec` déclaration de police (`\emojifont`) utilise `Renderer=Harfbuzz`.

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

[Ouvrez cet exemple LuaLaTeX pour composer un canard raster.](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)

Voici le canard raster produit par l’exemple ci-dessus :

![Un canard raster composé par LaTeX](/files/77ab64e705a81fb1255289f7fd9a513db09c75c7)

Si vous essayez d’utiliser `NotoColorEmoji.ttf` mais omettez `[Renderer=Harfbuzz]` de la `fontspec` déclaration, LuaHBTeX échouera et affichera un message d’erreur lorsqu’il tentera d’écrire le fichier PDF :

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

La raison de cette erreur dans la [table loca](https://docs.microsoft.com/en-us/typography/opentype/spec/loca) est [expliquée sur GitHub](https://github.com/latex3/luaotfload/issues/98#issuecomment-531610153).

**Utilisation du format de police couleur OpenType sbix d’Apple avec LuaHBTeX**

Des tests hors ligne démontrent que LuaHBTeX prend en charge la variante `sbix` de police OpenType couleur, mais, à la date de rédaction de cet article, nous n’avons pas pu trouver une police d’émoji couleur `sbix`-variant convenablement licenciée pour démontrer la composition d’un canard. Veuillez [nous contacter](https://www.overleaf.com/contact) si vous en connaissez une, et nous mettrons rapidement à jour cet article pour l’utiliser.

## Introduction à l’API HarfBuzz de LuaHBTeX

![Db.gif](/files/06817a214d196d81a67a7f4c55b703e959d23056) ![Db.gif](/files/06817a214d196d81a67a7f4c55b703e959d23056)

La composition du texte, en particulier pour les langues à écritures complexes, et même pour les émojis, est une tâche intrinsèquement difficile ; il n’est donc pas surprenant que HarfBuzz soit une bibliothèque sophistiquée, qui peut s’avérer délicate à utiliser — à moins d’être déjà familier avec les opérations de composition du texte. Dans cette dernière section, nous examinons l’intégration de HarfBuzz par LuaHBTeX et la manière d’y accéder via du code Lua dans `\directlua`.

Notre exemple utilise un code assez basique pour démontrer l’API HarfBuzz de LuaHBTeX. Il est quelque peu artificiel, n’a pas la qualité d’une production, ni n’est très pratique, car son seul but est d’introduire quelques idées fondamentales. Nous avons séparé le code Lua en deux `\directlua` blocs : le premier charge la `luaharfbuzz` bibliothèque et crée quelques variables globales que nous utiliserons dans notre second `\directlua` bloc, où nous définissons une macro appelée `\codestoemoji`.

Il semble approprié de reproduire l’utilisation par Knuth de doubles signes d’interdiction en zigzag (image fournie par [ce site](http://www.truetex.com/db.htm)) car le contenu est quelque peu de bas niveau et « soulève le capot » — bien que nous espérions qu’il puisse intéresser le lecteur plus intrépide. L’intégration de HarfBuzz par LuaHBTeX est dérivée du [projet luaharfbuzz sur GitHub](https://github.com/ufyTeX/luaharfbuzz/wiki#projects-using-luaharfbuzz) où vous pouvez trouver une [introduction au projet](https://github.com/ufyTeX/luaharfbuzz/wiki) ainsi qu’une [liste de l’API luaharfbuzz](http://ufytex.github.io/luaharfbuzz/).

### Premiers pas : charger la bibliothèque luaharfbuzz et trouver une police

Pour utiliser l’API HarfBuzz de LuaHBTeX, nous devons d’abord charger la bibliothèque (module) appelée `luaharfbuzz`, intégrée à LuaHBTeX, et enregistrer la table renvoyée dans une variable (globale) que nous appellerons `hblib`:

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

Ensuite, nous devons localiser une police OpenType couleur d’émoji appropriée : nous utiliserons Noto Color Emoji — notez que nous faisons preuve d’une grande paresse et ne procédons à aucun contrôle d’erreur au cas où nous ne la trouverions pas ! Pour la trouver, nous utiliserons la bibliothèque `kpse` (Kpathsea), qui fait également partie de LuaTeX/LuaHBTeX :

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

Maintenant que nous avons accès à la bibliothèque HarfBuzz, via notre variable `hblib`, et au chemin d’accès à une police appropriée (`pathtofontfile`), nous pouvons commencer à l’utiliser. `hblib`Pour commencer, nous allons créer une police HarfBuzz et une face HarfBuzz à utiliser dans le second `\directlua` bloc de code où nous définissons notre macro.

```latex
%Créer une face HarfBuzz et une police HarfBuzz à partir de Noto Color Emoji
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)
```

#### Police HarfBuzz et face HarfBuzz : de quoi s’agit-il ?

A [Objet face HarfBuzz](https://harfbuzz.github.io/fonts-and-faces.html) représente une police chargée à partir d’un fichier de police, mais sans paramètres spécifiques (tels que la taille) définis. Un [objet police HarfBuzz](https://harfbuzz.github.io/fonts-and-faces.html) représente une *instance spécifique* d’une face HarfBuzz ; par conséquent, différents objets police HarfBuzz peuvent être dérivés d’une seule face HarfBuzz : chaque police HarfBuzz peut avoir ses propriétés, telles que la taille, définies à des valeurs différentes. Une face HarfBuzz est un niveau d’abstraction plus élevé qu’une police HarfBuzz.

### Utiliser les glyphes de police pour créer des fichiers PNG

La dernière partie de notre premier `\directlua` bloc est une fonction appelée `writePNGglyph(hbfontobject, glyphID)` que nous utilisons pour démontrer que certaines polices OpenType couleur, telles que Noto Color Emoji, utilisent des graphiques PNG pour représenter les glyphes d’émoji qu’elles contiennent.

Cette fonction utilise l’API HarfBuzz de LuaHBTeX pour extraire des données PNG à partir des glyphes et écrire ces données dans un fichier `.png` fichier nommé `Graphics<glyphID>.png`. Le nom de ce `.png` fichier est renvoyé pour être utilisé par `\includegraphics` pour intégrer les images PNG des glyphes dans notre PDF composé.

Avec le `writePNGglyph(hbfontobject, glyphID)` en place, notre premier `\directlua` bloc de code ressemble à ceci :

```latex
\directlua{

% Charger la bibliothèque luaharfbuzz depuis LuaHBTeX
hblib=require("luaharfbuzz")

% Localiser la police Noto Color Emoji sur le serveur d’Overleaf
pathtofontfile=kpse.find_file("NotoColorEmoji.ttf","truetype fonts")

% Créer une face HarfBuzz et une police HarfBuzz à partir de Noto Color Emoji
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)

% Cette fonction accepte une police et un identifiant de glyphe :
% elle extrait les données PNG des glyphes et les écrit
% dans un fichier .png

function writePNGglyph(hbfontobject, glyphID)

    % Obtenir les données PNG du glyphe
    local pngblob=hbfontobject:ot_color_glyph_get_png(glyphID)
    local pngdata=pngblob:get_data()

    % Construire un nom de fichier pour notre fichier .png
    local fname="Glyph"..glyphID..".png"

    % Écrire le fichier .png et renvoyer le nom du fichier
    local output = assert(io.open(fname, "wb"))
    output:write(pngdata)
    output:close()

    % Renvoyer le nom du fichier à utiliser par \includegraphics
    return fname
end
}
```

### Deuxième bloc \directlua : créer la macro \codestoemoji

Le but est de définir une macro `\codestoemoji` que nous pouvons appeler avec un morceau de texte contenant des codes de caractères émoji que nous voulons voir composer par HarfBuzz. Plus précisément, nous utiliserons `\Uchar<code de caractère>` pour représenter chaque caractère émoji ; par exemple :

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

Il se passe beaucoup de choses dans la définition de `\codestoemoji` que nous expliquerons ci-dessous, mais la définition ressemble à ceci :

```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 table de glyphes, hbglyphs, est indexée à partir de 1
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Réduire la taille de nos images PNG importées
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
}}
```

#### Comprendre la définition de la macro \codestoemoji

Le `\codestoemoji` la macro est pour l’essentiel du code Lua contenu dans `\directlua`, donc si vous souhaitez en savoir plus sur *comment* `\directlua` son fonctionnement, consultez l’article Overleaf [Comprendre `\directlua`](/latex/fr/articles-approfondis/09-an-introduction-to-luatex-part-2-understanding-directlua.md). Il explique comment LuaTeX et LuaHBTeX traitent `\directlua` lorsque des commandes TeX/LaTeX sont incluses dans le code Lua et, en particulier, la nécessité d’utiliser `\noexpand` et `\unexpanded`.

**Gestion du paramètre de macro : "#1"**

La macro commence par ces trois lignes :

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

qui accomplissent les tâches suivantes :

* `local str="#1"`: cela crée une chaîne Lua à partir de l’entrée passée par la macro ;
* `local hbbuffer = hblib.Buffer.new()`: cela utilise l’API HarfBuzz pour créer un tampon destiné à contenir le texte que nous voulons voir composé par HarfBuzz ;
* `hbbuffer:add_utf8(str)`: cela ajoute au tampon HarfBuzz une chaîne au format UTF-8, créée à partir de l’entrée de notre macro.

La première ligne de code

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

semble assez simple, mais son fonctionnement implique une certaine complexité, qu’il vaut la peine d’explorer un peu plus en détail.

Si l’on considère la troisième ligne de code

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

on voit qu’elle utilise notre `str` variable pour fournir au tampon HarfBuzz une chaîne Unicode formatée en UTF-8. Pour que cela fonctionne, la variable `str` doit elle-même contenir du texte Unicode formaté en UTF-8 ; la question se pose donc : *comment* LuaHBTeX a-t-il « converti » l’argument de macro `"#1"`, contenant `\Uchar` commandes, en la variable chaîne Lua `str` contenant du texte UTF-8 destiné à HarfBuzz ?

Si l’on regarde l’utilisation prévue de la `\codestoemoji` macro :

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

l’entrée, comme `\Uchar"1F3F4\Uchar"E0067\Uchar"E0062\Uchar"E0065...`, ne ressemble en rien à une suite de caractères émoji encodés en UTF-8. De plus, HarfBuzz ne connaît rien des commandes TeX. D’une manière ou d’une autre, l’entrée TeX brute composée de `\Uchar` commandes est transformée en caractères Unicode encodés en UTF-8 que HarfBuzz peut utiliser, mais *comment*?

la réponse réside dans le comportement de la `\Uchar` commande : tenter d’appeler `\codestoemoji` en utilisant `\char` à la place de `\Uchar` échouera, mais *pourquoi*?

**\Uchar : expansion dans \directlua**

Lorsque la `\codestoemoji` macro est appelée, la `\directlua` commande, stockée dans la définition de la macro, doit préparer du code Lua à envoyer à l’interpréteur Lua intégré de LuaHBTeX. Une partie de ce processus de préparation du code consiste à développer toutes les commandes TeX/LaTeX présentes dans le code Lua original de la définition de la macro, ainsi que les arguments de macro fournis par l’utilisateur. Ce processus de développement produit une liste de tokens qui est ensuite reconvertie en texte, générant le code Lua à transmettre à l’interpréteur Lua. Pour plus de commodité, nous reproduisons un diagramme tiré de l’article Overleaf [Comprendre `\directlua`](/latex/fr/articles-approfondis/09-an-introduction-to-luatex-part-2-understanding-directlua.md):

![Le mécanisme de \directlua](/files/02c7dc73e007ef127f6b97e29ac4eef9257adaee)

La macro `\codestoemoji` est destinée à être appelée avec `\Uchar` des commandes et,  [comme indiqué précédemment dans l’article](#the-key-difference-expansion), `\Uchar` est une commande développable dont le développement génère un jeton de caractère. Dans les activités de traitement de `\directlua`, LuaHBTeX développe chaque `\Uchar<code de caractère>` commande où il *supprime* chaque `\Uchar<code de caractère>` retirée de l’entrée et *remplace* avec la valeur d’expansion correspondante : un jeton de caractère représentant le `<code de caractère>`.

Dans la dernière étape du traitement, la liste initiale de jetons générée par `\directlua` est converti *en texte* pour devenir le code Lua destiné à l’interpréteur Lua (voir le diagramme ci-dessus). Tous les jetons de caractère produits par l’expansion de `\Uchar` sont également *reconvertis en texte*: cette conversion des jetons de caractère en texte génère les représentations UTF-8 des `<code de caractère>` valeurs d’origine.

Dans notre exemple, au moment où le code Lua est généré et prêt pour l’interpréteur Lua, l’entrée de la macro pour « #1 » a été convertie en une séquence de texte UTF-8 : la `str` variable est désormais une chaîne de texte UTF-8 qui peut être ajoutée sans risque au tampon HarfBuzz.

**Pourquoi \char ne fonctionne-t-il pas ?**

La réponse simple est que `\char` est *ne* une commande extensible. Contrairement aux `\Uchar` commandes, `\char` commandes *ne sont pas supprimés* du texte d’entrée pendant `\directlua`le traitement initial de `\directlua`pour générer une liste de jetons, ils « passent à travers » pour être incorporés dans la liste de jetons en cours de construction par `\codestoemoji` contenait `\char"1F3F4` LuaHBTeX convertirait cela en une séquence de jetons et les stockerait comme partie de la liste totale de jetons générée.

Dans l’étape suivante du traitement, lors de la conversion des jetons en texte, le code Lua résultant contiendrait la *chaîne littérale* `\char"1F3F4` dans le texte utilisé pour définir notre variable `str`. Lorsque le contenu de `str` est ajouté au tampon HarfBuzz, il ne contiendra pas une séquence encodée UTF-8 représentant le caractère emoji \\"1F3F4, il contiendrait la chaîne littérale `\char"1F3F4`, qu’HarfBuzz essaiera de mettre en forme et qui, pour nos besoins, ne produira pas de glyphe emoji. Au passage, la chaîne `\char"1F3F4` générerait également des erreurs de syntaxe Lua, sauf si elle était créée comme une « chaîne à longs crochets » — voir [Qu’est-ce que les séquences d’échappement Lua](/latex/fr/articles-approfondis/09-an-introduction-to-luatex-part-2-understanding-directlua.md#what-are-e2809clua-escape-sequencese2809d3f) pour un contexte sur ce point.

Si nous essayons d’utiliser `\codestoemoji` avec une commande `\char` la commande, comme ceci :

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

LuaHBTeX échouera et signalera une erreur de syntaxe du genre :

```latex
[\directlua]:1: invalid escape sequence near '"\c'.
\codestoemoji ...ing \includegraphics }.}]]) end }

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

L’interpréteur Lua a rencontré un problème, donc le
reste de ce bloc Lua sera ignoré.
```

#### Appeler la fonction de mise en forme HarfBuzz

**Définition des paramètres du tampon**

HarfBuzz a parfois besoin d’informations supplémentaires sur le texte qu’on lui demande de mettre en forme. Vous pouvez fournir ces informations en configurant vos `<variable de tampon>` en utilisant *méthodes du tampon*, telles que :

* `<variable de tampon>:set_direction(*direction HarfBuzz*)`;
* `<variable de tampon>:set_language(*langue HarfBuzz*)`;
* `<variable de tampon>:set_script(*script HarfBuzz*)`.

Par exemple, nous devons informer HarfBuzz que la direction de notre texte emoji sera de gauche à droite. Pour ce faire, nous utilisons la `set_direction()` méthode sur notre `<variable de tampon>` (appelé `hbbuffer`) en écrivant :

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

où `hblib.Direction.new("ltr")` crée un « objet de direction » approprié à transmettre au moteur HarfBuzz via Lua.

**Effectuer la mise en forme**

Une fois le tampon correctement initialisé, nous pouvons demander à HarfBuzz d’effectuer la mise en forme proprement dite via la fonction `shape_full()`. Dans notre exemple, nous écrivons :

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

Les 3e et 4e paramètres de la `shape_full()` fonction doivent être des tables Lua — nous avons utilisé des tables vides «`{}`» pour les deux paramètres. La forme générale de `shape_full()` est :

```latex
shape_full(police HarfBuzz, tampon HarfBuzz, {caractéristiques de police}, {"shaper"}
```

* **`{"shaper"}`**: n’a généralement pas besoin d’être défini, mais les options sont `{"ot"}` ou `{"graphite2"}`. Plus d’informations sur le concept de « shaper » se trouvent dans [la documentation HarfBuzz](https://harfbuzz.github.io/shaping-and-shape-plans.html)— notez qu’elle documente l’API C de bas niveau, et non le `luaharfbuzz` binding (implémentation) basé sur Lua.
* **`{caractéristiques de police}`**: Il s’agit d’une table répertoriant les [fonctionnalités OpenType](https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist)— prises en charge par la police — que vous voulez que HarfBuzz applique pendant la mise en forme.

Toute caractéristique de police que vous souhaitez utiliser doit être créée à l’aide d’une `luaharfbuzz` fonction de bibliothèque

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

où

* `library_instance` est votre `luaharfbuzz` variable d’instance de bibliothèque (`hblib` dans notre exemple) ;
* `feature_string` utilise une [syntaxe pour définir les caractéristiques](https://github.com/ufytex/luaharfbuzz/wiki/Feature-Strings). Exemples : `+smcp` pour activer les petites capitales ou `-kern` pour désactiver le crénage.

Par exemple :

```latex
local dosmcp = hblib.Feature.new("+smcp")
local nokern = hblib.Feature.new("-kern")
% Utilisez vos caractéristiques de police comme ceci
local res = hblib.shape_full(hbfont, hbbuffer, {dosmcp,nokern},{})
```

#### Accéder au résultat : obtenir les glyphes

Et enfin, si l’opération de mise en forme réussit, les glyphes mis en forme sont renvoyés dans la variable de tampon `hbbuffer` que nous avons créée plus haut dans le code.

Nous accédons aux glyphes via la méthode du tampon `get_glyphs()` et utilisons une boucle pour récupérer chaque glyphe individuellement. Notez que la table Lua contenant les glyphes, `hbglyphs` dans notre exemple, est indexée à partir de 1, pas de 0.

L’ *identifiant de glyphe* (appelé de manière trompeuse `codepoint`), et la police HarfBuzz (`hbfont`), sont transmis à la fonction `writePNGglyph()` qui crée un fichier PNG en utilisant la représentation rasterisée de ce glyphe par la police.

`writePNGglyph()` écrit un fichier PNG et renvoie le nom du fichier PNG, qui est utilisé pour importer le fichier PNG (mis à l’échelle) dans notre document LaTeX via `\includegraphics[scale=0.75]{<fname>}`. Notez comment nous pouvons utiliser `\includegraphics` directement dans le code Lua.

```latex
if (res) then
    local hbglyphs=hbbuffer:get_glyphs()
    % La table de glyphes, hbglyphs, est indexée à partir de 1
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Réduire la taille de nos images PNG importées
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
```

### Le code complet que vous pouvez ouvrir dans Overleaf

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

% Charger la bibliothèque luaharfbuzz depuis LuaHBTeX
hblib=require("luaharfbuzz")

% Localiser la police Noto Color Emoji sur le serveur d’Overleaf
pathtofontfile=kpse.find_file("NotoColorEmoji.ttf","truetype fonts")

% Créer une face HarfBuzz et une police HarfBuzz à partir de Noto Color Emoji
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)

% Cette fonction accepte une police et un identifiant de glyphe :
% il extrait les données PNG des glyphes et écrit
% dans un fichier .png

function writePNGglyph(hbfontobject, glyphID)

    % Obtenir les données PNG du glyphe
    local pngblob=hbfontobject:ot_color_glyph_get_png(glyphID)
    local pngdata=pngblob:get_data()

    % Construire un nom de fichier pour notre fichier .png
    local fname="Glyph"..glyphID..".png"

    % Écrire le fichier .png et renvoyer le nom du fichier
    local output = assert(io.open(fname, "wb"))
    output:write(pngdata)
    output:close()

    % Renvoyer le nom du fichier à utiliser par \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 table des glyphes, hbglyphs, est indexée à partir de 1.
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Réduire la taille de nos images PNG importées
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
}}

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

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

[Ouvrez cet exemple d’API luaharfbuzz dans Overleaf.](/latex/fr/articles-approfondis/10-an-overview-of-technologies-supporting-the-use-of-colour-emoji-fonts-in-latex.md)

Cet exemple produit le résultat suivant :

![Harfbuzzexample.png](/files/ced31d8da903bae25b231ced790ddc75f5e82c20)

## Section bonus : s’amuser avec les mathématiques emoji

Pour finir sur une note légère, un membre de l’équipe Overleaf a utilisé [`emoji` package LaTeX](https://ctan.org/pkg/emoji?lang=en) pour créer un exemple amusant :

```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}
```

[Ouvrez cet exemple amusant dans 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)

Cet exemple produit le résultat suivant :

![Emojimath2.png](/files/62994cfc9b2e1a2df533e05fdc41d8a6944b5352)


---

# 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/fr/articles-approfondis/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.
