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

# Ein Überblick über Technologien, die die Verwendung von Emoji-Schriftarten in Farbe in LaTeX unterstützen

## Einführung

Dieser Artikel bietet einen Überblick über verschiedene [Hintergrundthemen](#which-topics-do-we-cover) im Zusammenhang mit der Verwendung von OpenType-Farbfonts für den Schriftsatz farbiger Emojis in LaTeX. Wir haben versucht, eine breite Auswahl an Materialien bereitzustellen, die ein breites Spektrum an Interessen und Fachwissen abdecken. Um den Artikel überschaubar zu halten, verzichtet unsere Behandlung bestimmter Themen auf viele technische Details, aber wir hoffen, dass genügend Material vorhanden ist, um Ihre Erkundung des Schriftsatzes farbiger Emojis in LaTeX zu orientieren.

**Aktualisierung (Juli 2023)**: Dieser Artikel wurde erstmals im August 2021 veröffentlicht und im Juli 2023 überarbeitet, um den Abschnitt über [Verwendung von SVG-basierten OpenType-Farbfonts mit LuaHBTeX](#using-svg-based-opentype-color-fonts-with-luahbtex).

### Welche Themen behandeln wir?

Dieser Artikel behandelt die folgenden allgemeinen Themen:

* Unicode: der Standard, der Emojis als Zeichen kodiert und ihr erwartetes Verhalten in Anwendungen zur Textverarbeitung und zum Schriftsatz festlegt.
* OpenType-Farbfonts: spezielle Schriftarten, die farbige Darstellungen von Emoji-Zeichen in Ihrem LaTeX-Dokument bereitstellen.
* Textshaping: Einführung in eine Schlüsselkomponente beim Satz komplexer Schriftsysteme und Emojis.
* HarfBuzz: die Komponente von LuaHBTeX, die fortgeschrittenen mehrsprachigen Schriftsatz und die Verwendung von OpenType-Farbfonts ermöglicht, um Emojis in LaTeX zu setzen.
* Verschiedene TeX-Engines: ihre Unterstützung für OpenType-Farbfonts untersuchen und auswählen, welche TeX-Engine verwendet werden soll.
* LuaHBTeXs HarfBuzz-API: eine Einführung in die „Magie“ hinter [dem Textshaping](#the-concept-of-text-shaping) in LuaHBTeX.

### Drei Möglichkeiten, farbige Emojis zu setzen

Farbige Emojis können mit LaTeX auf drei Hauptarten gesetzt werden:

1. Verwendung standardmäßiger LaTeX-Grafikwerkzeuge wie TikZ, MetaPost oder Asymptote, um die Emojis zu zeichnen.
2. Einfügen von Emojis mithilfe vorab vorbereiteter Emoji-Grafiken, die in externen Dateien gespeichert sind.
3. Emojis als Unicode-kodierten Text behandeln und [dem Textshaping](#the-concept-of-text-shaping) mit [OpenType-Farbfonts](#opentype-color-fonts) verwenden, um sie zu setzen.

Die praktischen Optionen zum Einbinden farbiger Emojis in Ihr LaTeX-Dokument hängen von der verwendeten TeX-Engine ab, mit der das Dokument kompiliert wird: d. h., ob Sie verwenden:

* pdfLaTeX: pdfTeX-Engine + LaTeX;
* XeLaTeX: XeTeX-Engine + LaTeX;
* LuaLaTeX: LuaHBTeX-Engine (ab TeX Live 2020) + LaTeX.

Alle drei dieser TeX-Engines können LaTeX-Werkzeuge oder -Pakete verwenden, um Emojis zu zeichnen oder `\includegraphics{...}` zu verwenden, um Emojis einzufügen, die in externen Grafikdateien gespeichert sind. Das Zeichnen oder Importieren von Grafiken sind ideale Techniken, um Emojis zu setzen, wenn Sie eine Lösung benötigen, die nicht von der TeX-Engine abhängt, die zum Kompilieren des LaTeX-Dokuments verwendet wird.

Wenn Ihr Workflow jedoch die Flexibilität bietet, eine bestimmte TeX-Engine zu wählen, und Sie lieber OpenType-Farbfonts und Unicode-basiertes Textprocessing verwenden möchten, dann benötigen Sie die neueste Version von LuaTeX, genannt LuaHBTeX. Ab TeX Live 2020 wird LuaHBTeX verwendet, um LaTeX-Dokumente basierend auf dem LuaLaTeX-Format zu kompilieren.

## Hintergrund zu Unicode und Emoji-Zeichen

### Zeichenkodierungen

Computer speichern, übertragen und verarbeiten Text mithilfe einer Folge numerischer (Ganzzahl-)Werte, die die Bestandteile des Textes darstellen *Zeichen*. Zuverlässige Textverarbeitung erfordert, dass Erzeuger und Empfänger von Text sich darauf einigen, welche Ganzzahlwerte verwendet werden sollen, um einzelne Zeichen innerhalb des Textstroms darzustellen. Anders ausgedrückt: Was ist die *Zeichen* *Kodierung* eines solchen Textes?

### Einführung in Unicode

Historisch gesehen, in der Ära des 8-Bit-Texts, wurden viele verschiedene Zeichenkodierungen verwendet, wodurch stets das Gespenst von *Kodierungsinkompatibilitäten*: Erzeuger und Empfänger von Text nehmen fälschlicherweise unterschiedliche Kodierungen an, was zu Fehlern bei der Textverarbeitung führt. Wer seit einigen Jahren mit TeX/LaTeX arbeitet, ist wahrscheinlich auf Kodierungsinkompatibilitäten zwischen dem Eingabetext und den zum Satz eines Dokuments verwendeten Schriftarten gestoßen. Wenn die Dokumentenschriften so konfiguriert sind, dass sie eine andere Kodierung als die des Textes verwenden, führt dies wahrscheinlich zu fehlenden oder fehlerhaften Zeichen im gesetzten PDF.

Diese historischen Kodierungsprobleme können mithilfe eines internationalen Standards gelöst werden, der alle Zeichen der Welt kodiert: Unicode. Der Unicode-Standard ist nicht statisch, sondern wird regelmäßig aktualisiert, um weitere Zeichen und Schriftsysteme (Schreibsysteme) in sein Kodierungsschema aufzunehmen. Es gibt einen [formalen Begutachtungsprozess für das Vorschlagen neuer Zeichen](http://www.unicode.org/pending/proposals.html) mit einem speziellen [Schema für neue Emoji-Zeichen](https://www.unicode.org/emoji/proposals.html).

### Wie viele Unicode-Zeichen?

Unicode kodiert ein theoretisches Maximum von 1.114.112 Zeichen. Jeder der 1.114.112 Ganzzahlwerte wird als *Codepunkt*bezeichnet: der Ganzzahlwert, der zur Identifikation jedes Zeichens zugewiesen wird. Aus verschiedenen technischen Gründen können jedoch nur [1.112.064 Codepunkte](https://en.wikipedia.org/wiki/Unicode#Architecture_and_terminology) tatsächlichen Zeichen zugewiesen werden: 2048 Codepunkte sind nicht zuweisbar und für die Verwendung innerhalb Unicode-konformer Texte verboten.

Zum Zeitpunkt des Verfassens dieses Artikels (der ersten Version dieses Artikels) hatte Version 13 des Unicode-Standards insgesamt 143.859 Codepunkte tatsächlichen Zeichen zugewiesen, darunter [3304 Zeichen, die jetzt als Emojis kodiert sind](https://www.unicode.org/L2/L2020/20114r-family-emoji-explor.pdf) (siehe Seite 2 dieses Dokuments). Das Wachstum der Anzahl der von Unicode kodierten Zeichen ist im Artikel schön dokumentiert [Wie viele Unicode-Zeichen gibt es?](https://www.babelstone.co.uk/Unicode/HowMany.html) und in einem [Wikipedia-Eintrag](https://en.wikipedia.org/wiki/Unicode#Versions).

### Unicode-Ebenen

Die gesamte Sammlung von 1.114.112 Unicode-Codepunkten ist in 17 sogenannte Ebenen gegliedert: Ebene 0 bis Ebene 16, jede mit 65536 Codepunktwerten, was insgesamt ergibt $$17\times2^{16} = 1,114,112$$ Zeichen. Ebene 0, die [Basic Multilingual Plane](https://en.wikipedia.org/wiki/Plane_\(Unicode\)#Basic_Multilingual_Plane), kodiert die am häufigsten verwendeten Zeichen. Die Ebenen 1–16 heißen [Ergänzungsebenen](http://unicode.org/glossary/#supplementary_planes).

### Der Aufstieg der Emojis

Neue Zeichen entstehen durch veränderte Formen der menschlichen Kommunikation, und die Mobiltelefontechnologie brachte einen solchen Zeichensatz hervor: Emojis, die sich in Japan in den späten 1990er-Jahren entwickelten. Es überrascht nicht, dass die [Unicode-FAQ zu Emojis](https://unicode.org/faq/emoji_dingbats.html) merkt an

> „Das Wort emoji kommt vom japanischen [絵](http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=%E7%B5%B5) (e ≅ Bild) + [文字](http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=%E6%96%87) (moji ≅ geschriebenes Zeichen).“

Leser, die sich für den Hintergrund und die historische Entwicklung von Emojis interessieren, könnten Interesse an dieser [Unicode-Einführung](https://unicode.org/reports/tr51/#Introduction) oder dem Artikel [I second that emoji: Die Standards, Strukturen und soziale Produktion von Emojis](https://firstmonday.org/ojs/index.php/fm/article/view/9381).

Erst 2010, mit der Veröffentlichung von [Version 6.0 des Unicode-Standards](https://www.unicode.org/versions/Unicode6.0.0/), wurden viele Emojis offiziell als *Zeichen* für sich genommen [3304 Zeichen als Emojis kodiert](https://www.unicode.org/L2/L2020/20114r-family-emoji-explor.pdf) (siehe Seite 2 dieses Dokuments), wobei Unicode 13.1 [führt 3521 Emojis auf](https://unicode.org/emoji/charts/emoji-counts.html).

### Emojis leben auf einer höheren Ebene

Unicode hat vielen Emoji-Zeichen Codepunkte außerhalb der Basic Multilingual Plane (BMP) zugewiesen, kodiert [in Ebene 1](https://en.wikibooks.org/wiki/Unicode/Character_reference/1F000-1FFFF) mit Codepunkten im Bereich 1F000–1FFFF – was eine wichtige Konsequenz für alle hat, die Emojis in die Overleaf-Editoren (Code-Editor oder visueller Editor) *kopieren und einfügen* möchten. Die Texteditoren von Overleaf können derzeit nur Zeichen innerhalb der Basic Multilingual Plane verarbeiten, obwohl wir hoffen, dass zukünftige Upgrades Unterstützung für Nicht-BMP-Zeichen einführen werden. Beachten Sie, dass diese Einschränkung nur Nicht-BMP-Zeichen innerhalb von Text betrifft, der in Dateien eingefügt wird, die über die Overleaf-Editoren bearbeitet werden sollen. Es gibt weitere Möglichkeiten, auf Emoji-Zeichen zuzugreifen:

* Verwendung der primitiven Befehle `\char"<Codepunkt>` oder `\Uchar"<Codepunkt>` (siehe [diesen Abschnitt](#optional-detail-luatexluahbtex-char-vs-uchar) des Artikels).
* Verwendung von Eingabetextdateien, die Emoji-Zeichen im UTF-8-Format enthalten.
* Verwendung von LaTeX-Befehlen (Makros), die Emoji-Zeichen einfügen.

#### Emoji und andere Nicht-BMP-Zeichen in Overleaf einfügen

Wenn Sie beispielsweise ein Emoji-Zeichen 😀 in den Overleaf-Code-Editor einfügen, wird es derzeit in die Zeichen �� umgewandelt.

![Fehler durch Kopieren + Einfügen von Nicht-BMP-Zeichen in Overleaf-Editoren](/files/6a89996705446afab2380ccf60ca506aa3998aa8)

Das Zeichen � hat den Unicode-Codepunkt FFFD und sein offizieller Name ist REPLACEMENT CHARACTER und wird verwendet, um „[ein unbekanntes, nicht erkanntes oder nicht darstellbares Zeichen zu ersetzen](https://en.wikipedia.org/wiki/Specials_\(Unicode_block\))“ bezeichnet wird.

### Verwendung von Unicode-Codepunkten (U+) in LuaLaTeX

Die Unicode-Dokumentation stellt Codepunktwerte mit der Notation `U+<Hexadezimalwert>`– wie `U+1F600`, wobei `1F600` ist der `<Hexadezimalwert>` des Unicode-Codepunkts für das Emoji-Zeichen 😀. Um diese Codepunktwerte in LuaLaTeX zu verwenden, entfernen Sie das `U+` und schreiben `\char"<Hexadezimalwert>` oder `\Uchar"<Hexadezimalwert>`. Das `"` Zeichen teilt einer TeX-Engine mit, dass die angegebene Zahl hexadezimal dargestellt ist. Um beispielsweise das Emoji 😀 zu verwenden, würden Sie schreiben `\char"1F600` oder `\Uchar"1F600`—unter Verwendung einer Schriftart, die es setzen kann.

Ein minimales LuaLaTeX-Beispiel mit `\char` und `\Uchar` um das Emoji-Zeichen 😀 zu setzen, könnte sein:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont[Renderer=Harfbuzz]{NotoColorEmoji.ttf}
%Verwenden Sie \emojifont in einer Gruppe, um seine Wirkung lokal zu halten
{\emojifont
\Uchar"1F600
\char"1F600}
\end{document}
```

[Dieses LuaLaTeX-Beispiel in Overleaf öffnen](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)

**(optionales Detail) LuaTeX/LuaHBTeX: \char vs. \Uchar**

Zusätzlich zu dem herkömmlichen `\char<Zeichencode>` Befehl zum Setzen eines bestimmten `<Zeichencode>`mit der aktuellen Schrift bieten die LuaTeX-, LuaHBTeX- und XeTeX-Engines auch den `\Uchar<Zeichencode>` Befehl. Aus Sicht des Benutzers sehen die Ergebnisse von `\char` und `\Uchar` gleich aus, aber es gibt einen subtilen Unterschied darin, wie diese Befehle funktionieren, wie wir unten anmerken.

**Der entscheidende Unterschied: Expansion**

`\Uchar` ist ein sogenannter [expandierbarer Befehl](/latex/de/ausfuhrliche-artikel/22-how-does-expandafter-work-the-meaning-of-expansion.md#expansion-a-general-term-for-a-set-of-operations) während `\char` nicht expandierbar ist. Wenn ein `\char<Zeichencode>` oder `\Uchar<Zeichencode>` Befehl „ausgeführt“ wird – d. h. der Befehl wird nicht als Teil eines Makros oder einer anderen Tokenliste gespeichert –, finden innerhalb der TeX-Engine die folgenden Aktionen statt:

* **`\char<Zeichencode>`** weist die TeX-Engine an, sofort ein Zeichentoken einzufügen, das `<Zeichencode>`, in das jeweilige Stück Inhalt darstellt, das gerade gesetzt wird.
* Im Gegensatz dazu hat **`\Uchar<Zeichencode>`** zwei unterschiedliche Verarbeitungsschritte:

1. Die `\Uchar<Zeichencode>` Befehl wird *expandiert*, und das `<Zeichencode>` wird in eine temporäre Tokenliste umgewandelt, die ein einzelnes [Zeichen-Token](/latex/de/ausfuhrliche-artikel/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md#tex-tokens-101-28and-notions-of-expansion29) enthält, welches das `<Zeichencode>`.
2. Diese Tokenliste mit einem einzelnen Zeichen ist nun *verfügbar gemacht* für die TeX-Engine als Quelle ihrer nächsten Eingabe. In der Praxis „richtet die TeX-Engine ihren Blick vorübergehend um“, um diese Tokenliste mit einem einzigen Token als Ort ihres nächsten Eingabeelements (Tokens) zu verwenden. Standardmäßig geht die TeX-Engine einfach zurück, um dieses Token zu lesen (einzugeben) und das entsprechende Zeichen zu setzen, wodurch das Verhalten von `\char` Befehl zu interpretieren ist. **Allerdings**, da dieses `<Zeichencode>` nicht sofort gesetzt, sondern vorübergehend *gespeichert* (gespeichert) als ein einzelnes Token, können primitive TeX-Befehle oder LaTeX-Makros dieses Token verwenden (aufnehmen) – es muss nicht sofort gesetzt werden, sondern kann bei Bedarf in der weiteren Verarbeitung verwendet werden.

In der Praxis `\char<Zeichencode>` sagt „setze dieses `<Zeichencode>` jetzt“, während `\Uchar<Zeichencode>` eine Form von „verzögerter Aktion“ hat, indem ein gespeichertes Zeichentoken erzeugt und als nächstes Eingabeelement (ein Token) verfügbar gemacht wird. Dieses Token kann entweder von TeX-Befehlen und -Makros verwendet (aufgenommen) oder von der TeX-Engine erneut gelesen und gesetzt werden.

### Unicode (Kodierung) ist nicht die ganze Geschichte

Die Möglichkeit, Emoji-Zeichen innerhalb von Unicode-kodiertem Text zu verwenden, ist nur ein Teil der Erfolgsgeschichte der Emojis. Der starke Anstieg der Emoji-Nutzung wurde auch durch Entwicklungen in [der OpenType-Schrifttechnologie](https://learn.microsoft.com/en-us/typography/opentype/)ermöglicht — Schriftarten, deren Glyphendaten (Zeichendesigns) [Farbdaten](https://learn.microsoft.com/en-us/typography/opentype/spec/colr)enthalten können: [OpenType-Farbfonts](#opentype-color-fonts).

Abgesehen von geeigneten Schriftarten erfordert die Verwendung farbiger Emojis zusätzliche Softwarekomponenten, deren Aufgaben unter anderem umfassen:

* Vorverarbeitung („[Shaping](#the-concept-of-text-shaping)“) von Unicode-kodiertem Text, *Vorbereitung* für die Anzeige mit einer bestimmten Schriftart;
* *Rendern und Anzeigen* der farbigen Emoji *Glyphen* auf dem Bildschirm eines Geräts.

#### Glyph vs. Zeichen: Ist das nicht dasselbe?

Die Begriffe „Glyph“ und „Zeichen“ werden oft so verwendet, als seien sie austauschbar – sie beziehen sich auf dasselbe Grundkonzept –, doch in ihrer Bedeutung gibt es einen subtilen, wenn auch wichtigen Unterschied.

Unicode [definiert den Begriff „Zeichen“](http://www.unicode.org/glossary/#character) als:

> „Die kleinste Komponente geschriebener Sprache, die semantischen Wert hat; bezieht sich auf die abstrakte Bedeutung und/oder Form, nicht auf eine bestimmte Form …“

Im Gegensatz dazu ist ein „Glyph“ eine *spezifische* *Form* (Gestaltung) für die *visuelle Darstellung* eines bestimmten *Zeichen*.

Das Problem Zeichen vs. Glyph lässt sich leicht beobachten, wenn emoji-haltiger Text auf verschiedenen Softwaresystemen/-plattformen betrachtet wird, etwa beim Lesen desselben Textes auf Ihrem iOS- oder Android-basierten Mobiltelefon oder Windows-Desktopcomputer. Unabhängig davon, welches Gerät oder welche Plattform verwendet wird, würde der zugrunde liegende Text (Zeichenfolge) dieselben Unicode-kodierten *Emojis* *Zeichen*enthalten. Es sind gerätespezifische Fähigkeiten bei der *Vorverarbeitung* dieses Textes und dann bei der *Darstellung* und *Display-* der Ergebnisse, möglicherweise unter Verwendung gerätespezifischer Schriftarten, die unterschiedliche Glyphen (Zeichendesigns) erzeugen, um dieselben Emoji-Zeichen darzustellen.

Unicodes [vollständige Emoji-Liste](https://unicode.org/emoji/charts/full-emoji-list.html) stellt Beispielbilder bereit, die jedes Unicode-Emoji-Zeichen repräsentieren – und zeigt dabei verschiedene Glyphen, die von unterschiedlichen Technologieanbietern verwendet werden. Nicht nur übernehmen Schriftgestalter ihre eigenen spezifischen Designs (Glyphen), um Emoji-Zeichen darzustellen, sondern einzelne Schriftarten unterscheiden sich auch in der Anzahl der von ihnen unterstützten Emoji-Zeichen (für die sie Glyphen enthalten) und können mehr oder weniger fortgeschrittene Funktionen der Emoji-Textverarbeitung enthalten, die in den Unicode-Emoji-Spezifikationen enthalten sind.

Die Vorstellung und das Konzept von Zeichen, ihre Semantik und Kodierung bilden die Grundlage für die Welt von Unicode: Es geht um Zeichen. Die Gestaltung und visuelle Darstellung einzelner Zeichen als Glyphen gehören zu den Schrifttechnologien und zum Handwerk des Schriftentwurfs.

#### Unicode-Emojis: viel mehr als Textkodierung

Unicodes zentrale Rolle besteht darin, einen globalen Kodierungsstandard bereitzustellen, der definiert, welcher Ganzzahlwert, genannt *Codepunkt,* zur Darstellung jedes Zeichens, einschließlich Emojis, innerhalb eines Stroms Unicode-kodierten Textes verwendet werden soll.

Unicodes Spezifikation für Emojis definiert auch *Verarbeitungsverhalten* für bestimmte *Sequenzen* von Emoji-Zeichen, die in einem Strom Unicode-kodierten Textes erscheinen. Definierte Sequenzen von Emoji-Zeichen können durch einen Prozess namens [dem Textshaping](#the-concept-of-text-shaping) zusammengeführt werden, um eine einzelne resultierende („komposite“) Emoji-Glyphe zu erzeugen – diese einzelne Glyphe würde vom Betriebssystem des Geräts verwendet werden, um die ursprüngliche Zeichenfolge im Text darzustellen.

Unicodes technischer Bericht über [Unicode-Emoji](https://unicode.org/reports/tr51/) dokumentiert den reichen Funktionsumfang, der Software zur Verfügung steht, die eine Unicode-konforme Verarbeitung von Emoji-Zeichen bereitstellen möchte. Als Beispiel definiert (kodiert) Unicode Zeichen namens [Emoji-Modifikatoren](http://www.unicode.org/reports/tr51/#Emoji_Modifiers_Table) die verwendet werden können, um *Variationen* von „Basis“-Emoji-Zeichen zu erzeugen, etwa Variationen in [Hautton basierend auf der Fitzpatrick-Skala](http://www.unicode.org/reports/tr51/#Diversity). Beachten Sie, dass der Satz der Basis-Emoji-Zeichen und die anwendbaren Modifikatoren als Teil des gesamten [Unicode-Emoji-Standards](http://www.unicode.org/reports/tr51).

Die Unicode-Seite [Emoji-Sequenzen](http://unicode.org/emoji/charts/emoji-sequences.html) bietet ein Diagramm der Sequenzen, die derzeit von der Unicode-Spezifikation bereitgestellt werden. Bewegen Sie den Mauszeiger über eines der Emoji-Glyphenbilder, um einen kleinen Tooltip zu sehen, der Ihnen die zugrunde liegende Unicode-Emoji-Zeichenfolge mitteilt, aus der diese Glyphe erzeugt wird:

![EmojiSequenceChart.png](/files/845d9355e92104838f3d13691fb3fbbe38ac81b7)

Zum Beispiel ist die Emoji-Glyphe:

![HandMediumSkinTone.png](/files/1fd21496279a268003f7363bb4a0857f3de1050b)

im [Abschnitt der Modifikatorsequenzen](http://unicode.org/emoji/charts/emoji-sequences.html#modifier_sequences) aufgeführt und wird durch die zweizeichige Sequenz U+1F44B U+1F3FD erzeugt. Diese Bestandteile sind:

U+1F44B:![UnicodeWavingHandDefault.png](/files/a2fecb122095540176c61656b211769385d29e43) (WINKENDE HAND)

U+1F3FD:![FitzPatrick3.png](/files/584eb3b11aba1affaf6355d5ec81a755dc2215fd) (EMOJI-MODIFIKATOR FITZPATRICK-TYP-4)

**Verwendung von Hauttonmodifikatoren in LuaHBTeX**

Das folgende Beispiel verwendet LuaHBTeX, um die Verwendung von Emoji-Modifikatoren zu demonstrieren:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont[Renderer=HarfBuzz,SizeFeatures={Size=20}]{NotoColorEmoji.ttf}
Isoliertes Winken mit der Hand: {\emojifont\Uchar"1F44B}\par
Isolierter Modifikator: {\emojifont\Uchar"1F3FD}\par
Kombiniertes Ergebnis: {\emojifont\Uchar"1F44B\Uchar"1F3FD}
\end{document}
```

[Dieses LuaLaTeX-Beispiel für Emoji-Modifikatoren in Overleaf öffnen](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)

Dieses Beispiel erzeugt die folgende Ausgabe:

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

#### UTF-8: seine Rolle beim Speichern von Unicode-Text

Jeglicher Text oder Code, den Sie in Overleafs Code-Editor (oder visuellen Editor) eingeben oder einfügen, wird im UTF-8-Format gespeichert, daher überprüfen wir kurz, was UTF-8 eigentlich bedeutet. UTF steht für Unicode Transformation Format, und UTF-8s Rolle beim Speichern oder Übertragen von Unicode-kodiertem Text wird durch die Wendung „Transformation *Format*“ angezeigt.

Unicodes Codepunktwerte reichen von 0 bis zu einem Maximum von 1.114.111, daher ist es unmöglich, alle Unicode-Zeichenwerte mit einem einzelnen 8-Bit-Byte darzustellen, das nur bis zu 256 verschiedene Werte speichern kann: 0 bis 255. Es ist jedoch möglich, jeden Unicode-Codepunkt als eine *aufeinanderfolgende Sequenz* von bytegroßen Werten darzustellen – das ist das Prinzip hinter UTF-8.

UFT-8 bietet ein „Rezept“, um *transformieren* (d. h. zu „kodieren“ oder „konvertieren“) einen Unicode-Ganzzahl-Codepunktwert in eine eindeutige Folge von 1 bis 4 aufeinanderfolgenden bytegroßen Ganzzahlen: Die Anzahl der erforderlichen aufeinanderfolgenden Bytes hängt vom Wert des Codepunkts ab. Folglich kann man lesen, dass UTF-8 Unicode-Zeichen als *mehrbyteige Sequenzen* speichert, weil ein einzelnes Unicode-Zeichen (Codepunkt-Ganzzahl) in UTF-8 als eine Folge von 1 bis 4 aufeinanderfolgenden Bytes dargestellt wird.

Natürlich kann in UTF-8 gespeicherter Text wieder in seine ursprüngliche Folge von Unicode-Codepunkt-Ganzzahlen zurückverwandelt werden – das müssen XeTeX oder LuaTeX/LuaHBTeX beim Lesen einer im UTF-8-Format gespeicherten LaTeX-Eingabedatei tun. Diese TeX-Engines müssen die Unicode-Codepunkt- (Zeichen-) Werte der Eingabe kennen, bevor sie den Text setzen können. Beachten Sie, dass pdfTeX keine eingebaute UTF-8-Decodierungsfähigkeit hat und sich daher auf TeX-Makros verlassen muss, um im UTF-8-Format formatierten Eingabetext zu verarbeiten (zu dekodieren).

**Einige UTF-8-Beispiele**

* Das arabische Zeichen ش („sheen“) hat den Unicode-Codepunkt 0634 in Hexadezimal (Basis 16) bzw. 1588 in Dezimal (Basis 10). In UTF-8 wird ش durch 2 (hexadezimale) Werte D8 und B4 dargestellt, sodass das Zeichen ش als die zwei aufeinanderfolgenden Bytes D8B4 innerhalb von UTF-8-kodiertem Text gespeichert würde.
* Das Emoji-Zeichen 😀 hat den Unicode-Codepunkt 1F600 in Hexadezimal (Basis 16) bzw. 128512 in Dezimal (Basis 10). In UTF-8 wird 😀 durch 4 (hexadezimale) Werte F0, 9F, 98 und 80 dargestellt, sodass das Zeichen 😀 in einer UTF-8-Textdatei als die 4 aufeinanderfolgenden Bytes F09F9880 gespeichert würde.

#### Sonderzeichen, die in der Unicode-basierten Emoji-Textverarbeitung verwendet werden

Nicht jedes Zeichen, das innerhalb von Unicode kodiert ist, ist für die visuelle Darstellung durch die Glyphen einer Schriftart gedacht: Einige kodierte Zeichen sind als *nicht druckbare Zeichen* gekennzeichnet, deren Zweck darin besteht, spezialisierte Textverarbeitungsfunktionen (in unterstützender Software) zu unterstützen. Verschiedene Softwareanwendungen bieten unterschiedliche Unterstützungsstufen für die in Unicode kodierten nicht druckbaren Zeichen, sodass das Ergebnis von der verwendeten Softwareumgebung – Anwendungen und Schriftarten – abhängt.

**Zwei nicht druckbare Zeichen, die man kennen sollte**

* **Zero Width Joiner (ZWJ)**, Codepunkt 200D (hexadezimal), soll – wie sein Name andeutet – das „Verbindungsverhalten“ von Eingabezeichen auslösen; allerdings nur, wenn diese Eingabezeichen *besitzen* ein definiertes Verbindungsverhalten.
* **Zero Width Non-Joiner (ZWNJ)**, Codepunkt 200C (hexadezimal), soll *verhindern* das „Verbindungsverhalten“ unterbinden, das Eingabezeichen andernfalls zeigen könnten. Beispielsweise können Sie den ZWNJ verwenden, um das Verbindungsverhalten aufeinanderfolgender arabischer Zeichen zu verhindern, die normalerweise in ihre Verbindungsformen verarbeitet (geformt) würden.

Unicode hat eine Liste von [empfohlene Emoji-ZWJ-Sequenzen](https://unicode.org/emoji/charts/emoji-zwj-sequences.html) veröffentlicht, die einen U+200D ZERO WIDTH JOINER (ZWJ) verwenden, um Emoji-Zeichenfolgen zu einer einzigen zusammengesetzten Emoji-Glyphe zu kombinieren – sofern sie in den verwendeten Schriftarten verfügbar ist.

**Beispiel für die Verwendung von Zero Width Non-Joiner**

Das folgende minimale Codefragment verwendet die in TeX Live enthaltene Scheherazade-OpenType-Schrift, um eine LaTeX-Schrift namens `\arabicfont` zu definieren, die wir zum Setzen einiger arabischer Texte verwenden können. Die Zeile

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

verwendet ein Zero-Width-Non-Joiner-Zeichen über `\Uchar"200C`, um das normale Verbindungsverhalten der beiden arabischen Buchstaben ل (lam) und ا (alef) zu verhindern. Beachten Sie die Verwendung von `\textdir TRT` um die Textrichtung auf rechts-nach-links festzulegen:

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

[Dieses LuaLaTeX-Beispiel in Overleaf öffnen](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)

Dieses Beispiel erzeugt die folgende Ausgabe:

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

## Das Konzept des „Textshapings“

Beginnen wir mit einem visuellen Beispiel anhand einer Urdu-Übersetzung des Wortes „educational“. Der Text der Urdu-Übersetzung könnte auf einer Tastatur oder einem Touchscreen-Gerät eingegeben werden und würde als einfache lineare Folge Unicode-arabischer Zeichen erstellt. Wenn dieser Text jedoch gesetzt oder auf dem Bildschirm eines Geräts im [Nastaliq-Stil](https://en.wikipedia.org/wiki/Nastaliq)angezeigt wird, entsteht eine komplexe zweidimensionale Anordnung von Glyphen.

Anhand unseres Urdu-Beispiels vergleicht die folgende Grafik die lineare Eingabe von Unicode-Arabisch *Zeichen* mit der im Nastaliq-Stil gesetzten Ausgabe, die eine zweidimensionale Anordnung von *Glyphen* enthalten ist in der (kostenlosen) Schriftart [Awami Nastaliq](https://software.sil.org/awami/download/):

![](/files/8efafe74f39d67b445efa0903b7ad43c4544d4f6)

Der Prozess des „Übersetzens“ von Eingabezeichen in eine Menge korrekt positionierter Ausgabe-Glyphen wird genannt *dem Textshaping*und ist ein wesentlicher Bestandteil der Verarbeitung von Text vor seiner Anzeige oder seinem Schriftsatz. Unser Beispiel verwendete Text in der Urdu-Sprache (arabische Schrift), weil das Ergebnis des Shapings dort deutlich sichtbar ist, im Gegensatz zu Sprachen mit lateinischer Schrift wie Englisch, wo Shaping viel weniger ausgeprägt ist – etwa bei der Bildung einfacher Ligaturen.

Textshaping ist wesentlich bei der Verwendung von Schriftsystemen wie [Arabisch](https://en.wikipedia.org/wiki/Arabic), [Hebräisch](https://en.wikipedia.org/wiki/Hebrew_language), [Devanagari](https://en.wikipedia.org/wiki/Devanagari) oder [Malayalam](https://en.wikipedia.org/wiki/Malayalam), nur vier Beispiele der sogenannten *komplexen Schriftsysteme*. Um die korrekte Darstellung von Text in diesen Schriftsystemen und den Sprachen, die sie verwenden, sicherzustellen, muss der Shaping-Prozess sorgfältig alle Shaping-Regeln und Nuancen berücksichtigen, die in der jeweiligen Schriftsystem-Sprach-Kombination vorhanden sind. Beispielsweise erfordern manche Sprachen mehrere Eingabezeichen, um eine bestimmte Ausgabe-Glyphe zu erzeugen, oder es kann komplexe Anforderungen an die sorgfältige Positionierung diakritischer Zeichen und an Umordnungen zwischen Glyphen geben, um sicherzustellen, dass einzelne Glyphen korrekt (zueinander relativ) positioniert werden.

Im Allgemeinen erfordert das Shaping eines Textstücks mehrere Informationen:

* Das Schriftsystem oder *Schrift* in dem der Text geschrieben ist.
* Die spezifische *Sprache* verwendet wird. Einzelne Schriften können für mehrere Sprachen verwendet werden, wobei jede Schrift-Sprach-Kombination ihre eigenen Besonderheiten/Feinheiten beim Shaping hat.
* Die Schreibrichtung *Richtung* des Textes – etwa von rechts nach links oder von links nach rechts.
* Ein *Schriftart* die die Glyphen bereitstellt, die benötigt werden, um den geformten Text darzustellen, und optional zusätzliche „Shaping-Regeln“ enthält, die den Text-Shaping-Prozess steuern.

Die Anforderungen an das Text-Shaping, insbesondere bei komplexen Schriften und den dazugehörigen Sprachen, können äußerst detailliert und nuanciert sein, was den Bedarf an spezialisierter Software erkennen lässt, die potenziell sehr komplexe Text-Shaping-„Regeln“ anwenden kann. Wenig überraschend gibt es solche Software, und sie wird als *Text-Shaping-Engine*bezeichnet; diejenige, über die wir sprechen werden, heißt [HarfBuzz](https://en.wikipedia.org/wiki/HarfBuzz), dessen Dokumentation lesenswert ist – zum Beispiel [Warum brauche ich eine Shaping-Engine?](https://harfbuzz.github.io/why-do-i-need-a-shaping-engine.html).

**Weiterführende Lektüre zum Text-Shaping**

Diese kurzen Einführungen werden sehr empfohlen:

* [Was ist Text-Shaping?](https://harfbuzz.github.io/what-is-harfbuzz.html#what-is-text-shaping)
* [Warum brauche ich eine Shaping-Engine?](https://harfbuzz.github.io/why-do-i-need-a-shaping-engine.html)

**TeXnischer Hinweis: mehrere Shaping-Technologien (Modelle)**

Die HarfBuzz-Text-Shaping-Engine unterstützt mehrere „Shaping-Technologien“, die sich darin unterscheiden, wie sie den Shaping-Prozess implementieren – jede Implementierung wird als *Shaper*bezeichnet, auch in `luaotfload` -Dokumentation. Der Schwerpunkt dieses Artikels liegt auf OpenType-Shaping, aber eine alternative, frei nutzbare Technologie ist [Graphite](https://scripts.sil.org/cms/scripts/page.php?site_id=projects\&item_id=graphite_aboutOT), entwickelt von [SIL International](https://www.sil.org/). Ein weiteres von HarfBuzz unterstütztes Shaping-Modell ist [Apple Advanced Typography (AAT)](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6AATIntro.html)– Schriften mit AAT-Unterstützung werden im Allgemeinen auf Apple-Technologieplattformen verwendet.

**Beispiel mit dem Graphite-Shaper**

Das folgende Beispiel setzt etwas Urdu-Text mit einer Schrift namens [Awami Nastaliq](https://software.sil.org/awami/download/), die Graphite-Shaping unterstützt und auf Overleaf verfügbar ist. Awami Nastaliq wurde von [SIL International](https://www.sil.org/)erstellt, der Organisation, die für die Entwicklung der Graphite-Technologie verantwortlich ist.

Das folgende Beispiel zeigt die fortgeschrittene Shaping-Fähigkeit von Graphite-basierten Schriften – beachte, wie die `luaotfload` Schriftdeklaration Graphite-Shaping mit `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

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

[Dieses Beispiel in Overleaf öffnen.](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)

Dieses Beispiel erzeugt die folgende Ausgabe:

![](/files/206505b3154e61fb56d39d7a60b1252bb1a62ebd)

#### Emoji und Text-Shaping

Text-Shaping wurde anhand von Beispielen aus einer Sprache mit komplexer Schrift, Urdu, eingeführt. Es mag jedoch überraschend sein zu erfahren, dass die Darstellung der korrekten Emoji-Glyphe(n) Text-Shaping erfordert, das auf Unicode-Text mit Sequenzen von Emoji-Zeichen angewendet wird –[wie vom leitenden Entwickler von HarfBuzz angemerkt](https://github.com/harfbuzz/harfbuzz/issues/2428#issuecomment-639108677):

> ... Emoji mit HarfBuzz zu shapen gehört vollständig dazu und ist tatsächlich notwendig, um Familien-Emoji, Hautfarbe usw. zu erhalten.

Wir werden uns Beispiele dafür ansehen.

### Aufteilung der Verantwortung: Text-Shaping-Engine + OpenType-Schriften

In der Praxis ist Text-Shaping eine „gemeinsame Aufgabe“ oder Arbeitsteilung zwischen der in die Text-Shaping-Engine eingebauten Logik und den zusätzlichen Shaping-Regeln und Daten, die in die verwendeten Schrift(en) eingebettet sind – ab jetzt behandeln wir nur noch OpenType-basiertes Shaping *nur*.

Um Shaping durchzuführen, wird die Text-Shaping-Engine typischerweise mit etwas Unicode-Text, einer angegebenen Schriftart und Sprache, möglicherweise einer Schreibrichtung und, am wichtigsten, einer OpenType-Schrift für die Verwendung während des Shaping-Prozesses versorgt – die Schrift liefert die Ausgabe: einen Satz von Glyphen und Positionierungsdaten. Falls gewünscht, kann die Shaping-Engine zusätzliche Regeln ([OpenType-Features](https://en.wikipedia.org/wiki/List_of_typographic_features#OpenType_typographic_features)) anwenden, die in der verwendeten OpenType-Schrift enthalten sind – welche Regeln angewendet werden, ist üblicherweise vom Benutzer aus der Liste der von der Schrift unterstützten Features auswählbar.

Das Ergebnis des Shaping-Prozesses ist eine *Liste von Glyphen* aus der OpenType-Schrift, zusammen mit *zwischen den Glyphen* Positionierungsdaten. Diese Positionierungsdaten beziehen sich auf die *relative Platzierung der geformten Glyphen*; sie beziehen sich nicht auf die absolute Positionierung innerhalb der gesetzten Seite oder anderer Medien/Inhalte wie einer Webseite, eines Tweets usw. Die Darstellungssoftware (Satz-Engine, Webbrowser usw.) verwendet die Inter-Glyphen-Positionierungsinformationen, um sicherzustellen, dass die Glyphen nach dem Zusammensetzen und Einfügen in die finale Ausgabe korrekt zueinander positioniert sind.

#### Was ist eine Liste von Glyphen?

Intern wird jeder Glyphe innerhalb einer OpenType-Schrift eine numerische Kennung zugewiesen, ein ganzzahliger Wert, der Glyphenindex genannt wird – auch Glyphen-Identifikator oder GID. Nach Abschluss ihrer Shaping-Aufgabe gibt die Text-Shaping-Engine ihre Ergebnisse als eine *Liste von Glyphen-Identifikatoren* plus *Positionierungsdaten* für diese Glyphen zurück.

Einzelne Glyphen innerhalb von OpenType-Schriften werden vom Ersteller der Schrift mit Indizes (Kennungen) versehen, was diesen Wert sehr schriften­spezifisch und willkürlich macht – er kann sich auch zwischen Versionen einer bestimmten Schrift unterscheiden. Du solltest niemals annehmen, dass derselbe GID-Wert für „ähnliche“ Glyphen in verschiedenen Schriften gilt; das wird fast sicher nicht der Fall sein. Wenn du eine von einer Shaping-Engine bereitgestellte Liste von Glyphen-Identifikatoren hast, kannst du sie nur verwenden, um auf Glyphen in der Schrift zuzugreifen, aus der sie stammen.

#### Was sind OpenType-Schriften?

Das Web ist *überschwemmt* mit Erklärungen und Details zu OpenType-Schriften, daher beschränken wir uns auf eine kurze Beschreibung. Die [OpenType-Spezifikation](https://docs.microsoft.com/en-us/typography/opentype/spec/) ist ein komplexes Dokument für Entwickler, aber im Wesentlichen definiert sie ein Dateiformat oder Container für Schriftdaten. Eine OpenType-Schrift enthält Daten, die die Glyphenformen beschreiben, zusammen mit Informationen über die unterstützten Schrift(en) und Sprache(n), Metadaten zur Schrift und verschiedene „Tabellen“, die [typografische Merkmale](https://en.wikipedia.org/wiki/List_of_typographic_features#OpenType_typographic_features) festlegen, die von der Schrift unterstützt werden.

Eine Text-Shaping-Engine kann normalerweise angewiesen werden, die Features einer Schrift während des Shaping-Prozesses selektiv anzuwenden (zu verwenden) und dabei bestimmte typografische Effekte („Regeln“) anzuwenden, die den geeigneten Satz von Glyphen auswählen, der in der Schrift enthalten ist. Die gewählte Schrift muss alle Features, die die Text-Shaping-Engine anwenden soll, unterstützen und die Glyphen dafür bereitstellen.

#### Kodierte und unkodierte „Glyphen“

OpenType-Schriften enthalten eine Datentabelle namens [cmap](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap) (Character to Glyph Index Mapping), die die Menge der Unicode-Zeichen, die von der Schrift unterstützt werden, dem entsprechenden Glyphenindex in dieser Schrift zuordnet. Das folgende Video gibt einen kurzen Einblick in die cmap-Tabelle einer Schrift namens `lmmono10-regiular.otf` (enthalten in TeX Live).

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

Schriften enthalten jedoch typischerweise viele Glyphen, die kein bestimmtes Unicode-Zeichen darstellen und nicht als Teil dieser cmap-Tabelle enthalten sind. Folglich kann die Menge der in einer OpenType-Schrift vorhandenen Glyphen in zwei Hauptmengen unterteilt werden:

* kodierte Glyphen, die Unicode-Zeichen darstellen;
* unkodierte Glyphen, die keine Unicode-Zeichen darstellen.

Kodierte Glyphen können durch Einfügen des entsprechenden Unicode-Zeichens in den Text aufgerufen werden – aber was ist mit unkodierten Glyphen, wie werden sie verwendet/aufgerufen? Diese Glyphen werden typischerweise verwendet, um die Ausgabe von Text-Shaping-Operationen bereitzustellen, einschließlich der Anwendung von Schrift-Features, um bestimmte visuelle/typografische Effekte zu erzeugen.

### OpenType-Farbfonts

Von Emoji-Zeichen wird erwartet, dass sie in voller Farbe angezeigt/gerendert werden – schwarz-weiße Emoji bieten nicht ganz das „volle Emoji-Erlebnis“. Zum Zeitpunkt der ursprünglichen Unicode-Kodierung von Emoji hatte die [OpenType-Schrift­spezifikation](https://docs.microsoft.com/en-us/typography/opentype/spec/) keine geeignete Möglichkeit, *colorful*-Glyphen-Daten innerhalb von OpenType-Schriften einzubetten. Diese „Lücke“ in OpenType veranlasste führende Technologie-/Plattformanbieter, nach Lösungen zu suchen, und das daraus resultierende „Wettrennen“ führte zu [verschiedenen Vorschlägen zur Erweiterung von OpenType](https://www.fontlab.com/news/color-font-format-proposals/) , um OpenType-Farbschriften zu unterstützen – nicht nur für die Darstellung farbiger Emoji-Zeichen (Glyphen), sondern um jede Glyphe in Farbe darzustellen.

#### Vier Varianten von OpenType-Farbschriften

[Adobe, Microsoft, Google und Apple haben jeweils Vorschläge eingereicht](https://www.fontlab.com/news/color-font-format-proposals/) , um OpenType so zu erweitern, dass vollfarbige OpenType-Schriften unterstützt werden, und letztlich wurden vier Vorschläge übernommen und in die formale OpenType-Spezifikation aufgenommen. Der Einfachheit halber können wir diese vier Varianten grob in vektorbasierte und rasterbasierte Gruppen einteilen – wie jedoch in diesem [GitHub-Repository](https://github.com/simoncozens/test-fonts)gezeigt wird, ist die OpenType-Spezifikation flexibel genug, um OpenType-Farbschriftdateien zu unterstützen, die diese vier Basistechnologien kombinieren.

* **Vektorbasierte OpenType-Schriften:**
* **Microsoft**: Glyphenformen werden mithilfe einer Form geschichteter Farbvektoren beschrieben ([COLR](https://docs.microsoft.com/en-us/typography/opentype/spec/colr) und [CPAL](https://docs.microsoft.com/en-us/typography/opentype/spec/cpal) Tabellen).
* [**Adobe und Mozilla**](https://www.w3.org/2013/10/SVG_in_OpenType/) ([SVG-Tabelle](https://docs.microsoft.com/en-us/typography/opentype/spec/svg)): Glyphenformen werden mit SVG gezeichnet, das Glyphen unterstützt, die aus Vektoren *und Rasterbildern* zusammengesetzt sind. Siehe auch [Adobes Benutzerhandbuch zu SVG-Schriften](https://helpx.adobe.com/fonts/user-guide.html/fonts/using/ot-svg-color-fonts.ug.html).
* **Rasterbasierte OpenType-Schriften:**
* **Google**: Glyphen werden durch farbige PNG-Bilder dargestellt, die in die Schrift eingebettet sind ([CBDT](https://docs.microsoft.com/en-us/typography/opentype/spec/cbdt) und [CBLC](https://docs.microsoft.com/en-us/typography/opentype/spec/cblc) Tabellen).
* **Apple**: Glyphen werden ebenfalls durch farbige Bilder dargestellt, die in die Schrift eingebettet sind. Zusätzlich zu PNG unterstützt Apples Mechanismus ([sbix-Tabelle](https://docs.microsoft.com/en-us/typography/opentype/spec/colr)) auch JPEG und TIFF.

Infolgedessen müssen Betriebssysteme und Anwendungssoftware, die OpenType-Farbschriften unterstützen, mit der heutigen gemischten Technologielandschaft umgehen. Außerdem solltest du wissen, dass einzelne OpenType-Farbschriften – und *Versionen* derselben Schrift –

* eine unterschiedliche Abdeckung des gesamten Satzes von [Unicode-Emoji-Zeichen](https://unicode.org/emoji/charts/emoji-list.html)haben werden – d. h. wie viele Emoji-Zeichen die Schrift mit Glyphen versorgt;
* unterschiedliche Glyphendesigns verwenden, um einzelne Emoji-Zeichen darzustellen;
* sich in den Funktionen unterscheiden, die sie zur Unterstützung fortgeschrittenerer Anwendungen der Unicode-Standards bereitstellen, wie z. B. [Emoji-Modifikatoren](https://unicode.org/reports/tr51/#Emoji_Modifiers_Table), und andere in [Unicode Technical Standard #51: Unicode Emoji](https://unicode.org/reports/tr51/).

#### Der Hype um HarfBuzz

Wir haben auf die Notwendigkeit einer *Text-Shaping-Engine*: Software, die Unicode-Text als Eingabe nimmt, geschrieben mit einer bestimmten Schrift- und Sprachkombination, und diesen Text mithilfe einer festgelegten Schrift in eine Folge von Glyphen samt Positionierungsdaten formt, die zum Satz des ursprünglichen Eingabetextes verwendet werden können.

[HarfBuzz](https://harfbuzz.github.io/) ist eine solche Text-Shaping-Engine: Es ist [eine Open-Source-Codebibliothek](https://github.com/harfbuzz/harfbuzz) und das Ergebnis von mehr als einem Jahrzehnt Forschung und Entwicklung – und wird weiterhin aktiv entwickelt und als Teil vieler Softwareprodukte eingesetzt. HarfBuzz selbst führt kein „Typesetting“ durch, sondern stellt „Text-Shaping-Dienste“ für Software bereit, die sich dafür entscheidet, es zu integrieren, darunter XeTeX, LuaHBTeX, [Adobe Photoshop und Adobe InDesign](https://en.wikipedia.org/wiki/HarfBuzz).

Durch die Einbindung von HarfBuzz können TeX-Engines dessen fortgeschrittene Text-Shaping-Fähigkeiten nutzen, um sehr ausgefeilten mehrsprachigen Satz bereitzustellen, insbesondere für komplexe Schriften wie Arabisch, Hebräisch, Devanagari und viele andere. Beachte auch, dass HarfBuzz verwendet wird, um Unicode-Emoji-Textzeichen zu verarbeiten und zu shapen, was wir noch genauer untersuchen werden.

Die folgende Grafik fasst die Rolle zusammen, die HarfBuzz bei der Integration mit Software wie XeTeX oder LuaHBTeX beim Satz von Text in einer komplexen Schrift, etwa Arabisch, spielt:

![Ein Überblick über das Shaping arabischen Textes mit HarfBuzz](/files/8cdd946267d0bdb2c345b7f46de5d432abc9674f)

**HarfBuzz erkunden**

Jeder, der mehr über HarfBuzz und die OpenType-Shaping-Dienste erfahren möchte, die es XeTeX und LuaHBTeX bereitstellt, kann [eine Binärdistribution von HarfBuzz herunterladen](https://github.com/harfbuzz/harfbuzz/releases) , die die HarfBuzz-Bibliothek (für Programmierer) und Kommandozeilen-Dienstprogramme enthält `hb-view` und `hb-shape`.

**Beispiel: wie man hb-view verwendet**

Erstelle eine neue Datei in deinem bevorzugten UTF-8-fähigen Texteditor und kopiere die folgenden sechs Emoji-Zeichen 👋👋🏻👋🏼👋🏽👋🏾👋🏿 in diese Textdatei, speichere sie dann im UTF-8-Format in einer Datei namens, sagen wir, `emoji.txt`.

Beachte, dass dein Texteditor möglicherweise schwarz-weiße (Ersatz-)Versionen der Emoji anzeigt, weil er farbige Glyphen nicht darstellen kann (oder dafür nicht programmiert ist). Sobald diese 6 Emoji gespeichert sind, sollte die Datei `emoji.txt` UTF-8-Daten für die folgende Sequenz von Unicode-Emoji-Zeichen enthalten – wir haben Emoji-Modifier nur zur besseren Lesbarkeit mit Kommas getrennt *nur*:

* `1F44B` um 👋 zu erzeugen
* `1F44B`, `1F3FB` um 👋🏻 zu erzeugen
* `1F44B`, `1F3FC` um 👋🏼 zu erzeugen
* `1F44B`, `1F3FD` um 👋🏽 zu erzeugen
* `1F44B`, `1F3FE` um 👋🏾 zu erzeugen
* `1F44B`, `1F3FF` um 👋🏿 zu erzeugen

Es sollte insgesamt **11** Unicode-Zeichen geben, die jeweils 4 Bytes UTF-8-Daten erzeugen, sodass die resultierende `emoji.txt` Datei 44 Bytes lang sein sollte, ohne eventuelle Zeilenendmarkierungen, die am Ende der Zeile mit den Emoji verwendet werden.

Die `hb-view` -Dienstprogramm kann die Datei `emoji.txt`, zusammen mit einer geeigneten OpenType-Farbschrift deiner Wahl, wie z. B. `NotoColorEmoji.ttf`, verwenden, um eine SVG-Datei der von HarfBuzz geformten Ausgabe zu erzeugen. Das folgende Kommandozeilenbeispiel, das **in einer Zeile eingegeben werden muss** , erzeugt in deinem Terminal die SVG-Datei `emoji.svg`:

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

Bei erfolgreicher Ausführung kann die von `emoji.svg`erzeugte Datei `hb-view`mit Inkscape geöffnet werden und sollte ungefähr so aussehen:

![Hbvieemoji.png](/files/7caa9f863f2ed455688214c6ee9c22c18b1f9217)

`hb-view` kann verwendet werden, um HarfBuzz-Shaping für jede geeignete Unicode-Textdatei und OpenType-Schrift zu erkunden – es ist keineswegs auf die Verwendung mit Emoji beschränkt! Gib

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

ein, um die Fülle an Kommandozeilenoptionen dieses leistungsstarken und praktischen Dienstprogramms zu sehen. Viel Spaß beim Shaping!

## Text-Shaping und TeX-Engines

Hier werden wir die Text-Shaping-Fähigkeiten von XeTeX und der LuaTeX-Familie der TeX-Engines überprüfen.

### XeTeX

XeTeX wurde in den frühen 2000er-Jahren entwickelt und setzte mehrere Innovationen im TeX-basierten Satz um, vor allem *integrierte* Unterstützung für:

* das Lesen von Unicode-Text im UTF-8-Format;
* die Verwendung von OpenType-Schriften;
* Text-Shaping für mehrsprachigen Satz;
* OpenType-basierter mathematischer Satz.

XeTeXs Fähigkeit, komplexe Schriftsysteme einfach und bequem zu setzen, ist seinen integrierten Text-Shaping-Fähigkeiten zu verdanken – ursprünglich basierend auf der inzwischen veralteten [ICU LayoutEngine](http://userguide.icu-project.org/layoutengine). Dank der Arbeit von Khaled Hosny stellte XeTeX auf HarfBuzz für Text-Shaping um, wie in einer Ankündigung vom [März 2013](https://tug.org/pipermail/xetex/2013-March/024118.html)festgehalten wurde. Für alle, die mehrsprachigen Text setzen möchten, wird XeTeX normalerweise als die TeX-Engine der Wahl genannt – aber inzwischen gibt es eine weitere Option, LuaHBTeX, die wir uns ansehen werden.

### LuaTeX und LuaHBTeX

Die Entwicklung von LuaTeX begann um 2005, folgte jedoch einer ganz anderen Designphilosophie als XeTeX, das neue Funktionen *direkt in* die XeTeX-Software integrierte. Im Gegensatz zu XeTeX entschieden sich die Entwickler von LuaTeX dafür, „...ein minimales Set an Werkzeugen und keine Lösungen bereitzustellen.“ (siehe [Referenzhandbuch für LuaTeX](https://www.pragma-ade.com/general/manuals/luatex.pdf)). Anstatt eine Reihe zusätzlicher Funktionen bereitzustellen, *die in* LuaTeX-basierte Engines eingebaut sind, werden die internen Mechanismen von LuaTeX-Engines geöffnet, sodass Entwickler und fortgeschrittene Anwender die integrierte Skriptsprache Lua nutzen können, um ihre eigenen Lösungen zu bauen.

Zum Beispiel kann die LuaTeX-Engine im Gegensatz zu XeTeX nicht *direktes* OpenType-Schriften verwenden; stattdessen müssen OpenType-Schriften über in Lua-Code geschriebene Schriftladefunktionen geladen und „zur Verwendung vorbereitet“ werden. Diese Schriftladefunktionen werden als *Callback-* Funktionen bezeichnet: Lua-Code, den LuaTeX aufruft („ausführt“), wenn eine Schrift geladen werden soll.

Außerdem bietet die LuaTeX-Engine keine *integrierte* Text-Shaping-Fähigkeiten – auch diese müssen durch externen Code bereitgestellt werden, den die LuaTeX-Engine aufrufen kann, um ihr Text-Shaping-Dienste bereitzustellen. Auch das steht im Gegensatz zur XeTeX-Engine, die Text-Shaping-Fähigkeiten in die Kernsoftware integriert hatte.

#### luaotfload: unverzichtbar für die Verwendung von OpenType-Schriften in LuaTeX/LuaHBTeX

LuaTeXs Callback-Mechanismus zum Laden von Schriften bietet ein großes Maß an Flexibilität, allerdings „auf Kosten“ zusätzlicher Programmierung. Glücklicherweise hat die TeX-Community für LuaLaTeX-Anwender ein Paket namens `luaotfload`, entwickelt, das Teil der [jährlichen TeX-Live-Version](https://www.tug.org/texlive/) ist und natürlich auch Overleaf-Nutzern zur Verfügung steht.

`luaotfload` ist [auf CTAN verfügbar ist](https://ctan.org/pkg/luaotfload?lang=en) und hat ein [Entwicklungs-Repository auf GitHub](https://github.com/latex3/luaotfload) , wo du die neuesten Entwicklungen verfolgen und [neue Releases](https://github.com/latex3/luaotfload/releases).

`luaotfload` direkt in ein LaTeX-Dokumentpräambel über

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

Beachten Sie, dass `luaotfload` ist der Name eines LaTeX- *Paket*, was bedeutet, dass es den Dateinamen `luaotfload.sty`hat. Wenn du `luaotfload` mit Plain TeX verwenden wolltest, kannst du das tun, indem du die Zeile

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

in dein Plain-TeX-Dokument einfügst.

Normalerweise müssen sich Anwender von LuaLaTeX – also diejenigen, die LaTeX mit LuaTeX/LuaHBTeX setzen – nicht direkt mit `luaotfload` weil der [`fontspec` Paket](https://ctan.org/pkg/fontspec) befasst, wird das `luaotfload` -Paket für dich laden und viele Details auf niedriger Ebene über benutzerseitige Befehle handhaben, die von `fontspec` Pakets erkunden.

### LuaHBTeX: neue Optionen für Text-Shaping

`luaotfload` ist eine ausgereifte und leistungsstarke Lua-Bibliothek, die LuaTeXs Umgang mit OpenType-Schriften bereitstellt – zusammen mit der Bereitstellung von Text-Shaping-Diensten für eine Reihe von Sprachen und Schriftsystemen. Ursprünglich wurden die Text-Shaping-Funktionen von `luaotfload` in reinem Lua-Code implementiert, aber die Veröffentlichung von TeX Live 2020 brachte eine weitere Mainstream-Option für Text-Shaping – eine neue LuaTeX-basierte Engine namens LuaHBTeX.

Das „HB“ in LuaHBTeX steht für HarfBuzz – im Wesentlichen ist LuaHBTeX die ursprüngliche LuaTeX-Engine *plus* eine integrierte HarfBuzz-Text-Shaping-Engine. Entsprechend der Designphilosophie von LuaTeX führt die Verfügbarkeit von HarfBuzz nicht *automatisch* dazu, dass Text von LuaHBTeX geformt wird: HarfBuzz ist ein weiteres Werkzeug, das zum Aufbau von Text-Shaping-Lösungen verwendet werden kann.

LuaHBTeXs Integration von HarfBuzz ist [per Lua-Code programmierbar](#introduction-to-the-luahbtex-harfbuzz-api), was es `luaotfload`Entwicklern ermöglicht hat, HarfBuzz-basierte Text-Shaping-Lösungen hinzuzufügen. Folglich wurde [ab Version 3.1, veröffentlicht am 5. November 2019](https://github.com/latex3/luaotfload/releases/tag/v3.1), `luaotfload` erweitert, um HarfBuzz zu nutzen – wodurch HarfBuzzs Text-Shaping-Fähigkeiten für den normalen Anwender leicht zugänglich werden.

Leser, die an den technischen Details der HarfBuzz-Integration mit LuaTeX interessiert sind, können dieses [Papier von Khaled Hosny](https://www.tug.org/TUGboat/tb40-1/tb124hosny-harfbuzz.pdf).

### luaotfload: zwei Optionen für Text-Shaping (wann sollte man HarfBuzz verwenden?)

LuaLaTeX-Anwender haben jetzt zwei Optionen für Text-Shaping:

* `luaotfload`die ursprüngliche (knotenbasierte) Text-Shaping-Implementierung von
* `luaotfload`, die rein in Lua geschrieben ist;

`luaotfload` HarfBuzz-basiertes Shaping von`modus`Parameter – wobei die meisten Benutzer stattdessen die entsprechende `fontspec` “`Renderer`-Option verwenden werden, anstatt direkt die Funktionen niedrigerer Ebene von `luaotfload`.

Jede von `luaotfload`Text-Shaping-Lösungen hat ihre Stärken und (derzeitigen) Schwächen, aber welche solltest du verwenden, und wann? Hier sind einige Punkte, die zu berücksichtigen sind:

* `luaotfload`Die native knotenbasierte Verarbeitung von
* kann speicherintensiv sein, insbesondere bei großen CJK-OpenType-Schriften. Die Verwendung von HarfBuzz für das Shaping von CJK-Text kann Geschwindigkeitsverbesserungen und geringeren Speicherverbrauch bringen. `luaotfload` Handbuch).
* HarfBuzzs Integration in `luaotfload` ist noch relativ neu und wird weiterentwickelt. Zum Zeitpunkt der Abfassung dieses Textes (Juli 2021) ist es ratsam, für die Hauptschrift deines Dokuments das eingebaute Shaping von luaotfload zu verwenden (Einstellung `mode=node`), insbesondere wenn dein Dokument die lateinische Schrift verwendet. Siehe dieses [GitHub-Issue](https://github.com/latex3/luaotfload/issues/175#issue-801120377), das die Probleme und Diskussionen zusammenfasst. Wenn du experimentieren möchtest, kannst du `luaotfload` verwenden, um eine Schriftdatei zu laden und zwei LaTeX-Schriften zu erstellen: eine, die HarfBuzz-basiertes Shaping verwendet, und die andere Lua-basiertes Shaping. Overleaf hat ein [Beispielprojekt](#sample-project-arabic-shaping), das dies demonstriert.
* Verwende HarfBuzz nicht für mathematische Schriften. Wie Entwickler auf tex.stackexchange diskutiert haben, ist HarfBuzz [nicht dafür ausgelegt, Schriften für den mathematischen Satz zu verarbeiten](https://tex.stackexchange.com/questions/544881/does-luahbtex-with-harfbuzz-renderer-completely-supports-math-formating) verwende es also nicht für diesen Zweck.

**Beispielprojekt: arabisches Shaping**

Hier ist ein Overleaf-Projekt, das mehrere hochwertige arabische Schriftarten verwendet, um `luaotfload`knotenbasierte Text-Shaping-Dienste von`mode=node`mit denen von HarfBuzz (`mode=harf`):

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

Dieses Projekt enthält eine Ausgabe, die im folgenden Bild gezeigt wird:

![Arabisch setzen](/files/34b800ab8af6ced6e22e9b99d65af95ff7d2e192)

### Den „Renderer“ in fontspec wählen

Wie in seiner [Dokumentation](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf), `fontspec` „...ermöglicht es Nutzern von XeTeX oder LuaTeX, OpenType-Schriften in einem LaTeX-Dokument zu laden“. Wenn du die LuaTeX- oder LuaHBTeX-Engines verwendest, `fontspec` befasst, wird das `luaotfload` Bibliothek für dich und stellt darüber hinaus eine Reihe praktischer benutzerseitiger Befehle bereit, die die Notwendigkeit verringern, sich mit `luaotfload`-Funktionalität auf niedriger Ebene zu befassen.

Wie wählst du also zwischen HarfBuzz-Shaping und dem eingebauten Shaping von `luaotfload`? Die Antwort findet sich im ausgezeichneten [`fontspec` Dokumentation](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf), insbesondere in Teil VI: LuaTeX-spezifische Schriftfunktionen. `fontspec` stellt eine Einstellung namens `Renderer` bereit, die gesetzt werden kann, wenn die Schrift über `fontspec`. `Renderer` definiert wird. Sie steuert die Verarbeitung der Schrift auf niedriger Ebene. Die beiden interessanten Optionen sind

* `Renderer = Node`: der Standard-„Modus“ für den Satz von OpenType-Schriften – dieser verwendet `luaotfload`Text-Shaping-Funktionen, die rein in Lua implementiert sind.
* `Renderer = Harfbuzz`: dieser „Modus“ definiert/lädt die Schrift zur Verwendung mit der HarfBuzz-Text-Shaping-Engine. `luaotfload` verwendet LuaHBTeXs API, um Funktionen in HarfBuzz aufzurufen.

Weitere Informationen findest du in den [`fontspec` Dokumentation](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf).

## TeX-Engines, HarfBuzz und farbigen Emoji

Obwohl XeTeX und LuaHBTeX beide HarfBuzz integrieren, bieten sie unterschiedliche Unterstützungsgrade für einige von HarfBuzzs fortgeschritteneren Funktionen – vor allem für das Laden und die Verwendung von OpenType-Farbschriften.

### XeTeX und OpenType-Farbschriften

Wie erwähnt, gibt es zwei Kategorien von OpenType-Farbschriften, basierend auf dem Datenformat, das zur Speicherung der Schriftglyphen verwendet wird: vektorbasiert und rasterbasiert.

#### XeTeX und rasterbasierte OpenType-Farbschriften

XeTeX kann rasterbasierte OpenType-Farbfonts nicht laden – wie etwa Googles [Noto Color Emoji](https://www.google.com/get/noto/help/emoji/) mit TeX Live 2020 ausgeliefert. Wenn Sie beispielsweise versuchen, Noto Color Emoji (NotoColorEmoji.ttf) zu laden, schlägt XeLaTeX mit einer möglicherweise irreführenden Fehlermeldung fehl, die behauptet, dass Noto Color Emoji „nicht gefunden werden kann“. Der folgende LaTeX-Code, gesetzt mit XeLaTeX, *funktioniert nicht*:

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

[Öffnen Sie diesen XeLaTeX-Code in Overleaf (er ***nicht*** funktioniert).](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)

Es schlägt mit dem Fehler fehl:

```
! Package fontspec Fehler: Die Schriftart "NotoColorEmoji" kann nicht gefunden werden.
```

Ebenso schlägt ein einfaches Plain-TeX-Beispiel, das von XeTeX verarbeitet wird, fehl

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

[Öffnen Sie dieses Plain-TeX-(XeTeX)-Beispiel in Overleaf (es ***nicht*** funktioniert).](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)

Das Plain-TeX-Beispiel meldet eine ähnliche, aber andere Fehlermeldung:

```
! Font \emojifont=[NotoColorEmoji.ttf] at 12.0pt nicht ladbar: Metric (TFM) fil
e oder installierte Schriftart nicht gefunden.
l.1 \font\emojifont="[NotoColorEmoji.ttf]" at 12pt

Ich konnte die Größendaten für diese Schriftart nicht lesen,
daher werde ich die Schriftartangabe ignorieren.
[Experten können TFM-Dateien mit TFtoPL/PLtoTF reparieren.]
Sie könnten versuchen, eine andere Schriftartangabe einzufügen;
z. B. tippen Sie `I\font<same font id>=<substitute font name>'.
```

**Einfaches LuaHBTeX-Beispiel**

Zum Vergleich hier ein minimales Plain-TeX-Beispiel, das mit LuaHBTeX kompiliert wurde

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

[Öffnen Sie dieses Plain-TeX-(LuaHBTeX)-Beispiel in Overleaf (es wird erfolgreich kompiliert).](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)

#### Die eigentliche Ursache für das Versagen von XeTeX

Die von XeTeX ausgegebenen Fehlermeldungen verschleiern teilweise die eigentliche Ursache des Problems: OpenType-Farbfonts, insbesondere rasterbasierte Varianten, werden *nicht* von XeTeX unterstützt. In Wirklichkeit kann XeTeX (Kpathsea) *finden* die Schriftart Noto Color Emoji, aber XeTeX kann sie nicht vollständig *laden* und kann die internen Schriftart-Datentabellen, die für die Verwendung dieser Schriftart zum Satz benötigt werden, nicht initialisieren. Intern versucht XeTeX *beginnt* den Ladevorgang der Schriftart und prüft sie auf „Skalierbarkeit“ (unter Verwendung von FreeTypes „Definition“ von „Skalierbarkeit“), aber dieser Test schlägt fehl, und XeTeX gibt eine standardmäßige, durchaus irreführende Fehlermeldung der TeX-Engine aus.

**Technischer Hinweis**

Die Verarbeitung von NotoColorEmoji.ttf durch XeTeX wurde untersucht, indem eine Debug-Version des XeTeX-Programms kompiliert wurde. In der Eclipse-IDE wurde ein Haltepunkt für die XeTeX-Funktion gesetzt `creatFontFromFile(filename, index, pointsize)`und anschließend wurde der Code schrittweise durchlaufen, um die weitere Verarbeitung zu beobachten.

#### XeTeX und vektorbasierten OpenType-Farbfonts

XeTeX kann *laden* vektorbasierte OpenType-Farbfonts verwenden, erzeugt jedoch keine farbigen Emojis im resultierenden PDF – falls XeTeX überhaupt ein PDF erzeugt. Anders als LuaTeX, LuaHBTeX und pdfTeX gibt XeTeX keine *direktes* gesetzten Dokumente im PDF-Format aus. Stattdessen erzeugt XeTeX ein Zwischen- `.xdv` (er**x**weitert **dv**i) Dateiformat, das von einem Hilfsprogramm namens `xdvipdfmx`. Zum Zeitpunkt der Abfassung, `xdvipdfmx` ist nicht in der Lage, die passenden farbigen Emoji-Glyphpdaten in das PDF einzubetten, sodass Sie im besten Fall monochrome Emojis – das „Fallback“-Ergebnis – im PDF sehen, oder möglicherweise gar nichts, je nach verwendeter Schriftart.

Hier ist ein XeLaTeX-Beispiel, das die OpenType-Farbfont [TwemojiMozilla.ttf](https://ctan.org/tex-archive/fonts/twemoji-colr), verfügbar in TeX Live. TwemojiMozilla.ttf verwendet Microsofts COLR/CPAL-Vektorformat zum Speichern farbiger Glyphen und wird mit TeX Live 2020 ausgeliefert. In diesem Beispiel kann XeTeX die Schriftart laden und ein `.xdv` und eine PDF-Datei erzeugen, aber das Emoji-Glyph ist im gesetzten PDF nicht vorhanden:

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

[Öffnen Sie diesen XeLaTeX-Code in Overleaf (er FUNKTIONIERT NICHT).](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)

Im Gegensatz dazu funktioniert der obige Code mit LuaLaTeX, wenn Sie definieren `\emojifont` mit dem `fontspec` Einstellung `[Renderer=HarfBuzz]`:

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

[Öffnen Sie diesen LuaLaTeX-Code in Overleaf (er funktioniert).](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 und OpenType-Farbfonts

Durch seine integrierte HarfBuzz-Formungs-Engine und die `luaoftload` Bibliothek unterstützt LuaHBTeX alle vier Varianten von OpenType-Farbfonts. Nutzer von LuaLaTeX können die Unicode-basierte Verarbeitung von Text mit Emoji-Zeichen voll ausnutzen oder ihre Dokumente einfach mit sehr farbigem Text mithilfe von OpenType-Farbfonts verschönern.

Wie bereits erwähnt, lassen sich die vier Varianten von OpenType-Farbfonts in zwei Gruppen einteilen:

* diejenigen, die Glyphen in Rasterbildformaten wie PNG enthalten;
* andere, die vektorbasierte Formate von SVG oder Microsofts COLR/CPAL-Mechanismus verwenden.

Vektorbasierte Glyphenformate haben den Vorteil der Skalierbarkeit: Sie erzeugen scharfe Glyphengrafiken in jeder Punktgröße.

**Verwendung von Microsoft-COLR/CPAL-Farbfonts mit LuaHBTeX**

Wenn Sie für Ihre OpenType-Farb-Emoji-Fonts ein Vektorformat verwenden möchten, sehen Sie sich die Schriftart [TwemojiMozilla.ttf](https://ctan.org/tex-archive/fonts/twemoji-colr?lang=en), die auf Microsofts COLR/CPAL-Format basiert. TwemojiMozilla.ttf ist in TeX Live enthalten, aber Sie können die neueste Version von dessen [GitHub-Repository](https://github.com/mozilla/twemoji-colr/releases) herunterladen und in Ihr Overleaf-Projekt hochladen.

Hier ist ein kleines, `fontspec`-basiertes Beispiel mit `Renderer=Harfbuzz`, das eine große (Vektor-)Emoji-Ente setzt:

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

[Öffnen Sie dieses LuaLaTeX-Beispiel, um eine Vektor-Ente zu setzen.](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)

Hier ist die (Vektor-)Ente, die vom obigen Beispiel erzeugt wurde:

![](/files/dec5a7b8f06aad0ed146262e882ad3f37e97a1cb)

#### Verwendung von SVG-basierten OpenType-Farbfonts mit LuaHBTeX

Zum Zeitpunkt der Aktualisierung dieses Artikels (Juli 2023) gibt es wenig formale Dokumentation zur Verwendung von SVG-OpenType-Farbfonts mit LuaLaTeX. Einige [in Online-Diskussionen gemachte Kommentare](https://github.com/latex3/luaotfload/issues/96) empfehlen die Verwendung von `fontspec`s `RawFeature`, wie im Pseudocode unten gezeigt. Ersetzen Sie `*Ihr SVG-Schriftdateiname hier*` durch den Namen einer SVG-basierten Schriftdatei, auf die Ihr LaTeX-Code zugreifen kann:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emoji[RawFeature={+svg},SizeFeatures={Size=20}]{Ihr SVG-Schriftdateiname hier}
\emoji Ihr Emoji hier...
\end{document}
```

Wenn Sie weglassen `fontspec` und laden `luaotfload` direkt, müssen Sie möglicherweise eine Schriftart auf folgende Weise deklarieren und angeben – unsere Experimente deuten darauf hin, dass Sie das `mode=harf` Option für diese Funktion weglassen müssen:

```latex
\font\emoji=[Ihr SVG-Schriftdateiname hier]:+svg;
```

**Einige Warnhinweise**

Leser, die SVG-OpenType-Farbfonts verwenden möchten, sollten beachten:

* SVG-OpenType-Fonts mit einer großen Anzahl von Glyphen können [für LuaLaTeX rechenintensiv sein](#processing-svg-glyph-data) in der Verarbeitung, was möglicherweise zu [Overleaf-Timeouts](/latex/de/wissensdatenbank/038-fixing-and-preventing-compile-timeouts.md).
* Die Unterstützung von LuaLaTeX für diese Fonts könnte [als experimentell angesehen werden](https://github.com/latex3/luaotfload/issues/96#issuecomment-530317399): die Ergebnisse können je nach von Ihrem Projekt verwendeter TeX-Live-Version variieren; daher ist es ratsam, zu experimentieren und vorsichtig vorzugehen.

**Verarbeitung von SVG-Glyphendaten**

SVG ermöglicht es Designern, komplexe und farbenfrohe Gestaltungen zu erstellen, die die Glyphen einer Schriftart darstellen – vorbehaltlich einiger SVG-Einschränkungen [die in der OpenType-Spezifikation dokumentiert sind](https://docs.microsoft.com/en-us/typography/opentype/spec/svg). Allerdings können TeX-Engines, einschließlich LuaHBTeX, SVG-Dateien oder -Daten – etwa die SVG-Daten, mit denen Glyphenformen innerhalb von SVG-OpenType-Farbfonts beschrieben werden – nicht direkt importieren (verwenden). Die SVG-Daten einer Glyphe müssen in PDF-Format konvertiert werden, weil LuaHBTeX diese zum Satz der Glyphe und zur Erstellung des endgültigen PDF-Dokuments verwenden kann. Diese SVG-zu-PDF-Konvertierung wird von Lua-Code innerhalb von `luaoftload`: Die SVG-Daten jeder Glyphe werden aus der Schriftdatei extrahiert und in einer temporären `.svg` Datei gespeichert und mithilfe von Inkscape über die Befehlszeile in PDF konvertiert. Das Extrahieren der SVG-Daten und die Konvertierung in PDF verursacht einen gewissen Verarbeitungsaufwand, was potenziell lange Dokumentenkompilierungszeiten zur Folge hat – insbesondere bei Dokumenten, die große SVG-Fonts mit Tausenden von Emoji-Glyphen verwenden.

#### Rasterbasierte OpenType-Farbfonts

**Verwendung von Googles CBDT/CBLC-OpenType-Farbfontformat mit LuaHBTeX**

[Noto Color Emoji](https://fonts.google.com/noto/specimen/Noto+Color+Emoji) ist ein OpenType-Farbfont, der in TeX Live enthalten ist und sich daher leicht in einem Overleaf-Projekt verwenden lässt. Da Noto Color Emoji PNG-Grafiken zur Darstellung von Emoji-Glyphen verwendet, können wir ihn verwenden, um eine große (Raster-)Enten-Emoji zu setzen – wie das folgende Beispiel zeigt. Beachten Sie erneut, dass die `fontspec` Schriftartdeklaration (`\emojifont`) verwendet `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}
```

[Öffnen Sie dieses LuaLaTeX-Beispiel, um eine Raster-Ente zu setzen.](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)

Hier ist die Raster-Ente, die vom obigen Beispiel erzeugt wurde:

![Ein von LaTeX gesetztes Raster-Enten-Emoji](/files/dc4deb1d32b6c7eca35e0d344c8d2c1acfe918e2)

Wenn Sie versuchen, `NotoColorEmoji.ttf` aber `[Renderer=Harfbuzz]` aus dem `fontspec` die Deklaration jedoch weglassen, schlägt LuaHBTeX fehl und gibt eine Fehlermeldung aus, wenn es versucht, die PDF-Datei zu schreiben:

```latex
! Fehler:  (Datei /usr/local/texlive/2020/texmf-dist/fonts/truetype/google/noto-em
oji/NotoColorEmoji.ttf) (ttf): loca-Tabelle nicht gefunden
```

Der Grund für diesen Fehler in der [loca-Tabelle](https://docs.microsoft.com/en-us/typography/opentype/spec/loca) ist [auf GitHub erklärt](https://github.com/latex3/luaotfload/issues/98#issuecomment-531610153).

**Verwendung von Apples sbix-OpenType-Farbfontformat mit LuaHBTeX**

Offline-Tests zeigen, dass LuaHBTeX die `sbix` Variante von OpenType-Farbfonts unterstützt, aber zum Zeitpunkt der Abfassung dieses Artikels konnten wir keine passend lizenzierte `sbix`-variante eines farbigen Emoji-Fonts finden, um das Setzen einer Ente zu demonstrieren. Bitte [uns zu kontaktieren](https://www.overleaf.com/contact) lassen Sie es uns wissen, falls Sie eine kennen, und wir aktualisieren diesen Artikel quakend schnell, um sie zu verwenden.

## Einführung in die LuaHBTeX-HarfBuzz-API

![Db.gif](/files/0ecd0e66d1d06793edf40e0a0e02cc5f6f55d56d) ![Db.gif](/files/0ecd0e66d1d06793edf40e0a0e02cc5f6f55d56d)

Die Textformung, insbesondere für Sprachen mit komplexen Schriftsystemen und sogar für Emojis, ist eine von Natur aus schwierige Aufgabe, daher ist es nicht überraschend, dass HarfBuzz eine ausgefeilte Bibliothek ist, mit der zu arbeiten knifflig sein kann – es sei denn, Sie sind bereits mit Textformungsoperationen vertraut. In diesem abschließenden Abschnitt betrachten wir die Integration von HarfBuzz in LuaHBTeX und wie man über Lua-Code innerhalb von darauf zugreift `\directlua`.

Unser Beispiel verwendet recht einfachen Code, um die LuaHBTeX-HarfBuzz-API zu demonstrieren. Es ist etwas konstruiert, weder von Produktionsqualität noch sehr praktisch, da sein einziger Zweck darin besteht, einige Grundideen einzuführen. Wir haben den Lua-Code in zwei `\directlua` Abschnitte aufgeteilt: Der erste lädt die `luaharfbuzz` Bibliothek und erstellt einige globale Variablen, die wir in unserem zweiten `\directlua` Abschnitt verwenden werden, in dem wir ein Makro namens `\codestoemoji`.

Es erscheint angemessen, Knuths Verwendung von doppelten Gefahrenzeichen zu übernehmen (Bild mit freundlicher Genehmigung von [dieser Website](http://www.truetex.com/db.htm)) da der Inhalt etwas niedrigschwellig ist und „unter die Haube schaut“ – obwohl wir hoffen, dass er für den mutigeren Leser interessant sein könnte. LuaHBTeXs Integration von HarfBuzz stammt aus dem [luaharfbuzz-Projekt auf GitHub](https://github.com/ufyTeX/luaharfbuzz/wiki#projects-using-luaharfbuzz) wo Sie eine [Einführung in das Projekt](https://github.com/ufyTeX/luaharfbuzz/wiki) sowie eine [Auflistung der luaharfbuzz-API](http://ufytex.github.io/luaharfbuzz/).

### Erste Schritte: die luaharfbuzz-Bibliothek laden und eine Schriftart finden

Um die HarfBuzz-API von LuaHBTeX zu verwenden, müssen wir zunächst die Bibliothek (das Modul) laden, genannt `luaharfbuzz`, die in LuaHBTeX eingebaut ist, und die zurückgegebene Tabelle in einer (globalen) Variablen speichern, die wir nennen werden `hblib`:

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

Als Nächstes müssen wir eine geeignete Emoji-OpenType-Farbfont finden: Wir verwenden Noto Color Emoji – beachten Sie, dass wir sehr faul sind und keine Fehlerprüfung durchführen, falls wir sie nicht finden! Um sie zu finden, verwenden wir die `kpse` (Kpathsea)-Bibliothek, die ebenfalls Teil von LuaTeX/LuaHBTeX ist:

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

Jetzt, da wir über unsere Variable Zugriff auf die HarfBuzz-Bibliothek haben `hblib`, und den Pfad zu einer geeigneten Schriftart (`pathtofontfile`), können wir beginnen, `hblib`. `\directlua` Code-Abschnitt, in dem wir unser Makro definieren.

```latex
% Erstellen Sie ein HarfBuzz-Face und eine HarfBuzz-Schriftart aus Noto Color Emoji
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)
```

#### HarfBuzz-Schriftart und HarfBuzz-Face: Was sind das?

Ein [HarfBuzz-Face-Objekt](https://harfbuzz.github.io/fonts-and-faces.html) repräsentiert eine Schriftart, die aus einer Schriftdatei geladen wurde, jedoch ohne festgelegte spezifische Parameter (wie etwa die Größe). Ein [HarfBuzz-Schriftobjekt](https://harfbuzz.github.io/fonts-and-faces.html) repräsentiert eine *konkrete Instanz* eines HarfBuzz-Faces; folglich können aus einem einzigen HarfBuzz-Face verschiedene HarfBuzz-Schriftobjekte abgeleitet werden: Jedes HarfBuzz-Schriftobjekt kann seine Eigenschaften, etwa die Größe, auf unterschiedliche Werte gesetzt bekommen. Ein HarfBuzz-Face ist eine abstraktere Ebene als eine HarfBuzz-Schriftart.

### Schriftglyphen verwenden, um PNG-Dateien zu erstellen

Der letzte Teil unseres ersten `\directlua` Abschnitts ist eine Funktion namens `writePNGglyph(hbfontobject, glyphID)` die wir verwenden, um zu demonstrieren, dass einige OpenType-Farbfonts, wie Noto Color Emoji, PNG-Grafiken verwenden, um die darin enthaltenen Emoji-Glyphen darzustellen.

Diese Funktion verwendet die HarfBuzz-API von LuaHBTeX, um PNG-Daten aus Glyphen zu extrahieren und diese Daten in eine `.png` Datei mit dem Namen `Graphics<glyphID>.png`. Der Name dieser `.png` Datei wird zurückgegeben zur Verwendung durch `\includegraphics` um PNG-Glyphenbilder in unser gesetztes PDF einzubetten.

Mit dem `writePNGglyph(hbfontobject, glyphID)` an seinem Platz ist, sieht unser erster `\directlua` Code-Abschnitt so aus:

```latex
\directlua{

% Laden Sie die luaharfbuzz-Bibliothek aus LuaHBTeX
hblib=require("luaharfbuzz")

% Suchen Sie die Noto-Color-Emoji-Schriftart auf dem Server von Overleaf
pathtofontfile=kpse.find_file("NotoColorEmoji.ttf","truetype fonts")

% Erstellen Sie ein HarfBuzz-Face und eine HarfBuzz-Schriftart aus Noto Color Emoji
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)

% Diese Funktion akzeptiert eine Schriftart und eine Glyphen-ID:
% sie extrahiert die PNG-Daten der Glyphen und schreibt
% sie in eine .png-Datei

function writePNGglyph(hbfontobject, glyphID)

    % Glyphen-PNG-Daten abrufen
    local pngblob=hbfontobject:ot_color_glyph_get_png(glyphID)
    local pngdata=pngblob:get_data()

    % Einen Dateinamen für unsere .png-Datei konstruieren
    local fname="Glyph"..glyphID..".png"

    % Die .png-Datei schreiben und den Dateinamen zurückgeben
    local output = assert(io.open(fname, "wb"))
    output:write(pngdata)
    output:close()

    % Den Dateinamen für \includegraphics zurückgeben
    return fname
end
}
```

### Zweiter \directlua-Abschnitt: das Makro \codestoemoji erstellen

Das Ziel ist es, ein Makro zu definieren `\codestoemoji` das wir mit einem Textstück aufrufen können, das Emoji-Zeichenkodierungen enthält, die HarfBuzz formen soll. Genauer gesagt verwenden wir `\Uchar<Zeichencode>` um jedes Emoji-Zeichen darzustellen; zum Beispiel:

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

In der Definition von passiert eine Menge `\codestoemoji` , was wir unten erklären werden, aber die Definition sieht so aus:

```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()
    % Die Glyphen-Tabelle, hbglyphs, ist 1-basiert
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Die Größe unserer importierten PNG-Bilder verringern
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
}}
```

#### Die Definition des Makros \codestoemoji verstehen

Die `\codestoemoji` Das Makro besteht größtenteils aus Lua-Code, der in `\directlua`enthalten ist, also wenn Sie mehr darüber wissen möchten, wie *wie* `\directlua` funktioniert, sehen Sie sich den Overleaf-Artikel [Verstehen `\directlua`](/latex/de/ausfuhrliche-artikel/09-an-introduction-to-luatex-part-2-understanding-directlua.md). Er erklärt, wie LuaTeX und LuaHBTeX `\directlua` verarbeiten, wenn TeX/LaTeX-Befehle im Lua-Code enthalten sind, und insbesondere die Notwendigkeit, `\noexpand` und `\unexpanded`.

**Umgang mit dem Makro-Parameter: "#1"**

Das Makro beginnt mit diesen drei Zeilen:

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

die die folgenden Aufgaben erfüllen:

* `local str="#1"`: dadurch wird aus dem vom Makro übergebenen Eingabetext ein Lua-String erstellt;
* `local hbbuffer = hblib.Buffer.new()`: hierbei wird die HarfBuzz-API verwendet, um einen Puffer zu erstellen, der den Text aufnimmt, den HarfBuzz formen soll;
* `hbbuffer:add_utf8(str)`: dadurch wird ein UTF-8-Format-String, der aus der Eingabe unseres Makros erzeugt wurde, in den HarfBuzz-Puffer eingefügt.

Die erste Codezeile

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

erscheint recht einfach, aber ihre Funktionsweise ist ziemlich komplex und lohnt eine etwas genauere Betrachtung.

Wenn wir die dritte Codezeile betrachten

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

sehen wir, dass sie unsere `str` Variable verwendet, um den HarfBuzz-Puffer mit einem in UTF-8 formatierten Unicode-String zu versorgen. Damit das funktioniert, muss die Variable `str` selbst Unicode-Text enthalten, der als UTF-8 formatiert ist; daher stellt sich die Frage: *wie* hat LuaHBTeX das Makroargument „umgewandelt“ `"#1"`, das enthält `\Uchar` Befehle, in die Lua-String-Variable `str` die UTF-8-Text für HarfBuzz enthält?

Wenn wir uns die beabsichtigte Verwendung des `\codestoemoji` Makros ansehen:

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

die Eingabe, etwa `\Uchar"1F3F4\Uchar"E0067\Uchar"E0062\Uchar"E0065...`, sieht überhaupt nicht aus wie eine Folge von Emoji-Zeichen, die in UTF-8 kodiert sind. Außerdem weiß HarfBuzz nichts von TeX-Befehlen. Irgendwie wird die rohe TeX-Eingabe, bestehend aus `\Uchar` Befehlen, in Unicode-Zeichen umgewandelt, die in UTF-8 kodiert sind und von HarfBuzz verwendet werden können, aber *wie*?

Die Antwort liegt im Verhalten des `\Uchar` Befehls: Der Versuch, aufzurufen `\codestoemoji` unter Verwendung von `\char` anstelle von `\Uchar` wird fehlschlagen, aber *warum*?

**\Uchar: Expansion in \directlua**

Wenn das `\codestoemoji` Makro aufgerufen wird, muss der `\directlua` Befehl, der in der Definition des Makros gespeichert ist, Lua-Code vorbereiten, der an den eingebauten Lua-Interpreter von LuaHBTeX gesendet wird. Teil dieses Codevorbereitungsprozesses ist die Expansion aller im ursprünglichen Lua-Code der Makrodefinition vorhandenen TeX/LaTeX-Befehle zusammen mit der Expansion aller vom Benutzer bereitgestellten Makroargumente. Dieser Expansionsprozess erzeugt eine Tokenliste, die anschließend wieder in Text umgewandelt wird und den Lua-Code für den Lua-Interpreter erzeugt. Der Einfachheit halber wiederholen wir ein Diagramm aus dem Overleaf-Artikel [Verstehen `\directlua`](/latex/de/ausfuhrliche-artikel/09-an-introduction-to-luatex-part-2-understanding-directlua.md):

![Die Funktionsweise von \directlua](/files/87a2116199e427cfed6442305bac43df8028c453)

Das Makro `\codestoemoji` soll mit `\Uchar` Befehlen aufgerufen werden und, [wie bereits früher im Artikel bemerkt](#the-key-difference-expansion), `\Uchar` ist ein expandierbarer Befehl, dessen Expansion ein Zeichentoken erzeugt. Innerhalb der Verarbeitungsabläufe von `\directlua`, expandiert LuaHBTeX jeden `\Uchar<Zeichencode>` Befehl dort, wo er *entfernt* jeweils `\Uchar<Zeichencode>` aus der Eingabe entfernt und *ersetzt* ihn mit dem entsprechenden Expansionswert: einem Zeichentoken, das `<Zeichencode>`.

In der letzten Verarbeitungsphase wird die anfängliche Tokenliste, die von `\directlua` erzeugt wurde, in *Text zurück* umgewandelt, sodass der für den Lua-Interpreter bestimmte Lua-Code entsteht (siehe Diagramm oben). Alle Zeichentoken, die durch die Expansion von `\Uchar` erzeugt werden, werden ebenfalls *wieder in Text umgewandelt*: diese Umwandlung von Zeichentoken in Text erzeugt die UTF-8-Darstellungen der ursprünglichen `<Zeichencode>` Werte.

In unserem Beispiel ist, sobald der Lua-Code erzeugt und für den Lua-Interpreter bereit ist, die Makroeingabe für "#1" in eine Folge von UTF-8-Text umgewandelt worden: die `str` Variable ist nun ein UTF-8-Textstring, der sicher zum HarfBuzz-Puffer hinzugefügt werden kann.

**Warum funktioniert \char nicht?**

Die kurze Antwort lautet: weil `\char` ist *nicht* ein erweiterbarer Befehl. Anders als `\Uchar` Befehle, `\char` Befehle *werden nicht entfernt* aus der Eingabe während `\directlua`der ersten Verarbeitung, um eine Tokenliste zu erzeugen, „durchlaufen“ sie diese und werden in die Tokenliste integriert, die von `\directlua`. Wenn zum Beispiel das Argument an `\codestoemoji` enthielt `\char"1F3F4` LuaHBTeX würde dies in eine Folge von Token umwandeln und sie als Teil der gesamten Tokenliste speichern, die gerade erzeugt wird.

In der nächsten Verarbeitungsstufe, beim Zurückwandeln der Token in Text, würde der resultierende Lua-Code die *wörtliche Zeichenkette* `\char"1F3F4` im Text enthalten, der zur Definition unserer Variable verwendet wird `str`. Wenn der Inhalt von `str` zum HarfBuzz-Puffer hinzugefügt wird, enthält er keine UTF-8-kodierte Sequenz, die das Emoji-Zeichen "1F3F4 darstellt; stattdessen würde er die wörtliche Zeichenkette enthalten `\char"1F3F4`, die HarfBuzz zu setzen versuchen wird und die für unsere Zwecke kein Emoji-Glyphe erzeugen würde. Übrigens würde die Zeichenkette `\char"1F3F4` würde ebenfalls Lua-Syntaxfehler erzeugen, sofern sie nicht als „long-bracket string“ erstellt wurde — siehe [Was sind Lua-Escape-Sequenzen](/latex/de/ausfuhrliche-artikel/09-an-introduction-to-luatex-part-2-understanding-directlua.md#what-are-e2809clua-escape-sequencese2809d3f) für Hintergrundinformationen zu diesem Problem.

Wenn wir versuchen, zu verwenden `\codestoemoji` durch eine `\char` Befehl, etwa so:

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

LuaHBTeX wird fehlschlagen und einen Syntaxfehler etwa so melden:

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

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

Der Lua-Interpreter ist auf ein Problem gestoßen, daher wird der
Rest dieses Lua-Blocks ignoriert.
```

#### Die HarfBuzz-Setzfunktion aufrufen

**Pufferparameter festlegen**

HarfBuzz benötigt manchmal zusätzliche Informationen über den Text, den es setzen soll. Diese Informationen können Sie bereitstellen, indem Sie Ihre `<buffer variable>` unter Verwendung von *Puffermethoden*, wie zum Beispiel:

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

Zum Beispiel müssen wir HarfBuzz mitteilen, dass die Richtung unseres Emoji-Texts von links nach rechts verläuft. Dazu verwenden wir die `set_direction()` Methode für unseren `<buffer variable>` (genannt `hbbuffer`) indem wir schreiben:

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

wobei `hblib.Direction.new("ltr")` erstellt ein „Richtungsobjekt“, das sich für die Übergabe an die HarfBuzz-Engine über Lua eignet.

**Setzung durchführen**

Nachdem der Puffer entsprechend initialisiert wurde, können wir HarfBuzz bitten, die eigentliche Setzung mit der Funktion `shape_full()`. In unserem Beispiel schreiben wir:

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

Die 3. und 4. Parameter der `shape_full()` Funktion müssen Lua-Tabellen sein — wir haben leere Tabellen „`{}`“ für beide Parameter verwendet. Die allgemeine Form von `shape_full()` ist:

```latex
shape_full(Harfbuzz font, Harfbuzz buffer, {font features}, {"shaper"}
```

* **`{"shaper"}`**: Muss normalerweise nicht gesetzt werden, aber die Optionen sind `{"ot"}` oder `{"graphite2"}`. Weitere Informationen zum Konzept eines „shapers“ finden Sie in [der HarfBuzz-Dokumentation](https://harfbuzz.github.io/shaping-and-shape-plans.html)—beachten Sie, dass dort das Low-Level-C-API dokumentiert ist, nicht die Lua-basierte `luaharfbuzz` Bindung (Implementierung).
* **`{font features}`**: Dies ist eine Tabelle, die die [OpenType-Features](https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist)—vom Schriftfont unterstützt— auflistet, die HarfBuzz während der Setzung anwenden soll.

Jede Schriftfunktion, die Sie verwenden möchten, muss mit einer `luaharfbuzz` Bibliotheksfunktion

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

wobei

* `library_instance` ist Ihre `luaharfbuzz` Bibliotheksinstanz-Variable (`hblib` in unserem Beispiel);
* `feature_string` verwendet eine [Syntax zur Definition von Merkmalen](https://github.com/ufytex/luaharfbuzz/wiki/Feature-Strings). Beispiele dafür sind `+smcp` zum Aktivieren von Kapitälchen oder `-kern` zum Deaktivieren des Kerning.

Zum Beispiel:

```latex
local dosmcp = hblib.Feature.new("+smcp")
local nokern = hblib.Feature.new("-kern")
% Verwenden Sie Ihre Schriftmerkmale so
local res = hblib.shape_full(hbfont, hbbuffer, {dosmcp,nokern},{})
```

#### Auf das Ergebnis zugreifen: die Glyphen abrufen

Und schließlich werden, wenn die Setzung erfolgreich ist, die gesetzten Glyphen in der Puffer-Variable zurückgegeben `hbbuffer` die wir zuvor im Code erstellt haben.

Wir greifen über die Puffermethode auf die Glyphen zu `get_glyphs()` und verwenden eine Schleife, um jedes einzelne Glyph zu erhalten. Beachten Sie, dass die Lua-Tabelle mit den Glyphen, `hbglyphs` in unserem Beispiel ab 1 indiziert ist, nicht ab 0.

Jede Glyphe *Glyphenkennung* (irreführenderweise genannt `codepoint`), und die HarfBuzz-Schrift (`hbfont`), wird an die `writePNGglyph()` Funktion übergeben, die mithilfe der Rasterbilddarstellung dieser Glyphe aus der Schrift eine PNG-Datei erstellt.

`writePNGglyph()` schreibt eine PNG-Datei und gibt den Namen der PNG-Datei zurück, der verwendet wird, um die (skalierte) PNG-Datei über `\includegraphics[scale=0.75]{<fname>}`. Beachten Sie, wie wir `\includegraphics` direkt innerhalb des Lua-Codes verwenden können.

```latex
if (res) then
    local hbglyphs=hbbuffer:get_glyphs()
    % Die Glyphen-Tabelle, hbglyphs, ist 1-basiert
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Die Größe unserer importierten PNG-Bilder verringern
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
```

### Der vollständige Code, den Sie in Overleaf öffnen können

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

% Laden Sie die luaharfbuzz-Bibliothek aus LuaHBTeX
hblib=require("luaharfbuzz")

% Suchen Sie die Schrift Noto Color Emoji auf dem Server von Overleaf
pathtofontfile=kpse.find_file("NotoColorEmoji.ttf","truetype fonts")

% Erstellen Sie ein HarfBuzz-Face und eine HarfBuzz-Schriftart aus Noto Color Emoji
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)

% Diese Funktion akzeptiert eine Schriftart und eine Glyphen-ID:
% es extrahiert die PNG-Daten der Glyphe und schreibt
% sie in eine .png-Datei

function writePNGglyph(hbfontobject, glyphID)

    % Glyphen-PNG-Daten abrufen
    local pngblob=hbfontobject:ot_color_glyph_get_png(glyphID)
    local pngdata=pngblob:get_data()

    % Einen Dateinamen für unsere .png-Datei konstruieren
    local fname="Glyph"..glyphID..".png"

    % Die .png-Datei schreiben und den Dateinamen zurückgeben
    local output = assert(io.open(fname, "wb"))
    output:write(pngdata)
    output:close()

    % Den Dateinamen für \includegraphics zurückgeben
    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()
    % Die Glyphen-Tabelle, hbglyphs, basiert auf 1.
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Die Größe unserer importierten PNG-Bilder verringern
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
}}

Eine Ente: \codestoemoji{\Uchar"1F986}

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

[Öffnen Sie dieses luaharfbuzz-API-Beispiel in Overleaf.](/latex/de/ausfuhrliche-artikel/10-an-overview-of-technologies-supporting-the-use-of-colour-emoji-fonts-in-latex.md)

Dieses Beispiel erzeugt die folgende Ausgabe:

![Harfbuzzexample.png](/files/63dcb04628d17b39457e98dd5448ddbfb48b153c)

## Bonusabschnitt: Spaß mit Emoji-Mathematik

Zum Abschluss mit einer leichten Note hat ein Mitglied des Overleaf-Teams die [`Emojis` LaTeX-Paket](https://ctan.org/pkg/emoji?lang=en) verwendet, um ein unterhaltsames Beispiel zu erstellen:

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

[Öffnen Sie dieses unterhaltsame Beispiel in 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)

Dieses Beispiel erzeugt die folgende Ausgabe:

![Emojimath2.png](/files/7c9ab8f17f7a2815fc1b9581734f3843bb0b8443)


---

# 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/de/ausfuhrliche-artikel/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.
