> 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/cs/clanky-do-hloubky/10-an-overview-of-technologies-supporting-the-use-of-colour-emoji-fonts-in-latex.md).

# Přehled technologií podporujících použití barevných emoji písem v LaTeXu

## Úvod

Tento článek poskytuje přehled různých [základních témat](#which-topics-do-we-cover) souvisejících s používáním barevných fontů OpenType pro sazbu barevných emoji v LaTeXu. Snažili jsme se poskytnout širokou škálu materiálů, která vyhoví širokému spektru zájmů a úrovní odbornosti. Aby byl článek přehledný, naše pojednání o některých tématech vynechává mnoho technických detailů, ale doufáme, že zde je dostatek materiálu, který vás nasměruje při vašem zkoumání sazby barevných emoji v LaTeXu.

**Aktualizace (červenec 2023)**: Tento článek byl poprvé publikován v srpnu 2021 a v červenci 2023 revidován za účelem aktualizace části o [Používání barevných fontů OpenType založených na SVG s LuaHBTeX](#using-svg-based-opentype-color-fonts-with-luahbtex).

### Která témata pokrýváme?

Tento článek pokrývá následující obecná témata:

* Unicode: standard, který kóduje emoji jako znaky a kodifikuje jejich očekávané chování v aplikacích pro zpracování textu a sazbu.
* Barevné fonty OpenType: specializované fonty, které poskytují barevné reprezentace znaků emoji zobrazených ve vašem dokumentu LaTeXu.
* Tvarování textu: představení klíčové součásti sazby jazyků se složitými písmy a emoji.
* HarfBuzz: součást LuaHBTeXu, která umožňuje pokročilou vícejazyčnou sazbu a použití barevných fontů OpenType pro sazbu emoji v LaTeXu.
* Různé enginy TeXu: zkoumání jejich podpory barevných fontů OpenType a výběr, který engine TeXu použít.
* API HarfBuzz v LuaHBTeXu: úvod do „kouzla“ stojícího za [tvarováním textu](#the-concept-of-text-shaping) v LuaHBTeXu.

### Tři způsoby sazby barevných emoji

Barevná emoji lze sázet v LaTeXu třemi hlavními metodami:

1. Použití standardních grafických nástrojů LaTeXu, jako jsou TikZ, MetaPost nebo Asymptote, k vykreslení emoji.
2. Vkládání emoji pomocí předpřipravených grafických souborů emoji uložených v externích souborech.
3. Považování emoji za text kódovaný v Unicode a použití [tvarováním textu](#the-concept-of-text-shaping) s [barevných fontů OpenType](#opentype-color-fonts) k jejich sazbě.

Praktické možnosti zahrnutí barevných emoji do dokumentu LaTeXu závisí na enginu TeXu použitém k překladu daného dokumentu: tj. zda používáte:

* pdfLaTeX: engine pdfTeX + LaTeX;
* XeLaTeX: engine XeTeX + LaTeX;
* LuaLaTeX: engine LuaHBTeX (od TeX Live 2020) + LaTeX.

Všechny tři tyto enginy TeXu mohou používat nástroje nebo balíčky LaTeXu k vykreslení emoji nebo použít `\includegraphics{...}` pro vložení emoji uložených v externích grafických souborech. Kreslení nebo import grafiky jsou ideální techniky pro sazbu emoji, když potřebujete řešení, které nezávisí na enginu TeXu použitém k překladu dokumentu LaTeXu.

Pokud však váš pracovní postup poskytuje flexibilitu zvolit konkrétní engine TeXu a dáváte přednost používání barevných fontů OpenType a zpracování textu založeného na Unicode, potřebujete nejnovější verzi LuaTeXu, nazývanou LuaHBTeX. Od TeX Live 2020 se LuaHBTeX používá k překladu dokumentů LaTeXu založených na formátu LuaLaTeX.

## Pozadí o Unicode a emoji znacích

### Kódování znaků

Počítače ukládají, přenášejí a zpracovávají text pomocí posloupnosti číselných (celočíselných) hodnot, které představují jednotlivé *znaky*. Spolehlivé zpracování textu vyžaduje, aby se výrobci a příjemci textu shodli na tom, které celočíselné hodnoty mají být použity k reprezentaci jednotlivých znaků v toku textu. Jinými slovy, jaké je *znaku* *kódování?* Kódování je soubor dohodnutých celočíselných hodnot přiřazených k reprezentaci určité sady znaků: každý znak je reprezentován celočíselnou hodnotou v používaném kódování.

### Přichází Unicode

Historicky, v éře 8bitového textu, bylo používáno mnoho různých kódování znaků, což vždy vyvolávalo hrozbu *nesouladů kódování*: výrobci a příjemci textu si mylně předpokládají různá kódování, což vede k chybám při zpracování textu. Každý, kdo několik let pracoval s TeXem/LaTeXem, se pravděpodobně setkal s nesoulady kódování mezi vstupním textem a fonty použitými pro sazbu dokumentu. Pokud jsou fonty dokumentu nakonfigurovány tak, aby používaly jiné kódování než text, pravděpodobně to vede k chybějícím nebo chybným znakům ve vysázeném PDF.

Tyto historické problémy s kódováním lze vyřešit pomocí mezinárodního standardu, který kóduje všechny znaky světa: Unicode. Standard Unicode není statický, ale je pravidelně aktualizován, aby do svého schématu kódování zahrnoval další znaky a písma (systémy zápisu). Existuje [formální proces posuzování návrhů nových znaků](http://www.unicode.org/pending/proposals.html) s konkrétním [schématem pro nové znaky emoji](https://www.unicode.org/emoji/proposals.html).

### Kolik znaků Unicode?

Unicode kóduje teoretické maximum 1 114 112 znaků. Každá z 1 114 112 celočíselných hodnot se nazývá *kódový bod*: celočíselná hodnota přiřazená k identifikaci každého znaku. Z různých technických důvodů však lze skutečným znakům přiřadit pouze [1 112 064 kódových bodů](https://en.wikipedia.org/wiki/Unicode#Architecture_and_terminology) : 2048 kódových bodů nelze přiřadit a jejich použití v textu vyhovujícím Unicode je zakázáno.

V době psaní tohoto textu (první verze tohoto článku) verze 13 standardu Unicode přidělila celkem 143 859 kódových bodů skutečným znakům, včetně [3304 znaků nyní kódovaných jako emoji](https://www.unicode.org/L2/L2020/20114r-family-emoji-explor.pdf) (viz stranu 2 tohoto dokumentu). Růst počtu znaků kódovaných v Unicode je dobře zdokumentován v článku [Kolik je znaků Unicode?](https://www.babelstone.co.uk/Unicode/HowMany.html) a v [položce na Wikipedii](https://en.wikipedia.org/wiki/Unicode#Versions).

### Roviny Unicode

Celý soubor 1 114 112 kódových bodů Unicode je rozdělen do 17 takzvaných rovin: rovina 0 až rovina 16, z nichž každá obsahuje 65 536 hodnot kódových bodů, což dává celkem $$17\times2^{16} = 1,114,112$$ znaků. Rovina 0, nazývaná [Základní vícejazyčná rovina](https://en.wikipedia.org/wiki/Plane_\(Unicode\)#Basic_Multilingual_Plane), kóduje nejčastěji používané znaky. Roviny 1–16 se nazývají [Doplňkové roviny](http://unicode.org/glossary/#supplementary_planes).

### Vzestup emoji

Nové znaky vznikají s měnícími se způsoby lidské komunikace a mobilní telefonní technologie dala vzniknout jedné takové sadě znaků: emoji, která se vyvinula v Japonsku na konci 90. let 20. století. Není překvapivé, že [FAQ Unicode o emoji](https://unicode.org/faq/emoji_dingbats.html) uvádí

> „Slovo emoji pochází z japonštiny [絵](http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=%E7%B5%B5) (e ≅ obrázek) + [文字](http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=%E6%96%87) (moji ≅ psaný znak).“

Čtenáři, které zajímá pozadí a historický vývoj emoji, mohou najít zajímavé informace v tomto [Úvod do Unicode](https://unicode.org/reports/tr51/#Introduction) nebo v článku [Také souhlasím s tím emoji: standardy, struktury a společenská produkce emoji](https://firstmonday.org/ojs/index.php/fm/article/view/9381).

Teprve v roce 2010, s vydáním [verze 6.0 standardu Unicode](https://www.unicode.org/versions/Unicode6.0.0/), byla mnohá emoji formálně uznána jako *znaky* sama o sobě. Unicode 13.0 kódoval [3304 znaků jako emoji](https://www.unicode.org/L2/L2020/20114r-family-emoji-explor.pdf) (viz stranu 2 tohoto dokumentu), přičemž Unicode 13.1 uvádí [uvádí 3521 emoji](https://unicode.org/emoji/charts/emoji-counts.html).

### Emoji žijí ve vyšší rovině

Unicode přiřadil mnoho znaků emoji kódovým bodům mimo Základní vícejazyčnou rovinu (BMP), kódovaným [v rovině 1](https://en.wikibooks.org/wiki/Unicode/Character_reference/1F000-1FFFF) s kódovými body v rozsahu 1F000–1FFFF — což má důležitý důsledek pro každého, kdo chce *kopírovat a vkládat* znaky emoji do editorů Overleafu (Code Editor nebo Visual Editor). Textové editory Overleafu umí pracovat pouze se znaky v rámci Základní vícejazyčné roviny, i když doufáme, že budoucí aktualizace přinesou podporu pro znaky mimo BMP. Upozorňujeme, že toto omezení se týká pouze znaků mimo BMP v textu vloženém do souborů určených k úpravám prostřednictvím editorů Overleafu. Existují i jiné způsoby, jak se dostat k znakům emoji:

* Použitím primitivních příkazů `\char"<code point>` nebo `\Uchar"<code point>` (viz [tuto část](#optional-detail-luatexluahbtex-char-vs-uchar) článku).
* Použitím vstupních textových souborů obsahujících znaky emoji ve formátu UTF-8.
* Použitím příkazů LaTeXu (maker), které vkládají znaky emoji.

#### Vkládání emoji a dalších znaků mimo BMP do Overleafu

Pokud například vložíte znak emoji 😀 do editoru Overleaf Code Editor, bude v současnosti převeden na znaky ��.

![Chyba způsobená kopírováním a vkládáním znaků mimo BMP do editorů Overleaf](/files/fbceffa59ac965d015ad53554f5206159e8cb480)

Znak � má v Unicode kódový bod FFFD a jeho oficiální název je REPLACEMENT CHARACTER a používá se k „[nahrazení neznámého, nerozpoznaného nebo nereprezentovatelného znaku](https://en.wikipedia.org/wiki/Specials_\(Unicode_block\))“.

### Používání kódových bodů Unicode (U+) v LuaLaTeXu

Dokumentace Unicode zobrazuje hodnoty kódových bodů pomocí zápisu `U+<hexadecimální hodnota>`— například `U+1F600`, kde `1F600` je `<hexadecimální hodnota>` kódového bodu Unicode pro znak emoji 😀. Chcete-li tyto hodnoty kódových bodů použít v LuaLaTeXu, odstraníte `U+` a napíšete `\char"<hexadecimální hodnota>` nebo `\Uchar"<hexadecimální hodnota>`. Balíček `"` Znak říká enginu TeXu, že zadané číslo je uvedeno v šestnáctkové soustavě. Například pro použití emoji 😀 byste napsali `\char"1F600` nebo `\Uchar"1F600`—s použitím fontu, který jej umí vysázet.

Minimální příklad LuaLaTeXu používající `\char` a `\Uchar` pro sazbu znaku emoji 😀 může vypadat takto:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont[Renderer=Harfbuzz,SizeFeatures={Size=20}]{NotoColorEmoji.ttf}
%Použijte \emojifont ve skupině, aby jeho účinky zůstaly lokální
{\emojifont
\Uchar"1F600
\char"1F600}
\end{document}
```

[Otevřete tento příklad LuaLaTeXu v Overleafu](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)

**(volitelný detail) LuaTeX/LuaHBTeX: \char vs \Uchar**

Kromě konvenčního `\char<character code>` příkazu pro sazbu konkrétního `<character code>`, používají enginy LuaTeX, LuaHBTeX a XeTeX také `\Uchar<character code>` příkaz. Z pohledu uživatele vypadá výsledek `\char` a `\Uchar` stejně, ale v tom, jak tyto příkazy fungují, je jemný rozdíl, jak uvádíme níže.

**Klíčový rozdíl: expanze**

`\Uchar` je takzvaný [rozšiřitelný příkaz](/latex/cs/clanky-do-hloubky/22-how-does-expandafter-work-the-meaning-of-expansion.md#expansion-a-general-term-for-a-set-of-operations) zatímco `\char` není rozšiřitelný. Když je `\char<character code>` nebo `\Uchar<character code>` příkaz „vykonáván“ — tj. příkaz není ukládán jako součást makra nebo jiného seznamu tokenů — uvnitř enginu TeXu probíhají následující akce:

* **`\char<character code>`** nařizuje enginu TeXu, aby okamžitě vložil token znaku, reprezentující `<character code>`, do jakéhokoli obsahu, který právě sází.
* Naproti tomu **`\Uchar<character code>`** má dva odlišné kroky zpracování:

1. Ta `\Uchar<character code>` příkaz je *rozbalen*a `<character code>` je převeden na dočasný seznam tokenů obsahující jediný [znakový token](/latex/cs/clanky-do-hloubky/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md#tex-tokens-101-28and-notions-of-expansion29) který představuje `<character code>`.
2. Tento seznam tokenů s jediným znakem je nyní *zpřístupněn* enginu TeXu jako zdroj jeho dalšího vstupu. Ve skutečnosti engine TeXu „dočasně přesune svůj pohled“, aby použil tento seznam s jediným tokenem jako místo svého dalšího vstupního prvku (tokenu). Ve výchozím nastavení engine TeXu jednoduše znovu přečte (vstoupí) tento token a vysází odpovídající znak, čímž reprodukuje chování `\char` příkaz. **Avšak**, protože tento `<character code>` nebyl okamžitě vysázen, ale dočasně *uloženy* (uložen) jako jediný token, mohou primitivní příkazy TeXu nebo makra LaTeXu tento token využít (absorbovat) — nemusí být vysázen hned, ale lze jej podle potřeby použít v dalším zpracování.

Ve skutečnosti `\char<character code>` říká „vysaď toto `<character code>` nyní“, zatímco `\Uchar<character code>` má formu „odložené akce“ tím, že vytvoří uložený token znaku a zpřístupní jej jako další vstupní položku (token). Tento token může být buď použit (absorbován) příkazy a makry TeXu, nebo znovu přečten enginem TeXu a vysázen.

### Unicode (kódování) není celý příběh

Možnost používat znaky emoji v textu kódovaném v Unicode je jen částí úspěšného příběhu emoji. Nárůst používání emoji byl umožněn také vývojem v [technologii fontů OpenType](https://learn.microsoft.com/en-us/typography/opentype/)—fonty, jejichž data glyfů (podoby znaků) mohou obsahovat [barevná data](https://learn.microsoft.com/en-us/typography/opentype/spec/colr): takzvané [barevných fontů OpenType](#opentype-color-fonts).

Kromě vhodných fontů vyžaduje použití barevných emoji další softwarové komponenty, jejichž úkoly zahrnují:

* předzpracování („[tvarování](#the-concept-of-text-shaping)“) textu kódovaného v Unicode, *přípravu* na zobrazení pomocí konkrétního fontu;
* *vykreslování a zobrazení* barevných emoji daného fontu *glyfů* na obrazovce zařízení.

#### Glyf vs. znak: nejsou to totéž?

Pojmy „glyf“ a „znak“ se často používají, jako by byly zaměnitelné — odkazující na stejný základní koncept — ale v jejich významu je jemný, i když důležitý rozdíl.

Unicode [definuje pojem „znak“](http://www.unicode.org/glossary/#character) jako:

> „Nejmenší součást psaného jazyka, která má sémantickou hodnotu; odkazuje na abstraktní význam a/nebo tvar, nikoli na konkrétní tvar… “

Naproti tomu „glyf“ je *konkrétní* *tvar* (návrh) pro *vizuální reprezentaci* určitého *znaku*.

Problém znak vs. glyf lze snadno pozorovat, když se text nabitý emoji zobrazuje na různých softwarových systémech/platformách, například když si tentýž text přečtete na mobilním telefonu s iOS nebo Androidem nebo na stolním počítači s Windows. Bez ohledu na použité zařízení nebo platformu by základní text (posloupnost znaků) obsahoval stejný Unicode-kódovaný *emoji* *znaky*. Jsou to schopnosti specifické pro zařízení, které se podílejí na *předzpracování* tohoto textu a poté *vykreslování* a *zobrazeného* výsledků, případně s použitím fontů specifických pro dané zařízení, které vytvářejí odlišné glyfy (podoby znaků) pro reprezentaci stejných znaků emoji.

Unicode’s [Úplný seznam emoji](https://unicode.org/emoji/charts/full-emoji-list.html) poskytuje ukázkové obrázky reprezentující každý znak emoji Unicode — ukazuje různé glyfy používané různými dodavateli technologií. Nejenže návrháři fontů přijímají své vlastní specifické návrhy (glyfy) k reprezentaci znaků emoji, ale jednotlivé fonty se také liší v počtu znaků emoji, které podporují (pro které obsahují glyfy), a mohou, nebo nemusí, obsahovat pokročilejší funkce zpracování emoji-textu zahrnuté ve specifikacích emoji Unicode.

Pojem a koncept znaků, jejich sémantika a kódování tvoří základ světa Unicode: ten se zabývá znaky. Návrh a vizuální reprezentace jednotlivých znaků jako glyfů náleží technologiím fontů a řemeslu návrhu fontů.

#### Emoji v Unicode: mnohem víc než jen kódování textu

Hlavní úlohou Unicode je poskytnout globální standard kódování, který určuje, jaká celočíselná hodnota, nazývaná *kódový bod,* má být použita k reprezentaci každého znaku, včetně emoji, v proudu textu kódovaného v Unicode.

Specifikace Unicode pro emoji také definuje *chování při zpracování* pro určité *sekvence* znaky emoji vyskytující se v proudu textu kódovaného v Unicode. Definované sekvence znaků emoji mohou být „slučovány“ procesem nazývaným [tvarováním textu](#the-concept-of-text-shaping) aby vznikl jediný výsledný („kompozitní“) glyf emoji — tento jediný glyf by pak operační systém zařízení použil k reprezentaci původní sekvence znaků obsažené v textu.

Technická zpráva Unicode o [emoji Unicode](https://unicode.org/reports/tr51/) dokumentuje bohatou sadu funkcí dostupných softwaru, který chce poskytovat zpracování znaků emoji v souladu s Unicode. Jako příklad Unicode definuje (kóduje) znaky nazývané [modifikátory emoji](http://www.unicode.org/reports/tr51/#Emoji_Modifiers_Table) které lze použít k vytvoření *variant* „základních“ znaků emoji, například variant [barvy pleti podle Fitzpatrickovy stupnice](http://www.unicode.org/reports/tr51/#Diversity). Upozorňujeme, že sada základních znaků emoji a příslušné modifikátory jsou definovány jako součást celkového [standardu emoji Unicode](http://www.unicode.org/reports/tr51).

Stránka Unicode [Emoji sekvence](http://unicode.org/emoji/charts/emoji-sequences.html) poskytuje tabulku sekvencí, které aktuálně uvádí specifikace Unicode. Umístěte ukazatel myši na kterýkoli z obrázků glyfů emoji a zobrazí se malý vyskakovací nástroj s nápovědou, který vám sdělí základní sekvenci znaků emoji Unicode, jež daný glyf vytváří:

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

Například glyf emoji:

![HandMediumSkinTone.png](/files/173596782a01bd6251c88667b418ec294f12a77d)

je uveden v části [sekce modifikačních sekvencí](http://unicode.org/emoji/charts/emoji-sequences.html#modifier_sequences) a je vytvořen dvouznakovou sekvencí U+1F44B U+1F3FD. Tyto složkové znaky jsou:

U+1F44B:![UnicodeWavingHandDefault.png](/files/bfc22f27df6d4b949c0756e78f5c5c272df4f563) (MÁVAJÍCÍ RUKA)

U+1F3FD:![FitzPatrick3.png](/files/15c3249ac33ed3770801d83e8c738c8bb50ac90c) (MODIFIKÁTOR EMOJI FITZPATRICK TYPE-4)

**Používání modifikátorů odstínu pleti v LuaHBTeXu**

Následující příklad používá LuaHBTeX k demonstraci použití modifikátorů emoji:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont[Renderer=HarfBuzz,SizeFeatures={Size=20}]{NotoColorEmoji.ttf}
Izolovaná mávající ruka: {\emojifont\Uchar"1F44B}\par
Izolovaný modifikátor: {\emojifont\Uchar"1F3FD}\par
Kombinovaný výsledek: {\emojifont\Uchar"1F44B\Uchar"1F3FD}
\end{document}
```

[Otevřete tento příklad modifikátorů emoji v LuaLaTeXu v Overleafu](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)

Tento příklad vytvoří následující výstup:

![ModifiersInLuaHBTeX.png](/files/17a1305b01d78295a12ff4bfa09392265bbb45f5)

#### UTF-8: jeho role při ukládání textu Unicode

Jakýkoli text nebo kód, který napíšete nebo vložíte do Code Editoru Overleafu (nebo Visual Editoru), bude uložen ve formátu UTF-8, takže si stručně připomeneme, co UTF-8 vlastně znamená. UTF znamená Unicode Transformation Format a úloha UTF-8 při ukládání nebo přenosu textu kódovaného v Unicode je vyjádřena frází „Transformation *formát*.”

Hodnoty kódových bodů Unicode se pohybují od 0 do maxima 1 114 111, takže je nemožné reprezentovat všechny hodnoty znaků Unicode pomocí jediného 8bitového bajtu, který může uložit pouze až 256 různých hodnot: 0 až 255. Je však možné reprezentovat libovolnou celočíselnou hodnotu kódového bodu Unicode pomocí *souvislé sekvence* hodnot o velikosti bajtu — a to je princip UTF-8.

UFT-8 poskytuje „recept“ k *transformaci* (tj. k „zakódování“ nebo „převodu“) celočíselné hodnoty kódového bodu Unicode na jedinečnou sekvenci 1 až 4 po sobě jdoucích hodnot o velikosti bajtu: počet potřebných po sobě jdoucích bajtů závisí na hodnotě celočíselného kódového bodu. Proto můžete číst, že UTF-8 ukládá znaky Unicode jako *vícebajtové sekvence* protože jediný znak Unicode (celočíselný kódový bod) je v UTF-8 reprezentován jako sekvence 1 až 4 po sobě jdoucích bajtů.

Samozřejmě text uložený v UTF-8 lze převést zpět na původní posloupnost celočíselných hodnot kódových bodů Unicode — to je to, co musí dělat XeTeX nebo LuaTeX/LuaHBTeX při čtení vstupního souboru LaTeXu uloženého ve formátu UTF-8. Tyto enginy TeXu potřebují znát vstupní hodnoty Unicode kódových bodů (znaků), než mohou text vysázet. Všimněte si, že pdfTeX nemá vestavěnou schopnost dekódování UTF-8, a proto se musí spoléhat na makra TeXu při zpracování (dekódování) vstupního textu ve formátu UTF-8.

**Některé příklady UTF-8**

* Arabský znak ش („šín“) má v Unicode kódový bod 0634 v šestnáctkové soustavě (základ 16) nebo 1588 v desítkové soustavě (základ 10). V UTF-8 je ش reprezentován dvěma (šestnáctkovými) hodnotami D8 a B4, takže znak ش by byl uložen jako dva po sobě jdoucí bajty D8B4 v textu kódovaném UTF-8.
* Znak emoji 😀 má v Unicode kódový bod 1F600 v šestnáctkové soustavě (základ 16) nebo 128512 v desítkové soustavě (základ 10). V UTF-8 je 😀 reprezentován 4 (šestnáctkovými) hodnotami F0, 9F, 98 a 80, takže znak 😀 by byl uložen jako 4 po sobě jdoucí bajty F09F9880 v textovém souboru UTF-8.

#### Speciální znaky používané při zpracování textu emoji založeného na Unicode

Ne každý znak kódovaný v Unicode je určen k vizuálnímu zobrazení prostřednictvím glyfů v nějakém fontu: některé zakódované znaky jsou označeny jako *netisknutelné znaky* jejichž účelem je pomáhat specializovaným funkcím zpracování textu (v podporujícím softwaru). Různé softwarové aplikace poskytují různou úroveň podpory pro netisknutelné znaky zakódované v Unicode, takže výsledek bude záviset na používaném softwarovém prostředí — aplikacích a fontech.

**Dva netisknutelné znaky, které stojí za to znát**

* **Spojovník nulové šířky (ZWJ)**, kódový bod 200D (šestnáctkově), je, jak jeho název napovídá, určen k vyvolání „spojovacího chování“ vstupních znaků — ale pouze pokud tyto vstupní znaky *mají* definované spojovací chování.
* **Nespojovník nulové šířky (ZWNJ)**, kódový bod 200C (šestnáctkově), je určen k potlačení *zabránit* „spojovacího chování“, které by jinak vstupní znaky mohly vykazovat. Například můžete ZWNJ použít k zabránění spojovacího chování po sobě jdoucích arabských znaků, které by se obvykle zpracovaly (ztvarovaly) do svých spojovacích forem.

Unicode zveřejnil seznam [doporučených sekvencí emoji se ZWJ](https://unicode.org/emoji/charts/emoji-zwj-sequences.html) které používají U+200D ZERO WIDTH JOINER (ZWJ) ke spojení sekvencí znaků emoji do jediného kompozitního glyfu emoji — pokud je k dispozici v používaném fontu (fontech).

**Příklad použití nespojovníku nulové šířky**

Následující minimální úryvek kódu používá font OpenType Scheherazade, obsažený v TeX Live, k definování fontu LaTeXu nazvaného `\arabicfont` který můžeme použít pro sazbu arabštiny. Řádek

```latex
{\arabicfont Nespojující:\textdir TRT\Uchar"0644\Uchar"200C\Uchar"0627}
```

používá znak nespojovníku nulové šířky prostřednictvím `\Uchar"200C`, aby zabránil normálnímu spojovacímu chování dvou arabských písmen ل (lam) a ا (alef). Všimněte si použití `\textdir TRT` pro nastavení směru textu zprava doleva:

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

[Otevřete tento příklad LuaLaTeXu v Overleafu](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)

Tento příklad vytvoří následující výstup:

![NonJoiner.png](/files/9456d523d54ec5eb97285196810c73d2c25d12ec)

## Pojem „tvarování textu“

Začněme vizuálním příkladem s urdským překladem slova „edukační“. Text urdského překladu může být napsán na klávesnici nebo dotykovém zařízení a vznikl by jako jednoduchá lineární sekvence arabských znaků Unicode. Když je však tento text vysázen nebo zobrazen na obrazovce zařízení ve [stylu Nastaliq](https://en.wikipedia.org/wiki/Nastaliq), výsledkem je složité dvojrozměrné uspořádání glyfů.

Pomocí našeho urdského příkladu následující grafika porovnává lineární vstup arabského Unicode *znaky* s výstupem vysázeným ve stylu Nastaliq, tvořeným dvojrozměrným uspořádáním *glyfů* obsaženým ve (svobodném) fontu [Awami Nastaliq](https://software.sil.org/awami/download/):

![](/files/209ed3cc065f83eaee4254ac2a54c1cbbe395911)

Proces „překladu“ vstupních znaků na sadu správně umístěných výstupních glyfů se nazývá *tvarováním textu*a je zásadní součástí zpracování textu před jeho zobrazením nebo sazbou. Náš příklad použil text v urdském jazyce (arabské písmo), protože výsledek tvarování je zcela zřetelný, na rozdíl od jazyků používajících latinku, jako je angličtina, kde je tvarování mnohem méně výrazné — například při tvorbě jednoduchých ligatur.

Tvarování textu je nezbytné při používání písem (systémů zápisu), jako je [Arabština](https://en.wikipedia.org/wiki/Arabic), [hebrejština](https://en.wikipedia.org/wiki/Hebrew_language), [dévanágarí](https://en.wikipedia.org/wiki/Devanagari) nebo [malajálamština](https://en.wikipedia.org/wiki/Malayalam), jen čtyři příklady tzv. *složitých písem*. Aby bylo zajištěno správné zobrazení textu v těchto písmech a jazycích, které je používají, musí proces tvarování pečlivě řešit všechna pravidla a nuance tvarování přítomné v konkrétní kombinaci písma a jazyka. Například některé jazyky vyžadují, aby více vstupních znaků vytvořilo určitý výstupní glyf, nebo mohou existovat složité požadavky na pečlivé umisťování diakritických znamének a přeskupování mezi glyfy, aby byly jednotlivé glyfy umístěny správně (ve vzájemném vztahu).

Obecně je pro tvarování části textu potřeba několik informací:

* Písmo nebo *skript* systém zápisu, ve kterém je text napsán.
* Konkrétní *jazyk* který se používá. Jednotlivé skripty lze použít pro více jazyků, přičemž každá kombinace skriptu a jazyka má své vlastní jemnosti/nuance při tvarování.
* Písemný *směr* textu—například zprava doleva nebo zleva doprava.
* Zkopírovaný *písmo* který poskytuje glyfy potřebné k reprezentaci tvarovaného textu a případně obsahuje další „pravidla tvarování“, která řídí proces tvarování textu.

Požadavky na tvarování textu, zejména u složitých skriptů a jejich souvisejících jazyků, mohou být mimořádně podrobné a jemné, což naznačuje potřebu specializovaného softwaru, který dokáže uplatňovat potenciálně velmi složitá „pravidla“ tvarování textu. Není proto překvapivé, že takový software existuje a označuje se jako *engine pro tvarování textu*; ten, o kterém budeme mluvit, se nazývá [HarfBuzz](https://en.wikipedia.org/wiki/HarfBuzz), jehož dokumentace stojí za přečtení — například [Proč potřebuji tvarovací engine?](https://harfbuzz.github.io/why-do-i-need-a-shaping-engine.html).

**Další četba o tvarování textu**

Tyto krátké úvody vřele doporučujeme:

* [Co je tvarování textu?](https://harfbuzz.github.io/what-is-harfbuzz.html#what-is-text-shaping)
* [Proč potřebuji tvarovací engine?](https://harfbuzz.github.io/why-do-i-need-a-shaping-engine.html)

**Technická poznámka: více technologií tvarování (modelů)**

Tvarovací engine HarfBuzz podporuje několik „technologií tvarování“, které se liší způsobem, jakým proces tvarování implementují — každá implementace se označuje jako *tvarovač*, včetně v `luaotfload` dokumentaci. Hlavním zaměřením tohoto článku je tvarování OpenType, ale alternativní, volně použitelnou technologií je [Graphite](https://scripts.sil.org/cms/scripts/page.php?site_id=projects\&item_id=graphite_aboutOT), vyvinutá [SIL International](https://www.sil.org/). Další model tvarování podporovaný HarfBuzzem je [Apple Advanced Typography (AAT)](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6AATIntro.html)— písma podporující AAT se obecně používají na platformách Apple.

**Příklad použití tvarovače Graphite**

Následující příklad vysází část urdského textu pomocí písma nazvaného [Awami Nastaliq](https://software.sil.org/awami/download/), které podporuje tvarování Graphite a je k dispozici na Overleafu. Awami Nastaliq vytvořila [SIL International](https://www.sil.org/), organizace odpovědná za vývoj technologie Graphite.

Následující příklad ukazuje pokročilou schopnost tvarování fontů založených na Graphite — všimněte si, jak `luaotfload` deklarace písma vybírá tvarování Graphite pomocí `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

% Vzdělávací
\pardir TRT\textdir TRT \urdutest تعلیمی
\end{document}
```

[Otevřít tento příklad v Overleafu.](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)

Tento příklad vytvoří následující výstup:

![](/files/1af16dfdaaf277a28d52cd10d7c72ac4e35b0133)

#### Emoji a tvarování textu

Tvarování textu bylo představeno na příkladech z jazyka se složitým skriptem, urdštiny. Může však být překvapením zjistit, že vykreslení správného emoji glyfu/glyfů vyžaduje uplatnění tvarování textu na Unicode text obsahující sekvence znaků emoji —[jak poznamenal hlavní vývojář HarfBuzzu](https://github.com/harfbuzz/harfbuzz/issues/2428#issuecomment-639108677):

> ...tvarování emoji pomocí HarfBuzzu je plně v rozsahu a ve skutečnosti je nezbytné pro získání rodinných emoji, barvy pleti atd.

Podíváme se na příklady.

### Rozdělení odpovědnosti: textový tvarovací engine + fonty OpenType

V praxi je tvarování textu „společnou operací“, neboli dělením práce, mezi logikou a pravidly zabudovanými v textovém tvarovacím enginu a dalšími pravidly a daty tvarování zabudovanými ve používaných fontech — od této chvíle budeme pokrývat tvarování založené na OpenType *pouze*.

Aby bylo možné provést tvarování, dostane textový tvarovací engine obvykle nějaký Unicode text, určený skript a jazyk, případně směr zápisu a hlavně font OpenType, který se použije během procesu tvarování — font poskytne výstup: sadu glyfů a poziční data. Pokud je to požadováno, může tvarovací engine uplatnit další pravidla ([funkce OpenType](https://en.wikipedia.org/wiki/List_of_typographic_features#OpenType_typographic_features)) obsažená v používaném fontu OpenType — která pravidla se mají použít, si obvykle může vybrat uživatel z seznamu funkcí podporovaných fontem.

Výsledkem procesu tvarování je *seznam glyfů* obsažený ve fontu OpenType, spolu s *meziglyfovými* pozičními daty. Tato poziční data se vztahují ke *relativnímu umístění tvarovaných glyfů*; nevztahují se na absolutní umístění v sazené stránce nebo jiném médiu/obsahu, například na webové stránce, Tweetu atd. Renderovací software (sazecí engine, webový prohlížeč atd.) používá informace o meziglyfovém umístění, aby zajistil, že glyfy budou po sestavení a začlenění do konečného výstupu správně umístěny vůči sobě navzájem.

#### Co je seznam glyfů?

Interně je každému glyfu ve fontu OpenType přiřazen číselný identifikátor, celočíselná hodnota nazývaná index glyfu — také označovaná jako identifikátor glyfu neboli GID. Po dokončení úkolu tvarování vrátí textový tvarovací engine své výsledky jako *seznam identifikátorů glyfů* plus *poziční data* pro tyto glyfy.

Jednotlivým glyfům ve fontech OpenType přiřazuje indexy (identifikátory) tvůrce fontu, takže jde o velmi specifickou a libovolnou hodnotu pro daný font — může se také lišit mezi verzemi konkrétního fontu. Nikdy nepředpokládejte, že stejná hodnota GID bude platit pro „podobné“ glyfy v různých fontech; téměř jistě nebude. Pokud máte seznam identifikátorů glyfů poskytnutý tvarovacím enginem, můžete je použít pouze k přístupu ke glyfům ve fontu, ze kterého byly získány.

#### Co jsou fonty OpenType?

Web je *zaplaven* vysvětleními a podrobnostmi o fontech OpenType, takže se omezíme na krátký popis.  [specifikace OpenType](https://docs.microsoft.com/en-us/typography/opentype/spec/) je složitý dokument určený pro vývojáře, ale v zásadě definuje formát souboru neboli kontejner pro data fontu. Font OpenType obsahuje data popisující tvary glyfů spolu s informacemi o podporovaných skriptech a jazycích, metadaty o fontu a různými „tabulkami“, které definují [typografické prvky](https://en.wikipedia.org/wiki/List_of_typographic_features#OpenType_typographic_features) podporované fontem.

Textový tvarovací engine lze obvykle instruovat, aby během procesu tvarování selektivně použil (využil) prvky fontu, a aplikoval tak konkrétní typografické efekty („pravidla“), které vyberou příslušnou sadu glyfů obsažených ve fontu. Zvolený font bude muset podporovat a poskytovat glyfy pro všechny prvky, které má textový tvarovací engine aplikovat.

#### Zakódované a nezakódované „glyfy“

Fonty OpenType obsahují datovou tabulku nazvanou [cmap](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap) (Character to Glyph Index Mapping), která mapuje sadu znaků Unicode podporovaných fontem na odpovídající index glyfu v daném fontu. Následující video nabízí krátký pohled do tabulky cmap obsažené ve fontu nazvaném `lmmono10-regiular.otf` (součást TeX Live).

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

Fonty však obvykle obsahují mnoho glyfů, které nepředstavují žádný konkrétní znak Unicode a nejsou zahrnuty jako součást této tabulky cmap. V důsledku toho lze sadu glyfů přítomných ve fontu OpenType rozdělit do dvou hlavních sad:

* zakódované glyfy, které představují znaky Unicode;
* nezakódované glyfy, které nepředstavují znaky Unicode.

Zakódované glyfy lze zpřístupnit zahrnutím příslušného znaku Unicode do textu — ale co nezakódované glyfy, jak se používají/přistupuje se k nim? Tyto glyfy se obvykle používají jako výstup operací tvarování textu, včetně použití funkcí fontu k vytvoření specifických vizuálních/typografických efektů.

### barevných fontů OpenType

Očekává se, že znaky emoji se budou zobrazovat/vykreslovat v plných barvách — černobílé emoji neposkytují úplně „plný zážitek z emoji“. V době počátečního kódování emoji v Unicode však [specifikace fontů OpenType](https://docs.microsoft.com/en-us/typography/opentype/spec/) neměla žádné vhodné ustanovení pro vkládání *colorful*-glyfových dat do fontů OpenType. Tato „mezera“ v OpenType přiměla přední technologické/platformní dodavatele hledat řešení a následný „závod“ vyústil v [různé návrhy na rozšíření OpenType](https://www.fontlab.com/news/color-font-format-proposals/) o podporu barevných fontů OpenType — nejen pro zobrazení barevných znaků emoji (glyfů), ale i pro vykreslování libovolného glyfu v barvě.

#### Čtyři varianty barevných fontů OpenType

[Adobe, Microsoft, Google a Apple předložili návrhy](https://www.fontlab.com/news/color-font-format-proposals/) na rozšíření OpenType o podporu plnobarevných fontů OpenType a nakonec byly čtyři návrhy přijaty a zahrnuty do formální specifikace OpenType. Pro pohodlí je můžeme volně rozdělit na vektorové a rastrové — ale jak je ukázáno v tomto [úložiště GitHub](https://github.com/simoncozens/test-fonts), specifikace OpenType je dostatečně flexibilní, aby podporovala soubory barevných fontů OpenType, které kombinují tyto čtyři základní technologie.

* **Vektorové fonty OpenType:**
* **Microsoft**: tvary glyfů jsou popsány pomocí formy vrstevnatých barevných vektorů ([COLR](https://docs.microsoft.com/en-us/typography/opentype/spec/colr) a [CPAL](https://docs.microsoft.com/en-us/typography/opentype/spec/cpal) tabulky).
* [**Adobe a Mozilla**](https://www.w3.org/2013/10/SVG_in_OpenType/) ([tabulka SVG](https://docs.microsoft.com/en-us/typography/opentype/spec/svg)): tvary glyfů se kreslí pomocí SVG, které podporuje glyfy vytvářené z vektorů *a rastrových obrázků*. Viz také [uživatelskou příručku Adobe k fontům SVG](https://helpx.adobe.com/fonts/user-guide.html/fonts/using/ot-svg-color-fonts.ug.html).
* **Rastrové fonty OpenType:**
* **Google**: glyfy jsou reprezentovány barevnými obrázky PNG vloženými ve fontu ([CBDT](https://docs.microsoft.com/en-us/typography/opentype/spec/cbdt) a [CBLC](https://docs.microsoft.com/en-us/typography/opentype/spec/cblc) tabulky).
* **Apple**: glyfy jsou rovněž reprezentovány barevnými obrázky vloženými ve fontu. Kromě PNG podporuje mechanismus Apple ([tabulka sbix](https://docs.microsoft.com/en-us/typography/opentype/spec/colr)) také JPEG a TIFF.

V důsledku toho se operační systémy a aplikační software podporující barevné fonty OpenType musí vypořádat se současnou smíšenou technologickou krajinou. Kromě toho byste si měli uvědomit, že jednotlivé barevné fonty OpenType — a *verze* téhož fontu — budou:

* mít odlišné pokrytí celé sady [znaků Unicode emoji](https://unicode.org/emoji/charts/emoji-list.html)— tj. kolik znaků emoji font poskytuje glyfů;
* používat odlišné návrhy glyfů pro reprezentaci jednotlivých znaků emoji;
* lišit se v možnostech, které poskytují pro podporu pokročilejšího používání standardů Unicode, například [modifikátory emoji](https://unicode.org/reports/tr51/#Emoji_Modifiers_Table), a další schopnosti zpracování textu emoji popsané v [Technická norma Unicode #51: Unicode Emoji](https://unicode.org/reports/tr51/).

#### Rozruch kolem HarfBuzzu

Naznačili jsme potřebu *engine pro tvarování textu*tvarovacího engine: softwaru, který vezme nějaký vstupní Unicode text napsaný pomocí konkrétní kombinace skriptu a jazyka a pomocí určeného fontu tento text vytvaruje do sekvence glyfů spolu s pozičními daty, která lze použít k sazbě původního vstupního textu.

[HarfBuzz](https://harfbuzz.github.io/) je jedním takovým tvarovacím enginem textu: jde o [open-source knihovnu kódu](https://github.com/harfbuzz/harfbuzz) a výsledek více než desetiletého výzkumu a vývoje — a je stále aktivně vyvíjen a nasazován jako součást mnoha softwarových produktů. Samotný HarfBuzz neprovádí „sazbu“, ale poskytuje „služby tvarování textu“ softwaru, který se jej rozhodne integrovat, včetně XeTeXu, LuaHBTeXu, [Adobe PhotoShop a Adobe InDesign](https://en.wikipedia.org/wiki/HarfBuzz).

Začleněním HarfBuzzu mohou enginy TeX využívat jeho pokročilé schopnosti tvarování textu a poskytovat velmi sofistikovanou vícejazyčnou sazbu, zejména pro složité skripty, jako je arabština, hebrejština, dévanágarí a mnoho dalších. Všimněte si také, že HarfBuzz se používá ke zpracování a tvarování Unicode znaků emoji, čemuž se budeme věnovat podrobněji.

Následující grafika shrnuje roli, kterou hraje HarfBuzz při integraci se softwarem, jako je XeTeX nebo LuaHBTeX, při sazbě textu ve složitém skriptu, jako je arabština:

![Přehled tvarování arabského textu pomocí HarfBuzzu](/files/5809ac4ee038d99eb604094f52f15ab3d6ce4f6b)

**Prozkoumávání HarfBuzzu**

Kdokoli, kdo se chce dozvědět více o HarfBuzzu a službách tvarování OpenType, které poskytuje XeTeXu a LuaHBTeXu, může [stáhnout binární distribuci HarfBuzzu](https://github.com/harfbuzz/harfbuzz/releases) která obsahuje knihovnu HarfBuzz (pro programátory) a nástroje příkazového řádku `hb-view` a `hb-shape`.

**Příklad: jak používat hb-view**

Vytvořte nový soubor ve svém oblíbeném textovém editoru s podporou UTF-8 a zkopírujte/vložte do něj následujících šest znaků emoji 👋👋🏻👋🏼👋🏽👋🏾👋🏿, poté jej uložte v UTF-8 formátu do souboru nazvaného například `emoji.txt`.

Všimněte si, že váš textový editor může zobrazovat (náhradní) černobílé verze emoji, protože není schopen (není naprogramován tak, aby) vykresloval barevné glyfy. Jakmile jsou těchto 6 emoji uložena, soubor `emoji.txt` by měl obsahovat data UTF-8 pro následující sekvenci znaků emoji Unicode — modifikátory emoji jsme oddělili čárkami jen pro *snazší čtení*:

* `1F44B` k vytvoření 👋
* `1F44B`, `1F3FB` k vytvoření 👋🏻
* `1F44B`, `1F3FC` k vytvoření 👋🏼
* `1F44B`, `1F3FD` k vytvoření 👋🏽
* `1F44B`, `1F3FE` k vytvoření 👋🏾
* `1F44B`, `1F3FF` k vytvoření 👋🏿

Celkem by mělo být **11** znaků Unicode, z nichž každý generuje 4 bajty dat UTF-8, takže výsledný `emoji.txt` soubor by měl být 44 bajtů dlouhý, bez koncových značek řádku použitých na konci řádku obsahujícího emoji.

Ta `hb-view` může použít soubor `emoji.txt`, spolu s vhodným barevným fontem OpenType dle vašeho výběru, například `NotoColorEmoji.ttf`, k vygenerování souboru SVG s vytvarovaným výstupem HarfBuzzu. Následující příklad příkazové řádky, který musí být **zapsán na jednom řádku** ve vašem terminálu, vygeneruje soubor SVG `emoji.svg`:

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

Při úspěšném spuštění bude soubor `emoji.svg`, vygenerovaný `hb-view`, lze otevřít v Inkscape a měl by vypadat nějak takto:

![Hbvieemoji.png](/files/59a7111f83308f80161e20b689def8599dded1f1)

`hb-view` lze použít k prozkoumání tvarování HarfBuzzem pro libovolný vhodný Unicode textový soubor a font OpenType — rozhodně se neomezuje jen na emoji! Zadejte

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

a zobrazí se vám bohatá nabídka možností příkazové řádky pro tento výkonný a užitečný nástroj. Šťastné tvarování!

## Tvarování textu a enginy TeX

Zde si projdeme schopnosti tvarování textu engineů XeTeX a rodiny engineů TeX založených na LuaTeXu.

### XeTeX

XeTeX byl vyvinut na začátku 21. století a zavedl několik inovací v sazbě založené na TeXu, zejména *vestavěnou* podporu pro:

* čtení Unicode textu ve formátu UTF-8;
* používání fontů OpenType;
* tvarování textu pro vícejazyčnou sazbu;
* matematickou sazbu založenou na OpenType.

Schopnost XeTeXu snadno a pohodlně sázet jazyky se složitými skripty je dána jeho vestavěnými schopnostmi tvarování textu — původně založenými na dnes již zastaralém [ICU LayoutEngine](http://userguide.icu-project.org/layoutengine). Díky práci Khaleda Hosnyho přešel XeTeX na používání HarfBuzzu pro tvarování textu, jak bylo uvedeno v oznámení z [března 2013](https://tug.org/pipermail/xetex/2013-March/024118.html). Pro každého, kdo chce sázet vícejazyčný text, je XeTeX obvykle uváděn jako volba číslo jedna — ale nyní existuje i další možnost, LuaHBTeX, kterou si projdeme.

### LuaTeX a LuaHBTeX

Vývoj LuaTeXu začal kolem roku 2005, ale řídil se zcela odlišnou návrhovou filozofií než XeTeX, který nové funkce začleňoval *přímo do* softwaru XeTeX. Na rozdíl od XeTeXu se vývojáři LuaTeXu rozhodli „...poskytnout minimální sadu nástrojů a žádná řešení.“ (viz [Referenční příručka k LuaTeXu](https://www.pragma-ade.com/general/manuals/luatex.pdf)). Místo poskytování sady dalších funkcí *zabudovaných do* enginy založené na LuaTeXu, jsou vnitřní mechanismy enginů LuaTeX otevřeny tak, aby vývojáři a zkušení uživatelé mohli využít integrovaný skriptovací jazyk Lua k vytváření vlastních řešení.

Například na rozdíl od XeTeXu nemůže engine LuaTeX *přímo* používat fonty OpenType; místo toho je třeba fonty OpenType načíst a „připravit k použití“ prostřednictvím funkcí pro načítání fontů napsaných v kódu Lua. Tyto funkce pro načítání fontů se označují jako *callback* funkce: kód Lua, který LuaTeX zavolá („provede“), když je podán požadavek na načtení fontu.

Kromě toho engine LuaTeX neposkytuje žádné *vestavěnou* schopnosti tvarování textu — ty také musí poskytovat externí kód, který může engine LuaTeX vyvolat, aby mu poskytl služby tvarování textu. To opět kontrastuje s enginem XeTeX, který zahrnul schopnosti tvarování textu do jádra softwaru.

#### luaotfload: nezbytný pro používání fontů OpenType v LuaTeXu/LuaHBTeXu

Callbackový mechanismus LuaTeXu pro načítání fontů poskytuje značnou flexibilitu, ovšem za cenu dodatečného programování. Naštěstí pro uživatele LuaLaTeXu komunita TeXu vyvinula balíček nazvaný `luaotfload`, který je součástí [každoročního vydání TeX Live](https://www.tug.org/texlive/) a je samozřejmě dostupný i pro uživatele Overleafu.

`luaotfload` je [dostupný na CTANu](https://ctan.org/pkg/luaotfload?lang=en) a má [vývojové úložiště na GitHubu](https://github.com/latex3/luaotfload) kde můžete sledovat nejnovější vývoj a [nová vydání](https://github.com/latex3/luaotfload/releases).

`luaotfload` lze načíst přímo do preambule dokumentu LaTeX prostřednictvím

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

Všimněte si, že `luaotfload` je název balíčku LaTeX *accents*, což znamená, že má název souboru `luaotfload.sty`. Pokud byste chtěli používat `luaotfload` s plain TeXem, můžete to udělat přidáním řádku

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

do vašeho dokumentu plain TeXu.

Obvykle se uživatelé LuaLaTeXu — tj. ti, kteří sázejí LaTeX pomocí LuaTeXu/LuaHBTeXu — nemusejí přímo zabývat `luaotfload` protože [`fontspec` accents](https://ctan.org/pkg/fontspec) načte `luaotfload` balíček za vás a navíc se postará o mnoho nízkoúrovňových detailů prostřednictvím uživatelských příkazů poskytovaných `fontspec` balíček.

### LuaHBTeX: nové možnosti pro tvarování textu

`luaotfload` je zralá a výkonná knihovna Lua, která zajišťuje práci LuaTeXu s fonty OpenType — spolu s poskytováním služeb tvarování textu pro řadu jazyků a skriptů. Původně byly funkce tvarování textu `luaotfload` implementovány v čistém kódu Lua, ale vydání TeX Live 2020 přineslo další mainstreamovou možnost pro tvarování textu — nový engine založený na LuaTeXu nazvaný LuaHBTeX.

„HB“ v LuaHBTeXu znamená HarfBuzz — v podstatě je LuaHBTeX původní engine LuaTeX *plus* s integrovaným tvarovacím enginem HarfBuzz. V souladu s návrhovou filozofií LuaTeXu dostupnost HarfBuzzu *ne* zaručuje automaticky, že text bude v LuaHBTeXu vytvarován: HarfBuzz je další nástroj, který lze použít k vytváření řešení tvarování textu.

Integrace HarfBuzzu do LuaHBTeXu je [programovatelná pomocí kódu Lua](#introduction-to-the-luahbtex-harfbuzz-api), což umožnilo vývojářům `luaotfload`přidat řešení tvarování textu založená na HarfBuzzu. V důsledku toho, [počínaje verzí 3.1, vydanou 5. listopadu 2019](https://github.com/latex3/luaotfload/releases/tag/v3.1), `luaotfload` byl rozšířen tak, aby využíval HarfBuzz — čímž se schopnosti tvarování textu HarfBuzzu snadno zpřístupnily běžnému uživateli.

Čtenáři, které zajímají technické detaily integrace HarfBuzzu s LuaTeXem, si mohou přečíst tento [článek od Khaleda Hosnyho](https://www.tug.org/TUGboat/tb40-1/tb124hosny-harfbuzz.pdf).

### luaotfload: dvě možnosti pro tvarování textu (kdy použít HarfBuzz?)

Uživatelé LuaLaTeXu nyní mají dvě možnosti pro tvarování textu:

* `luaotfload`původní (uzlově založená) implementace tvarování textu, napsaná čistě v Lua;
* `luaotfload`tvarování založené na HarfBuzzu — zpřístupněné pomocí kódu Lua, který volá funkce tvarování textu HarfBuzzu.

`luaotfload` poskytuje přístup k těmto dvěma systémům tvarování prostřednictvím svého parametru „`mode`“ — většina uživatelů však spíše použije odpovídající možnost `fontspec` “`Renderer`“ než aby přímo používala nízkoúrovňové funkce `luaotfload`.

Každé z `luaotfload`řešení tvarování textu má své silné stránky a (aktuální) slabiny, ale které byste měli použít a kdy? Zde je několik bodů k úvaze:

* `luaotfload`Nativní uzlově založené zpracování může být paměťově náročné, zejména u velkých fontů OpenType pro CJK. Použití HarfBuzzu pro tvarování CJK textu může přinést zrychlení a snížení spotřeby paměti.
* Používejte HarfBuzz pro složité skripty, protože „...výrazně zlepšuje vykreslování indických a arabských skriptů a je pro tyto skripty vysoce doporučován.“ (viz `luaotfload` manuál).
* Integrace HarfBuzzu do `luaotfload` je stále poměrně nová a prochází dalším vývojem. V době psaní tohoto textu (červenec 2021) je vhodné používat vestavěné tvarování luaotfloadu (nastavení `mode=node`) pro hlavní fonty dokumentu, zejména pokud váš dokument používá latinku. Viz tento [problém na GitHubu](https://github.com/latex3/luaotfload/issues/175#issue-801120377), který shrnuje problémy a diskuse. Pokud chcete experimentovat, můžete použít `luaotfload` k načtení souboru fontu a vytvoření dvou fontů LaTeXu: jednoho, které používá tvarování založené na HarfBuzzu, a druhého používajícího tvarování založené na Lua. Overleaf vytvořil [ukázkový projekt](#sample-project-arabic-shaping), který to demonstruje.
* Nepoužívejte HarfBuzz pro práci s matematickými fonty. Jak uvádějí vývojáři na tex.stackexchange, HarfBuzz není [navržen pro práci s fonty pro matematickou sazbu](https://tex.stackexchange.com/questions/544881/does-luahbtex-with-harfbuzz-renderer-completely-supports-math-formating) a proto jej k tomuto účelu nepoužívejte.

**Ukázkový projekt: arabské tvarování**

Zde je projekt Overleafu, který používá několik kvalitních arabských písem ke srovnání `luaotfload`služeb tvarování textu založených na uzlech od`mode=node`(mode=node) se službami HarfBuzzu (`mode=harf`):

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

Tento projekt zahrnuje výstup zobrazený na následujícím obrázku:

![Sazba arabštiny](/files/e9f6d8c7c81e1905aa53fbc2052fd02a3eedffab)

### Volba „Renderer“ ve fontspec

Jak je uvedeno v jeho [dokumentace](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf), `fontspec` „...umožňuje uživatelům XeTeXu nebo LuaTeXu načítat fonty OpenType v dokumentu LaTeX“. Pokud používáte enginy LuaTeX nebo LuaHBTeX, `fontspec` načte `luaotfload` knihovnu za vás a navíc poskytne sadu pohodlných uživatelských příkazů, které snižují potřebu zabývat se `luaotfload`nízkoúrovňovou funkcionalitou.

Jak tedy zvolit mezi tvarováním HarfBuzzu nebo vestavěným tvarováním poskytovaným `luaotfload`? Odpověď je obsažena ve vynikajícím [`fontspec` dokumentace](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf), konkrétně v části VI: funkce fontů pouze pro LuaTeX. `fontspec` poskytuje nastavení nazvané `Renderer` které lze nastavit při definování fontu prostřednictvím `fontspec`. `Renderer` řídí nízkoúrovňové zpracování fontu. Dvě zajímavé možnosti jsou

* `Renderer = Node`: výchozí „mode“ pro sazbu fontů OpenType — používá `luaotfload`funkce tvarování textu luaotfloadu implementované čistě v Lua.
* `Renderer = Harfbuzz`: tento „mode“ definuje/načítá font pro použití s tvarovacím enginem HarfBuzz. `luaotfload` používá rozhraní LuaHBTeXu k volání funkcí v HarfBuzzu.

Další informace najdete v [`fontspec` dokumentace](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf).

## TeX enginy, HarfBuzz a barevné emoji

Ačkoli XeTeX i LuaHBTeX integrují HarfBuzz, poskytují odlišnou úroveň podpory některých pokročilejších funkcí HarfBuzzu — zejména načítání a používání barevných fontů OpenType.

### XeTeX a barevné fonty OpenType

Jak bylo uvedeno, existují dvě kategorie barevných fontů OpenType na základě datového formátu použitého k ukládání glyfů fontu: vektorové a rastrové.

#### XeTeX a rastrové barevné fonty OpenType

XeTeX nemůže načíst rastrová barevná písma OpenType — například Googleovo [Noto Color Emoji](https://www.google.com/get/noto/help/emoji/) dodaný s TeX Live 2020. Pokud se například pokusíte načíst Noto Color Emoji (NotoColorEmoji.ttf), XeLaTeX selže s potenciálně zavádějící chybou, která tvrdí, že Noto Color Emoji „nelze najít“. Následující kód LaTeXu, vysázený pomocí XeLaTeXu, *nefunguje*:

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

[Otevřete tento kód XeLaTeX v Overleafu ( ***ne*** funguje).](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)

Selže s chybou:

```
! Package fontspec Error: Písmo "NotoColorEmoji" nelze najít.
```

Podobně i jednoduchý příklad Plain TeXu zpracovaný XeTeXem také selže

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

[Otevřete tento příklad Plain TeXu (XeTeXu) v Overleafu ( ***ne*** funguje).](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)

Příklad Plain TeXu hlásí podobnou, ale jinou chybovou zprávu:

```
! Font \emojifont=[NotoColorEmoji.ttf] at 12.0pt not loadable: Metric (TFM) fil
e nebo nainstalované písmo nebylo nalezeno.
l.1 \font\emojifont="[NotoColorEmoji.ttf]" at 12pt

Nepodařilo se mi přečíst velikostní data pro toto písmo,
takže specifikaci písma budu ignorovat.
[Kouzelníci mohou opravit soubory TFM pomocí TFtoPL/PLtoTF.]
Můžete zkusit vložit jinou specifikaci písma;
např. napište `I\font<same font id>=<substitute font name>'.
```

**Příklad Plain LuaHBTeXu**

Pro srovnání zde je minimální příklad Plain TeXu přeložený pomocí LuaHBTeXu

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

[Otevřete tento příklad Plain TeXu (LuaHBTeXu) v Overleafu (úspěšně se přeloží).](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)

#### Skutečná příčina selhání XeTeXu

Chybové zprávy poskytované XeTeXem částečně zakrývají skutečnou příčinu problému: barevná písma OpenType, zejména rastrové varianty, jsou *ne* podporována XeTeXem. Ve skutečnosti XeTeX (Kpathsea) může *najít* písmo Noto Color Emoji, ale XeTeX toto písmo nemůže plně *načíst* a není schopen inicializovat interní tabulky dat písma potřebné k použití tohoto písma pro sazbu. Vnitřně XeTeX *začíná* proces načítání písma a testuje jeho „škálovatelnost“ (pomocí FreeTypeovy „definice“ „škálovatelnosti“), ale tento test selže a XeTeX vydá standardní, ne zcela jednoznačnou chybovou zprávu TeXového enginu.

**Technická poznámka**

Zpracování NotoColorEmoji.ttf v XeTeXu bylo prozkoumáno kompilací ladicí verze spustitelného souboru XeTeXu. V Eclipse IDE byl nastaven breakpoint na funkci XeTeXu `creatFontFromFile(filename, index, pointsize)`, a poté se krokováním procházelo kódem, aby bylo možné pozorovat následné zpracování.

#### XeTeX a vektorová barevná písma OpenType

XeTeX může *načíst* vektorová barevná písma OpenType, ale ve výsledném PDF nevygeneruje barevné emoji — pokud vůbec nějaké PDF XeTeX vytvoří. Na rozdíl od LuaTeXu, LuaHBTeXu a pdfTeXu XeTeX *přímo* nevystupuje vysázené dokumenty ve formátu PDF. Místo toho XeTeX vytváří mezilehlý `.xdv` (e**x**xtend **dv**i) formát souboru, který se převádí do PDF pomocí nástroje zvaného `xdvipdfmx`. V době psaní tohoto textu `xdvipdfmx` není schopen vložit do PDF příslušná data barevných glyphů emoji, takže v nejlepším případě uvidíte v PDF monochromatické emoji — „náhradní“ výsledek — nebo možná vůbec nic, podle použitého písma.

Zde je příklad XeLaTeXu, který používá barevné písmo OpenType [TwemojiMozilla.ttf](https://ctan.org/tex-archive/fonts/twemoji-colr), dostupné v TeX Live. TwemojiMozilla.ttf používá vektorový formát COLR/CPAL od Microsoftu pro ukládání barevných glyfů a je dodáván s TeX Live 2020. V tomto příkladu XeTeX dokáže načíst písmo, vygenerovat `.xdv` a soubor PDF, ale glyf emoji ve vysázeném PDF chybí:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont{TwemojiMozilla.ttf}
\newcommand{\smiley}{{\emojifont\char"1F600}}
Tady je smajlík: \smiley
\end{document}
```

[Otevřete tento kód XeLaTeX v Overleafu (NEFUNGUJE).](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)

Naproti tomu výše uvedený kód funguje s LuaLaTeXem, pokud definujete `\emojifont` použitím `fontspec` nastavení `[Renderer=HarfBuzz]`:

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

[Otevřete tento kód LuaLaTeXu v Overleafu (funguje).](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 a barevná písma OpenType

Díky svému integrovanému sazebnímu enginu HarfBuzz a knihovně `luaoftload` poskytuje LuaHBTeX podporu pro všechny čtyři varianty barevných písem OpenType. Uživatelé LuaLaTeXu mohou plně využít zpracování textu založeného na Unicode, který obsahuje znaky emoji, nebo jednoduše oživit své dokumenty velmi barevným textem pomocí barevných písem OpenType.

Jak již bylo zmíněno, čtyři varianty barevného písma OpenType lze rozdělit do dvou skupin:

* ty obsahující glyfy v rastrových obrazových formátech, jako je PNG;
* ostatní, které používají vektorové formáty SVG nebo mechanismus COLR/CPAL od Microsoftu.

Vektorové formáty glyfů mají výhodu škálovatelnosti: vytvářejí ostrou grafiku glyfů při libovolné velikosti bodu.

**Použití barevných písem Microsoft COLR/CPAL s LuaHBTeXem**

Pokud chcete pro svá barevná emoji písma OpenType použít vektorový formát, podívejte se na písmo [TwemojiMozilla.ttf](https://ctan.org/tex-archive/fonts/twemoji-colr?lang=en), které je založeno na formátu Microsoft COLR/CPAL. TwemojiMozilla.ttf je součástí TeX Live, ale nejnovější verzi můžete získat z jeho [úložiště GitHub](https://github.com/mozilla/twemoji-colr/releases) a nahrát ji do svého projektu v Overleafu.

Tady je malý, `fontspec`-založený příklad používající `Renderer=Harfbuzz`, který vysázuje velkou (vektorovou) emoji kachnu:

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

[Otevřete tento příklad LuaLaTeXu pro sazbu vektorové kachny.](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)

Tady je (vektorová) kachna vytvořená výše uvedeným příkladem:

![](/files/0d597bc2d2ef82ed1ea8888dcf60223e2d085647)

#### Používání barevných fontů OpenType založených na SVG s LuaHBTeX

V době aktualizace tohoto článku (červenec 2023) existuje jen malá formální dokumentace k používání barevných písem OpenType ve formátu SVG s LuaLaTeXem. Některé [komentáře v online diskusích](https://github.com/latex3/luaotfload/issues/96) navrhují použít `fontspec`’s `RawFeature`, jak je ukázáno v pseudo-kódu níže. Nahraďte `*název vašeho SVG souboru písma zde*` názvem SVG založeného souboru písma, který je dostupný vašemu kódu LaTeXu:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emoji[RawFeature={+svg},SizeFeatures={Size=20}]{název vašeho SVG souboru písma zde}
\emoji Vaše emoji zde...
\end{document}
```

Pokud vynecháte `fontspec` a načtete `luaotfload` přímo, možná budete muset deklarovat a specifikovat písmo následujícím způsobem — naše experimenty naznačují, že pro fungování je třeba vynechat možnost `mode=harf` :

```latex
\font\emoji=[název vašeho SVG souboru písma zde]:+svg;
```

**Několik varovných poznámek**

Čtenáři, kteří chtějí používat barevná písma OpenType ve formátu SVG, by měli vzít na vědomí:

* SVG barevná písma OpenType obsahující velký počet glyfů mohou být [výpočetně náročná pro LuaLaTeX](#processing-svg-glyph-data) ke zpracování, což může vést k [časovým limitům v Overleafu](/latex/cs/znalostni-baze/038-fixing-and-preventing-compile-timeouts.md).
* podpora LuaLaTeXu pro tato písma by mohla být [považována za experimentální](https://github.com/latex3/luaotfload/issues/96#issuecomment-530317399): výsledky se mohou lišit podle verze TeX Live použité ve vašem projektu; proto je vhodné experimentovat a postupovat opatrně.

**Zpracování dat glyfů SVG**

SVG umožňuje návrhářům vytvářet složité a barevné návrhy reprezentující glyfy písma — s určitými omezeními SVG [zdokumentovanými ve specifikaci OpenType](https://docs.microsoft.com/en-us/typography/opentype/spec/svg). Nicméně TeXové enginy, včetně LuaHBTeXu, nemohou přímo importovat (používat) soubory nebo data SVG — například data SVG používaná k popisu tvarů glyfů v barevných písmech OpenType ve formátu SVG. Data SVG glyfu musí být převedena do formátu PDF, protože LuaHBTeX je může použít k sazbě glyfu a vytvoření výsledného PDF dokumentu. Tento převod SVG do PDF zajišťuje Lua kód v rámci `luaoftload`: data SVG každého glyfu jsou extrahována ze souboru písma, uložena do dočasného `.svg` souboru a převedena do PDF pomocí Inkscapu přes příkazový řádek. Extrakce dat SVG a jejich převod do PDF s sebou nese určitý režijní náklad zpracování, což vede k potenciálně dlouhým časům kompilace dokumentu — zvláště u dokumentů používajících velká SVG písma obsahující tisíce emoji glyfů.

#### Rastrová barevná písma OpenType

**Použití barevného formátu písma OpenType CBDT/CBLC od Googlu s LuaHBTeXem**

[Noto Color Emoji](https://fonts.google.com/noto/specimen/Noto+Color+Emoji) je barevné písmo OpenType obsažené v TeX Live, takže se snadno používá v projektu v Overleafu. Protože Noto Color Emoji používá k reprezentaci emoji glyfů grafiku ve formátu PNG, můžeme jej použít k sazbě velké emoji kachny v rastrové podobě — jak ukazuje následující příklad. Znovu si všimněte, že deklarace písma ( `fontspec` písma (`\emojifont`) používá `Renderer=Harfbuzz`.

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

[Otevřete tento příklad LuaLaTeXu pro sazbu rastrové kachny.](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)

Tady je rastrová kachna vytvořená výše uvedeným příkladem:

![Emoji kachna v rastrové podobě vysázená LaTeXem](/files/57207822e3c631b13982379e4c4b67f7c1c8ea21)

Pokud se pokusíte použít `NotoColorEmoji.ttf` ale vynecháte `[Renderer=Harfbuzz]` z balíčku `fontspec` deklaraci, LuaHBTeX selže a při pokusu o zápis souboru PDF vypíše chybovou zprávu:

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

Důvod této chyby v tabulce [loca](https://docs.microsoft.com/en-us/typography/opentype/spec/loca) je [je vysvětlen na GitHubu](https://github.com/latex3/luaotfload/issues/98#issuecomment-531610153).

**Použití barevného formátu písma OpenType sbix od Applu s LuaHBTeXem**

Offline testy ukazují, že LuaHBTeX podporuje variantu `sbix` barevného písma OpenType, ale v době psaní tohoto článku se nám nepodařilo najít vhodně licencovaný `sbix`-variantní barevný emoji font, na kterém bychom demonstrovali sazbu kachny. Prosím [nás kontaktovat](https://www.overleaf.com/contact) napište nám, pokud o nějaký víte, a my tento článek kvákavě aktualizujeme a použijeme jej.

## Úvod do HarfBuzz API v LuaHBTeXu

![Db.gif](/files/4622490578cc58ae23a170bf4248fe13c6123455) ![Db.gif](/files/4622490578cc58ae23a170bf4248fe13c6123455)

Sazba textu, zejména pro jazyky se složitým písmem, a dokonce i emoji, je ze své podstaty obtížný úkol, takže není překvapivé, že HarfBuzz je sofistikovaná knihovna, se kterou může být práce složitá — pokud už nejste obeznámeni s operacemi sazby textu. V této závěrečné části se podíváme na integraci HarfBuzzu v LuaHBTeXu a na to, jak k ní přistupovat přes Lua kód v rámci `\directlua`.

Náš příklad používá poměrně základní kód, aby demonstroval HarfBuzz API v LuaHBTeXu. Je poněkud umělý, nemá produkční kvalitu ani velkou praktičnost, protože jeho jediným účelem je představit některé základní myšlenky. Lua kód jsme rozdělili do dvou `\directlua` bloků: první načítá `knihovnu luaharfbuzz` a vytváří některé globální proměnné, které použijeme v našem druhém `\directlua` bloku, kde definujeme makro nazvané `\codestoemoji`.

Připadá mi vhodné zopakovat Knuthovo použití dvojitých nebezpečných značek ohybu (obrázek s laskavým svolením [této stránky](http://www.truetex.com/db.htm)) protože obsah je poněkud nízkoúrovňový a „dívá se pod kapotu“ — i když doufáme, že by mohl být zajímavý pro odvážnější čtenáře. Integrace HarfBuzzu v LuaHBTeXu je odvozena z projektu [luaharfbuzz na GitHubu](https://github.com/ufyTeX/luaharfbuzz/wiki#projects-using-luaharfbuzz) kde najdete [úvod do projektu](https://github.com/ufyTeX/luaharfbuzz/wiki) spolu s [výpisem API luaharfbuzz](http://ufytex.github.io/luaharfbuzz/).

### První kroky: načtěte knihovnu luaharfbuzz a najděte písmo

Pro použití HarfBuzz API v LuaHBTeXu musíme nejprve načíst knihovnu (modul) nazvanou `knihovnu luaharfbuzz`, zabudovanou v LuaHBTeXu, a uložit vrácenou tabulku do (globální) proměnné, kterou budeme nazývat `hblib`:

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

Dále musíme najít vhodné emoji barevné písmo OpenType: použijeme Noto Color Emoji — všimněte si, že jsme velmi líní a neděláme žádnou kontrolu chyb pro případ, že jej nenajdeme! K jeho nalezení použijeme knihovnu `kpse` (Kpathsea), která je také součástí LuaTeXu/LuaHBTeXu:

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

Nyní, když máme přístup ke knihovně HarfBuzz přes naši proměnnou `hblib`a cestu k vhodnému písmu (`pathtofontfile`), můžeme začít používat `hblib`. Pro začátek vytvoříme font a tvář HarfBuzz pro použití v druhém `\directlua` bloku kódu, kde definujeme naše makro.

```latex
%Vytvořte HarfBuzz face a HarfBuzz font z Noto Color Emoji
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)
```

#### HarfBuzz font a HarfBuzz face: co to jsou?

Zkopírovaný [Objekt HarfBuzz face](https://harfbuzz.github.io/fonts-and-faces.html) představuje typ písma načtený ze souboru písma, ale bez nastavení konkrétních parametrů (například velikosti). [Objekt HarfBuzz font](https://harfbuzz.github.io/fonts-and-faces.html) představuje *konkrétní instanci* HarfBuzz face; v důsledku toho lze z jednoho HarfBuzz face odvodit různé objekty HarfBuzz font: každý HarfBuzz font může mít své vlastnosti, jako je velikost, nastavené na různé hodnoty. HarfBuzz face je vyšší úroveň abstrakce než HarfBuzz font.

### Použití glyfů písma k vytváření souborů PNG

Závěrečná část našeho prvního `\directlua` bloku je funkce nazvaná `writePNGglyph(hbfontobject, glyphID)` kterou používáme k demonstraci, že některá barevná písma OpenType, například Noto Color Emoji, používají pro reprezentaci emoji glyfů grafiku PNG, kterou obsahují.

Tato funkce používá HarfBuzz API v LuaHBTeXu k extrakci dat PNG z glyfů a zápisu těchto dat do `.png` souboru `Graphics<glyphID>.png`. Název tohoto `.png` souboru je vrácen pro použití funkcí `\includegraphics` k vložení obrázků PNG glyfů do našeho vysázeného PDF.

S `writePNGglyph(hbfontobject, glyphID)` na místě je náš první `\directlua` blok kódu takto:

```latex
\directlua{

% Načtěte knihovnu luaharfbuzz z LuaHBTeXu
hblib=require("luaharfbuzz")

% Najděte písmo Noto Color Emoji na serveru Overleafu
pathtofontfile=kpse.find_file("NotoColorEmoji.ttf","truetype fonts")

% Vytvořte HarfBuzz face a HarfBuzz font z Noto Color Emoji
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)

% Tato funkce přijímá písmo a ID glyfu:
% extrahuje data PNG glyfů a zapisuje
% je do souboru .png

function writePNGglyph(hbfontobject, glyphID)

    % Získejte data PNG glyfu
    local pngblob=hbfontobject:ot_color_glyph_get_png(glyphID)
    local pngdata=pngblob:get_data()

    % Sestavte název souboru pro náš soubor .png
    local fname="Glyph"..glyphID..".png"

    % Zapište soubor .png a vraťte název souboru
    local output = assert(io.open(fname, "wb"))
    output:write(pngdata)
    output:close()

    % Vraťte název souboru, který použije \includegraphics
    return fname
end
}
```

### Druhý blok \directlua: vytvořte makro \codestoemoji

Cílem je definovat makro `\codestoemoji` které můžeme zavolat s kusem textu obsahujícím kódy znaků emoji, které chceme, aby HarfBuzz vysázel. Konkrétně použijeme `\Uchar<character code>` k reprezentaci každého znaku emoji; například:

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

V definici `\codestoemoji` se děje spousta věcí, které vysvětlíme níže, ale definice vypadá takto:

```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()
    % Tabulka glyfů, hbglyphs, je indexovaná od 1
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Zmenšete velikost našich importovaných obrázků PNG
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
}}
```

#### Pochopení definice makra \codestoemoji

Ta `\codestoemoji` makro je většinou Lua kód obsažený v `\directlua`, takže pokud se chcete dozvědět více o tom, jak *jak* `\directlua` funguje, podívejte se na článek Overleafu [Pochopení `\directlua`](/latex/cs/clanky-do-hloubky/09-an-introduction-to-luatex-part-2-understanding-directlua.md). Vysvětluje, jak LuaTeX a LuaHBTeX zpracovávají `\directlua` když jsou příkazy TeX/LaTeXu zahrnuty v Lua kódu, a zejména potřebu používat `\noexpand` a `\unexpanded`.

**Práce s parametrem makra: "#1"**

Makro začíná těmito třemi řádky:

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

které vykonávají následující úlohy:

* `local str="#1"`: tím se z vstupu předaného makrem vytvoří Lua řetězec;
* `local hbbuffer = hblib.Buffer.new()`: tím se pomocí HarfBuzz API vytvoří buffer pro uložení textu, který chceme, aby HarfBuzz vysázel;
* `hbbuffer:add_utf8(str)`: tím se do bufferu HarfBuzzu přidá řetězec ve formátu UTF-8 vytvořený ze vstupu našeho makra.

První řádek kódu

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

se zdá být poměrně přímočarý, ale jeho činnost zahrnuje poměrně velkou složitost, kterou stojí za to prozkoumat trochu podrobněji.

Pokud se podíváme na třetí řádek kódu

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

vidíme, že používá naši `str` proměnnou k tomu, aby poskytla bufferu HarfBuzzu Unicode řetězec ve formátu UTF-8. Aby to fungovalo, proměnná `str` sama musí obsahovat Unicode text ve formátu UTF-8; takže vyvstává otázka: *jak* přetvořil LuaHBTeX argument makra `"#1"`, obsahující `\Uchar` příkazy, na Lua řetězcovou proměnnou `str` obsahující UTF-8 text pro HarfBuzz?

Když se podíváme na zamýšlené použití `\codestoemoji` makra:

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

vstup, například `\Uchar"1F3F4\Uchar"E0067\Uchar"E0062\Uchar"E0065...`, nevypadá nijak jako sekvence znaků emoji zakódovaných v UTF-8. HarfBuzz navíc o příkazech TeXu nic neví. Nějakým způsobem se surový vstup TeXu sestávající z `\Uchar` příkazů přemění na Unicode znaky zakódované v UTF-8, které může HarfBuzz použít, ale *jak*?

Odpověď spočívá v chování `\Uchar` příkazu: pokus o volání `\codestoemoji` pomocí `\char` místo `\Uchar` selže, ale *proč*?

**\Uchar: rozšíření v \directlua**

Když je `\codestoemoji` makro voláno, příkaz `\directlua` , uložený v definici makra, musí připravit Lua kód pro odeslání do vestavěného Lua interpretru LuaHBTeXu. Část tohoto procesu přípravy kódu je rozšíření všech příkazů TeXu/LaTeXu přítomných v původním Lua kódu v definici makra spolu s rozšířením všech argumentů makra poskytnutých uživatelem. Tento proces rozšíření vytvoří seznam tokenů, který je poté převeden zpět na text, čímž vznikne Lua kód určený pro předání Lua interpretru. Pro pohodlí přetiskujeme diagram z článku Overleafu [Pochopení `\directlua`](/latex/cs/clanky-do-hloubky/09-an-introduction-to-luatex-part-2-understanding-directlua.md):

![Mechanika \directlua](/files/e67d904ac5a322aba0da8efefc84d52b4ada050b)

Makro `\codestoemoji` je určeno k volání pomocí `\Uchar` příkazů a, [jak bylo dříve v článku uvedeno,](#the-key-difference-expansion), `\Uchar` je rozšiřitelný příkaz, jehož rozšíření generuje znakový token. V rámci zpracování `\directlua`, LuaHBTeX rozšiřuje každý `\Uchar<character code>` příkaz tam, kde *odstraní* každý `\Uchar<character code>` ze vstupu a *nahradí* jej nahradí odpovídající hodnotou rozšíření: znakový token reprezentující `<character code>`.

V závěrečné fázi zpracování je počáteční seznam tokenů vygenerovaný `\directlua` převeden *zpět na text* aby se stal Lua kódem určeným pro Lua interpreter (viz diagram výše). Všechny znakové tokeny vytvořené rozšířením `\Uchar` jsou také *převedeny zpět na text*: tento převod znakových tokenů na text generuje UTF-8 reprezentace původních `<character code>` hodnot.

V našem příkladu, v okamžiku kdy je Lua kód vygenerován a připraven pro Lua interpreter, byl vstup makra pro "#1" převeden na sekvenci UTF-8 textu: proměnná `str` je nyní UTF-8 textový řetězec, který lze bezpečně přidat do bufferu HarfBuzzu.

**Proč nefunguje \char?**

Přímá odpověď zní, protože `\char` je *ne* rozšiřitelný příkaz. Na rozdíl od `\Uchar` příkazů, `\char` příkazy *nejsou odstraněny* z vstupu během `\directlua`počátečního zpracování pro vytvoření seznamu tokenů, „projdou skrz“ a stanou se součástí seznamu tokenů vytvářeného pomocí `\directlua`. Například, pokud argument pro `\codestoemoji` obsahoval `\char"1F3F4` LuaHBTeX by to převedl na posloupnost tokenů a uložil je jako součást celkového seznamu tokenů, který se generuje.

V další fázi zpracování, při převodu tokenů zpět na text, by výsledný kód Lua obsahoval *doslovný řetězec* `\char"1F3F4` uvnitř textu použitého k definici naší proměnné `str`. Když se obsah `str` se přidá do bufferu HarfBuzz, nebude obsahovat UTF-8 kódovanou sekvenci představující znak emoji "1F3F4, ale bude obsahovat doslovný řetězec `\char"1F3F4`, který se HarfBuzz pokusí tvarovat a pro naše účely by nevytvořil glyf emoji. Mimochodem, řetězec `\char"1F3F4` by také generoval syntaktické chyby Lua, pokud by nebyl vytvořen jako „řetězec s dlouhými hranatými závorkami“ — viz [Co jsou únikové sekvence Lua](/latex/cs/clanky-do-hloubky/09-an-introduction-to-luatex-part-2-understanding-directlua.md#what-are-e2809clua-escape-sequencese2809d3f) pro kontext k tomuto problému.

Pokud se pokusíme použít `\codestoemoji` za `\char` příkaz, například takto:

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

LuaHBTeX selže a ohlásí syntaktickou chybu zhruba takto:

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

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

Interpretátor Lua narazil na problém, takže
zbytek tohoto bloku Lua bude ignorován.
```

#### Volání tvarovací funkce HarfBuzz

**Nastavení parametrů bufferu**

HarfBuzz někdy vyžaduje další informace o textu, který má tvarovat. Tyto informace můžete poskytnout konfigurací svého `<proměnná bufferu>` pomocí *metody bufferu*, například:

* `<proměnná bufferu>:set_direction(*směr HarfBuzz*)`;
* `<proměnná bufferu>:set_language(*jazyk HarfBuzz*)`;
* `<proměnná bufferu>:set_script(*skript HarfBuzz*)`.

Například musíme HarfBuzz informovat, že směr našeho textu s emoji bude zleva doprava. K tomu použijeme `set_direction()` metodu na našem `<proměnná bufferu>` (nazvané `hbbuffer`) takto:

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

kde `hblib.Direction.new("ltr")` vytváří „objekt směru“ vhodný pro předání enginu HarfBuzz prostřednictvím Lua.

**Proveďte tvarování**

Po vhodné inicializaci bufferu můžeme HarfBuzz požádat, aby provedl samotné tvarování prostřednictvím funkce `shape_full()`. V našem příkladu píšeme:

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

3\. a 4. parametr funkce `shape_full()` musí být tabulky Lua — použili jsme prázdné tabulky „`{}`“ pro oba parametry. Obecný tvar `shape_full()` je:

```latex
shape_full(Harfbuzz font, Harfbuzz buffer, {vlastnosti písma}, {"shaper"}
```

* **`{"shaper"}`**: Obvykle není třeba nastavovat, ale možnosti jsou `{"ot"}` nebo `{"graphite2"}`. Více informací o konceptu „shaperu“ lze nalézt v [dokumentaci HarfBuzz](https://harfbuzz.github.io/shaping-and-shape-plans.html)—mějte na paměti, že tato dokumentace popisuje nízkoúrovňové C API, nikoli Lua-based `knihovnu luaharfbuzz` vazbu (implementaci).
* **`{vlastnosti písma}`**: Toto je tabulka uvádějící [funkce OpenType](https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist)—podporované písmem—které chcete, aby HarfBuzz použil při tvarování.

Každá vlastnost písma, kterou chcete použít, musí být vytvořena pomocí `knihovnu luaharfbuzz` funkce knihovny

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

kde

* `instance_knihovny` je vaše `knihovnu luaharfbuzz` proměnná instance knihovny (`hblib` v našem příkladu);
* `feature_string` používá [syntaxi pro definování vlastností](https://github.com/ufytex/luaharfbuzz/wiki/Feature-Strings). Příklady toho jsou `+smcp` pro aktivaci kapitálek nebo `-kern` pro vypnutí kerningu.

Například:

```latex
local dosmcp = hblib.Feature.new("+smcp")
local nokern = hblib.Feature.new("-kern")
% Použijte vlastnosti písma takto
local res = hblib.shape_full(hbfont, hbbuffer, {dosmcp,nokern},{})
```

#### Přístup k výsledku: získání glyfů

A nakonec, pokud je operace tvarování úspěšná, vrátí se vytvarované glyfy v proměnné bufferu `hbbuffer` kterou jsme vytvořili dříve v kódu.

Ke glyfům přistupujeme pomocí metody bufferu `get_glyphs()` a pomocí smyčky získáme každý jednotlivý glyf. Všimněte si, že tabulka Lua obsahující glyfy, `hbglyphs` v našem příkladu je indexována od 1, ne od 0.

Každý glyf má *identifikátor glyfu* (matoucím způsobem nazývaný `codepoint`), a písmo HarfBuzz (`hbfont`) se předá do `writePNGglyph()` funkce, která vytvoří soubor PNG pomocí rastrové obrazové reprezentace tohoto glyfu v písmu.

`writePNGglyph()` zapíše soubor PNG a vrátí název souboru PNG, který se použije k importu (zmenšeného) souboru PNG do našeho dokumentu LaTeX prostřednictvím `\includegraphics[scale=0.75]{<fname>}`. Všimněte si, jak můžeme použít `\includegraphics` přímo v kódu Lua.

```latex
if (res) then
    local hbglyphs=hbbuffer:get_glyphs()
    % Tabulka glyfů, hbglyphs, je indexovaná od 1
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Zmenšete velikost našich importovaných obrázků PNG
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
```

### Úplný kód, který můžete otevřít v Overleafu

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

% Načtěte knihovnu luaharfbuzz z LuaHBTeXu
hblib=require("luaharfbuzz")

% Najděte písmo Noto Color Emoji na serveru Overleafu
pathtofontfile=kpse.find_file("NotoColorEmoji.ttf","truetype fonts")

% Vytvořte HarfBuzz face a HarfBuzz font z Noto Color Emoji
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)

% Tato funkce přijímá písmo a ID glyfu:
% extrahuje PNG data glyfu a zapisuje
% je do souboru .png

function writePNGglyph(hbfontobject, glyphID)

    % Získejte data PNG glyfu
    local pngblob=hbfontobject:ot_color_glyph_get_png(glyphID)
    local pngdata=pngblob:get_data()

    % Sestavte název souboru pro náš soubor .png
    local fname="Glyph"..glyphID..".png"

    % Zapište soubor .png a vraťte název souboru
    local output = assert(io.open(fname, "wb"))
    output:write(pngdata)
    output:close()

    % Vraťte název souboru, který použije \includegraphics
    return fname
end
}

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

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

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

if (res) then
    local hbglyphs=hbbuffer:get_glyphs()
    % Tabulka glyfů, hbglyphs, je indexována od 1.
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Zmenšete velikost našich importovaných obrázků PNG
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
}}

Kachna: \codestoemoji{\Uchar"1F986}

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

[Otevřete tento příklad API luaharfbuzz v Overleafu.](/latex/cs/clanky-do-hloubky/10-an-overview-of-technologies-supporting-the-use-of-colour-emoji-fonts-in-latex.md)

Tento příklad vytvoří následující výstup:

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

## Bonusová sekce: Zábava s emoji matematikou

Na odlehčenou závěrečnou poznámku použil člen týmu Overleaf [`emoji` balíček LaTeX](https://ctan.org/pkg/emoji?lang=en) k vytvoření zábavného příkladu:

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

[Otevřete tento zábavný příklad v Overleafu](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)

Tento příklad vytvoří následující výstup:

![Emojimath2.png](/files/b6a7f5959771a3cb74287900a455a282bf16899c)


---

# 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/cs/clanky-do-hloubky/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.
