1mod freetype_sys;
2mod harfbuzz_sys;
3
4use self::freetype_sys::*;
5use self::harfbuzz_sys::*;
6
7use crate::color::Color;
8use crate::device::CURRENT_DEVICE;
9use crate::framebuffer::Framebuffer;
10use crate::geom::{Point, Vec2};
11use crate::helpers::IsHidden;
12use anyhow::{format_err, Error};
13use bitflags::bitflags;
14use fxhash::FxHashMap;
15use globset::Glob;
16use lazy_static::lazy_static;
17use std::collections::BTreeSet;
18use std::ffi::{CStr, CString};
19use std::os::unix::ffi::OsStrExt;
20use std::path::Path;
21use std::path::PathBuf;
22use std::ptr;
23use std::rc::Rc;
24use std::slice;
25use std::str;
26use thiserror::Error;
27use tracing::{error, warn};
28use walkdir::WalkDir;
29
30pub const FONT_SIZES: [u32; 3] = [349, 524, 629];
32
33pub const KEYBOARD_FONT_SIZES: [u32; 2] = [337, 843];
34
35pub const DISPLAY_FONT_SIZE: u32 = 2516;
36
37pub const NORMAL_STYLE: Style = Style {
38 family: Family::SansSerif,
39 variant: Variant::REGULAR,
40 size: FONT_SIZES[1],
41};
42
43pub const SPECIAL_STYLE: Style = Style {
44 family: Family::SansSerif,
45 variant: Variant::ITALIC,
46 size: FONT_SIZES[1],
47};
48
49pub const KBD_CHAR: Style = Style {
50 family: Family::Keyboard,
51 variant: Variant::REGULAR,
52 size: KEYBOARD_FONT_SIZES[1],
53};
54
55pub const KBD_LABEL: Style = Style {
56 family: Family::Keyboard,
57 variant: Variant::REGULAR,
58 size: FONT_SIZES[0],
59};
60
61pub const DISPLAY_STYLE: Style = Style {
62 family: Family::Display,
63 variant: Variant::REGULAR,
64 size: DISPLAY_FONT_SIZE,
65};
66
67lazy_static! {
68 pub static ref MD_TITLE: Style = {
69 let ratio = (CURRENT_DEVICE.dims.0 as f32 * 300.0) /
72 (CURRENT_DEVICE.dpi as f32 * 1404.0);
73 let size = ((FONT_SIZES[2] as f32 * ratio) as u32).clamp(FONT_SIZES[1],
74 FONT_SIZES[2]);
75 Style {
76 family: Family::Serif,
77 variant: Variant::ITALIC,
78 size,
79 }
80 };
81}
82
83pub const MD_AUTHOR: Style = Style {
84 family: Family::Serif,
85 variant: Variant::REGULAR,
86 size: FONT_SIZES[1],
87};
88
89pub const MD_YEAR: Style = NORMAL_STYLE;
90
91pub const MD_KIND: Style = Style {
92 family: Family::SansSerif,
93 variant: Variant::BOLD,
94 size: FONT_SIZES[0],
95};
96
97pub const MD_SIZE: Style = Style {
98 family: Family::SansSerif,
99 variant: Variant::REGULAR,
100 size: FONT_SIZES[0],
101};
102
103#[cfg(any(not(target_os = "linux"), target_arch = "arm"))]
104#[link(name = "mupdf")]
105extern "C" {
106 pub static _binary_DroidSansFallback_ttf: [libc::c_uchar; 3556308];
110 pub static _binary_NotoEmoji_Regular_ttf: [libc::c_uchar; 418804];
111 pub static _binary_NotoMusic_Regular_otf: [libc::c_uchar; 60812];
112 pub static _binary_NotoNaskhArabic_Regular_otf: [libc::c_uchar; 119664];
113 pub static _binary_NotoNastaliqUrdu_Regular_otf: [libc::c_uchar; 373220];
114 pub static _binary_NotoSans_Regular_otf: [libc::c_uchar; 290336];
115 pub static _binary_NotoSansAdlam_Regular_otf: [libc::c_uchar; 33448];
116 pub static _binary_NotoSansAnatolianHieroglyphs_Regular_otf: [libc::c_uchar; 134420];
117 pub static _binary_NotoSansAvestan_Regular_otf: [libc::c_uchar; 9300];
118 pub static _binary_NotoSansBamum_Regular_otf: [libc::c_uchar; 103668];
119 pub static _binary_NotoSansBassaVah_Regular_otf: [libc::c_uchar; 6300];
120 pub static _binary_NotoSansBatak_Regular_otf: [libc::c_uchar; 11108];
121 pub static _binary_NotoSansBhaiksuki_Regular_otf: [libc::c_uchar; 121620];
122 pub static _binary_NotoSansBrahmi_Regular_otf: [libc::c_uchar; 29544];
123 pub static _binary_NotoSansBuginese_Regular_otf: [libc::c_uchar; 6256];
124 pub static _binary_NotoSansBuhid_Regular_otf: [libc::c_uchar; 5076];
125 pub static _binary_NotoSansCanadianAboriginal_Regular_otf: [libc::c_uchar; 38068];
126 pub static _binary_NotoSansCarian_Regular_otf: [libc::c_uchar; 5592];
127 pub static _binary_NotoSansCaucasianAlbanian_Regular_otf: [libc::c_uchar; 17388];
128 pub static _binary_NotoSansChakma_Regular_otf: [libc::c_uchar; 29488];
129 pub static _binary_NotoSansCham_Regular_otf: [libc::c_uchar; 21224];
130 pub static _binary_NotoSansCherokee_Regular_otf: [libc::c_uchar; 57308];
131 pub static _binary_NotoSansChorasmian_Regular_otf: [libc::c_uchar; 12460];
132 pub static _binary_NotoSansCoptic_Regular_otf: [libc::c_uchar; 21380];
133 pub static _binary_NotoSansCuneiform_Regular_otf: [libc::c_uchar; 416308];
134 pub static _binary_NotoSansCypriot_Regular_otf: [libc::c_uchar; 7024];
135 pub static _binary_NotoSansCyproMinoan_Regular_otf: [libc::c_uchar; 8568];
136 pub static _binary_NotoSansDeseret_Regular_otf: [libc::c_uchar; 9016];
137 pub static _binary_NotoSansDuployan_Regular_otf: [libc::c_uchar; 10276];
138 pub static _binary_NotoSansEgyptianHieroglyphs_Regular_otf: [libc::c_uchar; 362960];
139 pub static _binary_NotoSansElbasan_Regular_otf: [libc::c_uchar; 8684];
140 pub static _binary_NotoSansElymaic_Regular_otf: [libc::c_uchar; 7620];
141 pub static _binary_NotoSansGlagolitic_Regular_otf: [libc::c_uchar; 17176];
142 pub static _binary_NotoSansGothic_Regular_otf: [libc::c_uchar; 5416];
143 pub static _binary_NotoSansGunjalaGondi_Regular_otf: [libc::c_uchar; 32372];
144 pub static _binary_NotoSansHanifiRohingya_Regular_otf: [libc::c_uchar; 16576];
145 pub static _binary_NotoSansHanunoo_Regular_otf: [libc::c_uchar; 6596];
146 pub static _binary_NotoSansHatran_Regular_otf: [libc::c_uchar; 4324];
147 pub static _binary_NotoSansImperialAramaic_Regular_otf: [libc::c_uchar; 5436];
148 pub static _binary_NotoSansInscriptionalPahlavi_Regular_otf: [libc::c_uchar; 5464];
149 pub static _binary_NotoSansInscriptionalParthian_Regular_otf: [libc::c_uchar; 6788];
150 pub static _binary_NotoSansJavanese_Regular_otf: [libc::c_uchar; 86944];
151 pub static _binary_NotoSansKaithi_Regular_otf: [libc::c_uchar; 39756];
152 pub static _binary_NotoSansKawi_Regular_otf: [libc::c_uchar; 30940];
153 pub static _binary_NotoSansKayahLi_Regular_otf: [libc::c_uchar; 7100];
154 pub static _binary_NotoSansKharoshthi_Regular_otf: [libc::c_uchar; 27708];
155 pub static _binary_NotoSansKhudawadi_Regular_otf: [libc::c_uchar; 14764];
156 pub static _binary_NotoSansLepcha_Regular_otf: [libc::c_uchar; 18832];
157 pub static _binary_NotoSansLimbu_Regular_otf: [libc::c_uchar; 10040];
158 pub static _binary_NotoSansLinearA_Regular_otf: [libc::c_uchar; 33640];
159 pub static _binary_NotoSansLinearB_Regular_otf: [libc::c_uchar; 36892];
160 pub static _binary_NotoSansLisu_Regular_otf: [libc::c_uchar; 5688];
161 pub static _binary_NotoSansLycian_Regular_otf: [libc::c_uchar; 4108];
162 pub static _binary_NotoSansLydian_Regular_otf: [libc::c_uchar; 4088];
163 pub static _binary_NotoSansMahajani_Regular_otf: [libc::c_uchar; 10136];
164 pub static _binary_NotoSansMandaic_Regular_otf: [libc::c_uchar; 13160];
165 pub static _binary_NotoSansManichaean_Regular_otf: [libc::c_uchar; 16496];
166 pub static _binary_NotoSansMarchen_Regular_otf: [libc::c_uchar; 69240];
167 pub static _binary_NotoSansMasaramGondi_Regular_otf: [libc::c_uchar; 23052];
168 pub static _binary_NotoSansMath_Regular_otf: [libc::c_uchar; 258796];
169 pub static _binary_NotoSansMedefaidrin_Regular_otf: [libc::c_uchar; 27060];
170 pub static _binary_NotoSansMeeteiMayek_Regular_otf: [libc::c_uchar; 13056];
171 pub static _binary_NotoSansMendeKikakui_Regular_otf: [libc::c_uchar; 19664];
172 pub static _binary_NotoSansMeroitic_Regular_otf: [libc::c_uchar; 19980];
173 pub static _binary_NotoSansMiao_Regular_otf: [libc::c_uchar; 26460];
174 pub static _binary_NotoSansModi_Regular_otf: [libc::c_uchar; 29412];
175 pub static _binary_NotoSansMongolian_Regular_otf: [libc::c_uchar; 111040];
176 pub static _binary_NotoSansMro_Regular_otf: [libc::c_uchar; 5608];
177 pub static _binary_NotoSansMultani_Regular_otf: [libc::c_uchar; 7852];
178 pub static _binary_NotoSansNabataean_Regular_otf: [libc::c_uchar; 6448];
179 pub static _binary_NotoSansNagMundari_Regular_otf: [libc::c_uchar; 8612];
180 pub static _binary_NotoSansNandinagari_Regular_otf: [libc::c_uchar; 86940];
181 pub static _binary_NotoSansNewa_Regular_otf: [libc::c_uchar; 99568];
182 pub static _binary_NotoSansNewTaiLue_Regular_otf: [libc::c_uchar; 10884];
183 pub static _binary_NotoSansNKo_Regular_otf: [libc::c_uchar; 15164];
184 pub static _binary_NotoSansNushu_Regular_otf: [libc::c_uchar; 72472];
185 pub static _binary_NotoSansOgham_Regular_otf: [libc::c_uchar; 3720];
186 pub static _binary_NotoSansOlChiki_Regular_otf: [libc::c_uchar; 7024];
187 pub static _binary_NotoSansOldHungarian_Regular_otf: [libc::c_uchar; 44628];
188 pub static _binary_NotoSansOldItalic_Regular_otf: [libc::c_uchar; 6360];
189 pub static _binary_NotoSansOldNorthArabian_Regular_otf: [libc::c_uchar; 6132];
190 pub static _binary_NotoSansOldPermic_Regular_otf: [libc::c_uchar; 8512];
191 pub static _binary_NotoSansOldPersian_Regular_otf: [libc::c_uchar; 9856];
192 pub static _binary_NotoSansOldSogdian_Regular_otf: [libc::c_uchar; 12260];
193 pub static _binary_NotoSansOldSouthArabian_Regular_otf: [libc::c_uchar; 4624];
194 pub static _binary_NotoSansOldTurkic_Regular_otf: [libc::c_uchar; 6884];
195 pub static _binary_NotoSansOsage_Regular_otf: [libc::c_uchar; 9292];
196 pub static _binary_NotoSansOsmanya_Regular_otf: [libc::c_uchar; 6784];
197 pub static _binary_NotoSansPahawhHmong_Regular_otf: [libc::c_uchar; 13024];
198 pub static _binary_NotoSansPalmyrene_Regular_otf: [libc::c_uchar; 8480];
199 pub static _binary_NotoSansPauCinHau_Regular_otf: [libc::c_uchar; 8124];
200 pub static _binary_NotoSansPhagsPa_Regular_otf: [libc::c_uchar; 24036];
201 pub static _binary_NotoSansPhoenician_Regular_otf: [libc::c_uchar; 5288];
202 pub static _binary_NotoSansPsalterPahlavi_Regular_otf: [libc::c_uchar; 12748];
203 pub static _binary_NotoSansRejang_Regular_otf: [libc::c_uchar; 6440];
204 pub static _binary_NotoSansRunic_Regular_otf: [libc::c_uchar; 7200];
205 pub static _binary_NotoSansSamaritan_Regular_otf: [libc::c_uchar; 9024];
206 pub static _binary_NotoSansSaurashtra_Regular_otf: [libc::c_uchar; 16020];
207 pub static _binary_NotoSansSharada_Regular_otf: [libc::c_uchar; 32824];
208 pub static _binary_NotoSansShavian_Regular_otf: [libc::c_uchar; 5468];
209 pub static _binary_NotoSansSiddham_Regular_otf: [libc::c_uchar; 91992];
210 pub static _binary_NotoSansSignWriting_Regular_otf: [libc::c_uchar; 2780224];
211 pub static _binary_NotoSansSogdian_Regular_otf: [libc::c_uchar; 48356];
212 pub static _binary_NotoSansSoraSompeng_Regular_otf: [libc::c_uchar; 6332];
213 pub static _binary_NotoSansSoyombo_Regular_otf: [libc::c_uchar; 52036];
214 pub static _binary_NotoSansSundanese_Regular_otf: [libc::c_uchar; 9420];
215 pub static _binary_NotoSansSylotiNagri_Regular_otf: [libc::c_uchar; 12852];
216 pub static _binary_NotoSansSymbols_Regular_otf: [libc::c_uchar; 109696];
217 pub static _binary_NotoSansSymbols2_Regular_otf: [libc::c_uchar; 375388];
218 pub static _binary_NotoSansSyriac_Regular_otf: [libc::c_uchar; 124756];
219 pub static _binary_NotoSansTagalog_Regular_otf: [libc::c_uchar; 5500];
220 pub static _binary_NotoSansTagbanwa_Regular_otf: [libc::c_uchar; 5356];
221 pub static _binary_NotoSansTaiLe_Regular_otf: [libc::c_uchar; 8616];
222 pub static _binary_NotoSansTaiTham_Regular_otf: [libc::c_uchar; 76880];
223 pub static _binary_NotoSansTaiViet_Regular_otf: [libc::c_uchar; 12280];
224 pub static _binary_NotoSansTakri_Regular_otf: [libc::c_uchar; 17864];
225 pub static _binary_NotoSansTangsa_Regular_otf: [libc::c_uchar; 16908];
226 pub static _binary_NotoSansThaana_Regular_otf: [libc::c_uchar; 12392];
227 pub static _binary_NotoSansTifinagh_Regular_otf: [libc::c_uchar; 24776];
228 pub static _binary_NotoSansTirhuta_Regular_otf: [libc::c_uchar; 52432];
229 pub static _binary_NotoSansUgaritic_Regular_otf: [libc::c_uchar; 5048];
230 pub static _binary_NotoSansVai_Regular_otf: [libc::c_uchar; 24088];
231 pub static _binary_NotoSansWancho_Regular_otf: [libc::c_uchar; 15140];
232 pub static _binary_NotoSansWarangCiti_Regular_otf: [libc::c_uchar; 23484];
233 pub static _binary_NotoSansYi_Regular_otf: [libc::c_uchar; 92164];
234 pub static _binary_NotoSansZanabazarSquare_Regular_otf: [libc::c_uchar; 13804];
235 pub static _binary_NotoSerif_Regular_otf: [libc::c_uchar; 289412];
236 pub static _binary_NotoSerifAhom_Regular_otf: [libc::c_uchar; 14516];
237 pub static _binary_NotoSerifArmenian_Regular_otf: [libc::c_uchar; 14160];
238 pub static _binary_NotoSerifBalinese_Regular_otf: [libc::c_uchar; 32348];
239 pub static _binary_NotoSerifBengali_Regular_otf: [libc::c_uchar; 101332];
240 pub static _binary_NotoSerifDevanagari_Regular_otf: [libc::c_uchar; 169744];
241 pub static _binary_NotoSerifDivesAkuru_Regular_otf: [libc::c_uchar; 27972];
242 pub static _binary_NotoSerifDogra_Regular_otf: [libc::c_uchar; 19944];
243 pub static _binary_NotoSerifEthiopic_Regular_otf: [libc::c_uchar; 113328];
244 pub static _binary_NotoSerifGeorgian_Regular_otf: [libc::c_uchar; 31988];
245 pub static _binary_NotoSerifGrantha_Regular_otf: [libc::c_uchar; 368396];
246 pub static _binary_NotoSerifGujarati_Regular_otf: [libc::c_uchar; 64848];
247 pub static _binary_NotoSerifGurmukhi_Regular_otf: [libc::c_uchar; 26992];
248 pub static _binary_NotoSerifHebrew_Regular_otf: [libc::c_uchar; 15320];
249 pub static _binary_NotoSerifKannada_Regular_otf: [libc::c_uchar; 89032];
250 pub static _binary_NotoSerifKhitanSmallScript_Regular_otf: [libc::c_uchar; 508920];
251 pub static _binary_NotoSerifKhmer_Regular_otf: [libc::c_uchar; 40436];
252 pub static _binary_NotoSerifKhojki_Regular_otf: [libc::c_uchar; 60112];
253 pub static _binary_NotoSerifLao_Regular_otf: [libc::c_uchar; 16196];
254 pub static _binary_NotoSerifMakasar_Regular_otf: [libc::c_uchar; 5864];
255 pub static _binary_NotoSerifMalayalam_Regular_otf: [libc::c_uchar; 45668];
256 pub static _binary_NotoSerifMyanmar_Regular_otf: [libc::c_uchar; 127564];
257 pub static _binary_NotoSerifNyiakengPuachueHmong_Regular_otf: [libc::c_uchar; 12208];
258 pub static _binary_NotoSerifOldUyghur_Regular_otf: [libc::c_uchar; 15620];
259 pub static _binary_NotoSerifOriya_Regular_otf: [libc::c_uchar; 105824];
260 pub static _binary_NotoSerifSinhala_Regular_otf: [libc::c_uchar; 74924];
261 pub static _binary_NotoSerifTamil_Regular_otf: [libc::c_uchar; 33752];
262 pub static _binary_NotoSerifTelugu_Regular_otf: [libc::c_uchar; 82032];
263 pub static _binary_NotoSerifThai_Regular_otf: [libc::c_uchar; 17556];
264 pub static _binary_NotoSerifTibetan_Regular_otf: [libc::c_uchar; 334156];
265 pub static _binary_NotoSerifToto_Regular_otf: [libc::c_uchar; 5732];
266 pub static _binary_NotoSerifVithkuqi_Regular_otf: [libc::c_uchar; 42508];
267 pub static _binary_NotoSerifYezidi_Regular_otf: [libc::c_uchar; 8664];
268}
269
270#[cfg(all(target_os = "linux", not(target_arch = "arm")))]
271#[link(name = "mupdf")]
272extern "C" {
273 pub static _binary_resources_fonts_droid_DroidSansFallback_ttf_start: [libc::c_uchar; 3556308];
274 pub static _binary_resources_fonts_noto_NotoEmoji_Regular_ttf_start: [libc::c_uchar; 418804];
275 pub static _binary_resources_fonts_noto_NotoMusic_Regular_otf_start: [libc::c_uchar; 60812];
276 pub static _binary_resources_fonts_noto_NotoNaskhArabic_Regular_otf_start:
277 [libc::c_uchar; 119664];
278 pub static _binary_resources_fonts_noto_NotoNastaliqUrdu_Regular_otf_start:
279 [libc::c_uchar; 373220];
280 pub static _binary_resources_fonts_noto_NotoSans_Regular_otf_start: [libc::c_uchar; 290336];
281 pub static _binary_resources_fonts_noto_NotoSansAdlam_Regular_otf_start: [libc::c_uchar; 33448];
282 pub static _binary_resources_fonts_noto_NotoSansAnatolianHieroglyphs_Regular_otf_start:
283 [libc::c_uchar; 134420];
284 pub static _binary_resources_fonts_noto_NotoSansAvestan_Regular_otf_start:
285 [libc::c_uchar; 9300];
286 pub static _binary_resources_fonts_noto_NotoSansBamum_Regular_otf_start:
287 [libc::c_uchar; 103668];
288 pub static _binary_resources_fonts_noto_NotoSansBassaVah_Regular_otf_start:
289 [libc::c_uchar; 6300];
290 pub static _binary_resources_fonts_noto_NotoSansBatak_Regular_otf_start: [libc::c_uchar; 11108];
291 pub static _binary_resources_fonts_noto_NotoSansBhaiksuki_Regular_otf_start:
292 [libc::c_uchar; 121620];
293 pub static _binary_resources_fonts_noto_NotoSansBrahmi_Regular_otf_start:
294 [libc::c_uchar; 29544];
295 pub static _binary_resources_fonts_noto_NotoSansBuginese_Regular_otf_start:
296 [libc::c_uchar; 6256];
297 pub static _binary_resources_fonts_noto_NotoSansBuhid_Regular_otf_start: [libc::c_uchar; 5076];
298 pub static _binary_resources_fonts_noto_NotoSansCanadianAboriginal_Regular_otf_start:
299 [libc::c_uchar; 38068];
300 pub static _binary_resources_fonts_noto_NotoSansCarian_Regular_otf_start: [libc::c_uchar; 5592];
301 pub static _binary_resources_fonts_noto_NotoSansCaucasianAlbanian_Regular_otf_start:
302 [libc::c_uchar; 17388];
303 pub static _binary_resources_fonts_noto_NotoSansChakma_Regular_otf_start:
304 [libc::c_uchar; 29488];
305 pub static _binary_resources_fonts_noto_NotoSansCham_Regular_otf_start: [libc::c_uchar; 21224];
306 pub static _binary_resources_fonts_noto_NotoSansCherokee_Regular_otf_start:
307 [libc::c_uchar; 57308];
308 pub static _binary_resources_fonts_noto_NotoSansChorasmian_Regular_otf_start:
309 [libc::c_uchar; 12460];
310 pub static _binary_resources_fonts_noto_NotoSansCoptic_Regular_otf_start:
311 [libc::c_uchar; 21380];
312 pub static _binary_resources_fonts_noto_NotoSansCuneiform_Regular_otf_start:
313 [libc::c_uchar; 416308];
314 pub static _binary_resources_fonts_noto_NotoSansCypriot_Regular_otf_start:
315 [libc::c_uchar; 7024];
316 pub static _binary_resources_fonts_noto_NotoSansCyproMinoan_Regular_otf_start:
317 [libc::c_uchar; 8568];
318 pub static _binary_resources_fonts_noto_NotoSansDeseret_Regular_otf_start:
319 [libc::c_uchar; 9016];
320 pub static _binary_resources_fonts_noto_NotoSansDuployan_Regular_otf_start:
321 [libc::c_uchar; 10276];
322 pub static _binary_resources_fonts_noto_NotoSansEgyptianHieroglyphs_Regular_otf_start:
323 [libc::c_uchar; 362960];
324 pub static _binary_resources_fonts_noto_NotoSansElbasan_Regular_otf_start:
325 [libc::c_uchar; 8684];
326 pub static _binary_resources_fonts_noto_NotoSansElymaic_Regular_otf_start:
327 [libc::c_uchar; 7620];
328 pub static _binary_resources_fonts_noto_NotoSansGlagolitic_Regular_otf_start:
329 [libc::c_uchar; 17176];
330 pub static _binary_resources_fonts_noto_NotoSansGothic_Regular_otf_start: [libc::c_uchar; 5416];
331 pub static _binary_resources_fonts_noto_NotoSansGunjalaGondi_Regular_otf_start:
332 [libc::c_uchar; 32372];
333 pub static _binary_resources_fonts_noto_NotoSansHanifiRohingya_Regular_otf_start:
334 [libc::c_uchar; 16576];
335 pub static _binary_resources_fonts_noto_NotoSansHanunoo_Regular_otf_start:
336 [libc::c_uchar; 6596];
337 pub static _binary_resources_fonts_noto_NotoSansHatran_Regular_otf_start: [libc::c_uchar; 4324];
338 pub static _binary_resources_fonts_noto_NotoSansImperialAramaic_Regular_otf_start:
339 [libc::c_uchar; 5436];
340 pub static _binary_resources_fonts_noto_NotoSansInscriptionalPahlavi_Regular_otf_start:
341 [libc::c_uchar; 5464];
342 pub static _binary_resources_fonts_noto_NotoSansInscriptionalParthian_Regular_otf_start:
343 [libc::c_uchar; 6788];
344 pub static _binary_resources_fonts_noto_NotoSansJavanese_Regular_otf_start:
345 [libc::c_uchar; 86944];
346 pub static _binary_resources_fonts_noto_NotoSansKaithi_Regular_otf_start:
347 [libc::c_uchar; 39756];
348 pub static _binary_resources_fonts_noto_NotoSansKawi_Regular_otf_start: [libc::c_uchar; 30940];
349 pub static _binary_resources_fonts_noto_NotoSansKayahLi_Regular_otf_start:
350 [libc::c_uchar; 7100];
351 pub static _binary_resources_fonts_noto_NotoSansKharoshthi_Regular_otf_start:
352 [libc::c_uchar; 27708];
353 pub static _binary_resources_fonts_noto_NotoSansKhudawadi_Regular_otf_start:
354 [libc::c_uchar; 14764];
355 pub static _binary_resources_fonts_noto_NotoSansLepcha_Regular_otf_start:
356 [libc::c_uchar; 18832];
357 pub static _binary_resources_fonts_noto_NotoSansLimbu_Regular_otf_start: [libc::c_uchar; 10040];
358 pub static _binary_resources_fonts_noto_NotoSansLinearA_Regular_otf_start:
359 [libc::c_uchar; 33640];
360 pub static _binary_resources_fonts_noto_NotoSansLinearB_Regular_otf_start:
361 [libc::c_uchar; 36892];
362 pub static _binary_resources_fonts_noto_NotoSansLisu_Regular_otf_start: [libc::c_uchar; 5688];
363 pub static _binary_resources_fonts_noto_NotoSansLycian_Regular_otf_start: [libc::c_uchar; 4108];
364 pub static _binary_resources_fonts_noto_NotoSansLydian_Regular_otf_start: [libc::c_uchar; 4088];
365 pub static _binary_resources_fonts_noto_NotoSansMahajani_Regular_otf_start:
366 [libc::c_uchar; 10136];
367 pub static _binary_resources_fonts_noto_NotoSansMandaic_Regular_otf_start:
368 [libc::c_uchar; 13160];
369 pub static _binary_resources_fonts_noto_NotoSansManichaean_Regular_otf_start:
370 [libc::c_uchar; 16496];
371 pub static _binary_resources_fonts_noto_NotoSansMarchen_Regular_otf_start:
372 [libc::c_uchar; 69240];
373 pub static _binary_resources_fonts_noto_NotoSansMasaramGondi_Regular_otf_start:
374 [libc::c_uchar; 23052];
375 pub static _binary_resources_fonts_noto_NotoSansMath_Regular_otf_start: [libc::c_uchar; 258796];
376 pub static _binary_resources_fonts_noto_NotoSansMedefaidrin_Regular_otf_start:
377 [libc::c_uchar; 27060];
378 pub static _binary_resources_fonts_noto_NotoSansMeeteiMayek_Regular_otf_start:
379 [libc::c_uchar; 13056];
380 pub static _binary_resources_fonts_noto_NotoSansMendeKikakui_Regular_otf_start:
381 [libc::c_uchar; 19664];
382 pub static _binary_resources_fonts_noto_NotoSansMeroitic_Regular_otf_start:
383 [libc::c_uchar; 19980];
384 pub static _binary_resources_fonts_noto_NotoSansMiao_Regular_otf_start: [libc::c_uchar; 26460];
385 pub static _binary_resources_fonts_noto_NotoSansModi_Regular_otf_start: [libc::c_uchar; 29412];
386 pub static _binary_resources_fonts_noto_NotoSansMongolian_Regular_otf_start:
387 [libc::c_uchar; 111040];
388 pub static _binary_resources_fonts_noto_NotoSansMro_Regular_otf_start: [libc::c_uchar; 5608];
389 pub static _binary_resources_fonts_noto_NotoSansMultani_Regular_otf_start:
390 [libc::c_uchar; 7852];
391 pub static _binary_resources_fonts_noto_NotoSansNabataean_Regular_otf_start:
392 [libc::c_uchar; 6448];
393 pub static _binary_resources_fonts_noto_NotoSansNagMundari_Regular_otf_start:
394 [libc::c_uchar; 8612];
395 pub static _binary_resources_fonts_noto_NotoSansNandinagari_Regular_otf_start:
396 [libc::c_uchar; 86940];
397 pub static _binary_resources_fonts_noto_NotoSansNewa_Regular_otf_start: [libc::c_uchar; 99568];
398 pub static _binary_resources_fonts_noto_NotoSansNewTaiLue_Regular_otf_start:
399 [libc::c_uchar; 10884];
400 pub static _binary_resources_fonts_noto_NotoSansNKo_Regular_otf_start: [libc::c_uchar; 15164];
401 pub static _binary_resources_fonts_noto_NotoSansNushu_Regular_otf_start: [libc::c_uchar; 72472];
402 pub static _binary_resources_fonts_noto_NotoSansOgham_Regular_otf_start: [libc::c_uchar; 3720];
403 pub static _binary_resources_fonts_noto_NotoSansOlChiki_Regular_otf_start:
404 [libc::c_uchar; 7024];
405 pub static _binary_resources_fonts_noto_NotoSansOldHungarian_Regular_otf_start:
406 [libc::c_uchar; 44628];
407 pub static _binary_resources_fonts_noto_NotoSansOldItalic_Regular_otf_start:
408 [libc::c_uchar; 6360];
409 pub static _binary_resources_fonts_noto_NotoSansOldNorthArabian_Regular_otf_start:
410 [libc::c_uchar; 6132];
411 pub static _binary_resources_fonts_noto_NotoSansOldPermic_Regular_otf_start:
412 [libc::c_uchar; 8512];
413 pub static _binary_resources_fonts_noto_NotoSansOldPersian_Regular_otf_start:
414 [libc::c_uchar; 9856];
415 pub static _binary_resources_fonts_noto_NotoSansOldSogdian_Regular_otf_start:
416 [libc::c_uchar; 12260];
417 pub static _binary_resources_fonts_noto_NotoSansOldSouthArabian_Regular_otf_start:
418 [libc::c_uchar; 4624];
419 pub static _binary_resources_fonts_noto_NotoSansOldTurkic_Regular_otf_start:
420 [libc::c_uchar; 6884];
421 pub static _binary_resources_fonts_noto_NotoSansOsage_Regular_otf_start: [libc::c_uchar; 9292];
422 pub static _binary_resources_fonts_noto_NotoSansOsmanya_Regular_otf_start:
423 [libc::c_uchar; 6784];
424 pub static _binary_resources_fonts_noto_NotoSansPahawhHmong_Regular_otf_start:
425 [libc::c_uchar; 13024];
426 pub static _binary_resources_fonts_noto_NotoSansPalmyrene_Regular_otf_start:
427 [libc::c_uchar; 8480];
428 pub static _binary_resources_fonts_noto_NotoSansPauCinHau_Regular_otf_start:
429 [libc::c_uchar; 8124];
430 pub static _binary_resources_fonts_noto_NotoSansPhagsPa_Regular_otf_start:
431 [libc::c_uchar; 24036];
432 pub static _binary_resources_fonts_noto_NotoSansPhoenician_Regular_otf_start:
433 [libc::c_uchar; 5288];
434 pub static _binary_resources_fonts_noto_NotoSansPsalterPahlavi_Regular_otf_start:
435 [libc::c_uchar; 12748];
436 pub static _binary_resources_fonts_noto_NotoSansRejang_Regular_otf_start: [libc::c_uchar; 6440];
437 pub static _binary_resources_fonts_noto_NotoSansRunic_Regular_otf_start: [libc::c_uchar; 7200];
438 pub static _binary_resources_fonts_noto_NotoSansSamaritan_Regular_otf_start:
439 [libc::c_uchar; 9024];
440 pub static _binary_resources_fonts_noto_NotoSansSaurashtra_Regular_otf_start:
441 [libc::c_uchar; 16020];
442 pub static _binary_resources_fonts_noto_NotoSansSharada_Regular_otf_start:
443 [libc::c_uchar; 32824];
444 pub static _binary_resources_fonts_noto_NotoSansShavian_Regular_otf_start:
445 [libc::c_uchar; 5468];
446 pub static _binary_resources_fonts_noto_NotoSansSiddham_Regular_otf_start:
447 [libc::c_uchar; 91992];
448 pub static _binary_resources_fonts_noto_NotoSansSignWriting_Regular_otf_start:
449 [libc::c_uchar; 2780224];
450 pub static _binary_resources_fonts_noto_NotoSansSogdian_Regular_otf_start:
451 [libc::c_uchar; 48356];
452 pub static _binary_resources_fonts_noto_NotoSansSoraSompeng_Regular_otf_start:
453 [libc::c_uchar; 6332];
454 pub static _binary_resources_fonts_noto_NotoSansSoyombo_Regular_otf_start:
455 [libc::c_uchar; 52036];
456 pub static _binary_resources_fonts_noto_NotoSansSundanese_Regular_otf_start:
457 [libc::c_uchar; 9420];
458 pub static _binary_resources_fonts_noto_NotoSansSylotiNagri_Regular_otf_start:
459 [libc::c_uchar; 12852];
460 pub static _binary_resources_fonts_noto_NotoSansSymbols_Regular_otf_start:
461 [libc::c_uchar; 109696];
462 pub static _binary_resources_fonts_noto_NotoSansSymbols2_Regular_otf_start:
463 [libc::c_uchar; 375388];
464 pub static _binary_resources_fonts_noto_NotoSansSyriac_Regular_otf_start:
465 [libc::c_uchar; 124756];
466 pub static _binary_resources_fonts_noto_NotoSansTagalog_Regular_otf_start:
467 [libc::c_uchar; 5500];
468 pub static _binary_resources_fonts_noto_NotoSansTagbanwa_Regular_otf_start:
469 [libc::c_uchar; 5356];
470 pub static _binary_resources_fonts_noto_NotoSansTaiLe_Regular_otf_start: [libc::c_uchar; 8616];
471 pub static _binary_resources_fonts_noto_NotoSansTaiTham_Regular_otf_start:
472 [libc::c_uchar; 76880];
473 pub static _binary_resources_fonts_noto_NotoSansTaiViet_Regular_otf_start:
474 [libc::c_uchar; 12280];
475 pub static _binary_resources_fonts_noto_NotoSansTakri_Regular_otf_start: [libc::c_uchar; 17864];
476 pub static _binary_resources_fonts_noto_NotoSansTangsa_Regular_otf_start:
477 [libc::c_uchar; 16908];
478 pub static _binary_resources_fonts_noto_NotoSansThaana_Regular_otf_start:
479 [libc::c_uchar; 12392];
480 pub static _binary_resources_fonts_noto_NotoSansTifinagh_Regular_otf_start:
481 [libc::c_uchar; 24776];
482 pub static _binary_resources_fonts_noto_NotoSansTirhuta_Regular_otf_start:
483 [libc::c_uchar; 52432];
484 pub static _binary_resources_fonts_noto_NotoSansUgaritic_Regular_otf_start:
485 [libc::c_uchar; 5048];
486 pub static _binary_resources_fonts_noto_NotoSansVai_Regular_otf_start: [libc::c_uchar; 24088];
487 pub static _binary_resources_fonts_noto_NotoSansWancho_Regular_otf_start:
488 [libc::c_uchar; 15140];
489 pub static _binary_resources_fonts_noto_NotoSansWarangCiti_Regular_otf_start:
490 [libc::c_uchar; 23484];
491 pub static _binary_resources_fonts_noto_NotoSansYi_Regular_otf_start: [libc::c_uchar; 92164];
492 pub static _binary_resources_fonts_noto_NotoSansZanabazarSquare_Regular_otf_start:
493 [libc::c_uchar; 13804];
494 pub static _binary_resources_fonts_noto_NotoSerif_Regular_otf_start: [libc::c_uchar; 289412];
495 pub static _binary_resources_fonts_noto_NotoSerifAhom_Regular_otf_start: [libc::c_uchar; 14516];
496 pub static _binary_resources_fonts_noto_NotoSerifArmenian_Regular_otf_start:
497 [libc::c_uchar; 14160];
498 pub static _binary_resources_fonts_noto_NotoSerifBalinese_Regular_otf_start:
499 [libc::c_uchar; 32348];
500 pub static _binary_resources_fonts_noto_NotoSerifBengali_Regular_otf_start:
501 [libc::c_uchar; 101332];
502 pub static _binary_resources_fonts_noto_NotoSerifDevanagari_Regular_otf_start:
503 [libc::c_uchar; 169744];
504 pub static _binary_resources_fonts_noto_NotoSerifDivesAkuru_Regular_otf_start:
505 [libc::c_uchar; 27972];
506 pub static _binary_resources_fonts_noto_NotoSerifDogra_Regular_otf_start:
507 [libc::c_uchar; 19944];
508 pub static _binary_resources_fonts_noto_NotoSerifEthiopic_Regular_otf_start:
509 [libc::c_uchar; 113328];
510 pub static _binary_resources_fonts_noto_NotoSerifGeorgian_Regular_otf_start:
511 [libc::c_uchar; 31988];
512 pub static _binary_resources_fonts_noto_NotoSerifGrantha_Regular_otf_start:
513 [libc::c_uchar; 368396];
514 pub static _binary_resources_fonts_noto_NotoSerifGujarati_Regular_otf_start:
515 [libc::c_uchar; 64848];
516 pub static _binary_resources_fonts_noto_NotoSerifGurmukhi_Regular_otf_start:
517 [libc::c_uchar; 26992];
518 pub static _binary_resources_fonts_noto_NotoSerifHebrew_Regular_otf_start:
519 [libc::c_uchar; 15320];
520 pub static _binary_resources_fonts_noto_NotoSerifKannada_Regular_otf_start:
521 [libc::c_uchar; 89032];
522 pub static _binary_resources_fonts_noto_NotoSerifKhitanSmallScript_Regular_otf_start:
523 [libc::c_uchar; 508920];
524 pub static _binary_resources_fonts_noto_NotoSerifKhmer_Regular_otf_start:
525 [libc::c_uchar; 40436];
526 pub static _binary_resources_fonts_noto_NotoSerifKhojki_Regular_otf_start:
527 [libc::c_uchar; 60112];
528 pub static _binary_resources_fonts_noto_NotoSerifLao_Regular_otf_start: [libc::c_uchar; 16196];
529 pub static _binary_resources_fonts_noto_NotoSerifMakasar_Regular_otf_start:
530 [libc::c_uchar; 5864];
531 pub static _binary_resources_fonts_noto_NotoSerifMalayalam_Regular_otf_start:
532 [libc::c_uchar; 45668];
533 pub static _binary_resources_fonts_noto_NotoSerifMyanmar_Regular_otf_start:
534 [libc::c_uchar; 127564];
535 pub static _binary_resources_fonts_noto_NotoSerifNyiakengPuachueHmong_Regular_otf_start:
536 [libc::c_uchar; 12208];
537 pub static _binary_resources_fonts_noto_NotoSerifOldUyghur_Regular_otf_start:
538 [libc::c_uchar; 15620];
539 pub static _binary_resources_fonts_noto_NotoSerifOriya_Regular_otf_start:
540 [libc::c_uchar; 105824];
541 pub static _binary_resources_fonts_noto_NotoSerifSinhala_Regular_otf_start:
542 [libc::c_uchar; 74924];
543 pub static _binary_resources_fonts_noto_NotoSerifTamil_Regular_otf_start:
544 [libc::c_uchar; 33752];
545 pub static _binary_resources_fonts_noto_NotoSerifTelugu_Regular_otf_start:
546 [libc::c_uchar; 82032];
547 pub static _binary_resources_fonts_noto_NotoSerifThai_Regular_otf_start: [libc::c_uchar; 17556];
548 pub static _binary_resources_fonts_noto_NotoSerifTibetan_Regular_otf_start:
549 [libc::c_uchar; 334156];
550 pub static _binary_resources_fonts_noto_NotoSerifToto_Regular_otf_start: [libc::c_uchar; 5732];
551 pub static _binary_resources_fonts_noto_NotoSerifVithkuqi_Regular_otf_start:
552 [libc::c_uchar; 42508];
553 pub static _binary_resources_fonts_noto_NotoSerifYezidi_Regular_otf_start:
554 [libc::c_uchar; 8664];
555}
556
557pub const SLIDER_VALUE: Style = MD_SIZE;
558
559pub struct FontFamily {
560 pub regular: Font,
561 pub italic: Font,
562 pub bold: Font,
563 pub bold_italic: Font,
564}
565
566pub fn family_names<P: AsRef<Path>>(search_path: P) -> Result<BTreeSet<String>, Error> {
567 if !search_path.as_ref().exists() {
568 return Err(format_err!("the search path doesn't exist"));
569 }
570
571 let opener = FontOpener::new()?;
572 let glob = Glob::new("**/*.[ot]tf")?.compile_matcher();
573
574 let mut families = BTreeSet::new();
575
576 for entry in WalkDir::new(search_path.as_ref())
577 .min_depth(1)
578 .into_iter()
579 .filter_entry(|e| !e.is_hidden())
580 {
581 if entry.is_err() {
582 continue;
583 }
584 let entry = entry.unwrap();
585 let path = entry.path();
586 if !glob.is_match(path) {
587 continue;
588 }
589 if let Ok(font) = opener
590 .open(path)
591 .map_err(|e| error!("Can't open '{}': {:#}.", path.display(), e))
592 {
593 if let Some(family_name) = font.family_name() {
594 families.insert(family_name.to_string());
595 } else {
596 warn!("Can't get the family name of '{}'.", path.display());
597 }
598 }
599 }
600
601 Ok(families)
602}
603
604impl FontFamily {
605 pub fn from_name<P: AsRef<Path>>(
606 family_name: &str,
607 search_path: P,
608 ) -> Result<FontFamily, Error> {
609 let opener = FontOpener::new()?;
610 let glob = Glob::new("**/*.[ot]tf")?.compile_matcher();
611 let mut styles = FxHashMap::default();
612
613 for entry in WalkDir::new(search_path.as_ref())
614 .min_depth(1)
615 .into_iter()
616 .filter_entry(|e| !e.is_hidden())
617 {
618 if entry.is_err() {
619 continue;
620 }
621 let entry = entry.unwrap();
622 let path = entry.path();
623 if !glob.is_match(path) {
624 continue;
625 }
626 if let Ok(font) = opener
627 .open(path)
628 .map_err(|e| error!("Can't open '{}': {:#}.", path.display(), e))
629 {
630 if font.family_name() == Some(family_name) {
631 styles.insert(
632 font.style_name()
633 .map(String::from)
634 .unwrap_or_else(|| "Regular".to_string()),
635 path.to_path_buf(),
636 );
637 }
638 }
639 }
640
641 let regular_path = if styles.len() == 1 {
642 styles.values().next().unwrap()
643 } else {
644 styles
645 .get("Regular")
646 .or_else(|| styles.get("Roman"))
647 .or_else(|| styles.get("Book"))
648 .ok_or_else(|| format_err!("can't find regular style"))?
649 };
650 let italic_path = styles
651 .get("Italic")
652 .or_else(|| styles.get("Book Italic"))
653 .or_else(|| styles.get("Regular Italic"))
654 .unwrap_or(regular_path);
655 let bold_path = styles
656 .get("Bold")
657 .or_else(|| styles.get("Semibold"))
658 .or_else(|| styles.get("SemiBold"))
659 .or_else(|| styles.get("Medium"))
660 .unwrap_or(regular_path);
661 let bold_italic_path = styles
662 .get("Bold Italic")
663 .or_else(|| styles.get("SemiBold Italic"))
664 .or_else(|| styles.get("Medium Italic"))
665 .unwrap_or(italic_path);
666 Ok(FontFamily {
667 regular: opener.open(regular_path)?,
668 italic: opener.open(italic_path)?,
669 bold: opener.open(bold_path)?,
670 bold_italic: opener.open(bold_italic_path)?,
671 })
672 }
673}
674
675pub struct Fonts {
676 pub sans_serif: FontFamily,
677 pub serif: FontFamily,
678 pub monospace: FontFamily,
679 pub keyboard: Font,
680 pub display: Font,
681}
682
683impl Fonts {
684 fn _load(root_dir: Option<PathBuf>) -> Result<Fonts, Error> {
685 let search_path = if let Some(root_dir) = root_dir {
686 root_dir.join("fonts")
687 } else {
688 PathBuf::from("fonts")
689 };
690
691 let opener = FontOpener::new()?;
692 let mut fonts = Fonts {
693 sans_serif: FontFamily {
694 regular: opener.open(search_path.join("NotoSans-Regular.ttf").as_path())?,
695 italic: opener.open(search_path.join("NotoSans-Italic.ttf").as_path())?,
696 bold: opener.open(search_path.join("NotoSans-Bold.ttf").as_path())?,
697 bold_italic: opener.open(search_path.join("NotoSans-BoldItalic.ttf").as_path())?,
698 },
699 serif: FontFamily {
700 regular: opener.open(search_path.join("NotoSerif-Regular.ttf").as_path())?,
701 italic: opener.open(search_path.join("NotoSerif-Italic.ttf").as_path())?,
702 bold: opener.open(search_path.join("NotoSerif-Bold.ttf").as_path())?,
703 bold_italic: opener.open(search_path.join("NotoSerif-BoldItalic.ttf").as_path())?,
704 },
705 monospace: FontFamily {
706 regular: opener.open(search_path.join("SourceCodeVariable-Roman.otf").as_path())?,
707 italic: opener.open(search_path.join("SourceCodeVariable-Italic.otf").as_path())?,
708 bold: opener.open(search_path.join("SourceCodeVariable-Roman.otf").as_path())?,
709 bold_italic: opener
710 .open(search_path.join("SourceCodeVariable-Italic.otf").as_path())?,
711 },
712 keyboard: opener.open(search_path.join("VarelaRound-Regular.ttf").as_path())?,
713 display: opener.open(search_path.join("Cormorant-Regular.ttf").as_path())?,
714 };
715 fonts.monospace.bold.set_variations(&["wght=600"]);
716 fonts.monospace.bold_italic.set_variations(&["wght=600"]);
717 Ok(fonts)
718 }
719
720 pub fn load() -> Result<Fonts, Error> {
721 Fonts::_load(None)
722 }
723
724 pub fn load_from(root_dir: PathBuf) -> Result<Fonts, Error> {
725 Fonts::_load(Some(root_dir))
726 }
727}
728
729bitflags! {
730 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
731 pub struct Variant: u8 {
732 const REGULAR = 0;
733 const ITALIC = 1;
734 const BOLD = 2;
735 }
736}
737
738#[derive(Debug, Copy, Clone, Eq, PartialEq)]
739pub enum Family {
740 SansSerif,
741 Serif,
742 Monospace,
743 Keyboard,
744 Display,
745}
746
747pub struct Style {
748 family: Family,
749 variant: Variant,
750 pub size: u32,
751}
752
753pub fn font_from_variant(family: &mut FontFamily, variant: Variant) -> &mut Font {
754 if variant.contains(Variant::ITALIC | Variant::BOLD) {
755 &mut family.bold_italic
756 } else if variant.contains(Variant::ITALIC) {
757 &mut family.italic
758 } else if variant.contains(Variant::BOLD) {
759 &mut family.bold
760 } else {
761 &mut family.regular
762 }
763}
764
765pub fn font_from_style<'a>(fonts: &'a mut Fonts, style: &Style, dpi: u16) -> &'a mut Font {
766 let font = match style.family {
767 Family::SansSerif => {
768 let family = &mut fonts.sans_serif;
769 font_from_variant(family, style.variant)
770 }
771 Family::Serif => {
772 let family = &mut fonts.serif;
773 font_from_variant(family, style.variant)
774 }
775 Family::Monospace => {
776 let family = &mut fonts.monospace;
777 font_from_variant(family, style.variant)
778 }
779 Family::Keyboard => &mut fonts.keyboard,
780 Family::Display => &mut fonts.display,
781 };
782 font.set_size(style.size, dpi);
783 font
784}
785
786#[inline]
787unsafe fn font_data_from_script(script: HbScript) -> &'static [libc::c_uchar] {
788 #[cfg(any(not(target_os = "linux"), target_arch = "arm"))]
790 match script {
791 HB_SCRIPT_HANGUL | HB_SCRIPT_HIRAGANA | HB_SCRIPT_KATAKANA | HB_SCRIPT_BOPOMOFO
792 | HB_SCRIPT_HAN => &_binary_DroidSansFallback_ttf,
793
794 HB_SCRIPT_ARABIC => &_binary_NotoNaskhArabic_Regular_otf,
795 HB_SCRIPT_SYRIAC => &_binary_NotoSansSyriac_Regular_otf,
796 HB_SCRIPT_MEROITIC_CURSIVE | HB_SCRIPT_MEROITIC_HIEROGLYPHS => {
797 &_binary_NotoSansMeroitic_Regular_otf
798 }
799
800 HB_SCRIPT_ADLAM => &_binary_NotoSansAdlam_Regular_otf,
801 HB_SCRIPT_AHOM => &_binary_NotoSerifAhom_Regular_otf,
802 HB_SCRIPT_ANATOLIAN_HIEROGLYPHS => &_binary_NotoSansAnatolianHieroglyphs_Regular_otf,
803 HB_SCRIPT_ARMENIAN => &_binary_NotoSerifArmenian_Regular_otf,
804 HB_SCRIPT_AVESTAN => &_binary_NotoSansAvestan_Regular_otf,
805 HB_SCRIPT_BALINESE => &_binary_NotoSerifBalinese_Regular_otf,
806 HB_SCRIPT_BAMUM => &_binary_NotoSansBamum_Regular_otf,
807 HB_SCRIPT_BASSA_VAH => &_binary_NotoSansBassaVah_Regular_otf,
808 HB_SCRIPT_BATAK => &_binary_NotoSansBatak_Regular_otf,
809 HB_SCRIPT_BENGALI => &_binary_NotoSerifBengali_Regular_otf,
810 HB_SCRIPT_BHAIKSUKI => &_binary_NotoSansBhaiksuki_Regular_otf,
811 HB_SCRIPT_BRAHMI => &_binary_NotoSansBrahmi_Regular_otf,
812 HB_SCRIPT_BUGINESE => &_binary_NotoSansBuginese_Regular_otf,
813 HB_SCRIPT_BUHID => &_binary_NotoSansBuhid_Regular_otf,
814 HB_SCRIPT_CANADIAN_SYLLABICS => &_binary_NotoSansCanadianAboriginal_Regular_otf,
815 HB_SCRIPT_CARIAN => &_binary_NotoSansCarian_Regular_otf,
816 HB_SCRIPT_CAUCASIAN_ALBANIAN => &_binary_NotoSansCaucasianAlbanian_Regular_otf,
817 HB_SCRIPT_CHAKMA => &_binary_NotoSansChakma_Regular_otf,
818 HB_SCRIPT_CHAM => &_binary_NotoSansCham_Regular_otf,
819 HB_SCRIPT_CHEROKEE => &_binary_NotoSansCherokee_Regular_otf,
820 HB_SCRIPT_CHORASMIAN => &_binary_NotoSansChorasmian_Regular_otf,
821 HB_SCRIPT_COPTIC => &_binary_NotoSansCoptic_Regular_otf,
822 HB_SCRIPT_CUNEIFORM => &_binary_NotoSansCuneiform_Regular_otf,
823 HB_SCRIPT_CYPRIOT => &_binary_NotoSansCypriot_Regular_otf,
824 HB_SCRIPT_CYPRO_MINOAN => &_binary_NotoSansCyproMinoan_Regular_otf,
825 HB_SCRIPT_DESERET => &_binary_NotoSansDeseret_Regular_otf,
826 HB_SCRIPT_DEVANAGARI => &_binary_NotoSerifDevanagari_Regular_otf,
827 HB_SCRIPT_DIVES_AKURU => &_binary_NotoSerifDivesAkuru_Regular_otf,
828 HB_SCRIPT_DOGRA => &_binary_NotoSerifDogra_Regular_otf,
829 HB_SCRIPT_DUPLOYAN => &_binary_NotoSansDuployan_Regular_otf,
830 HB_SCRIPT_EGYPTIAN_HIEROGLYPHS => &_binary_NotoSansEgyptianHieroglyphs_Regular_otf,
831 HB_SCRIPT_ELBASAN => &_binary_NotoSansElbasan_Regular_otf,
832 HB_SCRIPT_ELYMAIC => &_binary_NotoSansElymaic_Regular_otf,
833 HB_SCRIPT_ETHIOPIC => &_binary_NotoSerifEthiopic_Regular_otf,
834 HB_SCRIPT_GEORGIAN => &_binary_NotoSerifGeorgian_Regular_otf,
835 HB_SCRIPT_GLAGOLITIC => &_binary_NotoSansGlagolitic_Regular_otf,
836 HB_SCRIPT_GOTHIC => &_binary_NotoSansGothic_Regular_otf,
837 HB_SCRIPT_GRANTHA => &_binary_NotoSerifGrantha_Regular_otf,
838 HB_SCRIPT_GUJARATI => &_binary_NotoSerifGujarati_Regular_otf,
839 HB_SCRIPT_GUNJALA_GONDI => &_binary_NotoSansGunjalaGondi_Regular_otf,
840 HB_SCRIPT_GURMUKHI => &_binary_NotoSerifGurmukhi_Regular_otf,
841 HB_SCRIPT_HANIFI_ROHINGYA => &_binary_NotoSansHanifiRohingya_Regular_otf,
842 HB_SCRIPT_HANUNOO => &_binary_NotoSansHanunoo_Regular_otf,
843 HB_SCRIPT_HATRAN => &_binary_NotoSansHatran_Regular_otf,
844 HB_SCRIPT_HEBREW => &_binary_NotoSerifHebrew_Regular_otf,
845 HB_SCRIPT_IMPERIAL_ARAMAIC => &_binary_NotoSansImperialAramaic_Regular_otf,
846 HB_SCRIPT_INSCRIPTIONAL_PAHLAVI => &_binary_NotoSansInscriptionalPahlavi_Regular_otf,
847 HB_SCRIPT_INSCRIPTIONAL_PARTHIAN => &_binary_NotoSansInscriptionalParthian_Regular_otf,
848 HB_SCRIPT_JAVANESE => &_binary_NotoSansJavanese_Regular_otf,
849 HB_SCRIPT_KAITHI => &_binary_NotoSansKaithi_Regular_otf,
850 HB_SCRIPT_KANNADA => &_binary_NotoSerifKannada_Regular_otf,
851 HB_SCRIPT_KAWI => &_binary_NotoSansKawi_Regular_otf,
852 HB_SCRIPT_KAYAH_LI => &_binary_NotoSansKayahLi_Regular_otf,
853 HB_SCRIPT_KHAROSHTHI => &_binary_NotoSansKharoshthi_Regular_otf,
854 HB_SCRIPT_KHITAN_SMALL_SCRIPT => &_binary_NotoSerifKhitanSmallScript_Regular_otf,
855 HB_SCRIPT_KHMER => &_binary_NotoSerifKhmer_Regular_otf,
856 HB_SCRIPT_KHOJKI => &_binary_NotoSerifKhojki_Regular_otf,
857 HB_SCRIPT_KHUDAWADI => &_binary_NotoSansKhudawadi_Regular_otf,
858 HB_SCRIPT_LAO => &_binary_NotoSerifLao_Regular_otf,
859 HB_SCRIPT_LEPCHA => &_binary_NotoSansLepcha_Regular_otf,
860 HB_SCRIPT_LIMBU => &_binary_NotoSansLimbu_Regular_otf,
861 HB_SCRIPT_LINEAR_A => &_binary_NotoSansLinearA_Regular_otf,
862 HB_SCRIPT_LINEAR_B => &_binary_NotoSansLinearB_Regular_otf,
863 HB_SCRIPT_LISU => &_binary_NotoSansLisu_Regular_otf,
864 HB_SCRIPT_LYCIAN => &_binary_NotoSansLycian_Regular_otf,
865 HB_SCRIPT_LYDIAN => &_binary_NotoSansLydian_Regular_otf,
866 HB_SCRIPT_MAHAJANI => &_binary_NotoSansMahajani_Regular_otf,
867 HB_SCRIPT_MAKASAR => &_binary_NotoSerifMakasar_Regular_otf,
868 HB_SCRIPT_MALAYALAM => &_binary_NotoSerifMalayalam_Regular_otf,
869 HB_SCRIPT_MANDAIC => &_binary_NotoSansMandaic_Regular_otf,
870 HB_SCRIPT_MANICHAEAN => &_binary_NotoSansManichaean_Regular_otf,
871 HB_SCRIPT_MARCHEN => &_binary_NotoSansMarchen_Regular_otf,
872 HB_SCRIPT_MASARAM_GONDI => &_binary_NotoSansMasaramGondi_Regular_otf,
873 HB_SCRIPT_MEDEFAIDRIN => &_binary_NotoSansMedefaidrin_Regular_otf,
874 HB_SCRIPT_MEETEI_MAYEK => &_binary_NotoSansMeeteiMayek_Regular_otf,
875 HB_SCRIPT_MENDE_KIKAKUI => &_binary_NotoSansMendeKikakui_Regular_otf,
876 HB_SCRIPT_MIAO => &_binary_NotoSansMiao_Regular_otf,
877 HB_SCRIPT_MODI => &_binary_NotoSansModi_Regular_otf,
878 HB_SCRIPT_MONGOLIAN => &_binary_NotoSansMongolian_Regular_otf,
879 HB_SCRIPT_MRO => &_binary_NotoSansMro_Regular_otf,
880 HB_SCRIPT_MULTANI => &_binary_NotoSansMultani_Regular_otf,
881 HB_SCRIPT_MYANMAR => &_binary_NotoSerifMyanmar_Regular_otf,
882 HB_SCRIPT_NABATAEAN => &_binary_NotoSansNabataean_Regular_otf,
883 HB_SCRIPT_NAG_MUNDARI => &_binary_NotoSansNagMundari_Regular_otf,
884 HB_SCRIPT_NANDINAGARI => &_binary_NotoSansNandinagari_Regular_otf,
885 HB_SCRIPT_NEWA => &_binary_NotoSansNewa_Regular_otf,
886 HB_SCRIPT_NEW_TAI_LUE => &_binary_NotoSansNewTaiLue_Regular_otf,
887 HB_SCRIPT_NKO => &_binary_NotoSansNKo_Regular_otf,
888 HB_SCRIPT_NUSHU => &_binary_NotoSansNushu_Regular_otf,
889 HB_SCRIPT_NYIAKENG_PUACHUE_HMONG => &_binary_NotoSerifNyiakengPuachueHmong_Regular_otf,
890 HB_SCRIPT_OGHAM => &_binary_NotoSansOgham_Regular_otf,
891 HB_SCRIPT_OLD_HUNGARIAN => &_binary_NotoSansOldHungarian_Regular_otf,
892 HB_SCRIPT_OLD_ITALIC => &_binary_NotoSansOldItalic_Regular_otf,
893 HB_SCRIPT_OLD_NORTH_ARABIAN => &_binary_NotoSansOldNorthArabian_Regular_otf,
894 HB_SCRIPT_OLD_PERMIC => &_binary_NotoSansOldPermic_Regular_otf,
895 HB_SCRIPT_OLD_PERSIAN => &_binary_NotoSansOldPersian_Regular_otf,
896 HB_SCRIPT_OLD_SOGDIAN => &_binary_NotoSansOldSogdian_Regular_otf,
897 HB_SCRIPT_OLD_SOUTH_ARABIAN => &_binary_NotoSansOldSouthArabian_Regular_otf,
898 HB_SCRIPT_OLD_TURKIC => &_binary_NotoSansOldTurkic_Regular_otf,
899 HB_SCRIPT_OLD_UYGHUR => &_binary_NotoSerifOldUyghur_Regular_otf,
900 HB_SCRIPT_OL_CHIKI => &_binary_NotoSansOlChiki_Regular_otf,
901 HB_SCRIPT_ORIYA => &_binary_NotoSerifOriya_Regular_otf,
902 HB_SCRIPT_OSAGE => &_binary_NotoSansOsage_Regular_otf,
903 HB_SCRIPT_OSMANYA => &_binary_NotoSansOsmanya_Regular_otf,
904 HB_SCRIPT_PAHAWH_HMONG => &_binary_NotoSansPahawhHmong_Regular_otf,
905 HB_SCRIPT_PALMYRENE => &_binary_NotoSansPalmyrene_Regular_otf,
906 HB_SCRIPT_PAU_CIN_HAU => &_binary_NotoSansPauCinHau_Regular_otf,
907 HB_SCRIPT_PHAGS_PA => &_binary_NotoSansPhagsPa_Regular_otf,
908 HB_SCRIPT_PHOENICIAN => &_binary_NotoSansPhoenician_Regular_otf,
909 HB_SCRIPT_PSALTER_PAHLAVI => &_binary_NotoSansPsalterPahlavi_Regular_otf,
910 HB_SCRIPT_REJANG => &_binary_NotoSansRejang_Regular_otf,
911 HB_SCRIPT_RUNIC => &_binary_NotoSansRunic_Regular_otf,
912 HB_SCRIPT_SAMARITAN => &_binary_NotoSansSamaritan_Regular_otf,
913 HB_SCRIPT_SAURASHTRA => &_binary_NotoSansSaurashtra_Regular_otf,
914 HB_SCRIPT_SHARADA => &_binary_NotoSansSharada_Regular_otf,
915 HB_SCRIPT_SHAVIAN => &_binary_NotoSansShavian_Regular_otf,
916 HB_SCRIPT_SIDDHAM => &_binary_NotoSansSiddham_Regular_otf,
917 HB_SCRIPT_SIGNWRITING => &_binary_NotoSansSignWriting_Regular_otf,
918 HB_SCRIPT_SINHALA => &_binary_NotoSerifSinhala_Regular_otf,
919 HB_SCRIPT_SOGDIAN => &_binary_NotoSansSogdian_Regular_otf,
920 HB_SCRIPT_SORA_SOMPENG => &_binary_NotoSansSoraSompeng_Regular_otf,
921 HB_SCRIPT_SOYOMBO => &_binary_NotoSansSoyombo_Regular_otf,
922 HB_SCRIPT_SUNDANESE => &_binary_NotoSansSundanese_Regular_otf,
923 HB_SCRIPT_SYLOTI_NAGRI => &_binary_NotoSansSylotiNagri_Regular_otf,
924 HB_SCRIPT_TAGALOG => &_binary_NotoSansTagalog_Regular_otf,
925 HB_SCRIPT_TAGBANWA => &_binary_NotoSansTagbanwa_Regular_otf,
926 HB_SCRIPT_TAI_LE => &_binary_NotoSansTaiLe_Regular_otf,
927 HB_SCRIPT_TAI_THAM => &_binary_NotoSansTaiTham_Regular_otf,
928 HB_SCRIPT_TAI_VIET => &_binary_NotoSansTaiViet_Regular_otf,
929 HB_SCRIPT_TAKRI => &_binary_NotoSansTakri_Regular_otf,
930 HB_SCRIPT_TAMIL => &_binary_NotoSerifTamil_Regular_otf,
931 HB_SCRIPT_TANGSA => &_binary_NotoSansTangsa_Regular_otf,
932 HB_SCRIPT_TELUGU => &_binary_NotoSerifTelugu_Regular_otf,
933 HB_SCRIPT_THAANA => &_binary_NotoSansThaana_Regular_otf,
934 HB_SCRIPT_THAI => &_binary_NotoSerifThai_Regular_otf,
935 HB_SCRIPT_TIBETAN => &_binary_NotoSerifTibetan_Regular_otf,
936 HB_SCRIPT_TIFINAGH => &_binary_NotoSansTifinagh_Regular_otf,
937 HB_SCRIPT_TIRHUTA => &_binary_NotoSansTirhuta_Regular_otf,
938 HB_SCRIPT_TOTO => &_binary_NotoSerifToto_Regular_otf,
939 HB_SCRIPT_UGARITIC => &_binary_NotoSansUgaritic_Regular_otf,
940 HB_SCRIPT_VAI => &_binary_NotoSansVai_Regular_otf,
941 HB_SCRIPT_VITHKUQI => &_binary_NotoSerifVithkuqi_Regular_otf,
942 HB_SCRIPT_WANCHO => &_binary_NotoSansWancho_Regular_otf,
943 HB_SCRIPT_WARANG_CITI => &_binary_NotoSansWarangCiti_Regular_otf,
944 HB_SCRIPT_YEZIDI => &_binary_NotoSerifYezidi_Regular_otf,
945 HB_SCRIPT_YI => &_binary_NotoSansYi_Regular_otf,
946 HB_SCRIPT_ZANABAZAR_SQUARE => &_binary_NotoSansZanabazarSquare_Regular_otf,
947
948 HB_SYMBOL_MATHS => &_binary_NotoSansMath_Regular_otf,
949 HB_SYMBOL_MUSIC => &_binary_NotoMusic_Regular_otf,
950 HB_SYMBOL_MISC_ONE => &_binary_NotoSansSymbols_Regular_otf,
951 HB_SCRIPT_BRAILLE | HB_SYMBOL_MISC_TWO => &_binary_NotoSansSymbols2_Regular_otf,
952 HB_SYMBOL_EMOJI => &_binary_NotoEmoji_Regular_ttf,
953
954 _ => &_binary_DroidSansFallback_ttf,
955 }
956
957 #[cfg(all(target_os = "linux", not(target_arch = "arm")))]
958 match script {
959 HB_SCRIPT_HANGUL | HB_SCRIPT_HIRAGANA | HB_SCRIPT_KATAKANA | HB_SCRIPT_BOPOMOFO
960 | HB_SCRIPT_HAN => &_binary_resources_fonts_droid_DroidSansFallback_ttf_start,
961
962 HB_SCRIPT_ARABIC => &_binary_resources_fonts_noto_NotoNaskhArabic_Regular_otf_start,
963 HB_SCRIPT_SYRIAC => &_binary_resources_fonts_noto_NotoSansSyriac_Regular_otf_start,
964 HB_SCRIPT_MEROITIC_CURSIVE | HB_SCRIPT_MEROITIC_HIEROGLYPHS => {
965 &_binary_resources_fonts_noto_NotoSansMeroitic_Regular_otf_start
966 }
967
968 HB_SCRIPT_ADLAM => &_binary_resources_fonts_noto_NotoSansAdlam_Regular_otf_start,
969 HB_SCRIPT_AHOM => &_binary_resources_fonts_noto_NotoSerifAhom_Regular_otf_start,
970 HB_SCRIPT_ANATOLIAN_HIEROGLYPHS => {
971 &_binary_resources_fonts_noto_NotoSansAnatolianHieroglyphs_Regular_otf_start
972 }
973 HB_SCRIPT_ARMENIAN => &_binary_resources_fonts_noto_NotoSerifArmenian_Regular_otf_start,
974 HB_SCRIPT_AVESTAN => &_binary_resources_fonts_noto_NotoSansAvestan_Regular_otf_start,
975 HB_SCRIPT_BALINESE => &_binary_resources_fonts_noto_NotoSerifBalinese_Regular_otf_start,
976 HB_SCRIPT_BAMUM => &_binary_resources_fonts_noto_NotoSansBamum_Regular_otf_start,
977 HB_SCRIPT_BASSA_VAH => &_binary_resources_fonts_noto_NotoSansBassaVah_Regular_otf_start,
978 HB_SCRIPT_BATAK => &_binary_resources_fonts_noto_NotoSansBatak_Regular_otf_start,
979 HB_SCRIPT_BENGALI => &_binary_resources_fonts_noto_NotoSerifBengali_Regular_otf_start,
980 HB_SCRIPT_BHAIKSUKI => &_binary_resources_fonts_noto_NotoSansBhaiksuki_Regular_otf_start,
981 HB_SCRIPT_BRAHMI => &_binary_resources_fonts_noto_NotoSansBrahmi_Regular_otf_start,
982 HB_SCRIPT_BUGINESE => &_binary_resources_fonts_noto_NotoSansBuginese_Regular_otf_start,
983 HB_SCRIPT_BUHID => &_binary_resources_fonts_noto_NotoSansBuhid_Regular_otf_start,
984 HB_SCRIPT_CANADIAN_SYLLABICS => {
985 &_binary_resources_fonts_noto_NotoSansCanadianAboriginal_Regular_otf_start
986 }
987 HB_SCRIPT_CARIAN => &_binary_resources_fonts_noto_NotoSansCarian_Regular_otf_start,
988 HB_SCRIPT_CAUCASIAN_ALBANIAN => {
989 &_binary_resources_fonts_noto_NotoSansCaucasianAlbanian_Regular_otf_start
990 }
991 HB_SCRIPT_CHAKMA => &_binary_resources_fonts_noto_NotoSansChakma_Regular_otf_start,
992 HB_SCRIPT_CHAM => &_binary_resources_fonts_noto_NotoSansCham_Regular_otf_start,
993 HB_SCRIPT_CHEROKEE => &_binary_resources_fonts_noto_NotoSansCherokee_Regular_otf_start,
994 HB_SCRIPT_CHORASMIAN => &_binary_resources_fonts_noto_NotoSansChorasmian_Regular_otf_start,
995 HB_SCRIPT_COPTIC => &_binary_resources_fonts_noto_NotoSansCoptic_Regular_otf_start,
996 HB_SCRIPT_CUNEIFORM => &_binary_resources_fonts_noto_NotoSansCuneiform_Regular_otf_start,
997 HB_SCRIPT_CYPRIOT => &_binary_resources_fonts_noto_NotoSansCypriot_Regular_otf_start,
998 HB_SCRIPT_CYPRO_MINOAN => {
999 &_binary_resources_fonts_noto_NotoSansCyproMinoan_Regular_otf_start
1000 }
1001 HB_SCRIPT_DESERET => &_binary_resources_fonts_noto_NotoSansDeseret_Regular_otf_start,
1002 HB_SCRIPT_DEVANAGARI => &_binary_resources_fonts_noto_NotoSerifDevanagari_Regular_otf_start,
1003 HB_SCRIPT_DIVES_AKURU => {
1004 &_binary_resources_fonts_noto_NotoSerifDivesAkuru_Regular_otf_start
1005 }
1006 HB_SCRIPT_DOGRA => &_binary_resources_fonts_noto_NotoSerifDogra_Regular_otf_start,
1007 HB_SCRIPT_DUPLOYAN => &_binary_resources_fonts_noto_NotoSansDuployan_Regular_otf_start,
1008 HB_SCRIPT_EGYPTIAN_HIEROGLYPHS => {
1009 &_binary_resources_fonts_noto_NotoSansEgyptianHieroglyphs_Regular_otf_start
1010 }
1011 HB_SCRIPT_ELBASAN => &_binary_resources_fonts_noto_NotoSansElbasan_Regular_otf_start,
1012 HB_SCRIPT_ELYMAIC => &_binary_resources_fonts_noto_NotoSansElymaic_Regular_otf_start,
1013 HB_SCRIPT_ETHIOPIC => &_binary_resources_fonts_noto_NotoSerifEthiopic_Regular_otf_start,
1014 HB_SCRIPT_GEORGIAN => &_binary_resources_fonts_noto_NotoSerifGeorgian_Regular_otf_start,
1015 HB_SCRIPT_GLAGOLITIC => &_binary_resources_fonts_noto_NotoSansGlagolitic_Regular_otf_start,
1016 HB_SCRIPT_GOTHIC => &_binary_resources_fonts_noto_NotoSansGothic_Regular_otf_start,
1017 HB_SCRIPT_GRANTHA => &_binary_resources_fonts_noto_NotoSerifGrantha_Regular_otf_start,
1018 HB_SCRIPT_GUJARATI => &_binary_resources_fonts_noto_NotoSerifGujarati_Regular_otf_start,
1019 HB_SCRIPT_GUNJALA_GONDI => {
1020 &_binary_resources_fonts_noto_NotoSansGunjalaGondi_Regular_otf_start
1021 }
1022 HB_SCRIPT_GURMUKHI => &_binary_resources_fonts_noto_NotoSerifGurmukhi_Regular_otf_start,
1023 HB_SCRIPT_HANIFI_ROHINGYA => {
1024 &_binary_resources_fonts_noto_NotoSansHanifiRohingya_Regular_otf_start
1025 }
1026 HB_SCRIPT_HANUNOO => &_binary_resources_fonts_noto_NotoSansHanunoo_Regular_otf_start,
1027 HB_SCRIPT_HATRAN => &_binary_resources_fonts_noto_NotoSansHatran_Regular_otf_start,
1028 HB_SCRIPT_HEBREW => &_binary_resources_fonts_noto_NotoSerifHebrew_Regular_otf_start,
1029 HB_SCRIPT_IMPERIAL_ARAMAIC => {
1030 &_binary_resources_fonts_noto_NotoSansImperialAramaic_Regular_otf_start
1031 }
1032 HB_SCRIPT_INSCRIPTIONAL_PAHLAVI => {
1033 &_binary_resources_fonts_noto_NotoSansInscriptionalPahlavi_Regular_otf_start
1034 }
1035 HB_SCRIPT_INSCRIPTIONAL_PARTHIAN => {
1036 &_binary_resources_fonts_noto_NotoSansInscriptionalParthian_Regular_otf_start
1037 }
1038 HB_SCRIPT_JAVANESE => &_binary_resources_fonts_noto_NotoSansJavanese_Regular_otf_start,
1039 HB_SCRIPT_KAITHI => &_binary_resources_fonts_noto_NotoSansKaithi_Regular_otf_start,
1040 HB_SCRIPT_KANNADA => &_binary_resources_fonts_noto_NotoSerifKannada_Regular_otf_start,
1041 HB_SCRIPT_KAWI => &_binary_resources_fonts_noto_NotoSansKawi_Regular_otf_start,
1042 HB_SCRIPT_KAYAH_LI => &_binary_resources_fonts_noto_NotoSansKayahLi_Regular_otf_start,
1043 HB_SCRIPT_KHAROSHTHI => &_binary_resources_fonts_noto_NotoSansKharoshthi_Regular_otf_start,
1044 HB_SCRIPT_KHITAN_SMALL_SCRIPT => {
1045 &_binary_resources_fonts_noto_NotoSerifKhitanSmallScript_Regular_otf_start
1046 }
1047 HB_SCRIPT_KHMER => &_binary_resources_fonts_noto_NotoSerifKhmer_Regular_otf_start,
1048 HB_SCRIPT_KHOJKI => &_binary_resources_fonts_noto_NotoSerifKhojki_Regular_otf_start,
1049 HB_SCRIPT_KHUDAWADI => &_binary_resources_fonts_noto_NotoSansKhudawadi_Regular_otf_start,
1050 HB_SCRIPT_LAO => &_binary_resources_fonts_noto_NotoSerifLao_Regular_otf_start,
1051 HB_SCRIPT_LEPCHA => &_binary_resources_fonts_noto_NotoSansLepcha_Regular_otf_start,
1052 HB_SCRIPT_LIMBU => &_binary_resources_fonts_noto_NotoSansLimbu_Regular_otf_start,
1053 HB_SCRIPT_LINEAR_A => &_binary_resources_fonts_noto_NotoSansLinearA_Regular_otf_start,
1054 HB_SCRIPT_LINEAR_B => &_binary_resources_fonts_noto_NotoSansLinearB_Regular_otf_start,
1055 HB_SCRIPT_LISU => &_binary_resources_fonts_noto_NotoSansLisu_Regular_otf_start,
1056 HB_SCRIPT_LYCIAN => &_binary_resources_fonts_noto_NotoSansLycian_Regular_otf_start,
1057 HB_SCRIPT_LYDIAN => &_binary_resources_fonts_noto_NotoSansLydian_Regular_otf_start,
1058 HB_SCRIPT_MAHAJANI => &_binary_resources_fonts_noto_NotoSansMahajani_Regular_otf_start,
1059 HB_SCRIPT_MAKASAR => &_binary_resources_fonts_noto_NotoSerifMakasar_Regular_otf_start,
1060 HB_SCRIPT_MALAYALAM => &_binary_resources_fonts_noto_NotoSerifMalayalam_Regular_otf_start,
1061 HB_SCRIPT_MANDAIC => &_binary_resources_fonts_noto_NotoSansMandaic_Regular_otf_start,
1062 HB_SCRIPT_MANICHAEAN => &_binary_resources_fonts_noto_NotoSansManichaean_Regular_otf_start,
1063 HB_SCRIPT_MARCHEN => &_binary_resources_fonts_noto_NotoSansMarchen_Regular_otf_start,
1064 HB_SCRIPT_MASARAM_GONDI => {
1065 &_binary_resources_fonts_noto_NotoSansMasaramGondi_Regular_otf_start
1066 }
1067 HB_SCRIPT_MEDEFAIDRIN => {
1068 &_binary_resources_fonts_noto_NotoSansMedefaidrin_Regular_otf_start
1069 }
1070 HB_SCRIPT_MEETEI_MAYEK => {
1071 &_binary_resources_fonts_noto_NotoSansMeeteiMayek_Regular_otf_start
1072 }
1073 HB_SCRIPT_MENDE_KIKAKUI => {
1074 &_binary_resources_fonts_noto_NotoSansMendeKikakui_Regular_otf_start
1075 }
1076 HB_SCRIPT_MIAO => &_binary_resources_fonts_noto_NotoSansMiao_Regular_otf_start,
1077 HB_SCRIPT_MODI => &_binary_resources_fonts_noto_NotoSansModi_Regular_otf_start,
1078 HB_SCRIPT_MONGOLIAN => &_binary_resources_fonts_noto_NotoSansMongolian_Regular_otf_start,
1079 HB_SCRIPT_MRO => &_binary_resources_fonts_noto_NotoSansMro_Regular_otf_start,
1080 HB_SCRIPT_MULTANI => &_binary_resources_fonts_noto_NotoSansMultani_Regular_otf_start,
1081 HB_SCRIPT_MYANMAR => &_binary_resources_fonts_noto_NotoSerifMyanmar_Regular_otf_start,
1082 HB_SCRIPT_NABATAEAN => &_binary_resources_fonts_noto_NotoSansNabataean_Regular_otf_start,
1083 HB_SCRIPT_NAG_MUNDARI => &_binary_resources_fonts_noto_NotoSansNagMundari_Regular_otf_start,
1084 HB_SCRIPT_NANDINAGARI => {
1085 &_binary_resources_fonts_noto_NotoSansNandinagari_Regular_otf_start
1086 }
1087 HB_SCRIPT_NEWA => &_binary_resources_fonts_noto_NotoSansNewa_Regular_otf_start,
1088 HB_SCRIPT_NEW_TAI_LUE => &_binary_resources_fonts_noto_NotoSansNewTaiLue_Regular_otf_start,
1089 HB_SCRIPT_NKO => &_binary_resources_fonts_noto_NotoSansNKo_Regular_otf_start,
1090 HB_SCRIPT_NUSHU => &_binary_resources_fonts_noto_NotoSansNushu_Regular_otf_start,
1091 HB_SCRIPT_NYIAKENG_PUACHUE_HMONG => {
1092 &_binary_resources_fonts_noto_NotoSerifNyiakengPuachueHmong_Regular_otf_start
1093 }
1094 HB_SCRIPT_OGHAM => &_binary_resources_fonts_noto_NotoSansOgham_Regular_otf_start,
1095 HB_SCRIPT_OLD_HUNGARIAN => {
1096 &_binary_resources_fonts_noto_NotoSansOldHungarian_Regular_otf_start
1097 }
1098 HB_SCRIPT_OLD_ITALIC => &_binary_resources_fonts_noto_NotoSansOldItalic_Regular_otf_start,
1099 HB_SCRIPT_OLD_NORTH_ARABIAN => {
1100 &_binary_resources_fonts_noto_NotoSansOldNorthArabian_Regular_otf_start
1101 }
1102 HB_SCRIPT_OLD_PERMIC => &_binary_resources_fonts_noto_NotoSansOldPermic_Regular_otf_start,
1103 HB_SCRIPT_OLD_PERSIAN => &_binary_resources_fonts_noto_NotoSansOldPersian_Regular_otf_start,
1104 HB_SCRIPT_OLD_SOGDIAN => &_binary_resources_fonts_noto_NotoSansOldSogdian_Regular_otf_start,
1105 HB_SCRIPT_OLD_SOUTH_ARABIAN => {
1106 &_binary_resources_fonts_noto_NotoSansOldSouthArabian_Regular_otf_start
1107 }
1108 HB_SCRIPT_OLD_TURKIC => &_binary_resources_fonts_noto_NotoSansOldTurkic_Regular_otf_start,
1109 HB_SCRIPT_OLD_UYGHUR => &_binary_resources_fonts_noto_NotoSerifOldUyghur_Regular_otf_start,
1110 HB_SCRIPT_OL_CHIKI => &_binary_resources_fonts_noto_NotoSansOlChiki_Regular_otf_start,
1111 HB_SCRIPT_ORIYA => &_binary_resources_fonts_noto_NotoSerifOriya_Regular_otf_start,
1112 HB_SCRIPT_OSAGE => &_binary_resources_fonts_noto_NotoSansOsage_Regular_otf_start,
1113 HB_SCRIPT_OSMANYA => &_binary_resources_fonts_noto_NotoSansOsmanya_Regular_otf_start,
1114 HB_SCRIPT_PAHAWH_HMONG => {
1115 &_binary_resources_fonts_noto_NotoSansPahawhHmong_Regular_otf_start
1116 }
1117 HB_SCRIPT_PALMYRENE => &_binary_resources_fonts_noto_NotoSansPalmyrene_Regular_otf_start,
1118 HB_SCRIPT_PAU_CIN_HAU => &_binary_resources_fonts_noto_NotoSansPauCinHau_Regular_otf_start,
1119 HB_SCRIPT_PHAGS_PA => &_binary_resources_fonts_noto_NotoSansPhagsPa_Regular_otf_start,
1120 HB_SCRIPT_PHOENICIAN => &_binary_resources_fonts_noto_NotoSansPhoenician_Regular_otf_start,
1121 HB_SCRIPT_PSALTER_PAHLAVI => {
1122 &_binary_resources_fonts_noto_NotoSansPsalterPahlavi_Regular_otf_start
1123 }
1124 HB_SCRIPT_REJANG => &_binary_resources_fonts_noto_NotoSansRejang_Regular_otf_start,
1125 HB_SCRIPT_RUNIC => &_binary_resources_fonts_noto_NotoSansRunic_Regular_otf_start,
1126 HB_SCRIPT_SAMARITAN => &_binary_resources_fonts_noto_NotoSansSamaritan_Regular_otf_start,
1127 HB_SCRIPT_SAURASHTRA => &_binary_resources_fonts_noto_NotoSansSaurashtra_Regular_otf_start,
1128 HB_SCRIPT_SHARADA => &_binary_resources_fonts_noto_NotoSansSharada_Regular_otf_start,
1129 HB_SCRIPT_SHAVIAN => &_binary_resources_fonts_noto_NotoSansShavian_Regular_otf_start,
1130 HB_SCRIPT_SIDDHAM => &_binary_resources_fonts_noto_NotoSansSiddham_Regular_otf_start,
1131 HB_SCRIPT_SIGNWRITING => {
1132 &_binary_resources_fonts_noto_NotoSansSignWriting_Regular_otf_start
1133 }
1134 HB_SCRIPT_SINHALA => &_binary_resources_fonts_noto_NotoSerifSinhala_Regular_otf_start,
1135 HB_SCRIPT_SOGDIAN => &_binary_resources_fonts_noto_NotoSansSogdian_Regular_otf_start,
1136 HB_SCRIPT_SORA_SOMPENG => {
1137 &_binary_resources_fonts_noto_NotoSansSoraSompeng_Regular_otf_start
1138 }
1139 HB_SCRIPT_SOYOMBO => &_binary_resources_fonts_noto_NotoSansSoyombo_Regular_otf_start,
1140 HB_SCRIPT_SUNDANESE => &_binary_resources_fonts_noto_NotoSansSundanese_Regular_otf_start,
1141 HB_SCRIPT_SYLOTI_NAGRI => {
1142 &_binary_resources_fonts_noto_NotoSansSylotiNagri_Regular_otf_start
1143 }
1144 HB_SCRIPT_TAGALOG => &_binary_resources_fonts_noto_NotoSansTagalog_Regular_otf_start,
1145 HB_SCRIPT_TAGBANWA => &_binary_resources_fonts_noto_NotoSansTagbanwa_Regular_otf_start,
1146 HB_SCRIPT_TAI_LE => &_binary_resources_fonts_noto_NotoSansTaiLe_Regular_otf_start,
1147 HB_SCRIPT_TAI_THAM => &_binary_resources_fonts_noto_NotoSansTaiTham_Regular_otf_start,
1148 HB_SCRIPT_TAI_VIET => &_binary_resources_fonts_noto_NotoSansTaiViet_Regular_otf_start,
1149 HB_SCRIPT_TAKRI => &_binary_resources_fonts_noto_NotoSansTakri_Regular_otf_start,
1150 HB_SCRIPT_TAMIL => &_binary_resources_fonts_noto_NotoSerifTamil_Regular_otf_start,
1151 HB_SCRIPT_TANGSA => &_binary_resources_fonts_noto_NotoSansTangsa_Regular_otf_start,
1152 HB_SCRIPT_TELUGU => &_binary_resources_fonts_noto_NotoSerifTelugu_Regular_otf_start,
1153 HB_SCRIPT_THAANA => &_binary_resources_fonts_noto_NotoSansThaana_Regular_otf_start,
1154 HB_SCRIPT_THAI => &_binary_resources_fonts_noto_NotoSerifThai_Regular_otf_start,
1155 HB_SCRIPT_TIBETAN => &_binary_resources_fonts_noto_NotoSerifTibetan_Regular_otf_start,
1156 HB_SCRIPT_TIFINAGH => &_binary_resources_fonts_noto_NotoSansTifinagh_Regular_otf_start,
1157 HB_SCRIPT_TIRHUTA => &_binary_resources_fonts_noto_NotoSansTirhuta_Regular_otf_start,
1158 HB_SCRIPT_TOTO => &_binary_resources_fonts_noto_NotoSerifToto_Regular_otf_start,
1159 HB_SCRIPT_UGARITIC => &_binary_resources_fonts_noto_NotoSansUgaritic_Regular_otf_start,
1160 HB_SCRIPT_VAI => &_binary_resources_fonts_noto_NotoSansVai_Regular_otf_start,
1161 HB_SCRIPT_VITHKUQI => &_binary_resources_fonts_noto_NotoSerifVithkuqi_Regular_otf_start,
1162 HB_SCRIPT_WANCHO => &_binary_resources_fonts_noto_NotoSansWancho_Regular_otf_start,
1163 HB_SCRIPT_WARANG_CITI => &_binary_resources_fonts_noto_NotoSansWarangCiti_Regular_otf_start,
1164 HB_SCRIPT_YEZIDI => &_binary_resources_fonts_noto_NotoSerifYezidi_Regular_otf_start,
1165 HB_SCRIPT_YI => &_binary_resources_fonts_noto_NotoSansYi_Regular_otf_start,
1166 HB_SCRIPT_ZANABAZAR_SQUARE => {
1167 &_binary_resources_fonts_noto_NotoSansZanabazarSquare_Regular_otf_start
1168 }
1169
1170 HB_SYMBOL_MATHS => &_binary_resources_fonts_noto_NotoSansMath_Regular_otf_start,
1171 HB_SYMBOL_MUSIC => &_binary_resources_fonts_noto_NotoMusic_Regular_otf_start,
1172 HB_SYMBOL_MISC_ONE => &_binary_resources_fonts_noto_NotoSansSymbols_Regular_otf_start,
1173 HB_SCRIPT_BRAILLE | HB_SYMBOL_MISC_TWO => {
1174 &_binary_resources_fonts_noto_NotoSansSymbols2_Regular_otf_start
1175 }
1176 HB_SYMBOL_EMOJI => &_binary_resources_fonts_noto_NotoEmoji_Regular_ttf_start,
1177
1178 _ => &_binary_resources_fonts_droid_DroidSansFallback_ttf_start,
1179 }
1180}
1181
1182#[inline]
1183fn script_from_code(code: u32) -> HbScript {
1184 match code {
1187 0x2032..=0x2037
1188 | 0x2057
1189 | 0x20D0..=0x20DC
1190 | 0x20E1
1191 | 0x20E5..=0x20EF
1192 | 0x2102
1193 | 0x210A..=0x210E
1194 | 0x2110..=0x2112
1195 | 0x2115
1196 | 0x2119..=0x211D
1197 | 0x2124
1198 | 0x2128
1199 | 0x212C
1200 | 0x212D
1201 | 0x212F..=0x2131
1202 | 0x2133..=0x2138
1203 | 0x213C..=0x2140
1204 | 0x2145..=0x2149
1205 | 0x2190..=0x21AE
1206 | 0x21B0..=0x21E5
1207 | 0x21F1
1208 | 0x21F2
1209 | 0x21F4..=0x22FF
1210 | 0x2308..=0x230B
1211 | 0x2310
1212 | 0x2319
1213 | 0x231C..=0x2321
1214 | 0x2336..=0x237A
1215 | 0x237C
1216 | 0x2395
1217 | 0x239B..=0x23B6
1218 | 0x23D0
1219 | 0x23DC..=0x23E1
1220 | 0x2474
1221 | 0x2475
1222 | 0x25AF
1223 | 0x25B3
1224 | 0x25B7
1225 | 0x25BD
1226 | 0x25C1
1227 | 0x25CA
1228 | 0x25CC
1229 | 0x25FB
1230 | 0x266D..=0x266F
1231 | 0x27C0..=0x27FF
1232 | 0x2900..=0x2AFF
1233 | 0x2B0E..=0x2B11
1234 | 0x2B30..=0x2B4C
1235 | 0x2BFE
1236 | 0xFF5B
1237 | 0xFF5D
1238 | 0x1D400..=0x1D454
1239 | 0x1D456..=0x1D49C
1240 | 0x1D49E
1241 | 0x1D49F
1242 | 0x1D4A2
1243 | 0x1D4A5
1244 | 0x1D4A6
1245 | 0x1D4A9..=0x1D4AC
1246 | 0x1D4AE..=0x1D4B9
1247 | 0x1D4BB
1248 | 0x1D4BD..=0x1D4C3
1249 | 0x1D4C5..=0x1D505
1250 | 0x1D507..=0x1D50A
1251 | 0x1D50D..=0x1D514
1252 | 0x1D516..=0x1D51C
1253 | 0x1D51E..=0x1D539
1254 | 0x1D53B..=0x1D53E
1255 | 0x1D540..=0x1D544
1256 | 0x1D546
1257 | 0x1D54A..=0x1D550
1258 | 0x1D552..=0x1D6A5
1259 | 0x1D6A8..=0x1D7CB
1260 | 0x1D7CE..=0x1D7FF
1261 | 0x1EE00..=0x1EE03
1262 | 0x1EE05..=0x1EE1F
1263 | 0x1EE21
1264 | 0x1EE22
1265 | 0x1EE24
1266 | 0x1EE27
1267 | 0x1EE29..=0x1EE32
1268 | 0x1EE34..=0x1EE37
1269 | 0x1EE39
1270 | 0x1EE3B
1271 | 0x1EE42
1272 | 0x1EE47
1273 | 0x1EE49
1274 | 0x1EE4B
1275 | 0x1EE4D..=0x1EE4F
1276 | 0x1EE51
1277 | 0x1EE52
1278 | 0x1EE54
1279 | 0x1EE57
1280 | 0x1EE59
1281 | 0x1EE5B
1282 | 0x1EE5D
1283 | 0x1EE5F
1284 | 0x1EE61
1285 | 0x1EE62
1286 | 0x1EE64
1287 | 0x1EE67..=0x1EE6A
1288 | 0x1EE6C..=0x1EE72
1289 | 0x1EE74..=0x1EE77
1290 | 0x1EE79..=0x1EE7C
1291 | 0x1EE7E
1292 | 0x1EE80..=0x1EE89
1293 | 0x1EE8B..=0x1EE9B
1294 | 0x1EEA1..=0x1EEA3
1295 | 0x1EEA5..=0x1EEA9
1296 | 0x1EEAB..=0x1EEBB
1297 | 0x1EEF0
1298 | 0x1EEF1 => HB_SYMBOL_MATHS,
1299
1300 0x1D000..=0x1D0F5 | 0x1D100..=0x1D126 | 0x1D129..=0x1D1E8 | 0x1D200..=0x1D245 => {
1301 HB_SYMBOL_MUSIC
1302 }
1303
1304 0x20DD..=0x20E0
1305 | 0x20E2..=0x20E4
1306 | 0x2160..=0x2183
1307 | 0x2185..=0x2188
1308 | 0x218A
1309 | 0x218B
1310 | 0x2300..=0x230F
1311 | 0x2311..=0x2315
1312 | 0x2317
1313 | 0x2322
1314 | 0x2323
1315 | 0x2329
1316 | 0x232A
1317 | 0x232C..=0x2335
1318 | 0x2380..=0x2394
1319 | 0x2396..=0x239A
1320 | 0x23BE..=0x23CD
1321 | 0x23D1..=0x23DB
1322 | 0x23E2..=0x23E8
1323 | 0x2460..=0x24FF
1324 | 0x260A..=0x260D
1325 | 0x2613
1326 | 0x2624..=0x262F
1327 | 0x2638..=0x263B
1328 | 0x263D..=0x2653
1329 | 0x2669..=0x267E
1330 | 0x2690..=0x269D
1331 | 0x26A2..=0x26A9
1332 | 0x26AD..=0x26BC
1333 | 0x26CE
1334 | 0x26E2..=0x26FF
1335 | 0x271D..=0x2721
1336 | 0x2776..=0x2793
1337 | 0x1F100..=0x1F10C
1338 | 0x1F110..=0x1F12F
1339 | 0x1F130..=0x1F16C
1340 | 0x1F170..=0x1F190
1341 | 0x1F19B..=0x1F1AC
1342 | 0x1F546..=0x1F549
1343 | 0x1F54F
1344 | 0x1F610
1345 | 0x1F700..=0x1F773 => HB_SYMBOL_MISC_ONE,
1346
1347 0x2022
1348 | 0x21AF
1349 | 0x21E6..=0x21F0
1350 | 0x21F3
1351 | 0x2316
1352 | 0x2318
1353 | 0x231A
1354 | 0x231B
1355 | 0x2324..=0x2328
1356 | 0x232B
1357 | 0x237B
1358 | 0x237D..=0x237F
1359 | 0x23CE
1360 | 0x23CF
1361 | 0x23E9
1362 | 0x23ED..=0x23EF
1363 | 0x23F1..=0x23FF
1364 | 0x2400..=0x2426
1365 | 0x2440..=0x244A
1366 | 0x25A0..=0x2609
1367 | 0x260E..=0x2612
1368 | 0x2614..=0x2623
1369 | 0x2630..=0x2637
1370 | 0x263C
1371 | 0x2654..=0x2668
1372 | 0x267F..=0x268F
1373 | 0x269E..=0x26A1
1374 | 0x26AA..=0x26AC
1375 | 0x26BD..=0x26CD
1376 | 0x26CF..=0x26E1
1377 | 0x2700..=0x2704
1378 | 0x2706..=0x2709
1379 | 0x270B..=0x271C
1380 | 0x2722..=0x2727
1381 | 0x2729..=0x274B
1382 | 0x274D
1383 | 0x274F..=0x2752
1384 | 0x2756..=0x2775
1385 | 0x2794
1386 | 0x2798..=0x27AF
1387 | 0x27B1..=0x27BE
1388 | 0x2800..=0x28FF
1389 | 0x2B00..=0x2B0D
1390 | 0x2B12..=0x2B2F
1391 | 0x2B4D..=0x2B73
1392 | 0x2B76..=0x2B95
1393 | 0x2B97..=0x2BFD
1394 | 0x2BFF
1395 | 0x4DC0..=0x4DFF
1396 | 0xFFF9..=0xFFFB
1397 | 0x10140..=0x1018E
1398 | 0x10190..=0x1019C
1399 | 0x101A0
1400 | 0x101D0..=0x101FD
1401 | 0x102E0..=0x102FB
1402 | 0x10E60..=0x10E7E
1403 | 0x1D2E0..=0x1D2F3
1404 | 0x1D300..=0x1D356
1405 | 0x1D360..=0x1D378
1406 | 0x1F000..=0x1F02B
1407 | 0x1F030..=0x1F093
1408 | 0x1F0A0..=0x1F0AE
1409 | 0x1F0B1..=0x1F0BF
1410 | 0x1F0C1..=0x1F0CF
1411 | 0x1F0D1..=0x1F0F5
1412 | 0x1F30D..=0x1F30F
1413 | 0x1F315
1414 | 0x1F31C
1415 | 0x1F321..=0x1F32C
1416 | 0x1F336
1417 | 0x1F378
1418 | 0x1F37D
1419 | 0x1F394..=0x1F39F
1420 | 0x1F3A7
1421 | 0x1F3AC..=0x1F3AE
1422 | 0x1F3C2
1423 | 0x1F3CB..=0x1F3CE
1424 | 0x1F3D4..=0x1F3DF
1425 | 0x1F3ED
1426 | 0x1F3F1..=0x1F3F3
1427 | 0x1F3F5..=0x1F3F7
1428 | 0x1F408
1429 | 0x1F415
1430 | 0x1F41F
1431 | 0x1F426
1432 | 0x1F43F
1433 | 0x1F441
1434 | 0x1F446..=0x1F449
1435 | 0x1F44C..=0x1F44E
1436 | 0x1F453
1437 | 0x1F46A
1438 | 0x1F47D
1439 | 0x1F4A3
1440 | 0x1F4B0
1441 | 0x1F4B3
1442 | 0x1F4B9
1443 | 0x1F4BB
1444 | 0x1F4BF
1445 | 0x1F4C8..=0x1F4CB
1446 | 0x1F4DA
1447 | 0x1F4DF
1448 | 0x1F4E4..=0x1F4E6
1449 | 0x1F4EA..=0x1F4ED
1450 | 0x1F4F9..=0x1F4FB
1451 | 0x1F4FD
1452 | 0x1F4FE
1453 | 0x1F503
1454 | 0x1F507..=0x1F50A
1455 | 0x1F50D
1456 | 0x1F512
1457 | 0x1F513
1458 | 0x1F53E..=0x1F545
1459 | 0x1F54A
1460 | 0x1F550..=0x1F579
1461 | 0x1F57B..=0x1F594
1462 | 0x1F597..=0x1F5A3
1463 | 0x1F5A5..=0x1F5FA
1464 | 0x1F650..=0x1F67F
1465 | 0x1F687
1466 | 0x1F68D
1467 | 0x1F691
1468 | 0x1F694
1469 | 0x1F698
1470 | 0x1F6AD
1471 | 0x1F6B2
1472 | 0x1F6B9
1473 | 0x1F6BA
1474 | 0x1F6BC
1475 | 0x1F6C6..=0x1F6CB
1476 | 0x1F6CD..=0x1F6CF
1477 | 0x1F6D3..=0x1F6D7
1478 | 0x1F6E0..=0x1F6EA
1479 | 0x1F6F0..=0x1F6F3
1480 | 0x1F6F7..=0x1F6FC
1481 | 0x1F780..=0x1F7D8
1482 | 0x1F7E0..=0x1F7EB
1483 | 0x1F800..=0x1F80B
1484 | 0x1F810..=0x1F847
1485 | 0x1F850..=0x1F859
1486 | 0x1F860..=0x1F887
1487 | 0x1F890..=0x1F8AD
1488 | 0x1F8B0..=0x1F8B1
1489 | 0x1F93B
1490 | 0x1F946
1491 | 0x1FA00..=0x1FA53
1492 | 0x1FA60..=0x1FA6D
1493 | 0x1FA70..=0x1FA74
1494 | 0x1FA78..=0x1FA7A
1495 | 0x1FA80..=0x1FA86
1496 | 0x1FA90..=0x1FAA8
1497 | 0x1FAB0..=0x1FAB6
1498 | 0x1FAC0..=0x1FAC2
1499 | 0x1FAD0..=0x1FAD6
1500 | 0x1FB00..=0x1FBCA
1501 | 0x1FBF0..=0x1FBF9 => HB_SYMBOL_MISC_TWO,
1502
1503 0x2049
1504 | 0x2122
1505 | 0x2139
1506 | 0x23EA..=0x23EC
1507 | 0x23F0
1508 | 0x2705
1509 | 0x2708..=0x270C
1510 | 0x2728
1511 | 0x274C
1512 | 0x274E
1513 | 0x2753..=0x2755
1514 | 0x2795..=0x2797
1515 | 0x27B0
1516 | 0x27BF
1517 | 0x3030
1518 | 0x303D
1519 | 0x3297
1520 | 0x3299
1521 | 0xFEFF
1522 | 0x1F191..=0x1F19A
1523 | 0x1F1E6..=0x1F1FF
1524 | 0x1F201
1525 | 0x1F202
1526 | 0x1F21A
1527 | 0x1F22F
1528 | 0x1F232..=0x1F23A
1529 | 0x1F250
1530 | 0x1F251
1531 | 0x1F300..=0x1F320
1532 | 0x1F330..=0x1F335
1533 | 0x1F337..=0x1F37C
1534 | 0x1F380..=0x1F393
1535 | 0x1F3A0..=0x1F3C4
1536 | 0x1F3C6..=0x1F3CA
1537 | 0x1F3E0..=0x1F3F0
1538 | 0x1F400..=0x1F429
1539 | 0x1F42B..=0x1F43E
1540 | 0x1F440
1541 | 0x1F442..=0x1F4F7
1542 | 0x1F4F9..=0x1F4FC
1543 | 0x1F500..=0x1F53D
1544 | 0x1F5FB..=0x1F640
1545 | 0x1F645..=0x1F64F
1546 | 0x1F680..=0x1F697
1547 | 0x1F699..=0x1F6C5
1548 | 0xFE4E5..=0xFE4EE
1549 | 0xFE82C
1550 | 0xFE82E..=0xFE837 => HB_SYMBOL_EMOJI,
1551
1552 _ => HB_SCRIPT_UNKNOWN,
1553 }
1554}
1555
1556pub struct FontLibrary(*mut FtLibrary);
1557
1558pub struct FontOpener(Rc<FontLibrary>);
1559
1560pub struct Font {
1561 lib: Rc<FontLibrary>,
1562 face: *mut FtFace,
1563 font: *mut HbFont,
1564 size: u32,
1565 dpi: u16,
1566 pub ellipsis: RenderPlan,
1568 pub x_heights: (u32, u32),
1570 space_codepoint: u32,
1571}
1572
1573impl FontOpener {
1574 pub fn new() -> Result<FontOpener, Error> {
1575 unsafe {
1576 let mut lib = ptr::null_mut();
1577 let ret = FT_Init_FreeType(&mut lib);
1578 if ret != FT_ERR_OK {
1579 Err(Error::from(FreetypeError::from(ret)))
1580 } else {
1581 Ok(FontOpener(Rc::new(FontLibrary(lib))))
1582 }
1583 }
1584 }
1585
1586 pub fn open<P: AsRef<Path>>(&self, path: P) -> Result<Font, Error> {
1587 unsafe {
1588 let mut face = ptr::null_mut();
1589 let c_path = CString::new(path.as_ref().as_os_str().as_bytes()).unwrap();
1590 let ret = FT_New_Face((self.0).0, c_path.as_ptr(), 0, &mut face);
1591 if ret != FT_ERR_OK {
1592 return Err(Error::from(FreetypeError::from(ret)));
1593 }
1594 let font = ptr::null_mut();
1595 let ellipsis = RenderPlan::default();
1596 let x_heights = (0, 0);
1597 let space_codepoint = FT_Get_Char_Index(face, ' ' as libc::c_ulong);
1598 Ok(Font {
1599 lib: self.0.clone(),
1600 face,
1601 font,
1602 size: 0,
1603 dpi: 0,
1604 ellipsis,
1605 x_heights,
1606 space_codepoint,
1607 })
1608 }
1609 }
1610
1611 pub fn open_memory(&self, buf: &[u8]) -> Result<Font, Error> {
1612 unsafe {
1613 let mut face = ptr::null_mut();
1614 let ret = FT_New_Memory_Face(
1615 (self.0).0,
1616 buf.as_ptr() as *const FtByte,
1617 buf.len() as libc::c_long,
1618 0,
1619 &mut face,
1620 );
1621 if ret != FT_ERR_OK {
1622 return Err(Error::from(FreetypeError::from(ret)));
1623 }
1624 let ellipsis = RenderPlan::default();
1625 let font = ptr::null_mut();
1626 let x_heights = (0, 0);
1627 let space_codepoint = FT_Get_Char_Index(face, ' ' as libc::c_ulong);
1628 Ok(Font {
1629 lib: self.0.clone(),
1630 face,
1631 font,
1632 size: 0,
1633 dpi: 0,
1634 ellipsis,
1635 x_heights,
1636 space_codepoint,
1637 })
1638 }
1639 }
1640}
1641
1642impl Font {
1643 pub fn family_name(&self) -> Option<&str> {
1644 unsafe {
1645 let ptr = (*self.face).family_name;
1646 if ptr.is_null() {
1647 return None;
1648 }
1649 CStr::from_ptr(ptr).to_str().ok()
1650 }
1651 }
1652
1653 pub fn style_name(&self) -> Option<&str> {
1654 unsafe {
1655 let ptr = (*self.face).style_name;
1656 if ptr.is_null() {
1657 return None;
1658 }
1659 CStr::from_ptr(ptr).to_str().ok()
1660 }
1661 }
1662
1663 pub fn set_size(&mut self, size: u32, dpi: u16) {
1664 if !self.font.is_null() && self.size == size && self.dpi == dpi {
1665 return;
1666 }
1667
1668 self.size = size;
1669 self.dpi = dpi;
1670
1671 unsafe {
1672 let ret = FT_Set_Char_Size(self.face, size as FtF26Dot6, 0, dpi as libc::c_uint, 0);
1673
1674 if ret != FT_ERR_OK {
1675 return;
1676 }
1677
1678 if self.font.is_null() {
1679 self.font = hb_ft_font_create(self.face, ptr::null());
1680 } else {
1681 hb_ft_font_changed(self.font);
1682 }
1683
1684 self.ellipsis = self.plan("…", None, None);
1685 self.x_heights = (self.height('x'), self.height('X'));
1686 }
1687 }
1688
1689 pub fn set_variations(&mut self, specs: &[&str]) {
1690 unsafe {
1691 let mut varia = ptr::null_mut();
1692 let ret = FT_Get_MM_Var(self.face, &mut varia);
1693
1694 if ret != FT_ERR_OK {
1695 return;
1696 }
1697
1698 let axes_count = (*varia).num_axis as usize;
1699 let mut coords = Vec::with_capacity(axes_count);
1700
1701 for i in 0..(axes_count as isize) {
1702 let axis = ((*varia).axis).offset(i);
1703 coords.push((*axis).def);
1704 }
1705
1706 for s in specs {
1707 let tn = s[..4].as_bytes();
1708 let tag = tag(tn[0], tn[1], tn[2], tn[3]);
1709 let value: f32 = s[5..].parse().unwrap_or_default();
1710
1711 for i in 0..(axes_count as isize) {
1712 let axis = ((*varia).axis).offset(i);
1713
1714 if (*axis).tag == tag as libc::c_ulong {
1715 let scaled_value = ((value * 65536.0) as FtFixed)
1716 .min((*axis).maximum)
1717 .max((*axis).minimum);
1718 *coords.get_unchecked_mut(i as usize) = scaled_value;
1719 break;
1720 }
1721 }
1722 }
1723
1724 let ret = FT_Set_Var_Design_Coordinates(
1725 self.face,
1726 coords.len() as libc::c_uint,
1727 coords.as_ptr(),
1728 );
1729
1730 if ret == FT_ERR_OK && !self.font.is_null() {
1731 hb_ft_font_changed(self.font);
1732 }
1733
1734 FT_Done_MM_Var(self.lib.0, varia);
1735 }
1736 }
1737
1738 pub fn set_variations_from_name(&mut self, name: &str) -> bool {
1739 let mut found = false;
1740
1741 unsafe {
1742 let mut varia = ptr::null_mut();
1743 let ret = FT_Get_MM_Var(self.face, &mut varia);
1744
1745 if ret != FT_ERR_OK {
1746 return found;
1747 }
1748
1749 let styles_count = (*varia).num_namedstyles as isize;
1750 let names_count = FT_Get_Sfnt_Name_Count(self.face);
1751 let mut sfnt_name = FtSfntName::default();
1752
1753 'outer: for i in 0..styles_count {
1754 let style = ((*varia).namedstyle).offset(i);
1755 let strid = (*style).strid as libc::c_ushort;
1756 for j in 0..names_count {
1757 let ret = FT_Get_Sfnt_Name(self.face, j, &mut sfnt_name);
1758
1759 if ret != FT_ERR_OK || sfnt_name.name_id != strid {
1760 continue;
1761 }
1762
1763 if sfnt_name.platform_id != TT_PLATFORM_MICROSOFT
1764 || sfnt_name.encoding_id != TT_MS_ID_UNICODE_CS
1765 || sfnt_name.language_id != TT_MS_LANGID_ENGLISH_UNITED_STATES
1766 {
1767 continue;
1768 }
1769
1770 let slice = slice::from_raw_parts(sfnt_name.text, sfnt_name.len as usize);
1771 let vec_ascii: Vec<u8> = slice
1773 .iter()
1774 .enumerate()
1775 .filter_map(|x| if x.0 % 2 == 0 { None } else { Some(*x.1) })
1776 .collect();
1777
1778 if let Ok(name_str) = str::from_utf8(&vec_ascii[..]) {
1779 if name.eq_ignore_ascii_case(name_str) {
1780 found = true;
1781 let ret = FT_Set_Var_Design_Coordinates(
1782 self.face,
1783 (*varia).num_axis,
1784 (*style).coords,
1785 );
1786 if ret == FT_ERR_OK && !self.font.is_null() {
1787 hb_ft_font_changed(self.font);
1788 }
1789 break 'outer;
1790 }
1791 }
1792 }
1793 }
1794
1795 FT_Done_MM_Var(self.lib.0, varia);
1796 }
1797
1798 found
1799 }
1800
1801 #[inline]
1802 unsafe fn patch(
1803 &mut self,
1804 txt: &str,
1805 features: &[HbFeature],
1806 render_plan: &mut RenderPlan,
1807 missing_glyphs: Vec<(usize, usize)>,
1808 buf: *mut HbBuffer,
1809 ) {
1810 let mut drift = 0;
1811 for (mut start, mut end) in missing_glyphs.into_iter() {
1812 start = (start as i32 + drift).max(0) as usize;
1813 end = (end as i32 + drift).max(0) as usize;
1814 hb_buffer_clear_contents(buf);
1815 let start_index = render_plan.glyphs[start].cluster;
1816 let end_index = render_plan
1817 .glyphs
1818 .get(end)
1819 .map(|g| g.cluster)
1820 .unwrap_or_else(|| txt.len());
1821 let chunk = &txt[start_index..end_index];
1822 hb_buffer_add_utf8(
1823 buf,
1824 chunk.as_ptr() as *const libc::c_char,
1825 chunk.len() as libc::c_int,
1826 0,
1827 -1,
1828 );
1829 hb_buffer_guess_segment_properties(buf);
1830 let mut script = hb_buffer_get_script(buf);
1831 if script == HB_SCRIPT_INVALID || script == HB_SCRIPT_UNKNOWN {
1832 if let Some(c) = chunk.chars().next() {
1833 script = script_from_code(u32::from(c));
1834 }
1835 }
1836 let font_data = font_data_from_script(script);
1837 let mut face = ptr::null_mut();
1838 FT_New_Memory_Face(
1839 (self.lib).0,
1840 font_data.as_ptr() as *const FtByte,
1841 font_data.len() as libc::c_long,
1842 0,
1843 &mut face,
1844 );
1845 FT_Set_Pixel_Sizes(face, (*(*self.face).size).metrics.x_ppem as libc::c_uint, 0);
1846 let font = hb_ft_font_create(face, ptr::null());
1847 hb_shape(font, buf, features.as_ptr(), features.len() as libc::c_uint);
1848 let len = hb_buffer_get_length(buf) as usize;
1849 let info = hb_buffer_get_glyph_infos(buf, ptr::null_mut());
1850 let pos = hb_buffer_get_glyph_positions(buf, ptr::null_mut());
1851 let mut glyphs = Vec::with_capacity(len);
1852
1853 for i in 0..len {
1854 let pos_i = &*pos.add(i);
1855 let info_i = &*info.add(i);
1856 render_plan.width += pos_i.x_advance >> 6;
1857 glyphs.push(GlyphPlan {
1858 codepoint: info_i.codepoint,
1859 cluster: start_index + info_i.cluster as usize,
1860 advance: pt!(pos_i.x_advance >> 6, pos_i.y_advance >> 6),
1861 offset: pt!(pos_i.x_offset >> 6, -pos_i.y_offset >> 6),
1862 });
1863 render_plan.scripts.insert(start + i, script);
1864 }
1865
1866 render_plan.glyphs.splice(start..end, glyphs.into_iter());
1867 drift += len as i32 - (end - start) as i32;
1868
1869 hb_font_destroy(font);
1870 FT_Done_Face(face);
1871 }
1872 }
1873
1874 pub fn plan<S: AsRef<str>>(
1875 &mut self,
1876 text: S,
1877 max_width: Option<i32>,
1878 features: Option<&[String]>,
1879 ) -> RenderPlan {
1880 unsafe {
1881 let buf = hb_buffer_create();
1882 hb_buffer_add_utf8(
1883 buf,
1884 text.as_ref().as_ptr() as *const libc::c_char,
1885 text.as_ref().len() as libc::c_int,
1886 0,
1887 -1,
1888 );
1889
1890 hb_buffer_set_direction(buf, HB_DIRECTION_LTR);
1892 hb_buffer_guess_segment_properties(buf);
1893
1894 let features_vec: Vec<HbFeature> = features
1895 .map(|ftr| {
1896 ftr.iter()
1897 .filter_map(|f| {
1898 let mut feature = HbFeature::default();
1899 let ret = hb_feature_from_string(
1900 f.as_ptr() as *const libc::c_char,
1901 f.len() as libc::c_int,
1902 &mut feature,
1903 );
1904 if ret == 1 {
1905 Some(feature)
1906 } else {
1907 None
1908 }
1909 })
1910 .collect()
1911 })
1912 .unwrap_or_default();
1913
1914 hb_shape(
1915 self.font,
1916 buf,
1917 features_vec.as_ptr(),
1918 features_vec.len() as libc::c_uint,
1919 );
1920
1921 let len = hb_buffer_get_length(buf) as usize;
1922 let info = hb_buffer_get_glyph_infos(buf, ptr::null_mut());
1923 let pos = hb_buffer_get_glyph_positions(buf, ptr::null_mut());
1924 let mut render_plan = RenderPlan::default();
1925 let mut missing_glyphs = Vec::new();
1926
1927 for i in 0..len {
1928 let pos_i = &*pos.add(i);
1929 let info_i = &*info.add(i);
1930 if info_i.codepoint == 0 {
1931 if let Some((start, end)) = missing_glyphs.pop() {
1932 if i == end {
1933 missing_glyphs.push((start, end + 1));
1934 } else {
1935 missing_glyphs.push((start, end));
1936 missing_glyphs.push((i, i + 1));
1937 }
1938 } else {
1939 missing_glyphs.push((i, i + 1));
1940 }
1941 } else {
1942 render_plan.width += pos_i.x_advance >> 6;
1943 }
1944 let glyph = GlyphPlan {
1945 codepoint: info_i.codepoint,
1946 cluster: info_i.cluster as usize,
1947 advance: pt!(pos_i.x_advance >> 6, pos_i.y_advance >> 6),
1948 offset: pt!(pos_i.x_offset >> 6, -pos_i.y_offset >> 6),
1949 };
1950 render_plan.glyphs.push(glyph);
1951 }
1952
1953 self.patch(
1954 text.as_ref(),
1955 &features_vec,
1956 &mut render_plan,
1957 missing_glyphs,
1958 buf,
1959 );
1960
1961 hb_buffer_destroy(buf);
1962
1963 if let Some(mw) = max_width {
1964 self.crop_right(&mut render_plan, mw);
1965 }
1966
1967 render_plan
1968 }
1969 }
1970
1971 #[inline]
1972 pub fn crop_right(&self, render_plan: &mut RenderPlan, max_width: i32) {
1973 if render_plan.width <= max_width {
1974 return;
1975 }
1976
1977 render_plan.width += self.ellipsis.width;
1978
1979 while let Some(gp) = render_plan.glyphs.pop() {
1980 render_plan.width -= gp.advance.x;
1981 if render_plan.width <= max_width {
1982 break;
1983 }
1984 }
1985
1986 let len = render_plan.glyphs.len();
1987 render_plan.scripts.retain(|&k, _| k < len);
1988 render_plan
1989 .glyphs
1990 .extend_from_slice(&self.ellipsis.glyphs[..]);
1991 }
1992
1993 #[inline]
1994 pub fn trim_left(&self, render_plan: &mut RenderPlan) {
1995 if render_plan.glyphs.is_empty() {
1996 return;
1997 }
1998
1999 let mut i = 0;
2000
2001 while render_plan.glyphs[i].codepoint == self.space_codepoint {
2002 render_plan.width -= render_plan.glyphs[i].advance.x;
2003 i += 1;
2004 }
2005
2006 render_plan.glyphs.drain(..i);
2007 render_plan.scripts = render_plan
2008 .scripts
2009 .iter()
2010 .filter_map(|(&k, &v)| if k < i { None } else { Some((k - i, v)) })
2011 .collect();
2012 }
2013
2014 #[inline]
2015 pub fn crop_around(&self, render_plan: &mut RenderPlan, index: usize, max_width: i32) -> usize {
2016 if render_plan.width <= max_width {
2017 return 0;
2018 }
2019
2020 let len = render_plan.glyphs.len();
2021 let mut width = 0;
2022 let mut polarity = 0;
2023 let mut upper_index = index;
2024 let mut lower_index = index as i32 - 1;
2025
2026 loop {
2027 let next_width;
2028 if upper_index < len && (polarity % 2 == 0 || lower_index < 0) {
2029 next_width = width + render_plan.glyphs[upper_index].advance.x;
2030 if next_width > max_width {
2031 break;
2032 } else {
2033 width = next_width;
2034 }
2035 upper_index += 1;
2036 } else if lower_index >= 0 && (polarity % 2 == 1 || upper_index == len) {
2037 next_width = width + render_plan.glyphs[lower_index as usize].advance.x;
2038 if next_width > max_width {
2039 break;
2040 } else {
2041 width = next_width;
2042 }
2043 lower_index -= 1;
2044 }
2045 polarity += 1;
2046 }
2047
2048 if upper_index < len {
2049 width += self.ellipsis.width;
2050 upper_index -= 1;
2051 while width > max_width && upper_index > (lower_index.max(0) as usize) {
2052 width -= render_plan.glyphs[upper_index].advance.x;
2053 upper_index -= 1;
2054 }
2055 render_plan.glyphs.truncate(upper_index + 1);
2056 render_plan
2057 .glyphs
2058 .extend_from_slice(&self.ellipsis.glyphs[..]);
2059 }
2060
2061 if lower_index >= 0 {
2062 width += self.ellipsis.width;
2063 lower_index += 1;
2064 while width > max_width && (lower_index as usize) < upper_index {
2065 width -= render_plan.glyphs[lower_index as usize].advance.x;
2066 lower_index += 1;
2067 }
2068 render_plan.glyphs = self
2069 .ellipsis
2070 .glyphs
2071 .iter()
2072 .chain(render_plan.glyphs[lower_index as usize..].iter())
2073 .cloned()
2074 .collect();
2075 }
2076
2077 render_plan
2078 .scripts
2079 .retain(|&k, _| k >= lower_index.max(0) as usize && k <= upper_index);
2080 if lower_index > 0 {
2081 render_plan.scripts = render_plan
2082 .scripts
2083 .drain()
2084 .map(|(k, v)| (k - lower_index as usize + 1, v))
2085 .collect();
2086 }
2087 render_plan.width = width;
2088
2089 if lower_index < 0 {
2090 0
2091 } else {
2092 lower_index as usize
2093 }
2094 }
2095
2096 pub fn cut_point(&self, render_plan: &RenderPlan, max_width: i32) -> (usize, i32) {
2097 let mut width = render_plan.width;
2098 let glyphs = &render_plan.glyphs;
2099 let mut i = glyphs.len() - 1;
2100
2101 width -= glyphs[i].advance.x;
2102
2103 while i > 0 && width > max_width {
2104 i -= 1;
2105 width -= glyphs[i].advance.x;
2106 }
2107
2108 let j = i;
2109 let last_width = width;
2110
2111 while i > 0 && glyphs[i].codepoint != self.space_codepoint {
2112 i -= 1;
2113 width -= glyphs[i].advance.x;
2114 }
2115
2116 if i == 0 {
2117 i = j;
2118 width = last_width;
2119 }
2120
2121 (i, width)
2122 }
2123
2124 pub fn render(
2125 &mut self,
2126 fb: &mut dyn Framebuffer,
2127 color: Color,
2128 render_plan: &RenderPlan,
2129 origin: Point,
2130 ) {
2131 unsafe {
2132 let mut pos = origin;
2133 let mut fallback_faces = FxHashMap::default();
2134
2135 for (index, glyph) in render_plan.glyphs.iter().enumerate() {
2136 let face = if let Some(script) = render_plan.scripts.get(&index) {
2137 *fallback_faces.entry(script).or_insert_with(|| {
2138 let font_data = font_data_from_script(*script);
2139 let mut face = ptr::null_mut();
2140 FT_New_Memory_Face(
2141 (self.lib).0,
2142 font_data.as_ptr() as *const FtByte,
2143 font_data.len() as libc::c_long,
2144 0,
2145 &mut face,
2146 );
2147 FT_Set_Pixel_Sizes(
2148 face,
2149 (*(*self.face).size).metrics.x_ppem as libc::c_uint,
2150 0,
2151 );
2152 face
2153 })
2154 } else {
2155 self.face
2156 };
2157
2158 FT_Load_Glyph(face, glyph.codepoint, FT_LOAD_RENDER | FT_LOAD_NO_HINTING);
2159
2160 let glyph_slot = (*face).glyph;
2161 let top_left =
2162 pos + glyph.offset + pt!((*glyph_slot).bitmap_left, -(*glyph_slot).bitmap_top);
2163 let bitmap = &(*glyph_slot).bitmap;
2164
2165 for y in 0..bitmap.rows {
2166 for x in 0..bitmap.width {
2167 let blackness = *bitmap.buffer.offset((bitmap.pitch * y + x) as isize);
2168 let alpha = blackness as f32 / 255.0;
2169 let pt = top_left + pt!(x, y);
2170 fb.set_blended_pixel(pt.x as u32, pt.y as u32, color, alpha);
2171 }
2172 }
2173
2174 pos += glyph.advance;
2175 }
2176
2177 for (_, face) in fallback_faces {
2178 FT_Done_Face(face);
2179 }
2180 }
2181 }
2182
2183 pub fn height(&self, c: char) -> u32 {
2184 unsafe {
2185 FT_Load_Char(self.face, c as libc::c_ulong, FT_LOAD_DEFAULT);
2186 let metrics = &((*(*self.face).glyph).metrics);
2187 (metrics.height >> 6) as u32
2188 }
2189 }
2190
2191 pub fn em(&self) -> u16 {
2192 unsafe { (*(*self.face).size).metrics.x_ppem as u16 }
2193 }
2194
2195 pub fn ascender(&self) -> i32 {
2196 unsafe { (*(*self.face).size).metrics.ascender as i32 / 64 }
2197 }
2198
2199 pub fn descender(&self) -> i32 {
2200 unsafe { (*(*self.face).size).metrics.descender as i32 / 64 }
2201 }
2202
2203 pub fn line_height(&self) -> i32 {
2204 unsafe { (*(*self.face).size).metrics.height as i32 / 64 }
2205 }
2206}
2207
2208#[derive(Debug, Copy, Clone)]
2209struct GlyphPlan {
2210 codepoint: u32,
2211 cluster: usize,
2212 offset: Point,
2213 advance: Point,
2214}
2215
2216#[derive(Debug, Clone)]
2217pub struct RenderPlan {
2218 pub width: i32,
2219 scripts: FxHashMap<usize, HbScript>,
2220 glyphs: Vec<GlyphPlan>,
2221}
2222
2223impl Default for RenderPlan {
2224 fn default() -> RenderPlan {
2225 RenderPlan {
2226 width: 0,
2227 scripts: FxHashMap::default(),
2228 glyphs: Vec::new(),
2229 }
2230 }
2231}
2232
2233impl RenderPlan {
2234 pub fn scale(&self, scale: f32) -> RenderPlan {
2235 let width = (scale * self.width as f32) as i32;
2236 let scripts = self.scripts.clone();
2237 let glyphs = self
2238 .glyphs
2239 .iter()
2240 .map(|gp| GlyphPlan {
2241 offset: Point::from(scale * Vec2::from(gp.offset)),
2242 advance: Point::from(scale * Vec2::from(gp.advance)),
2243 ..*gp
2244 })
2245 .collect();
2246 RenderPlan {
2247 width,
2248 scripts,
2249 glyphs,
2250 }
2251 }
2252
2253 pub fn space_out(&mut self, letter_spacing: i32) {
2254 if letter_spacing == 0 {
2255 return;
2256 }
2257
2258 if let Some((_, start)) = self.glyphs.split_last_mut() {
2259 let len = start.len() as i32;
2260 for glyph in start {
2261 glyph.advance.x += letter_spacing;
2262 }
2263 self.width += len * letter_spacing;
2264 }
2265 }
2266
2267 pub fn split_off(&mut self, index: usize, width: i32) -> RenderPlan {
2268 let mut next_scripts = FxHashMap::default();
2269 if !self.scripts.is_empty() {
2270 for i in index..self.glyphs.len() {
2271 self.scripts
2272 .remove_entry(&i)
2273 .map(|(k, v)| next_scripts.insert(k - index, v));
2274 }
2275 }
2276 let next_glyphs = self.glyphs.split_off(index);
2277 let next_width = self.width - width;
2278 self.width = width;
2279 RenderPlan {
2280 width: next_width,
2281 scripts: next_scripts,
2282 glyphs: next_glyphs,
2283 }
2284 }
2285
2286 pub fn index_from_advance(&self, advance: i32) -> usize {
2287 let mut sum = 0;
2288 let mut index = 0;
2289 while index < self.glyphs.len() {
2290 let gad = self.glyph_advance(index);
2291 sum += gad;
2292 if sum > advance {
2293 if sum - advance < advance - sum + gad {
2294 index += 1;
2295 }
2296 break;
2297 }
2298 index += 1;
2299 }
2300 index
2301 }
2302
2303 pub fn append(&mut self, other: &mut Self) {
2304 let next_index = self.glyphs.len();
2305 self.scripts
2306 .extend(other.scripts.iter().map(|(k, v)| (next_index + k, *v)));
2307 self.glyphs.append(&mut other.glyphs);
2308 self.width += other.width;
2309 }
2310
2311 pub fn total_advance(&self, index: usize) -> i32 {
2312 self.glyphs.iter().take(index).map(|g| g.advance.x).sum()
2313 }
2314
2315 #[inline]
2316 pub fn glyph_advance(&self, index: usize) -> i32 {
2317 self.glyphs[index].advance.x
2318 }
2319}
2320
2321impl Drop for FontLibrary {
2322 fn drop(&mut self) {
2323 unsafe {
2324 FT_Done_FreeType(self.0);
2325 }
2326 }
2327}
2328
2329impl Drop for Font {
2330 fn drop(&mut self) {
2331 unsafe {
2332 FT_Done_Face(self.face);
2333 if !self.font.is_null() {
2334 hb_font_destroy(self.font);
2335 }
2336 }
2337 }
2338}
2339
2340#[inline]
2341fn tag(c1: u8, c2: u8, c3: u8, c4: u8) -> u32 {
2342 ((c1 as u32) << 24) | ((c2 as u32) << 16) | ((c3 as u32) << 8) | c4 as u32
2343}
2344
2345#[derive(Error, Debug)]
2346enum FreetypeError {
2347 #[error("Unknown error with code {0}.")]
2348 UnknownError(FtError),
2349
2350 #[error("Cannot open resource.")]
2351 CannotOpenResource,
2352
2353 #[error("Unknown file format.")]
2354 UnknownFileFormat,
2355
2356 #[error("Broken file.")]
2357 InvalidFileFormat,
2358
2359 #[error("Invalid FreeType version.")]
2360 InvalidVersion,
2361
2362 #[error("Module version is too low.")]
2363 LowerModuleVersion,
2364
2365 #[error("Invalid argument.")]
2366 InvalidArgument,
2367
2368 #[error("Unimplemented feature.")]
2369 UnimplementedFeature,
2370
2371 #[error("Broken table.")]
2372 InvalidTable,
2373
2374 #[error("Broken offset within table.")]
2375 InvalidOffset,
2376
2377 #[error("Array allocation size too large.")]
2378 ArrayTooLarge,
2379
2380 #[error("Missing module.")]
2381 MissingModule,
2382
2383 #[error("Missing property.")]
2384 MissingProperty,
2385
2386 #[error("Invalid glyph index.")]
2387 InvalidGlyphIndex,
2388
2389 #[error("Invalid character code.")]
2390 InvalidCharacterCode,
2391
2392 #[error("Unsupported glyph image format.")]
2393 InvalidGlyphFormat,
2394
2395 #[error("Cannot render this glyph format.")]
2396 CannotRenderGlyph,
2397
2398 #[error("Invalid outline.")]
2399 InvalidOutline,
2400
2401 #[error("Invalid composite glyph.")]
2402 InvalidComposite,
2403
2404 #[error("Too many hints.")]
2405 TooManyHints,
2406
2407 #[error("Invalid pixel size.")]
2408 InvalidPixelSize,
2409
2410 #[error("Invalid object handle.")]
2411 InvalidHandle,
2412
2413 #[error("Invalid library handle.")]
2414 InvalidLibraryHandle,
2415
2416 #[error("Invalid module handle.")]
2417 InvalidDriverHandle,
2418
2419 #[error("Invalid face handle.")]
2420 InvalidFaceHandle,
2421
2422 #[error("Invalid size handle.")]
2423 InvalidSizeHandle,
2424
2425 #[error("Invalid glyph slot handle.")]
2426 InvalidSlotHandle,
2427
2428 #[error("Invalid charmap handle.")]
2429 InvalidCharMapHandle,
2430
2431 #[error("Invalid cache manager handle.")]
2432 InvalidCacheHandle,
2433
2434 #[error("Invalid stream handle.")]
2435 InvalidStreamHandle,
2436
2437 #[error("Too many modules.")]
2438 TooManyDrivers,
2439
2440 #[error("Too many extensions.")]
2441 TooManyExtensions,
2442
2443 #[error("Out of memory.")]
2444 OutOfMemory,
2445
2446 #[error("Unlisted object.")]
2447 UnlistedObject,
2448
2449 #[error("Cannot open stream.")]
2450 CannotOpenStream,
2451
2452 #[error("Invalid stream seek.")]
2453 InvalidStreamSeek,
2454
2455 #[error("Invalid stream skip.")]
2456 InvalidStreamSkip,
2457
2458 #[error("Invalid stream read.")]
2459 InvalidStreamRead,
2460
2461 #[error("Invalid stream operation.")]
2462 InvalidStreamOperation,
2463
2464 #[error("Invalid frame operation.")]
2465 InvalidFrameOperation,
2466
2467 #[error("Nested frame access.")]
2468 NestedFrameAccess,
2469
2470 #[error("Invalid frame read.")]
2471 InvalidFrameRead,
2472
2473 #[error("Raster uninitialized.")]
2474 RasterUninitialized,
2475
2476 #[error("Raster corrupted.")]
2477 RasterCorrupted,
2478
2479 #[error("Raster overflow.")]
2480 RasterOverflow,
2481
2482 #[error("Negative height while rastering.")]
2483 RasterNegativeHeight,
2484
2485 #[error("Too many registered caches.")]
2486 TooManyCaches,
2487
2488 #[error("Invalid opcode.")]
2489 InvalidOpcode,
2490
2491 #[error("Too few arguments.")]
2492 TooFewArguments,
2493
2494 #[error("Stack overflow.")]
2495 StackOverflow,
2496
2497 #[error("Code overflow.")]
2498 CodeOverflow,
2499
2500 #[error("Bad argument.")]
2501 BadArgument,
2502
2503 #[error("Division by zero.")]
2504 DivideByZero,
2505
2506 #[error("Invalid reference.")]
2507 InvalidReference,
2508
2509 #[error("Found debug opcode.")]
2510 DebugOpCode,
2511
2512 #[error("Found ENDF opcode in execution stream.")]
2513 ENDFInExecStream,
2514
2515 #[error("Nested DEFS.")]
2516 NestedDEFS,
2517
2518 #[error("Invalid code range.")]
2519 InvalidCodeRange,
2520
2521 #[error("Execution context too long.")]
2522 ExecutionTooLong,
2523
2524 #[error("Too many function definitions.")]
2525 TooManyFunctionDefs,
2526
2527 #[error("Too many instruction definitions.")]
2528 TooManyInstructionDefs,
2529
2530 #[error("SFNT font table missing.")]
2531 TableMissing,
2532
2533 #[error("Horizontal header (hhea) table missing.")]
2534 HorizHeaderMissing,
2535
2536 #[error("Locations (loca) table missing.")]
2537 LocationsMissing,
2538
2539 #[error("Name table missing.")]
2540 NameTableMissing,
2541
2542 #[error("Character map (cmap) table missing.")]
2543 CMapTableMissing,
2544
2545 #[error("Horizontal metrics (hmtx) table missing.")]
2546 HmtxTableMissing,
2547
2548 #[error("PostScript (post) table missing.")]
2549 PostTableMissing,
2550
2551 #[error("Invalid horizontal metrics.")]
2552 InvalidHorizMetrics,
2553
2554 #[error("Invalid character map (cmap) format.")]
2555 InvalidCharMapFormat,
2556
2557 #[error("Invalid ppem value.")]
2558 InvalidPPem,
2559
2560 #[error("Invalid vertical metrics.")]
2561 InvalidVertMetrics,
2562
2563 #[error("Could not find context.")]
2564 CouldNotFindContext,
2565
2566 #[error("Invalid PostScript (post) table format.")]
2567 InvalidPostTableFormat,
2568
2569 #[error("Invalid PostScript (post) table.")]
2570 InvalidPostTable,
2571
2572 #[error("Found FDEF or IDEF opcode in glyf bytecode.")]
2573 DEFInGlyfBytecode,
2574
2575 #[error("Missing bitmap in strike.")]
2576 MissingBitmap,
2577
2578 #[error("Opcode syntax error.")]
2579 SyntaxError,
2580
2581 #[error("Argument stack underflow.")]
2582 StackUnderflow,
2583
2584 #[error("Ignore.")]
2585 Ignore,
2586
2587 #[error("No Unicode glyph name found.")]
2588 NoUnicodeGlyphName,
2589
2590 #[error("Glyph too big for hinting.")]
2591 GlyphTooBig,
2592
2593 #[error("`STARTFONT' field missing.")]
2594 MissingStartfontField,
2595
2596 #[error("`FONT' field missing.")]
2597 MissingFontField,
2598
2599 #[error("`SIZE' field missing.")]
2600 MissingSizeField,
2601
2602 #[error("`FONTBOUNDINGBOX' field missing.")]
2603 MissingFontboundingboxField,
2604
2605 #[error("`CHARS' field missing.")]
2606 MissingCharsField,
2607
2608 #[error("`STARTCHAR' field missing.")]
2609 MissingStartcharField,
2610
2611 #[error("`ENCODING' field missing.")]
2612 MissingEncodingField,
2613
2614 #[error("`BBX' field missing.")]
2615 MissingBbxField,
2616
2617 #[error("`BBX' too big.")]
2618 BbxTooBig,
2619
2620 #[error("Font header corrupted or missing fields.")]
2621 CorruptedFontHeader,
2622
2623 #[error("Font glyphs corrupted or missing fields.")]
2624 CorruptedFontGlyphs,
2625}
2626
2627impl From<FtError> for FreetypeError {
2628 fn from(code: FtError) -> FreetypeError {
2629 match code {
2630 0x01 => FreetypeError::CannotOpenResource,
2631 0x02 => FreetypeError::UnknownFileFormat,
2632 0x03 => FreetypeError::InvalidFileFormat,
2633 0x04 => FreetypeError::InvalidVersion,
2634 0x05 => FreetypeError::LowerModuleVersion,
2635 0x06 => FreetypeError::InvalidArgument,
2636 0x07 => FreetypeError::UnimplementedFeature,
2637 0x08 => FreetypeError::InvalidTable,
2638 0x09 => FreetypeError::InvalidOffset,
2639 0x0A => FreetypeError::ArrayTooLarge,
2640 0x0B => FreetypeError::MissingModule,
2641 0x0C => FreetypeError::MissingProperty,
2642 0x10 => FreetypeError::InvalidGlyphIndex,
2643 0x11 => FreetypeError::InvalidCharacterCode,
2644 0x12 => FreetypeError::InvalidGlyphFormat,
2645 0x13 => FreetypeError::CannotRenderGlyph,
2646 0x14 => FreetypeError::InvalidOutline,
2647 0x15 => FreetypeError::InvalidComposite,
2648 0x16 => FreetypeError::TooManyHints,
2649 0x17 => FreetypeError::InvalidPixelSize,
2650 0x20 => FreetypeError::InvalidHandle,
2651 0x21 => FreetypeError::InvalidLibraryHandle,
2652 0x22 => FreetypeError::InvalidDriverHandle,
2653 0x23 => FreetypeError::InvalidFaceHandle,
2654 0x24 => FreetypeError::InvalidSizeHandle,
2655 0x25 => FreetypeError::InvalidSlotHandle,
2656 0x26 => FreetypeError::InvalidCharMapHandle,
2657 0x27 => FreetypeError::InvalidCacheHandle,
2658 0x28 => FreetypeError::InvalidStreamHandle,
2659 0x30 => FreetypeError::TooManyDrivers,
2660 0x31 => FreetypeError::TooManyExtensions,
2661 0x40 => FreetypeError::OutOfMemory,
2662 0x41 => FreetypeError::UnlistedObject,
2663 0x51 => FreetypeError::CannotOpenStream,
2664 0x52 => FreetypeError::InvalidStreamSeek,
2665 0x53 => FreetypeError::InvalidStreamSkip,
2666 0x54 => FreetypeError::InvalidStreamRead,
2667 0x55 => FreetypeError::InvalidStreamOperation,
2668 0x56 => FreetypeError::InvalidFrameOperation,
2669 0x57 => FreetypeError::NestedFrameAccess,
2670 0x58 => FreetypeError::InvalidFrameRead,
2671 0x60 => FreetypeError::RasterUninitialized,
2672 0x61 => FreetypeError::RasterCorrupted,
2673 0x62 => FreetypeError::RasterOverflow,
2674 0x63 => FreetypeError::RasterNegativeHeight,
2675 0x70 => FreetypeError::TooManyCaches,
2676 0x80 => FreetypeError::InvalidOpcode,
2677 0x81 => FreetypeError::TooFewArguments,
2678 0x82 => FreetypeError::StackOverflow,
2679 0x83 => FreetypeError::CodeOverflow,
2680 0x84 => FreetypeError::BadArgument,
2681 0x85 => FreetypeError::DivideByZero,
2682 0x86 => FreetypeError::InvalidReference,
2683 0x87 => FreetypeError::DebugOpCode,
2684 0x88 => FreetypeError::ENDFInExecStream,
2685 0x89 => FreetypeError::NestedDEFS,
2686 0x8A => FreetypeError::InvalidCodeRange,
2687 0x8B => FreetypeError::ExecutionTooLong,
2688 0x8C => FreetypeError::TooManyFunctionDefs,
2689 0x8D => FreetypeError::TooManyInstructionDefs,
2690 0x8E => FreetypeError::TableMissing,
2691 0x8F => FreetypeError::HorizHeaderMissing,
2692 0x90 => FreetypeError::LocationsMissing,
2693 0x91 => FreetypeError::NameTableMissing,
2694 0x92 => FreetypeError::CMapTableMissing,
2695 0x93 => FreetypeError::HmtxTableMissing,
2696 0x94 => FreetypeError::PostTableMissing,
2697 0x95 => FreetypeError::InvalidHorizMetrics,
2698 0x96 => FreetypeError::InvalidCharMapFormat,
2699 0x97 => FreetypeError::InvalidPPem,
2700 0x98 => FreetypeError::InvalidVertMetrics,
2701 0x99 => FreetypeError::CouldNotFindContext,
2702 0x9A => FreetypeError::InvalidPostTableFormat,
2703 0x9B => FreetypeError::InvalidPostTable,
2704 0x9C => FreetypeError::DEFInGlyfBytecode,
2705 0x9D => FreetypeError::MissingBitmap,
2706 0xA0 => FreetypeError::SyntaxError,
2707 0xA1 => FreetypeError::StackUnderflow,
2708 0xA2 => FreetypeError::Ignore,
2709 0xA3 => FreetypeError::NoUnicodeGlyphName,
2710 0xA4 => FreetypeError::GlyphTooBig,
2711 0xB0 => FreetypeError::MissingStartfontField,
2712 0xB1 => FreetypeError::MissingFontField,
2713 0xB2 => FreetypeError::MissingSizeField,
2714 0xB3 => FreetypeError::MissingFontboundingboxField,
2715 0xB4 => FreetypeError::MissingCharsField,
2716 0xB5 => FreetypeError::MissingStartcharField,
2717 0xB6 => FreetypeError::MissingEncodingField,
2718 0xB7 => FreetypeError::MissingBbxField,
2719 0xB8 => FreetypeError::BbxTooBig,
2720 0xB9 => FreetypeError::CorruptedFontHeader,
2721 0xBA => FreetypeError::CorruptedFontGlyphs,
2722 _ => FreetypeError::UnknownError(code),
2723 }
2724 }
2725}