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

# Katsaus teknologioihin, jotka tukevat värillisten emoji-fonttien käyttöä LaTeXissa

## Johdanto

Tämä artikkeli tarjoaa yleiskatsauksen erilaisiin [taustateemoihin](#which-topics-do-we-cover) liittyen OpenType-värifonttien käyttöön värillisten emojien ladontaan LaTeXissa. Olemme yrittäneet tarjota laajan valikoiman aineistoa, joka palvelee monenlaisia kiinnostuksen kohteita ja asiantuntemuksen tasoja. Jotta artikkeli pysyisi hallittavana, käsittelemme joitakin aiheita melko pintapuolisesti teknisiä yksityiskohtia paljon jättäen, mutta toivomme, että aineistoa on riittävästi ohjaamaan tutustumistasi värillisten emojien ladontaan LaTeXissa.

**Päivitys (heinäkuu 2023)**: Tämä artikkeli julkaistiin ensimmäisen kerran elokuussa 2021 ja sitä tarkistettiin heinäkuussa 2023 osion päivittämiseksi [SVG-pohjaisten OpenType-värifonttien käyttö LuaHBTeX:n kanssa](#using-svg-based-opentype-color-fonts-with-luahbtex).

### Mitä aiheita käsittelemme?

Tämä artikkeli käsittelee seuraavia yleisiä aiheita:

* Unicode: standardi, joka koodaa emojit merkeiksi ja määrittelee niiden odotetun käyttäytymisen tekstinkäsittely- ja ladontasovelluksissa.
* OpenType-värifontit: erikoistuneet fontit, jotka tarjoavat värikkäitä esityksiä emoji-merkeistä LaTeX-dokumentissasi.
* Tekstin muotoilu: keskeisen osan esittely monimutkaisten kirjoitusjärjestelmien ja emojien ladonnassa.
* HarfBuzz: LuaHBTeX:n osa, joka mahdollistaa edistyneen monikielisen ladonnan ja OpenType-värifonttien käytön emojien ladontaan LaTeXissa.
* Eri TeX-moottorit: niiden OpenType-värifonttitukeen tutustuminen ja valinta siitä, mitä TeX-moottoria käyttää.
* LuaHBTeX:n HarfBuzz-API: johdatus sen taustalla olevaan “taikaan” [tekstin muotoilu](#the-concept-of-text-shaping) LuaHBTeX:ssa.

### Kolme tapaa latoa värillisiä emojia

Värillisiä emojia voidaan latoa LaTeXilla kolmella päämenetelmällä:

1. Käyttämällä tavallisia LaTeX-grafiikkatyökaluja, kuten TikZ, MetaPost tai Asymptote, emojien piirtämiseen.
2. Lisäämällä emojeita käyttämällä valmiiksi tehtyjä emoji-grafiikoita, jotka on tallennettu ulkoisiin tiedostoihin.
3. Käsittelemällä emojeja Unicode-koodattuina teksteinä ja käyttämällä [tekstin muotoilu](#the-concept-of-text-shaping) verrattuna [OpenType-värifontteja](#opentype-color-fonts) niiden latomiseen.

Käytännön vaihtoehdot värillisten emojien sisällyttämiseen LaTeX-dokumenttiin riippuvat siitä TeX-moottorista, jolla kyseinen dokumentti käännetään: eli käytätkö:

* pdfLaTeXia: pdfTeX-moottori + LaTeX;
* XeLaTeXia: XeTeX-moottori + LaTeX;
* LuaLaTeXia: LuaHBTeX-moottori (alkaen TeX Live 2020:sta) + LaTeX.

Kaikki nämä kolme TeX-moottoria voivat käyttää LaTeX-työkaluja tai paketteja emojien piirtämiseen tai käyttää `\includegraphics{...}` lisätäkseen ulkoisiin grafiikkatiedostoihin tallennettuja emojia. Emojien piirtäminen tai tuominen on ihanteellinen tekniikka, kun tarvitset ratkaisun, joka ei riipu siitä TeX-moottorista, jota käytetään LaTeX-dokumentin kääntämiseen.

Jos työnkulussasi on kuitenkin joustoa valita tietty TeX-moottori ja haluaisit käyttää OpenType-värifontteja sekä Unicode-pohjaista tekstinkäsittelyä, tarvitset LuaTeX:n uusimman version, nimeltä LuaHBTeX. TeX Live 2020:sta alkaen LuaHBTeX:ää käytetään LuaLaTeX-formaattiin perustuvien LaTeX-dokumenttien kääntämiseen.

## Taustaa Unicodesta ja emoji-merkeistä

### Merkistökoodaukset

Tietokoneet tallentavat, välittävät ja käsittelevät tekstiä numeroarvojen (kokonaislukujen) sarjana, jotka kuvaavat tekstin muodostavia *merkkejä*. Luotettava tekstinkäsittely edellyttää, että tekstin tuottajat ja kuluttajat sopivat siitä, mitä kokonaislukuarvoja käytetään yksittäisten merkkien esittämiseen tekstivirrassa. Toisin sanoen, mikä on kyseisen tekstin *merkkiä* *koodaus?* Koodaus on sovittujen kokonaislukuarvojen joukko, joka on määritetty edustamaan tiettyä merkkijoukkoa: kukin merkki esitetään käytössä olevan koodauksen kokonaislukuarvolla.

### Mukana tulee Unicode

Historiallisesti 8-bittisen tekstin aikana käytettiin monia erilaisia merkistökoodauksia, mikä toi jatkuvasti esiin *koodausristiriitojen*haamun: tekstin tuottajat ja kuluttajat olettivat virheellisesti eri koodauksia, mikä johti tekstinkäsittelyvirheisiin. Jokainen, joka on työskennellyt TeX/LaTeXin parissa useita vuosia, on todennäköisesti törmännyt syöteaineiston ja dokumentin ladontaan käytettyjen fonttien välisiin koodausristiriitoihin. Jos dokumentin fontit on määritetty käyttämään eri koodausta kuin teksti, seurauksena on todennäköisesti puuttuvia tai virheellisiä merkkejä ladotussa PDF:ssä.

Nämä historialliset koodausongelmat voidaan ratkaista kansainvälisellä standardilla, joka koodaa kaikki maailman merkit: Unicode. Unicode-standardi ei ole staattinen, vaan sitä päivitetään säännöllisesti, jotta sen koodausjärjestelmään voidaan lisätä uusia merkkejä ja kirjoitusjärjestelmiä. Uusien merkkien ehdottamiseen on [virallinen tarkistusprosessi](http://www.unicode.org/pending/proposals.html) sekä erityinen [uusia emoji-merkkejä koskeva menettely](https://www.unicode.org/emoji/proposals.html).

### Kuinka monta Unicode-merkkiä?

Unicode koodaa teoreettisen enimmäismäärän, 1 114 112 merkkiä. Kutakin 1 114 112:ta kokonaislukuarvoa kutsutaan *koodipisteeksi*: kokonaislukuarvoksi, joka on määritetty kunkin merkin tunnistamiseen. Teknisistä syistä vain [1 112 064 koodipistettä](https://en.wikipedia.org/wiki/Unicode#Architecture_and_terminology) voidaan määrittää todellisille merkeille: 2048 koodipistettä ei voida osoittaa mihinkään ja niiden käyttö Unicode-yhteensopivassa tekstissä on kielletty.

Tätä kirjoitettaessa (tämän artikkelin ensimmäisen version aikaan) Unicode-standardin versio 13 oli allokoinut yhteensä 143 859 koodipistettä todellisille merkeille, mukaan lukien [3304 merkkiä, jotka on nyt koodattu emojiksi](https://www.unicode.org/L2/L2020/20114r-family-emoji-explor.pdf) (katso tuon dokumentin sivu 2). Unicoden koodaamien merkkien määrän kasvu on dokumentoitu hyvin artikkelissa [Kuinka monta Unicode-merkkiä on olemassa?](https://www.babelstone.co.uk/Unicode/HowMany.html) sekä [Wikipedian artikkelissa](https://en.wikipedia.org/wiki/Unicode#Versions).

### Unicode-tasot

Koko 1 114 112 Unicode-koodipisteen joukko on ryhmitelty 17 niin sanottuun tasoon: tasoihin 0–16, joista kukin sisältää 65 536 koodipistearvoa, mikä tuottaa yhteensä $$17\times2^{16} = 1,114,112$$ merkkiä. Tasoa 0, jota kutsutaan [Basic Multilingual Plane](https://en.wikipedia.org/wiki/Plane_\(Unicode\)#Basic_Multilingual_Plane), koodaa yleisimmin käytetyt merkit. Tasoja 1–16 kutsutaan [Supplementary Planeiksi](http://unicode.org/glossary/#supplementary_planes).

### Emojien nousu

Uudet merkit syntyvät ihmisten viestintätapojen muuttuessa, ja matkapuhelinteknologia synnytti yhden tällaisen merkkijoukon: emojit, jotka kehittyivät Japanissa 1990-luvun lopulla. Ei ole yllättävää, että [Unicode FAQ on Emoji](https://unicode.org/faq/emoji_dingbats.html) huomauttaa

> “Sana emoji tulee japanin sanoista [絵](http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=%E7%B5%B5) (e ≅ kuva) + [文字](http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=%E6%96%87) (moji ≅ kirjoitettu merkki).”

Lukijat, joita kiinnostaa emojien tausta ja historiallinen kehitys, voivat pitää tätä kiinnostavana:  [Unicode-johdanto](https://unicode.org/reports/tr51/#Introduction) tai artikkelia [I second that emoji: The standards, structures, and social production of emoji](https://firstmonday.org/ojs/index.php/fm/article/view/9381).

Vasta vuonna 2010, kun [Unicode-standardin versio 6.0](https://www.unicode.org/versions/Unicode6.0.0/)julkaistiin, monet emojit tunnustettiin virallisesti *merkkejä* itsenäisiksi merkeiksi. Unicode 13.0 koodasi [3304 merkkiä emojiksi](https://www.unicode.org/L2/L2020/20114r-family-emoji-explor.pdf) (katso tuon dokumentin sivu 2), ja Unicode 13.1 listaa [3521 emojia](https://unicode.org/emoji/charts/emoji-counts.html).

### Emojit elävät korkeammalla tasolla

Unicode määritti monia emoji-merkkejä koodipisteisiin Basic Multilingual Plane -alueen (BMP) ulkopuolella, [tasolla 1](https://en.wikibooks.org/wiki/Unicode/Character_reference/1F000-1FFFF) koodipistealueella 1F000–1FFFF — millä on tärkeä seuraus kaikille, jotka haluavat *kopioida ja liittää* emoji-merkkejä Overleafin editoriin (Code Editor tai Visual Editor). Overleafin tekstieditorit pystyvät käsittelemään vain Basic Multilingual Plane -alueen merkkejä, vaikka toivomme, että tulevat päivitykset tuovat tuen myös BMP:n ulkopuolisille merkeille. Huomaa, että tämä rajoitus koskee vain BMP:n ulkopuolisia merkkejä, kun teksti liitetään tiedostoihin, joita aiotaan muokata Overleafin editorien kautta. Emojimerkkeihin pääsemiseksi on myös muita tapoja:

* Käyttämällä alkeiskomentoja `\char"<koodipiste>` tai `\Uchar"<koodipiste>` (katso [tätä osiota](#optional-detail-luatexluahbtex-char-vs-uchar) artikkelissa).
* Käyttämällä syötetiedostoja, jotka sisältävät emoji-merkkejä UTF-8-muodossa.
* Käyttämällä LaTeX-komentoja (makroja), jotka lisäävät emoji-merkkejä.

#### Emojien ja muiden BMP:n ulkopuolisten merkkien liittäminen Overleafiin

Jos liität esimerkiksi emojimerkin 😀 Overleafin Code Editor -editoriin, se muutetaan tällä hetkellä merkeiksi ��.

![Virhe, joka johtuu BMP:n ulkopuolisten merkkien kopioinnista ja liittämisestä Overleafin editoreihin](/files/258fcdcde838dcb852d497bef8ce1b49017e2fac)

Merkillä � on Unicode-koodipiste FFFD ja sen virallinen nimi on REPLACEMENT CHARACTER, ja sitä käytetään “[korvaamaan tuntematon, tunnistamaton tai esittämätön merkki](https://en.wikipedia.org/wiki/Specials_\(Unicode_block\))”.

### Unicode-koodipisteiden (U+) käyttö LuaLaTeXissa

Unicode-dokumentaatio esittää koodipistearvot merkinnällä `U+<heksadesimaalinen arvo>`— kuten `U+1F600`, jossa `1F600` on `<heksadesimaalinen arvo>` Unicode-koodipisteen arvo 😀-emoji-merkille. Käyttääksesi näitä koodipistearvoja LuaLaTeXissa poistat merkin `U+` ja kirjoitat `\char"<heksadesimaalinen arvo>` tai `\Uchar"<heksadesimaalinen arvo>`. Se `"` merkki kertoo TeX-moottorille, että annettu luku on heksadesimaalinen. Esimerkiksi jos haluat käyttää 😀-emojia, kirjoittaisit `\char"1F600` tai `\Uchar"1F600`— käyttäen fonttia, joka pystyy latomaan sen.

Minimaalinen LuaLaTeX-esimerkki käyttäen `\char` ja `\Uchar` 😀-emoji-merkin latomiseen voisi olla:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont[Renderer=Harfbuzz]{NotoColorEmoji.ttf}
%Käytä \emojifontia ryhmässä, jotta sen vaikutus pysyy paikallisena
{\emojifont
\Uchar"1F600
\char"1F600}
\end{document}
```

[Avaa tämä LuaLaTeX-esimerkki Overleafissa](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)

**(valinnainen yksityiskohta) LuaTeX/LuaHBTeX: \char vs \Uchar**

Tavallisen `\char<merkkikoodi>` -komennon lisäksi tietyn `<merkkikoodin>`latomiseen nykyisellä fontilla LuaTeX-, LuaHBTeX- ja XeTeX-moottorit tarjoavat myös `\Uchar<merkkikoodi>` -komennon. Käyttäjän näkökulmasta `\char` ja `\Uchar` tulokset näyttävät samalta, mutta näiden komentojen toiminnassa on hienovarainen ero, kuten alla huomautamme.

**Keskeinen ero: laajeneminen**

`\Uchar` on niin sanottu [laajeneva komento](/latex/fi/syvalliset-artikkelit/22-how-does-expandafter-work-the-meaning-of-expansion.md#expansion-a-general-term-for-a-set-of-operations) kun taas `\char` ei ole laajeneva. Kun `\char<merkkikoodi>` tai `\Uchar<merkkikoodi>` komentoa “suoritetaan” — eli komentoa ei tallenneta osaksi makroa tai muuta merkkiluetteloa — TeX-moottorissa tapahtuu seuraavat vaiheet:

* **`\char<merkkikoodi>`** ohjeistaa TeX-moottoria lisäämään välittömästi merkkitokenin, joka edustaa `<merkkikoodin>`, siihen sisältöön, jota se parhaillaan lataa.
* Sitä vastoin **`\Uchar<merkkikoodi>`** sisältää kaksi erillistä käsittelyvaihetta:

1. Se `\Uchar<merkkikoodi>` -komento *laajennettu*ja `<merkkikoodin>` muunnetaan väliaikaiseksi merkkilistaksi, joka sisältää yhden [merkkitokeniksi](/latex/fi/syvalliset-artikkelit/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md#tex-tokens-101-28and-notions-of-expansion29) , joka edustaa `<merkkikoodin>`.
2. Tämä yhden merkin merkkilista on nyt *saatavilla* TeX-moottorille sen seuraavan syötteen lähteenä. Käytännössä TeX-moottori “siirtää tilapäisesti katseensa” käyttäen tätä yksittäistä merkkilistaa seuraavan syöte-elementtinsä (tokeninsa) sijaintina. Oletusarvoisesti TeX-moottori yksinkertaisesti palaa lukemaan tuon tokenin ja lataa vastaavan merkin, toistaen näin `\char` komento. **kuitenkin**, koska tuo `<merkkikoodin>` ei ladottu heti, vaan se *tallennetaan* (talletettiin) yhtenä tokenina, alkeis-TeX-komennot tai LaTeX-makrot voivat käyttää (imeä) tuota tokenia — sitä ei tarvitse latoa heti, vaan sitä voidaan käyttää jatkokäsittelyssä tarpeen mukaan.

Käytännössä `\char<merkkikoodi>` sanoo “lato tämä `<merkkikoodin>` nyt,” kun taas `\Uchar<merkkikoodi>` sisältää eräänlaisen “viivästetyn toiminnan” luomalla tallennetun merkkitokenin ja tekemällä sen saataville seuraavana syöte-elementtinä (tokenina). Tätä tokenia voidaan joko käyttää (imeä) TeX-komentojen ja makrojen toimesta tai TeX-moottori voi lukea sen uudelleen ja latoa sen.

### Unicode (koodaus) ei kerro koko tarinaa

Mahdollisuus käyttää emoji-merkkejä Unicode-koodatussa tekstissä on vain osa emojien menestystarinaa. Emojien käytön kasvu mahdollistui myös [OpenType-fonttiteknologian](https://learn.microsoft.com/en-us/typography/opentype/)kehityksen myötä — fontit, joiden glyfidata (merkkipiirrokset) voi sisältää [väritietoa](https://learn.microsoft.com/en-us/typography/opentype/spec/colr): niin sanottua [OpenType-värifontteja](#opentype-color-fonts).

Sopivien fonttien lisäksi värillisten emojien käyttö edellyttää myös lisäohjelmistokomponentteja, joiden tehtäviin kuuluvat:

* esikäsittely (“[shaping](#the-concept-of-text-shaping)”) Unicode-koodatulle tekstille, *sen valmisteleminen* näytettäväksi tietyn fontin avulla;
* *renderöinti ja näyttäminen* fontin värikkäistä emoji- *glyfeistä* laitteen näytölle.

#### Glyfi vs. merkki: eivätkö ne ole sama asia?

Termejä “glyfi” ja “merkki” käytetään usein ikään kuin ne olisivat keskenään vaihdettavia — viittaamassa samaan peruskäsitteeseen — mutta niiden merkityksessä on hienovarainen, vaikkakin tärkeä, ero.

Unicode [määrittelee termin “merkki”](http://www.unicode.org/glossary/#character) näin:

> “Kirjoitetun kielen pienin komponentti, jolla on semanttinen arvo; viittaa abstraktiin merkitykseen ja/tai muotoon eikä tiettyyn muotoon… ”

Sitä vastoin “glyfi” on *tietty* *muoto* (suunnitelma) yhden *visuaalisesta esityksestä* tietystä *merkkiä*.

Merkki- ja glyfiero on helposti havaittavissa, kun emoji-painotteista tekstiä tarkastellaan eri ohjelmistojärjestelmissä/alustoilla, kuten luettaessa samaa tekstiä iOS- tai Android-pohjaisella matkapuhelimella tai Windows-työpöytätietokoneella. Riippumatta siitä, mitä laitetta tai alustaa käytetään, taustalla oleva teksti (merkkijono) sisältäisi saman Unicode-koodatun *emoji* *merkkejä*. Laitekohtaiset ominaisuudet liittyvät *esikäsittelyyn* tuon tekstin *renderöintiin* ja *näyttö* tuloksista, ehkä laitekohtaisia fontteja käyttäen, mikä tuottaa eri glyfejä (merkkipiirroksia) samaa emoji-merkkiä edustamaan.

Unicoden [Full Emoji List](https://unicode.org/emoji/charts/full-emoji-list.html) tarjoaa esimerkkikuvia, jotka esittävät jokaista Unicode-emoji-merkkiä — osoittaen eri teknologia-alan toimittajien käyttämiä glyfejä. Fonttisuunnittelijat eivät ainoastaan omaksu omia erityisiä mallejaan (glyfejään) emoji-merkkien esittämiseen, vaan myös yksittäisten fonttien välillä on eroja siinä, kuinka monta emoji-merkkiä ne tukevat (joille niissä on glyfit), ja niissä voi olla tai olla olematta Unicode-emoji-määrittelyihin sisältyviä emojitekstin käsittelyn edistyneempiä ominaisuuksia.

Käsitys ja konsepti merkeistä, niiden semantiikasta ja koodauksesta muodostavat Unicode-maailman perustan: se käsittelee merkkejä. Yksittäisten merkkien suunnittelu ja visuaalinen esitys glyfeinä kuuluvat fonttiteknologioihin ja fonttisuunnittelun taitoon.

#### Unicode-emojit: paljon enemmän kuin tekstikoodausta

Unicoden keskeinen rooli on tarjota globaali koodausstandardi, joka määrittelee, mitä kokonaislukuarvoa, jota kutsutaan *koodipisteeksi,* tulisi käyttää kunkin merkin, myös emojien, esittämiseen Unicode-koodatussa tekstivirrassa.

Unicoden emoji-määrittely määrittelee myös *käsittelykäyttäytymisen* tietyille *merkkijonoja* emoji-merkkijonoille, jotka esiintyvät Unicode-koodatussa tekstivirrassa. Määritellyt emoji-merkkijonot voidaan “yhdistää” prosessilla, jota kutsutaan [tekstin muotoilu](#the-concept-of-text-shaping) , jolloin syntyy yksi tuloksena oleva (“koostettu”) emoji-glyfi — laitteen käyttöjärjestelmä käyttäisi tätä yhtä glyfiä edustamaan tekstissä olevaa alkuperäistä merkkijonoa.

Unicoden tekninen raportti aiheesta [Unicode Emoji](https://unicode.org/reports/tr51/) dokumentoi rikkaan joukon ominaisuuksia, jotka ovat ohjelmistojen käytettävissä, jos ne haluavat tarjota Unicode-yhteensopivaa emoji-merkkien käsittelyä. Esimerkiksi Unicode määrittelee (koodaa) merkkejä, joita kutsutaan [emoji-muuntimiksi](http://www.unicode.org/reports/tr51/#Emoji_Modifiers_Table) joita voidaan käyttää luomaan *muunnelmia* “perus”emoji-merkeistä, kuten muutoksia [ihonsävyyn Fitzpatrickin asteikon perusteella](http://www.unicode.org/reports/tr51/#Diversity). Huomaa, että perusemojimerkkien joukko ja sovellettavat muuntimet määritellään osana koko [Unicode-emojistandardia](http://www.unicode.org/reports/tr51).

Unicode-sivu [Emoji Sequences](http://unicode.org/emoji/charts/emoji-sequences.html) tarjoaa kaavion niistä sekvensseistä, jotka Unicode-määrittely tällä hetkellä tarjoaa. Vie hiiren osoitin minkä tahansa emoji-glyfikuvan päälle nähdäksesi pienen ponnahdusvinkin, joka kertoo taustalla olevan Unicode-emoji-merkkijonon, joka tuottaa kyseisen glyfin:

![EmojiSequenceChart.png](/files/4d8a4c1cad42ce7e682b36d8704989a5a5ed3014)

Esimerkiksi emoji-glyfi:

![HandMediumSkinTone.png](/files/d0cb95fa98072ba6a613f70421bd1a1af14da4cd)

luetellaan [muunninsekvenssien osiossa](http://unicode.org/emoji/charts/emoji-sequences.html#modifier_sequences) ja se tuotetaan kaksimerkkisellä sekvenssillä U+1F44B U+1F3FD. Nämä osamerkit ovat:

U+1F44B:![UnicodeWavingHandDefault.png](/files/d4e232c2b2d4e11d984746ea2aeb07a2993a2778) (HEILUTTAVA KÄSI)

U+1F3FD:![FitzPatrick3.png](/files/1b8220a3439b14ca32ac07653f136fdd63b7400d) (EMOJI-MUUNNIN FITZPATRICK TYYPPI 4)

**Ihonsävymuuntimien käyttäminen LuaHBTeX:ssa**

Seuraava esimerkki käyttää LuaHBTeX:ää havainnollistamaan emoji-muuntimien käyttöä:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont[Renderer=HarfBuzz,SizeFeatures={Size=20}]{NotoColorEmoji.ttf}
Erillinen heiluttava käsi: {\emojifont\Uchar"1F44B}\par
Erillinen muunnin: {\emojifont\Uchar"1F3FD}\par
Yhdistetty tulos: {\emojifont\Uchar"1F44B\Uchar"1F3FD}
\end{document}
```

[Avaa tämä LuaLaTeX-emojimuunninesimerkki Overleafissa](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)

Tämä esimerkki tuottaa seuraavan tulosteen:

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

#### UTF-8: sen rooli Unicode-tekstin tallentamisessa

Mikä tahansa teksti tai koodi, jonka kirjoitat tai liität Overleafin Code Editor -editoriin (tai Visual editoriin), tallennetaan UTF-8-muodossa, joten kertaamme lyhyesti, mitä UTF-8 oikeastaan tarkoittaa. UTF tulee sanoista Unicode Transformation Format, ja UTF-8:n roolia Unicode-koodatun tekstin tallentamisessa tai siirtämisessä kuvaa ilmaus “Transformation *Format*.”

Unicode-koodipistearvot vaihtelevat välillä 0–1 114 111, joten kaikkia Unicode-merkkien arvoja on mahdotonta esittää yhdellä 8-bittisellä tavulla, johon mahtuu vain 256 eri arvoa: 0–255. On kuitenkin mahdollista esittää mikä tahansa Unicode-koodipisteen kokonaisluku käyttämällä *peräkkäistä sarjaa* tavukokoisista arvoista — tämä on UTF-8:n periaate.

UFT-8 tarjoaa “reseptin” *muuntaa* (eli “koodata” tai “muuntaa”) Unicode-kokonaislukukoodipistearvo ainutlaatuiseksi 1–4 peräkkäisen tavukokoisen kokonaisluvun sarjaksi: tarvittavien peräkkäisten tavujen määrä riippuu koodipisteen arvosta. Tämän vuoksi saatat lukea UTF-8:n tallentavan Unicode-merkkejä *monitavuista sarjoina* koska yksi Unicode-merkki (koodipisteen kokonaisluku) esitetään UTF-8:ssa 1–4 peräkkäisen tavun sarjana.

Luonnollisesti UTF-8:aan tallennettu teksti voidaan muuntaa takaisin alkuperäiseksi Unicode-koodipisteiden kokonaislukusarjakseen — juuri tämä XeTeX:n tai LuaTeX/LuaHBTeX:n on tehtävä, kun ne lukevat UTF-8-muotoon tallennettua LaTeX-syötetiedostoa. Näiden TeX-moottorien täytyy tietää syötteen Unicode-koodipisteen (merkin) arvot ennen kuin ne voivat latoa tekstin. Huomaa, että pdfTeXissä ei ole sisäänrakennettua UTF-8-purkukykyä, joten sen täytyy turvautua TeX-makroihin UTF-8-muodossa olevan syötetekstin käsittelemiseksi (purkamiseksi).

**Joitakin UTF-8-esimerkkejä**

* Arabian kirjain ش (“sheen”) on Unicode-koodipiste 0634 heksadesimaalisena (kantaluku 16) tai 1588 desimaalisena (kantaluku 10). UTF-8:ssa ش esitetään kahtena (heksadesimaalisena) arvona D8 ja B4, joten merkki ش tallennettaisiin kahtena peräkkäisenä tavuna D8B4 UTF-8-koodatussa tekstissä.
* Emoji-merkki 😀 on Unicode-koodipiste 1F600 heksadesimaalisena (kantaluku 16) tai 128512 desimaalisena (kantaluku 10). UTF-8:ssa 😀 esitetään neljänä (heksadesimaalisena) arvona F0, 9F, 98 ja 80, joten merkki 😀 tallennettaisiin neljänä peräkkäisenä tavuna F09F9880 UTF-8-tekstitiedostossa.

#### Unicode-pohjaisen emoji-tekstinkäsittelyn erikoismerkit

Kaikkia Unicodeen koodattuja merkkejä ei ole tarkoitettu visuaaliseen esittämiseen fontin glyfien avulla: jotkin koodatut merkit on määritelty *ei-tulostuviksi merkeiksi* joiden tarkoitus on auttaa erikoistuneissa tekstinkäsittelytoiminnoissa (tukevassa ohjelmistossa). Eri ohjelmistosovellukset tukevat vaihtelevasti Unicodeen koodattuja ei-tulostuvia merkkejä, joten lopputulos riippuu käytetystä ohjelmisto-ympäristöstä — sovelluksista ja fonteista.

**Kaksi ei-tulostuvaa merkkiä, jotka on hyvä tuntea**

* **Nollaleveä liitinmerkki (ZWJ)**, koodipiste 200D (heksadesimaalisena), on nimensä mukaisesti suunniteltu käynnistämään syötemerkkien “liittymiskäyttäytyminen” — mutta vain jos näillä syötemerkeillä *on* määritelty liittymiskäyttäytyminen.
* **Nollaleveä erottava merkki (ZWNJ)**, koodipiste 200C (heksadesimaalisena), on suunniteltu estämään syötemerkkien mahdollinen “liittymiskäyttäytyminen”. Esimerkiksi ZWNJ:tä voidaan käyttää estämään peräkkäisten arabian merkkien liittymiskäyttäytyminen, joka normaalisti käsiteltäisiin (muotoiltaisiin) niiden liittyviin muotoihin. *estää* Unicode on julkaissut luettelon

suositelluista emoji-ZWJ-sekvensseistä [, jotka käyttävät U+200D ZERO WIDTH JOINER (ZWJ) -merkkiä yhdistääkseen emoji-merkkisekvenssejä yhdeksi koostetuksi emoji-glyfiksi — jos se on käytettävissä käytetyissä fonteissa.](https://unicode.org/emoji/charts/emoji-zwj-sequences.html) Esimerkki nollaleveän erottavan merkin käytöstä

**Seuraava minimaalinen koodinpätkä käyttää TeX Liveen sisältyvää Scheherazade OpenType -fonttia määrittämään LaTeX-fontin nimeltä**

The following minimal code fragment uses the Scheherazade OpenType font, included in TeX Live, to define a LaTeX font called `\arabicfont` jota voimme käyttää joidenkin arabian tekstien latomiseen. Rivi

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

käyttää nollaleveää erottavaa merkkiä komennon `\Uchar"200C`kautta estämään kahden arabian kirjaimen ل (lam) ja ا (alef) normaalin liittymiskäyttäytymisen. Huomaa komennon `\textdir TRT` käyttö tekstisuunnan asettamiseen oikealta vasemmalle:

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

[Avaa tämä LuaLaTeX-esimerkki Overleafissa](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)

Tämä esimerkki tuottaa seuraavan tulosteen:

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

## Tekstin muotoilun käsite

Aloitetaan visuaalisella esimerkillä käyttäen urdunkielistä käännöstä sanasta “educational”. Urdun käännösteksti saatetaan kirjoittaa näppäimistöllä tai kosketusnäytöllä, ja se muodostuisi yksinkertaiseksi, lineaariseksi Unicode-arabian merkkien sarjaksi. Kun teksti kuitenkin ladataan tai näytetään laitteen ruudulla [nastaliq-tyylillä](https://en.wikipedia.org/wiki/Nastaliq), tuloksena on monimutkainen kaksiulotteinen glyfien asettelu.

Urdu-esimerkissämme seuraava kuva vertailee Unicode-arabian lineaarista syöttöä *merkkejä* Nastaliq-tyyliin ladottuun tulokseen, joka koostuu *glyfeistä* olevista kaksiulotteisista [Awami Nastaliq](https://software.sil.org/awami/download/):

![](/files/bee23db76f99d3139f72d2c8afc1ebe962226170)

Syötemerkkien “kääntämistä” oikein sijoitetuiksi lähtöglyfeiksi kutsutaan *tekstin muotoilu*, ja se on olennainen osa tekstin käsittelyä ennen sen näyttämistä tai ladontaa. Esimerkissämme käytettiin urdunkielistä tekstiä (arabialaista kirjoitusjärjestelmää), koska muotoilun tulos näkyy siinä selvästi, toisin kuin latinalaista kirjoitusjärjestelmää käyttävissä kielissä, kuten englannissa, joissa muotoilu on paljon vähemmän korostunutta — esimerkiksi yksinkertaisten ligatuurien muodostamisessa.

Tekstin muotoilu on olennaista käytettäessä kirjoitusjärjestelmiä kuten [Arabia](https://en.wikipedia.org/wiki/Arabic), [heprea](https://en.wikipedia.org/wiki/Hebrew_language), [Devanagari](https://en.wikipedia.org/wiki/Devanagari) tai [malajalam](https://en.wikipedia.org/wiki/Malayalam), vain neljä esimerkkiä niin sanotuista *monimutkaisista kirjoitusjärjestelmistä*. Jotta näiden kirjoitusjärjestelmien ja niitä käyttävien kielten teksti esitetään oikein, muotoiluprosessin on käsiteltävä huolellisesti kyseisessä kirjoitusjärjestelmä- ja kieliyhdistelmässä esiintyvät muotoilusäännöt ja vivahteet. Esimerkiksi jotkin kielet vaativat useita syötemerkkejä tietyn lähtöglyfin muodostamiseksi, tai diakriittisten merkkien huolelliseen sijoitteluun voi liittyä monimutkaisia vaatimuksia, sekä glyfien välisiä uudelleenjärjestelyjä, jotta yksittäiset glyfit sijoittuvat oikein suhteessa toisiinsa.

Yleisesti ottaen tekstinpalan muotoilu edellyttää useita tietoja:

* Kirjoitusjärjestelmä tai *kirjoitusjärjestelmälle* jolla teksti on kirjoitettu.
* Tietty *kielelle* käytössä oleva. Yksittäisiä kirjoitusjärjestelmiä voidaan käyttää useilla kielillä, ja kullakin kirjoitusjärjestelmän ja kielen yhdistelmällä on omat tekstinmuotoilun hienovaraisuutensa/erityispiirteensä.
* Kirjoitus *suunta* tekstin — esimerkiksi oikealta vasemmalle tai vasemmalta oikealle.
* Yksi *fontin* joka tarjoaa muotoillun tekstin esittämiseen tarvittavat glyfit ja voi lisäksi sisältää tekstinmuotoiluprosessia ohjaavia ”muotoilusääntöjä”.

Tekstin muotoilun vaatimukset, erityisesti monimutkaisten kirjoitusjärjestelmien ja niihin liittyvien kielten osalta, voivat olla erittäin yksityiskohtaisia ja vivahteikkaita, mikä osoittaa tarpeen erikoisohjelmistolle, joka voi soveltaa mahdollisesti hyvin monimutkaisia tekstinmuotoilu-”sääntöjä”. Ei ole yllättävää, että tällainen ohjelmisto on olemassa, ja sitä kutsutaan nimellä *tekstinmuotoilumoottori*; käsittelemämme moottori on nimeltään [Harfbuzz](https://en.wikipedia.org/wiki/HarfBuzz), jonka dokumentaatioon kannattaa tutustua — esimerkiksi [Miksi tarvitsen muotoilumoottorin?](https://harfbuzz.github.io/why-do-i-need-a-shaping-engine.html).

**Lisälukemista tekstinmuotoilusta**

Näitä lyhyitä johdantoja suositellaan lämpimästi:

* [Mitä tekstinmuotoilu on?](https://harfbuzz.github.io/what-is-harfbuzz.html#what-is-text-shaping)
* [Miksi tarvitsen muotoilumoottorin?](https://harfbuzz.github.io/why-do-i-need-a-shaping-engine.html)

**TeXninen huomautus: useita muotoiluteknologioita (malleja)**

HarfBuzz-tekstinmuotoilumoottori tukee useita ”muotoiluteknologioita”, jotka eroavat siinä, miten ne toteuttavat muotoiluprosessin — kutakin toteutusta kutsutaan nimellä *muotoilija*, myös `luaotfload` -dokumentaatiossa. Tämän artikkelin pääaihe on OpenType-muotoilu, mutta vaihtoehtoinen, vapaasti käytettävä teknologia on [Graphite](https://scripts.sil.org/cms/scripts/page.php?site_id=projects\&item_id=graphite_aboutOT), jonka on kehittänyt [SIL International](https://www.sil.org/). Toinen HarfBuzziä tukeva muotoilumalli on [Apple Advanced Typography (AAT)](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6AATIntro.html)— AAT:tä tukevia fontteja käytetään yleensä Applen teknologia-alustoilla.

**Esimerkki Graphite-muotoilijaa käyttäen**

Seuraava esimerkki ladottaa urdunkielistä tekstiä fontilla nimeltä [Awami Nastaliq](https://software.sil.org/awami/download/), joka tukee Graphite-muotoilua ja on saatavilla Overleafissa. Awami Nastaliqin on luonut [SIL International](https://www.sil.org/), Graphite-teknologian kehittämisestä vastaava organisaatio.

Seuraava esimerkki havainnollistaa Graphite-pohjaisten fonttien edistynyttä muotoilukykyä — huomaa, miten `luaotfload` fonttimäärittely valitsee Graphite-muotoilun käyttämällä `shaper=graphite2`.

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

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

\vskip 75bp

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

[Avaa tämä esimerkki Overleafissa.](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)

Tämä esimerkki tuottaa seuraavan tulosteen:

![](/files/182402229f8c050b3f157c4b1c2227ce253bfaf6)

#### Emojit ja tekstinmuotoilu

Tekstinmuotoilua on esitelty käyttämällä esimerkkejä monimutkaisen kirjoitusjärjestelmän kielestä, urdusta. Saattaa kuitenkin olla yllätys, että oikeiden emojiglyfien hahmontaminen edellyttää tekstinmuotoilun soveltamista Unicode-tekstiin, joka sisältää emoji-merkkijonoja —[kuten HarfBuzzin pääkehittäjä toteaa](https://github.com/harfbuzz/harfbuzz/issues/2428#issuecomment-639108677):

> ... emojien muotoilu HarfBuzzilla kuuluu täysin soveltamisalaan ja on itse asiassa välttämätöntä perhe-emojien, ihonvärin jne. tuottamiseksi.

Tarkastelemme tästä esimerkkejä.

### Vastuunjako: tekstinmuotoilumoottori + OpenType-fontit

Käytännössä tekstinmuotoilu on ”yhteisoperaatio” eli työnjako tekstinmuotoilumoottoriin sisäänrakennetun logiikan ja sääntöjen sekä käytettävään fonttiin tai fontteihin sisäänrakennettujen lisämuotoilusääntöjen ja -datan välillä — tästä eteenpäin käsittelemme OpenType-pohjaista muotoilua *ainoastaan*.

Muotoilua varten tekstinmuotoilumoottorille annetaan tyypillisesti Unicode-tekstiä, määritetty kirjoitusjärjestelmä ja kieli, mahdollisesti kirjoitussuunta ja mikä tärkeintä muotoiluprosessissa käytettävä OpenType-fontti — fontti tuottaa tuloksen: joukon glyfejä ja sijoitteludataa. Pyydettäessä muotoilumoottori voi soveltaa lisäsääntöjä ([OpenType-ominaisuudet](https://en.wikipedia.org/wiki/List_of_typographic_features#OpenType_typographic_features)) käytettävästä OpenType-fontista — sovellettavat säännöt ovat yleensä käyttäjän valittavissa fontin tukemien ominaisuuksien luettelosta.

Muotoiluprosessin tuloksena on *glyfiluettelo* jotka sisältyvät OpenType-fonttiin, sekä *glyfien välinen* sijoitteludata. Sijoitteludata koskee *muotoiltujen glyfien suhteellista sijoittelua*; se ei tarkoita absoluuttista sijoittelua ladotulla sivulla tai muussa mediassa/sisällössä, kuten verkkosivulla, tweetissä jne. Hahmonnusohjelmisto (ladontamoottori, selain jne.) käyttää glyfien välistä sijoittelutietoa varmistaakseen, että glyfit sijoitetaan oikein suhteessa toisiinsa, kun ne on koottu ja sisällytetty lopulliseen tulosteeseen.

#### Mikä on glyfiluettelo?

Sisäisesti jokaiselle OpenType-fontin glyfille annetaan numeerinen tunniste, kokonaislukuarvo nimeltä glyfi-indeksi — jota kutsutaan myös glyfitunnisteeksi eli GID:ksi. Muotoilutehtävänsä suoritettuaan tekstinmuotoilumoottori palauttaa tuloksensa muodossa *glyfitunnisteiden luettelo* sekä *sijoitteludata* näille glyfeille.

OpenType-fonttien yksittäisille glyfeille annetaan indeksit (tunnisteet) fontin luojan toimesta, joten arvo on hyvin fonttikohtainen ja mielivaltainen — se voi myös vaihdella tietyn fontin eri versioiden välillä. Älä koskaan oleta, että sama GID-arvo pätee eri fonttien ”samankaltaisiin” glyfeihin; se ei lähes varmasti päde. Jos sinulla on muotoilumoottorin antama glyfitunnisteiden luettelo, voit käyttää niitä vain niiden glyfien käyttämiseen siinä fontissa, josta ne on saatu.

#### Mitä OpenType-fontit ovat?

Verkko on *tulvillaan* OpenType-fonttien selityksiä ja yksityiskohtia, joten rajoitumme lyhyeen kuvaukseen.  [OpenType-määritys](https://docs.microsoft.com/en-us/typography/opentype/spec/) on kehittäjille suunniteltu monimutkainen asiakirja, mutta pohjimmiltaan se määrittelee fonttidatan tiedostomuodon eli säilön. OpenType-fontti sisältää dataa, joka kuvaa glyfien muodot, sekä tietoja tuetuista kirjoitusjärjestelmistä ja kielistä, fontin metatietoja ja erilaisia ”tauluja”, jotka määrittelevät [typografiset ominaisuudet](https://en.wikipedia.org/wiki/List_of_typographic_features#OpenType_typographic_features) joita fontti tukee.

Tekstinmuotoilumoottoria voidaan yleensä ohjeistaa soveltamaan fontin ominaisuuksia valikoivasti muotoiluprosessin aikana ja käyttämään tiettyjä typografisia tehosteita (”sääntöjä”), jotka valitsevat fonttiin sisältyvän sopivan glyfijoukon. Valitun fontin on tuettava kaikkia ominaisuuksia, joita tekstinmuotoilumoottoria pyydetään soveltamaan, ja tarjottava niiden glyfit.

#### Koodatut ja koodaamattomat ”glyfit”

OpenType-fontit sisältävät datataulun nimeltä [cmap](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap) (Character to Glyph Index Mapping), joka yhdistää fontin tukeman Unicode-merkkijoukon kyseisen fontin vastaaviin glyfi-indekseihin. Seuraava video tarjoaa lyhyen katsauksen cmap-tauluun fontissa nimeltä `lmmono10-regiular.otf` (sisältyy TeX Liveen).

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

Fontit sisältävät kuitenkin tyypillisesti monia glyfejä, jotka eivät esitä tiettyä Unicode-merkkiä eivätkä sisälly cmap-tauluun. Näin ollen OpenType-fontissa olevat glyfit voidaan jakaa kahteen pääjoukkoon:

* koodatut glyfit, jotka esittävät Unicode-merkkejä;
* koodaamattomat glyfit, jotka eivät esitä Unicode-merkkejä.

Koodattuihin glyfeihin pääsee sisällyttämällä tekstiin asianmukaisen Unicode-merkin — mutta entä koodaamattomat glyfit, miten niitä käytetään tai käytetäänkö niitä? Näitä glyfejä käytetään tyypillisesti tekstinmuotoiluoperaatioiden tulosteena, mukaan lukien fonttiominaisuuksien soveltaminen tiettyjen visuaalisten/typografisten tehosteiden tuottamiseksi.

### OpenType-värifontteja

Emoji-merkkien odotetaan näkyvän täysvärisinä — mustavalkoiset emojit eivät aivan tarjoa ”täyttä emoji-kokemusta”. Unicode-standardin koodatessa emoji-merkit alun perin [OpenType-fonttimäärityksessä](https://docs.microsoft.com/en-us/typography/opentype/spec/) ei kuitenkaan ollut sopivaa tapaa upottaa *colorful*-glyfidataa OpenType-fontteihin. Tämä OpenTypen ”aukko” sai johtavat teknologia- ja alustatoimittajat etsimään ratkaisuja, ja seurannut ”kilpailu” johti [erilaisiin ehdotuksiin OpenTypen laajentamiseksi](https://www.fontlab.com/news/color-font-format-proposals/) tukemaan OpenType-värifontteja — ei vain värillisten emoji-merkkien (glyfien) näyttämiseen, vaan minkä tahansa glyfin hahmontamiseen värillisenä.

#### Neljä OpenType-värifontin tyyppiä

[Adobe, Microsoft, Google ja Apple jättivät kukin ehdotuksia](https://www.fontlab.com/news/color-font-format-proposals/) OpenTypen laajentamiseksi täysväristen OpenType-fonttien tukemiseen, ja lopulta neljä ehdotusta hyväksyttiin ja sisällytettiin viralliseen OpenType-määritykseen. Kätevyyden vuoksi voimme jakaa nämä neljä muunnelmaa karkeasti vektori- ja rasteripohjaisiin — mutta kuten tässä [GitHub-repositoriosta](https://github.com/simoncozens/test-fonts)esitetään, OpenType-määritys on riittävän joustava tukemaan OpenType-värifonttitiedostoja, joissa yhdistetään nämä neljä perusteknologiaa.

* **Vektoripohjaiset OpenType-fontit:**
* **Microsoft**: glyfien muodot kuvataan kerrostettujen värivektorien muodossa ([COLR](https://docs.microsoft.com/en-us/typography/opentype/spec/colr) ja [CPAL](https://docs.microsoft.com/en-us/typography/opentype/spec/cpal) -taulut).
* [**Adobe ja Mozilla**](https://www.w3.org/2013/10/SVG_in_OpenType/) ([SVG-taulu](https://docs.microsoft.com/en-us/typography/opentype/spec/svg)): glyfien muodot piirretään SVG:llä, joka tukee vektoreista rakennettuja glyfejä *ja rasterikuvia*. Katso myös [Adoben SVG-fonttien käyttöopas](https://helpx.adobe.com/fonts/user-guide.html/fonts/using/ot-svg-color-fonts.ug.html).
* **Rasteripohjaiset OpenType-fontit:**
* **Google**: glyfit esitetään fonttiin upotettuina värillisinä PNG-kuvina ([CBDT](https://docs.microsoft.com/en-us/typography/opentype/spec/cbdt) ja [CBLC](https://docs.microsoft.com/en-us/typography/opentype/spec/cblc) -taulut).
* **Apple**: glyfit esitetään myös fonttiin upotettuina värikuvina. PNG:n lisäksi Applen mekanismi ([sbix-taulu](https://docs.microsoft.com/en-us/typography/opentype/spec/colr)) tukee myös JPEG- ja TIFF-muotoja.

Tästä seuraa, että OpenType-värifontteja tukevien käyttöjärjestelmien ja sovellusohjelmistojen on käsiteltävä nykyistä sekateknologista ympäristöä. Lisäksi on hyvä tietää, että yksittäiset OpenType-värifontit — ja *versiot* samasta fontista — voivat:

* kattaa eri laajuudessa koko [Unicode-emoji-merkkien](https://unicode.org/emoji/charts/emoji-list.html)joukon — eli sen, kuinka monelle emoji-merkille fontti tarjoaa glyfit;
* käyttää erilaisia glyfimalleja yksittäisten emoji-merkkien esittämiseen;
* vaihdella siinä, mitä ominaisuuksia ne tarjoavat Unicode-standardien edistyneempien käyttötapojen tukemiseen, kuten [emoji-muuntimiksi](https://unicode.org/reports/tr51/#Emoji_Modifiers_Table), sekä muissa emojitekstin käsittelyominaisuuksissa, jotka kuvataan julkaisussa [Unicode Technical Standard #51: Unicode Emoji](https://unicode.org/reports/tr51/).

#### Kuhina HarfBuzzin ympärillä

Olemme viitanneet tarpeeseen *tekstinmuotoilumoottori*: ohjelmisto, joka ottaa syötteenä Unicode-tekstiä, joka on kirjoitettu tietyllä kirjoitusjärjestelmän ja kielen yhdistelmällä, ja muotoilee tämän tekstin määrättyä fonttia käyttäen glyfijonoksi sekä sijoitteludataksi, jota voidaan käyttää alkuperäisen syöteteksin latomiseen.

[HarfBuzz](https://harfbuzz.github.io/) on yksi tällainen tekstinmuotoilumoottori: se on [avoimen lähdekoodin kirjasto](https://github.com/harfbuzz/harfbuzz) ja yli vuosikymmenen tutkimus- ja kehitystyön tulos — ja sitä kehitetään edelleen aktiivisesti sekä otetaan käyttöön osana monia ohjelmistotuotteita. HarfBuzz ei itse suorita ”ladontaa”, vaan tarjoaa ”tekstinmuotoilupalveluja” ohjelmistoille, jotka integroivat sen, mukaan lukien XeTeX, LuaHBTeX, [Adobe PhotoShop ja Adobe InDesign](https://en.wikipedia.org/wiki/HarfBuzz).

Integroimalla HarfBuzzin TeX-moottorit voivat hyödyntää sen edistyneitä tekstinmuotoiluominaisuuksia erittäin kehittyneeseen monikieliseen ladontaan, erityisesti monimutkaisille kirjoitusjärjestelmille, kuten arabialle, heprealle, devanagarille ja monille muille. Huomaa myös, että HarfBuzza käytetään Unicode-emojitekstimerkkien käsittelyyn ja muotoiluun, mitä tarkastelemme yksityiskohtaisemmin.

Seuraava kaavio tiivistää HarfBuzzin roolin, kun se on integroitu ohjelmistoon, kuten XeTeXiin tai LuaHBTeXiin, ladottaessa monimutkaisen kirjoitusjärjestelmän tekstiä, kuten arabiaa:

![Yleiskatsaus arabian tekstin muotoiluun HarfBuzzilla](/files/8e6f30ee2b598613dc7cde22634cfa5e642951aa)

**HarfBuzziin tutustuminen**

Jokainen, joka haluaa oppia lisää HarfBuzzista ja sen XeTeXille ja LuaHBTeXille tarjoamista OpenType-muotoilupalveluista, voi [ladata HarfBuzzin binäärijakelun](https://github.com/harfbuzz/harfbuzz/releases) joka sisältää HarfBuzz-kirjaston (ohjelmoijille) ja komentorivityökalut `hb-view` ja `hb-shape`.

**Esimerkki: hb-view:n käyttö**

Luo uusi tiedosto suosikki-UTF-8-tekstieditorissasi ja kopioi/liitä seuraavat kuusi emoji-merkkiä 👋👋🏻👋🏼👋🏽👋🏾👋🏿 tähän tekstitiedostoon. Tallenna se sitten UTF-8-muodossa esimerkiksi nimellä `emoji.txt`.

Huomaa, että tekstieditorisi voi näyttää emojien (varaversioina) mustavalkoiset versiot, koska se ei kykene (ei ole ohjelmoitu) hahmontamaan väriglyfejä. Kun nämä 6 emojia on tallennettu, tiedoston `emoji.txt` tulisi sisältää UTF-8-dataa seuraavalle Unicode-emoji-merkkien sarjalle — olemme erottaneet emoji-muokkaimet pilkuilla *vain luettavuuden helpottamiseksi*:

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

Yhteensä pitäisi olla **11** Unicode-merkkiä, joista kukin tuottaa 4 tavua UTF-8-dataa, joten tuloksena olevan `emoji.txt` tiedoston tulisi olla 44 tavua pitkä, lukuun ottamatta emoji-rivin lopussa käytettäviä rivinvaihtomerkkejä.

Se `hb-view` työkalu voi käyttää tiedostoa `emoji.txt`, yhdessä valitsemasi sopivan OpenType-värifontin, kuten `NotoColorEmoji.ttf`, kanssa HarfBuzzin muotoillusta tulosteesta SVG-tiedoston luomiseen. Seuraava komentoriviesimerkki, joka on **kirjoitettava yhdelle riville** päätteessäsi, luo SVG-tiedoston `emoji.svg`:

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

Onnistuneen suorittamisen jälkeen tiedosto `emoji.svg`, jonka on luonut `hb-view`, voidaan avata Inkscapella, ja sen pitäisi näyttää jotakuinkin tältä:

![Hbvieemoji.png](/files/56de07aa46fc1829facfea0e680ce928a5247790)

`hb-view` voidaan käyttää HarfBuzz-muotoilun tutkimiseen millä tahansa sopivalla Unicode-tekstitiedostolla ja OpenType-fontilla — se ei todellakaan rajoitu emojien käyttöön! Kirjoita

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

nähdäksesi tämän tehokkaan ja kätevän työkalun runsaat komentorivivalinnat. Iloisia muotoiluhetkiä!

## Tekstinmuotoilu ja TeX-moottorit

Tässä tarkastelemme XeTeXin ja LuaTeX-perheen TeX-moottorien tekstinmuotoiluominaisuuksia.

### XeTeX

XeTeX kehitettiin 2000-luvun alussa, ja se oli edelläkävijä useissa TeX-pohjaisen ladonnan innovaatioissa, erityisesti *sisäänrakennetussa* tuessa seuraaville:

* Unicode-tekstin lukeminen UTF-8-muodossa;
* OpenType-fonttien käyttäminen;
* tekstinmuotoilu monikielistä ladontaa varten;
* OpenType-pohjainen matemaattinen ladonta.

XeTeXin kyky latoa monimutkaisten kirjoitusjärjestelmien kieliä helposti ja kätevästi johtuu sen sisäänrakennetuista tekstinmuotoiluominaisuuksista — jotka perustuivat alun perin nykyisin vanhentuneeseen [ICU LayoutEngineen](http://userguide.icu-project.org/layoutengine). Khaled Hosnyn työn ansiosta XeTeX siirtyi käyttämään HarfBuzza tekstinmuotoiluun, kuten ilmoituksessa [maaliskuulta 2013](https://tug.org/pipermail/xetex/2013-March/024118.html)todetaan. Monikielistä tekstiä latoville XeTeX mainitaan yleensä ensisijaisena TeX-moottorina — mutta nyt on toinenkin vaihtoehto, LuaHBTeX, jota tutkimme.

### LuaTeX ja LuaHBTeX

LuaTeXin kehitys alkoi noin vuonna 2005, mutta sen suunnittelufilosofia oli varsin erilainen kuin XeTeXin, joka sisällytti uusia ominaisuuksia *suoraan* XeTeX-ohjelmistoon. Toisin kuin XeTeX, LuaTeXin kehittäjät päättivät ”...tarjota minimaalisen joukon työkaluja mutta ei ratkaisuja.” (katso [LuaTeXin viitekäsikirja](https://www.pragma-ade.com/general/manuals/luatex.pdf)). Lisäominaisuuksien kokonaisuuden tarjoamisen sijasta *sisäänrakennettuna* LuaTeX-pohjaisiin moottoreihin LuaTeX-moottorien sisäiset mekanismit avataan, jotta kehittäjät ja taitavat käyttäjät voivat hyödyntää integroitua Lua-komentosarjakieltä omien ratkaisujensa rakentamiseen.

Esimerkiksi XeTeXistä poiketen LuaTeX-moottori ei voi *suoraan* käyttää OpenType-fontteja; sen sijaan OpenType-fontit on ladattava ja ”valmisteltava käyttöön” Lua-koodilla kirjoitettujen fontinlatausfunktioiden avulla. Näitä fontinlatausfunktioita kutsutaan *takaisinkutsu-* funktioiksi: Lua-koodiksi, jota LuaTeX kutsuu (”suorittaa”), kun pyydetään fontin lataamista.

Lisäksi LuaTeX-moottori ei tarjoa mitään *sisäänrakennetussa* tekstinmuotoiluominaisuuksia — nekin on tarjottava ulkoisella koodilla, jota LuaTeX-moottori voi kutsua saadakseen tekstinmuotoilupalveluja. Tämäkin eroaa XeTeX-moottorista, jossa tekstinmuotoiluominaisuudet sisältyvät ydinohjelmistoon.

#### luaotfload: välttämätön OpenType-fonttien käyttämiseen LuaTeXissä/LuaHBTeXissä

LuaTeXin fontinlatauksen takaisinkutsumekanismi tarjoaa paljon joustavuutta, joskin lisäohjelmoinnin ”kustannuksella”. LuaLaTeXin käyttäjien onneksi TeX-yhteisö on kehittänyt paketin nimeltä `luaotfload`, joka on osa [TeX Liven vuosittaista julkaisua](https://www.tug.org/texlive/) ja on tietenkin Overleaf-käyttäjien saatavilla.

`luaotfload` on [saatavilla CTANissa](https://ctan.org/pkg/luaotfload?lang=en) ja sillä on [kehitysarkisto GitHubissa](https://github.com/latex3/luaotfload) jossa voit seurata uusinta kehitystä ja [uusia julkaisuja](https://github.com/latex3/luaotfload/releases).

`luaotfload` voidaan ladata suoraan LaTeX-asiakirjan esittelyosaan komennolla

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

Huomaa, että `luaotfload` on LaTeX- *paketti*nimi, mikä tarkoittaa, että sen tiedostonimi on `luaotfload.sty`. Jos haluaisit käyttää `luaotfload` plain TeXin kanssa, voit tehdä sen lisäämällä rivin

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

plain TeX -asiakirjaasi.

Tavallisesti LuaLaTeXin käyttäjien — eli niiden, jotka latovat LaTeXia LuaTeXillä/LuaHBTeXillä — ei tarvitse olla suoraan tekemisissä `luaotfload` koska [`fontspec` paketti](https://ctan.org/pkg/fontspec) lataa `luaotfload` -paketin puolestasi ja huolehtii monista matalan tason yksityiskohdista sen tarjoamien käyttäjätason komentojen avulla `fontspec` pakettiin.

### LuaHBTeX: uusia vaihtoehtoja tekstinmuotoiluun

`luaotfload` on kypsä ja tehokas Lua-kirjasto, joka tarjoaa LuaTeXin OpenType-fonttien käsittelyn — sekä tekstinmuotoilupalvelut monille kielille ja kirjoitusjärjestelmille. Alun perin tekstinmuotoilufunktiot `luaotfload` toteutettiin puhtaalla Lua-koodilla, mutta TeX Live 2020:n julkaisu toi toisen yleisen vaihtoehdon tekstinmuotoiluun — uuden LuaTeX-pohjaisen moottorin nimeltä LuaHBTeX.

LuaHBTeXin ”HB” tarkoittaa HarfBuzza — pohjimmiltaan LuaHBTeX on alkuperäinen LuaTeX-moottori, johon on lisätty *sekä* integroitu HarfBuzz-tekstinmuotoilumoottori. LuaTeXin suunnittelufilosofian mukaisesti HarfBuzzin saatavuus ei *automaattisesti* takaa, että LuaHBTeX muotoilee tekstin: HarfBuzz on toinen työkalu, jolla voidaan rakentaa tekstinmuotoiluratkaisuja.

LuaHBTeXin HarfBuzz-integraatio on [ohjelmoitavissa Lua-koodilla](#introduction-to-the-luahbtex-harfbuzz-api), minkä ansiosta `luaotfload`:n kehittäjät ovat voineet lisätä HarfBuzz-pohjaisia tekstinmuotoiluratkaisuja. Näin ollen [versiosta 3.1 alkaen, joka julkaistiin 5. marraskuuta 2019](https://github.com/latex3/luaotfload/releases/tag/v3.1), `luaotfload` parannettiin hyödyntämään HarfBuzza, jolloin HarfBuzzin tekstinmuotoiluominaisuudet ovat helposti tavallisen käyttäjän käytettävissä.

Lukijat, joita kiinnostavat HarfBuzzin LuaTeX-integraation tekniset yksityiskohdat, voivat lukea tämän [Khaled Hosnyn artikkelin](https://www.tug.org/TUGboat/tb40-1/tb124hosny-harfbuzz.pdf).

### luaotfload: kaksi tekstinmuotoiluvaihtoehtoa (milloin HarfBuzza käytetään?)

LuaLaTeXin käyttäjillä on nyt kaksi vaihtoehtoa tekstinmuotoiluun:

* `luaotfload`:n alkuperäinen (solmupohjainen) tekstinmuotoilutoteutus, joka on kirjoitettu kokonaan Lualla;
* `luaotfload`:n HarfBuzz-pohjainen muotoilu, jota käytetään Lua-koodilla, joka kutsuu HarfBuzzin tekstinmuotoilufunktioita.

`luaotfload` tarjoaa pääsyn näihin kahteen muotoilujärjestelmään ”`mode`”-parametrinsa kautta — useimmat käyttäjät käyttävät kuitenkin vastaavaa `fontspec` “`Renderer`”-valintaa sen sijaan, että käyttäisivät suoraan matalamman tason funktioita `luaotfload`.

Kummallakin `luaotfload`:n tekstinmuotoiluratkaisulla on vahvuutensa ja (nykyiset) heikkoutensa, mutta kumpaa kannattaa käyttää ja milloin? Tässä on joitakin huomioitavia seikkoja:

* `luaotfload`:n natiivi solmupohjainen käsittely voi kuluttaa paljon muistia, erityisesti suurilla CJK OpenType -fonteilla. HarfBuzzin käyttö CJK-tekstin muotoiluun voi parantaa nopeutta ja vähentää muistinkäyttöä.
* Käytä HarfBuzza monimutkaisille kirjoitusjärjestelmille, koska se ”...parantaa huomattavasti indialaisten ja arabialaisten kirjoitusjärjestelmien hahmonnusta ja sitä suositellaan vahvasti tällaisille kirjoitusjärjestelmille.” (katso `luaotfload` -käsikirja).
* HarfBuzzin integrointi `luaotfload` :iin on edelleen suhteellisen uusi ja sitä kehitetään yhä edelleen. Kirjoitushetkellä (heinäkuu 2021) on suositeltavaa käyttää luaotfloadin sisäänrakennettua muotoilua (asetus `mode=node`) asiakirjasi pääfonteille, erityisesti jos asiakirjasi käyttää latinalaista kirjoitusjärjestelmää. Katso tämä [GitHub-issue](https://github.com/latex3/luaotfload/issues/175#issue-801120377), joka tiivistää ongelmat ja keskustelut. Jos haluat kokeilla, voit käyttää `luaotfload` fonttitiedoston lataamiseen ja kahden LaTeX-fontin luomiseen: toinen käyttää HarfBuzz-pohjaista muotoilua ja toinen Lua-pohjaista muotoilua. Overleaf loi [esimerkkiprojektin](#sample-project-arabic-shaping), joka havainnollistaa tätä.
* Älä käytä HarfBuzza matemaattisten fonttien käsittelyyn. Kuten tex.stackexchangen kehittäjät toteavat, HarfBuzzia ei ole [suunniteltu käsittelemään matemaattiseen ladontaan tarkoitettuja fontteja](https://tex.stackexchange.com/questions/544881/does-luahbtex-with-harfbuzz-renderer-completely-supports-math-formating) joten älä käytä sitä tähän tarkoitukseen.

**Esimerkkiprojekti: arabian muotoilu**

Tässä on Overleaf-projekti, joka käyttää useita korkealaatuisia arabialaisia kirjasintyyppejä vertaillakseen `luaotfload`:n solmupohjaisia tekstinmuotoilupalveluja (`mode=node`) HarfBuzzin palveluihin (`mode=harf`):

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

Tämä projekti sisältää seuraavassa kuvassa esitetyn tulosteen:

![Arabian ladonta](/files/cb94b31a68aa26beaff0f31b460baf9c1b21575c)

### ”Renderer”-asetuksen valitseminen fontspecissä

Kuten sen [dokumentaatiota](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf), `fontspec` ”...antaa XeTeXin tai LuaTeXin käyttäjille mahdollisuuden ladata OpenType-fontteja LaTeX-asiakirjaan”. Jos käytät LuaTeX- tai LuaHBTeX-moottoreita, `fontspec` lataa `luaotfload` -kirjaston puolestasi ja tarjoaa lisäksi joukon käteviä käyttäjätason komentoja, jotka vähentävät tarvetta olla tekemisissä `luaotfload`:n matalan tason toiminnallisuuden kanssa.

Miten siis valitset HarfBuzzin muotoilun ja sisäänrakennetun muotoilun välillä, jonka tarjoaa `luaotfload`? Vastaus löytyy erinomaisesta [`fontspec` dokumentaatiota](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf), erityisesti osasta VI: vain LuaTeXiä koskevat fonttiominaisuudet. `fontspec` tarjoaa asetuksen nimeltä `Renderer` joka voidaan asettaa, kun fontti määritellään komennolla `fontspec`. `Renderer` ohjaa fontin matalan tason käsittelyä. Kaksi kiinnostavaa vaihtoehtoa ovat

* `Renderer = Node`: OpenType-fonttien ladonnan oletus-”tila” — tämä käyttää `luaotfload`:n puhtaasti Lualla toteutettuja tekstinmuotoilufunktioita.
* `Renderer = Harfbuzz`: tämä ”tila” määrittelee/lataa fontin käytettäväksi HarfBuzz-tekstinmuotoilumoottorin kanssa. `luaotfload` käyttää LuaHBTeXin APIa HarfBuzzin funktioiden kutsumiseen.

Lisätietoja on kohdassa [`fontspec` dokumentaatiota](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf).

## TeX-moottorit, HarfBuzz ja värilliset emojit

Vaikka sekä XeTeX että LuaHBTeX integroivat HarfBuzzin, ne tarjoavat eritasoista tukea joillekin HarfBuzzin edistyneemmille ominaisuuksille — erityisesti OpenType-värifonttien lataamiseen ja käyttöön.

### XeTeX ja OpenType-värifontit

Kuten todettiin, OpenType-värifontteja on kaksi luokkaa fonttiglyfien tallentamiseen käytetyn tietomuodon perusteella: vektoripohjaiset ja rasteripohjaiset.

#### XeTeX ja rasteripohjaiset OpenType-värifontit

XeTeX ei voi ladata rasteripohjaisia OpenType-väritekstejä—kuten Googlen [Noto Color Emoji](https://www.google.com/get/noto/help/emoji/) TeX Live 2020:ssä mukana tulevia. Esimerkiksi, jos yrität ladata Noto Color Emoji -fontin (NotoColorEmoji.ttf), XeLaTeX epäonnistuu ja antaa mahdollisesti harhaanjohtavan virheen väittäen, että Noto Color Emoji -fonttia “ei löydy”. Seuraava XeLaTeXillä ladottu LaTeX-koodi *ei toimi*:

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

[Avaa tämä XeLaTeX-koodi Overleafissä (se ***ei*** toimii).](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)

Se epäonnistuu seuraavalla virheellä:

```
! Package fontspec -virhe: Kirjasinta "NotoColorEmoji" ei löydy.
```

Vastaavasti XeTeXin käsittelemä yksinkertainen Plain TeX -esimerkki epäonnistuu myös

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

[Avaa tämä Plain TeX (XeTeX) -esimerkki Overleafissä (se ***ei*** toimii).](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)

Plain TeX -esimerkki ilmoittaa samankaltaisen mutta erilaisen virheilmoituksen:

```
! Fonttia \emojifont=[NotoColorEmoji.ttf] at 12.0pt ei voi ladata: Mitta (TFM) tie
dostoa tai asennettua fonttia ei löydy.
l.1 \font\emojifont="[NotoColorEmoji.ttf]" at 12pt

En pystynyt lukemaan tämän fontin kokotietoja,
joten ohitan fonttimäärityksen.
[Velhot voivat korjata TFM-tiedostoja käyttämällä TFtoPL/PLtoTF:ää.]
Voisit kokeilla lisätä toisen fonttimäärityksen;
esim. kirjoita `I\font<same font id>=<korvaavan fontin nimi>'.
```

**Plain LuaHBTeX -esimerkki**

Vertailun vuoksi tässä on minimaalinen Plain TeX -esimerkki, joka on käännetty LuaHBTeX:llä

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

[Avaa tämä Plain TeX (LuaHBTeX) -esimerkki Overleafissä (se kääntyy onnistuneesti).](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)

#### XeTeXin epäonnistumisen todellinen syy

XeTeXin antamat virheilmoitukset peittävät osittain ongelman todellisen syyn: OpenType-väritekstit, erityisesti rasteripohjaiset variantit, ovat *sisällä* tuettuja XeTeXissä. Todellisuudessa XeTeX (Kpathsea) voi *löytää* Noto Color Emoji -fontin, mutta XeTeX ei voi täysin *ladata* tuota fonttia eikä pysty alustamaan sisäisiä fonttitietotauluja, joita tarvitaan fontin käyttämiseen ladonnassa. Sisäisesti XeTeX *alkaa* tarkastelee fontin latausprosessia ja testaa sen “skaalautuvuutta” (FreeType’n “skaalautuvuuden” määritelmän mukaan), mutta tuo testi epäonnistuu, ja XeTeX antaa tavallisen, väitettäessä harhaanjohtavan TeX-moottorin virheilmoituksen.

**TeXninen huomautus**

NotoColorEmoji.ttf:n käsittelyä XeTeXissä tutkittiin kääntämällä XeTeX-suoritettavasta tiedostosta debug-versio. Eclipse IDE:tä käytettiin asettamaan keskeytyskohta XeTeX-funktioon `creatFontFromFile(filename, index, pointsize)`, minkä jälkeen koodia käytiin läpi askel askeleelta myöhempää käsittelyä tarkkaillen.

#### XeTeX ja vektoripohjaiset OpenType-väritekstit

XeTeX voi *ladata* käsitellä vektoripohjaisia OpenType-väritekstejä, mutta se ei tuota värillisiä emojeja tuloksena olevaan PDF:ään—jos XeTeX edes tuottaa sellaista. Toisin kuin LuaTeX, LuaHBTeX ja pdfTeX, XeTeX ei *suoraan* tulosta ladottuja asiakirjoja PDF-muodossa. Sen sijaan XeTeX tuottaa välivaiheen `.xdv` (laajennettu **x**dvi **) tiedostomuoto, joka muunnetaan PDF:ksi apuohjelmalla nimeltä**xdvipdfmx `. Artikkelin kirjoitushetkellä,`ei pysty upottamaan asianmukaista väriemoji-glyfidataa PDF:ään, joten parhaimmillaan näet PDF:ssä yksivärisiä emojeja—“varavaihtoehdon”—tai ehkä et mitään lainkaan, käytetystä fontista riippuen. `. Artikkelin kirjoitushetkellä,` is unable to embed the appropriate color emoji glyph data into the PDF, so, at best, you’ll see monochrome emoji—the “fallback” result—in the PDF, or perhaps nothing at all, depending on the font used.

Tässä on XeLaTeX-esimerkki, joka käyttää OpenType-väritekstiä [TwemojiMozilla.ttf](https://ctan.org/tex-archive/fonts/twemoji-colr), joka on saatavilla TeX Livessä. TwemojiMozilla.ttf käyttää Microsoftin COLR/CPAL-vektorimuotoa väriglyfien tallentamiseen, ja se toimitetaan TeX Live 2020:n mukana. Tässä esimerkissä XeTeX pystyy lataamaan fontin, luomaan `.xdv` ja PDF-tiedoston, mutta emoji-glyfiä ei ole ladotussa PDF:ssä:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont{TwemojiMozilla.ttf}
\newcommand{\smiley}{{\emojifont\char"1F600}}
Tässä on hymiö: \smiley
\end{document}
```

[Avaa tämä XeLaTeX-koodi Overleafissä (se EI toimi).](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)

Sen sijaan yllä oleva koodi toimii LuaLaTeXillä, jos määritellään `\emojifont` käyttäen `fontspec` asetus `[Renderer=HarfBuzz]`:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont{TwemojiMozilla.ttf}[Renderer=HarfBuzz]
\newcommand{\smiley}{{\emojifont\char"1F600}}
Tässä on hymiö: \smiley
\end{document}
```

[Avaa tämä LuaLaTeX-koodi Overleafissä (se toimii).](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 ja OpenType-väritekstit

Sisäänrakennetun HarfBuzz-muotoilumoottorinsa ja `luaoftload` kirjaston avulla LuaHBTeX tarjoaa tuen kaikille neljälle OpenType-väritekstityypille. LuaLaTeXin käyttäjät voivat hyödyntää täysimääräisesti emoji-merkkejä sisältävän tekstin Unicode-pohjaista käsittelyä tai yksinkertaisesti koristella asiakirjojaan erittäin värikkäällä tekstillä OpenType-väriteksteillä.

Kuten aiemmin todettiin, OpenType-väritekstin neljä varianttia voidaan luokitella kahteen ryhmään:

* ne, jotka sisältävät glyfejä rasterikuvamuodoissa, kuten PNG;
* toiset, jotka käyttävät SVG:n tai Microsoftin COLR/CPAL-mekanismin vektoripohjaisia muotoja.

Vektoripohjaisten glyfimuotojen etuna on skaalautuvuus: ne tuottavat teräviä glyfigrafiikoita missä tahansa pistekoossa.

**Microsoftin COLR/CPAL-väritekstien käyttäminen LuaHBTeXillä**

Jos haluat käyttää vektorimuotoa OpenType-väriemoji-fontteihisi, tutustu fonttiin [TwemojiMozilla.ttf](https://ctan.org/tex-archive/fonts/twemoji-colr?lang=en), joka perustuu Microsoftin COLR/CPAL-muotoon. TwemojiMozilla.ttf sisältyy TeX Liveen, mutta voit hankkia uusimman version sen [GitHub-repositoriosta](https://github.com/mozilla/twemoji-colr/releases) ja ladata sen Overleaf-projektiisi.

Tässä on pieni, `fontspec`-pohjainen esimerkki, joka käyttää `Renderer=Harfbuzz`, joka ladottaa suuren (vektori)emojiankan:

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

[Avaa tämä LuaLaTeX-esimerkki ladotaksesi vektoripohjaisen ankan.](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)

Tässä on yllä olevan esimerkin tuottama (vektori)ankka:

![](/files/4e57de527711240184a5e096756948d6bf80ac92)

#### SVG-pohjaisten OpenType-värifonttien käyttö LuaHBTeX:n kanssa

Tätä artikkelin päivitystä kirjoitettaessa (heinäkuu 2023) on vain vähän muodollista dokumentaatiota SVG-muotoisten OpenType-väritekstien käyttämisestä LuaLaTeXillä. Jotkin [verkossa käydyissä keskusteluissa esitetyt kommentit](https://github.com/latex3/luaotfload/issues/96) ehdottavat käyttämään `fontspec`’n `RawFeature`, kuten alla olevassa pseudokoodissa on esitetty. Korvaa `*SVG-fonttitiedoston nimesi tähän*` SVG-pohjaisen fonttitiedoston nimellä, johon LaTeX-koodillasi on pääsy:

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

Jos jätät pois `fontspec` ja lataat `luaotfload` suoraan, saatat joutua määrittelemään ja ilmoittamaan fontin seuraavalla tavalla—kokeemme osoittavat, että sinun on jätettävä pois `mode=harf` asetus, jotta tämä toimii:

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

**Muutamia varoituksen sanoja**

SVG-muotoisia OpenType-väritekstejä käyttävien lukijoiden kannattaa huomioida:

* SVG-muotoiset OpenType-fontit, jotka sisältävät suuren määrän glyfejä, voivat olla [laskennallisesti raskaita LuaLaTeXille](#processing-svg-glyph-data) käsitellä, mikä voi johtaa [Overleafin aikakatkaisuihin](/latex/fi/tietopankki/038-fixing-and-preventing-compile-timeouts.md).
* LuaLaTeXin tukea näille fonteille voidaan [pitää kokeellisena](https://github.com/latex3/luaotfload/issues/96#issuecomment-530317399): tulokset voivat vaihdella projektissasi käytetyn TeX Live -julkaisun mukaan; siksi on suositeltavaa kokeilla ja edetä varovaisesti.

**SVG-glyfidatan käsittely**

SVG:n avulla suunnittelijat voivat tuottaa monimutkaisia ja värikkäitä suunnitelmia, jotka esittävät fontin glyfejä—tiettyjen SVG-rajoitusten alaisina [kuten OpenType-määrityksessä on dokumentoitu](https://docs.microsoft.com/en-us/typography/opentype/spec/svg). TeX-moottorit, myös LuaHBTeX, eivät kuitenkaan voi tuoda (käyttää) SVG-tiedostoja tai -dataa suoraan—kuten SVG-dataa, jota käytetään kuvaamaan glyfien muotoja SVG-muotoisissa OpenType-väriteksteissä. Glyfin SVG-data on muunnettava PDF-muotoon, koska LuaHBTeX voi käyttää sitä glyfin ladontaan ja lopullisen PDF-asiakirjan tuottamiseen. Tuon SVG:stä PDF:ksi -muunnoksen hoitaa Lua-koodi osassa `luaoftload`: kunkin glyfin SVG-data puretaan fonttitiedostosta, tallennetaan tilapäiseen `.svg` tiedostoon ja muunnetaan PDF:ksi Inkscapen avulla komentorivin kautta. SVG-datan purkaminen ja sen muuntaminen PDF:ksi aiheuttaa jonkin verran käsittelykustannuksia, mikä voi johtaa pitkähköihin asiakirjan käännösaikoihin—erityisesti asiakirjoissa, joissa käytetään suuria SVG-fontteja, jotka sisältävät tuhansia emoji-glyfejä.

#### Rasteripohjaiset OpenType-väritekstit

**Googlen CBDT/CBLC OpenType-väritekstimuodon käyttäminen LuaHBTeXillä**

[Noto Color Emoji](https://fonts.google.com/noto/specimen/Noto+Color+Emoji) on TeX Liveen sisältyvä OpenType-väriteksti, joten sitä on helppo käyttää Overleaf-projektissa. Koska Noto Color Emoji käyttää PNG-muotoisia grafiikoita emoji-glyfien esittämiseen, voimme käyttää sitä suuren (rasteri)emojiankan ladontaan—kuten seuraava esimerkki osoittaa. Huomaa jälleen, että `fontspec` fonttimääritys (`\emojifont`) käyttää `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}
```

[Avaa tämä LuaLaTeX-esimerkki ladotaksesi rasteriankan.](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)

Tässä on yllä olevan esimerkin tuottama rasteriankka:

![LaTeXillä ladottu rasteriankkaemoji](/files/8600d244e5808c3754c60d7cecdb2a108b14f23f)

Jos yrität käyttää `NotoColorEmoji.ttf` mutta jätät pois `[Renderer=Harfbuzz]` paketista `fontspec` määrittelyn, LuaHBTeX epäonnistuu ja antaa virheilmoituksen, kun se yrittää kirjoittaa PDF-tiedoston:

```latex
! virhe: (tiedosto /usr/local/texlive/2020/texmf-dist/fonts/truetype/google/noto-em
oji/NotoColorEmoji.ttf) (ttf): loca-taulukkoa ei löydy
```

Syynä tähän virheeseen [loca-taulukossa](https://docs.microsoft.com/en-us/typography/opentype/spec/loca) on [selitetään GitHubissa](https://github.com/latex3/luaotfload/issues/98#issuecomment-531610153).

**Applen sbix OpenType-väritekstimuodon käyttäminen LuaHBTeXillä**

Offline-testit osoittavat, että LuaHBTeX tukee `sbix` OpenType-väritekstin varianttia, mutta tätä artikkelia kirjoitettaessa emme ole onnistuneet löytämään asianmukaisesti lisensoitua `sbix`-variantin väriemoji-fonttia ankan ladonnan demonstroimiseksi. Ole hyvä ja [ota yhteyttä](https://www.overleaf.com/contact) ilmoita, jos tiedät sellaisen, niin päivitämme tämän artikkelin nopeasti käyttämään sitä.

## Johdatus LuaHBTeXin HarfBuzz-APIin

![Db.gif](/files/f03eb681a3f7086935304ebf6c7889e1f98c17a0) ![Db.gif](/files/f03eb681a3f7086935304ebf6c7889e1f98c17a0)

Tekstin muotoilu, erityisesti monimutkaisten kirjoitusjärjestelmien kielissä ja jopa emojeissa, on lähtökohtaisesti vaikea tehtävä, joten ei ole yllätys, että HarfBuzz on kehittynyt kirjasto, jonka kanssa voi olla hankala työskennellä—ellei tekstinmuotoiluoperaatiot ole jo entuudestaan tuttuja. Tässä viimeisessä osassa tarkastelemme LuaHBTeXin HarfBuzz-integraatiota ja sitä, miten sitä voidaan käyttää Lua-koodin kautta `\directlua`.

Esimerkkimme käyttää melko yksinkertaista koodia LuaHBTeX HarfBuzz-API:n esittelemiseksi. Se on hieman keinotekoinen, ei tuotantotason laatua eikä kovin käytännöllinen, koska sen ainoa tarkoitus on esitellä joitakin keskeisiä ajatuksia. Olemme jakaneet Lua-koodin kahteen `\directlua` osaan: ensimmäinen lataa `luaharfbuzz` kirjaston ja luo joitakin globaaleja muuttujia, joita käytämme toisessa `\directlua` osassa, jossa määrittelemme makron nimeltä `\codestoemoji`.

Tuntuu sopivalta jäljitellä Knuthin kaksoisvaarakäännösten käyttöä (kuvan tarjoaa [tämä sivusto](http://www.truetex.com/db.htm)) koska sisältö on melko matalan tason juttua ja “kurkistaa konepellin alle”—vaikka toivomme sen kiinnostavan rohkeampaa lukijaa. LuaHBTeXin HarfBuzz-integraatio on peräisin [luaharfbuzz-projektista GitHubissa](https://github.com/ufyTeX/luaharfbuzz/wiki#projects-using-luaharfbuzz) josta löydät [johdannon projektiin](https://github.com/ufyTeX/luaharfbuzz/wiki) sekä [luaharfbuzz-API:n luettelon](http://ufytex.github.io/luaharfbuzz/).

### Ensimmäiset askeleet: lataa luaharfbuzz-kirjasto ja etsi fontti

Jotta voimme käyttää LuaHBTeXin HarfBuzz-APIa, meidän on ensin ladattava kirjasto (moduuli) nimeltä `luaharfbuzz`, joka on sisäänrakennettu LuaHBTeXiä varten, ja tallennettava palautettu taulu (globaaliin) muuttujaan, jota kutsumme `hblib`:

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

Seuraavaksi meidän on etsittävä sopiva emoji-OpenType-väriteksti: käytämme Noto Color Emoji -fonttia—huomaa, että olemme hyvin laiskoja emmekä tee mitään virhetarkistusta siltä varalta, ettemme löydä sitä! Löytääksemme sen käytämme `kpse` (Kpathsea)-kirjastoa, joka on myös osa LuaTeX/LuaHBTeXiä:

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

Nyt kun meillä on pääsy HarfBuzz-kirjastoon muuttujamme `hblib`sekä sopivan fontin polku (`pathtofontfile`), voimme alkaa käyttää `hblib`. `\directlua` koodiosassa, jossa määrittelemme makromme.

```latex
%Luo HarfBuzz-face ja HarfBuzz-fontti Noto Color Emojista
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)
```

#### HarfBuzz-fontti ja HarfBuzz-face: mitä ne ovat?

Yksi [HarfBuzz-face-objekti](https://harfbuzz.github.io/fonts-and-faces.html) edustaa fonttitiedostosta ladattua kirjasinlajia, mutta ilman että erityisiä parametreja (kuten koko) on asetettu. A [HarfBuzz-fontti-objekti](https://harfbuzz.github.io/fonts-and-faces.html) edustaa *tiettyä instanssia* HarfBuzz-facesta; näin ollen yhdestä HarfBuzz-facesta voidaan johtaa eri HarfBuzz-fonttiobjekteja: kullekin HarfBuzz-fontille voidaan asettaa ominaisuudet, kuten koko, eri arvoihin. HarfBuzz-face on korkeamman tason abstraktio kuin HarfBuzz-fontti.

### Fonttiglyfien käyttäminen PNG-tiedostojen luomiseen

Ensimmäisen `\directlua` koodiosamme on funktio nimeltä `writePNGglyph(hbfontobject, glyphID)` jota käytämme osoittamaan, että jotkin OpenType-väritekstit, kuten Noto Color Emoji, käyttävät PNG-grafiikoita niissä olevien emoji-glyfien esittämiseen.

Tämä funktio käyttää LuaHBTeXin HarfBuzz-APIa PNG-datan poimimiseen glyfeistä ja kirjoittaa tiedot `.png` nimiseen tiedostoon `Graphics<glyphID>.png`. Sen `.png` tiedostonimi palautetaan käytettäväksi `\includegraphics` PNG-glyfikuvien upottamiseksi ladottuun PDF:äämme.

Kun `writePNGglyph(hbfontobject, glyphID)` on paikallaan, ensimmäinen `\directlua` koodiosamme näyttää tältä:

```latex
\directlua{

% Lataa luaharfbuzz-kirjasto LuaHBTeXistä
hblib=require("luaharfbuzz")

% Etsi Noto Color Emoji -fontti Overleafin palvelimelta
pathtofontfile=kpse.find_file("NotoColorEmoji.ttf","truetype fonts")

% Luo HarfBuzz-face ja HarfBuzz-fontti Noto Color Emojista
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)

% Tämä funktio ottaa vastaan fontin ja glyfin tunnisteen:
% se poimii glyfien PNG-datan ja kirjoittaa
% sen ulos .png-tiedostoon

function writePNGglyph(hbfontobject, glyphID)

    % Hae glyfin PNG-data
    local pngblob=hbfontobject:ot_color_glyph_get_png(glyphID)
    local pngdata=pngblob:get_data()

    % Muodosta tiedostonimi .png-tiedostollemme
    local fname="Glyph"..glyphID..".png"

    % Kirjoita .png-tiedosto ja palauta tiedostonimi
    local output = assert(io.open(fname, "wb"))
    output:write(pngdata)
    output:close()

    % Palauta tiedostonimi \includegraphicsia varten
    return fname
end
}
```

### Toinen \directlua-koodiosa: luo makro \codestoemoji

Tavoitteena on määritellä makro `\codestoemoji` jota voimme kutsua tekstinpätkällä, joka sisältää emoji-merkkikoodeja, jotka haluamme HarfBuzzin muotoilevan. Tarkemmin sanottuna käytämme `\Uchar<merkkikoodi>` edustamaan jokaista emoji-merkkiä; esimerkiksi:

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

Määritelmässä on paljon meneillään `\codestoemoji` jota selitämme alla, mutta määritelmä näyttää tältä:

```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()
    % Glyfitaulu hbglyphs on 1-pohjainen
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Pienennä tuotujen PNG-kuvien kokoa
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
}}
```

#### Makron \codestoemoji määritelmän ymmärtäminen

Se `\codestoemoji` makro on pääosin Lua-koodia, joka sisältyy `\directlua`, joten jos haluat tietää lisää siitä, miten *miten* `\directlua` se toimii, tutustu Overleaf-artikkeliin [Ymmärtäminen `\directlua`](/latex/fi/syvalliset-artikkelit/09-an-introduction-to-luatex-part-2-understanding-directlua.md). Se selittää, miten LuaTeX ja LuaHBTeX käsittelevät `\directlua` kun TeX/LaTeX-komentoja sisällytetään Lua-koodiin ja erityisesti tarpeen käyttää `\noexpand` ja `\unexpanded`.

**Makroparametrin käsittely: "#1"**

Makro alkaa näillä kolmella rivillä:

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

jotka suorittavat seuraavat tehtävät:

* `local str="#1"`: tämä luo Lua-merkkijonon makron välittämästä syötteestä;
* `local hbbuffer = hblib.Buffer.new()`: tämä käyttää HarfBuzz-APIa luodakseen puskurin, johon tallennetaan teksti, jonka haluamme HarfBuzzin muotoilevan;
* `hbbuffer:add_utf8(str)`: tämä lisää makron syötteestä luodun UTF-8-muotoisen merkkijonon HarfBuzz-puskuriin.

Koodin ensimmäinen rivi

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

vaikuttaa melko suoraviivaiselta, mutta sen toiminta on varsin monimutkaista, ja sitä kannattaa tarkastella hieman yksityiskohtaisemmin.

Jos tarkastelemme koodin kolmatta riviä

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

näemme, että se käyttää meidän `str` muuttujaa, jotta HarfBuzz-puskurille voidaan antaa UTF-8-muotoiltu Unicode-merkkijono. Jotta tämä toimisi, muuttujan `str` itsensä on sisällettävä UTF-8-muotoista Unicode-tekstiä; joten herää kysymys: *miten* muunsiko LuaHBTeX makron argumentin `"#1"`, joka sisältää `\Uchar` komentoja, Lua-merkkijonomuuttujaan `str` joka sisältää UTF-8-tekstiä HarfBuzzia varten?

Jos tarkastelemme tarkoittamaamme käyttöä `\codestoemoji` makrolle:

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

syöte, kuten `\Uchar"1F3F4\Uchar"E0067\Uchar"E0062\Uchar"E0065...`, ei näytä lainkaan UTF-8:ksi koodattujen emoji-merkkejen sarjalta. Lisäksi HarfBuzz ei tiedä mitään TeX-komennoista. Jollain tavalla raakatekstisyöte, joka koostuu `\Uchar` komennoista, muutetaan UTF-8:ksi koodatuiksi Unicode-merkeiksi, joita HarfBuzz voi käyttää, mutta *miten*?

Vastaus löytyy `\Uchar` komennon toiminnasta: yritettäessä kutsua `\codestoemoji` käyttäen `\char` sen sijaan että `\Uchar` se epäonnistuu, mutta *miksi*?

**\Uchar: laajeneminen \directlua:ssa**

Kun `\codestoemoji` makroa kutsutaan,  `\directlua` komennon, joka on tallennettu makron määritelmään, on valmisteltava Lua-koodi lähetettäväksi LuaHBTeXin sisäänrakennetulle Lua-tulkille. Osa tuosta koodinvalmisteluprosessista on kaikkien alkuperäisessä makron määritelmässä olevien TeX/LaTeX-komentojen sekä käyttäjän antamien makroargumenttien laajentaminen. Tuo laajennusprosessi tuottaa tunnusluettelon, joka muunnetaan myöhemmin takaisin tekstiksi, jolloin syntyy Lua-tulkille toimitettava Lua-koodi. Havainnollisuuden vuoksi toistamme kaavion Overleaf-artikkelista [Ymmärtäminen `\directlua`](/latex/fi/syvalliset-artikkelit/09-an-introduction-to-luatex-part-2-understanding-directlua.md):

![\directlua:n toimintaperiaate](/files/3dd99bab236df0f5f6044d552a12f458ddd53520)

Makro `\codestoemoji` on tarkoitettu kutsuttavaksi käyttäen `\Uchar` komentoja, ja [kuten artikkelissa aiemmin todettiin](#the-key-difference-expansion), `\Uchar` on laajennettava komento, jonka laajeneminen tuottaa merkkitunnuksen. Käsittelyn aikana `\directlua`, LuaHBTeX laajentaa jokaisen `\Uchar<merkkikoodi>` komennon, jossa se *poistaa* jokainen `\Uchar<merkkikoodi>` syötteestä ja *korvaa* sen vastaavalla laajenemisarvolla: merkkitunnuksella, joka edustaa `<merkkikoodin>`.

Käsittelyn loppuvaiheessa alun perin tuottama tunnuslista `\directlua` muunnetaan *takaisin tekstiksi* jotta siitä tulee Lua-tulkille tarkoitettu Lua-koodi (katso yllä oleva kaavio). Kaikki laajenemisen tuottamat merkkitunnukset `\Uchar` muunnetaan myös *muutetaan takaisin tekstiksi*: tämä merkkitunnusten muuntaminen tekstiksi tuottaa alkuperäisten `<merkkikoodin>` arvojen UTF-8-esitykset.

Esimerkissämme siihen mennessä, kun Lua-koodi on luotu ja valmis Lua-tulkille, makron "#1" syöte on muunnettu UTF-8-tekstiä sisältäväksi sarjaksi:  `str` muuttuja on nyt UTF-8-tekstimerkkijono, joka voidaan turvallisesti lisätä HarfBuzz-puskuriin.

**Miksi \char ei toimi?**

Suora vastaus on, että `\char` on *sisällä* laajennettava komento. Toisin kuin `\Uchar` komennot, `\char` komennot *eivät poistu* syötteestä käsittelyn aikana `\directlua`alkuperäisessä käsittelyssä token-luettelon luomiseksi, ne “kulkevat läpi” ja sisällytetään token-luetteloon, jota rakentaa `\directlua`. Esimerkiksi, jos argumentti `\codestoemoji` sisälsi `\char"1F3F4` LuaHBTeX muuntaisi sen token-jonoksi ja tallentaisi ne osaksi luotavaa kokonaista token-luetteloa.

Seuraavassa käsittelyvaiheessa, kun tokenit muunnetaan takaisin tekstiksi, tuloksena syntyvä Lua-koodi sisältäisi *kirjaimellisen merkkijonon* `\char"1F3F4` määrittelemäämme muuttujaa varten käytetyssä tekstissä `str`. Kun `str` sisältö lisätään HarfBuzz-puskuriin, se ei sisällä UTF-8-koodattua jaksoa, joka edustaa emoji-merkkiä "1F3F4, vaan se sisältäisi kirjaimellisen merkkijonon `\char"1F3F4`, jota HarfBuzz yrittää muotoilla ja joka ei meidän tarkoituksiimme tuottaisi emoji-glyfiä. Sivumennen sanoen merkkijono `\char"1F3F4` tuottaisi myös Lua-syntaksivirheitä, ellei sitä olisi luotu “pitkäksi hakasulkemerkkijonoksi”—katso [Mitä ovat Lua-escape-sekvenssit](/latex/fi/syvalliset-artikkelit/09-an-introduction-to-luatex-part-2-understanding-directlua.md#what-are-e2809clua-escape-sequencese2809d3f) taustaksi tähän ongelmaan.

Jos yritämme käyttää `\codestoemoji` seuraavalla: `\char` komentoa, kuten tässä:

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

LuaHBTeX epäonnistuu ja ilmoittaa syntaksivirheestä jotakuinkin näin:

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

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

Lua-tulkki kohtasi ongelman, joten
tämän Lua-lohkon loppu jätetään huomiotta.
```

#### HarfBuzzin muotoilufunktion kutsuminen

**Puskuriparametrien asettaminen**

HarfBuzz tarvitsee joskus lisätietoja tekstistä, jota sen pyydetään muotoilemaan. Voit antaa nämä tiedot määrittämällä `<buffer variable>` käyttäen *puskurimetodit*, kuten:

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

Esimerkiksi meidän on kerrottava HarfBuzzille, että emoji-tekstimme suunta on vasemmalta oikealle. Teemme sen käyttämällä `set_direction()` metodia meidän `<buffer variable>` (nimeltään `hbbuffer`) kirjoittamalla:

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

jossa `hblib.Direction.new("ltr")` luo “suunta-objektin”, joka sopii välitettäväksi HarfBuzz-moottorille Luan kautta.

**Suorita muotoilu**

Kun puskuri on alustettu asianmukaisesti, voimme pyytää HarfBuzzia tekemään varsinaisen muotoilun funktion `shape_full()`. Esimerkissämme kirjoitamme:

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

funktion 3. ja 4. parametrin `shape_full()` täytyy olla Lua-taulukoita — olemme käyttäneet tyhjiä taulukoita “`{}`” molempia parametreja varten. Yleinen muoto `shape_full()` on:

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

* **`{"shaper"}`**: Sitä ei yleensä tarvitse asettaa, mutta vaihtoehdot ovat `{"ot"}` tai `{"graphite2"}`. Lisätietoja “shaper”-käsitteestä löytyy [HarfBuzzin dokumentaatiosta](https://harfbuzz.github.io/shaping-and-shape-plans.html)—huomaa, että tämä dokumentoi matalan tason C-rajapinnan, ei Lua-pohjaista `luaharfbuzz` sidontaa (toteutusta).
* **`{font features}`**: Tämä on taulukko, jossa luetellaan [OpenType-ominaisuudet](https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist)—fontin tukemat— ominaisuudet, jotka haluat HarfBuzzin soveltavan muotoilun aikana.

Kaikki käyttämäsi fonttiominaisuudet täytyy luoda käyttäen `luaharfbuzz` kirjastofunktiota

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

jossa

* `library_instance` on sinun `luaharfbuzz` kirjastoesiintymämuuttujasi (`hblib` esimerkissämme);
* `feature_string` käyttää [syntaksia ominaisuuksien määrittelemiseen](https://github.com/ufytex/luaharfbuzz/wiki/Feature-Strings). Esimerkkejä tästä ovat `+smcp` pienten versaalien aktivoimiseksi tai `-kern` kerningin poistamiseksi käytöstä.

Esimerkiksi:

```latex
local dosmcp = hblib.Feature.new("+smcp")
local nokern = hblib.Feature.new("-kern")
% Käytä fonttiominaisuuksiasi näin
local res = hblib.shape_full(hbfont, hbbuffer, {dosmcp,nokern},{})
```

#### Tuloksen käyttäminen: glyfien hakeminen

Ja lopuksi, jos muotoiluoperaatio onnistuu, muotoillut glyfit palautetaan puskurimuuttujaan `hbbuffer` jonka loimme aiemmin koodissa.

Käytämme glyfejä puskurin metodin kautta `get_glyphs()` ja käytämme silmukkaa saadaksemme jokaisen yksittäisen glyfin. Huomaa, että glyfejä sisältävä Lua-taulukko, `hbglyphs` esimerkissämme, on indeksoitu alkaen 1:stä, ei 0:sta.

Kunkin glyfin *glyfitunniste* (hämmentävästi nimeltään `koodipiste`), ja HarfBuzz-fontti (`hbfont`), välitetään `writePNGglyph()` funktion, joka luo PNG-tiedoston käyttäen fontin rasterikuvaesitystä kyseisestä glyfistä.

`writePNGglyph()` kirjoittaa PNG-tiedoston ja palauttaa PNG-tiedoston nimen, jota käytetään skaalatun PNG-tiedoston tuomiseen LaTeX-dokumenttiimme käyttäen `\includegraphics[scale=0.75]{<fname>}`. Huomaa, että voimme käyttää `\includegraphics` suoraan Lua-koodin sisällä.

```latex
if (res) then
    local hbglyphs=hbbuffer:get_glyphs()
    % Glyfitaulu hbglyphs on 1-pohjainen
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Pienennä tuotujen PNG-kuvien kokoa
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
```

### Koko koodi, jonka voit avata Overleafissa

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

% Lataa luaharfbuzz-kirjasto LuaHBTeXistä
hblib=require("luaharfbuzz")

% Etsi Noto Color Emoji -fontti Overleafin palvelimelta
pathtofontfile=kpse.find_file("NotoColorEmoji.ttf","truetype fonts")

% Luo HarfBuzz-face ja HarfBuzz-fontti Noto Color Emojista
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)

% Tämä funktio ottaa vastaan fontin ja glyfin tunnisteen:
% se poimii glyfien PNG-datan ja kirjoittaa
% sen ulos .png-tiedostoon

function writePNGglyph(hbfontobject, glyphID)

    % Hae glyfin PNG-data
    local pngblob=hbfontobject:ot_color_glyph_get_png(glyphID)
    local pngdata=pngblob:get_data()

    % Muodosta tiedostonimi .png-tiedostollemme
    local fname="Glyph"..glyphID..".png"

    % Kirjoita .png-tiedosto ja palauta tiedostonimi
    local output = assert(io.open(fname, "wb"))
    output:write(pngdata)
    output:close()

    % Palauta tiedostonimi \includegraphicsia varten
    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()
    % Glyfitaulukko, hbglyphs, on 1-pohjainen.
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Pienennä tuotujen PNG-kuvien kokoa
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
}}

Ankka: \codestoemoji{\Uchar"1F986}

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

[Avaa tämä luaharfbuzz-API-esimerkki Overleafissa.](/latex/fi/syvalliset-artikkelit/10-an-overview-of-technologies-supporting-the-use-of-colour-emoji-fonts-in-latex.md)

Tämä esimerkki tuottaa seuraavan tulosteen:

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

## Bonusosio: Hauskaa emoji-matematiikkaa

Lopuksi kevyen huumorin merkeissä eräs Overleafin tiimin jäsen käytti [`emoji` LaTeX-paketti](https://ctan.org/pkg/emoji?lang=en) luodakseen hauskan esimerkin:

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

[Avaa tämä hauska esimerkki Overleafissa](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)

Tämä esimerkki tuottaa seuraavan tulosteen:

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


---

# 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/fi/syvalliset-artikkelit/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.
