52 {
U"\ud55c\uad6d\uc5b4", 2, TT_UCR_HANGUL},
53 {
U"\u3042\u30a2\u4e9c", 2, TT_UCR_HIRAGANA},
54 {
U"\u30a2\u30a4\u4e9c", 2, TT_UCR_KATAKANA},
55 {
U"\u1956\u195b\u1966", 3, TT_UCR_TAI_LE},
56 {
U"\u3105\u3106\u3107", 2, TT_UCR_BOPOMOFO},
57 {
U"\ua840\ua841\ua85d", 2, TT_UCR_PHAGSPA},
58 {
U"\u5e03\u4e01\u4f53", 2, TT_UCR_CJK_UNIFIED_IDEOGRAPHS},
60 {
U"\u05d0\u05da\u05e4", 1, TT_UCR_HEBREW},
61 {
U"\ua500\ua502\ua549", 1, TT_UCR_VAI},
62 {
U"\ufee6\ufef4\ufeb3", 1, TT_UCR_ARABIC},
63 {
U"\u07C1\u07C2\u07C3", 1, TT_UCR_NKO},
64 {
U"\u0905\u093f\u092a", 1, TT_UCR_DEVANAGARI},
65 {
U"\u0986\u0987\u098c", 1, TT_UCR_BENGALI},
66 {
U"\u0a05\u0a16\u0a30", 1, TT_UCR_GURMUKHI},
67 {
U"\u0aaa\u0aaf\u0ab8", 1, TT_UCR_GUJARATI},
68 {
U"\u0b2a\u0b30\u0b37", 1, TT_UCR_ORIYA},
69 {
U"\u0b85\u0b88\u0b8f", 1, TT_UCR_TAMIL},
70 {
U"\u0c05\u0c0c\u0c36", 1, TT_UCR_TELUGU},
71 {
U"\u0c85\u0c87\u0c8e", 1, TT_UCR_KANNADA},
72 {
U"\u0d05\u0d09\u0d3d", 1, TT_UCR_MALAYALAM},
73 {
U"\u0e05\u0e06\u0e07", 1, TT_UCR_THAI},
74 {
U"\u0e81\u0e82\u0e84", 1, TT_UCR_LAO},
75 {
U"\u10a0\u10a1\u10a2", 1, TT_UCR_GEORGIAN},
76 {
U"\u1B05\u1B07\u1B09", 1, TT_UCR_BALINESE},
77 {
U"\u0f00\u0f04\u0f08", 3, TT_UCR_TIBETAN},
78 {
U"\u0710\u0717\u071c", 3, TT_UCR_SYRIAC},
79 {
U"\u0784\u0783\u0798", 3, TT_UCR_THAANA},
80 {
U"\u0d85\u0d89\u0daf", 3, TT_UCR_SINHALA},
81 {
U"\u1000\u1001\u1014", 3, TT_UCR_MYANMAR},
82 {
U"\u1202\u1207\u1250", 3, TT_UCR_ETHIOPIC},
83 {
U"\u13a3\u13a4\u13a8", 3, TT_UCR_CHEROKEE},
84 {
U"\u1401\u144d\u156e", 3, TT_UCR_CANADIAN_ABORIGINAL_SYLLABICS},
85 {
U"\u1681\u1687\u168b", 3, TT_UCR_OGHAM},
86 {
U"\u16A0\u16A4\u16AA", 3, TT_UCR_RUNIC},
87 {
U"\u1780\u1781\u1783", 3, TT_UCR_KHMER},
88 {
U"\u1820\u1826\u1845", 3, TT_UCR_MONGOLIAN},
89 {
U"\ua188\ua320\ua4bf", 3, TT_UCR_YI},
90 {
U"\u1900\u1901\u1902", 3, TT_UCR_LIMBU},
91 {
U"\u1950\u1951\u1952", 3, TT_UCR_TAI_LE},
92 {
U"\u1980\u1982\u1986", 3, (FT_ULong)TT_UCR_NEW_TAI_LUE},
93 {
U"\u1A00\u1A01\u1A02", 4, TT_UCR_BUGINESE},
94 {
U"\u2c01\u2c05\u2c0c", 4, TT_UCR_GLAGOLITIC},
95 {
U"\u2d31\u2d33\u2d37", 4, TT_UCR_TIFINAGH},
96 {
U"\u2d31\u2d33\u2d37", 4, TT_UCR_YIJING},
97 {
U"\u1B83\u1B84\u1B88", 4, TT_UCR_SUNDANESE},
98 {
U"\u1C00\u1C01\u1C02", 4, TT_UCR_LEPCHA},
99 {
U"\u1C50\u1C51\u1C52", 4, TT_UCR_OL_CHIKI},
100 {
U"\uA800\uA801\uA805", 4, TT_UCR_SYLOTI_NAGRI},
101 {
U"\uA882\uA88a\uA892", 4, TT_UCR_SAURASHTRA},
102 {
U"\uA901\uA902\uA904", 4, TT_UCR_KAYAH_LI},
103 {
U"\uA930\uA932\uA943", 4, TT_UCR_REJANG},
104 {
U"\uaa00\uaa02\uaa05", 4, TT_UCR_CHAM},
106 {
U"\U00010000\U00010001\U00010002", 4, TT_UCR_LINEAR_B},
107 {
U"\U00010300\U00010301\U00010302", 3, TT_UCR_OLD_ITALIC},
108 {
U"\U00010330\U00010331\U00010332", 3, TT_UCR_GOTHIC},
109 {
U"\U00010380\U00010381\U00010382", 4, TT_UCR_UGARITIC},
110 {
U"\U000103A0\U000103A1\U000103A2", 4, TT_UCR_OLD_PERSIAN},
111 {
U"\U00010400\U00010401\U00010402", 3, TT_UCR_DESERET},
112 {
U"\U00010450\U00010451\U00010452", 4, TT_UCR_SHAVIAN},
113 {
U"\U00010480\U00010481\U00010482", 4, TT_UCR_OSMANYA},
114 {
U"\U00010800\U00010803\U00010805", 4, TT_UCR_CYPRIOT_SYLLABARY},
115 {
U"\U00010900\U00010901\U00010902", 2, TT_UCR_PHOENICIAN},
116 {
U"\U00010A10\U00010A11\U00010A12", 4, TT_UCR_KHAROSHTHI},
117 {
U"\U00012000\U00012001\U00012002", 4, TT_UCR_CUNEIFORM},
119 {
U"\u1700\u1701\u1702", 3, TT_UCR_PHILIPPINE},
120 {
U"\u1720\u1721\u1722", 3, TT_UCR_PHILIPPINE},
121 {
U"\u1740\u1741\u1742", 3, TT_UCR_PHILIPPINE},
122 {
U"\u1760\u1761\u1762", 3, TT_UCR_PHILIPPINE},
124 {
U"\U000102A3\U000102A8\U000102CB", 4, TT_UCR_OLD_ANATOLIAN},
125 {
U"\U00010280\U00010281\U00010282", 4, TT_UCR_OLD_ANATOLIAN},
126 {
U"\U00010920\U00010921\U00010922", 4, TT_UCR_OLD_ANATOLIAN},
128 {
U"\U0001f600\U0001f638", 0, 0},
129 {
U"\uf021\uf022\uf023", 0, 0},
130 {
U"\u280f\u2815\u283f", 3, TT_UCR_BRAILLE},
131 {
U"\U0001D11e\U0001D161\U0001D130", 3, TT_UCR_MUSICAL_SYMBOLS},
132 {
U"\u2700\u2708\u2709", 2, TT_UCR_DINGBATS},
133 {
U"\u2600\u2601\u2602", 2, TT_UCR_MISCELLANEOUS_SYMBOLS},
134 {
U"\ue000\ue001\ue002", 2, TT_UCR_PRIVATE_USE},
135 {
U"\ue702\ue703\ue704", 2, TT_UCR_PRIVATE_USE},
136 {
U"\U000F0001\U000F0002\U000F0003", 2, TT_UCR_PRIVATE_USE_SUPPLEMENTARY},
138 {
U"\U00010350\U00010352\U00010353", 2, TT_UCR_NON_PLANE_0},
139 {
U"\U000104B0\U000104B6\U000104B8", 2, TT_UCR_NON_PLANE_0},
140 {
U"\U00010500\U00010501\U00010502", 2, TT_UCR_NON_PLANE_0},
141 {
U"\U00010530\U00010531\U00010532", 2, TT_UCR_NON_PLANE_0},
142 {
U"\U00010600\U00010601\U00010602", 2, TT_UCR_NON_PLANE_0},
143 {
U"\U00010840\U00010841\U00010842", 2, TT_UCR_NON_PLANE_0},
144 {
U"\U00010860\U00010861\U00010862", 2, TT_UCR_NON_PLANE_0},
145 {
U"\U00010880\U00010881\U00010882", 2, TT_UCR_NON_PLANE_0},
146 {
U"\U000108E0\U000108E3\U000108E4", 2, TT_UCR_NON_PLANE_0},
147 {
U"\U00010980\U00010983\U00010989", 2, TT_UCR_NON_PLANE_0},
148 {
U"\U000109A0\U000109A1\U000109A2", 2, TT_UCR_NON_PLANE_0},
149 {
U"\U00010A60\U00010A61\U00010A62", 2, TT_UCR_NON_PLANE_0},
150 {
U"\U00010A80\U00010A81\U00010A82", 2, TT_UCR_NON_PLANE_0},
151 {
U"\U00010ac0\U00010ac3\U00010ac6", 2, TT_UCR_NON_PLANE_0},
152 {
U"\U00010B00\U00010B04\U00010B08", 2, TT_UCR_NON_PLANE_0},
153 {
U"\U00010B40\U00010B41\U00010B42", 2, TT_UCR_NON_PLANE_0},
154 {
U"\U00010B60\U00010B61\U00010B62", 2, TT_UCR_NON_PLANE_0},
155 {
U"\U00010B80\U00010B84\U00010B87", 2, TT_UCR_NON_PLANE_0},
156 {
U"\U00010C00\U00010C01\U00010C02", 2, TT_UCR_NON_PLANE_0},
157 {
U"\U00010C80\U00010C81\U00010C82", 2, TT_UCR_NON_PLANE_0},
158 {
U"\U00010D00\U00010D07\U00010D0D", 2, TT_UCR_NON_PLANE_0},
159 {
U"\U00010E80\U00010E81\U00010E82", 2, TT_UCR_NON_PLANE_0},
160 {
U"\U00010F00\U00010F01\U00010F02", 2, TT_UCR_NON_PLANE_0},
161 {
U"\U00010F30\U00010F32\U00010F34", 2, TT_UCR_NON_PLANE_0},
162 {
U"\U00010F70\U00010F71\U00010F72", 2, TT_UCR_NON_PLANE_0},
163 {
U"\U00010FB0\U00010FB1\U00010FB2", 2, TT_UCR_NON_PLANE_0},
164 {
U"\U00010FE0\U00010FE1\U00010FE2", 2, TT_UCR_NON_PLANE_0},
165 {
U"\U00011003\U00011004\U00011005", 2, TT_UCR_NON_PLANE_0},
166 {
U"\U00011083\U00011085\U00011087", 2, TT_UCR_NON_PLANE_0},
167 {
U"\U000110D0\U000110D1\U000110D2", 2, TT_UCR_NON_PLANE_0},
168 {
U"\U00011103\U00011104\U00011105", 2, TT_UCR_NON_PLANE_0},
169 {
U"\U00011150\U00011151\U00011152", 2, TT_UCR_NON_PLANE_0},
170 {
U"\U00011183\U00011185\U0001118b", 2, TT_UCR_NON_PLANE_0},
171 {
U"\U00011200\U00011201\U00011202", 2, TT_UCR_NON_PLANE_0},
172 {
U"\U00011280\U00011281\U00011282", 2, TT_UCR_NON_PLANE_0},
173 {
U"\U000112B0\U000112B2\U000112B4", 2, TT_UCR_NON_PLANE_0},
174 {
U"\U00011305\U00011309\U0001130b", 2, TT_UCR_NON_PLANE_0},
175 {
U"\U00011400\U00011404\U00011409", 2, TT_UCR_NON_PLANE_0},
176 {
U"\U00011480\U00011481\U00011482", 2, TT_UCR_NON_PLANE_0},
177 {
U"\U00011580\U00011582\U00011589", 2, TT_UCR_NON_PLANE_0},
178 {
U"\U00011600\U00011604\U00011609", 2, TT_UCR_NON_PLANE_0},
179 {
U"\U00011680\U00011682\U0001168A", 2, TT_UCR_NON_PLANE_0},
180 {
U"\U00011700\U00011701\U00011702", 2, TT_UCR_NON_PLANE_0},
181 {
U"\U00011800\U00011801\U00011802", 2, TT_UCR_NON_PLANE_0},
182 {
U"\U000118A0\U000118A1\U000118AA", 2, TT_UCR_NON_PLANE_0},
183 {
U"\U00011900\U00011901\U00011902", 2, TT_UCR_NON_PLANE_0},
184 {
U"\U00011A00\U00011A10\U00011A15", 2, TT_UCR_NON_PLANE_0},
185 {
U"\U00011A50\U00011A5C\U00011A6B", 2, TT_UCR_NON_PLANE_0},
186 {
U"\U00011AC0\U00011AC1\U00011AC2", 2, TT_UCR_NON_PLANE_0},
187 {
U"\U00011C00\U00011C01\U00011C02", 2, TT_UCR_NON_PLANE_0},
188 {
U"\U00011C70\U00011C71\U00011C72", 2, TT_UCR_NON_PLANE_0},
189 {
U"\U00011D00\U00011D02\U00011D08", 2, TT_UCR_NON_PLANE_0},
190 {
U"\U00011D60\U00011D62\U00011D6c", 2, TT_UCR_NON_PLANE_0},
191 {
U"\U00011FC1\U00011FC2\U00011FC8", 2, TT_UCR_NON_PLANE_0},
192 {
U"\U00012F90\U00012F91\U00012F92", 2, TT_UCR_NON_PLANE_0},
193 {
U"\U00013000\U00013076\U0001307f", 2, TT_UCR_NON_PLANE_0},
194 {
U"\U00014400\U00014409\U00014447", 2, TT_UCR_NON_PLANE_0},
195 {
U"\U00016A40\U00016A41\U00016A42", 2, TT_UCR_NON_PLANE_0},
196 {
U"\U00016A70\U00016A71\U00016A72", 2, TT_UCR_NON_PLANE_0},
197 {
U"\U00016AD0\U00016AD2\U00016ADA", 2, TT_UCR_NON_PLANE_0},
198 {
U"\U00016B00\U00016B01\U00016B02", 2, TT_UCR_NON_PLANE_0},
199 {
U"\U00016F01\U00016F05\U00016F09", 2, TT_UCR_NON_PLANE_0},
200 {
U"\U0001BC19\U0001BC1f\U0001BC0e", 2, TT_UCR_NON_PLANE_0},
201 {
U"\U0001D2E0\U0001D2E6\U0001D2f3", 2, TT_UCR_NON_PLANE_0},
202 {
U"\U0001E800\U0001E80A\U0001E80F", 2, TT_UCR_NON_PLANE_0},
203 {
U"\U0001E900\U0001E902\U0001E907", 2, TT_UCR_NON_PLANE_0},
204 {
U"\U0001E2C0\U0001E2C2\U0001E2C7", 2, TT_UCR_NON_PLANE_0},
205 {
U"\U0001EC71\U0001EC72\U0001EC73", 2, TT_UCR_NON_PLANE_0},
207 {
U"\u0638\u0630\u0633", 0, 0},
208 {
U"\u0800\u0801\u0802", 0, 0},
209 {
U"\u0841\u0842\u084c", 0, 0},
210 {
U"\u1A20\u1A21\u1A22", 0, 0},
211 {
U"\u1BC0\u1BC1\u1BC2", 0, 0},
212 {
U"\uA4EF\uA4E8\uA4ED", 0, 0},
213 {
U"\uA6A0\uA6A1\uA6A2", 0, 0},
214 {
U"\ua983\ua984\ua98d", 0, 0},
215 {
U"\uaa80\uaa81\uaa82", 0, 0},
216 {
U"\uABC0\uABC1\uABC2", 0, 0},
218 {
U"\u03e2\u03e4\u03e8", 1, TT_UCR_COPTIC},
219 {
U"\u1f08\u03a6\u03a8", 1, TT_UCR_GREEK},
220 {
U"\u0518\u0409\u040f", 1, TT_UCR_CYRILLIC},
221 {
U"\u0533\u0537\u0539", 1, TT_UCR_ARMENIAN},
311 FT_Library
ft_lib =
nullptr;
312 if (FT_Init_FreeType(&
ft_lib) != FT_Err_Ok) {
317 if (FT_New_Face(
ft_lib, filepath, 0, &face) != FT_Err_Ok) {
322 if (!(face->face_flags & FT_FACE_FLAG_SCALABLE)) {
326 FT_Error err = FT_Select_Charmap(face, FT_ENCODING_UNICODE);
328 err = FT_Select_Charmap(face, FT_ENCODING_MS_SYMBOL);
331 err = FT_Select_Charmap(face, FT_ENCODING_APPLE_ROMAN);
333 if (err && face->num_charmaps > 0) {
334 err = FT_Select_Charmap(face, face->charmaps[0]->encoding);
336 if (err != FT_Err_Ok) {
346 if (FT_Set_Char_Size(face,
w * 64, 0, 72, 72) != FT_Err_Ok) {
355 glyph_ids[i] = FT_Get_Char_Index(face, codepoints[i]);
362 FT_Get_Advance(face, glyph_ids[i], FT_LOAD_NO_HINTING, &advance);
364 width +=
int(advance >> 16);
368 (
ft_pix)face->size->metrics.descender);
369 width = std::max(width, height);
372 float font_size = std::min({
float(
w),
374 float(h) * 0.96f /
float(height) *
float(h)});
376 if (font_size < 1 || FT_Set_Char_Size(face,
int(font_size * 64.0f), 0, 72, 72) != FT_Err_Ok) {
384 int left =
int((
float(
w) - (
float(width) * (font_size /
float(
w)))) / 2.0f);
385 int top =
int(
float(h) * 0.7f);
389 FT_Pos advance_x = 0;
393 if (FT_Load_Glyph(face, glyph_ids[i], FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING) != FT_Err_Ok)
398 if (FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL) != FT_Err_Ok ||
399 face->glyph->format != FT_GLYPH_FORMAT_BITMAP)
406 for (
int y = 0; y <
int(face->glyph->bitmap.rows); y++) {
407 int dest_row = (h - y - 1 +
int(face->glyph->bitmap_top) -
top);
408 if (dest_row >= 0 && dest_row < h) {
409 for (
int x = 0; x <
int(face->glyph->bitmap.width); x++) {
411 if (dest_col >= 0 && dest_col <
w) {
412 uchar *source = &face->glyph->bitmap.buffer[y *
int(face->glyph->bitmap.width) +
x];
413 uchar *dest = &buf[dest_row *
w * 4 + (dest_col * 4 + 3)];
414 *dest =
uchar(std::min((
uint(*dest) +
uint(*source)), 255u));
420 advance_x += face->glyph->advance.x;
427 return glyph_count > 0;