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::{Error, format_err};
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")]
105unsafe extern "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")]
272unsafe extern "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 CURRENT_DEVICE.install_path("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 unsafe {
789 #[cfg(any(not(target_os = "linux"), target_arch = "arm"))]
791 match script {
792 HB_SCRIPT_HANGUL | HB_SCRIPT_HIRAGANA | HB_SCRIPT_KATAKANA | HB_SCRIPT_BOPOMOFO
793 | HB_SCRIPT_HAN => &_binary_DroidSansFallback_ttf,
794
795 HB_SCRIPT_ARABIC => &_binary_NotoNaskhArabic_Regular_otf,
796 HB_SCRIPT_SYRIAC => &_binary_NotoSansSyriac_Regular_otf,
797 HB_SCRIPT_MEROITIC_CURSIVE | HB_SCRIPT_MEROITIC_HIEROGLYPHS => {
798 &_binary_NotoSansMeroitic_Regular_otf
799 }
800
801 HB_SCRIPT_ADLAM => &_binary_NotoSansAdlam_Regular_otf,
802 HB_SCRIPT_AHOM => &_binary_NotoSerifAhom_Regular_otf,
803 HB_SCRIPT_ANATOLIAN_HIEROGLYPHS => &_binary_NotoSansAnatolianHieroglyphs_Regular_otf,
804 HB_SCRIPT_ARMENIAN => &_binary_NotoSerifArmenian_Regular_otf,
805 HB_SCRIPT_AVESTAN => &_binary_NotoSansAvestan_Regular_otf,
806 HB_SCRIPT_BALINESE => &_binary_NotoSerifBalinese_Regular_otf,
807 HB_SCRIPT_BAMUM => &_binary_NotoSansBamum_Regular_otf,
808 HB_SCRIPT_BASSA_VAH => &_binary_NotoSansBassaVah_Regular_otf,
809 HB_SCRIPT_BATAK => &_binary_NotoSansBatak_Regular_otf,
810 HB_SCRIPT_BENGALI => &_binary_NotoSerifBengali_Regular_otf,
811 HB_SCRIPT_BHAIKSUKI => &_binary_NotoSansBhaiksuki_Regular_otf,
812 HB_SCRIPT_BRAHMI => &_binary_NotoSansBrahmi_Regular_otf,
813 HB_SCRIPT_BUGINESE => &_binary_NotoSansBuginese_Regular_otf,
814 HB_SCRIPT_BUHID => &_binary_NotoSansBuhid_Regular_otf,
815 HB_SCRIPT_CANADIAN_SYLLABICS => &_binary_NotoSansCanadianAboriginal_Regular_otf,
816 HB_SCRIPT_CARIAN => &_binary_NotoSansCarian_Regular_otf,
817 HB_SCRIPT_CAUCASIAN_ALBANIAN => &_binary_NotoSansCaucasianAlbanian_Regular_otf,
818 HB_SCRIPT_CHAKMA => &_binary_NotoSansChakma_Regular_otf,
819 HB_SCRIPT_CHAM => &_binary_NotoSansCham_Regular_otf,
820 HB_SCRIPT_CHEROKEE => &_binary_NotoSansCherokee_Regular_otf,
821 HB_SCRIPT_CHORASMIAN => &_binary_NotoSansChorasmian_Regular_otf,
822 HB_SCRIPT_COPTIC => &_binary_NotoSansCoptic_Regular_otf,
823 HB_SCRIPT_CUNEIFORM => &_binary_NotoSansCuneiform_Regular_otf,
824 HB_SCRIPT_CYPRIOT => &_binary_NotoSansCypriot_Regular_otf,
825 HB_SCRIPT_CYPRO_MINOAN => &_binary_NotoSansCyproMinoan_Regular_otf,
826 HB_SCRIPT_DESERET => &_binary_NotoSansDeseret_Regular_otf,
827 HB_SCRIPT_DEVANAGARI => &_binary_NotoSerifDevanagari_Regular_otf,
828 HB_SCRIPT_DIVES_AKURU => &_binary_NotoSerifDivesAkuru_Regular_otf,
829 HB_SCRIPT_DOGRA => &_binary_NotoSerifDogra_Regular_otf,
830 HB_SCRIPT_DUPLOYAN => &_binary_NotoSansDuployan_Regular_otf,
831 HB_SCRIPT_EGYPTIAN_HIEROGLYPHS => &_binary_NotoSansEgyptianHieroglyphs_Regular_otf,
832 HB_SCRIPT_ELBASAN => &_binary_NotoSansElbasan_Regular_otf,
833 HB_SCRIPT_ELYMAIC => &_binary_NotoSansElymaic_Regular_otf,
834 HB_SCRIPT_ETHIOPIC => &_binary_NotoSerifEthiopic_Regular_otf,
835 HB_SCRIPT_GEORGIAN => &_binary_NotoSerifGeorgian_Regular_otf,
836 HB_SCRIPT_GLAGOLITIC => &_binary_NotoSansGlagolitic_Regular_otf,
837 HB_SCRIPT_GOTHIC => &_binary_NotoSansGothic_Regular_otf,
838 HB_SCRIPT_GRANTHA => &_binary_NotoSerifGrantha_Regular_otf,
839 HB_SCRIPT_GUJARATI => &_binary_NotoSerifGujarati_Regular_otf,
840 HB_SCRIPT_GUNJALA_GONDI => &_binary_NotoSansGunjalaGondi_Regular_otf,
841 HB_SCRIPT_GURMUKHI => &_binary_NotoSerifGurmukhi_Regular_otf,
842 HB_SCRIPT_HANIFI_ROHINGYA => &_binary_NotoSansHanifiRohingya_Regular_otf,
843 HB_SCRIPT_HANUNOO => &_binary_NotoSansHanunoo_Regular_otf,
844 HB_SCRIPT_HATRAN => &_binary_NotoSansHatran_Regular_otf,
845 HB_SCRIPT_HEBREW => &_binary_NotoSerifHebrew_Regular_otf,
846 HB_SCRIPT_IMPERIAL_ARAMAIC => &_binary_NotoSansImperialAramaic_Regular_otf,
847 HB_SCRIPT_INSCRIPTIONAL_PAHLAVI => &_binary_NotoSansInscriptionalPahlavi_Regular_otf,
848 HB_SCRIPT_INSCRIPTIONAL_PARTHIAN => &_binary_NotoSansInscriptionalParthian_Regular_otf,
849 HB_SCRIPT_JAVANESE => &_binary_NotoSansJavanese_Regular_otf,
850 HB_SCRIPT_KAITHI => &_binary_NotoSansKaithi_Regular_otf,
851 HB_SCRIPT_KANNADA => &_binary_NotoSerifKannada_Regular_otf,
852 HB_SCRIPT_KAWI => &_binary_NotoSansKawi_Regular_otf,
853 HB_SCRIPT_KAYAH_LI => &_binary_NotoSansKayahLi_Regular_otf,
854 HB_SCRIPT_KHAROSHTHI => &_binary_NotoSansKharoshthi_Regular_otf,
855 HB_SCRIPT_KHITAN_SMALL_SCRIPT => &_binary_NotoSerifKhitanSmallScript_Regular_otf,
856 HB_SCRIPT_KHMER => &_binary_NotoSerifKhmer_Regular_otf,
857 HB_SCRIPT_KHOJKI => &_binary_NotoSerifKhojki_Regular_otf,
858 HB_SCRIPT_KHUDAWADI => &_binary_NotoSansKhudawadi_Regular_otf,
859 HB_SCRIPT_LAO => &_binary_NotoSerifLao_Regular_otf,
860 HB_SCRIPT_LEPCHA => &_binary_NotoSansLepcha_Regular_otf,
861 HB_SCRIPT_LIMBU => &_binary_NotoSansLimbu_Regular_otf,
862 HB_SCRIPT_LINEAR_A => &_binary_NotoSansLinearA_Regular_otf,
863 HB_SCRIPT_LINEAR_B => &_binary_NotoSansLinearB_Regular_otf,
864 HB_SCRIPT_LISU => &_binary_NotoSansLisu_Regular_otf,
865 HB_SCRIPT_LYCIAN => &_binary_NotoSansLycian_Regular_otf,
866 HB_SCRIPT_LYDIAN => &_binary_NotoSansLydian_Regular_otf,
867 HB_SCRIPT_MAHAJANI => &_binary_NotoSansMahajani_Regular_otf,
868 HB_SCRIPT_MAKASAR => &_binary_NotoSerifMakasar_Regular_otf,
869 HB_SCRIPT_MALAYALAM => &_binary_NotoSerifMalayalam_Regular_otf,
870 HB_SCRIPT_MANDAIC => &_binary_NotoSansMandaic_Regular_otf,
871 HB_SCRIPT_MANICHAEAN => &_binary_NotoSansManichaean_Regular_otf,
872 HB_SCRIPT_MARCHEN => &_binary_NotoSansMarchen_Regular_otf,
873 HB_SCRIPT_MASARAM_GONDI => &_binary_NotoSansMasaramGondi_Regular_otf,
874 HB_SCRIPT_MEDEFAIDRIN => &_binary_NotoSansMedefaidrin_Regular_otf,
875 HB_SCRIPT_MEETEI_MAYEK => &_binary_NotoSansMeeteiMayek_Regular_otf,
876 HB_SCRIPT_MENDE_KIKAKUI => &_binary_NotoSansMendeKikakui_Regular_otf,
877 HB_SCRIPT_MIAO => &_binary_NotoSansMiao_Regular_otf,
878 HB_SCRIPT_MODI => &_binary_NotoSansModi_Regular_otf,
879 HB_SCRIPT_MONGOLIAN => &_binary_NotoSansMongolian_Regular_otf,
880 HB_SCRIPT_MRO => &_binary_NotoSansMro_Regular_otf,
881 HB_SCRIPT_MULTANI => &_binary_NotoSansMultani_Regular_otf,
882 HB_SCRIPT_MYANMAR => &_binary_NotoSerifMyanmar_Regular_otf,
883 HB_SCRIPT_NABATAEAN => &_binary_NotoSansNabataean_Regular_otf,
884 HB_SCRIPT_NAG_MUNDARI => &_binary_NotoSansNagMundari_Regular_otf,
885 HB_SCRIPT_NANDINAGARI => &_binary_NotoSansNandinagari_Regular_otf,
886 HB_SCRIPT_NEWA => &_binary_NotoSansNewa_Regular_otf,
887 HB_SCRIPT_NEW_TAI_LUE => &_binary_NotoSansNewTaiLue_Regular_otf,
888 HB_SCRIPT_NKO => &_binary_NotoSansNKo_Regular_otf,
889 HB_SCRIPT_NUSHU => &_binary_NotoSansNushu_Regular_otf,
890 HB_SCRIPT_NYIAKENG_PUACHUE_HMONG => &_binary_NotoSerifNyiakengPuachueHmong_Regular_otf,
891 HB_SCRIPT_OGHAM => &_binary_NotoSansOgham_Regular_otf,
892 HB_SCRIPT_OLD_HUNGARIAN => &_binary_NotoSansOldHungarian_Regular_otf,
893 HB_SCRIPT_OLD_ITALIC => &_binary_NotoSansOldItalic_Regular_otf,
894 HB_SCRIPT_OLD_NORTH_ARABIAN => &_binary_NotoSansOldNorthArabian_Regular_otf,
895 HB_SCRIPT_OLD_PERMIC => &_binary_NotoSansOldPermic_Regular_otf,
896 HB_SCRIPT_OLD_PERSIAN => &_binary_NotoSansOldPersian_Regular_otf,
897 HB_SCRIPT_OLD_SOGDIAN => &_binary_NotoSansOldSogdian_Regular_otf,
898 HB_SCRIPT_OLD_SOUTH_ARABIAN => &_binary_NotoSansOldSouthArabian_Regular_otf,
899 HB_SCRIPT_OLD_TURKIC => &_binary_NotoSansOldTurkic_Regular_otf,
900 HB_SCRIPT_OLD_UYGHUR => &_binary_NotoSerifOldUyghur_Regular_otf,
901 HB_SCRIPT_OL_CHIKI => &_binary_NotoSansOlChiki_Regular_otf,
902 HB_SCRIPT_ORIYA => &_binary_NotoSerifOriya_Regular_otf,
903 HB_SCRIPT_OSAGE => &_binary_NotoSansOsage_Regular_otf,
904 HB_SCRIPT_OSMANYA => &_binary_NotoSansOsmanya_Regular_otf,
905 HB_SCRIPT_PAHAWH_HMONG => &_binary_NotoSansPahawhHmong_Regular_otf,
906 HB_SCRIPT_PALMYRENE => &_binary_NotoSansPalmyrene_Regular_otf,
907 HB_SCRIPT_PAU_CIN_HAU => &_binary_NotoSansPauCinHau_Regular_otf,
908 HB_SCRIPT_PHAGS_PA => &_binary_NotoSansPhagsPa_Regular_otf,
909 HB_SCRIPT_PHOENICIAN => &_binary_NotoSansPhoenician_Regular_otf,
910 HB_SCRIPT_PSALTER_PAHLAVI => &_binary_NotoSansPsalterPahlavi_Regular_otf,
911 HB_SCRIPT_REJANG => &_binary_NotoSansRejang_Regular_otf,
912 HB_SCRIPT_RUNIC => &_binary_NotoSansRunic_Regular_otf,
913 HB_SCRIPT_SAMARITAN => &_binary_NotoSansSamaritan_Regular_otf,
914 HB_SCRIPT_SAURASHTRA => &_binary_NotoSansSaurashtra_Regular_otf,
915 HB_SCRIPT_SHARADA => &_binary_NotoSansSharada_Regular_otf,
916 HB_SCRIPT_SHAVIAN => &_binary_NotoSansShavian_Regular_otf,
917 HB_SCRIPT_SIDDHAM => &_binary_NotoSansSiddham_Regular_otf,
918 HB_SCRIPT_SIGNWRITING => &_binary_NotoSansSignWriting_Regular_otf,
919 HB_SCRIPT_SINHALA => &_binary_NotoSerifSinhala_Regular_otf,
920 HB_SCRIPT_SOGDIAN => &_binary_NotoSansSogdian_Regular_otf,
921 HB_SCRIPT_SORA_SOMPENG => &_binary_NotoSansSoraSompeng_Regular_otf,
922 HB_SCRIPT_SOYOMBO => &_binary_NotoSansSoyombo_Regular_otf,
923 HB_SCRIPT_SUNDANESE => &_binary_NotoSansSundanese_Regular_otf,
924 HB_SCRIPT_SYLOTI_NAGRI => &_binary_NotoSansSylotiNagri_Regular_otf,
925 HB_SCRIPT_TAGALOG => &_binary_NotoSansTagalog_Regular_otf,
926 HB_SCRIPT_TAGBANWA => &_binary_NotoSansTagbanwa_Regular_otf,
927 HB_SCRIPT_TAI_LE => &_binary_NotoSansTaiLe_Regular_otf,
928 HB_SCRIPT_TAI_THAM => &_binary_NotoSansTaiTham_Regular_otf,
929 HB_SCRIPT_TAI_VIET => &_binary_NotoSansTaiViet_Regular_otf,
930 HB_SCRIPT_TAKRI => &_binary_NotoSansTakri_Regular_otf,
931 HB_SCRIPT_TAMIL => &_binary_NotoSerifTamil_Regular_otf,
932 HB_SCRIPT_TANGSA => &_binary_NotoSansTangsa_Regular_otf,
933 HB_SCRIPT_TELUGU => &_binary_NotoSerifTelugu_Regular_otf,
934 HB_SCRIPT_THAANA => &_binary_NotoSansThaana_Regular_otf,
935 HB_SCRIPT_THAI => &_binary_NotoSerifThai_Regular_otf,
936 HB_SCRIPT_TIBETAN => &_binary_NotoSerifTibetan_Regular_otf,
937 HB_SCRIPT_TIFINAGH => &_binary_NotoSansTifinagh_Regular_otf,
938 HB_SCRIPT_TIRHUTA => &_binary_NotoSansTirhuta_Regular_otf,
939 HB_SCRIPT_TOTO => &_binary_NotoSerifToto_Regular_otf,
940 HB_SCRIPT_UGARITIC => &_binary_NotoSansUgaritic_Regular_otf,
941 HB_SCRIPT_VAI => &_binary_NotoSansVai_Regular_otf,
942 HB_SCRIPT_VITHKUQI => &_binary_NotoSerifVithkuqi_Regular_otf,
943 HB_SCRIPT_WANCHO => &_binary_NotoSansWancho_Regular_otf,
944 HB_SCRIPT_WARANG_CITI => &_binary_NotoSansWarangCiti_Regular_otf,
945 HB_SCRIPT_YEZIDI => &_binary_NotoSerifYezidi_Regular_otf,
946 HB_SCRIPT_YI => &_binary_NotoSansYi_Regular_otf,
947 HB_SCRIPT_ZANABAZAR_SQUARE => &_binary_NotoSansZanabazarSquare_Regular_otf,
948
949 HB_SYMBOL_MATHS => &_binary_NotoSansMath_Regular_otf,
950 HB_SYMBOL_MUSIC => &_binary_NotoMusic_Regular_otf,
951 HB_SYMBOL_MISC_ONE => &_binary_NotoSansSymbols_Regular_otf,
952 HB_SCRIPT_BRAILLE | HB_SYMBOL_MISC_TWO => &_binary_NotoSansSymbols2_Regular_otf,
953 HB_SYMBOL_EMOJI => &_binary_NotoEmoji_Regular_ttf,
954
955 _ => &_binary_DroidSansFallback_ttf,
956 }
957
958 #[cfg(all(target_os = "linux", not(target_arch = "arm")))]
959 match script {
960 HB_SCRIPT_HANGUL | HB_SCRIPT_HIRAGANA | HB_SCRIPT_KATAKANA | HB_SCRIPT_BOPOMOFO
961 | HB_SCRIPT_HAN => &_binary_resources_fonts_droid_DroidSansFallback_ttf_start,
962
963 HB_SCRIPT_ARABIC => &_binary_resources_fonts_noto_NotoNaskhArabic_Regular_otf_start,
964 HB_SCRIPT_SYRIAC => &_binary_resources_fonts_noto_NotoSansSyriac_Regular_otf_start,
965 HB_SCRIPT_MEROITIC_CURSIVE | HB_SCRIPT_MEROITIC_HIEROGLYPHS => {
966 &_binary_resources_fonts_noto_NotoSansMeroitic_Regular_otf_start
967 }
968
969 HB_SCRIPT_ADLAM => &_binary_resources_fonts_noto_NotoSansAdlam_Regular_otf_start,
970 HB_SCRIPT_AHOM => &_binary_resources_fonts_noto_NotoSerifAhom_Regular_otf_start,
971 HB_SCRIPT_ANATOLIAN_HIEROGLYPHS => {
972 &_binary_resources_fonts_noto_NotoSansAnatolianHieroglyphs_Regular_otf_start
973 }
974 HB_SCRIPT_ARMENIAN => &_binary_resources_fonts_noto_NotoSerifArmenian_Regular_otf_start,
975 HB_SCRIPT_AVESTAN => &_binary_resources_fonts_noto_NotoSansAvestan_Regular_otf_start,
976 HB_SCRIPT_BALINESE => &_binary_resources_fonts_noto_NotoSerifBalinese_Regular_otf_start,
977 HB_SCRIPT_BAMUM => &_binary_resources_fonts_noto_NotoSansBamum_Regular_otf_start,
978 HB_SCRIPT_BASSA_VAH => &_binary_resources_fonts_noto_NotoSansBassaVah_Regular_otf_start,
979 HB_SCRIPT_BATAK => &_binary_resources_fonts_noto_NotoSansBatak_Regular_otf_start,
980 HB_SCRIPT_BENGALI => &_binary_resources_fonts_noto_NotoSerifBengali_Regular_otf_start,
981 HB_SCRIPT_BHAIKSUKI => {
982 &_binary_resources_fonts_noto_NotoSansBhaiksuki_Regular_otf_start
983 }
984 HB_SCRIPT_BRAHMI => &_binary_resources_fonts_noto_NotoSansBrahmi_Regular_otf_start,
985 HB_SCRIPT_BUGINESE => &_binary_resources_fonts_noto_NotoSansBuginese_Regular_otf_start,
986 HB_SCRIPT_BUHID => &_binary_resources_fonts_noto_NotoSansBuhid_Regular_otf_start,
987 HB_SCRIPT_CANADIAN_SYLLABICS => {
988 &_binary_resources_fonts_noto_NotoSansCanadianAboriginal_Regular_otf_start
989 }
990 HB_SCRIPT_CARIAN => &_binary_resources_fonts_noto_NotoSansCarian_Regular_otf_start,
991 HB_SCRIPT_CAUCASIAN_ALBANIAN => {
992 &_binary_resources_fonts_noto_NotoSansCaucasianAlbanian_Regular_otf_start
993 }
994 HB_SCRIPT_CHAKMA => &_binary_resources_fonts_noto_NotoSansChakma_Regular_otf_start,
995 HB_SCRIPT_CHAM => &_binary_resources_fonts_noto_NotoSansCham_Regular_otf_start,
996 HB_SCRIPT_CHEROKEE => &_binary_resources_fonts_noto_NotoSansCherokee_Regular_otf_start,
997 HB_SCRIPT_CHORASMIAN => {
998 &_binary_resources_fonts_noto_NotoSansChorasmian_Regular_otf_start
999 }
1000 HB_SCRIPT_COPTIC => &_binary_resources_fonts_noto_NotoSansCoptic_Regular_otf_start,
1001 HB_SCRIPT_CUNEIFORM => {
1002 &_binary_resources_fonts_noto_NotoSansCuneiform_Regular_otf_start
1003 }
1004 HB_SCRIPT_CYPRIOT => &_binary_resources_fonts_noto_NotoSansCypriot_Regular_otf_start,
1005 HB_SCRIPT_CYPRO_MINOAN => {
1006 &_binary_resources_fonts_noto_NotoSansCyproMinoan_Regular_otf_start
1007 }
1008 HB_SCRIPT_DESERET => &_binary_resources_fonts_noto_NotoSansDeseret_Regular_otf_start,
1009 HB_SCRIPT_DEVANAGARI => {
1010 &_binary_resources_fonts_noto_NotoSerifDevanagari_Regular_otf_start
1011 }
1012 HB_SCRIPT_DIVES_AKURU => {
1013 &_binary_resources_fonts_noto_NotoSerifDivesAkuru_Regular_otf_start
1014 }
1015 HB_SCRIPT_DOGRA => &_binary_resources_fonts_noto_NotoSerifDogra_Regular_otf_start,
1016 HB_SCRIPT_DUPLOYAN => &_binary_resources_fonts_noto_NotoSansDuployan_Regular_otf_start,
1017 HB_SCRIPT_EGYPTIAN_HIEROGLYPHS => {
1018 &_binary_resources_fonts_noto_NotoSansEgyptianHieroglyphs_Regular_otf_start
1019 }
1020 HB_SCRIPT_ELBASAN => &_binary_resources_fonts_noto_NotoSansElbasan_Regular_otf_start,
1021 HB_SCRIPT_ELYMAIC => &_binary_resources_fonts_noto_NotoSansElymaic_Regular_otf_start,
1022 HB_SCRIPT_ETHIOPIC => &_binary_resources_fonts_noto_NotoSerifEthiopic_Regular_otf_start,
1023 HB_SCRIPT_GEORGIAN => &_binary_resources_fonts_noto_NotoSerifGeorgian_Regular_otf_start,
1024 HB_SCRIPT_GLAGOLITIC => {
1025 &_binary_resources_fonts_noto_NotoSansGlagolitic_Regular_otf_start
1026 }
1027 HB_SCRIPT_GOTHIC => &_binary_resources_fonts_noto_NotoSansGothic_Regular_otf_start,
1028 HB_SCRIPT_GRANTHA => &_binary_resources_fonts_noto_NotoSerifGrantha_Regular_otf_start,
1029 HB_SCRIPT_GUJARATI => &_binary_resources_fonts_noto_NotoSerifGujarati_Regular_otf_start,
1030 HB_SCRIPT_GUNJALA_GONDI => {
1031 &_binary_resources_fonts_noto_NotoSansGunjalaGondi_Regular_otf_start
1032 }
1033 HB_SCRIPT_GURMUKHI => &_binary_resources_fonts_noto_NotoSerifGurmukhi_Regular_otf_start,
1034 HB_SCRIPT_HANIFI_ROHINGYA => {
1035 &_binary_resources_fonts_noto_NotoSansHanifiRohingya_Regular_otf_start
1036 }
1037 HB_SCRIPT_HANUNOO => &_binary_resources_fonts_noto_NotoSansHanunoo_Regular_otf_start,
1038 HB_SCRIPT_HATRAN => &_binary_resources_fonts_noto_NotoSansHatran_Regular_otf_start,
1039 HB_SCRIPT_HEBREW => &_binary_resources_fonts_noto_NotoSerifHebrew_Regular_otf_start,
1040 HB_SCRIPT_IMPERIAL_ARAMAIC => {
1041 &_binary_resources_fonts_noto_NotoSansImperialAramaic_Regular_otf_start
1042 }
1043 HB_SCRIPT_INSCRIPTIONAL_PAHLAVI => {
1044 &_binary_resources_fonts_noto_NotoSansInscriptionalPahlavi_Regular_otf_start
1045 }
1046 HB_SCRIPT_INSCRIPTIONAL_PARTHIAN => {
1047 &_binary_resources_fonts_noto_NotoSansInscriptionalParthian_Regular_otf_start
1048 }
1049 HB_SCRIPT_JAVANESE => &_binary_resources_fonts_noto_NotoSansJavanese_Regular_otf_start,
1050 HB_SCRIPT_KAITHI => &_binary_resources_fonts_noto_NotoSansKaithi_Regular_otf_start,
1051 HB_SCRIPT_KANNADA => &_binary_resources_fonts_noto_NotoSerifKannada_Regular_otf_start,
1052 HB_SCRIPT_KAWI => &_binary_resources_fonts_noto_NotoSansKawi_Regular_otf_start,
1053 HB_SCRIPT_KAYAH_LI => &_binary_resources_fonts_noto_NotoSansKayahLi_Regular_otf_start,
1054 HB_SCRIPT_KHAROSHTHI => {
1055 &_binary_resources_fonts_noto_NotoSansKharoshthi_Regular_otf_start
1056 }
1057 HB_SCRIPT_KHITAN_SMALL_SCRIPT => {
1058 &_binary_resources_fonts_noto_NotoSerifKhitanSmallScript_Regular_otf_start
1059 }
1060 HB_SCRIPT_KHMER => &_binary_resources_fonts_noto_NotoSerifKhmer_Regular_otf_start,
1061 HB_SCRIPT_KHOJKI => &_binary_resources_fonts_noto_NotoSerifKhojki_Regular_otf_start,
1062 HB_SCRIPT_KHUDAWADI => {
1063 &_binary_resources_fonts_noto_NotoSansKhudawadi_Regular_otf_start
1064 }
1065 HB_SCRIPT_LAO => &_binary_resources_fonts_noto_NotoSerifLao_Regular_otf_start,
1066 HB_SCRIPT_LEPCHA => &_binary_resources_fonts_noto_NotoSansLepcha_Regular_otf_start,
1067 HB_SCRIPT_LIMBU => &_binary_resources_fonts_noto_NotoSansLimbu_Regular_otf_start,
1068 HB_SCRIPT_LINEAR_A => &_binary_resources_fonts_noto_NotoSansLinearA_Regular_otf_start,
1069 HB_SCRIPT_LINEAR_B => &_binary_resources_fonts_noto_NotoSansLinearB_Regular_otf_start,
1070 HB_SCRIPT_LISU => &_binary_resources_fonts_noto_NotoSansLisu_Regular_otf_start,
1071 HB_SCRIPT_LYCIAN => &_binary_resources_fonts_noto_NotoSansLycian_Regular_otf_start,
1072 HB_SCRIPT_LYDIAN => &_binary_resources_fonts_noto_NotoSansLydian_Regular_otf_start,
1073 HB_SCRIPT_MAHAJANI => &_binary_resources_fonts_noto_NotoSansMahajani_Regular_otf_start,
1074 HB_SCRIPT_MAKASAR => &_binary_resources_fonts_noto_NotoSerifMakasar_Regular_otf_start,
1075 HB_SCRIPT_MALAYALAM => {
1076 &_binary_resources_fonts_noto_NotoSerifMalayalam_Regular_otf_start
1077 }
1078 HB_SCRIPT_MANDAIC => &_binary_resources_fonts_noto_NotoSansMandaic_Regular_otf_start,
1079 HB_SCRIPT_MANICHAEAN => {
1080 &_binary_resources_fonts_noto_NotoSansManichaean_Regular_otf_start
1081 }
1082 HB_SCRIPT_MARCHEN => &_binary_resources_fonts_noto_NotoSansMarchen_Regular_otf_start,
1083 HB_SCRIPT_MASARAM_GONDI => {
1084 &_binary_resources_fonts_noto_NotoSansMasaramGondi_Regular_otf_start
1085 }
1086 HB_SCRIPT_MEDEFAIDRIN => {
1087 &_binary_resources_fonts_noto_NotoSansMedefaidrin_Regular_otf_start
1088 }
1089 HB_SCRIPT_MEETEI_MAYEK => {
1090 &_binary_resources_fonts_noto_NotoSansMeeteiMayek_Regular_otf_start
1091 }
1092 HB_SCRIPT_MENDE_KIKAKUI => {
1093 &_binary_resources_fonts_noto_NotoSansMendeKikakui_Regular_otf_start
1094 }
1095 HB_SCRIPT_MIAO => &_binary_resources_fonts_noto_NotoSansMiao_Regular_otf_start,
1096 HB_SCRIPT_MODI => &_binary_resources_fonts_noto_NotoSansModi_Regular_otf_start,
1097 HB_SCRIPT_MONGOLIAN => {
1098 &_binary_resources_fonts_noto_NotoSansMongolian_Regular_otf_start
1099 }
1100 HB_SCRIPT_MRO => &_binary_resources_fonts_noto_NotoSansMro_Regular_otf_start,
1101 HB_SCRIPT_MULTANI => &_binary_resources_fonts_noto_NotoSansMultani_Regular_otf_start,
1102 HB_SCRIPT_MYANMAR => &_binary_resources_fonts_noto_NotoSerifMyanmar_Regular_otf_start,
1103 HB_SCRIPT_NABATAEAN => {
1104 &_binary_resources_fonts_noto_NotoSansNabataean_Regular_otf_start
1105 }
1106 HB_SCRIPT_NAG_MUNDARI => {
1107 &_binary_resources_fonts_noto_NotoSansNagMundari_Regular_otf_start
1108 }
1109 HB_SCRIPT_NANDINAGARI => {
1110 &_binary_resources_fonts_noto_NotoSansNandinagari_Regular_otf_start
1111 }
1112 HB_SCRIPT_NEWA => &_binary_resources_fonts_noto_NotoSansNewa_Regular_otf_start,
1113 HB_SCRIPT_NEW_TAI_LUE => {
1114 &_binary_resources_fonts_noto_NotoSansNewTaiLue_Regular_otf_start
1115 }
1116 HB_SCRIPT_NKO => &_binary_resources_fonts_noto_NotoSansNKo_Regular_otf_start,
1117 HB_SCRIPT_NUSHU => &_binary_resources_fonts_noto_NotoSansNushu_Regular_otf_start,
1118 HB_SCRIPT_NYIAKENG_PUACHUE_HMONG => {
1119 &_binary_resources_fonts_noto_NotoSerifNyiakengPuachueHmong_Regular_otf_start
1120 }
1121 HB_SCRIPT_OGHAM => &_binary_resources_fonts_noto_NotoSansOgham_Regular_otf_start,
1122 HB_SCRIPT_OLD_HUNGARIAN => {
1123 &_binary_resources_fonts_noto_NotoSansOldHungarian_Regular_otf_start
1124 }
1125 HB_SCRIPT_OLD_ITALIC => {
1126 &_binary_resources_fonts_noto_NotoSansOldItalic_Regular_otf_start
1127 }
1128 HB_SCRIPT_OLD_NORTH_ARABIAN => {
1129 &_binary_resources_fonts_noto_NotoSansOldNorthArabian_Regular_otf_start
1130 }
1131 HB_SCRIPT_OLD_PERMIC => {
1132 &_binary_resources_fonts_noto_NotoSansOldPermic_Regular_otf_start
1133 }
1134 HB_SCRIPT_OLD_PERSIAN => {
1135 &_binary_resources_fonts_noto_NotoSansOldPersian_Regular_otf_start
1136 }
1137 HB_SCRIPT_OLD_SOGDIAN => {
1138 &_binary_resources_fonts_noto_NotoSansOldSogdian_Regular_otf_start
1139 }
1140 HB_SCRIPT_OLD_SOUTH_ARABIAN => {
1141 &_binary_resources_fonts_noto_NotoSansOldSouthArabian_Regular_otf_start
1142 }
1143 HB_SCRIPT_OLD_TURKIC => {
1144 &_binary_resources_fonts_noto_NotoSansOldTurkic_Regular_otf_start
1145 }
1146 HB_SCRIPT_OLD_UYGHUR => {
1147 &_binary_resources_fonts_noto_NotoSerifOldUyghur_Regular_otf_start
1148 }
1149 HB_SCRIPT_OL_CHIKI => &_binary_resources_fonts_noto_NotoSansOlChiki_Regular_otf_start,
1150 HB_SCRIPT_ORIYA => &_binary_resources_fonts_noto_NotoSerifOriya_Regular_otf_start,
1151 HB_SCRIPT_OSAGE => &_binary_resources_fonts_noto_NotoSansOsage_Regular_otf_start,
1152 HB_SCRIPT_OSMANYA => &_binary_resources_fonts_noto_NotoSansOsmanya_Regular_otf_start,
1153 HB_SCRIPT_PAHAWH_HMONG => {
1154 &_binary_resources_fonts_noto_NotoSansPahawhHmong_Regular_otf_start
1155 }
1156 HB_SCRIPT_PALMYRENE => {
1157 &_binary_resources_fonts_noto_NotoSansPalmyrene_Regular_otf_start
1158 }
1159 HB_SCRIPT_PAU_CIN_HAU => {
1160 &_binary_resources_fonts_noto_NotoSansPauCinHau_Regular_otf_start
1161 }
1162 HB_SCRIPT_PHAGS_PA => &_binary_resources_fonts_noto_NotoSansPhagsPa_Regular_otf_start,
1163 HB_SCRIPT_PHOENICIAN => {
1164 &_binary_resources_fonts_noto_NotoSansPhoenician_Regular_otf_start
1165 }
1166 HB_SCRIPT_PSALTER_PAHLAVI => {
1167 &_binary_resources_fonts_noto_NotoSansPsalterPahlavi_Regular_otf_start
1168 }
1169 HB_SCRIPT_REJANG => &_binary_resources_fonts_noto_NotoSansRejang_Regular_otf_start,
1170 HB_SCRIPT_RUNIC => &_binary_resources_fonts_noto_NotoSansRunic_Regular_otf_start,
1171 HB_SCRIPT_SAMARITAN => {
1172 &_binary_resources_fonts_noto_NotoSansSamaritan_Regular_otf_start
1173 }
1174 HB_SCRIPT_SAURASHTRA => {
1175 &_binary_resources_fonts_noto_NotoSansSaurashtra_Regular_otf_start
1176 }
1177 HB_SCRIPT_SHARADA => &_binary_resources_fonts_noto_NotoSansSharada_Regular_otf_start,
1178 HB_SCRIPT_SHAVIAN => &_binary_resources_fonts_noto_NotoSansShavian_Regular_otf_start,
1179 HB_SCRIPT_SIDDHAM => &_binary_resources_fonts_noto_NotoSansSiddham_Regular_otf_start,
1180 HB_SCRIPT_SIGNWRITING => {
1181 &_binary_resources_fonts_noto_NotoSansSignWriting_Regular_otf_start
1182 }
1183 HB_SCRIPT_SINHALA => &_binary_resources_fonts_noto_NotoSerifSinhala_Regular_otf_start,
1184 HB_SCRIPT_SOGDIAN => &_binary_resources_fonts_noto_NotoSansSogdian_Regular_otf_start,
1185 HB_SCRIPT_SORA_SOMPENG => {
1186 &_binary_resources_fonts_noto_NotoSansSoraSompeng_Regular_otf_start
1187 }
1188 HB_SCRIPT_SOYOMBO => &_binary_resources_fonts_noto_NotoSansSoyombo_Regular_otf_start,
1189 HB_SCRIPT_SUNDANESE => {
1190 &_binary_resources_fonts_noto_NotoSansSundanese_Regular_otf_start
1191 }
1192 HB_SCRIPT_SYLOTI_NAGRI => {
1193 &_binary_resources_fonts_noto_NotoSansSylotiNagri_Regular_otf_start
1194 }
1195 HB_SCRIPT_TAGALOG => &_binary_resources_fonts_noto_NotoSansTagalog_Regular_otf_start,
1196 HB_SCRIPT_TAGBANWA => &_binary_resources_fonts_noto_NotoSansTagbanwa_Regular_otf_start,
1197 HB_SCRIPT_TAI_LE => &_binary_resources_fonts_noto_NotoSansTaiLe_Regular_otf_start,
1198 HB_SCRIPT_TAI_THAM => &_binary_resources_fonts_noto_NotoSansTaiTham_Regular_otf_start,
1199 HB_SCRIPT_TAI_VIET => &_binary_resources_fonts_noto_NotoSansTaiViet_Regular_otf_start,
1200 HB_SCRIPT_TAKRI => &_binary_resources_fonts_noto_NotoSansTakri_Regular_otf_start,
1201 HB_SCRIPT_TAMIL => &_binary_resources_fonts_noto_NotoSerifTamil_Regular_otf_start,
1202 HB_SCRIPT_TANGSA => &_binary_resources_fonts_noto_NotoSansTangsa_Regular_otf_start,
1203 HB_SCRIPT_TELUGU => &_binary_resources_fonts_noto_NotoSerifTelugu_Regular_otf_start,
1204 HB_SCRIPT_THAANA => &_binary_resources_fonts_noto_NotoSansThaana_Regular_otf_start,
1205 HB_SCRIPT_THAI => &_binary_resources_fonts_noto_NotoSerifThai_Regular_otf_start,
1206 HB_SCRIPT_TIBETAN => &_binary_resources_fonts_noto_NotoSerifTibetan_Regular_otf_start,
1207 HB_SCRIPT_TIFINAGH => &_binary_resources_fonts_noto_NotoSansTifinagh_Regular_otf_start,
1208 HB_SCRIPT_TIRHUTA => &_binary_resources_fonts_noto_NotoSansTirhuta_Regular_otf_start,
1209 HB_SCRIPT_TOTO => &_binary_resources_fonts_noto_NotoSerifToto_Regular_otf_start,
1210 HB_SCRIPT_UGARITIC => &_binary_resources_fonts_noto_NotoSansUgaritic_Regular_otf_start,
1211 HB_SCRIPT_VAI => &_binary_resources_fonts_noto_NotoSansVai_Regular_otf_start,
1212 HB_SCRIPT_VITHKUQI => &_binary_resources_fonts_noto_NotoSerifVithkuqi_Regular_otf_start,
1213 HB_SCRIPT_WANCHO => &_binary_resources_fonts_noto_NotoSansWancho_Regular_otf_start,
1214 HB_SCRIPT_WARANG_CITI => {
1215 &_binary_resources_fonts_noto_NotoSansWarangCiti_Regular_otf_start
1216 }
1217 HB_SCRIPT_YEZIDI => &_binary_resources_fonts_noto_NotoSerifYezidi_Regular_otf_start,
1218 HB_SCRIPT_YI => &_binary_resources_fonts_noto_NotoSansYi_Regular_otf_start,
1219 HB_SCRIPT_ZANABAZAR_SQUARE => {
1220 &_binary_resources_fonts_noto_NotoSansZanabazarSquare_Regular_otf_start
1221 }
1222
1223 HB_SYMBOL_MATHS => &_binary_resources_fonts_noto_NotoSansMath_Regular_otf_start,
1224 HB_SYMBOL_MUSIC => &_binary_resources_fonts_noto_NotoMusic_Regular_otf_start,
1225 HB_SYMBOL_MISC_ONE => &_binary_resources_fonts_noto_NotoSansSymbols_Regular_otf_start,
1226 HB_SCRIPT_BRAILLE | HB_SYMBOL_MISC_TWO => {
1227 &_binary_resources_fonts_noto_NotoSansSymbols2_Regular_otf_start
1228 }
1229 HB_SYMBOL_EMOJI => &_binary_resources_fonts_noto_NotoEmoji_Regular_ttf_start,
1230
1231 _ => &_binary_resources_fonts_droid_DroidSansFallback_ttf_start,
1232 }
1233 }
1234}
1235
1236#[inline]
1237fn script_from_code(code: u32) -> HbScript {
1238 match code {
1241 0x2032..=0x2037
1242 | 0x2057
1243 | 0x20D0..=0x20DC
1244 | 0x20E1
1245 | 0x20E5..=0x20EF
1246 | 0x2102
1247 | 0x210A..=0x210E
1248 | 0x2110..=0x2112
1249 | 0x2115
1250 | 0x2119..=0x211D
1251 | 0x2124
1252 | 0x2128
1253 | 0x212C
1254 | 0x212D
1255 | 0x212F..=0x2131
1256 | 0x2133..=0x2138
1257 | 0x213C..=0x2140
1258 | 0x2145..=0x2149
1259 | 0x2190..=0x21AE
1260 | 0x21B0..=0x21E5
1261 | 0x21F1
1262 | 0x21F2
1263 | 0x21F4..=0x22FF
1264 | 0x2308..=0x230B
1265 | 0x2310
1266 | 0x2319
1267 | 0x231C..=0x2321
1268 | 0x2336..=0x237A
1269 | 0x237C
1270 | 0x2395
1271 | 0x239B..=0x23B6
1272 | 0x23D0
1273 | 0x23DC..=0x23E1
1274 | 0x2474
1275 | 0x2475
1276 | 0x25AF
1277 | 0x25B3
1278 | 0x25B7
1279 | 0x25BD
1280 | 0x25C1
1281 | 0x25CA
1282 | 0x25CC
1283 | 0x25FB
1284 | 0x266D..=0x266F
1285 | 0x27C0..=0x27FF
1286 | 0x2900..=0x2AFF
1287 | 0x2B0E..=0x2B11
1288 | 0x2B30..=0x2B4C
1289 | 0x2BFE
1290 | 0xFF5B
1291 | 0xFF5D
1292 | 0x1D400..=0x1D454
1293 | 0x1D456..=0x1D49C
1294 | 0x1D49E
1295 | 0x1D49F
1296 | 0x1D4A2
1297 | 0x1D4A5
1298 | 0x1D4A6
1299 | 0x1D4A9..=0x1D4AC
1300 | 0x1D4AE..=0x1D4B9
1301 | 0x1D4BB
1302 | 0x1D4BD..=0x1D4C3
1303 | 0x1D4C5..=0x1D505
1304 | 0x1D507..=0x1D50A
1305 | 0x1D50D..=0x1D514
1306 | 0x1D516..=0x1D51C
1307 | 0x1D51E..=0x1D539
1308 | 0x1D53B..=0x1D53E
1309 | 0x1D540..=0x1D544
1310 | 0x1D546
1311 | 0x1D54A..=0x1D550
1312 | 0x1D552..=0x1D6A5
1313 | 0x1D6A8..=0x1D7CB
1314 | 0x1D7CE..=0x1D7FF
1315 | 0x1EE00..=0x1EE03
1316 | 0x1EE05..=0x1EE1F
1317 | 0x1EE21
1318 | 0x1EE22
1319 | 0x1EE24
1320 | 0x1EE27
1321 | 0x1EE29..=0x1EE32
1322 | 0x1EE34..=0x1EE37
1323 | 0x1EE39
1324 | 0x1EE3B
1325 | 0x1EE42
1326 | 0x1EE47
1327 | 0x1EE49
1328 | 0x1EE4B
1329 | 0x1EE4D..=0x1EE4F
1330 | 0x1EE51
1331 | 0x1EE52
1332 | 0x1EE54
1333 | 0x1EE57
1334 | 0x1EE59
1335 | 0x1EE5B
1336 | 0x1EE5D
1337 | 0x1EE5F
1338 | 0x1EE61
1339 | 0x1EE62
1340 | 0x1EE64
1341 | 0x1EE67..=0x1EE6A
1342 | 0x1EE6C..=0x1EE72
1343 | 0x1EE74..=0x1EE77
1344 | 0x1EE79..=0x1EE7C
1345 | 0x1EE7E
1346 | 0x1EE80..=0x1EE89
1347 | 0x1EE8B..=0x1EE9B
1348 | 0x1EEA1..=0x1EEA3
1349 | 0x1EEA5..=0x1EEA9
1350 | 0x1EEAB..=0x1EEBB
1351 | 0x1EEF0
1352 | 0x1EEF1 => HB_SYMBOL_MATHS,
1353
1354 0x1D000..=0x1D0F5 | 0x1D100..=0x1D126 | 0x1D129..=0x1D1E8 | 0x1D200..=0x1D245 => {
1355 HB_SYMBOL_MUSIC
1356 }
1357
1358 0x20DD..=0x20E0
1359 | 0x20E2..=0x20E4
1360 | 0x2160..=0x2183
1361 | 0x2185..=0x2188
1362 | 0x218A
1363 | 0x218B
1364 | 0x2300..=0x230F
1365 | 0x2311..=0x2315
1366 | 0x2317
1367 | 0x2322
1368 | 0x2323
1369 | 0x2329
1370 | 0x232A
1371 | 0x232C..=0x2335
1372 | 0x2380..=0x2394
1373 | 0x2396..=0x239A
1374 | 0x23BE..=0x23CD
1375 | 0x23D1..=0x23DB
1376 | 0x23E2..=0x23E8
1377 | 0x2460..=0x24FF
1378 | 0x260A..=0x260D
1379 | 0x2613
1380 | 0x2624..=0x262F
1381 | 0x2638..=0x263B
1382 | 0x263D..=0x2653
1383 | 0x2669..=0x267E
1384 | 0x2690..=0x269D
1385 | 0x26A2..=0x26A9
1386 | 0x26AD..=0x26BC
1387 | 0x26CE
1388 | 0x26E2..=0x26FF
1389 | 0x271D..=0x2721
1390 | 0x2776..=0x2793
1391 | 0x1F100..=0x1F10C
1392 | 0x1F110..=0x1F12F
1393 | 0x1F130..=0x1F16C
1394 | 0x1F170..=0x1F190
1395 | 0x1F19B..=0x1F1AC
1396 | 0x1F546..=0x1F549
1397 | 0x1F54F
1398 | 0x1F610
1399 | 0x1F700..=0x1F773 => HB_SYMBOL_MISC_ONE,
1400
1401 0x2022
1402 | 0x21AF
1403 | 0x21E6..=0x21F0
1404 | 0x21F3
1405 | 0x2316
1406 | 0x2318
1407 | 0x231A
1408 | 0x231B
1409 | 0x2324..=0x2328
1410 | 0x232B
1411 | 0x237B
1412 | 0x237D..=0x237F
1413 | 0x23CE
1414 | 0x23CF
1415 | 0x23E9
1416 | 0x23ED..=0x23EF
1417 | 0x23F1..=0x23FF
1418 | 0x2400..=0x2426
1419 | 0x2440..=0x244A
1420 | 0x25A0..=0x2609
1421 | 0x260E..=0x2612
1422 | 0x2614..=0x2623
1423 | 0x2630..=0x2637
1424 | 0x263C
1425 | 0x2654..=0x2668
1426 | 0x267F..=0x268F
1427 | 0x269E..=0x26A1
1428 | 0x26AA..=0x26AC
1429 | 0x26BD..=0x26CD
1430 | 0x26CF..=0x26E1
1431 | 0x2700..=0x2704
1432 | 0x2706..=0x2709
1433 | 0x270B..=0x271C
1434 | 0x2722..=0x2727
1435 | 0x2729..=0x274B
1436 | 0x274D
1437 | 0x274F..=0x2752
1438 | 0x2756..=0x2775
1439 | 0x2794
1440 | 0x2798..=0x27AF
1441 | 0x27B1..=0x27BE
1442 | 0x2800..=0x28FF
1443 | 0x2B00..=0x2B0D
1444 | 0x2B12..=0x2B2F
1445 | 0x2B4D..=0x2B73
1446 | 0x2B76..=0x2B95
1447 | 0x2B97..=0x2BFD
1448 | 0x2BFF
1449 | 0x4DC0..=0x4DFF
1450 | 0xFFF9..=0xFFFB
1451 | 0x10140..=0x1018E
1452 | 0x10190..=0x1019C
1453 | 0x101A0
1454 | 0x101D0..=0x101FD
1455 | 0x102E0..=0x102FB
1456 | 0x10E60..=0x10E7E
1457 | 0x1D2E0..=0x1D2F3
1458 | 0x1D300..=0x1D356
1459 | 0x1D360..=0x1D378
1460 | 0x1F000..=0x1F02B
1461 | 0x1F030..=0x1F093
1462 | 0x1F0A0..=0x1F0AE
1463 | 0x1F0B1..=0x1F0BF
1464 | 0x1F0C1..=0x1F0CF
1465 | 0x1F0D1..=0x1F0F5
1466 | 0x1F30D..=0x1F30F
1467 | 0x1F315
1468 | 0x1F31C
1469 | 0x1F321..=0x1F32C
1470 | 0x1F336
1471 | 0x1F378
1472 | 0x1F37D
1473 | 0x1F394..=0x1F39F
1474 | 0x1F3A7
1475 | 0x1F3AC..=0x1F3AE
1476 | 0x1F3C2
1477 | 0x1F3CB..=0x1F3CE
1478 | 0x1F3D4..=0x1F3DF
1479 | 0x1F3ED
1480 | 0x1F3F1..=0x1F3F3
1481 | 0x1F3F5..=0x1F3F7
1482 | 0x1F408
1483 | 0x1F415
1484 | 0x1F41F
1485 | 0x1F426
1486 | 0x1F43F
1487 | 0x1F441
1488 | 0x1F446..=0x1F449
1489 | 0x1F44C..=0x1F44E
1490 | 0x1F453
1491 | 0x1F46A
1492 | 0x1F47D
1493 | 0x1F4A3
1494 | 0x1F4B0
1495 | 0x1F4B3
1496 | 0x1F4B9
1497 | 0x1F4BB
1498 | 0x1F4BF
1499 | 0x1F4C8..=0x1F4CB
1500 | 0x1F4DA
1501 | 0x1F4DF
1502 | 0x1F4E4..=0x1F4E6
1503 | 0x1F4EA..=0x1F4ED
1504 | 0x1F4F9..=0x1F4FB
1505 | 0x1F4FD
1506 | 0x1F4FE
1507 | 0x1F503
1508 | 0x1F507..=0x1F50A
1509 | 0x1F50D
1510 | 0x1F512
1511 | 0x1F513
1512 | 0x1F53E..=0x1F545
1513 | 0x1F54A
1514 | 0x1F550..=0x1F579
1515 | 0x1F57B..=0x1F594
1516 | 0x1F597..=0x1F5A3
1517 | 0x1F5A5..=0x1F5FA
1518 | 0x1F650..=0x1F67F
1519 | 0x1F687
1520 | 0x1F68D
1521 | 0x1F691
1522 | 0x1F694
1523 | 0x1F698
1524 | 0x1F6AD
1525 | 0x1F6B2
1526 | 0x1F6B9
1527 | 0x1F6BA
1528 | 0x1F6BC
1529 | 0x1F6C6..=0x1F6CB
1530 | 0x1F6CD..=0x1F6CF
1531 | 0x1F6D3..=0x1F6D7
1532 | 0x1F6E0..=0x1F6EA
1533 | 0x1F6F0..=0x1F6F3
1534 | 0x1F6F7..=0x1F6FC
1535 | 0x1F780..=0x1F7D8
1536 | 0x1F7E0..=0x1F7EB
1537 | 0x1F800..=0x1F80B
1538 | 0x1F810..=0x1F847
1539 | 0x1F850..=0x1F859
1540 | 0x1F860..=0x1F887
1541 | 0x1F890..=0x1F8AD
1542 | 0x1F8B0..=0x1F8B1
1543 | 0x1F93B
1544 | 0x1F946
1545 | 0x1FA00..=0x1FA53
1546 | 0x1FA60..=0x1FA6D
1547 | 0x1FA70..=0x1FA74
1548 | 0x1FA78..=0x1FA7A
1549 | 0x1FA80..=0x1FA86
1550 | 0x1FA90..=0x1FAA8
1551 | 0x1FAB0..=0x1FAB6
1552 | 0x1FAC0..=0x1FAC2
1553 | 0x1FAD0..=0x1FAD6
1554 | 0x1FB00..=0x1FBCA
1555 | 0x1FBF0..=0x1FBF9 => HB_SYMBOL_MISC_TWO,
1556
1557 0x2049
1558 | 0x2122
1559 | 0x2139
1560 | 0x23EA..=0x23EC
1561 | 0x23F0
1562 | 0x2705
1563 | 0x2708..=0x270C
1564 | 0x2728
1565 | 0x274C
1566 | 0x274E
1567 | 0x2753..=0x2755
1568 | 0x2795..=0x2797
1569 | 0x27B0
1570 | 0x27BF
1571 | 0x3030
1572 | 0x303D
1573 | 0x3297
1574 | 0x3299
1575 | 0xFEFF
1576 | 0x1F191..=0x1F19A
1577 | 0x1F1E6..=0x1F1FF
1578 | 0x1F201
1579 | 0x1F202
1580 | 0x1F21A
1581 | 0x1F22F
1582 | 0x1F232..=0x1F23A
1583 | 0x1F250
1584 | 0x1F251
1585 | 0x1F300..=0x1F320
1586 | 0x1F330..=0x1F335
1587 | 0x1F337..=0x1F37C
1588 | 0x1F380..=0x1F393
1589 | 0x1F3A0..=0x1F3C4
1590 | 0x1F3C6..=0x1F3CA
1591 | 0x1F3E0..=0x1F3F0
1592 | 0x1F400..=0x1F429
1593 | 0x1F42B..=0x1F43E
1594 | 0x1F440
1595 | 0x1F442..=0x1F4F7
1596 | 0x1F4F9..=0x1F4FC
1597 | 0x1F500..=0x1F53D
1598 | 0x1F5FB..=0x1F640
1599 | 0x1F645..=0x1F64F
1600 | 0x1F680..=0x1F697
1601 | 0x1F699..=0x1F6C5
1602 | 0xFE4E5..=0xFE4EE
1603 | 0xFE82C
1604 | 0xFE82E..=0xFE837 => HB_SYMBOL_EMOJI,
1605
1606 _ => HB_SCRIPT_UNKNOWN,
1607 }
1608}
1609
1610pub struct FontLibrary(*mut FtLibrary);
1611
1612pub struct FontOpener(Rc<FontLibrary>);
1613
1614pub struct Font {
1615 lib: Rc<FontLibrary>,
1616 face: *mut FtFace,
1617 font: *mut HbFont,
1618 size: u32,
1619 dpi: u16,
1620 pub ellipsis: RenderPlan,
1622 pub x_heights: (u32, u32),
1624 space_codepoint: u32,
1625}
1626
1627impl FontOpener {
1628 pub fn new() -> Result<FontOpener, Error> {
1629 unsafe {
1630 let mut lib = ptr::null_mut();
1631 let ret = FT_Init_FreeType(&mut lib);
1632 if ret != FT_ERR_OK {
1633 Err(Error::from(FreetypeError::from(ret)))
1634 } else {
1635 Ok(FontOpener(Rc::new(FontLibrary(lib))))
1636 }
1637 }
1638 }
1639
1640 pub fn open<P: AsRef<Path>>(&self, path: P) -> Result<Font, Error> {
1641 unsafe {
1642 let mut face = ptr::null_mut();
1643 let c_path = CString::new(path.as_ref().as_os_str().as_bytes()).unwrap();
1644 let ret = FT_New_Face((self.0).0, c_path.as_ptr(), 0, &mut face);
1645 if ret != FT_ERR_OK {
1646 return Err(Error::from(FreetypeError::from(ret)));
1647 }
1648 let font = ptr::null_mut();
1649 let ellipsis = RenderPlan::default();
1650 let x_heights = (0, 0);
1651 let space_codepoint = FT_Get_Char_Index(face, ' ' as libc::c_ulong);
1652 Ok(Font {
1653 lib: self.0.clone(),
1654 face,
1655 font,
1656 size: 0,
1657 dpi: 0,
1658 ellipsis,
1659 x_heights,
1660 space_codepoint,
1661 })
1662 }
1663 }
1664
1665 pub fn open_memory(&self, buf: &[u8]) -> Result<Font, Error> {
1666 unsafe {
1667 let mut face = ptr::null_mut();
1668 let ret = FT_New_Memory_Face(
1669 (self.0).0,
1670 buf.as_ptr() as *const FtByte,
1671 buf.len() as libc::c_long,
1672 0,
1673 &mut face,
1674 );
1675 if ret != FT_ERR_OK {
1676 return Err(Error::from(FreetypeError::from(ret)));
1677 }
1678 let ellipsis = RenderPlan::default();
1679 let font = ptr::null_mut();
1680 let x_heights = (0, 0);
1681 let space_codepoint = FT_Get_Char_Index(face, ' ' as libc::c_ulong);
1682 Ok(Font {
1683 lib: self.0.clone(),
1684 face,
1685 font,
1686 size: 0,
1687 dpi: 0,
1688 ellipsis,
1689 x_heights,
1690 space_codepoint,
1691 })
1692 }
1693 }
1694}
1695
1696impl Font {
1697 pub fn family_name(&self) -> Option<&str> {
1698 unsafe {
1699 let ptr = (*self.face).family_name;
1700 if ptr.is_null() {
1701 return None;
1702 }
1703 CStr::from_ptr(ptr).to_str().ok()
1704 }
1705 }
1706
1707 pub fn style_name(&self) -> Option<&str> {
1708 unsafe {
1709 let ptr = (*self.face).style_name;
1710 if ptr.is_null() {
1711 return None;
1712 }
1713 CStr::from_ptr(ptr).to_str().ok()
1714 }
1715 }
1716
1717 pub fn set_size(&mut self, size: u32, dpi: u16) {
1718 if !self.font.is_null() && self.size == size && self.dpi == dpi {
1719 return;
1720 }
1721
1722 self.size = size;
1723 self.dpi = dpi;
1724
1725 unsafe {
1726 let ret = FT_Set_Char_Size(self.face, size as FtF26Dot6, 0, dpi as libc::c_uint, 0);
1727
1728 if ret != FT_ERR_OK {
1729 return;
1730 }
1731
1732 if self.font.is_null() {
1733 self.font = hb_ft_font_create(self.face, ptr::null());
1734 } else {
1735 hb_ft_font_changed(self.font);
1736 }
1737
1738 self.ellipsis = self.plan("…", None, None);
1739 self.x_heights = (self.height('x'), self.height('X'));
1740 }
1741 }
1742
1743 pub fn set_variations(&mut self, specs: &[&str]) {
1744 unsafe {
1745 let mut varia = ptr::null_mut();
1746 let ret = FT_Get_MM_Var(self.face, &mut varia);
1747
1748 if ret != FT_ERR_OK {
1749 return;
1750 }
1751
1752 let axes_count = (*varia).num_axis as usize;
1753 let mut coords = Vec::with_capacity(axes_count);
1754
1755 for i in 0..(axes_count as isize) {
1756 let axis = ((*varia).axis).offset(i);
1757 coords.push((*axis).def);
1758 }
1759
1760 for s in specs {
1761 let tn = s[..4].as_bytes();
1762 let tag = tag(tn[0], tn[1], tn[2], tn[3]);
1763 let value: f32 = s[5..].parse().unwrap_or_default();
1764
1765 for i in 0..(axes_count as isize) {
1766 let axis = ((*varia).axis).offset(i);
1767
1768 if (*axis).tag == tag as libc::c_ulong {
1769 let scaled_value = ((value * 65536.0) as FtFixed)
1770 .min((*axis).maximum)
1771 .max((*axis).minimum);
1772 *coords.get_unchecked_mut(i as usize) = scaled_value;
1773 break;
1774 }
1775 }
1776 }
1777
1778 let ret = FT_Set_Var_Design_Coordinates(
1779 self.face,
1780 coords.len() as libc::c_uint,
1781 coords.as_ptr(),
1782 );
1783
1784 if ret == FT_ERR_OK && !self.font.is_null() {
1785 hb_ft_font_changed(self.font);
1786 }
1787
1788 FT_Done_MM_Var(self.lib.0, varia);
1789 }
1790 }
1791
1792 pub fn set_variations_from_name(&mut self, name: &str) -> bool {
1793 let mut found = false;
1794
1795 unsafe {
1796 let mut varia = ptr::null_mut();
1797 let ret = FT_Get_MM_Var(self.face, &mut varia);
1798
1799 if ret != FT_ERR_OK {
1800 return found;
1801 }
1802
1803 let styles_count = (*varia).num_namedstyles as isize;
1804 let names_count = FT_Get_Sfnt_Name_Count(self.face);
1805 let mut sfnt_name = FtSfntName::default();
1806
1807 'outer: for i in 0..styles_count {
1808 let style = ((*varia).namedstyle).offset(i);
1809 let strid = (*style).strid as libc::c_ushort;
1810 for j in 0..names_count {
1811 let ret = FT_Get_Sfnt_Name(self.face, j, &mut sfnt_name);
1812
1813 if ret != FT_ERR_OK || sfnt_name.name_id != strid {
1814 continue;
1815 }
1816
1817 if sfnt_name.platform_id != TT_PLATFORM_MICROSOFT
1818 || sfnt_name.encoding_id != TT_MS_ID_UNICODE_CS
1819 || sfnt_name.language_id != TT_MS_LANGID_ENGLISH_UNITED_STATES
1820 {
1821 continue;
1822 }
1823
1824 let slice = slice::from_raw_parts(sfnt_name.text, sfnt_name.len as usize);
1825 let vec_ascii: Vec<u8> = slice
1827 .iter()
1828 .enumerate()
1829 .filter_map(|x| if x.0 % 2 == 0 { None } else { Some(*x.1) })
1830 .collect();
1831
1832 if let Ok(name_str) = str::from_utf8(&vec_ascii[..]) {
1833 if name.eq_ignore_ascii_case(name_str) {
1834 found = true;
1835 let ret = FT_Set_Var_Design_Coordinates(
1836 self.face,
1837 (*varia).num_axis,
1838 (*style).coords,
1839 );
1840 if ret == FT_ERR_OK && !self.font.is_null() {
1841 hb_ft_font_changed(self.font);
1842 }
1843 break 'outer;
1844 }
1845 }
1846 }
1847 }
1848
1849 FT_Done_MM_Var(self.lib.0, varia);
1850 }
1851
1852 found
1853 }
1854
1855 #[inline]
1856 unsafe fn patch(
1857 &mut self,
1858 txt: &str,
1859 features: &[HbFeature],
1860 render_plan: &mut RenderPlan,
1861 missing_glyphs: Vec<(usize, usize)>,
1862 buf: *mut HbBuffer,
1863 ) {
1864 unsafe {
1865 let mut drift = 0;
1866 for (mut start, mut end) in missing_glyphs.into_iter() {
1867 start = (start as i32 + drift).max(0) as usize;
1868 end = (end as i32 + drift).max(0) as usize;
1869 hb_buffer_clear_contents(buf);
1870 let start_index = render_plan.glyphs[start].cluster;
1871 let end_index = render_plan
1872 .glyphs
1873 .get(end)
1874 .map(|g| g.cluster)
1875 .unwrap_or_else(|| txt.len());
1876 let chunk = &txt[start_index..end_index];
1877 hb_buffer_add_utf8(
1878 buf,
1879 chunk.as_ptr() as *const libc::c_char,
1880 chunk.len() as libc::c_int,
1881 0,
1882 -1,
1883 );
1884 hb_buffer_guess_segment_properties(buf);
1885 let mut script = hb_buffer_get_script(buf);
1886 if (script == HB_SCRIPT_INVALID || script == HB_SCRIPT_UNKNOWN)
1887 && let Some(c) = chunk.chars().next()
1888 {
1889 script = script_from_code(u32::from(c));
1890 }
1891 let font_data = font_data_from_script(script);
1892 let mut face = ptr::null_mut();
1893 let face_error = FT_New_Memory_Face(
1894 (self.lib).0,
1895 font_data.as_ptr() as *const FtByte,
1896 font_data.len() as libc::c_long,
1897 0,
1898 &mut face,
1899 );
1900 if face_error != 0 || face.is_null() {
1901 hb_buffer_destroy(buf);
1902 tracing::warn!(face_error = face_error, "there has been a face_error");
1903
1904 continue;
1905 }
1906 FT_Set_Pixel_Sizes(face, (*(*self.face).size).metrics.x_ppem as libc::c_uint, 0);
1907 let font = hb_ft_font_create(face, ptr::null());
1908 hb_shape(font, buf, features.as_ptr(), features.len() as libc::c_uint);
1909 let len = hb_buffer_get_length(buf) as usize;
1910 let info = hb_buffer_get_glyph_infos(buf, ptr::null_mut());
1911 let pos = hb_buffer_get_glyph_positions(buf, ptr::null_mut());
1912 let mut glyphs = Vec::with_capacity(len);
1913
1914 for i in 0..len {
1915 let pos_i = &*pos.add(i);
1916 let info_i = &*info.add(i);
1917 render_plan.width += pos_i.x_advance >> 6;
1918 glyphs.push(GlyphPlan {
1919 codepoint: info_i.codepoint,
1920 cluster: start_index + info_i.cluster as usize,
1921 advance: pt!(pos_i.x_advance >> 6, pos_i.y_advance >> 6),
1922 offset: pt!(pos_i.x_offset >> 6, -pos_i.y_offset >> 6),
1923 });
1924 render_plan.scripts.insert(start + i, script);
1925 }
1926
1927 render_plan.glyphs.splice(start..end, glyphs);
1928 drift += len as i32 - (end - start) as i32;
1929
1930 hb_font_destroy(font);
1931 FT_Done_Face(face);
1932 }
1933 }
1934 }
1935
1936 pub fn plan<S: AsRef<str>>(
1937 &mut self,
1938 text: S,
1939 max_width: Option<i32>,
1940 features: Option<&[String]>,
1941 ) -> RenderPlan {
1942 unsafe {
1943 let buf = hb_buffer_create();
1944 hb_buffer_add_utf8(
1945 buf,
1946 text.as_ref().as_ptr() as *const libc::c_char,
1947 text.as_ref().len() as libc::c_int,
1948 0,
1949 -1,
1950 );
1951
1952 hb_buffer_set_direction(buf, HB_DIRECTION_LTR);
1954 hb_buffer_guess_segment_properties(buf);
1955
1956 let features_vec: Vec<HbFeature> = features
1957 .map(|ftr| {
1958 ftr.iter()
1959 .filter_map(|f| {
1960 let mut feature = HbFeature::default();
1961 let ret = hb_feature_from_string(
1962 f.as_ptr() as *const libc::c_char,
1963 f.len() as libc::c_int,
1964 &mut feature,
1965 );
1966 if ret == 1 { Some(feature) } else { None }
1967 })
1968 .collect()
1969 })
1970 .unwrap_or_default();
1971
1972 hb_shape(
1973 self.font,
1974 buf,
1975 features_vec.as_ptr(),
1976 features_vec.len() as libc::c_uint,
1977 );
1978
1979 let len = hb_buffer_get_length(buf) as usize;
1980 let info = hb_buffer_get_glyph_infos(buf, ptr::null_mut());
1981 let pos = hb_buffer_get_glyph_positions(buf, ptr::null_mut());
1982 let mut render_plan = RenderPlan::default();
1983 let mut missing_glyphs = Vec::new();
1984
1985 for i in 0..len {
1986 let pos_i = &*pos.add(i);
1987 let info_i = &*info.add(i);
1988 if info_i.codepoint == 0 {
1989 if let Some((start, end)) = missing_glyphs.pop() {
1990 if i == end {
1991 missing_glyphs.push((start, end + 1));
1992 } else {
1993 missing_glyphs.push((start, end));
1994 missing_glyphs.push((i, i + 1));
1995 }
1996 } else {
1997 missing_glyphs.push((i, i + 1));
1998 }
1999 } else {
2000 render_plan.width += pos_i.x_advance >> 6;
2001 }
2002 let glyph = GlyphPlan {
2003 codepoint: info_i.codepoint,
2004 cluster: info_i.cluster as usize,
2005 advance: pt!(pos_i.x_advance >> 6, pos_i.y_advance >> 6),
2006 offset: pt!(pos_i.x_offset >> 6, -pos_i.y_offset >> 6),
2007 };
2008 render_plan.glyphs.push(glyph);
2009 }
2010
2011 self.patch(
2012 text.as_ref(),
2013 &features_vec,
2014 &mut render_plan,
2015 missing_glyphs,
2016 buf,
2017 );
2018
2019 hb_buffer_destroy(buf);
2020
2021 if let Some(mw) = max_width {
2022 self.crop_right(&mut render_plan, mw);
2023 }
2024
2025 render_plan
2026 }
2027 }
2028
2029 #[inline]
2030 pub fn crop_right(&self, render_plan: &mut RenderPlan, max_width: i32) {
2031 if render_plan.width <= max_width {
2032 return;
2033 }
2034
2035 render_plan.width += self.ellipsis.width;
2036
2037 while let Some(gp) = render_plan.glyphs.pop() {
2038 render_plan.width -= gp.advance.x;
2039 if render_plan.width <= max_width {
2040 break;
2041 }
2042 }
2043
2044 let len = render_plan.glyphs.len();
2045 render_plan.scripts.retain(|&k, _| k < len);
2046 render_plan
2047 .glyphs
2048 .extend_from_slice(&self.ellipsis.glyphs[..]);
2049 }
2050
2051 #[inline]
2052 pub fn trim_left(&self, render_plan: &mut RenderPlan) {
2053 if render_plan.glyphs.is_empty() {
2054 return;
2055 }
2056
2057 let mut i = 0;
2058
2059 while render_plan.glyphs[i].codepoint == self.space_codepoint {
2060 render_plan.width -= render_plan.glyphs[i].advance.x;
2061 i += 1;
2062 }
2063
2064 render_plan.glyphs.drain(..i);
2065 render_plan.scripts = render_plan
2066 .scripts
2067 .iter()
2068 .filter_map(|(&k, &v)| if k < i { None } else { Some((k - i, v)) })
2069 .collect();
2070 }
2071
2072 #[inline]
2073 pub fn crop_around(&self, render_plan: &mut RenderPlan, index: usize, max_width: i32) -> usize {
2074 if render_plan.width <= max_width {
2075 return 0;
2076 }
2077
2078 let len = render_plan.glyphs.len();
2079 let mut width = 0;
2080 let mut polarity = 0;
2081 let mut upper_index = index;
2082 let mut lower_index = index as i32 - 1;
2083
2084 loop {
2085 let next_width;
2086 if upper_index < len && (polarity % 2 == 0 || lower_index < 0) {
2087 next_width = width + render_plan.glyphs[upper_index].advance.x;
2088 if next_width > max_width {
2089 break;
2090 } else {
2091 width = next_width;
2092 }
2093 upper_index += 1;
2094 } else if lower_index >= 0 && (polarity % 2 == 1 || upper_index == len) {
2095 next_width = width + render_plan.glyphs[lower_index as usize].advance.x;
2096 if next_width > max_width {
2097 break;
2098 } else {
2099 width = next_width;
2100 }
2101 lower_index -= 1;
2102 }
2103 polarity += 1;
2104 }
2105
2106 if upper_index < len {
2107 width += self.ellipsis.width;
2108 upper_index -= 1;
2109 while width > max_width && upper_index > (lower_index.max(0) as usize) {
2110 width -= render_plan.glyphs[upper_index].advance.x;
2111 upper_index -= 1;
2112 }
2113 render_plan.glyphs.truncate(upper_index + 1);
2114 render_plan
2115 .glyphs
2116 .extend_from_slice(&self.ellipsis.glyphs[..]);
2117 }
2118
2119 if lower_index >= 0 {
2120 width += self.ellipsis.width;
2121 lower_index += 1;
2122 while width > max_width && (lower_index as usize) < upper_index {
2123 width -= render_plan.glyphs[lower_index as usize].advance.x;
2124 lower_index += 1;
2125 }
2126 render_plan.glyphs = self
2127 .ellipsis
2128 .glyphs
2129 .iter()
2130 .chain(render_plan.glyphs[lower_index as usize..].iter())
2131 .cloned()
2132 .collect();
2133 }
2134
2135 render_plan
2136 .scripts
2137 .retain(|&k, _| k >= lower_index.max(0) as usize && k <= upper_index);
2138 if lower_index > 0 {
2139 render_plan.scripts = render_plan
2140 .scripts
2141 .drain()
2142 .map(|(k, v)| (k - lower_index as usize + 1, v))
2143 .collect();
2144 }
2145 render_plan.width = width;
2146
2147 if lower_index < 0 {
2148 0
2149 } else {
2150 lower_index as usize
2151 }
2152 }
2153
2154 pub fn cut_point(&self, render_plan: &RenderPlan, max_width: i32) -> (usize, i32) {
2155 let mut width = render_plan.width;
2156 let glyphs = &render_plan.glyphs;
2157 let mut i = glyphs.len() - 1;
2158
2159 width -= glyphs[i].advance.x;
2160
2161 while i > 0 && width > max_width {
2162 i -= 1;
2163 width -= glyphs[i].advance.x;
2164 }
2165
2166 let j = i;
2167 let last_width = width;
2168
2169 while i > 0 && glyphs[i].codepoint != self.space_codepoint {
2170 i -= 1;
2171 width -= glyphs[i].advance.x;
2172 }
2173
2174 if i == 0 {
2175 i = j;
2176 width = last_width;
2177 }
2178
2179 (i, width)
2180 }
2181
2182 pub fn render(
2183 &mut self,
2184 fb: &mut dyn Framebuffer,
2185 color: Color,
2186 render_plan: &RenderPlan,
2187 origin: Point,
2188 ) {
2189 unsafe {
2190 let mut pos = origin;
2191 let mut fallback_faces = FxHashMap::default();
2192
2193 for (index, glyph) in render_plan.glyphs.iter().enumerate() {
2194 let face = if let Some(script) = render_plan.scripts.get(&index) {
2195 *fallback_faces.entry(script).or_insert_with(|| {
2196 let font_data = font_data_from_script(*script);
2197 let mut face = ptr::null_mut();
2198 FT_New_Memory_Face(
2199 (self.lib).0,
2200 font_data.as_ptr() as *const FtByte,
2201 font_data.len() as libc::c_long,
2202 0,
2203 &mut face,
2204 );
2205 FT_Set_Pixel_Sizes(
2206 face,
2207 (*(*self.face).size).metrics.x_ppem as libc::c_uint,
2208 0,
2209 );
2210 face
2211 })
2212 } else {
2213 self.face
2214 };
2215
2216 FT_Load_Glyph(face, glyph.codepoint, FT_LOAD_RENDER | FT_LOAD_NO_HINTING);
2217
2218 let glyph_slot = (*face).glyph;
2219 let top_left =
2220 pos + glyph.offset + pt!((*glyph_slot).bitmap_left, -(*glyph_slot).bitmap_top);
2221 let bitmap = &(*glyph_slot).bitmap;
2222
2223 for y in 0..bitmap.rows {
2224 for x in 0..bitmap.width {
2225 let blackness = *bitmap.buffer.offset((bitmap.pitch * y + x) as isize);
2226 let alpha = blackness as f32 / 255.0;
2227 let pt = top_left + pt!(x, y);
2228 fb.set_blended_pixel(pt.x as u32, pt.y as u32, color, alpha);
2229 }
2230 }
2231
2232 pos += glyph.advance;
2233 }
2234
2235 for (_, face) in fallback_faces {
2236 FT_Done_Face(face);
2237 }
2238 }
2239 }
2240
2241 pub fn height(&self, c: char) -> u32 {
2242 unsafe {
2243 FT_Load_Char(self.face, c as libc::c_ulong, FT_LOAD_DEFAULT);
2244 let metrics = &((*(*self.face).glyph).metrics);
2245 (metrics.height >> 6) as u32
2246 }
2247 }
2248
2249 pub fn em(&self) -> u16 {
2250 unsafe { (*(*self.face).size).metrics.x_ppem as u16 }
2251 }
2252
2253 pub fn ascender(&self) -> i32 {
2254 unsafe { (*(*self.face).size).metrics.ascender as i32 / 64 }
2255 }
2256
2257 pub fn descender(&self) -> i32 {
2258 unsafe { (*(*self.face).size).metrics.descender as i32 / 64 }
2259 }
2260
2261 pub fn line_height(&self) -> i32 {
2262 unsafe { (*(*self.face).size).metrics.height as i32 / 64 }
2263 }
2264}
2265
2266#[derive(Debug, Copy, Clone)]
2267struct GlyphPlan {
2268 codepoint: u32,
2269 cluster: usize,
2270 offset: Point,
2271 advance: Point,
2272}
2273
2274#[derive(Debug, Clone)]
2275pub struct RenderPlan {
2276 pub width: i32,
2277 scripts: FxHashMap<usize, HbScript>,
2278 glyphs: Vec<GlyphPlan>,
2279}
2280
2281impl Default for RenderPlan {
2282 fn default() -> RenderPlan {
2283 RenderPlan {
2284 width: 0,
2285 scripts: FxHashMap::default(),
2286 glyphs: Vec::new(),
2287 }
2288 }
2289}
2290
2291impl RenderPlan {
2292 pub fn scale(&self, scale: f32) -> RenderPlan {
2293 let width = (scale * self.width as f32) as i32;
2294 let scripts = self.scripts.clone();
2295 let glyphs = self
2296 .glyphs
2297 .iter()
2298 .map(|gp| GlyphPlan {
2299 offset: Point::from(scale * Vec2::from(gp.offset)),
2300 advance: Point::from(scale * Vec2::from(gp.advance)),
2301 ..*gp
2302 })
2303 .collect();
2304 RenderPlan {
2305 width,
2306 scripts,
2307 glyphs,
2308 }
2309 }
2310
2311 pub fn space_out(&mut self, letter_spacing: i32) {
2312 if letter_spacing == 0 {
2313 return;
2314 }
2315
2316 if let Some((_, start)) = self.glyphs.split_last_mut() {
2317 let len = start.len() as i32;
2318 for glyph in start {
2319 glyph.advance.x += letter_spacing;
2320 }
2321 self.width += len * letter_spacing;
2322 }
2323 }
2324
2325 pub fn split_off(&mut self, index: usize, width: i32) -> RenderPlan {
2326 let mut next_scripts = FxHashMap::default();
2327 if !self.scripts.is_empty() {
2328 for i in index..self.glyphs.len() {
2329 self.scripts
2330 .remove_entry(&i)
2331 .map(|(k, v)| next_scripts.insert(k - index, v));
2332 }
2333 }
2334 let next_glyphs = self.glyphs.split_off(index);
2335 let next_width = self.width - width;
2336 self.width = width;
2337 RenderPlan {
2338 width: next_width,
2339 scripts: next_scripts,
2340 glyphs: next_glyphs,
2341 }
2342 }
2343
2344 pub fn index_from_advance(&self, advance: i32) -> usize {
2345 let mut sum = 0;
2346 let mut index = 0;
2347 while index < self.glyphs.len() {
2348 let gad = self.glyph_advance(index);
2349 sum += gad;
2350 if sum > advance {
2351 if sum - advance < advance - sum + gad {
2352 index += 1;
2353 }
2354 break;
2355 }
2356 index += 1;
2357 }
2358 index
2359 }
2360
2361 pub fn append(&mut self, other: &mut Self) {
2362 let next_index = self.glyphs.len();
2363 self.scripts
2364 .extend(other.scripts.iter().map(|(k, v)| (next_index + k, *v)));
2365 self.glyphs.append(&mut other.glyphs);
2366 self.width += other.width;
2367 }
2368
2369 pub fn total_advance(&self, index: usize) -> i32 {
2370 self.glyphs.iter().take(index).map(|g| g.advance.x).sum()
2371 }
2372
2373 #[inline]
2374 pub fn glyph_advance(&self, index: usize) -> i32 {
2375 self.glyphs[index].advance.x
2376 }
2377}
2378
2379impl Drop for FontLibrary {
2380 fn drop(&mut self) {
2381 unsafe {
2382 FT_Done_FreeType(self.0);
2383 }
2384 }
2385}
2386
2387impl Drop for Font {
2388 fn drop(&mut self) {
2389 unsafe {
2390 FT_Done_Face(self.face);
2391 if !self.font.is_null() {
2392 hb_font_destroy(self.font);
2393 }
2394 }
2395 }
2396}
2397
2398#[inline]
2399fn tag(c1: u8, c2: u8, c3: u8, c4: u8) -> u32 {
2400 ((c1 as u32) << 24) | ((c2 as u32) << 16) | ((c3 as u32) << 8) | c4 as u32
2401}
2402
2403#[derive(Error, Debug)]
2404enum FreetypeError {
2405 #[error("Unknown error with code {0}.")]
2406 UnknownError(FtError),
2407
2408 #[error("Cannot open resource.")]
2409 CannotOpenResource,
2410
2411 #[error("Unknown file format.")]
2412 UnknownFileFormat,
2413
2414 #[error("Broken file.")]
2415 InvalidFileFormat,
2416
2417 #[error("Invalid FreeType version.")]
2418 InvalidVersion,
2419
2420 #[error("Module version is too low.")]
2421 LowerModuleVersion,
2422
2423 #[error("Invalid argument.")]
2424 InvalidArgument,
2425
2426 #[error("Unimplemented feature.")]
2427 UnimplementedFeature,
2428
2429 #[error("Broken table.")]
2430 InvalidTable,
2431
2432 #[error("Broken offset within table.")]
2433 InvalidOffset,
2434
2435 #[error("Array allocation size too large.")]
2436 ArrayTooLarge,
2437
2438 #[error("Missing module.")]
2439 MissingModule,
2440
2441 #[error("Missing property.")]
2442 MissingProperty,
2443
2444 #[error("Invalid glyph index.")]
2445 InvalidGlyphIndex,
2446
2447 #[error("Invalid character code.")]
2448 InvalidCharacterCode,
2449
2450 #[error("Unsupported glyph image format.")]
2451 InvalidGlyphFormat,
2452
2453 #[error("Cannot render this glyph format.")]
2454 CannotRenderGlyph,
2455
2456 #[error("Invalid outline.")]
2457 InvalidOutline,
2458
2459 #[error("Invalid composite glyph.")]
2460 InvalidComposite,
2461
2462 #[error("Too many hints.")]
2463 TooManyHints,
2464
2465 #[error("Invalid pixel size.")]
2466 InvalidPixelSize,
2467
2468 #[error("Invalid object handle.")]
2469 InvalidHandle,
2470
2471 #[error("Invalid library handle.")]
2472 InvalidLibraryHandle,
2473
2474 #[error("Invalid module handle.")]
2475 InvalidDriverHandle,
2476
2477 #[error("Invalid face handle.")]
2478 InvalidFaceHandle,
2479
2480 #[error("Invalid size handle.")]
2481 InvalidSizeHandle,
2482
2483 #[error("Invalid glyph slot handle.")]
2484 InvalidSlotHandle,
2485
2486 #[error("Invalid charmap handle.")]
2487 InvalidCharMapHandle,
2488
2489 #[error("Invalid cache manager handle.")]
2490 InvalidCacheHandle,
2491
2492 #[error("Invalid stream handle.")]
2493 InvalidStreamHandle,
2494
2495 #[error("Too many modules.")]
2496 TooManyDrivers,
2497
2498 #[error("Too many extensions.")]
2499 TooManyExtensions,
2500
2501 #[error("Out of memory.")]
2502 OutOfMemory,
2503
2504 #[error("Unlisted object.")]
2505 UnlistedObject,
2506
2507 #[error("Cannot open stream.")]
2508 CannotOpenStream,
2509
2510 #[error("Invalid stream seek.")]
2511 InvalidStreamSeek,
2512
2513 #[error("Invalid stream skip.")]
2514 InvalidStreamSkip,
2515
2516 #[error("Invalid stream read.")]
2517 InvalidStreamRead,
2518
2519 #[error("Invalid stream operation.")]
2520 InvalidStreamOperation,
2521
2522 #[error("Invalid frame operation.")]
2523 InvalidFrameOperation,
2524
2525 #[error("Nested frame access.")]
2526 NestedFrameAccess,
2527
2528 #[error("Invalid frame read.")]
2529 InvalidFrameRead,
2530
2531 #[error("Raster uninitialized.")]
2532 RasterUninitialized,
2533
2534 #[error("Raster corrupted.")]
2535 RasterCorrupted,
2536
2537 #[error("Raster overflow.")]
2538 RasterOverflow,
2539
2540 #[error("Negative height while rastering.")]
2541 RasterNegativeHeight,
2542
2543 #[error("Too many registered caches.")]
2544 TooManyCaches,
2545
2546 #[error("Invalid opcode.")]
2547 InvalidOpcode,
2548
2549 #[error("Too few arguments.")]
2550 TooFewArguments,
2551
2552 #[error("Stack overflow.")]
2553 StackOverflow,
2554
2555 #[error("Code overflow.")]
2556 CodeOverflow,
2557
2558 #[error("Bad argument.")]
2559 BadArgument,
2560
2561 #[error("Division by zero.")]
2562 DivideByZero,
2563
2564 #[error("Invalid reference.")]
2565 InvalidReference,
2566
2567 #[error("Found debug opcode.")]
2568 DebugOpCode,
2569
2570 #[error("Found ENDF opcode in execution stream.")]
2571 ENDFInExecStream,
2572
2573 #[error("Nested DEFS.")]
2574 NestedDEFS,
2575
2576 #[error("Invalid code range.")]
2577 InvalidCodeRange,
2578
2579 #[error("Execution context too long.")]
2580 ExecutionTooLong,
2581
2582 #[error("Too many function definitions.")]
2583 TooManyFunctionDefs,
2584
2585 #[error("Too many instruction definitions.")]
2586 TooManyInstructionDefs,
2587
2588 #[error("SFNT font table missing.")]
2589 TableMissing,
2590
2591 #[error("Horizontal header (hhea) table missing.")]
2592 HorizHeaderMissing,
2593
2594 #[error("Locations (loca) table missing.")]
2595 LocationsMissing,
2596
2597 #[error("Name table missing.")]
2598 NameTableMissing,
2599
2600 #[error("Character map (cmap) table missing.")]
2601 CMapTableMissing,
2602
2603 #[error("Horizontal metrics (hmtx) table missing.")]
2604 HmtxTableMissing,
2605
2606 #[error("PostScript (post) table missing.")]
2607 PostTableMissing,
2608
2609 #[error("Invalid horizontal metrics.")]
2610 InvalidHorizMetrics,
2611
2612 #[error("Invalid character map (cmap) format.")]
2613 InvalidCharMapFormat,
2614
2615 #[error("Invalid ppem value.")]
2616 InvalidPPem,
2617
2618 #[error("Invalid vertical metrics.")]
2619 InvalidVertMetrics,
2620
2621 #[error("Could not find context.")]
2622 CouldNotFindContext,
2623
2624 #[error("Invalid PostScript (post) table format.")]
2625 InvalidPostTableFormat,
2626
2627 #[error("Invalid PostScript (post) table.")]
2628 InvalidPostTable,
2629
2630 #[error("Found FDEF or IDEF opcode in glyf bytecode.")]
2631 DEFInGlyfBytecode,
2632
2633 #[error("Missing bitmap in strike.")]
2634 MissingBitmap,
2635
2636 #[error("Opcode syntax error.")]
2637 SyntaxError,
2638
2639 #[error("Argument stack underflow.")]
2640 StackUnderflow,
2641
2642 #[error("Ignore.")]
2643 Ignore,
2644
2645 #[error("No Unicode glyph name found.")]
2646 NoUnicodeGlyphName,
2647
2648 #[error("Glyph too big for hinting.")]
2649 GlyphTooBig,
2650
2651 #[error("`STARTFONT' field missing.")]
2652 MissingStartfontField,
2653
2654 #[error("`FONT' field missing.")]
2655 MissingFontField,
2656
2657 #[error("`SIZE' field missing.")]
2658 MissingSizeField,
2659
2660 #[error("`FONTBOUNDINGBOX' field missing.")]
2661 MissingFontboundingboxField,
2662
2663 #[error("`CHARS' field missing.")]
2664 MissingCharsField,
2665
2666 #[error("`STARTCHAR' field missing.")]
2667 MissingStartcharField,
2668
2669 #[error("`ENCODING' field missing.")]
2670 MissingEncodingField,
2671
2672 #[error("`BBX' field missing.")]
2673 MissingBbxField,
2674
2675 #[error("`BBX' too big.")]
2676 BbxTooBig,
2677
2678 #[error("Font header corrupted or missing fields.")]
2679 CorruptedFontHeader,
2680
2681 #[error("Font glyphs corrupted or missing fields.")]
2682 CorruptedFontGlyphs,
2683}
2684
2685impl From<FtError> for FreetypeError {
2686 fn from(code: FtError) -> FreetypeError {
2687 match code {
2688 0x01 => FreetypeError::CannotOpenResource,
2689 0x02 => FreetypeError::UnknownFileFormat,
2690 0x03 => FreetypeError::InvalidFileFormat,
2691 0x04 => FreetypeError::InvalidVersion,
2692 0x05 => FreetypeError::LowerModuleVersion,
2693 0x06 => FreetypeError::InvalidArgument,
2694 0x07 => FreetypeError::UnimplementedFeature,
2695 0x08 => FreetypeError::InvalidTable,
2696 0x09 => FreetypeError::InvalidOffset,
2697 0x0A => FreetypeError::ArrayTooLarge,
2698 0x0B => FreetypeError::MissingModule,
2699 0x0C => FreetypeError::MissingProperty,
2700 0x10 => FreetypeError::InvalidGlyphIndex,
2701 0x11 => FreetypeError::InvalidCharacterCode,
2702 0x12 => FreetypeError::InvalidGlyphFormat,
2703 0x13 => FreetypeError::CannotRenderGlyph,
2704 0x14 => FreetypeError::InvalidOutline,
2705 0x15 => FreetypeError::InvalidComposite,
2706 0x16 => FreetypeError::TooManyHints,
2707 0x17 => FreetypeError::InvalidPixelSize,
2708 0x20 => FreetypeError::InvalidHandle,
2709 0x21 => FreetypeError::InvalidLibraryHandle,
2710 0x22 => FreetypeError::InvalidDriverHandle,
2711 0x23 => FreetypeError::InvalidFaceHandle,
2712 0x24 => FreetypeError::InvalidSizeHandle,
2713 0x25 => FreetypeError::InvalidSlotHandle,
2714 0x26 => FreetypeError::InvalidCharMapHandle,
2715 0x27 => FreetypeError::InvalidCacheHandle,
2716 0x28 => FreetypeError::InvalidStreamHandle,
2717 0x30 => FreetypeError::TooManyDrivers,
2718 0x31 => FreetypeError::TooManyExtensions,
2719 0x40 => FreetypeError::OutOfMemory,
2720 0x41 => FreetypeError::UnlistedObject,
2721 0x51 => FreetypeError::CannotOpenStream,
2722 0x52 => FreetypeError::InvalidStreamSeek,
2723 0x53 => FreetypeError::InvalidStreamSkip,
2724 0x54 => FreetypeError::InvalidStreamRead,
2725 0x55 => FreetypeError::InvalidStreamOperation,
2726 0x56 => FreetypeError::InvalidFrameOperation,
2727 0x57 => FreetypeError::NestedFrameAccess,
2728 0x58 => FreetypeError::InvalidFrameRead,
2729 0x60 => FreetypeError::RasterUninitialized,
2730 0x61 => FreetypeError::RasterCorrupted,
2731 0x62 => FreetypeError::RasterOverflow,
2732 0x63 => FreetypeError::RasterNegativeHeight,
2733 0x70 => FreetypeError::TooManyCaches,
2734 0x80 => FreetypeError::InvalidOpcode,
2735 0x81 => FreetypeError::TooFewArguments,
2736 0x82 => FreetypeError::StackOverflow,
2737 0x83 => FreetypeError::CodeOverflow,
2738 0x84 => FreetypeError::BadArgument,
2739 0x85 => FreetypeError::DivideByZero,
2740 0x86 => FreetypeError::InvalidReference,
2741 0x87 => FreetypeError::DebugOpCode,
2742 0x88 => FreetypeError::ENDFInExecStream,
2743 0x89 => FreetypeError::NestedDEFS,
2744 0x8A => FreetypeError::InvalidCodeRange,
2745 0x8B => FreetypeError::ExecutionTooLong,
2746 0x8C => FreetypeError::TooManyFunctionDefs,
2747 0x8D => FreetypeError::TooManyInstructionDefs,
2748 0x8E => FreetypeError::TableMissing,
2749 0x8F => FreetypeError::HorizHeaderMissing,
2750 0x90 => FreetypeError::LocationsMissing,
2751 0x91 => FreetypeError::NameTableMissing,
2752 0x92 => FreetypeError::CMapTableMissing,
2753 0x93 => FreetypeError::HmtxTableMissing,
2754 0x94 => FreetypeError::PostTableMissing,
2755 0x95 => FreetypeError::InvalidHorizMetrics,
2756 0x96 => FreetypeError::InvalidCharMapFormat,
2757 0x97 => FreetypeError::InvalidPPem,
2758 0x98 => FreetypeError::InvalidVertMetrics,
2759 0x99 => FreetypeError::CouldNotFindContext,
2760 0x9A => FreetypeError::InvalidPostTableFormat,
2761 0x9B => FreetypeError::InvalidPostTable,
2762 0x9C => FreetypeError::DEFInGlyfBytecode,
2763 0x9D => FreetypeError::MissingBitmap,
2764 0xA0 => FreetypeError::SyntaxError,
2765 0xA1 => FreetypeError::StackUnderflow,
2766 0xA2 => FreetypeError::Ignore,
2767 0xA3 => FreetypeError::NoUnicodeGlyphName,
2768 0xA4 => FreetypeError::GlyphTooBig,
2769 0xB0 => FreetypeError::MissingStartfontField,
2770 0xB1 => FreetypeError::MissingFontField,
2771 0xB2 => FreetypeError::MissingSizeField,
2772 0xB3 => FreetypeError::MissingFontboundingboxField,
2773 0xB4 => FreetypeError::MissingCharsField,
2774 0xB5 => FreetypeError::MissingStartcharField,
2775 0xB6 => FreetypeError::MissingEncodingField,
2776 0xB7 => FreetypeError::MissingBbxField,
2777 0xB8 => FreetypeError::BbxTooBig,
2778 0xB9 => FreetypeError::CorruptedFontHeader,
2779 0xBA => FreetypeError::CorruptedFontGlyphs,
2780 _ => FreetypeError::UnknownError(code),
2781 }
2782 }
2783}