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

# En oversigt over teknologier, der understøtter brugen af farvede emoji-skrifttyper i LaTeX

## Introduktion

Denne artikel giver et overblik over forskellige [baggrundsemner](#which-topics-do-we-cover) om brugen af OpenType-farvefonte til at sætte farve-emoji i LaTeX. Vi har forsøgt at give et bredt udvalg af materiale, der henvender sig til et bredt spektrum af interesser og ekspertise. For at holde artiklen håndterbar udelader vores behandling af visse emner en masse tekniske detaljer, men vi håber, at der er tilstrækkeligt materiale til at orientere din udforskning af sats af farve-emoji i LaTeX.

**Opdatering (juli 2023)**: Denne artikel blev første gang publiceret i august 2021 og revideret i juli 2023 for at opdatere afsnittet om [Brug af SVG-baserede OpenType-farvefonte med LuaHBTeX](#using-svg-based-opentype-color-fonts-with-luahbtex).

### Hvilke emner dækker vi?

Denne artikel dækker følgende generelle emner:

* Unicode: standarden, der koder emoji som tegn og fastlægger deres forventede adfærd i tekstbehandlings- og satsprogrammer.
* OpenType-farvefonte: specialiserede skrifttyper, der leverer farverige gengivelser af emoji-tegn vist i dit LaTeX-dokument.
* Tekstformning: introduktion til en nøglekomponent i satsning af komplekse skriftsprog og emoji.
* HarfBuzz: den komponent i LuaHBTeX, der muliggør avanceret flersproget sats og brug af OpenType-farvefonte til at sætte emoji i LaTeX.
* Forskellige TeX-motorer: undersøgelse af deres understøttelse af OpenType-farvefonte og valg af hvilken TeX-motor der skal bruges.
* LuaHBTeX’s HarfBuzz-API: en introduktion til “magien” bag [tekstformning](#the-concept-of-text-shaping) i LuaHBTeX.

### Tre måder at sætte farve-emoji på

Farve-emoji kan sættes med LaTeX ved hjælp af tre hovedmetoder:

1. Brug af standard LaTeX-grafikværktøjer såsom TikZ, MetaPost eller Asymptote til at tegne emoji.
2. Indsættelse af emoji ved hjælp af forberedte emoji-grafikker gemt i eksterne filer.
3. At behandle emoji som Unicode-kodet tekst og bruge [tekstformning](#the-concept-of-text-shaping) med [OpenType-farvefonte](#opentype-color-fonts) til at sætte dem.

De praktiske muligheder for at inkludere farve-emoji i dit LaTeX-dokument afhænger af den TeX-motor, der bruges til at kompilere dokumentet: dvs. om du bruger:

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

Alle tre af disse TeX-motorer kan bruge LaTeX-værktøjer eller -pakker til at tegne emoji eller bruge `\includegraphics{...}` til at indsætte emoji, der er gemt i eksterne grafikfiler. At tegne eller importere grafik er ideelle teknikker til at sætte emoji, når du har brug for en løsning, der ikke afhænger af den TeX-motor, der bruges til at kompilere LaTeX-dokumentet.

Men hvis din arbejdsgang giver fleksibilitet til at vælge en bestemt TeX-motor, og du foretrækker at bruge OpenType-farvefonte og Unicode-baseret tekstbehandling, er den nyeste version af LuaTeX, kaldet LuaHBTeX, det, du har brug for. Fra og med TeX Live 2020 bruges LuaHBTeX til at kompilere LaTeX-dokumenter baseret på LuaLaTeX-formatet.

## Baggrund om Unicode og emoji-tegn

### Tegnkodninger

Computere lagrer, transmitterer og behandler tekst ved hjælp af en sekvens af numeriske (heltal-)værdier, der repræsenterer tekstens bestanddele *tegn*. Pålidelig tekstbehandling kræver, at producenter og forbrugere af tekst er enige om, hvilke heltalsværdier der skal bruges til at repræsentere enkelte tegn i tekststrømmen. Med andre ord, hvad er denne teksts *tegn* *kodning?* En kodning er det sæt af aftalte heltalsværdier, der tildeles til at repræsentere et bestemt sæt tegn: hvert tegn repræsenteres af en heltalsværdi inden for den anvendte kodning.

### Ind træder Unicode

Historisk set, i 8-bit-teksternes tidsalder, blev mange forskellige tegnkodninger brugt, hvilket altid rejste spøgelset om *kodningsuoverensstemmelser*: producenter og forbrugere af tekst, der fejlagtigt antager forskellige kodninger, hvilket resulterer i fejl i tekstbehandlingen. Enhver, der har arbejdet med TeX/LaTeX i nogle år, er sandsynligvis stødt på kodningsuoverensstemmelser mellem inputteksten og de skrifttyper, der bruges til at sætte et dokument. Hvis dokumentets skrifttyper er konfigureret til at bruge en anden kodning end tekstens, fører det sandsynligvis til manglende eller fejlagtige tegn i den satsede PDF.

Disse historiske kodningsproblemer kan løses ved hjælp af en international standard, der koder alle verdens tegn: Unicode. Unicode-standarden er ikke statisk, men opdateres med jævne mellemrum for at omfatte yderligere tegn og skriftsystemer inden for sit kodningsskema. Der er en [formel gennemgangsproces for at foreslå nye tegn](http://www.unicode.org/pending/proposals.html) med et specifikt [skema for nye emoji-tegn](https://www.unicode.org/emoji/proposals.html).

### Hvor mange Unicode-tegn?

Unicode koder et teoretisk maksimum på 1.114.112 tegn. Hver af de 1.114.112 heltalsværdier kaldes et *kodepunkt*: den heltalsværdi, der tildeles for at identificere hvert tegn. Af tekniske grunde kan kun [1.112.064 kodepunkter](https://en.wikipedia.org/wiki/Unicode#Architecture_and_terminology) tildeles faktiske tegn: 2048 kodepunkter kan ikke tildeles og er forbudt til brug i Unicode-kompatibel tekst.

På tidspunktet for skrivningen (den første version af denne artikel) havde version 13 af Unicode-standarden tildelt i alt 143.859 kodepunkter til faktiske tegn, herunder [3304 tegn, der nu er kodet som emoji](https://www.unicode.org/L2/L2020/20114r-family-emoji-explor.pdf) (se side 2 i det dokument). Væksten i antallet af tegn kodet af Unicode er fint dokumenteret i artiklen [Hvor mange Unicode-tegn er der?](https://www.babelstone.co.uk/Unicode/HowMany.html) og i en [Wikipedia-artikel](https://en.wikipedia.org/wiki/Unicode#Versions).

### Unicode-planer

Hele samlingen af 1.114.112 Unicode-kodepunkter er grupperet i 17 såkaldte planer: Plan 0 til Plan 16, hver indeholdende 65.536 kodepunktsværdier, hvilket giver i alt $$17\times2^{16} = 1,114,112$$ tegn. Plan 0, kaldet den [Basic Multilingual Plane](https://en.wikipedia.org/wiki/Plane_\(Unicode\)#Basic_Multilingual_Plane), koder de mest almindeligt anvendte tegn. Plan 1–16 kaldes [supplerende planer](http://unicode.org/glossary/#supplementary_planes).

### Emojiens fremmarch

Nye tegn opstår gennem ændrede former for menneskelig kommunikation, og mobilteknologi gav anledning til et sådant sæt tegn: emoji, som udviklede sig i Japan i slutningen af 1990'erne. Det er ikke overraskende, at [Unicode-FAQ'en om emoji](https://unicode.org/faq/emoji_dingbats.html) bemærker

> “Ordet emoji kommer af det japanske [絵](http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=%E7%B5%B5) (e ≅ billede) + [文字](http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=%E6%96%87) (moji ≅ skrevet tegn).”

Læserne, der interesserer sig for baggrunden og den historiske udvikling af emoji, kan have interesse i denne [Unicode-introduktion](https://unicode.org/reports/tr51/#Introduction) eller artiklen [I second that emoji: Standarderne, strukturerne og den sociale produktion af emoji](https://firstmonday.org/ojs/index.php/fm/article/view/9381).

Det var først i 2010, med udgivelsen af [version 6.0 af Unicode-standarden](https://www.unicode.org/versions/Unicode6.0.0/), at mange emoji formelt blev anerkendt som *tegn* i deres egen ret. Unicode 13.0 kodede [3304 tegn som emoji](https://www.unicode.org/L2/L2020/20114r-family-emoji-explor.pdf) (se side 2 i det dokument), og Unicode 13.1 oplister [opremser 3521 emoji](https://unicode.org/emoji/charts/emoji-counts.html).

### Emoji lever på et højere plan

Unicode tildelte mange emoji-tegn til kodepunkter uden for Basic Multilingual Plane (BMP), kodet [i Plan 1](https://en.wikibooks.org/wiki/Unicode/Character_reference/1F000-1FFFF) med kodepunkter i området 1F000–1FFFF—hvilket har en vigtig konsekvens for enhver, der ønsker at *kopiere og indsætte* emoji-tegn i Overleaf-editorerne (Code Editor eller Visual Editor). Overleafs teksteditorer kan kun håndtere tegn inden for Basic Multilingual Plane, selv om vi håber, at fremtidige opgraderinger vil indføre understøttelse af ikke-BMP-tegn. Bemærk, at denne begrænsning kun påvirker ikke-BMP-tegn i tekst, der indsættes i filer, som skal redigeres via Overleaf-editorerne. Der er andre måder at få adgang til emoji-tegn på:

* Ved brug af de primitive kommandoer `\char"<kodepunkt>` eller `\Uchar"<kodepunkt>` (se [dette afsnit](#optional-detail-luatexluahbtex-char-vs-uchar) i artiklen).
* Ved brug af inputtekstfiler, der indeholder emoji-tegn i UTF-8-format.
* Ved brug af LaTeX-kommandoer (makroer), som indsætter emoji-tegn.

#### Indsættelse af emoji og andre ikke-BMP-tegn i Overleaf

Hvis du indsætter et emoji-tegn, for eksempel 😀, i Overleaf Code Editor, vil det i øjeblikket blive konverteret til tegnene ��.

![Fejl som følge af kopiering + indsættelse af ikke-BMP-tegn i Overleaf-editorer](/files/969386fd11ebfbf660691328ed42892dd70d7f84)

Tegnet � har Unicode-kodepunkt FFFD og dets officielle navn er REPLACEMENT CHARACTER og bruges til at “[erstatte et ukendt, ikke-genkendt eller ikke-repræsentérbart tegn](https://en.wikipedia.org/wiki/Specials_\(Unicode_block\))”.

### Brug af Unicode-kodepunkter (U+) i LuaLaTeX

Unicode-dokumentationen repræsenterer kodepunktsværdier ved hjælp af notationen `U+<hexadecimal værdi>`—såsom `U+1F600`, hvor `1F600` er `<hexadecimal værdi>` af Unicode-kodepunktet for emoji-tegnet 😀. For at bruge disse kodepunktsværdier i LuaLaTeX sletter du `U+` og skriver `\char"<hexadecimal værdi>` eller `\Uchar"<hexadecimal værdi>`. `"` tegnet fortæller en TeX-motor, at det angivne tal er specificeret i hexadecimal. For eksempel, for at bruge emoji'en 😀, ville du skrive `\char"1F600` eller `\Uchar"1F600`—ved hjælp af en skrifttype, der er i stand til at sætte det.

Et minimalt LuaLaTeX-eksempel, der bruger `\char` og `\Uchar` til at sætte emoji-tegnet 😀 kunne være:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont[Renderer=Harfbuzz,SizeFeatures={Size=20}]{NotoColorEmoji.ttf}
%Brug \emojifont i en gruppe for at holde dens virkninger lokale
{\emojifont
\Uchar"1F600
\char"1F600}
\end{document}
```

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

**(valgfri detalje) LuaTeX/LuaHBTeX: \char vs \Uchar**

Ud over den konventionelle `\char<tegnkode>` kommando til at sætte en bestemt `<tegnkode>`, med den aktuelle skrifttype, tilbyder LuaTeX-, LuaHBTeX- og XeTeX-motorerne også `\Uchar<tegnkode>` kommandoen. Set fra en brugers perspektiv ser resultatet af `\char` og `\Uchar` ens ud, men der er en subtil forskel i, hvordan disse kommandoer virker, som vi bemærker nedenfor.

**Den væsentlige forskel: ekspansion**

`\Uchar` er en såkaldt [ekspanderbar kommando](/latex/da/dybtgaende-artikler/22-how-does-expandafter-work-the-meaning-of-expansion.md#expansion-a-general-term-for-a-set-of-operations) mens `\char` ikke er ekspanderbar. Når en `\char<tegnkode>` eller `\Uchar<tegnkode>` kommando bliver “udført”—dvs. kommandoen ikke lagres som en del af en makro eller anden tokenliste—finder følgende handlinger sted inde i TeX-motoren:

* **`\char<tegnkode>`** instruerer TeX-motoren til straks at indsætte et tegntoken, der repræsenterer `<tegnkode>`, i det stykke indhold, den i øjeblikket sætter.
* I modsætning hertil, **`\Uchar<tegnkode>`** har to adskilte behandlingstrin:

1. Den `\Uchar<tegnkode>` kommandoen *ekspanderet*udvides `<tegnkode>` , og [karaktertoken](/latex/da/dybtgaende-artikler/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md#tex-tokens-101-28and-notions-of-expansion29) konverteres til en midlertidig tokenliste indeholdende et enkelt `<tegnkode>`.
2. som repræsenterer *gøres tilgængelig* for TeX-motoren som kilden til dens næste input. I praksis “flytter” TeX-motoren midlertidigt sit blik til at bruge denne enkelt-token-liste som stedet for dens næste inputelement (token). Som standard går TeX-motoren blot tilbage for at læse (indlæse) det token og sætte det tilsvarende tegn, hvorved den gengiver adfærden af `\char` kommandoen. **Men**, fordi det `<tegnkode>` ikke blev sat straks, men midlertidigt *gemt* (gemt) som et enkelt token, kan primitive TeX-kommandoer eller LaTeX-makroer gøre brug af (opfange) det token—det behøver ikke at blive sat med det samme, men kan bruges i yderligere behandling efter behov.

I praksis, `\char<tegnkode>` siger “sæt dette `<tegnkode>` nu,” mens `\Uchar<tegnkode>` har en form for “forsinket handling” ved at oprette et gemt tegntoken og gøre det tilgængeligt som det næste inputelement (et token). Det token kan enten bruges (opfanges) af TeX-kommandoer og makroer eller læses igen af TeX-motoren og sættes.

### Unicode (kodning) er ikke hele historien

Muligheden for at bruge emoji-tegn i Unicode-kodet tekst er kun en del af emoji-succeshistorien. Den markante stigning i brugen af emoji blev også muliggjort af udviklingen inden for [OpenType-skrifttype-teknologi](https://learn.microsoft.com/en-us/typography/opentype/)—skrifttyper, hvis glyph-data (tegnudformninger) kan indeholde [farvedata](https://learn.microsoft.com/en-us/typography/opentype/spec/colr): såkaldte [OpenType-farvefonte](#opentype-color-fonts).

Ud over egnede skrifttyper kræver brugen af farve-emoji yderligere softwarekomponenter, hvis opgaver omfatter:

* forbehandling (“[formning](#the-concept-of-text-shaping)”) af Unicode-kodet tekst, *forberedelse* af den til visning med en bestemt skrifttype;
* *gengivelse og visning* af en skrifttypes farverige emoji *glyffer* på en enheds skærm.

#### Glyph vs. tegn: er de ikke det samme?

Udtrykkene “glyph” og “tegn” bruges ofte, som om de var indbyrdes udskiftelige—som henvisninger til det samme grundlæggende begreb—men der er en subtil, om end vigtig, forskel i deres betydning.

Unicode [definerer udtrykket “tegn”](http://www.unicode.org/glossary/#character) som:

> “Den mindste komponent i et skrevet sprog, der har semantisk værdi; henviser til den abstrakte betydning og/eller form, snarere end en specifik form… ”

I modsætning hertil er en “glyph” en *specifik* *form* (design) for den *visuelle repræsentation* af et bestemt *tegn*.

Problemet med tegn vs. glyph ses let, når emoji-fyldt tekst vises på forskellige softwaresystemer/platforme, såsom når den samme tekst læses på din iOS- eller Android-baserede mobiltelefon eller Windows-computer. Uanset hvilken enhed eller platform der bruges, vil den underliggende tekst (sekvens af tegn) indeholde den samme Unicode-kodede *emoji* *tegn*. Det er enhedsspecifikke funktioner, der er involveret i *forbehandlingen* af den tekst, og derefter *gengivelsen* og *visning* af resultaterne, måske ved hjælp af enhedsspecifikke skrifttyper, som producerer forskellige glyphs (tegnudformninger) til at repræsentere de samme emoji-tegn.

Unicode’s [Fuld Emoji-liste](https://unicode.org/emoji/charts/full-emoji-list.html) indeholder eksemplarbilleder, der repræsenterer hvert Unicode-emoji-tegn—og demonstrerer forskellige glyphs, som bruges af forskellige teknologileverandører. Ikke alene anvender skrifttypedesignere deres egne særlige design (glyphs) til at repræsentere emoji-tegn, men individuelle skrifttyper varierer også i antallet af emoji-tegn, de understøtter (indeholder glyphs for), og de kan indeholde eller ikke indeholde mere avancerede funktioner til emoji-tekstbehandling, som er medtaget i Unicode’s emoji-specifikationer.

Forestillingen og begrebet om tegn, deres semantik og kodning danner grundlaget for Unicode-verdenen: den beskæftiger sig med tegn. Designet og den visuelle repræsentation af enkelte tegn som glyphs hører til skrifttypeteknologierne og skrifttypedesignets håndværk.

#### Unicode-emoji: langt mere end tekstkodning

Unicode’s kernerolle er at levere en global kodningsstandard, der definerer, hvilken heltalsværdi, kaldet et *kodepunkt,* der skal bruges til at repræsentere hvert tegn, herunder emoji, inden for en strøm af Unicode-kodet tekst.

Unicode’s specifikation for emoji definerer også *behandlingsadfærd* for visse *sekvenser* af emoji-tegn, der optræder inden for en strøm af Unicode-kodet tekst. Definerede sekvenser af emoji-tegn kan “sammenflettes” gennem en proces kaldet [tekstformning](#the-concept-of-text-shaping) for at producere et enkelt resulterende (“sammensat”) emoji-glyph—den ene glyph ville blive brugt af enhedens operativsystem til at repræsentere den oprindelige tegnsekvens, der findes i teksten.

Unicode’s tekniske rapport om [Unicode Emoji](https://unicode.org/reports/tr51/) dokumenterer det rige sæt af funktioner, der er til rådighed for software, der ønsker at levere Unicode-kompatibel behandling af emoji-tegn. Som eksempel definerer (koder) Unicode tegn kaldet [emoji-modifikatorer](http://www.unicode.org/reports/tr51/#Emoji_Modifiers_Table) der kan bruges til at generere *variationer* af “basis”-emoji-tegn, såsom variationer i [hudtone baseret på Fitzpatrick-skalaen](http://www.unicode.org/reports/tr51/#Diversity). Bemærk, at sættet af basis-emoji-tegn og de anvendelige modifikatorer er defineret som en del af den overordnede [Unicode-emoji-standard](http://www.unicode.org/reports/tr51).

Unicode-siden [Emoji-sekvenser](http://unicode.org/emoji/charts/emoji-sequences.html) indeholder et diagram over de sekvenser, som i øjeblikket er angivet i Unicode-specifikationen. Placer en musemarkør over et af emoji-glyph-billederne for at se en lille pop-up-værktøjstip, der fortæller dig den underliggende Unicode-emoji-tegnsekvens, som producerer den glyph:

![EmojiSequenceChart.png](/files/07c8dea8ca57ab128950a7761165bf8b32f39272)

For eksempel er emoji-glyphen:

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

listet i [afsnittet om modifikatorsekvenser](http://unicode.org/emoji/charts/emoji-sequences.html#modifier_sequences) og produceres af den tocifrede sekvens U+1F44B U+1F3FD. Disse komponenttegn er:

U+1F44B:![UnicodeWavingHandDefault.png](/files/20dba5e36a56f51914dbe6326039500f8849cdb2) (VINKENDE HÅND)

U+1F3FD:![FitzPatrick3.png](/files/14a2eccc9b46bf488ebf0543cbaafcbdd3d894fa) (EMOJI-MODIFIKATOR FITZPATRICK TYPE-4)

**Brug af hudtonemodifikatorer i LuaHBTeX**

Det følgende eksempel bruger LuaHBTeX til at demonstrere brugen af emoji-modifikatorer:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont[Renderer=HarfBuzz,SizeFeatures={Size=20}]{NotoColorEmoji.ttf}
Isoleret vinkende hånd: {\emojifont\Uchar"1F44B}\par
Isoleret modifikator: {\emojifont\Uchar"1F3FD}\par
Kombineret resultat: {\emojifont\Uchar"1F44B\Uchar"1F3FD}
\end{document}
```

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

Dette eksempel giver følgende output:

![ModifiersInLuaHBTeX.png](/files/5d4b6a897d441798d140a8d0d4080cc8d54c490c)

#### UTF-8: dets rolle i lagring af Unicode-tekst

Enhver tekst eller kode, du skriver eller indsætter i Overleafs Code Editor (eller Visual Editor), vil blive gemt i UTF-8-format, så vi gennemgår kort, hvad UTF-8 egentlig betyder. UTF står for Unicode Transformation Format, og UTF-8’s rolle i lagring eller transmission af Unicode-kodet tekst angives af frasen “Transformation *Format*.”

Unicode’s kodepunktsværdier spænder fra 0 til maksimalt 1.114.111, så det er umuligt at repræsentere alle Unicode-tegnværdier ved hjælp af en enkelt 8-bit byte, som kun kan lagre op til 256 forskellige værdier: 0 til 255. Det er dog muligt at repræsentere et vilkårligt Unicode-kodepunkt-heltal ved hjælp af en *sammenhængende sekvens* af byte-store værdier—det er princippet bag UTF-8.

UFT-8 giver en “opskrift” på *at omdanne* (dvs. at “kode” eller “konvertere”) en Unicode-heltalskodepunktværdi til en unik sekvens på 1 til 4 sammenhængende byte-store heltal: antallet af sammenhængende bytes, der kræves, afhænger af kodepunktets værdi. Derfor kan du læse om, at UTF-8 lagrer Unicode-tegn som *multibytesekvenser* fordi et enkelt Unicode-tegn (et kodepunkt-heltal) repræsenteres i UTF-8 som en sekvens på 1 til 4 sammenhængende bytes.

Naturligvis kan tekst gemt i UTF-8 konverteres tilbage til sin oprindelige sekvens af heltalsværdier for Unicode-kodepunkter—det er, hvad XeTeX eller LuaTeX/LuaHBTeX skal gøre, når de læser en LaTeX-inputfil gemt i UTF-8-format. Disse TeX-motorer skal kende de indgående Unicode-kodepunkts- (tegn-) værdier, før de kan sætte teksten. Bemærk, at pdfTeX ikke har indbygget UTF-8-dekodningsfunktionalitet, så den må stole på TeX-makroer til at behandle (afkode) indtastet tekst formateret i UTF-8.

**Nogle UTF-8-eksempler**

* Det arabiske tegn ش (“sheen”) har Unicode-kodepunkt 0634 i hexadecimal (base 16) eller 1588 i decimal (base 10). I UTF-8 repræsenteres ش som 2 (hexadecimal) værdier D8 og B4, så tegnet ش vil blive gemt som de to sammenhængende bytes D8B4 i UTF-8-kodet tekst.
* Emoji-tegnet 😀 har Unicode-kodepunkt 1F600 i hexadecimal (base 16) eller 128512 i decimal (base 10). I UTF-8 repræsenteres 😀 som 4 (hexadecimal) værdier F0, 9F, 98 og 80, så tegnet 😀 vil blive gemt som de 4 sammenhængende bytes F09F9880 i en UTF-8-tekstfil.

#### Specialtegn brugt i Unicode-baseret emoji-tekstbehandling

Ikke alle tegn, der er kodet i Unicode, er beregnet til visuel præsentation via glyphs i en skrifttype: nogle kodede tegn er udpeget som *ikke-udskrivbare tegn* hvis formål er at hjælpe specialiserede tekstbehandlingsfunktioner (i understøttende software). Forskellige softwareprogrammer tilbyder varierende grad af understøttelse af de ikke-udskrivbare tegn, der er kodet i Unicode, så resultatet vil afhænge af det softwaremiljø—programmer og skrifttyper—der bruges.

**To ikke-udskrivbare tegn, du bør kende**

* **Zero width joiner (ZWJ)**, kodepunkt 200D (hexadecimal), er, som navnet antyder, designet til at udløse inputtegns “sammenføjningsadfærd”—men kun hvis disse inputtegn *har* en defineret sammenføjningsadfærd.
* **Zero width non-joiner (ZWNJ)**, kodepunkt 200C (hexadecimal), er designet til at *forhindre* hæmme den “sammenføjningsadfærd”, som inputtegn ellers kunne udvise. For eksempel kan du bruge ZWNJ til at forhindre sammenføjningsadfærden hos på hinanden følgende arabiske tegn, som normalt ville blive behandlet (formet) til deres sammenføjningsformer.

Unicode har offentliggjort en liste over [anbefalede Emoji ZWJ-sekvenser](https://unicode.org/emoji/charts/emoji-zwj-sequences.html) som bruger en U+200D ZERO WIDTH JOINER (ZWJ) til at kombinere emoji-tegnsekvenser til én sammensat emoji-glyph—hvis den er tilgængelig i de skrifttyper, der bruges.

**Eksempel på brug af zero width non-joiner**

Det følgende minimale kodestykke bruger Scheherazade OpenType-skrifttypen, som er inkluderet i TeX Live, til at definere en LaTeX-skrifttype kaldet `\arabicfont` som vi kan bruge til at sætte lidt arabisk. Linjen

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

bruger et zero width non-joiner-tegn via `\Uchar"200C`, for at forhindre den normale sammenføjningsadfærd hos de to arabiske bogstaver ل (lam) og ا (alef). Bemærk brugen af `\textdir TRT` til at sætte tekstretningen som højre-mod-venstre:

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

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

Dette eksempel giver følgende output:

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

## Begrebet “tekstformning”

Lad os begynde med et visuelt eksempel ved hjælp af en urdu-oversættelse af ordet “educational”. Tekst på urdu-oversættelsen kan være skrevet på et tastatur eller en touchscreen-enhed og ville blive oprettet som en simpel lineær sekvens af Unicode-arabiske tegn. Men når den tekst sættes eller vises på enhedens skærm i [Nastaliq-stil](https://en.wikipedia.org/wiki/Nastaliq), bliver resultatet en kompleks todimensional arrangement af glyphs.

Ved hjælp af vores urdu-eksempel sammenligner den følgende grafik den lineære input af Unicode-arabisk *tegn* med output sat i Nastaliq-stil, bestående af en todimensional arrangement af *glyffer* til stede i den (gratis) skrifttype [Awami Nastaliq](https://software.sil.org/awami/download/):

![](/files/42d97076c3cabc2a2a128242a9e84cce2a0a5de8)

Processen med at “oversætte” inputtegn til et sæt korrekt placerede outputglyphs kaldes *tekstformning*, og er en afgørende komponent i behandling af tekst forud for dens visning eller sats. Vores eksempel brugte tekst på urdu-sproget (arabisk skrift), fordi resultatet af formningen er tydeligt synligt, i modsætning til sprog, der bruger det latinske alfabet, såsom engelsk, hvor formningen er langt mindre fremtrædende—såsom produktionen af simple ligaturer.

Tekstformning er afgørende ved brug af skriftsystemer såsom [Arabisk](https://en.wikipedia.org/wiki/Arabic), [Hebraisk](https://en.wikipedia.org/wiki/Hebrew_language), [Devanagari](https://en.wikipedia.org/wiki/Devanagari) eller [Malayalam](https://en.wikipedia.org/wiki/Malayalam), blot fire eksempler på såkaldte *komplekse skriftsystemer*. For at sikre korrekt præsentation af tekst i disse skriftsystemer og de sprog, der bruger dem, skal formningsprocessen omhyggeligt tage højde for eventuelle formningsregler og nuancer, der findes i den specifikke kombination af skrift og sprog. For eksempel kræver nogle sprog, at flere inputtegn genererer en bestemt outputglyph, eller der kan være komplekse krav til omhyggelig placering af diakritiske tegn og omarrangering mellem glyphs for at sikre, at enkelte glyphs er positioneret korrekt (i forhold til hinanden).

Generelt kræver formning af et stykke tekst flere oplysninger:

* Skriftsystemet eller *skriftsystem* hvori teksten er skrevet.
* Den specifikke *sprog* der bruges. Individuelle skriftsystemer kan bruges til flere sprog, og hver kombination af skriftsystem og sprog har sine egne finesser/nuancer i formgivningen.
* Skriften *retning* af teksten—såsom højre-mod-venstre eller venstre-mod-højre.
* Et *skrift* som leverer de glyffer, der skal til for at repræsentere den formgivne tekst og eventuelt indeholder yderligere “formgivningsregler”, som styrer tekstformgivningsprocessen.

Kravene til tekstformgivning, især for komplekse skriftsystemer og deres tilhørende sprog, kan være ekstremt detaljerede og nuancerede, hvilket indikerer behovet for specialiseret software, der kan anvende potentielt meget komplekse tekstformgivnings-“regler”. Ikke overraskende findes sådan software og omtales som en *tekstformgivningsmotor*; den, vi vil diskutere, hedder [Harfbuzz](https://en.wikipedia.org/wiki/HarfBuzz), hvis dokumentation er værd at læse—for eksempel [Hvorfor har jeg brug for en formgivningsmotor?](https://harfbuzz.github.io/why-do-i-need-a-shaping-engine.html).

**Yderligere læsning om tekstformgivning**

Disse korte introduktioner kan varmt anbefales:

* [Hvad er tekstformgivning?](https://harfbuzz.github.io/what-is-harfbuzz.html#what-is-text-shaping)
* [Hvorfor har jeg brug for en formgivningsmotor?](https://harfbuzz.github.io/why-do-i-need-a-shaping-engine.html)

**Teknisk note: flere formgivningsteknologier (modeller)**

HarfBuzz-tekstformgivningsmotoren understøtter flere “formgivningsteknologier”, som adskiller sig i, hvordan de implementerer formgivningsprocessen—hver implementering omtales som en *formgiver*, herunder i `luaotfload` dokumentationen. Hovedfokus i denne artikel er OpenType-formgivning, men en alternativ, gratis teknologi er [Graphite](https://scripts.sil.org/cms/scripts/page.php?site_id=projects\&item_id=graphite_aboutOT), udviklet af [SIL International](https://www.sil.org/). En anden formgivningsmodel, som understøttes af HarfBuzz, er [Apple Advanced Typography (AAT)](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6AATIntro.html)—skrifter, der understøtter AAT, bruges generelt på Apple-teknologiplatforme.

**Eksempel med Graphite-formgiveren**

Det følgende eksempel sætter noget urdu-tekst med en skrifttype kaldet [Awami Nastaliq](https://software.sil.org/awami/download/), som understøtter Graphite-formgivning og er tilgængelig på Overleaf. Awami Nastaliq er skabt af [SIL International](https://www.sil.org/), organisationen bag udviklingen af Graphite-teknologien.

Det følgende eksempel demonstrerer den avancerede formgivningskapacitet i Graphite-baserede skrifter—bemærk, hvordan `luaotfload` skriftdeklarationen vælger Graphite-formgivning ved hjælp af `shaper=graphite2`.

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

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

\vskip 75bp

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

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

Dette eksempel giver følgende output:

![](/files/c3393d763129c75618e289d103730f7caeadb74d)

#### Emoji og tekstformgivning

Tekstformgivning er blevet introduceret ved hjælp af eksempler fra et sprog med komplekst skriftsystem, urdu. Det kan dog komme som en overraskelse at lære, at gengivelse af de korrekte emoji-glyf(er) kræver, at tekstformgivning anvendes på Unicode-tekst, der indeholder sekvenser af emoji-tegn—[som bemærket af hovedudvikleren af HarfBuzz](https://github.com/harfbuzz/harfbuzz/issues/2428#issuecomment-639108677):

> ... at formgive emoji med HarfBuzz er helt inden for området og faktisk nødvendigt for at få familieemoji, hudfarve osv.

Vi vil se på eksempler på dette.

### Ansvarsfordeling: tekstformgivningsmotor + OpenType-skrifter

I praksis er tekstformgivning en “fælles operation” eller arbejdsdeling mellem logikken og reglerne indbygget i tekstformgivningsmotoren og yderligere formgivningsregler og data indbygget i den eller de skrifter, der bruges—fra nu af dækker vi OpenType-baseret formgivning *kun*.

For at udføre formgivning forsynes tekstformgivningsmotoren typisk med noget Unicode-tekst, et angivet skriftsystem og sprog, eventuelt en skrive-retning og vigtigst af alt en OpenType-skrift til brug under formgivningsprocessen—skriften leverer outputtet: et sæt glyffer og positioneringsdata. Hvis det ønskes, kan formgivningsmotoren anvende yderligere regler ([OpenType-funktioner](https://en.wikipedia.org/wiki/List_of_typographic_features#OpenType_typographic_features)) indeholdt i den OpenType-skrift, der bruges—hvilke regler der skal anvendes, kan normalt vælges af brugeren fra listen over funktioner, som skrifttypen understøtter.

Resultatet af formgivningsprocessen er en *liste over glyffer* i den OpenType-skrift, sammen med *mellem-glyf-* positioneringsdata. Disse positioneringsdata vedrører *den relative placering af de formgivne glyffer*; de refererer ikke til absolut placering på den satssatte side eller andet medie/indhold såsom en webside, en Tweet osv. Gengivelsessoftwaren (satsmotor, webbrowser osv.) bruger informationen om positionering mellem glyfferne til at sikre, at glyfferne er korrekt placeret i forhold til hinanden, efter at de er samlet og indarbejdet i det endelige output.

#### Hvad er en liste over glyffer?

Internt tildeles hver glyf i en OpenType-skrift en numerisk identifikator, en heltalsværdi kaldet glyfindekset—også kaldet glyfidentifikatoren eller GID. Når tekstformgivningsmotoren har fuldført sin opgave, returnerer den sine resultater som en *liste over glyfidentifikatorer* plus *positioneringsdata* for disse glyffer.

Enkeltglyffer i OpenType-skrifter tildeles indekser (identifikatorer) af skrifttypens skaber, hvilket gør det til en meget skrifttype-specifik og vilkårlig værdi—den kan også variere mellem versioner af en bestemt skrifttype. Du bør aldrig antage, at den samme GID-værdi vil gælde for “lignende” glyffer i forskellige skrifter; det vil den næsten helt sikkert ikke. Hvis du har en liste over glyfidentifikatorer, som er leveret af en formgivningsmotor, kan du kun bruge dem til at få adgang til glyffer i den skrifttype, de blev hentet fra.

#### Hvad er OpenType-skrifter?

Internettet er *fyldt* med forklaringer og detaljer om OpenType-skrifter, så vi begrænser os til en kort beskrivelse. OpenType-specifikationen [OpenType-specifikationen](https://docs.microsoft.com/en-us/typography/opentype/spec/) er et komplekst dokument designet til udviklere, men i bund og grund definerer det et filformat eller en beholder til skrifttypedata. En OpenType-skrift indeholder data, der beskriver glyf-formerne, sammen med oplysninger om de understøttede skriftsystemer og sprog, metadata om skriften og forskellige “tabeller”, der definerer [typografiske funktioner](https://en.wikipedia.org/wiki/List_of_typographic_features#OpenType_typographic_features) understøttet af skrifttypen.

En tekstformgivningsmotor kan normalt instrueres til selektivt at anvende (bruge) en skrifttypes funktioner under formgivningsprocessen og dermed anvende specifikke typografiske effekter (“regler”), som vælger det passende sæt glyffer, der er indeholdt i skrifttypen. Den valgte skrifttype skal understøtte og levere glyfferne til de funktioner, som tekstformgivningsmotoren bliver bedt om at anvende.

#### Kodede og ukodede “glyffer”

OpenType-skrifter indeholder en datatabel kaldet [cmap](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap) (Character to Glyph Index Mapping), som mapper mængden af Unicode-tegn, der understøttes af skrifttypen, til det tilsvarende glyfindeks i den skrifttype. Den følgende video giver et kort indblik i cmap-tabellen i en skrifttype kaldet `lmmono10-regiular.otf` (inkluderet i TeX Live).

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

Imidlertid indeholder skrifter typisk mange glyffer, som ikke repræsenterer et bestemt Unicode-tegn og ikke er inkluderet som en del af den cmap-tabel. Derfor kan det sæt glyffer, der findes i en OpenType-skrift, opdeles i to hovedmængder:

* kodede glyffer, der repræsenterer Unicode-tegn;
* ukodede glyffer, der ikke repræsenterer Unicode-tegn.

Kodede glyffer kan tilgås ved at inkludere det relevante Unicode-tegn i teksten—men hvad med ukodede glyffer, hvordan bruges/tilgås de? Disse glyffer bruges typisk til at levere outputtet af tekstformgivningsoperationer, herunder anvendelse af skriftegenskaber for at producere specifikke visuelle/typografiske effekter.

### OpenType-farvefonte

Emoji-tegn forventes at blive vist/gengivet i fuld farve—sort-hvide emoji giver ikke helt den “fulde emoji-oplevelse”. Men på tidspunktet for Unicode's første kodning af emoji havde [OpenType-skriftespecifikationen](https://docs.microsoft.com/en-us/typography/opentype/spec/) ikke nogen passende mulighed for indlejring af *colorful*-glyfdata i OpenType-skrifter. Dette “hul” i OpenType fik førende teknologiplatformleverandører til at lede efter løsninger, og det efterfølgende “kapløb” resulterede i [forskellige forslag til at udvide OpenType](https://www.fontlab.com/news/color-font-format-proposals/) til at understøtte OpenType-farveskrifter—ikke kun for at vise farvede emoji-tegn (glyffer), men for at gengive enhver glyf i farve.

#### Fire varianter af OpenType-farveskrifter

[Adobe, Microsoft, Google og Apple fremsatte hver deres forslag](https://www.fontlab.com/news/color-font-format-proposals/) til at udvide OpenType til at understøtte OpenType-skrifter i fuld farve, og i sidste ende blev fire forslag vedtaget og inkluderet i den formelle OpenType-specifikation. For nemheds skyld kan vi groft gruppere disse fire varianter i vektorbaserede og rasterbaserede—men som vist i denne [GitHub-lageret](https://github.com/simoncozens/test-fonts)—er OpenType-specifikationen fleksibel nok til at understøtte OpenType-farveskriftfiler, der kombinerer disse fire grundteknologier.

* **Vektorbaserede OpenType-skrifter:**
* **Microsoft**: glyfformer beskrives ved hjælp af en form for lagdelte farvevektorer ([COLR](https://docs.microsoft.com/en-us/typography/opentype/spec/colr) og [CPAL](https://docs.microsoft.com/en-us/typography/opentype/spec/cpal) tabeller).
* [**Adobe og Mozilla**](https://www.w3.org/2013/10/SVG_in_OpenType/) ([SVG-tabel](https://docs.microsoft.com/en-us/typography/opentype/spec/svg)): glyfformer tegnes ved hjælp af SVG, som understøtter glyffer konstrueret ud fra vektorer *og rasterbilleder*. Se også [Adobes brugervejledning til SVG-skrifter](https://helpx.adobe.com/fonts/user-guide.html/fonts/using/ot-svg-color-fonts.ug.html).
* **Rasterbaserede OpenType-skrifter:**
* **Google**: glyffer repræsenteres af farvede PNG-billeder indlejret i skriften ([CBDT](https://docs.microsoft.com/en-us/typography/opentype/spec/cbdt) og [CBLC](https://docs.microsoft.com/en-us/typography/opentype/spec/cblc) tabeller).
* **Apple**: glyffer repræsenteres også af farvebilleder indlejret i skriften. Ud over PNG understøtter Apples mekanisme ([sbix-tabel](https://docs.microsoft.com/en-us/typography/opentype/spec/colr)) også JPEG og TIFF.

Som følge heraf er operativsystemer og applikationssoftware, der understøtter OpenType-farveskrifter, nødt til at håndtere nutidens blandede teknologilandskab. Desuden bør du være opmærksom på, at individuelle OpenType-farveskrifter—and *versioner* af den samme skrifttype—vil:

* have forskellig dækning af hele mængden af [Unicode-emoji-tegn](https://unicode.org/emoji/charts/emoji-list.html)—dvs. hvor mange emoji-tegn skrifttypen leverer glyffer til;
* bruge forskellige glyfdesigns til at repræsentere enkelte emoji-tegn;
* variere i de funktioner, de tilbyder, for at understøtte mere avancerede anvendelser af Unicode-standarderne, såsom [emoji-modifikatorer](https://unicode.org/reports/tr51/#Emoji_Modifiers_Table), og andre emoji-tekstbehandlingsfunktioner beskrevet i [Unicode Technical Standard #51: Unicode Emoji](https://unicode.org/reports/tr51/).

#### Hype omkring HarfBuzz

Vi har henvist til behovet for en *tekstformgivningsmotor*: software, der tager noget indgående Unicode-tekst, skrevet ved hjælp af en bestemt kombination af skriftsystem og sprog, og som ved hjælp af en udvalgt skrifttype former teksten til en sekvens af glyffer, sammen med positioneringsdata, som kan bruges til at sætte den oprindelige indtastede tekst.

[HarfBuzz](https://harfbuzz.github.io/) er en sådan tekstformgivningsmotor: den er [et open source-kodebibliotek](https://github.com/harfbuzz/harfbuzz) og resultatet af mere end et årtis forskning og udvikling—og er stadig under aktiv udvikling og implementering som en del af mange softwareprodukter. HarfBuzz udfører ikke selv “sats”, men leverer “tekstformgivningstjenester” til software, der vælger at integrere det, herunder XeTeX, LuaHBTeX, [Adobe PhotoShop og Adobe InDesign](https://en.wikipedia.org/wiki/HarfBuzz).

Ved at inkorporere HarfBuzz kan TeX-motorer drage fordel af dens avancerede tekstformgivningsmuligheder til at levere meget sofistikeret flersproget sats, især for komplekse skriftsystemer såsom arabisk, hebraisk, devanagari og mange andre. Bemærk også, at HarfBuzz bruges til at behandle og forme Unicode-emoji-teksttegn, hvilket vi vil undersøge nærmere.

Den følgende grafik opsummerer den rolle, HarfBuzz spiller, når den integreres med software såsom XeTeX eller LuaHBTeX under sats af tekst i et komplekst skriftsystem såsom arabisk:

![Et overblik over arabisk tekstformgivning med HarfBuzz](/files/63a40561f5424752c2e18987a1e5ad30effa003d)

**Udforsk HarfBuzz**

Enhver, der er interesseret i at lære mere om HarfBuzz og de OpenType-formgivningstjenester, den leverer til XeTeX og LuaHBTeX, kan [downloade en binær distribution af HarfBuzz](https://github.com/harfbuzz/harfbuzz/releases) som indeholder HarfBuzz-biblioteket (til programmører) og kommandolinjeværktøjerne `hb-view` og `hb-shape`.

**Eksempel: sådan bruger du hb-view**

Opret en ny fil i din foretrukne teksteditor med UTF-8-understøttelse, og kopier/indsæt de følgende seks emoji-tegn 👋👋🏻👋🏼👋🏽👋🏾👋🏿 i den tekstfil, og gem derefter i UTF-8-format til en fil kaldet for eksempel `emoji.txt`.

Bemærk, at din teksteditor muligvis viser (fallback-)sort-hvide versioner af emoji'erne, fordi den ikke er i stand til (programmeret til) at gengive farveglyffer. Når disse 6 emoji er gemt, bør filen `emoji.txt` indeholde UTF-8-data for følgende sekvens af Unicode-emoji-tegn—vi har adskilt emoji-modifikatorer med kommaer kun for *læsbarhedens skyld*:

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

Der bør være i alt **11** Unicode-tegn, hvor hvert genererer 4 bytes UTF-8-data, så den resulterende `emoji.txt` fil bør være 44 bytes lang, eksklusive eventuelle linjeslutmarkører, der bruges i slutningen af linjen, som indeholder emoji'erne.

Den `hb-view` værktøj kan bruge filen `emoji.txt`, sammen med en passende OpenType-farveskrift efter eget valg, såsom `NotoColorEmoji.ttf`, til at generere en SVG-fil med HarfBuzz' formgivne output. Det følgende kommandolinjeeksempel, som skal **skrives på én linje** i din terminal, vil generere SVG-filen `emoji.svg`:

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

Ved vellykket udførelse kan filen `emoji.svg`, genereret af `hb-view`, åbnes i Inkscape og bør se nogenlunde sådan ud:

![Hbvieemoji.png](/files/0b21fa06296cb65f83efbf75867fa2fb76fc0f3c)

`hb-view` kan bruges til at udforske HarfBuzz-formgivning for enhver passende Unicode-tekstfil og OpenType-skrift—det er bestemt ikke begrænset til brug med emoji! Skriv

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

for at se det væld af kommandolinjeindstillinger for dette kraftfulde og praktiske værktøj. God formgivning!

## Tekstformgivning og TeX-motorer

Her gennemgår vi tekstformgivningsfunktionerne i XeTeX og TeX-motorfamilien LuaTeX.

### XeTeX

XeTeX blev udviklet i begyndelsen af 2000'erne og var pioner for flere nyskabelser inden for TeX-baseret sats, især *indbygget* understøttelse af:

* læsning af Unicode-tekst i UTF-8-format;
* brug af OpenType-skrifter;
* tekstformgivning til flersproget sats;
* OpenType-baseret matematiksats.

XeTeX's evne til nemt og bekvemt at sætte tekster i komplekse skriftsystemer skyldes dens indbyggede tekstformgivningsfunktioner—oprindeligt baseret på den, nu udfasede, [ICU LayoutEngine](http://userguide.icu-project.org/layoutengine). Takket være arbejdet af Khaled Hosny skiftede XeTeX til at bruge HarfBuzz til tekstformgivning, som bemærket i en meddelelse fra [marts 2013](https://tug.org/pipermail/xetex/2013-March/024118.html). For alle, der ønsker at sætte flersproget tekst, nævnes XeTeX normalt som det foretrukne TeX-program—men nu findes der et andet valg, LuaHBTeX, som vi vil udforske.

### LuaTeX og LuaHBTeX

Udviklingen af LuaTeX begyndte omkring 2005, men fulgte en helt anden designfilosofi end XeTeX, som inkorporerede nye funktioner *direkte i* XeTeX-softwaren. I modsætning til XeTeX valgte LuaTeX's udviklere at “...tilbyde et minimalt sæt værktøjer og ingen løsninger.” (se [Reference Manual for LuaTeX](https://www.pragma-ade.com/general/manuals/luatex.pdf)). I stedet for at levere en række yderligere funktioner *indbygget i* LuaTeX-baserede motorer åbnes LuaTeX-motorernes interne mekanismer, så udviklere og erfarne brugere kan udnytte det integrerede Lua-scriptsprog til at bygge deres egne løsninger.

For eksempel kan LuaTeX-motoren, i modsætning til XeTeX, *direkte* ikke bruge OpenType-skrifter; i stedet skal OpenType-skrifter indlæses og “forberedes til brug” gennem fontindlæsningsfunktioner skrevet i Lua-kode. Disse fontindlæsningsfunktioner omtales som *callback* funktioner: Lua-kode, som LuaTeX vil kalde (“udføre”), når der anmodes om at indlæse en skrifttype.

Derudover leverer LuaTeX-motoren ingen *indbygget* tekstformgivningsfunktioner—de skal også leveres af ekstern kode, som LuaTeX-motoren kan kalde på for at få leveret tekstformgivningstjenester. Dette står igen i kontrast til XeTeX-motoren, som indarbejdede tekstformgivningsfunktioner i kernen af softwaren.

#### luaotfload: afgørende for brug af OpenType-skrifter i LuaTeX/LuaHBTeX

LuaTeX's callback-mekanisme til fontindlæsning giver stor fleksibilitet, om end på “bekostning” af yderligere programmering. Heldigvis for brugere af LuaLaTeX har TeX-fællesskabet udviklet en pakke kaldet `luaotfload`, som er en del af [den årlige udgivelse af TeX Live](https://www.tug.org/texlive/) og selvfølgelig er tilgængelig for Overleaf-brugere.

`luaotfload` er [tilgængelig på CTAN](https://ctan.org/pkg/luaotfload?lang=en) og har et [udviklingsarkiv på GitHub](https://github.com/latex3/luaotfload) hvor du kan følge de seneste udviklinger og [nye udgivelser](https://github.com/latex3/luaotfload/releases).

`luaotfload` kan indlæses direkte i en LaTeX-dokuments præambel via

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

Bemærk, at `luaotfload` er navnet på en LaTeX *pakken*, hvilket betyder, at den har filnavnet `luaotfload.sty`. Hvis du ønskede at bruge `luaotfload` med plain TeX, kan du gøre det ved at tilføje linjen

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

til dit plain TeX-dokument.

Normalt behøver brugere af LuaLaTeX—dvs. dem, der sætter LaTeX ved hjælp af LuaTeX/LuaHBTeX—ikke at arbejde direkte med `luaotfload` fordi [`fontspec` pakken](https://ctan.org/pkg/fontspec) vil indlæse `luaotfload` pakken for dig og håndtere mange lavniveau-detaljer gennem brugerniveau-kommandoer leveret af `fontspec` pakken.

### LuaHBTeX: nye muligheder for tekstformgivning

`luaotfload` er et modent og kraftfuldt Lua-bibliotek, som leverer LuaTeX's håndtering af OpenType-skrifter—sammen med leveringen af tekstformgivningstjenester for en række sprog og skriftsystemer. Oprindeligt blev tekstformgivningsfunktionerne i `luaotfload` implementeret i ren Lua-kode, men udgivelsen af TeX Live 2020 bragte endnu en mainstream-mulighed for tekstformgivning—en ny LuaTeX-baseret motor kaldet LuaHBTeX.

“HB” i LuaHBTeX står for HarfBuzz—i bund og grund er LuaHBTeX den oprindelige LuaTeX-motor *plus* med en integreret HarfBuzz-tekstformgivningsmotor. I tråd med LuaTeX's designfilosofi betyder tilgængeligheden af HarfBuzz ikke *automatisk* at tekst vil blive formgivet af LuaHBTeX: HarfBuzz er endnu et værktøj, som kan bruges til at bygge tekstformgivningsløsninger.

LuaHBTeX's integration af HarfBuzz er [programmerbar via Lua-kode](#introduction-to-the-luahbtex-harfbuzz-api), hvilket har gjort det muligt for `luaotfload`’s udviklere at tilføje HarfBuzz-baserede tekstformgivningsløsninger. Derfor, [startende med version 3.1, udgivet den 5. november 2019](https://github.com/latex3/luaotfload/releases/tag/v3.1), `luaotfload` blev forbedret til at drage fordel af HarfBuzz—hvilket gjorde HarfBuzz' tekstformgivningsfunktioner nemme at få adgang til for den almindelige bruger.

Læsere, der er interesserede i de tekniske detaljer om integrationen af HarfBuzz med LuaTeX, kan læse denne [artikel af Khaled Hosny](https://www.tug.org/TUGboat/tb40-1/tb124hosny-harfbuzz.pdf).

### luaotfload: to muligheder for tekstformgivning (hvornår bør HarfBuzz bruges?)

Brugere af LuaLaTeX har nu to muligheder for tekstformgivning:

* `luaotfload`’s oprindelige (node-baserede) implementering af tekstformgivning, skrevet udelukkende i Lua;
* `luaotfload`’s HarfBuzz-baserede formgivning—tilgået via Lua-kode, der kalder HarfBuzz' tekstformgivningsfunktioner.

`luaotfload` giver adgang til disse to formgivningssystemer via dens “`mode`”-parameter—selvom de fleste brugere vil bruge den tilsvarende `fontspec` “`Renderer`”-indstilling i stedet for direkte at bruge lavniveaufunktioner i `luaotfload`.

Hver af `luaotfload`s tekstformgivningsløsninger har deres styrker og (nuværende) svagheder, men hvilken skal du bruge, og hvornår? Her er nogle punkter at overveje:

* `luaotfload`s egen node-baserede behandling kan være hukommelseskrævende, især for store CJK OpenType-skrifter. Brug af HarfBuzz til formgivning af CJK-tekst kan give forbedringer i hastighed og reduktioner i hukommelsesforbrug.
* Brug HarfBuzz til komplekse skriftsystemer, fordi det “...forbedrer gengivelsen af indiske og arabiske skriftsystemer betydeligt og anbefales stærkt til sådanne skriftsystemer.” (se `luaotfload` manualen).
* HarfBuzz' integration i `luaotfload` er stadig relativt ny og under videre udvikling. På tidspunktet for skrivningen (juli 2021) tilrådes det at bruge luaotfloads indbyggede formgivning (sætning `mode=node`) til dine hoveddokument-skrifter, især hvis dit dokument bruger latinsk skrift. Se denne [GitHub-issue](https://github.com/latex3/luaotfload/issues/175#issue-801120377), som opsummerer problemerne og diskussionerne. Hvis du vil eksperimentere, kan du bruge `luaotfload` til at indlæse en skrifttypefil og oprette to LaTeX-skrifter: en som bruger HarfBuzz-baseret formgivning og den anden, som bruger Lua-baseret formgivning. Overleaf oprettede et [eksempelprojekt](#sample-project-arabic-shaping), som demonstrerer dette.
* Brug ikke HarfBuzz til håndtering af matematiske skrifter. Som udviklere på tex.stackexchange har diskuteret, er HarfBuzz [ikke designet til at håndtere skrifter til matematiksats](https://tex.stackexchange.com/questions/544881/does-luahbtex-with-harfbuzz-renderer-completely-supports-math-formating) så brug det ikke til det formål.

**Eksempelprojekt: arabisk formgivning**

Her er et Overleaf-projekt, der bruger flere arabiske skrifttyper af høj kvalitet til at sammenligne `luaotfload`s node-baserede tekstformgivningstjenester (`mode=node`) med HarfBuzz' (`mode=harf`):

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

Dette projekt inkluderer output vist i det følgende billede:

![Sats af arabisk](/files/f33cdfb6b01721596deb0a902447f834a3ef7d67)

### Valg af “Renderer” i fontspec

Som nævnt i dens [dokumentationen](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf), `fontspec` “...giver brugere af enten XeTeX eller LuaTeX mulighed for at indlæse OpenType-skrifter i et LaTeX-dokument”. Hvis du bruger LuaTeX- eller LuaHBTeX-motorerne, `fontspec` vil indlæse `luaotfload` biblioteket for dig og leverer derudover en række praktiske kommandoer på brugerniveau, som mindsker behovet for at arbejde med `luaotfload`s lavniveaufunktionalitet.

Så hvordan vælger du mellem HarfBuzz' formgivning og den indbyggede formgivning, som leveres af `luaotfload`? Svaret findes i den fremragende [`fontspec` dokumentationen](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf), især del VI: LuaTeX-only skrifttypefunktioner. `fontspec` giver en indstilling kaldet `Renderer` som kan sættes, når skrifttypen defineres via `fontspec`. `Renderer` styrer lavniveaubehandlingen af skriften. De to interessante muligheder er

* `Renderer = Node`: standard“mode” til sats af OpenType-skrifter—den bruger `luaotfload`s tekstformgivningsfunktioner implementeret udelukkende i Lua.
* `Renderer = Harfbuzz`: denne “mode” definerer/indlæser skrifttypen til brug med HarfBuzz-tekstformgivningsmotoren. `luaotfload` bruger LuaHBTeX's API til at kalde funktioner i HarfBuzz.

For mere information se [`fontspec` dokumentationen](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf).

## TeX-motorer, HarfBuzz og farveemoji

Selvom XeTeX og LuaHBTeX begge integrerer HarfBuzz, tilbyder de forskellige niveauer af understøttelse af nogle af HarfBuzz' mere avancerede funktioner—mest bemærkelsesværdigt indlæsning og brug af OpenType-farveskrifter.

### XeTeX og OpenType-farveskrifter

Som nævnt er der to kategorier af OpenType-farveskrifter baseret på det dataformat, der bruges til at lagre skrifttypeglyfferne: vektorbaserede og rasterbaserede.

#### XeTeX og rasterbaserede OpenType-farveskrifter

XeTeX kan ikke indlæse rasterbaserede OpenType-farvefonte—såsom Googles [Noto Color Emoji](https://www.google.com/get/noto/help/emoji/) fulgte med TeX Live 2020. Hvis du for eksempel forsøger at indlæse Noto Color Emoji (NotoColorEmoji.ttf), vil XeLaTeX fejle med en potentielt misvisende fejl, der hævder, at Noto Color Emoji “cannot be found”. Følgende LaTeX-kode, sat med XeLaTeX, *fungerer ikke*:

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

[Åbn denne XeLaTeX-kode i Overleaf (den ***ikke*** virker).](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)

Den fejler med fejlen:

```
! Pakken fontspec-fejl: Skrifttypen "NotoColorEmoji" kan ikke findes.
```

På samme måde fejler et enkelt Plain TeX-eksempel behandlet af XeTeX også

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

[Åbn dette Plain TeX-(XeTeX)-eksempel i Overleaf (det ***ikke*** virker).](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-eksemplet rapporterer en lignende, men anderledes, fejlmeddelelse:

```
! Skriften \emojifont=[NotoColorEmoji.ttf] at 12.0pt kan ikke indlæses: Metric (TFM) fil
e eller installeret skrifttype blev ikke fundet.
l.1 \font\emojifont="[NotoColorEmoji.ttf]" at 12pt

Jeg kunne ikke læse størrelsesdataene for denne skrifttype,
så jeg vil ignorere skrifttypeangivelsen.
[Tryllekunstnere kan rette TFM-filer ved hjælp af TFtoPL/PLtoTF.]
Du kan prøve at indsætte en anden skrifttypeangivelse;
f.eks. skriv `I\font<samme skrifttype-id>=<erstatningsskrifttypenavn>'.
```

**Plain LuaHBTeX-eksempel**

Til sammenligning er her et minimalt Plain TeX-eksempel kompilieret med LuaHBTeX

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

[Åbn dette Plain TeX-(LuaHBTeX)-eksempel i Overleaf (det kompilerer med succes).](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)

#### Den egentlige årsag til XeTeX's fejl

Fejlmeddelelserne fra XeTeX skjuler delvist den egentlige årsag til problemet: OpenType-farvefonte, især rasterbaserede varianter, understøttes *ikke* af XeTeX. I virkeligheden kan XeTeX (Kpathsea) *finde* Noto Color Emoji-skrifttypen, men XeTeX kan ikke fuldt ud *indlæse* denne skrifttype og kan ikke initialisere interne skrifttypedatatabeller, som kræves for at bruge denne skrifttype til satsning. Internt *starter* går XeTeX igennem processen med at indlæse skrifttypen og tester den for “skalerbarhed” (ved hjælp af FreeTypes “definition” af “skalerbarhed”), men den test fejler, og XeTeX udsender en standard, og kan måske diskuteres som misvisende, TeX-motor-fejlmeddelelse.

**Teknisk note**

XeTeX's behandling af NotoColorEmoji.ttf blev undersøgt ved at kompilere en debug-version af XeTeX-eksekverbaren. Eclipse IDE blev brugt til at sætte et breakpoint ved XeTeX-funktionen `creatFontFromFile(filename, index, pointsize)`, og derefter trinvis gennemgå koden for at observere den efterfølgende behandling.

#### XeTeX og vectorbaserede OpenType-farvefonte

XeTeX kan *indlæse* vectorbaserede OpenType-farvefonte, men vil ikke producere farve-emoji i den resulterende PDF—hvis XeTeX overhovedet producerer en. I modsætning til LuaTeX, LuaHBTeX og pdfTeX sender XeTeX ikke satsede dokumenter i PDF-format. I stedet udsender XeTeX et mellemformat, *direkte* .xdv `(u` dvidet**x**dvi **) filformat, som konverteres til PDF af et værktøj kaldet**xdvipdfmx `. På tidspunktet for skrivningen`kan ikke indlejre de passende farve-emoji-glyfdata i PDF'en, så i bedste fald vil du se monokrome emoji—“fallback”-resultatet—i PDF'en, eller måske slet ingenting, afhængigt af den skrifttype, der bruges. `. På tidspunktet for skrivningen` Her er et XeLaTeX-eksempel, som bruger den OpenType-farveskrifttype

Her er et XeLaTeX-eksempel, som bruger den OpenType-farveskrifttype [TwemojiMozilla.ttf](https://ctan.org/tex-archive/fonts/twemoji-colr), tilgængelig i TeX Live. TwemojiMozilla.ttf bruger Microsofts COLR/CPAL-vektorformat til at lagre farveglyffer og fulgte med TeX Live 2020. I dette eksempel er XeTeX i stand til at indlæse skrifttypen, generere en `(u` og PDF-fil, men emoji-glyffen er ikke til stede i den satte PDF:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont{TwemojiMozilla.ttf}
\newcommand{\smiley}{{\emojifont\char"1F600}}
Her er et smiley-ansigt: \smiley
\end{document}
```

[Åbn denne XeLaTeX-kode i Overleaf (den MISLYKKES i at virke).](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)

I modsætning hertil virker koden ovenfor med LuaLaTeX, hvis du definerer `\emojifont` ved hjælp af `fontspec` indstillingen `[Renderer=HarfBuzz]`:

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

[Åbn denne LuaLaTeX-kode i Overleaf (den virker).](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 og OpenType-farvefonte

Gennem dens integrerede HarfBuzz-formgivningsmotor og `luaoftload` biblioteket giver LuaHBTeX understøttelse af alle fire varianter af OpenType-farveskrifttyper. Brugere af LuaLaTeX kan udnytte Unicode-baseret behandling af tekst, der indeholder emoji-tegn, fuldt ud eller blot pynte deres dokumenter med meget farverig tekst ved hjælp af OpenType-farvefonte.

Som nævnt tidligere kan de fire varianter af OpenType-farveskrifttyper klassificeres i to grupper:

* dem, der indeholder glyffer i rasterbilledformater, såsom PNG;
* andre, der bruger SVG-baserede formater eller Microsofts COLR/CPAL-mekanisme.

Vectorbaserede glyffformater har fordelen af skalerbarhed: de producerer skarpe glyfbilleder i enhver punktstørrelse.

**Brug af Microsoft COLR/CPAL-farvefonte med LuaHBTeX**

Hvis du vil bruge et vektorformat til dine OpenType-farve-emoji-fonte, så [TwemojiMozilla.ttf](https://ctan.org/tex-archive/fonts/twemoji-colr?lang=en), som er baseret på Microsofts COLR/CPAL-format. TwemojiMozilla.ttf er inkluderet i TeX Live, men du kan hente den seneste version fra dens [GitHub-lageret](https://github.com/mozilla/twemoji-colr/releases) og uploade den til dit Overleaf-projekt.

Her er et lille, `fontspec`-baseret eksempel, der bruger `Renderer=Harfbuzz`, som sætter en stor (vektor) emoji-and:

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

[Åbn dette LuaLaTeX-eksempel for at sætte en vectorand.](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)

Her er den (vektor)and, som eksemplet ovenfor producerer:

![](/files/7a45f325f070bccb87172011cecb4239097b5e17)

#### Brug af SVG-baserede OpenType-farvefonte med LuaHBTeX

På tidspunktet for denne artikels opdatering (juli 2023) er der kun lidt formel dokumentation om brugen af SVG-varianten af OpenType-farvefonte med LuaLaTeX. Nogle [kommentarer i online-diskussioner](https://github.com/latex3/luaotfload/issues/96) foreslår at bruge `fontspec`’s `RawFeature`, som vist i pseudokoden nedenfor. Erstat `*navn på din SVG-skrifttypefil her*` med navnet på en SVG-baseret skrifttypefil, som er tilgængelig for din LaTeX-kode:

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

Hvis du udelader `fontspec` og indlæser `luaotfload` direkte, kan du blive nødt til at erklære og angive en skrifttype på følgende måde—vores eksperimenter tyder på, at du skal udelade `mode=harf` indstillingen for at dette virker:

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

**Nogle advarsler**

Læsere, der er interesserede i at bruge SVG-varianten af OpenType-farvefonte, bør bemærke:

* SVG-variant OpenType-skrifttyper, der indeholder et stort antal glyffer, kan være [beregningsmæssigt kostbare for LuaLaTeX](#processing-svg-glyph-data) at behandle, hvilket potentielt kan resultere i [Overleaf-timeouts](/latex/da/vidensbase/038-fixing-and-preventing-compile-timeouts.md).
* LuaLaTeX's understøttelse af disse skrifttyper kan [betragtes som eksperimentel](https://github.com/latex3/luaotfload/issues/96#issuecomment-530317399): resultaterne kan variere afhængigt af den TeX Live-udgivelse, som dit projekt bruger; derfor anbefales det at eksperimentere og gå forsigtigt frem.

**Behandling af SVG-glyfdata**

SVG giver designere mulighed for at producere komplekse og farverige designs, der repræsenterer en skrifttypes glyffer—underlagt nogle SVG-begrænsninger [dokumenteret i OpenType-specifikationen](https://docs.microsoft.com/en-us/typography/opentype/spec/svg). TeX-motorer, herunder LuaHBTeX, kan dog ikke direkte importere (bruge) SVG-filer eller data—såsom de SVG-data, der bruges til at beskrive glyffformer i SVG-varianten af OpenType-farvefonte. En glyffs SVG-data skal konverteres til PDF-format, fordi LuaHBTeX kan bruge det til at sætte glyffen og producere det endelige PDF-dokument. Denne SVG-til-PDF-konvertering håndteres af Lua-kode i `luaoftload`: hver glyffs SVG-data udtrækkes fra skrifttypefilen, gemmes i en midlertidig `.svg` fil og konverteres til PDF ved hjælp af Inkscape via dens kommandolinje. Udtrækning af SVG-dataene og konvertering til PDF medfører en vis behandlingsomkostning, hvilket kan resultere i lange dokumentkompileringstider—især dokumenter, der bruger store SVG-skrifttyper med tusindvis af emoji-glyffer.

#### Rasterbaserede OpenType-farvefonte

**Brug af Googles CBDT/CBLC OpenType-farveskrifttypeformat med LuaHBTeX**

[Noto Color Emoji](https://fonts.google.com/noto/specimen/Noto+Color+Emoji) er en OpenType-farveskrifttype inkluderet i TeX Live, hvilket gør den nem at bruge i et Overleaf-projekt. Fordi Noto Color Emoji bruger PNG-formatgrafik til at repræsentere emoji-glyffer, kan vi bruge den til at sætte en stor (raster) ande-emoji—som demonstreret ved følgende eksempel. Bemærk igen, at `fontspec` skrifttypeangivelsen (`\emojifont`) bruger `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}
```

[Åbn dette LuaLaTeX-eksempel for at sætte en rasterand.](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)

Her er den rasterand, som eksemplet ovenfor producerer:

![En rasterand-emoji sat med LaTeX](/files/870a0a9576157a3e1598afe9bd8de5aeae5c9881)

Hvis du forsøger at bruge `NotoColorEmoji.ttf` men udelader `[Renderer=Harfbuzz]` fra `fontspec` angivelsen, vil LuaHBTeX fejle og udsende en fejlmeddelelse, når den forsøger at skrive PDF-filen:

```latex
! fejl:  (fil /usr/local/texlive/2020/texmf-dist/fonts/truetype/google/noto-em
oji/NotoColorEmoji.ttf) (ttf): loca-tabel ikke fundet
```

Årsagen til denne fejl i [loca-tabel](https://docs.microsoft.com/en-us/typography/opentype/spec/loca) er [forklaret på GitHub](https://github.com/latex3/luaotfload/issues/98#issuecomment-531610153).

**Brug af Apples sbix OpenType-farveskrifttypeformat med LuaHBTeX**

Offline-tests viser, at LuaHBTeX understøtter `sbix` varianten af OpenType-farveskrifttype, men per skrivende stund har vi ikke kunnet finde en passende licenseret `sbix`-variant farve-emoji-skrifttype til at demonstrere satsning af en and. Venligst [kontakte os](https://www.overleaf.com/contact) giv os besked,

## Introduktion til LuaHBTeX HarfBuzz-API'en

![Db.gif](/files/842d40f1a5f1a9bb60bc37a99d2a149367f6b196) ![Db.gif](/files/842d40f1a5f1a9bb60bc37a99d2a149367f6b196)

Skriftformning, især for sprog med komplekse skriftsystemer og endda emoji, er en iboende vanskelig opgave, så det er ikke overraskende, at HarfBuzz er et sofistikeret bibliotek, der kan være vanskeligt at arbejde med—medmindre du allerede er fortrolig med tekstformningsoperationer. I dette afsluttende afsnit ser vi på LuaHBTeX's integration af HarfBuzz, og hvordan man får adgang til det via Lua-kode i `\directlua`.

Vores eksempel bruger ret grundlæggende kode til at demonstrere LuaHBTeX HarfBuzz-API'en. Det er noget kunstlet, ikke i produktionskvalitet og heller ikke særlig praktisk, fordi det eneste formål er at introducere nogle kerneideer. Vi har delt Lua-koden i to `\directlua` stykker: det første indlæser `luaharfbuzz` biblioteket og opretter nogle globale variabler, som vi vil bruge i vores andet `\directlua` stykke, hvor vi definerer en makro kaldet `\codestoemoji`.

Det føles passende at efterligne Knuths brug af dobbelte farebøjninger (billede venligst af [dette websted](http://www.truetex.com/db.htm)) fordi indholdet er noget lavniveau og “kigger under motorhjelmen”—selvom vi håber, det kan være af interesse for den mere vovede læser. LuaHBTeX's integration af HarfBuzz er afledt af [luaharfbuzz-projektet på GitHub](https://github.com/ufyTeX/luaharfbuzz/wiki#projects-using-luaharfbuzz) hvor du kan finde en [introduktion til projektet](https://github.com/ufyTeX/luaharfbuzz/wiki) sammen med en [liste over luaharfbuzz-API'en](http://ufytex.github.io/luaharfbuzz/).

### Første skridt: indlæs luaharfbuzz-biblioteket og find en skrifttype

For at bruge LuaHBTeX's HarfBuzz-API skal vi først indlæse biblioteket (modulet) kaldet `luaharfbuzz`, indbygget i LuaHBTeX, og gemme den returnerede tabel i en (global) variabel, som vi vil kalde `hblib`:

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

Næste skridt er at finde en passende emoji-OpenType-farveskrifttype: vi bruger Noto Color Emoji—bemærk, at vi er meget dovne og ikke laver nogen fejlkontrol, hvis vi ikke finder den! For at finde den bruger vi `kpse` (Kpathsea)-biblioteket, som også er en del af LuaTeX/LuaHBTeX:

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

Nu hvor vi har adgang til HarfBuzz-biblioteket via vores variabel `hblib`og stien til en passende skrifttype (`pathtofontfile`), kan vi begynde at bruge `hblib`. Til at begynde med opretter vi en HarfBuzz-font og en HarfBuzz-face til brug i det andet `\directlua` kodestykke, hvor vi definerer vores makro.

```latex
%Opret HarfBuzz-face og HarfBuzz-font fra Noto Color Emoji
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)
```

#### HarfBuzz-font og HarfBuzz-face: hvad er de?

Et [HarfBuzz-face-objekt](https://harfbuzz.github.io/fonts-and-faces.html) repræsenterer en skrifttype indlæst fra en skrifttypefil, men uden at specifikke parametre (såsom størrelse) er sat. Et [HarfBuzz-fontobjekt](https://harfbuzz.github.io/fonts-and-faces.html) repræsenterer en *specifik instans* af en HarfBuzz-face; derfor kan forskellige HarfBuzz-fontobjekter afledes fra en enkelt HarfBuzz-face: hver HarfBuzz-font kan have sine egenskaber, såsom størrelse, sat til forskellige værdier. En HarfBuzz-face er et højere abstraktionsniveau end en HarfBuzz-font.

### Brug af skrifttypeglyffer til at oprette PNG-filer

Den sidste del af vores første `\directlua` stykke er en funktion kaldet `writePNGglyph(hbfontobject, glyphID)` som vi bruger til at demonstrere, at nogle OpenType-farvefonte, såsom Noto Color Emoji, bruger PNG-grafik til at repræsentere de emoji-glyffer, de indeholder.

Denne funktion bruger LuaHBTeX's HarfBuzz-API til at udtrække PNG-data fra glyffer og skrive disse data til en `.png` fil med navnet `Graphics<glyphID>.png`. Navnet på denne `.png` fil returneres til brug af `\includegraphics` til at indlejre PNG-glyfbilleder i vores satte PDF.

Med `writePNGglyph(hbfontobject, glyphID)` på plads ser vores første `\directlua` kodestykke sådan ud:

```latex
\directlua{

% Indlæs luaharfbuzz-biblioteket fra LuaHBTeX
hblib=require("luaharfbuzz")

% Find Noto Color Emoji-skrifttypen på Overleafs server
pathtofontfile=kpse.find_file("NotoColorEmoji.ttf","truetype fonts")

% Opret HarfBuzz-face og HarfBuzz-font fra Noto Color Emoji
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)

% Denne funktion accepterer en skrifttype og et glyf-id:
% den udtrækker glyffernes PNG-data og skriver
% det ud til en .png-fil

function writePNGglyph(hbfontobject, glyphID)

    % Hent glyffens PNG-data
    local pngblob=hbfontobject:ot_color_glyph_get_png(glyphID)
    local pngdata=pngblob:get_data()

    % Konstruer et filnavn til vores .png-fil
    local fname="Glyph"..glyphID..".png"

    % Skriv .png-filen og returner filnavnet
    local output = assert(io.open(fname, "wb"))
    output:write(pngdata)
    output:close()

    % Returner filnavnet til brug for \includegraphics
    return fname
end
}
```

### Andet \directlua-kodestykke: opret makroen \codestoemoji

Målet er at definere en makro `\codestoemoji` som vi kan kalde med et stykke tekst, der indeholder emoji-tegnkoder, som vi ønsker, at HarfBuzz skal forme. Specifikt vil vi bruge `\Uchar<tegnkode>` til at repræsentere hvert emoji-tegn; for eksempel:

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

Der foregår meget i definitionen af `\codestoemoji` som vi forklarer nedenfor, men definitionen ser sådan ud:

```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()
    % Glyf-tabellen, hbglyphs, er 1-baseret
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Reducer størrelsen på vores importerede PNG-billeder
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
}}
```

#### Forstå definitionen af makroen \codestoemoji

Den `\codestoemoji` makroen er for det meste Lua-kode indeholdt i `\directlua`, så hvis du gerne vil vide mere om *hvordan* `\directlua` hvordan [fungerer, så tjek Overleaf-artiklen `\directlua`](/latex/da/dybtgaende-artikler/09-an-introduction-to-luatex-part-2-understanding-directlua.md). Den forklarer, hvordan LuaTeX og LuaHBTeX behandler `\directlua` , når TeX/LaTeX-kommandoer er inkluderet i Lua-koden, og især behovet for at bruge `\noexpand` og `\unexpanded`.

**Håndtering af makroparameteren: "#1"**

Makroen begynder med disse tre linjer:

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

som udfører følgende opgaver:

* `local str="#1"`: dette opretter en Lua-streng ud fra input, der sendes ind af makroen;
* `local hbbuffer = hblib.Buffer.new()`: dette bruger HarfBuzz-API'en til at oprette en buffer til at holde den tekst, vi ønsker, at HarfBuzz skal forme;
* `hbbuffer:add_utf8(str)`: dette tilføjer en UTF-8-formateret streng, oprettet ud fra makroens input, til HarfBuzz-bufferen.

Den første kodelinje

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

ser ret ligetil ud, men dens virkemåde indebærer en del kompleksitet, som det er værd at udforske lidt nærmere.

Hvis vi ser på den tredje kodelinje

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

ser vi, at den bruger vores `str` variabel til at give HarfBuzz-bufferen en Unicode-streng formateret i UTF-8. For at det kan fungere, `str` skal variablen *hvordan* konverterede LuaHBTeX makroargumentet `"#1"`, der indeholder `\Uchar` kommandoer, til Lua-strengvariablen `str` indeholdende UTF-8-tekst til HarfBuzz?

Hvis vi ser på vores tilsigtede brug af `\codestoemoji` makroen:

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

inputtet, såsom `\Uchar"1F3F4\Uchar"E0067\Uchar"E0062\Uchar"E0065...`, ligner slet ikke en sekvens af emoji-tegn kodet i UTF-8. Derudover ved HarfBuzz intet om TeX-kommandoer. På en eller anden måde omdannes det rå TeX-input bestående af `\Uchar` kommandoer til Unicode-tegn kodet i UTF-8, som HarfBuzz kan bruge, men *hvordan*?

svaret ligger i adfærden af `\Uchar` kommandoen: at forsøge at kalde `\codestoemoji` ved hjælp af `\char` i stedet for `\Uchar` vil fejle, men *hvorfor*?

**\Uchar: ekspansion i \directlua**

Når `\codestoemoji` makroen kaldes, skal `\directlua` kommandoen, som er gemt i makroens definition, forberede Lua-kode til at blive sendt til LuaHBTeX's indbyggede Lua-fortolker. En del af denne kodeforberedelsesproces er ekspansion af eventuelle TeX/LaTeX-kommandoer, der findes i den oprindelige Lua-kode i makroens definition, sammen med ekspansionen af eventuelle makroargumenter, som brugeren har angivet. Denne ekspansionsproces giver en tokenliste, som efterfølgende konverteres tilbage til tekst, hvilket genererer Lua-koden til overførsel til Lua-fortolkeren. For nemheds skyld gengiver vi et diagram fra Overleaf-artiklen [fungerer, så tjek Overleaf-artiklen `\directlua`](/latex/da/dybtgaende-artikler/09-an-introduction-to-luatex-part-2-understanding-directlua.md):

![Mekanismen bag \directlua](/files/50c310adddb3126d340241c968209ed95f5a311c)

Makroen `\codestoemoji` er beregnet til at blive kaldt ved hjælp af `\Uchar` kommandoer og, [som nævnt tidligere i artiklen](#the-key-difference-expansion), `\Uchar` er en ekspanderbar kommando, hvis ekspansion genererer et tegntoken. Inden for behandlingsaktiviteterne i `\directlua`, udvider LuaHBTeX hvert `\Uchar<tegnkode>` kommando, hvor det *fjerner* hver `\Uchar<tegnkode>` fra inputtet og *erstatter* erstatter det med den tilsvarende ekspansionsværdi: et tegntoken, der repræsenterer `<tegnkode>`.

I den afsluttende behandlingsfase konverteres den oprindelige tokenliste genereret af `\directlua` tilbage *til tekst* for at blive den Lua-kode, der er bestemt til Lua-fortolkeren (se diagrammet ovenfor). Alle tegntokens, der produceres ved ekspansionen af `\Uchar` bliver også *konverteret tilbage til tekst*: denne konvertering af tegntokens til tekst genererer UTF-8-repræsentationerne af de oprindelige `<tegnkode>` værdier.

I vores eksempel, når Lua-koden er genereret og klar til Lua-fortolkeren, er makroinputtet for "#1" blevet konverteret til en sekvens af UTF-8-tekst: variablen `str` er nu en UTF-8-tekststreng, som sikkert kan tilføjes til HarfBuzz-bufferen.

**Hvorfor virker \char ikke?**

Det korte svar er fordi `\char` er *ikke* en udvidelig kommando. I modsætning til `\Uchar` kommandoer, `\char` kommandoer *fjernes ikke* fra inputtet under `\directlua`’s oprindelige behandling for at generere en tokenliste, “passerer de igennem” og bliver inkorporeret i den tokenliste, der opbygges af `\directlua`. For eksempel, hvis argumentet til `\codestoemoji` indeholdt `\char"1F3F4` ville LuaHBTeX omdanne det til en sekvens af tokens og gemme dem som en del af den samlede tokenliste, der genereres.

I næste behandlingsfase, hvor tokens konverteres tilbage til tekst, ville den resulterende Lua-kode indeholde den *bogstavelige streng* `\char"1F3F4` i teksten, der bruges til at definere vores variabel `str`. Når indholdet af `str` tilføjes til HarfBuzz-bufferen, vil det ikke indeholde en UTF-8-kodet sekvens, der repræsenterer emoji-tegnet "1F3F4, det ville indeholde den bogstavelige streng `\char"1F3F4`, som HarfBuzz vil forsøge at forme, og for vores formål ville det ikke give en emoji-glyf. I øvrigt vil strengen `\char"1F3F4` ville også give Lua-syntaksfejl, medmindre den blev oprettet som en “lang-bracket-streng”—se [Hvad er Lua escape-sekvenser](/latex/da/dybtgaende-artikler/09-an-introduction-to-luatex-part-2-understanding-directlua.md#what-are-e2809clua-escape-sequencese2809d3f) for baggrund om det problem.

Hvis vi forsøger at bruge `\codestoemoji` med en `\char` kommando, sådan her:

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

vil LuaHBTeX fejle og rapportere en syntaksfejl noget i stil med dette:

```latex
[\directlua]:1: ugyldig escape-sekvens nær '"\c'.
\codestoemoji ...ing \includegraphics }.}]]) end }

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

Lua-tolkeren stødte på et problem, så
resten af denne lua-chunk vil blive ignoreret.
```

#### Kalder HarfBuzz-formningsfunktionen

**Indstilling af bufferparametre**

HarfBuzz kræver undertiden yderligere oplysninger om teksten, som den bliver bedt om at forme. Du kan give disse oplysninger ved at konfigurere din `<buffer-variabel>` ved hjælp af *buffer-metoder*, såsom:

* `<buffer-variabel>:set_direction(*HarfBuzz-retning*)`;
* `<buffer-variabel>:set_language(*HarfBuzz-sprog*)`;
* `<buffer-variabel>:set_script(*HarfBuzz-skrift*)`.

For eksempel skal vi fortælle HarfBuzz, at retningen for vores emoji-tekst vil være fra venstre mod højre. For at gøre det bruger vi `set_direction()` metoden på vores `<buffer-variabel>` (kaldet `hbbuffer`) ved at skrive:

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

hvor `hblib.Direction.new("ltr")` opretter et “retning-objekt”, der er egnet til at blive sendt til HarfBuzz-motoren via Lua.

**Udfør formning**

Når bufferen er tilstrækkeligt initialiseret, kan vi bede HarfBuzz om at udføre den egentlige formning via funktionen `shape_full()`. I vores eksempel skriver vi:

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

De 3. og 4. parametre til `shape_full()` funktionen skal være Lua-tabeller—vi har brugt tomme tabeller “`{}`” for begge parametre. Den generelle form af `shape_full()` er:

```latex
shape_full(HarfBuzz-skrifttype, HarfBuzz-buffer, {skrifttypefunktioner}, {"shaper"}
```

* **`{"shaper"}`**: Behøver normalt ikke at være sat, men mulighederne er `{"ot"}` eller `{"graphite2"}`. Mere information om begrebet en “shaper” kan findes i [HarfBuzz-dokumentationen](https://harfbuzz.github.io/shaping-and-shape-plans.html)—bemærk, at denne dokumenterer det lavniveau C-API, ikke den Lua-baserede `luaharfbuzz` binding (implementering).
* **`{font features}`**: Dette er en tabel, der viser de [OpenType-funktioner](https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist)—understøttet af skrifttypen—som du vil have HarfBuzz til at anvende under formningen.

Enhver skrifttypefunktion, du vil bruge, skal oprettes ved hjælp af en `luaharfbuzz` biblioteksfunktion

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

hvor

* `library_instance` er din `luaharfbuzz` biblioteksinstans-variabel (`hblib` i vores eksempel);
* `feature_string` bruger en [syntaks til at definere funktioner](https://github.com/ufytex/luaharfbuzz/wiki/Feature-Strings). Eksempler på dette er `+smcp` for at aktivere små kapitæler eller `-kern` for at deaktivere kerning.

For eksempel:

```latex
local dosmcp = hblib.Feature.new("+smcp")
local nokern = hblib.Feature.new("-kern")
% Brug dine skrifttypefunktioner sådan her
local res = hblib.shape_full(hbfont, hbbuffer, {dosmcp,nokern},{})
```

#### Tilgang til resultatet: at hente glyfferne

Og endelig, hvis formningsoperationen lykkes, returneres de formede glyffer i buffer-variablen `hbbuffer` som vi oprettede tidligere i koden.

Vi tilgår glyfferne via buffer-metoden `get_glyphs()` og bruger en løkke til at hente hver enkelt glyf. Bemærk, at Lua-tabellen, der indeholder glyfferne, `hbglyphs` i vores eksempel er indekseret begyndende ved 1, ikke 0.

Hver glyfs *glyfidentifikator* (forvirrende kaldet `kodepunkt`), og HarfBuzz-skrifttypen (`hbfont`), sendes til `writePNGglyph()` funktionen, som opretter en PNG-fil ved hjælp af skrifttypens rasterbilledrepræsentation af den glyf.

`writePNGglyph()` skriver en PNG-fil ud og returnerer PNG-filnavnet, som bruges til at importere den (skalerede) PNG-fil i vores LaTeX-dokument via `\includegraphics[scale=0.75]{<fname>}`. Bemærk, hvordan vi kan bruge `\includegraphics` direkte i Lua-koden.

```latex
if (res) then
    local hbglyphs=hbbuffer:get_glyphs()
    % Glyf-tabellen, hbglyphs, er 1-baseret
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Reducer størrelsen på vores importerede PNG-billeder
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
```

### Den fulde kode, som du kan åbne i Overleaf

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

% Indlæs luaharfbuzz-biblioteket fra LuaHBTeX
hblib=require("luaharfbuzz")

% Find Noto Color Emoji-skrifttypen på Overleafs server
pathtofontfile=kpse.find_file("NotoColorEmoji.ttf","truetype fonts")

% Opret HarfBuzz-face og HarfBuzz-font fra Noto Color Emoji
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)

% Denne funktion accepterer en skrifttype og et glyf-id:
% den udtrækker glyffernes PNG-data og skriver
% det ud til en .png-fil

function writePNGglyph(hbfontobject, glyphID)

    % Hent glyffens PNG-data
    local pngblob=hbfontobject:ot_color_glyph_get_png(glyphID)
    local pngdata=pngblob:get_data()

    % Konstruer et filnavn til vores .png-fil
    local fname="Glyph"..glyphID..".png"

    % Skriv .png-filen og returner filnavnet
    local output = assert(io.open(fname, "wb"))
    output:write(pngdata)
    output:close()

    % Returner filnavnet til brug for \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()
    % Glyftabellen, hbglyphs, er 1-baseret.
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Reducer størrelsen på vores importerede PNG-billeder
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
}}

En and: \codestoemoji{\Uchar"1F986}

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

[Åbn dette luaharfbuzz-API-eksempel i Overleaf.](/latex/da/dybtgaende-artikler/10-an-overview-of-technologies-supporting-the-use-of-colour-emoji-fonts-in-latex.md)

Dette eksempel giver følgende output:

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

## Bonusafsnit: Sjov med emoji-matematik

For at afslutte med en munter note brugte et medlem af Overleaf-teamet [`emoji` LaTeX-pakke](https://ctan.org/pkg/emoji?lang=en) til at oprette et sjovt eksempel:

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

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

Dette eksempel giver følgende output:

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


---

# 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/da/dybtgaende-artikler/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.
