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

# Gambaran umum teknologi yang mendukung penggunaan font emoji berwarna di LaTeX

## Pendahuluan

Artikel ini memberikan gambaran umum tentang berbagai [topik latar belakang](#which-topics-do-we-cover) terkait penggunaan font warna OpenType untuk penataan huruf emoji berwarna di LaTeX. Kami telah mencoba menyediakan berbagai materi, yang mencakup spektrum minat dan keahlian yang luas. Untuk menjaga artikel ini tetap mudah dikelola, cakupan kami atas topik tertentu menghilangkan banyak detail teknis, tetapi kami berharap ada cukup materi untuk memandu eksplorasi Anda tentang penataan huruf emoji berwarna di LaTeX.

**Pembaruan (Juli 2023)**: Artikel ini pertama kali diterbitkan pada Agustus 2021 dan direvisi pada Juli 2023 untuk memperbarui bagian tentang [Menggunakan font warna OpenType berbasis SVG dengan LuaHBTeX](#using-svg-based-opentype-color-fonts-with-luahbtex).

### Topik apa saja yang kami bahas?

Artikel ini membahas topik umum berikut:

* Unicode: standar yang mengodekan emoji sebagai karakter dan mengkodifikasi perilaku yang diharapkan dalam aplikasi pemrosesan teks dan penataan huruf.
* Font warna OpenType: font khusus yang menyediakan representasi berwarna dari karakter emoji yang ditampilkan dalam dokumen LaTeX Anda.
* Penyusunan bentuk teks: pengenalan komponen kunci penataan huruf bahasa skrip kompleks dan emoji.
* HarfBuzz: komponen LuaHBTeX yang memungkinkan penataan huruf multibahasa tingkat lanjut dan penggunaan font warna OpenType untuk menata huruf emoji di LaTeX.
* Berbagai mesin TeX: menelaah dukungannya terhadap font warna OpenType dan memilih mesin TeX yang akan digunakan.
* API HarfBuzz milik LuaHBTeX: pengantar tentang “keajaiban” di balik [penyusunan bentuk teks](#the-concept-of-text-shaping) di LuaHBTeX.

### Tiga cara menata huruf emoji berwarna

Emoji berwarna dapat ditata dengan LaTeX menggunakan tiga metode utama:

1. Menggunakan alat grafis LaTeX standar seperti TikZ, MetaPost, atau Asymptote untuk menggambar emoji.
2. Menyisipkan emoji menggunakan grafis emoji yang telah disiapkan sebelumnya dan disimpan dalam berkas eksternal.
3. Memperlakukan emoji sebagai teks ber-encoding Unicode dan menggunakan [penyusunan bentuk teks](#the-concept-of-text-shaping) dengan [font warna OpenType](#opentype-color-fonts) untuk menatanya.

Opsi praktis untuk menyertakan emoji berwarna dalam dokumen LaTeX Anda bergantung pada mesin TeX yang digunakan untuk mengompilasi dokumen itu: yaitu, apakah Anda menggunakan:

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

Ketiga mesin TeX ini dapat menggunakan alat atau paket LaTeX untuk menggambar emoji atau menggunakan `\includegraphics{...}` untuk menyisipkan emoji yang disimpan dalam berkas grafis eksternal. Menggambar atau mengimpor grafis adalah teknik yang ideal untuk menata huruf emoji ketika Anda memerlukan solusi yang tidak bergantung pada mesin TeX yang digunakan untuk mengompilasi dokumen LaTeX.

Namun, jika alur kerja Anda memberi fleksibilitas untuk memilih mesin TeX tertentu, dan Anda lebih memilih menggunakan font warna OpenType serta pemrosesan teks berbasis Unicode, versi terbaru LuaTeX, yang disebut LuaHBTeX, adalah yang Anda perlukan. Mulai TeX Live 2020, LuaHBTeX digunakan untuk mengompilasi dokumen LaTeX berdasarkan format LuaLaTeX.

## Latar belakang tentang Unicode dan karakter emoji

### Pengkodean karakter

Komputer menyimpan, mengirim, dan memproses teks menggunakan urutan nilai numerik (integer) yang merepresentasikan *karakter*. Pemrosesan teks yang andal mengharuskan produsen dan konsumen teks menyepakati nilai integer mana yang harus digunakan untuk merepresentasikan karakter individual dalam aliran teks. Dengan kata lain, apakah *karakter* *pengkodeannya?* Pengkodean adalah himpunan nilai integer yang disepakati untuk merepresentasikan suatu kumpulan karakter tertentu: setiap karakter direpresentasikan oleh nilai integer dalam pengkodean yang digunakan.

### Masuklah Unicode

Secara historis, pada era teks 8-bit, banyak pengkodean karakter berbeda digunakan, yang selalu memunculkan bayang-bayang *ketidakcocokan pengkodean*: produsen dan konsumen teks secara keliru mengira pengkodean yang berbeda, sehingga menimbulkan kesalahan pemrosesan teks. Siapa pun yang telah bekerja dengan TeX/LaTeX selama beberapa tahun kemungkinan pernah mengalami ketidakcocokan pengkodean antara teks masukan dan font yang digunakan untuk menata huruf sebuah dokumen. Jika font dokumen dikonfigurasi menggunakan pengkodean yang berbeda dari teks, hal ini kemungkinan menghasilkan karakter yang hilang atau salah dalam PDF hasil penataan huruf.

Masalah pengkodean historis ini dapat diatasi menggunakan standar internasional yang mengodekan semua karakter di dunia: Unicode. Standar Unicode tidak statis, melainkan diperbarui secara berkala untuk menyertakan karakter dan skrip (sistem penulisan) tambahan dalam skema pengkodeannya. Ada [proses tinjauan formal untuk mengusulkan karakter baru](http://www.unicode.org/pending/proposals.html) dengan skema khusus [untuk karakter emoji baru](https://www.unicode.org/emoji/proposals.html).

### Berapa banyak karakter Unicode?

Unicode mengodekan maksimum teoretis 1.114.112 karakter. Masing-masing dari 1.114.112 nilai integer tersebut disebut *titik kode*: nilai integer yang ditetapkan untuk mengidentifikasi setiap karakter. Namun, karena berbagai alasan teknis hanya [1.112.064 titik kode](https://en.wikipedia.org/wiki/Unicode#Architecture_and_terminology) dapat ditetapkan ke karakter aktual: 2048 titik kode tidak dapat ditetapkan dan dilarang untuk digunakan dalam teks yang mematuhi Unicode.

Pada saat penulisan (versi pertama artikel ini), Versi 13 standar Unicode telah mengalokasikan total 143.859 titik kode kepada karakter aktual, termasuk [3304 karakter yang kini dikodekan sebagai emoji](https://www.unicode.org/L2/L2020/20114r-family-emoji-explor.pdf) (lihat halaman 2 dokumen tersebut). Pertumbuhan jumlah karakter yang dikodekan oleh Unicode didokumentasikan dengan baik dalam artikel [Ada berapa karakter Unicode?](https://www.babelstone.co.uk/Unicode/HowMany.html) dan dalam sebuah [entri Wikipedia](https://en.wikipedia.org/wiki/Unicode#Versions).

### Bidang Unicode

Seluruh kumpulan 1.114.112 titik kode Unicode dikelompokkan menjadi 17 yang disebut Bidang: Bidang 0 hingga Bidang 16, masing-masing berisi 65536 nilai titik kode, menghasilkan total $$17\times2^{16} = 1,114,112$$ karakter. Bidang 0, yang disebut [Bidang Multibahasa Dasar](https://en.wikipedia.org/wiki/Plane_\(Unicode\)#Basic_Multilingual_Plane), mengodekan karakter yang paling umum digunakan. Bidang 1–16 disebut [Bidang Tambahan](http://unicode.org/glossary/#supplementary_planes).

### Munculnya emoji

Karakter baru muncul melalui perubahan mode komunikasi manusia, dan teknologi telepon seluler melahirkan salah satu set karakter tersebut: emoji, yang berkembang di Jepang pada akhir 1990-an. Tidak mengherankan bahwa [FAQ Unicode tentang Emoji](https://unicode.org/faq/emoji_dingbats.html) menyatakan

> “Kata emoji berasal dari bahasa Jepang [絵](http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=%E7%B5%B5) (e ≅ gambar) + [文字](http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=%E6%96%87) (moji ≅ karakter tertulis).”

Pembaca yang tertarik pada latar belakang dan perkembangan historis emoji mungkin akan tertarik pada [pengantar Unicode](https://unicode.org/reports/tr51/#Introduction) atau artikel [Saya setuju dengan emoji itu: Standar, struktur, dan produksi sosial emoji](https://firstmonday.org/ojs/index.php/fm/article/view/9381).

Baru pada 2010, dengan dirilisnya [versi 6.0 dari Standar Unicode](https://www.unicode.org/versions/Unicode6.0.0/), banyak emoji secara formal diakui sebagai *karakter* sebagai entitas tersendiri. Unicode 13.0 mengodekan [3304 karakter sebagai emoji](https://www.unicode.org/L2/L2020/20114r-family-emoji-explor.pdf) (lihat halaman 2 dokumen itu), dengan Unicode 13.1 mencantumkan [mencantumkan 3521 emoji](https://unicode.org/emoji/charts/emoji-counts.html).

### Emoji berada pada bidang yang lebih tinggi

Unicode menetapkan banyak karakter emoji ke titik kode di luar Bidang Multibahasa Dasar (BMP), dikodekan [di Bidang 1](https://en.wikibooks.org/wiki/Unicode/Character_reference/1F000-1FFFF) dengan titik kode dalam rentang 1F000–1FFFF—yang memiliki konsekuensi penting bagi siapa pun yang ingin *menyalin dan menempelkan* karakter emoji ke dalam editor Overleaf (Code Editor atau Visual Editor). Editor teks Overleaf hanya dapat menangani karakter dalam Bidang Multibahasa Dasar, meskipun kami berharap peningkatan di masa depan akan memperkenalkan dukungan untuk karakter non-BMP. Perhatikan bahwa keterbatasan ini hanya memengaruhi karakter non-BMP dalam teks yang ditempelkan ke berkas yang nantinya akan diedit melalui editor Overleaf. Ada cara lain untuk mengakses karakter emoji:

* Menggunakan perintah primitif `\char\"<code point>` atau `\Uchar\"<code point>` (lihat [bagian ini](#optional-detail-luatexluahbtex-char-vs-uchar) dalam artikel).
* Menggunakan berkas teks masukan yang berisi karakter emoji dalam format UTF-8.
* Menggunakan perintah LaTeX (makro) yang menyisipkan karakter emoji.

#### Menempelkan emoji dan karakter non-BMP lainnya ke dalam Overleaf

Jika Anda menempelkan karakter emoji, misalnya 😀, ke dalam Overleaf Code Editor, saat ini karakter tersebut akan dikonversi menjadi karakter ��.

![Kesalahan akibat menyalin + menempel karakter non-BMP ke editor Overleaf](/files/9e8d509f5d4d1deca88d3d3cce904cb9bd2f26db)

Karakter � memiliki titik kode Unicode FFFD dan nama resminya adalah REPLACEMENT CHARACTER serta digunakan untuk “[mengganti karakter yang tidak diketahui, tidak dikenali, atau tidak dapat direpresentasikan](https://en.wikipedia.org/wiki/Specials_\(Unicode_block\))”.

### Menggunakan titik kode Unicode (U+) di LuaLaTeX

Dokumentasi Unicode merepresentasikan nilai titik kode menggunakan notasi `U+<nilai heksadesimal>`—seperti `U+1F600`, di mana `1F600` adalah `<nilai heksadesimal>` dari titik kode Unicode untuk karakter emoji 😀. Untuk menggunakan nilai titik kode ini di LuaLaTeX, Anda menghapus `U+` dan menulis `\char\"<nilai heksadesimal>` atau `\Uchar\"<nilai heksadesimal>`. Paket `"` karakter memberi tahu mesin TeX bahwa angka yang diberikan dinyatakan dalam heksadesimal. Misalnya, untuk menggunakan emoji 😀, Anda akan menulis `\char\"1F600` atau `\Uchar\"1F600`—dengan menggunakan font yang mampu menatanya.

Contoh minimal LuaLaTeX yang menggunakan `\char` dan `\Uchar` untuk menata karakter emoji 😀 mungkin adalah:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont[Renderer=Harfbuzz]{NotoColorEmoji.ttf}
%Gunakan \emojifont dalam grup untuk menjaga efeknya tetap lokal
{\emojifont
\Uchar\"1F600
\char\"1F600}
\end{document}
```

[Buka contoh LuaLaTeX ini di 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)

**(rincian opsional) LuaTeX/LuaHBTeX: \char vs \Uchar**

Selain `\char<kode karakter>` perintah konvensional untuk menata huruf `<kode karakter>`, dengan menggunakan font saat ini, mesin LuaTeX, LuaHBTeX, dan XeTeX juga menyediakan `\Uchar<kode karakter>` perintah. Dari sudut pandang pengguna, hasil dari `\char` dan `\Uchar` tampak sama, tetapi ada perbedaan halus dalam cara perintah-perintah ini bekerja, seperti kami jelaskan di bawah.

**Perbedaan utama: ekspansi**

`\Uchar` adalah yang disebut [perintah yang dapat diekspansi](/latex/id/artikel-mendalam/22-how-does-expandafter-work-the-meaning-of-expansion.md#expansion-a-general-term-for-a-set-of-operations) sedangkan `\char` tidak dapat diekspansi. Ketika sebuah `\char<kode karakter>` atau `\Uchar<kode karakter>` perintah sedang “dijalankan”—yaitu, perintah itu tidak disimpan sebagai bagian dari makro atau daftar token lain—tindakan berikut terjadi di dalam mesin TeX:

* **`\char<kode karakter>`** menginstruksikan mesin TeX untuk segera menyisipkan token karakter, yang merepresentasikan `<kode karakter>`, ke dalam bagian konten apa pun yang sedang ditatanya saat itu.
* Sebaliknya, **`\Uchar<kode karakter>`** memiliki dua langkah pemrosesan yang berbeda:

1. Fitur `\Uchar<kode karakter>` perintah *diekspansi*, dan `<kode karakter>` dikonversi menjadi daftar token sementara yang berisi satu [token karakter](/latex/id/artikel-mendalam/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md#tex-tokens-101-28and-notions-of-expansion29) yang merepresentasikan `<kode karakter>`.
2. Daftar token satu karakter itu sekarang *disediakan* kepada mesin TeX sebagai sumber masukan berikutnya. Pada praktiknya, mesin TeX “sementara mengalihkan pandangannya” untuk menggunakan daftar satu token itu sebagai lokasi item masukan (token) berikutnya. Secara default, mesin TeX hanya kembali membaca (input) token itu dan menata huruf karakter yang sesuai, meniru perilaku `\char` perintah. **Namun**, karena token itu `<kode karakter>` tidak langsung ditata huruf, melainkan sementara *disimpan* (disimpan) sebagai satu token, perintah primitif TeX atau makro LaTeX dapat memanfaatkan (menyerap) token itu—token tersebut tidak harus segera ditata huruf, tetapi dapat digunakan dalam pemrosesan lanjutan sesuai kebutuhan.

Pada praktiknya, `\char<kode karakter>` berkata “tatakan ini `<kode karakter>` sekarang,” sedangkan `\Uchar<kode karakter>` memiliki bentuk “aksi tertunda” dengan membuat token karakter tersimpan dan menyediakannya sebagai item masukan berikutnya (sebuah token). Token itu dapat digunakan (diserap) oleh perintah dan makro TeX atau dibaca ulang oleh mesin TeX dan ditata huruf.

### Unicode (pengkodean) bukanlah keseluruhan cerita

Kemampuan menggunakan karakter emoji dalam teks ber-encoding Unicode hanyalah sebagian dari kisah keberhasilan emoji. Lonjakan penggunaan emoji juga dimungkinkan oleh perkembangan dalam [teknologi font OpenType](https://learn.microsoft.com/en-us/typography/opentype/)—font yang data glifnya (desain karakter) dapat berisi [data warna](https://learn.microsoft.com/en-us/typography/opentype/spec/colr): yang disebut [font warna OpenType](#opentype-color-fonts).

Selain font yang sesuai, penggunaan emoji berwarna memerlukan komponen perangkat lunak tambahan yang tugasnya mencakup:

* pra-pemrosesan (“[shaping](#the-concept-of-text-shaping)”) teks ber-encoding Unicode, *mempersiapkannya* untuk ditampilkan menggunakan font tertentu;
* *perenderan dan tampilan* dari emoji berwarna milik font *glif* ke layar perangkat.

#### Glif vs. karakter: bukankah itu sama?

Istilah “glyph” dan “character” sering digunakan seolah-olah keduanya dapat dipertukarkan—merujuk pada konsep dasar yang sama—tetapi ada perbedaan makna yang halus, namun penting.

Unicode [mendefinisikan istilah “character”](http://www.unicode.org/glossary/#character) sebagai:

> “Komponen terkecil dari bahasa tulis yang memiliki nilai semantik; merujuk pada makna dan/atau bentuk abstrak, bukan pada bentuk spesifik… ”

Sebaliknya, “glyph” adalah *representasi* *bentuk* (desain) yang spesifik untuk *representasi visual* dari suatu *karakter*.

Permasalahan karakter vs. glif mudah diamati ketika teks yang dipenuhi emoji dilihat pada berbagai sistem/platform perangkat lunak, misalnya saat membaca teks yang sama di ponsel berbasis iOS atau Android atau komputer desktop Windows Anda. Apa pun perangkat atau platform yang digunakan, teks yang mendasarinya (urutan karakter) akan memuat emoji yang dikodekan Unicode yang sama *emoji* *karakter*. Kemampuan khusus perangkatlah yang terlibat dalam *pra-pemrosesan* teks itu kemudian *merender* dan *tampilan* hasilnya, mungkin menggunakan font khusus perangkat, yang menghasilkan glif (desain karakter) yang berbeda untuk merepresentasikan karakter emoji yang sama.

milik Unicode [Daftar Emoji Lengkap](https://unicode.org/emoji/charts/full-emoji-list.html) menyediakan gambar contoh yang merepresentasikan setiap karakter emoji Unicode—menunjukkan berbagai glif yang digunakan oleh vendor teknologi yang berbeda. Bukan hanya perancang font yang mengadopsi desain glif mereka sendiri untuk merepresentasikan karakter emoji, tetapi font individual juga berbeda dalam jumlah karakter emoji yang mereka dukung (untuk mana mereka memiliki glif) dan mungkin atau mungkin tidak memuat fitur pemrosesan teks emoji yang lebih canggih yang tercantum dalam spesifikasi emoji Unicode.

Gagasan dan konsep karakter, semantiknya, dan pengkodeannya, menjadi dasar dunia Unicode: Unicode menangani karakter. Desain dan representasi visual karakter individual sebagai glif merupakan ranah teknologi font dan keahlian desain font.

#### Emoji Unicode: jauh lebih dari sekadar pengkodean teks

Peran inti Unicode adalah menyediakan standar pengkodean global yang menentukan nilai integer mana, yang disebut *titik kode,* yang harus digunakan untuk mewakili setiap karakter, termasuk emoji, dalam aliran teks ber-encoding Unicode.

Spesifikasi Unicode untuk emoji juga mendefinisikan *perilaku pemrosesan* untuk karakter emoji tertentu *rangkaian* yang muncul dalam aliran teks ber-encoding Unicode. Urutan emoji yang terdefinisi dapat “digabungkan” melalui proses yang disebut [penyusunan bentuk teks](#the-concept-of-text-shaping) untuk menghasilkan satu glif emoji hasil (“komposit”)—glif tunggal itu akan digunakan oleh sistem operasi perangkat untuk mewakili urutan karakter asli yang ada dalam teks.

Laporan Teknis Unicode tentang [Emoji Unicode](https://unicode.org/reports/tr51/) mendokumentasikan kumpulan fitur kaya yang tersedia bagi perangkat lunak yang ingin menyediakan pemrosesan karakter emoji sesuai Unicode. Sebagai contoh, Unicode mendefinisikan (mengodekan) karakter yang disebut [pengubah emoji](http://www.unicode.org/reports/tr51/#Emoji_Modifiers_Table) yang dapat digunakan untuk menghasilkan *variasi* dari karakter emoji “dasar”, seperti variasi dalam [warna kulit berdasarkan skala Fitzpatrick](http://www.unicode.org/reports/tr51/#Diversity). Perhatikan bahwa kumpulan karakter emoji dasar dan pengubah yang berlaku didefinisikan sebagai bagian dari keseluruhan [standar emoji Unicode](http://www.unicode.org/reports/tr51).

Halaman Unicode [Urutan Emoji](http://unicode.org/emoji/charts/emoji-sequences.html) menyediakan bagan urutan yang saat ini disediakan oleh spesifikasi Unicode. Arahkan penunjuk mouse ke salah satu gambar glif emoji untuk melihat tooltip pop-up kecil yang memberi tahu Anda urutan karakter emoji Unicode yang mendasari dan menghasilkan glif tersebut:

![EmojiSequenceChart.png](/files/8c2cf930d03129d899783146dc37518781d77703)

Sebagai contoh, glif emoji:

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

tercantum dalam [bagian urutan pengubah](http://unicode.org/emoji/charts/emoji-sequences.html#modifier_sequences) dan dihasilkan oleh urutan dua karakter U+1F44B U+1F3FD. Karakter komponennya adalah:

U+1F44B:![UnicodeWavingHandDefault.png](/files/38906a98a39a0672749771a3512402984535df60) (TANGAN MELAMBAI)

U+1F3FD:![FitzPatrick3.png](/files/fa1c878648e3c6bc3f8d1150b7c01820e9373552) (PENGUBAH EMOJI FITZPATRICK TIPE-4)

**Menggunakan pengubah warna kulit di LuaHBTeX**

Contoh berikut menggunakan LuaHBTeX untuk mendemonstrasikan penggunaan pengubah emoji:

```latex
\documentclass{article}
\usepackage{fontspec}
\begin{document}
\newfontfamily\emojifont[Renderer=HarfBuzz,SizeFeatures={Size=20}]{NotoColorEmoji.ttf}
Tangan melambai terpisah: {\emojifont\Uchar\"1F44B}\par
Pengubah terpisah: {\emojifont\Uchar\"1F3FD}\par
Hasil gabungan: {\emojifont\Uchar\"1F44B\Uchar\"1F3FD}
\end{document}
```

[Buka contoh pengubah emoji LuaLaTeX ini di 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)

Contoh ini menghasilkan keluaran berikut:

![ModifiersInLuaHBTeX.png](/files/04914bb55f99159285e8c99dc8d298ffb73c0c07)

#### UTF-8: perannya dalam menyimpan teks Unicode

Setiap teks atau kode yang Anda ketik atau tempel ke Code Editor Overleaf (atau Visual Editor) akan disimpan dalam format UTF-8, jadi kita akan meninjau secara singkat apa arti UTF-8 sebenarnya. UTF adalah singkatan dari Unicode Transformation Format, dan peran UTF-8 dalam menyimpan atau mengirim teks ber-encoding Unicode ditunjukkan oleh frasa “Transformation *Format*.”

Nilai titik kode Unicode berkisar dari 0 hingga maksimum 1.114.111, jadi mustahil merepresentasikan semua nilai karakter Unicode menggunakan satu byte 8-bit, yang hanya dapat menyimpan hingga 256 nilai berbeda: 0 hingga 255. Namun, setiap bilangan titik kode Unicode dapat direpresentasikan menggunakan *urutan berkesinambungan* nilai seukuran byte—dan itulah prinsip di balik UTF-8.

UFT-8 menyediakan “resep” untuk *mengubah* (yaitu, untuk “mengodekan” atau “mengonversi”) nilai titik kode integer Unicode menjadi urutan unik 1 hingga 4 bilangan integer seukuran byte yang berurutan: jumlah byte berurutan yang diperlukan bergantung pada nilai integer titik kode. Akibatnya, Anda mungkin membaca bahwa UTF-8 menyimpan karakter Unicode sebagai *urutan multibita* karena satu karakter Unicode (integer titik kode) direpresentasikan dalam UTF-8 sebagai urutan 1 hingga 4 byte berurutan.

Tentu saja, teks yang disimpan dalam UTF-8 dapat dikonversi kembali ke urutan nilai integer titik kode Unicode aslinya—itulah yang harus dilakukan XeTeX atau LuaTeX/LuaHBTeX ketika membaca berkas masukan LaTeX yang disimpan dalam format UTF-8. Mesin TeX tersebut perlu mengetahui nilai titik kode (karakter) Unicode masukan sebelum mereka dapat menata huruf teks. Perhatikan bahwa pdfTeX tidak memiliki kemampuan decoding UTF-8 bawaan sehingga harus mengandalkan makro TeX untuk memproses (mendekode) teks masukan yang diformat dalam UTF-8.

**Beberapa contoh UTF-8**

* Karakter Arab ش (“sheen”) memiliki titik kode Unicode 0634 dalam heksadesimal (basis 16) atau 1588 dalam desimal (basis 10). Dalam UTF-8, ش direpresentasikan sebagai 2 nilai (heksadesimal) D8 dan B4, sehingga karakter ش akan disimpan sebagai dua byte berurutan D8B4 dalam teks ber-encoding UTF-8.
* Karakter emoji 😀 memiliki titik kode Unicode 1F600 dalam heksadesimal (basis 16) atau 128512 dalam desimal (basis 10). Dalam UTF-8, 😀 direpresentasikan sebagai 4 nilai (heksadesimal) F0, 9F, 98, dan 80, sehingga karakter 😀 akan disimpan sebagai 4 byte berurutan F09F9880 dalam berkas teks UTF-8.

#### Karakter khusus yang digunakan dalam pemrosesan teks emoji berbasis Unicode

Tidak setiap karakter yang dikodekan dalam Unicode dimaksudkan untuk ditampilkan secara visual melalui glif dalam font: beberapa karakter yang dikodekan ditetapkan sebagai *karakter noncetak* yang tujuannya adalah membantu fungsi pemrosesan teks khusus (di dalam perangkat lunak pendukung). Berbagai aplikasi perangkat lunak memberikan tingkat dukungan yang berbeda untuk karakter noncetak yang dikodekan ke dalam Unicode, sehingga hasilnya akan bergantung pada lingkungan perangkat lunak—aplikasi dan font—yang digunakan.

**Dua karakter noncetak yang perlu diketahui**

* **Zero Width Joiner (ZWJ)**, titik kode 200D (heksadesimal), seperti namanya, dirancang untuk memicu “perilaku penggabungan” karakter masukan—tetapi hanya jika karakter masukan tersebut *memiliki* perilaku penggabungan yang terdefinisi.
* **Zero Width Non-Joiner (ZWNJ)**, titik kode 200C (heksadesimal), dirancang untuk *mencegah* menghambat “perilaku penggabungan” yang sebaliknya mungkin ditampilkan oleh karakter masukan. Misalnya, Anda dapat menggunakan ZWNJ untuk mencegah perilaku penggabungan karakter Arab berurutan yang biasanya akan diproses (dibentuk) menjadi bentuk gabungannya.

Unicode telah menerbitkan daftar [Urutan ZWJ Emoji yang Direkomendasikan](https://unicode.org/emoji/charts/emoji-zwj-sequences.html) yang menggunakan U+200D ZERO WIDTH JOINER (ZWJ) untuk menggabungkan urutan karakter emoji menjadi satu glif emoji komposit—jika tersedia dalam font yang digunakan.

**Contoh penggunaan zero width non-joiner**

Fragmen kode minimal berikut menggunakan font OpenType Scheherazade, yang disertakan dalam TeX Live, untuk mendefinisikan font LaTeX yang disebut `\arabicfont` yang dapat kita gunakan untuk menata huruf sebagian teks Arab. Baris

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

menggunakan karakter zero width non-joiner, melalui `\Uchar\"200C`, untuk mencegah perilaku penggabungan normal dari dua huruf Arab ل (lam) dan ا (alef). Perhatikan penggunaan `\textdir TRT` untuk mengatur arah teks dari kanan ke kiri:

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

[Buka contoh LuaLaTeX ini di 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)

Contoh ini menghasilkan keluaran berikut:

![NonJoiner.png](/files/079a6fc103386eab00c7c138d7d6f4790af746c5)

## Konsep “text shaping”

Mari mulai dengan contoh visual menggunakan terjemahan Urdu dari kata “educational.” Teks terjemahan Urdu itu mungkin diketik pada keyboard atau perangkat layar sentuh, dan akan dibuat sebagai urutan linear sederhana karakter Arab Unicode. Namun, ketika teks itu ditata huruf, atau ditampilkan pada layar perangkat dalam [gaya Nastaliq](https://en.wikipedia.org/wiki/Nastaliq), hasilnya adalah susunan glif dua dimensi yang kompleks.

Dengan contoh Urdu kita, grafik berikut membandingkan masukan linear Arab Unicode *karakter* dengan keluaran yang ditata huruf dalam gaya Nastaliq, yang terdiri atas susunan dua dimensi dari *glif* yang terdapat dalam font (gratis) [Awami Nastaliq](https://software.sil.org/awami/download/):

![](/files/5597e089302ce81f4b55f29867bdce5ac0844123)

Proses “menerjemahkan” karakter masukan menjadi serangkaian glif keluaran yang ditempatkan dengan benar disebut *penyusunan bentuk teks*, dan merupakan komponen vital dalam memproses teks sebelum ditampilkan atau ditata huruf. Contoh kami menggunakan teks dalam bahasa Urdu (aksara Arab) karena hasil shaping sangat jelas terlihat, berbeda dengan bahasa yang menggunakan aksara Latin, seperti bahasa Inggris, di mana shaping jauh kurang menonjol—misalnya produksi ligatur sederhana.

Penyusunan bentuk teks sangat penting ketika menggunakan skrip (sistem penulisan) seperti [Arab](https://en.wikipedia.org/wiki/Arabic), [Ibrani](https://en.wikipedia.org/wiki/Hebrew_language), [Devanagari](https://en.wikipedia.org/wiki/Devanagari) atau [Malayalam](https://en.wikipedia.org/wiki/Malayalam), hanya empat contoh dari yang disebut *skrip kompleks*. Untuk memastikan penyajian teks yang benar dalam skrip tersebut, dan bahasa yang menggunakannya, proses shaping perlu menangani dengan cermat setiap aturan dan nuansa shaping yang ada pada kombinasi skrip dan bahasa tertentu. Misalnya, beberapa bahasa memerlukan beberapa karakter masukan untuk menghasilkan glif keluaran tertentu, atau mungkin ada persyaratan kompleks untuk penempatan tanda diakritik yang cermat, serta penataan ulang antarglif untuk memastikan glif individual ditempatkan dengan benar (relatif satu sama lain).

Secara umum, membentuk sepotong teks memerlukan beberapa informasi:

* Sistem penulisan atau *aksara* di mana teks itu ditulis.
* Spesifik *Rusia* yang digunakan. Skrip individual dapat digunakan untuk beberapa bahasa, dengan setiap kombinasi skrip–bahasa memiliki kehalusan/nuansa pembentukan tersendiri.
* Penulisan *arah* teks—seperti dari kanan ke kiri atau dari kiri ke kanan.
* Sebuah *font* yang menyediakan glyph yang diperlukan untuk merepresentasikan teks yang telah dibentuk dan, secara opsional, berisi “aturan pembentukan” tambahan yang memandu proses pembentukan teks.

Persyaratan pembentukan teks, khususnya untuk skrip kompleks dan bahasa-bahasa terkaitnya, dapat sangat rinci dan bernuansa, yang menunjukkan perlunya perangkat lunak khusus yang dapat menerapkan “aturan” pembentukan teks yang berpotensi sangat kompleks. Tak mengherankan, perangkat lunak semacam itu memang ada dan disebut sebagai sebuah *mesin pembentukan teks*; yang akan kita bahas disebut [HarfBuzz](https://en.wikipedia.org/wiki/HarfBuzz), yang dokumentasinya layak dibaca—misalnya [Mengapa saya memerlukan mesin pembentukan?](https://harfbuzz.github.io/why-do-i-need-a-shaping-engine.html).

**Bacaan lanjutan tentang pembentukan teks**

Pengantar singkat ini sangat direkomendasikan:

* [Apa itu pembentukan teks?](https://harfbuzz.github.io/what-is-harfbuzz.html#what-is-text-shaping)
* [Mengapa saya memerlukan mesin pembentukan?](https://harfbuzz.github.io/why-do-i-need-a-shaping-engine.html)

**Catatan teknis TeX: beberapa teknologi pembentukan (model)**

Mesin pembentukan teks HarfBuzz mendukung beberapa “teknologi pembentukan” yang berbeda dalam cara mereka mengimplementasikan proses pembentukan—setiap implementasi disebut sebagai sebuah *shaper*, termasuk dalam dokumentasi `luaotfload` . Fokus utama artikel ini adalah pembentukan OpenType, tetapi teknologi alternatif yang gratis digunakan adalah [Graphite](https://scripts.sil.org/cms/scripts/page.php?site_id=projects\&item_id=graphite_aboutOT), yang dikembangkan oleh [SIL International](https://www.sil.org/). Model pembentukan lain yang didukung HarfBuzz adalah [Apple Advanced Typography (AAT)](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6AATIntro.html)—font yang mendukung AAT umumnya digunakan pada platform teknologi Apple.

**Contoh menggunakan shaper Graphite**

Contoh berikut mengatur beberapa teks Urdu menggunakan font bernama [Awami Nastaliq](https://software.sil.org/awami/download/), yang mendukung pembentukan Graphite dan tersedia di Overleaf. Awami Nastaliq dibuat oleh [SIL International](https://www.sil.org/), organisasi yang bertanggung jawab untuk mengembangkan teknologi Graphite.

Contoh berikut menunjukkan kemampuan pembentukan lanjutan dari font berbasis Graphite—perhatikan bagaimana `luaotfload` deklarasi font memilih pembentukan Graphite menggunakan `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

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

[Buka contoh ini di 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)

Contoh ini menghasilkan keluaran berikut:

![](/files/5cb81280fbbbfa75abd288efe877c9de2316d9e9)

#### Emoji dan pembentukan teks

Pembentukan teks telah diperkenalkan menggunakan contoh dari bahasa skrip kompleks, Urdu. Namun, mungkin mengejutkan untuk mengetahui bahwa merender glyph emoji yang benar memerlukan pembentukan teks diterapkan pada teks Unicode yang berisi rangkaian karakter emoji—[seperti dicatat oleh pengembang utama HarfBuzz](https://github.com/harfbuzz/harfbuzz/issues/2428#issuecomment-639108677):

> ...membentuk emoji dengan HarfBuzz sepenuhnya masuk dalam cakupan dan sebenarnya diperlukan untuk mendapatkan emoji keluarga, warna kulit, dll.

Kita akan melihat contohnya.

### Pembagian tanggung jawab: mesin pembentukan teks + font OpenType

Dalam praktiknya, pembentukan teks adalah “operasi bersama”, atau pembagian kerja, antara logika dan aturan yang dibangun ke dalam mesin pembentukan teks dan aturan serta data pembentukan tambahan yang dibangun ke dalam font yang digunakan—mulai sekarang kita membahas pembentukan berbasis OpenType *saja*.

Untuk melakukan pembentukan, mesin pembentukan teks biasanya diberi beberapa teks Unicode, skrip dan bahasa yang ditentukan, mungkin arah penulisan, dan, yang paling penting, sebuah font OpenType untuk digunakan selama proses pembentukan—font akan menyediakan keluaran: sekumpulan glyph dan data penempatan. Jika diminta, mesin pembentukan dapat menerapkan aturan tambahan ([fitur OpenType](https://en.wikipedia.org/wiki/List_of_typographic_features#OpenType_typographic_features)) yang terkandung dalam font OpenType yang digunakan—aturan mana yang diterapkan biasanya dapat dipilih pengguna dari daftar fitur yang didukung font.

Hasil dari proses pembentukan adalah sebuah *daftar glyph* yang terkandung dalam font OpenType, bersama dengan *antar-glyph* data penempatan. Data penempatan itu berkaitan dengan *penempatan relatif glyph yang telah dibentuk*; data tersebut tidak merujuk pada penempatan absolut di dalam halaman yang telah disusun atau media/konten lain seperti halaman web, Tweet, dll. Perangkat lunak rendering (mesin typesetting, peramban web, dll.) menggunakan informasi penempatan antar-glyph untuk memastikan glyph ditempatkan dengan benar relatif satu sama lain setelah dirakit dan dimasukkan ke dalam output akhir.

#### Apa itu daftar glyph?

Secara internal, setiap glyph dalam font OpenType diberi pengenal numerik, sebuah nilai bilangan bulat yang disebut indeks glyph—juga disebut pengenal glyph atau GID. Setelah menyelesaikan tugas pembentukannya, mesin pembentukan teks akan mengembalikan hasilnya sebagai sebuah *daftar pengenal glyph* plus *data penempatan* untuk glyph tersebut.

Glyph individual dalam font OpenType diberi indeks (pengenal) oleh pembuat font, sehingga nilainya sangat spesifik untuk font tersebut dan bersifat arbitrer—nilai itu juga bisa berbeda antar versi dari font tertentu. Anda jangan pernah mengasumsikan bahwa nilai GID yang sama akan berlaku untuk glyph “serupa” dalam font yang berbeda; hampir pasti tidak. Jika Anda memiliki daftar pengenal glyph yang disediakan oleh mesin pembentukan, Anda hanya dapat menggunakannya untuk mengakses glyph dalam font tempat glyph itu diperoleh.

#### Apa itu font OpenType?

Web dipenuhi *dengan* penjelasan dan detail tentang font OpenType, jadi kita akan membatasi diri pada deskripsi singkat.  [spesifikasi OpenType](https://docs.microsoft.com/en-us/typography/opentype/spec/) adalah dokumen kompleks yang dirancang untuk pengembang, tetapi pada dasarnya ia mendefinisikan format berkas, atau wadah, untuk data font. Sebuah font OpenType berisi data yang menjelaskan bentuk glyph, bersama dengan informasi tentang skrip dan bahasa yang didukung, metadata tentang font, dan berbagai “tabel” yang mendefinisikan [fitur tipografis](https://en.wikipedia.org/wiki/List_of_typographic_features#OpenType_typographic_features) yang didukung oleh font.

Mesin pembentukan teks biasanya dapat diarahkan untuk menerapkan secara selektif fitur-fitur font selama proses pembentukan, menerapkan efek tipografis tertentu (“aturan”) yang memilih kumpulan glyph yang sesuai yang terkandung dalam font. Font yang dipilih perlu mendukung, dan menyediakan glyph untuk, fitur apa pun yang diminta untuk diterapkan oleh mesin pembentukan teks.

#### Glyph yang dikodekan dan yang tidak dikodekan

Font OpenType menyertakan tabel data yang disebut [cmap](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap) (Character to Glyph Index Mapping) yang memetakan kumpulan karakter Unicode yang didukung font ke indeks glyph yang sesuai dalam font tersebut. Video berikut memberikan sekilas singkat tentang tabel cmap yang terdapat dalam font bernama `lmmono10-regiular.otf` (disertakan dalam TeX Live).

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

Namun, font biasanya berisi banyak glyph yang tidak merepresentasikan karakter Unicode tertentu dan tidak disertakan sebagai bagian dari tabel cmap tersebut. Akibatnya, kumpulan glyph yang ada di dalam font OpenType dapat dibagi menjadi dua set utama:

* glyph yang dikodekan yang merepresentasikan karakter Unicode;
* glyph yang tidak dikodekan yang tidak merepresentasikan karakter Unicode.

Glyph yang dikodekan dapat diakses dengan menyertakan karakter Unicode yang sesuai dalam teks—tetapi bagaimana dengan glyph yang tidak dikodekan, bagaimana mereka digunakan/diakses? Glyph tersebut biasanya digunakan untuk menyediakan keluaran dari operasi pembentukan teks, termasuk penerapan fitur font untuk menghasilkan efek visual/tipografis tertentu.

### font warna OpenType

Karakter emoji diharapkan ditampilkan/render dalam warna penuh—emoji hitam putih tidak benar-benar memberikan “pengalaman emoji penuh.” Namun, pada saat pengkodean emoji oleh Unicode pada awalnya,  [spesifikasi font OpenType](https://docs.microsoft.com/en-us/typography/opentype/spec/) tidak memiliki ketentuan yang sesuai untuk menyematkan *colorful*-glyph data dalam font OpenType. “Kekosongan” dalam OpenType ini mendorong vendor teknologi/platform terkemuka mencari solusi, dan “perlombaan” yang terjadi kemudian menghasilkan [berbagai proposal untuk memperluas OpenType](https://www.fontlab.com/news/color-font-format-proposals/) agar mendukung font warna OpenType—bukan hanya untuk menampilkan karakter emoji berwarna (glyph), tetapi juga merender glyph apa pun dalam warna.

#### Empat varian font warna OpenType

[Adobe, Microsoft, Google, dan Apple masing-masing mengajukan proposal](https://www.fontlab.com/news/color-font-format-proposals/) untuk memperluas OpenType agar mendukung font OpenType berwarna penuh dan, pada akhirnya, empat proposal diadopsi dan dimasukkan ke dalam spesifikasi formal OpenType. Untuk memudahkan, kita dapat secara longgar mengelompokkan keempat varian itu menjadi berbasis vektor dan berbasis raster—tetapi, seperti ditunjukkan dalam [repositori GitHub](https://github.com/simoncozens/test-fonts), spesifikasi OpenType cukup fleksibel untuk mendukung berkas font warna OpenType yang menggabungkan keempat teknologi dasar tersebut.

* **Font OpenType berbasis vektor:**
* **Microsoft**: bentuk glyph dijelaskan menggunakan bentuk vektor warna berlapis ([COLR](https://docs.microsoft.com/en-us/typography/opentype/spec/colr) dan [CPAL](https://docs.microsoft.com/en-us/typography/opentype/spec/cpal) tabel).
* [**Adobe dan Mozilla**](https://www.w3.org/2013/10/SVG_in_OpenType/) ([tabel SVG](https://docs.microsoft.com/en-us/typography/opentype/spec/svg)): bentuk glyph digambar menggunakan SVG, yang mendukung glyph yang dibangun dari vektor *dan gambar raster*. Lihat juga [panduan pengguna Adobe tentang font SVG](https://helpx.adobe.com/fonts/user-guide.html/fonts/using/ot-svg-color-fonts.ug.html).
* **Font OpenType berbasis raster:**
* **Google**: glyph direpresentasikan oleh gambar PNG berwarna yang disematkan dalam font ([CBDT](https://docs.microsoft.com/en-us/typography/opentype/spec/cbdt) dan [CBLC](https://docs.microsoft.com/en-us/typography/opentype/spec/cblc) tabel).
* **Apple**: glyph juga direpresentasikan oleh gambar berwarna yang disematkan dalam font. Selain PNG, mekanisme Apple ([tabel sbix](https://docs.microsoft.com/en-us/typography/opentype/spec/colr)) juga mendukung JPEG dan TIFF.

Akibatnya, sistem operasi dan perangkat lunak aplikasi yang mendukung font warna OpenType perlu menangani lanskap teknologi campuran saat ini. Selain itu, Anda harus menyadari bahwa font warna OpenType individual—dan *versi* dari font yang sama—akan:

* memiliki cakupan yang berbeda dari seluruh set [karakter emoji Unicode](https://unicode.org/emoji/charts/emoji-list.html)—yaitu, berapa banyak karakter emoji yang disediakan glyph oleh font tersebut;
* menggunakan desain glyph yang berbeda untuk merepresentasikan karakter emoji individual;
* bervariasi dalam fitur yang mereka sediakan untuk mendukung penggunaan standar Unicode yang lebih lanjutan, seperti [pengubah emoji](https://unicode.org/reports/tr51/#Emoji_Modifiers_Table), dan kemampuan pemrosesan teks emoji lainnya yang dijelaskan dalam [Standar Teknis Unicode #51: Emoji Unicode](https://unicode.org/reports/tr51/).

#### Hype tentang HarfBuzz

Kita telah menyinggung perlunya sebuah *mesin pembentukan teks*: perangkat lunak yang mengambil teks Unicode masukan, ditulis menggunakan kombinasi skrip dan bahasa tertentu, dan, menggunakan font yang ditetapkan, membentuk teks tersebut menjadi urutan glyph, bersama dengan data penempatan, yang dapat digunakan untuk menyusun teks masukan asli.

[HarfBuzz](https://harfbuzz.github.io/) adalah salah satu mesin pembentukan teks tersebut: ini adalah [pustaka kode sumber terbuka](https://github.com/harfbuzz/harfbuzz) dan hasil dari lebih dari satu dekade penelitian dan pengembangan—dan masih terus dikembangkan serta diterapkan secara aktif sebagai bagian dari banyak produk perangkat lunak. HarfBuzz sendiri tidak melakukan “typesetting” tetapi menyediakan “layanan pembentukan teks” untuk perangkat lunak yang memilih mengintegrasikannya, termasuk XeTeX, LuaHBTeX, [Adobe PhotoShop dan Adobe InDesign](https://en.wikipedia.org/wiki/HarfBuzz).

Dengan mengintegrasikan HarfBuzz, mesin TeX dapat memanfaatkan kemampuan pembentukan teks lanjutannya untuk menyediakan typesetting multibahasa yang sangat canggih, khususnya untuk skrip kompleks seperti Arab, Ibrani, Devanagari, dan banyak lainnya. Perhatikan juga bahwa HarfBuzz digunakan untuk memproses dan membentuk karakter teks emoji Unicode, yang akan kita jelajahi lebih rinci.

Grafik berikut merangkum peran HarfBuzz ketika diintegrasikan dengan perangkat lunak, seperti XeTeX atau LuaHBTeX, saat menyusun teks dalam skrip kompleks, seperti Arab:

![Gambaran umum pembentukan teks Arab dengan HarfBuzz](/files/541aee3687d9e73f770ef066a2552bac5a077447)

**Menjelajahi HarfBuzz**

Siapa pun yang tertarik untuk mempelajari lebih lanjut tentang HarfBuzz dan layanan pembentukan OpenType yang diberikannya kepada XeTeX dan LuaHBTeX dapat [mengunduh distribusi biner HarfBuzz](https://github.com/harfbuzz/harfbuzz/releases) yang berisi pustaka HarfBuzz (untuk programmer) dan utilitas baris perintah `hb-view` dan `hb-shape`.

**Contoh: cara menggunakan hb-view**

Buat file baru di editor teks favorit Anda yang mendukung UTF-8 dan salin/tempel enam karakter emoji berikut 👋👋🏻👋🏼👋🏽👋🏾👋🏿 ke dalam file teks itu, lalu simpan dalam format UTF-8 ke file bernama, misalnya, `emoji.txt`.

Perhatikan bahwa editor teks Anda mungkin menampilkan versi emoji hitam-putih sebagai cadangan karena ia tidak mampu (diprogram untuk) merender glyph berwarna. Setelah 6 emoji itu disimpan, file `emoji.txt` harus berisi data UTF-8 untuk rangkaian karakter emoji Unicode berikut—kami memisahkan modifier emoji dengan koma hanya untuk *kemudahan membaca saja*:

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

Seharusnya ada total **11** karakter Unicode, masing-masing menghasilkan 4 byte data UTF-8, sehingga `emoji.txt` file yang dihasilkan harus berukuran 44 byte, tidak termasuk penanda akhir baris apa pun yang digunakan pada akhir baris yang berisi emoji.

Fitur `hb-view` utilitas dapat menggunakan file `emoji.txt`, bersama dengan font warna OpenType yang sesuai pilihan Anda, seperti `NotoColorEmoji.ttf`, untuk menghasilkan file SVG dari keluaran HarfBuzz yang telah dibentuk. Contoh perintah baris berikut, yang harus **diketik dalam satu baris** di terminal Anda, akan menghasilkan file SVG `emoji.svg`:

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

Setelah berhasil dijalankan, file `emoji.svg`, yang dihasilkan oleh `hb-view`, dapat dibuka dengan Inkscape dan seharusnya terlihat kurang lebih seperti ini:

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

`hb-view` dapat digunakan untuk mengeksplorasi pembentukan HarfBuzz untuk berkas teks Unicode dan font OpenType yang sesuai apa pun—jelas tidak terbatas hanya untuk emoji! Ketik

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

untuk melihat banyaknya opsi baris perintah dari utilitas yang kuat dan praktis ini. Selamat Membentuk!

## Pembentukan teks dan mesin TeX

Di sini, kita akan meninjau kemampuan pembentukan teks dari XeTeX dan keluarga mesin TeX LuaTeX.

### XeTeX

XeTeX dikembangkan pada awal 2000-an dan memelopori beberapa inovasi dalam typesetting berbasis TeX, paling menonjol *bawaan* dukungan untuk:

* membaca teks Unicode dalam format UTF-8;
* menggunakan font OpenType;
* pembentukan teks untuk typesetting multibahasa;
* typesetting matematika berbasis OpenType.

Kemampuan XeTeX untuk dengan mudah dan nyaman menyusun bahasa skrip kompleks disebabkan oleh kemampuan pembentukan teks bawaan—awalnya berdasarkan pada, yang kini tidak digunakan lagi, [ICU LayoutEngine](http://userguide.icu-project.org/layoutengine). Berkat kerja Khaled Hosny, XeTeX beralih menggunakan HarfBuzz untuk pembentukan teks, seperti dicatat dalam pengumuman dari [Maret 2013](https://tug.org/pipermail/xetex/2013-March/024118.html). Bagi siapa pun yang ingin menyusun teks multibahasa, XeTeX biasanya disebut sebagai mesin TeX pilihan—tetapi sekarang ada opsi lain, LuaHBTeX, yang akan kita jelajahi.

### LuaTeX dan LuaHBTeX

Pengembangan LuaTeX dimulai sekitar 2005 tetapi mengikuti filosofi desain yang sangat berbeda dari XeTeX, yang menggabungkan fitur baru *langsung ke dalam* perangkat lunak XeTeX. Berbeda dengan XeTeX, pengembang LuaTeX memilih untuk “...menyediakan seperangkat alat minimal dan tanpa solusi.” (lihat [Manual Referensi untuk LuaTeX](https://www.pragma-ade.com/general/manuals/luatex.pdf)). Alih-alih menyediakan serangkaian fitur tambahan *yang dibangun ke dalam* mesin berbasis LuaTeX, mekanisme internal mesin LuaTeX dibuka sehingga pengembang dan pengguna terampil dapat memanfaatkan bahasa skrip Lua terintegrasi untuk membangun solusi mereka sendiri.

Misalnya, tidak seperti XeTeX, mesin LuaTeX tidak dapat *langsung* menggunakan font OpenType; sebagai gantinya, font OpenType harus dimuat dan “dipersiapkan untuk digunakan” melalui fungsi pemuatan font yang ditulis dalam kode Lua. Fungsi pemuatan font tersebut disebut sebagai *callback* fungsi: kode Lua yang akan dipanggil (“dieksekusi”) oleh LuaTeX ketika permintaan dibuat untuk memuat font.

Selain itu, mesin LuaTeX tidak menyediakan apa pun *bawaan* kemampuan pembentukan teks—itu juga harus disediakan oleh kode eksternal yang dapat dipanggil oleh mesin LuaTeX untuk memberinya layanan pembentukan teks. Sekali lagi, ini berbeda dengan mesin XeTeX, yang memasukkan kemampuan pembentukan teks ke dalam perangkat lunak inti.

#### luaotfload: penting untuk menggunakan font OpenType di LuaTeX/LuaHBTeX

Mekanisme callback LuaTeX untuk pemuatan font memberikan banyak fleksibilitas, meskipun dengan “biaya” pemrograman tambahan. Untungnya bagi pengguna LuaLaTeX, komunitas TeX telah mengembangkan paket bernama `luaotfload`, yang merupakan bagian dari [rilis tahunan TeX Live](https://www.tug.org/texlive/) dan tentu saja tersedia bagi pengguna Overleaf.

`luaotfload` adalah [tersedia di CTAN](https://ctan.org/pkg/luaotfload?lang=en) dan memiliki [repositori pengembangan di GitHub](https://github.com/latex3/luaotfload) tempat Anda dapat mengikuti perkembangan terbaru dan [rilis baru](https://github.com/latex3/luaotfload/releases).

`luaotfload` dapat dimuat langsung ke dalam pembukaan dokumen LaTeX melalui

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

Perhatikan bahwa `luaotfload` adalah nama sebuah LaTeX *ke preambel dokumen Anda (seperti disarankan*, artinya ia memiliki nama berkas `luaotfload.sty`. Jika Anda ingin menggunakan `luaotfload` dengan plain TeX, Anda dapat melakukannya dengan menambahkan baris

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

ke dokumen plain TeX Anda.

Biasanya, pengguna LuaLaTeX—yaitu, mereka yang menyusun LaTeX menggunakan LuaTeX/LuaHBTeX—tidak perlu berurusan langsung dengan `luaotfload` perintah tidak melakukan perluasan: ia hanya membuat token dan menyimpannya. Dalam contoh kita, [`fontspec` ke preambel dokumen Anda (seperti disarankan](https://ctan.org/pkg/fontspec) akan memuat `luaotfload` paket untuk Anda, sambil menangani banyak detail tingkat rendah melalui perintah tingkat pengguna yang disediakan oleh `fontspec` paket.

### LuaHBTeX: opsi baru untuk pembentukan teks

`luaotfload` adalah pustaka Lua yang matang dan kuat yang menyediakan penanganan font OpenType oleh LuaTeX—bersama dengan penyediaan layanan pembentukan teks untuk berbagai bahasa dan skrip. Awalnya, fungsi pembentukan teks dari `luaotfload` diimplementasikan dalam kode Lua murni, tetapi rilis TeX Live 2020 membawa opsi arus utama lain untuk pembentukan teks—sebuah mesin berbasis LuaTeX baru bernama LuaHBTeX.

“HB” dalam LuaHBTeX adalah singkatan dari HarfBuzz—pada dasarnya, LuaHBTeX adalah mesin LuaTeX asli *plus* mesin pembentukan teks HarfBuzz terintegrasi. Sesuai dengan filosofi desain LuaTeX, ketersediaan HarfBuzz tidak *secara otomatis* memastikan teks akan dibentuk oleh LuaHBTeX: HarfBuzz adalah alat lain yang dapat digunakan untuk membangun solusi pembentukan teks.

Integrasi HarfBuzz dalam LuaHBTeX [dapat diprogram melalui kode Lua](#introduction-to-the-luahbtex-harfbuzz-api), yang telah memungkinkan `luaotfload`para pengembang untuk menambahkan solusi pembentukan teks berbasis HarfBuzz. Akibatnya, [mulai versi 3.1, dirilis pada 5 November 2019](https://github.com/latex3/luaotfload/releases/tag/v3.1), `luaotfload` ditingkatkan untuk memanfaatkan HarfBuzz—membuat kemampuan pembentukan teks HarfBuzz mudah diakses oleh pengguna umum.

Pembaca yang tertarik pada detail teknis integrasi HarfBuzz dengan LuaTeX dapat membaca [makalah oleh Khaled Hosny](https://www.tug.org/TUGboat/tb40-1/tb124hosny-harfbuzz.pdf).

### luaotfload: dua opsi untuk pembentukan teks (kapan menggunakan HarfBuzz?)

Pengguna LuaLaTeX kini memiliki dua opsi untuk pembentukan teks:

* `luaotfload`implementasi asli (berbasis node) dari pembentukan teks, ditulis sepenuhnya dalam Lua;
* `luaotfload`pembentukan berbasis HarfBuzz milik—diakses melalui kode Lua yang memanggil fungsi pembentukan teks HarfBuzz.

`luaotfload` menyediakan akses ke dua sistem pembentukan ini melalui parameter “`mode`”—meskipun sebagian besar pengguna akan menggunakan opsi setara `fontspec` “`Renderer`” alih-alih langsung menggunakan fungsi tingkat rendah dari `luaotfload`.

Masing-masing `luaotfload`solusi pembentukan teks milik memiliki kekuatan dan kelemahan (saat ini), tetapi yang mana yang sebaiknya Anda gunakan, dan kapan? Berikut beberapa poin untuk dipertimbangkan:

* `luaotfload`Pemrosesan node bawaan dapat sangat intensif memori, khususnya untuk font OpenType CJK yang besar. Menggunakan HarfBuzz untuk membentuk teks CJK dapat menghasilkan peningkatan kecepatan dan pengurangan penggunaan memori.
* Gunakan HarfBuzz untuk skrip kompleks karena “...secara signifikan meningkatkan rendering skrip indic dan Arab dan sangat direkomendasikan untuk skrip semacam itu.” (lihat `luaotfload` manual).
* Integrasi HarfBuzz ke dalam `luaotfload` masih relatif baru dan masih dalam pengembangan lebih lanjut. Pada saat penulisan ini (Juli 2021), disarankan untuk menggunakan pembentukan bawaan luaotfload (mengatur `mode=node`) untuk font dokumen utama Anda, terutama jika dokumen Anda menggunakan skrip Latin. Lihat [masalah GitHub ini](https://github.com/latex3/luaotfload/issues/175#issue-801120377), yang merangkum isu dan diskusi. Jika Anda ingin bereksperimen, Anda dapat menggunakan `luaotfload` untuk memuat berkas font dan membuat dua font LaTeX: satu yang menggunakan pembentukan berbasis HarfBuzz dan yang lain menggunakan pembentukan berbasis Lua. Overleaf membuat sebuah [proyek contoh](#sample-project-arabic-shaping), yang mendemonstrasikan hal ini.
* Jangan gunakan HarfBuzz untuk menangani font matematika. Seperti dibahas oleh para pengembang di tex.stackexchange, HarfBuzz [tidak dirancang untuk menangani font bagi typesetting matematika](https://tex.stackexchange.com/questions/544881/does-luahbtex-with-harfbuzz-renderer-completely-supports-math-formating) jadi jangan gunakan itu untuk tujuan tersebut.

**Proyek contoh: pembentukan Arab**

Berikut adalah proyek Overleaf yang menggunakan beberapa tipe huruf Arab berkualitas tinggi untuk membandingkan `luaotfload`layanan pembentukan berbasis node milik`mode=node`dengan milik HarfBuzz (`mode=harf`):

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

Proyek ini menyertakan output yang ditampilkan pada gambar berikut:

![Typesetting Arab](/files/08d33cf9dd319e9b07e58a168653ed6df8fe1198)

### Memilih “Renderer” di fontspec

Seperti dicatat dalam [dokumentasi](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf), `fontspec` “...memungkinkan pengguna XeTeX atau LuaTeX untuk memuat font OpenType dalam dokumen LaTeX”. Jika Anda menggunakan mesin LuaTeX atau LuaHBTeX, `fontspec` akan memuat `luaotfload` pustaka untuk Anda dan, selain itu, menyediakan serangkaian perintah tingkat pengguna yang praktis yang mengurangi kebutuhan untuk berurusan dengan `luaotfload`fungsionalitas tingkat rendah

Jadi bagaimana Anda memilih antara pembentukan HarfBuzz atau pembentukan bawaan yang disediakan oleh `luaotfload`? Jawabannya terdapat dalam [`fontspec` dokumentasi](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf), khususnya Bagian VI: fitur font khusus LuaTeX saja. `fontspec` menyediakan pengaturan yang disebut `Renderer` yang dapat diatur saat font didefinisikan melalui `fontspec`. `Renderer` mengendalikan pemrosesan tingkat rendah dari font. Dua opsi yang menarik adalah

* `Renderer = Node`: mode default untuk menyusun font OpenType—ini menggunakan `luaotfload`fungsi pembentukan teks milik yang diimplementasikan sepenuhnya dalam Lua.
* `Renderer = Harfbuzz`: mode ini mendefinisikan/memuat font untuk digunakan dengan mesin pembentukan teks HarfBuzz. `luaotfload` menggunakan API LuaHBTeX untuk memanggil fungsi dalam HarfBuzz.

Untuk informasi lebih lanjut lihat [`fontspec` dokumentasi](https://mirror.ox.ac.uk/sites/ctan.org/macros/unicodetex/latex/fontspec/fontspec.pdf).

## mesin TeX, HarfBuzz, dan emoji warna

Meskipun XeTeX dan LuaHBTeX keduanya mengintegrasikan HarfBuzz, mereka menyediakan tingkat dukungan yang berbeda untuk beberapa fitur HarfBuzz yang lebih lanjut—terutama pemuatan dan penggunaan font warna OpenType.

### XeTeX dan font warna OpenType

Seperti dicatat, ada dua kategori font warna OpenType berdasarkan format data yang digunakan untuk menyimpan glyph font: berbasis vektor dan berbasis raster.

#### XeTeX dan font warna OpenType berbasis raster

XeTeX tidak dapat memuat font warna OpenType berbasis raster—seperti milik Google [Noto Color Emoji](https://www.google.com/get/noto/help/emoji/) yang disertakan dengan TeX Live 2020. Misalnya, jika Anda mencoba memuat Noto Color Emoji (NotoColorEmoji.ttf), XeLaTeX akan gagal dengan pesan kesalahan yang berpotensi menyesatkan yang menyatakan bahwa Noto Color Emoji “tidak dapat ditemukan”. Kode LaTeX berikut, yang ditata menggunakan XeLaTeX, *tidak berfungsi*:

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

[Buka kode XeLaTeX ini di Overleaf (itu ***tidak*** berfungsi).](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)

Gagal dengan kesalahan:

```
! Kesalahan Package fontspec: Font "NotoColorEmoji" tidak dapat ditemukan.
```

Demikian pula, contoh Plain TeX sederhana yang diproses oleh XeTeX juga gagal

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

[Buka contoh Plain TeX (XeTeX) ini di Overleaf (itu ***tidak*** berfungsi).](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)

Contoh Plain TeX melaporkan pesan kesalahan yang serupa, tetapi berbeda:

```
! Font \emojifont=[NotoColorEmoji.ttf] at 12.0pt tidak dapat dimuat: berkas Metric (TFM) fil
e atau font terpasang tidak ditemukan.
l.1 \font\emojifont="[NotoColorEmoji.ttf]" at 12pt

Saya tidak dapat membaca data ukuran untuk font ini,
jadi saya akan mengabaikan spesifikasi font.
[Para ahli dapat memperbaiki berkas TFM menggunakan TFtoPL/PLtoTF.]
Anda mungkin mencoba menyisipkan spesifikasi font yang berbeda;
misalnya, ketik `I\font<same font id>=<substitute font name>'.
```

**Contoh Plain LuaHBTeX**

Sebagai perbandingan, berikut contoh Plain TeX minimal yang dikompilasi dengan LuaHBTeX

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

[Buka contoh Plain TeX (LuaHBTeX) ini di Overleaf (berhasil dikompilasi).](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)

#### Penyebab sebenarnya dari kegagalan XeTeX

Pesan kesalahan yang diberikan oleh XeTeX sebagian menutupi penyebab sebenarnya dari masalah: font warna OpenType, khususnya varian berbasis raster, *berisi nilai data aktual yang disimpan dalam* didukung oleh XeTeX. Sebenarnya, XeTeX (Kpathsea) dapat *menemukan* font Noto Color Emoji, tetapi XeTeX tidak dapat sepenuhnya *memuat* font itu dan tidak dapat menginisialisasi tabel data font internal yang diperlukan untuk menggunakan font itu dalam penataan huruf. Secara internal, XeTeX *dimulai* proses pemuatan font dan mengujinya untuk “skalabilitas” (menggunakan “definisi” “skalabilitas” ala FreeType), tetapi pengujian itu gagal, dan XeTeX mengeluarkan pesan kesalahan standar mesin TeX yang boleh jadi menyesatkan.

**Catatan teknis**

Pemrosesan NotoColorEmoji.ttf oleh XeTeX diselidiki dengan mengompilasi versi debug dari executable XeTeX. Eclipse IDE digunakan untuk memasang breakpoint pada fungsi XeTeX `creatFontFromFile(filename, index, pointsize)`, lalu melangkah melalui kode untuk mengamati pemrosesan berikutnya.

#### XeTeX dan font warna OpenType berbasis vektor

XeTeX dapat *memuat* font warna OpenType berbasis vektor tetapi tidak akan menghasilkan emoji berwarna dalam PDF yang dihasilkan—jika XeTeX menghasilkan PDF sama sekali. Tidak seperti LuaTeX, LuaHBTeX, dan pdfTeX, XeTeX tidak *langsung* mengeluarkan dokumen yang ditata huruf dalam format PDF. Sebaliknya, XeTeX mengeluarkan sebuah `.xdv` (e**x**kstensi **dv**i) format berkas yang kemudian dikonversi menjadi PDF oleh utilitas bernama `xdvipdfmx`. Pada saat penulisan ini, `xdvipdfmx` tidak mampu menyematkan data glyph emoji berwarna yang sesuai ke dalam PDF, sehingga, paling banter, Anda akan melihat emoji monokrom—hasil “cadangan”—dalam PDF, atau mungkin tidak ada sama sekali, tergantung font yang digunakan.

Berikut adalah contoh XeLaTeX yang menggunakan font warna OpenType [TwemojiMozilla.ttf](https://ctan.org/tex-archive/fonts/twemoji-colr), tersedia di TeX Live. TwemojiMozilla.ttf menggunakan format vektor COLR/CPAL milik Microsoft untuk menyimpan glyph berwarna dan disertakan dengan TeX Live 2020. Dalam contoh ini, XeTeX mampu memuat font, menghasilkan sebuah `.xdv` dan berkas PDF, tetapi glyph emoji tidak muncul dalam PDF yang ditata huruf:

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

[Buka kode XeLaTeX ini di Overleaf (ITU GAGAL berfungsi).](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)

Sebaliknya, kode di atas berfungsi dengan LuaLaTeX jika mendefinisikan `\emojifont` menggunakan `fontspec` pengaturan `[Renderer=HarfBuzz]`:

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

[Buka kode LuaLaTeX ini di Overleaf (berfungsi).](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 dan font warna OpenType

Melalui mesin pembentukan huruf HarfBuzz terintegrasinya dan `luaoftload` pustaka, LuaHBTeX menyediakan dukungan untuk keempat variasi font warna OpenType. Pengguna LuaLaTeX dapat memanfaatkan sepenuhnya pemrosesan berbasis Unicode dari teks yang mengandung karakter emoji atau sekadar memperindah dokumen mereka dengan teks yang sangat berwarna menggunakan font warna OpenType.

Seperti disebutkan sebelumnya, empat varian font warna OpenType dapat diklasifikasikan menjadi dua kelompok:

* yang berisi glyph dalam format citra raster, seperti PNG;
* yang lain yang menggunakan format vektor SVG atau mekanisme COLR/CPAL milik Microsoft.

Format glyph berbasis vektor memiliki keunggulan skalabilitas: menghasilkan grafis glyph yang tajam pada ukuran titik berapa pun.

**Menggunakan font warna Microsoft COLR/CPAL dengan LuaHBTeX**

Jika Anda ingin menggunakan format vektor untuk font emoji warna OpenType Anda, lihat font [TwemojiMozilla.ttf](https://ctan.org/tex-archive/fonts/twemoji-colr?lang=en), yang berbasis format COLR/CPAL milik Microsoft. TwemojiMozilla.ttf disertakan dengan TeX Live, tetapi Anda dapat memperoleh versi terbarunya dari [repositori GitHub](https://github.com/mozilla/twemoji-colr/releases) dan mengunggahnya ke proyek Overleaf Anda.

Ini adalah contoh kecil, `fontspec`-berbasis, yang menggunakan `Renderer=Harfbuzz`, yang menata huruf seekor bebek emoji (vektor) besar:

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

[Buka contoh LuaLaTeX ini untuk menata huruf seekor bebek vektor.](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)

Berikut adalah bebek (vektor) yang dihasilkan oleh contoh di atas:

![](/files/2f0d55bd9d2c75022512c70ba04e77dc6936e887)

#### Menggunakan font warna OpenType berbasis SVG dengan LuaHBTeX

Pada saat pembaruan artikel ini ditulis (Juli 2023), masih sedikit dokumentasi formal tentang penggunaan font warna OpenType berflavor SVG dengan LuaLaTeX. Beberapa [komentar yang dibuat dalam diskusi daring](https://github.com/latex3/luaotfload/issues/96) menyarankan penggunaan `fontspec`’s `RawFeature`, seperti ditunjukkan dalam pseudokode di bawah. Ganti `*nama berkas font SVG Anda di sini*` dengan nama berkas font berbasis SVG yang dapat diakses oleh kode LaTeX Anda:

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

Jika Anda menghilangkan `fontspec` dan memuat `luaotfload` secara langsung, Anda mungkin perlu mendeklarasikan dan menentukan font dengan cara berikut—eksperimen kami menunjukkan bahwa Anda perlu menghilangkan opsi `mode=harf` agar ini berfungsi:

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

**Beberapa catatan kehati-hatian**

Pembaca yang tertarik menggunakan font warna OpenType berflavor SVG perlu memperhatikan:

* Font OpenType berflavor SVG yang mengandung sejumlah besar glyph dapat [mahal secara komputasi bagi LuaLaTeX](#processing-svg-glyph-data) untuk diproses, yang berpotensi mengakibatkan [timeout Overleaf](/latex/id/basis-pengetahuan/038-fixing-and-preventing-compile-timeouts.md).
* Dukungan LuaLaTeX untuk font-font ini dapat [dianggap eksperimental](https://github.com/latex3/luaotfload/issues/96#issuecomment-530317399): hasilnya dapat bervariasi menurut rilis TeX Live yang digunakan proyek Anda; oleh karena itu, disarankan untuk bereksperimen dan melangkah dengan hati-hati.

**Pemrosesan data glyph SVG**

SVG memungkinkan para perancang menghasilkan desain yang kompleks dan berwarna yang merepresentasikan glyph sebuah font—dengan tunduk pada beberapa pembatasan SVG [yang didokumentasikan dalam spesifikasi OpenType](https://docs.microsoft.com/en-us/typography/opentype/spec/svg). Namun, mesin TeX, termasuk LuaHBTeX, tidak dapat langsung mengimpor (menggunakan) berkas atau data SVG—seperti data SVG yang digunakan untuk mendeskripsikan bentuk glyph dalam font warna OpenType berflavor SVG. Data SVG sebuah glyph harus dikonversi ke format PDF karena LuaHBTeX dapat menggunakannya untuk menata glyph dan menghasilkan dokumen PDF akhir. Konversi SVG-ke-PDF itu ditangani oleh kode Lua di dalam `luaoftload`: setiap data SVG glyph diekstrak dari berkas font, disimpan ke sebuah `.svg` file sementara dan dikonversi ke PDF menggunakan Inkscape melalui baris perintahnya. Mengekstrak data SVG dan mengonversinya ke PDF menimbulkan sejumlah overhead pemrosesan, yang berakibat pada waktu kompilasi dokumen yang berpotensi lama—terutama dokumen yang menggunakan font SVG besar yang berisi ribuan glyph emoji.

#### Font warna OpenType berbasis raster

**Menggunakan format font warna OpenType CBDT/CBLC milik Google dengan LuaHBTeX**

[Noto Color Emoji](https://fonts.google.com/noto/specimen/Noto+Color+Emoji) adalah font warna OpenType yang disertakan dengan TeX Live, sehingga mudah digunakan dalam proyek Overleaf. Karena Noto Color Emoji menggunakan grafis format PNG untuk merepresentasikan glyph emoji, kita dapat menggunakannya untuk menata huruf emoji bebek (raster) berukuran besar—seperti ditunjukkan oleh contoh berikut. Perhatikan lagi bahwa `fontspec` deklarasi font (`\emojifont`) menggunakan `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}
```

[Buka contoh LuaLaTeX ini untuk menata huruf bebek raster.](https://www.overleaf.com/docs?engine=lualatex\&snip_name=Typesetting+a+large+raster+duck\&snip=%5Cdocumentclass%7Barticle%7D%0A%5Cusepackage%7Bfontspec%7D%0A%5Ctitle%7BDuck+demo%7D%0A%5Cbegin%7Bdocument%7D%0A%5Cnewfontfamily%5Cemojifont%5BRenderer%3DHarfbuzz%2CSizeFeatures%3D%7BSize%3D400%7D%5D%7BNotoColorEmoji.ttf%7D%0A%5Cemojifont%5CUchar%221F986%0A%5Cend%7Bdocument%7D)

Berikut bebek raster yang dihasilkan oleh contoh di atas:

![Emoji bebek raster yang ditata huruf oleh LaTeX](/files/0c841a70b4b75a5c3605d84d4dca33145ebadd13)

Jika Anda mencoba menggunakan `NotoColorEmoji.ttf` tetapi menghilangkan `[Renderer=Harfbuzz]` dari `fontspec` deklarasi, LuaHBTeX akan gagal dan mengeluarkan pesan kesalahan ketika mencoba menuliskan berkas PDF:

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

Alasan untuk kesalahan ini pada [tabel loca](https://docs.microsoft.com/en-us/typography/opentype/spec/loca) adalah [dijelaskan di GitHub](https://github.com/latex3/luaotfload/issues/98#issuecomment-531610153).

**Menggunakan format font warna OpenType sbix milik Apple dengan LuaHBTeX**

Pengujian offline menunjukkan bahwa LuaHBTeX mendukung varian `sbix` font warna OpenType, tetapi, sampai artikel ini ditulis, kami belum dapat menemukan font emoji warna varian `sbix`-varian yang berlisensi sesuai untuk mendemonstrasikan penataan huruf bebek. Mohon [hubungi kami](https://www.overleaf.com/contact) beri tahu kami

## Pengenalan ke LuaHBTeX HarfBuzz API

![Db.gif](/files/8e9cb3961717e15eff4a9e636ffbb3363fc8150f) ![Db.gif](/files/8e9cb3961717e15eff4a9e636ffbb3363fc8150f)

Pembentukan huruf, khususnya untuk bahasa dengan aksara kompleks, dan bahkan emoji, merupakan tugas yang secara inheren sulit sehingga, tidak mengherankan, HarfBuzz adalah pustaka canggih yang bisa jadi sulit digunakan—kecuali Anda sudah akrab dengan operasi pembentukan teks. Pada bagian terakhir ini, kita melihat integrasi HarfBuzz di LuaHBTeX dan cara mengaksesnya melalui kode Lua di dalam `\directlua`.

Contoh kami menggunakan kode yang cukup dasar untuk mendemonstrasikan API HarfBuzz LuaHBTeX. Kode ini agak dibuat-buat, bukan berkualitas tingkat produksi, dan juga tidak terlalu praktis karena satu-satunya tujuannya adalah memperkenalkan beberapa gagasan inti. Kami membagi kode Lua menjadi dua `\directlua` bagian: yang pertama memuat `luaharfbuzz` pustaka dan membuat beberapa variabel global yang akan kami gunakan dalam `\directlua` bagian `\codestoemoji`.

Tampaknya tepat untuk meniru penggunaan Knuth atas tanda double dangerous-bend (gambar milik [situs ini](http://www.truetex.com/db.htm)) karena kontennya agak tingkat rendah dan “mengintip ke balik kap mesin”—meskipun kami berharap ini mungkin menarik bagi pembaca yang lebih berani. Integrasi HarfBuzz oleh LuaHBTeX berasal dari [proyek luaharfbuzz di GitHub](https://github.com/ufyTeX/luaharfbuzz/wiki#projects-using-luaharfbuzz) tempat Anda dapat menemukan sebuah [pengantar ke proyek](https://github.com/ufyTeX/luaharfbuzz/wiki) bersama dengan sebuah [daftar API luaharfbuzz](http://ufytex.github.io/luaharfbuzz/).

### Langkah pertama: memuat pustaka luaharfbuzz dan menemukan font

Untuk menggunakan API HarfBuzz LuaHBTeX, pertama-tama kita perlu memuat pustaka (modul) bernama `luaharfbuzz`, yang dibangun ke dalam LuaHBTeX, dan menyimpan tabel yang dikembalikan dalam sebuah variabel (global) yang akan kita sebut `hblib`:

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

Selanjutnya, kita perlu menemukan font warna OpenType emoji yang sesuai: kita akan menggunakan Noto Color Emoji—perhatikan kita sangat malas dan tidak melakukan pemeriksaan kesalahan apa pun jika kita tidak menemukannya! Untuk menemukannya, kita akan menggunakan pustaka `kpse` (Kpathsea), yang juga merupakan bagian dari LuaTeX/LuaHBTeX:

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

Sekarang bahwa kita memiliki akses ke pustaka HarfBuzz, melalui variabel kita `hblib`, dan jalur ke font yang sesuai (`pathtofontfile`), kita dapat mulai menggunakan `hblib`. Untuk memulai, kita akan membuat HarfBuzz font dan HarfBuzz face untuk digunakan dalam `\directlua` bagian kode

```latex
%Buat HarfBuzz face dan HarfBuzz font dari Noto Color Emoji
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)
```

#### HarfBuzz font dan HarfBuzz face: apa itu?

Sebuah [Objek HarfBuzz face](https://harfbuzz.github.io/fonts-and-faces.html) merepresentasikan suatu typeface yang dimuat dari sebuah berkas font, tetapi tanpa parameter spesifik (seperti ukuran) yang ditetapkan. Sebuah [objek HarfBuzz font](https://harfbuzz.github.io/fonts-and-faces.html) merepresentasikan sebuah *instansi spesifik* dari sebuah HarfBuzz face; oleh karena itu, objek HarfBuzz font yang berbeda dapat diturunkan dari satu HarfBuzz face: setiap HarfBuzz font dapat memiliki propertinya sendiri, seperti ukuran, yang ditetapkan ke nilai yang berbeda. HarfBuzz face adalah tingkat abstraksi yang lebih tinggi daripada HarfBuzz font.

### Menggunakan glyph font untuk membuat berkas PNG

Bagian terakhir dari `\directlua` bagian `writePNGglyph(hbfontobject, glyphID)` yang kita gunakan untuk menunjukkan bahwa beberapa font warna OpenType, seperti Noto Color Emoji, menggunakan grafis PNG untuk merepresentasikan glyph emoji yang dikandungnya.

Fungsi ini menggunakan API HarfBuzz LuaHBTeX untuk mengekstrak data PNG dari glyph dan menuliskan data itu ke sebuah `.png` file bernama `Graphics<glyphID>.png`. Nama berkas itu `.png` dikembalikan untuk digunakan oleh `\includegraphics` untuk menyematkan gambar glyph PNG dalam PDF yang kita tata huruf.

Dengan `writePNGglyph(hbfontobject, glyphID)` di tempat, bagian `\directlua` kode pertama kita terlihat seperti ini:

```latex
\directlua{

% Muat pustaka luaharfbuzz dari LuaHBTeX
hblib=require("luaharfbuzz")

% Temukan font Noto Color Emoji di server Overleaf
pathtofontfile=kpse.find_file("NotoColorEmoji.ttf","truetype fonts")

% Buat HarfBuzz face dan HarfBuzz font dari Noto Color Emoji
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)

% Fungsi ini menerima sebuah font dan sebuah ID glyph:
% fungsi ini mengekstrak data PNG glyph dan menulis
% data itu ke sebuah berkas .png

function writePNGglyph(hbfontobject, glyphID)

    % Ambil data PNG glyph
    local pngblob=hbfontobject:ot_color_glyph_get_png(glyphID)
    local pngdata=pngblob:get_data()

    % Susun nama berkas untuk berkas .png kita
    local fname="Glyph"..glyphID..".png"

    % Tulis berkas .png dan kembalikan nama berkas
    local output = assert(io.open(fname, "wb"))
    output:write(pngdata)
    output:close()

    % Kembalikan nama berkas untuk digunakan oleh \includegraphics
    return fname
end
}
```

### Bagian \directlua kedua: buat makro \codestoemoji

Tujuannya adalah untuk mendefinisikan sebuah makro `\codestoemoji` yang dapat kita panggil dengan sepotong teks yang berisi kode karakter emoji yang ingin kita bentuk dengan HarfBuzz. Secara khusus, kita akan menggunakan `\Uchar<kode karakter>` untuk merepresentasikan setiap karakter emoji; contohnya:

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

Banyak hal terjadi dalam definisi `\codestoemoji` yang akan kami jelaskan di bawah, tetapi definisinya terlihat seperti ini:

```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()
    % Tabel glyph, hbglyphs, menggunakan indeks 1-based
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Perkecil ukuran gambar PNG impor kita
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
}}
```

#### Memahami definisi makro \codestoemoji

Fitur `\codestoemoji` makro sebagian besar adalah kode Lua yang terkandung di dalam `\directlua`, jadi jika Anda ingin tahu lebih banyak tentang *bagaimana* `\directlua` cara kerja [lihat artikel Overleaf `\directlua`](/latex/id/artikel-mendalam/09-an-introduction-to-luatex-part-2-understanding-directlua.md)Memahami `\directlua` . Artikel ini menjelaskan bagaimana LuaTeX dan LuaHBTeX memproses `\noexpand` dan `\unexpanded`.

**Menangani parameter makro: "#1"**

Makro dimulai dengan tiga baris ini:

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

yang menjalankan tugas berikut:

* `local str="#1"`: ini membuat string Lua dari input yang diteruskan oleh makro;
* `local hbbuffer = hblib.Buffer.new()`: ini menggunakan API HarfBuzz untuk membuat buffer guna menampung teks yang ingin kita bentuk dengan HarfBuzz;
* `hbbuffer:add_utf8(str)`: ini menambahkan string format UTF-8, yang dibuat dari input makro kita, ke buffer HarfBuzz.

Baris kode pertama

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

tampak cukup sederhana tetapi operasinya melibatkan kompleksitas yang cukup besar, yang layak dieksplorasi sedikit lebih rinci.

Jika kita mempertimbangkan baris kode ketiga

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

kita melihat bahwa baris ini menggunakan variabel `str` untuk menyediakan buffer HarfBuzz sebuah string Unicode yang diformat dalam UTF-8. Agar itu berhasil, variabel `str` itu sendiri harus berisi teks Unicode yang diformat sebagai UTF-8; jadi timbul pertanyaan: *bagaimana* apakah LuaHBTeX “mengonversi” argumen makro `"#1"`, yang berisi `\Uchar` perintah, ke variabel string Lua `str` yang berisi teks UTF-8 untuk HarfBuzz?

Jika kita melihat penggunaan yang kita maksud dari `\codestoemoji` makro:

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

inputnya, seperti `\Uchar"1F3F4\Uchar"E0067\Uchar"E0062\Uchar"E0065...`, sama sekali tidak terlihat seperti urutan karakter emoji yang dienkode dalam UTF-8. Selain itu, HarfBuzz tidak tahu apa-apa tentang perintah TeX. Entah bagaimana, input TeX mentah yang terdiri dari `\Uchar` perintah diubah menjadi karakter Unicode yang dienkode dalam UTF-8 yang dapat digunakan HarfBuzz, tetapi *bagaimana*?

Jawabannya terletak pada perilaku `\Uchar` perintah: mencoba memanggil `\codestoemoji` menggunakan `\char` bukannya `\Uchar` akan gagal, tetapi *mengapa*?

**\Uchar: ekspansi dalam \directlua**

Ketika `\codestoemoji` makro dipanggil, perintah `\directlua` , yang tersimpan dalam definisi makro, harus menyiapkan kode Lua untuk dikirim ke interpreter Lua bawaan LuaHBTeX. Bagian dari proses persiapan kode itu adalah perluasan terhadap setiap perintah TeX/LaTeX yang ada dalam kode Lua asli dalam definisi makro, bersama dengan perluasan terhadap argumen makro apa pun yang diberikan oleh pengguna. Proses perluasan itu menghasilkan sebuah daftar token yang selanjutnya diubah kembali menjadi teks, menghasilkan kode Lua untuk diteruskan ke interpreter Lua. Demi kenyamanan, kami menampilkan ulang sebuah diagram dari artikel Overleaf [lihat artikel Overleaf `\directlua`](/latex/id/artikel-mendalam/09-an-introduction-to-luatex-part-2-understanding-directlua.md):

![Mekanika \directlua](/files/c57f1ae763be83a2b460e25bd84b352a91032c04)

Makro `\codestoemoji` dimaksudkan untuk dipanggil menggunakan `\Uchar` perintah dan, [seperti dicatat sebelumnya dalam artikel](#the-key-difference-expansion), `\Uchar` adalah perintah yang dapat diekspansi dan ekspansinya menghasilkan token karakter. Dalam aktivitas pemrosesan `\directlua`, LuaHBTeX memperluas setiap `\Uchar<kode karakter>` perintah di mana *menghapus* setiap `\Uchar<kode karakter>` dari masukan dan *menggantikannya* itu dengan nilai perluasan yang sesuai: sebuah token karakter yang merepresentasikan `<kode karakter>`.

Pada tahap akhir pemrosesan, daftar token awal yang dihasilkan oleh `\directlua` diubah *kembali menjadi teks* untuk menjadi kode Lua yang ditujukan bagi interpreter Lua (lihat diagram di atas). Semua token karakter yang dihasilkan oleh perluasan `\Uchar` juga *diubah kembali menjadi teks*: konversi token karakter menjadi teks itu menghasilkan representasi UTF-8 dari `<kode karakter>` nilai asli.

Dalam contoh kita, pada saat kode Lua dihasilkan dan siap untuk interpreter Lua, input makro untuk "#1" telah dikonversi menjadi urutan teks UTF-8: variabel `str` sekarang adalah string teks UTF-8 yang dapat dengan aman ditambahkan ke buffer HarfBuzz.

**Mengapa \char tidak berfungsi?**

Jawaban singkatnya adalah karena `\char` adalah *berisi nilai data aktual yang disimpan dalam* sebuah perintah yang dapat diperluas. Tidak seperti `\Uchar` perintah, `\char` perintah *tidak dihapus* dari input selama `\directlua`pemrosesan awalnya untuk menghasilkan daftar token, mereka “melewati” dan menjadi bagian dari daftar token yang sedang dibangun oleh `\directlua`. Misalnya, jika argumen untuk `\codestoemoji` berisi `\char"1F3F4` LuaHBTeX akan mengubahnya menjadi urutan token dan menyimpannya sebagai bagian dari total daftar token yang sedang dihasilkan.

Pada tahap pemrosesan berikutnya, yakni mengubah token kembali menjadi teks, kode Lua yang dihasilkan akan berisi *string literal* `\char"1F3F4` di dalam teks yang digunakan untuk mendefinisikan variabel kita `str`. Ketika konten dari `str` ditambahkan ke buffer HarfBuzz, buffer tersebut tidak akan berisi urutan yang dienkode UTF-8 yang merepresentasikan karakter emoji "1F3F4, melainkan akan berisi string literal `\char"1F3F4`, yang akan dicoba dibentuk oleh HarfBuzz dan, untuk tujuan kita, tidak akan menghasilkan glif emoji. Kebetulan, string `\char"1F3F4` juga akan menghasilkan galat sintaks Lua kecuali jika dibuat sebagai “long-bracket string”—lihat [Apa itu escape sequence Lua](/latex/id/artikel-mendalam/09-an-introduction-to-luatex-part-2-understanding-directlua.md#what-are-e2809clua-escape-sequencese2809d3f) untuk latar belakang tentang masalah itu.

Jika kita mencoba menggunakan `\codestoemoji` dengan sebuah `\char` perintah, seperti ini:

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

LuaHBTeX akan gagal dan melaporkan galat sintaks seperti ini:

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

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

Interpreter Lua mengalami masalah, sehingga
sisa potongan Lua ini akan diabaikan.
```

#### Memanggil fungsi pembentukan HarfBuzz

**Menetapkan parameter buffer**

HarfBuzz terkadang memerlukan informasi tambahan tentang teks yang diminta untuk dibentuk. Anda dapat memberikan informasi tersebut dengan mengonfigurasi `<buffer variable>` menggunakan *metode buffer*, seperti:

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

Misalnya, kita perlu memberi tahu HarfBuzz bahwa arah teks emoji kita adalah kiri-ke-kanan. Untuk melakukannya, kita menggunakan `set_direction()` metode pada `<buffer variable>` (disebut `hbbuffer`) dengan menulis:

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

di mana `hblib.Direction.new("ltr")` membuat sebuah “objek arah” yang cocok untuk diteruskan ke mesin HarfBuzz melalui Lua.

**Lakukan pembentukan**

Setelah buffer diinisialisasi dengan tepat, kita dapat meminta HarfBuzz melakukan pembentukan sebenarnya melalui fungsi `shape_full()`. Dalam contoh kita, kita menulis:

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

Parameter ke-3 dan ke-4 dari `shape_full()` fungsi harus berupa tabel Lua—kita telah menggunakan tabel kosong “`{}`” untuk kedua parameter. Bentuk umum dari `shape_full()` adalah:

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

* **`{"shaper"}`**: Biasanya tidak perlu diatur, tetapi opsinya adalah `{"ot"}` atau `{"graphite2"}`. Informasi lebih lanjut tentang konsep “shaper” dapat ditemukan di [dokumentasi HarfBuzz](https://harfbuzz.github.io/shaping-and-shape-plans.html)—catat bahwa ini mendokumentasikan API C tingkat rendah, bukan `luaharfbuzz` binding (implementasi) berbasis Lua.
* **`{font features}`**: Ini adalah tabel yang mencantumkan [fitur OpenType](https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist)—didukung oleh font—yang ingin Anda minta HarfBuzz terapkan selama pembentukan.

Setiap fitur font yang ingin Anda gunakan perlu dibuat menggunakan `luaharfbuzz` fungsi pustaka

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

di mana

* `library_instance` adalah `luaharfbuzz` variabel instance pustaka Anda (`hblib` dalam contoh kita);
* `feature_string` menggunakan [sintaks untuk mendefinisikan fitur](https://github.com/ufytex/luaharfbuzz/wiki/Feature-Strings). Contohnya adalah `+smcp` untuk mengaktifkan huruf kapital kecil atau `-kern` untuk menonaktifkan kerning.

Misalnya:

```latex
local dosmcp = hblib.Feature.new("+smcp")
local nokern = hblib.Feature.new("-kern")
% Gunakan fitur font Anda seperti ini
local res = hblib.shape_full(hbfont, hbbuffer, {dosmcp,nokern},{})
```

#### Mengakses hasil: mendapatkan glif

Dan akhirnya, jika operasi pembentukan berhasil, glif yang telah dibentuk dikembalikan dalam variabel buffer `hbbuffer` yang kita buat sebelumnya dalam kode.

Kita mengakses glif melalui metode buffer `get_glyphs()` dan menggunakan loop untuk mendapatkan setiap glif secara individual. Perhatikan bahwa tabel Lua yang menyimpan glif, `hbglyphs` dalam contoh kita, diindeks mulai dari 1, bukan 0.

Setiap *pengidentifikasi glif* (yang membingungkan disebut `codepoint`), dan font HarfBuzz (`hbfont`), diteruskan ke `writePNGglyph()` fungsi yang membuat file PNG menggunakan representasi citra raster font dari glif tersebut.

`writePNGglyph()` menulis file PNG dan mengembalikan nama file PNG, yang digunakan untuk mengimpor file PNG (yang diskalakan) ke dokumen LaTeX kita melalui `\includegraphics[scale=0.75]{<fname>}`. Perhatikan bagaimana kita dapat menggunakan `\includegraphics` secara langsung di dalam kode Lua.

```latex
if (res) then
    local hbglyphs=hbbuffer:get_glyphs()
    % Tabel glyph, hbglyphs, menggunakan indeks 1-based
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Perkecil ukuran gambar PNG impor kita
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
```

### Kode lengkap yang dapat Anda Buka di Overleaf

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

% Muat pustaka luaharfbuzz dari LuaHBTeX
hblib=require("luaharfbuzz")

% Temukan font Noto Color Emoji di server Overleaf
pathtofontfile=kpse.find_file("NotoColorEmoji.ttf","truetype fonts")

% Buat HarfBuzz face dan HarfBuzz font dari Noto Color Emoji
hbface = hblib.Face.new(pathtofontfile)
hbfont = hblib.Font.new(hbface)

% Fungsi ini menerima sebuah font dan sebuah ID glyph:
% ia mengekstrak data PNG glif dan menulis
% data itu ke sebuah berkas .png

function writePNGglyph(hbfontobject, glyphID)

    % Ambil data PNG glyph
    local pngblob=hbfontobject:ot_color_glyph_get_png(glyphID)
    local pngdata=pngblob:get_data()

    % Susun nama berkas untuk berkas .png kita
    local fname="Glyph"..glyphID..".png"

    % Tulis berkas .png dan kembalikan nama berkas
    local output = assert(io.open(fname, "wb"))
    output:write(pngdata)
    output:close()

    % Kembalikan nama berkas untuk digunakan oleh \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()
    % Tabel glif, hbglyphs, berbasis 1.
    local i = 1
    while hbglyphs[i] \noexpand~= nil do
        local glyph = hbglyphs[i]
        i = i + 1
        local fname=writePNGglyph(hbfont, glyph.codepoint)
        % Perkecil ukuran gambar PNG impor kita
        local s = 0.75
        local scal="[scale="..tostring(s).."]"
        tex.print([[\noexpand\includegraphics]]..scal..[[{]]..fname..[[}]])
     end
end
}}

Seekor bebek: \codestoemoji{\Uchar"1F986}

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

[Buka contoh API luaharfbuzz ini di Overleaf.](/latex/id/artikel-mendalam/10-an-overview-of-technologies-supporting-the-use-of-colour-emoji-fonts-in-latex.md)

Contoh ini menghasilkan keluaran berikut:

![Harfbuzzexample.png](/files/758e8c1eef968463d4a6ac1006df49098201ba95)

## Bagian bonus: Seru-seruan dengan matematika emoji

Untuk menutup dengan nada ringan, seorang anggota tim Overleaf menggunakan [`emoji` Paket LaTeX](https://ctan.org/pkg/emoji?lang=en) untuk membuat contoh yang menyenangkan:

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

[Buka contoh seru ini di 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)

Contoh ini menghasilkan keluaran berikut:

![Emojimath2.png](/files/8e0ea16ea57be77be99100c4b710ef66f8a9dda3)


---

# 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/id/artikel-mendalam/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.
