Coverage Report

Created: 2025-11-07 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/mupdf/source/fitz/noto.c
Line
Count
Source
1
// Copyright (C) 2004-2025 Artifex Software, Inc.
2
//
3
// This file is part of MuPDF.
4
//
5
// MuPDF is free software: you can redistribute it and/or modify it under the
6
// terms of the GNU Affero General Public License as published by the Free
7
// Software Foundation, either version 3 of the License, or (at your option)
8
// any later version.
9
//
10
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
11
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13
// details.
14
//
15
// You should have received a copy of the GNU Affero General Public License
16
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
17
//
18
// Alternative licensing terms are available from the licensor.
19
// For commercial licensing, see <https://www.artifex.com/> or contact
20
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
21
// CA 94129, USA, for further information.
22
23
#include "mupdf/fitz.h"
24
#include "mupdf/ucdn.h"
25
26
#include <string.h>
27
28
/*
29
  Base 14 PDF fonts from URW.
30
  Noto fonts from Google.
31
  Source Han Serif from Adobe for CJK.
32
  DroidSansFallback from Android for CJK.
33
  Charis SIL from SIL.
34
35
  Define TOFU to only include the Base14 and CJK fonts.
36
37
  Define TOFU_CJK_LANG to skip Source Han Serif per-language fonts.
38
  Define TOFU_CJK_EXT to skip DroidSansFallbackFull (and the above).
39
  Define TOFU_CJK to skip DroidSansFallback (and the above).
40
41
  Define TOFU_NOTO to skip ALL non-CJK noto fonts.
42
  Define TOFU_SYMBOL to skip symbol fonts.
43
  Define TOFU_EMOJI to skip emoji/extended symbol font.
44
45
  Define TOFU_SIL to skip the SIL fonts (warning: makes EPUB documents ugly).
46
  Define TOFU_BASE14 to skip the Base 14 fonts (warning: makes PDF unusable).
47
*/
48
49
#ifdef NOTO_SMALL
50
#define TOFU_CJK_EXT
51
#define TOFU_SYMBOL
52
#define TOFU_EMOJI
53
#define TOFU_SIL
54
#endif
55
56
#ifdef NO_CJK
57
#define TOFU_CJK
58
#endif
59
60
#ifdef TOFU
61
#define TOFU_NOTO
62
#define TOFU_SIL
63
#endif
64
65
#ifdef TOFU_NOTO
66
#define TOFU_SYMBOL
67
#define TOFU_EMOJI
68
#endif
69
70
/* This historic script has an unusually large font (2MB), so we skip it by default. */
71
#ifndef NOTO_TANGUT
72
#define NOTO_TANGUT 0
73
#endif
74
75
/* Define some extra scripts for special fonts. */
76
enum
77
{
78
  MUPDF_SCRIPT_MUSIC = UCDN_LAST_SCRIPT+1,
79
  MUPDF_SCRIPT_MATH,
80
  MUPDF_SCRIPT_SYMBOLS,
81
  MUPDF_SCRIPT_SYMBOLS2,
82
  MUPDF_SCRIPT_EMOJI,
83
  MUPDF_SCRIPT_CJKV
84
};
85
86
enum
87
{
88
  BOLD = 1,
89
  ITALIC = 2
90
};
91
92
typedef struct
93
{
94
  const unsigned char *data;
95
#ifdef HAVE_OBJCOPY
96
  const unsigned char *start;
97
  const unsigned char *end;
98
4
#define INBUILT_SIZE(e) (e->end - e->start)
99
#else
100
  const unsigned int *size;
101
#define INBUILT_SIZE(e) (e->size ? *e->size : 0)
102
#endif
103
  char family[48];
104
  int script;
105
  int lang;
106
  int subfont;
107
  int attr;
108
} font_entry;
109
110
57
#define END_OF_DATA -2
111
0
#define ANY_SCRIPT -1
112
#define NO_SUBFONT 0
113
2
#define REGULAR 0
114
115
/* First, declare all the fonts. */
116
#ifdef HAVE_OBJCOPY
117
#define FONT(FORGE,NAME,NAME2,SCRIPT,LANG,SUBFONT,ATTR) \
118
extern const unsigned char _binary_resources_fonts_##FORGE##_##NAME##_start; \
119
extern const unsigned char _binary_resources_fonts_##FORGE##_##NAME##_end;
120
#else
121
#define FONT(FORGE,NAME,NAME2,SCRIPT,LANG,SUBFONT,ATTR) \
122
extern const unsigned char _binary_##NAME[];\
123
extern const unsigned int _binary_##NAME##_size;
124
#endif
125
#define ALIAS(FORGE,NAME,NAME2,SCRIPT,LANG,SUBFONT,ATTR)
126
#define EMPTY(SCRIPT)
127
128
#include "font-table.h"
129
130
#undef FONT
131
#undef ALIAS
132
#undef EMPTY
133
134
/* Now the actual list. */
135
#ifdef HAVE_OBJCOPY
136
#define FONT_DATA(FORGE,NAME) &_binary_resources_fonts_##FORGE##_##NAME##_start
137
#define FONT_SIZE(FORGE,NAME) &_binary_resources_fonts_##FORGE##_##NAME##_start, &_binary_resources_fonts_##FORGE##_##NAME##_end
138
#define EMPTY(SCRIPT) { NULL, NULL, NULL, "", SCRIPT, FZ_LANG_UNSET, NO_SUBFONT, REGULAR },
139
#else
140
#define FONT_DATA(FORGE,NAME) _binary_##NAME
141
#define FONT_SIZE(FORCE,NAME) &_binary_##NAME##_size
142
#define EMPTY(SCRIPT) { NULL, 0, "", SCRIPT, FZ_LANG_UNSET, NO_SUBFONT, REGULAR },
143
#endif
144
145
#define FONT(FORGE,NAME,NAME2,SCRIPT,LANG,SUBFONT,ATTR) { FONT_DATA(FORGE, NAME), FONT_SIZE(FORGE, NAME), NAME2, SCRIPT, LANG, SUBFONT, ATTR },
146
#define ALIAS(FORGE,NAME,NAME2,SCRIPT,LANG,SUBFONT,ATTR) { FONT_DATA(FORGE, NAME), FONT_SIZE(FORGE, NAME), NAME2, SCRIPT, LANG, SUBFONT, ATTR },
147
static font_entry inbuilt_fonts[] =
148
{
149
#include "font-table.h"
150
  { NULL,
151
#ifdef HAVE_OBJCOPY
152
  NULL, NULL,
153
#else
154
  0,
155
#endif
156
  "", END_OF_DATA, FZ_LANG_UNSET, NO_SUBFONT, REGULAR }
157
};
158
159
#undef FONT
160
#undef ALIAS
161
#undef EMPTY
162
#undef FONT_DATA
163
#undef FONT_SIZE
164
165
static const unsigned char *
166
search_by_script_lang_strict(int *size, int *subfont, int script, int language)
167
0
{
168
  /* Search in the inbuilt font table. */
169
0
  font_entry *e;
170
171
0
  if (subfont)
172
0
    *subfont = 0;
173
174
0
  for (e = inbuilt_fonts; e->script != END_OF_DATA; e++)
175
0
  {
176
0
    if (script != ANY_SCRIPT && e->script != script)
177
0
      continue;
178
0
    if (e->lang != language)
179
0
      continue;
180
0
    *size = INBUILT_SIZE(e);
181
0
    if (subfont)
182
0
      *subfont = e->subfont;
183
0
    return e->data;
184
0
  }
185
186
0
  return *size = 0, NULL;
187
0
}
188
189
static const unsigned char *
190
search_by_script_lang(int *size, int *subfont, int script, int language)
191
0
{
192
0
  const unsigned char *result;
193
0
  result = search_by_script_lang_strict(size, subfont, script, language);
194
0
  if (!result && language != FZ_LANG_UNSET)
195
0
    result = search_by_script_lang_strict(size, subfont, script, FZ_LANG_UNSET);
196
0
  return result;
197
0
}
198
199
static const unsigned char *
200
search_by_family(int *size, const char *family, int attr)
201
4
{
202
  /* Search in the inbuilt font table. */
203
4
  font_entry *e;
204
205
57
  for (e = inbuilt_fonts; e->script != END_OF_DATA; e++)
206
57
  {
207
57
    if (e->family[0] == '\0')
208
0
      continue;
209
57
    if (attr != e->attr)
210
42
      continue;
211
15
    if (!fz_strcasecmp(e->family, family))
212
4
    {
213
4
      *size = INBUILT_SIZE(e);
214
4
      return e->data;
215
4
    }
216
15
  }
217
218
0
  return *size = 0, NULL;
219
4
}
220
221
const unsigned char *
222
fz_lookup_base14_font(fz_context *ctx, const char *name, int *size)
223
4
{
224
  /* We want to insist on the base14 name matching exactly,
225
   * so we check that here first, before we look in the font table
226
   * to see if we actually have data. */
227
228
4
  if (!strcmp(name, "Courier"))
229
0
    return search_by_family(size, "Courier", REGULAR);
230
4
  if (!strcmp(name, "Courier-Oblique"))
231
0
    return search_by_family(size, "Courier", ITALIC);
232
4
  if (!strcmp(name, "Courier-Bold"))
233
0
    return search_by_family(size, "Courier", BOLD);
234
4
  if (!strcmp(name, "Courier-BoldOblique"))
235
0
    return search_by_family(size, "Courier", BOLD|ITALIC);
236
237
4
  if (!strcmp(name, "Helvetica"))
238
1
    return search_by_family(size, "Helvetica", REGULAR);
239
3
  if (!strcmp(name, "Helvetica-Oblique"))
240
1
    return search_by_family(size, "Helvetica", ITALIC);
241
2
  if (!strcmp(name, "Helvetica-Bold"))
242
1
    return search_by_family(size, "Helvetica", BOLD);
243
1
  if (!strcmp(name, "Helvetica-BoldOblique"))
244
0
    return search_by_family(size, "Helvetica", BOLD|ITALIC);
245
246
1
  if (!strcmp(name, "Times-Roman"))
247
1
    return search_by_family(size, "Times", REGULAR);
248
0
  if (!strcmp(name, "Times-Italic"))
249
0
    return search_by_family(size, "Times", ITALIC);
250
0
  if (!strcmp(name, "Times-Bold"))
251
0
    return search_by_family(size, "Times", BOLD);
252
0
  if (!strcmp(name, "Times-BoldItalic"))
253
0
    return search_by_family(size, "Times", BOLD|ITALIC);
254
255
0
  if (!strcmp(name, "Symbol"))
256
0
    return search_by_family(size, "Symbol", REGULAR);
257
0
  if (!strcmp(name, "ZapfDingbats"))
258
0
    return search_by_family(size, "ZapfDingbats", REGULAR);
259
260
0
  *size = 0;
261
0
  return NULL;
262
0
}
263
264
const unsigned char *
265
fz_lookup_builtin_font(fz_context *ctx, const char *family, int is_bold, int is_italic, int *size)
266
0
{
267
0
  return search_by_family(size, family, (is_bold ? BOLD : 0) | (is_italic ? ITALIC : 0));
268
0
}
269
270
const unsigned char *
271
fz_lookup_cjk_font(fz_context *ctx, int ordering, int *size, int *subfont)
272
0
{
273
0
  int lang = FZ_LANG_UNSET;
274
0
  switch (ordering)
275
0
  {
276
0
  case FZ_ADOBE_JAPAN: lang = FZ_LANG_ja; break;
277
0
  case FZ_ADOBE_KOREA: lang = FZ_LANG_ko; break;
278
0
  case FZ_ADOBE_GB: lang = FZ_LANG_zh_Hans; break;
279
0
  case FZ_ADOBE_CNS: lang = FZ_LANG_zh_Hant; break;
280
0
  }
281
0
  return search_by_script_lang(size, subfont, UCDN_SCRIPT_HAN, lang);
282
0
}
283
284
int
285
fz_lookup_cjk_ordering_by_language(const char *lang)
286
0
{
287
0
  if (!strcmp(lang, "zh-Hant")) return FZ_ADOBE_CNS;
288
0
  if (!strcmp(lang, "zh-TW")) return FZ_ADOBE_CNS;
289
0
  if (!strcmp(lang, "zh-HK")) return FZ_ADOBE_CNS;
290
0
  if (!strcmp(lang, "zh-Hans")) return FZ_ADOBE_GB;
291
0
  if (!strcmp(lang, "zh-CN")) return FZ_ADOBE_GB;
292
0
  if (!strcmp(lang, "ja")) return FZ_ADOBE_JAPAN;
293
0
  if (!strcmp(lang, "ko")) return FZ_ADOBE_KOREA;
294
0
  return -1;
295
0
}
296
297
static int
298
fz_lookup_cjk_language(const char *lang)
299
0
{
300
0
  if (!strcmp(lang, "zh-Hant")) return FZ_LANG_zh_Hant;
301
0
  if (!strcmp(lang, "zh-TW")) return FZ_LANG_zh_Hant;
302
0
  if (!strcmp(lang, "zh-HK")) return FZ_LANG_zh_Hant;
303
0
  if (!strcmp(lang, "zh-Hans")) return FZ_LANG_zh_Hans;
304
0
  if (!strcmp(lang, "zh-CN")) return FZ_LANG_zh_Hans;
305
0
  if (!strcmp(lang, "ja")) return FZ_LANG_ja;
306
0
  if (!strcmp(lang, "ko")) return FZ_LANG_ko;
307
0
  return FZ_LANG_UNSET;
308
0
}
309
310
const unsigned char *
311
fz_lookup_cjk_font_by_language(fz_context *ctx, const char *lang, int *size, int *subfont)
312
0
{
313
0
  return search_by_script_lang(size, subfont, UCDN_SCRIPT_HAN, fz_lookup_cjk_language(lang));
314
0
}
315
316
const unsigned char *
317
fz_lookup_noto_font(fz_context *ctx, int script, int language, int *size, int *subfont)
318
0
{
319
0
  return search_by_script_lang(size, subfont, script, language);
320
0
}
321
322
const unsigned char *
323
fz_lookup_noto_math_font(fz_context *ctx, int *size)
324
0
{
325
0
  return search_by_script_lang(size, NULL, MUPDF_SCRIPT_MATH, FZ_LANG_UNSET);
326
0
}
327
328
const unsigned char *
329
fz_lookup_noto_music_font(fz_context *ctx, int *size)
330
0
{
331
0
  return search_by_script_lang(size, NULL, MUPDF_SCRIPT_MUSIC, FZ_LANG_UNSET);
332
0
}
333
334
const unsigned char *
335
fz_lookup_noto_symbol1_font(fz_context *ctx, int *size)
336
0
{
337
0
  return search_by_script_lang(size, NULL, MUPDF_SCRIPT_SYMBOLS, FZ_LANG_UNSET);
338
0
}
339
340
const unsigned char *
341
fz_lookup_noto_symbol2_font(fz_context *ctx, int *size)
342
0
{
343
0
  return search_by_script_lang(size, NULL, MUPDF_SCRIPT_SYMBOLS2, FZ_LANG_UNSET);
344
0
}
345
346
const unsigned char *
347
fz_lookup_noto_emoji_font(fz_context *ctx, int *size)
348
0
{
349
0
  return search_by_script_lang(size, NULL, MUPDF_SCRIPT_EMOJI, FZ_LANG_UNSET);
350
0
}
351
352
const unsigned char *
353
fz_lookup_noto_boxes_font(fz_context *ctx, int *size)
354
0
{
355
0
  return search_by_family(size, "Nimbus Boxes", REGULAR);
356
0
}
357
358
359
const char *
360
fz_lookup_noto_stem_from_script(fz_context *ctx, int script, int language)
361
0
{
362
0
  switch (script)
363
0
  {
364
0
  default:
365
0
  case UCDN_SCRIPT_COMMON:
366
0
  case UCDN_SCRIPT_INHERITED:
367
0
  case UCDN_SCRIPT_UNKNOWN:
368
0
    return NULL;
369
370
0
  case UCDN_SCRIPT_HANGUL: return "KR";
371
0
  case UCDN_SCRIPT_HIRAGANA: return "JP";
372
0
  case UCDN_SCRIPT_KATAKANA: return "JP";
373
0
  case UCDN_SCRIPT_BOPOMOFO: return "TC";
374
0
  case UCDN_SCRIPT_HAN:
375
0
    switch (language)
376
0
    {
377
0
    case FZ_LANG_ja: return "JP";
378
0
    case FZ_LANG_ko: return "KR";
379
0
    case FZ_LANG_zh_Hans: return "SC";
380
0
    default:
381
0
    case FZ_LANG_zh_Hant: return "TC";
382
0
    }
383
384
0
  case UCDN_SCRIPT_LATIN: return "";
385
0
  case UCDN_SCRIPT_GREEK: return "";
386
0
  case UCDN_SCRIPT_CYRILLIC: return "";
387
0
  case UCDN_SCRIPT_ARABIC: return "Naskh";
388
389
0
  case UCDN_SCRIPT_ARMENIAN: return "Armenian";
390
0
  case UCDN_SCRIPT_HEBREW: return "Hebrew";
391
0
  case UCDN_SCRIPT_SYRIAC: return "Syriac";
392
0
  case UCDN_SCRIPT_THAANA: return "Thaana";
393
0
  case UCDN_SCRIPT_DEVANAGARI: return "Devanagari";
394
0
  case UCDN_SCRIPT_BENGALI: return "Bengali";
395
0
  case UCDN_SCRIPT_GURMUKHI: return "Gurmukhi";
396
0
  case UCDN_SCRIPT_GUJARATI: return "Gujarati";
397
0
  case UCDN_SCRIPT_ORIYA: return "Oriya";
398
0
  case UCDN_SCRIPT_TAMIL: return "Tamil";
399
0
  case UCDN_SCRIPT_TELUGU: return "Telugu";
400
0
  case UCDN_SCRIPT_KANNADA: return "Kannada";
401
0
  case UCDN_SCRIPT_MALAYALAM: return "Malayalam";
402
0
  case UCDN_SCRIPT_SINHALA: return "Sinhala";
403
0
  case UCDN_SCRIPT_THAI: return "Thai";
404
0
  case UCDN_SCRIPT_LAO: return "Lao";
405
0
  case UCDN_SCRIPT_TIBETAN: return "Tibetan";
406
0
  case UCDN_SCRIPT_MYANMAR: return "Myanmar";
407
0
  case UCDN_SCRIPT_GEORGIAN: return "Georgian";
408
0
  case UCDN_SCRIPT_ETHIOPIC: return "Ethiopic";
409
0
  case UCDN_SCRIPT_CHEROKEE: return "Cherokee";
410
0
  case UCDN_SCRIPT_CANADIAN_ABORIGINAL: return "CanadianAboriginal";
411
0
  case UCDN_SCRIPT_OGHAM: return "Ogham";
412
0
  case UCDN_SCRIPT_RUNIC: return "Runic";
413
0
  case UCDN_SCRIPT_KHMER: return "Khmer";
414
0
  case UCDN_SCRIPT_MONGOLIAN: return "Mongolian";
415
0
  case UCDN_SCRIPT_YI: return "Yi";
416
0
  case UCDN_SCRIPT_OLD_ITALIC: return "OldItalic";
417
0
  case UCDN_SCRIPT_GOTHIC: return "Gothic";
418
0
  case UCDN_SCRIPT_DESERET: return "Deseret";
419
0
  case UCDN_SCRIPT_TAGALOG: return "Tagalog";
420
0
  case UCDN_SCRIPT_HANUNOO: return "Hanunoo";
421
0
  case UCDN_SCRIPT_BUHID: return "Buhid";
422
0
  case UCDN_SCRIPT_TAGBANWA: return "Tagbanwa";
423
0
  case UCDN_SCRIPT_LIMBU: return "Limbu";
424
0
  case UCDN_SCRIPT_TAI_LE: return "TaiLe";
425
0
  case UCDN_SCRIPT_LINEAR_B: return "LinearB";
426
0
  case UCDN_SCRIPT_UGARITIC: return "Ugaritic";
427
0
  case UCDN_SCRIPT_SHAVIAN: return "Shavian";
428
0
  case UCDN_SCRIPT_OSMANYA: return "Osmanya";
429
0
  case UCDN_SCRIPT_CYPRIOT: return "Cypriot";
430
0
  case UCDN_SCRIPT_BUGINESE: return "Buginese";
431
0
  case UCDN_SCRIPT_COPTIC: return "Coptic";
432
0
  case UCDN_SCRIPT_NEW_TAI_LUE: return "NewTaiLue";
433
0
  case UCDN_SCRIPT_GLAGOLITIC: return "Glagolitic";
434
0
  case UCDN_SCRIPT_TIFINAGH: return "Tifinagh";
435
0
  case UCDN_SCRIPT_SYLOTI_NAGRI: return "SylotiNagri";
436
0
  case UCDN_SCRIPT_OLD_PERSIAN: return "OldPersian";
437
0
  case UCDN_SCRIPT_KHAROSHTHI: return "Kharoshthi";
438
0
  case UCDN_SCRIPT_BALINESE: return "Balinese";
439
0
  case UCDN_SCRIPT_CUNEIFORM: return "Cuneiform";
440
0
  case UCDN_SCRIPT_PHOENICIAN: return "Phoenician";
441
0
  case UCDN_SCRIPT_PHAGS_PA: return "PhagsPa";
442
0
  case UCDN_SCRIPT_NKO: return "NKo";
443
0
  case UCDN_SCRIPT_SUNDANESE: return "Sundanese";
444
0
  case UCDN_SCRIPT_LEPCHA: return "Lepcha";
445
0
  case UCDN_SCRIPT_OL_CHIKI: return "OlChiki";
446
0
  case UCDN_SCRIPT_VAI: return "Vai";
447
0
  case UCDN_SCRIPT_SAURASHTRA: return "Saurashtra";
448
0
  case UCDN_SCRIPT_KAYAH_LI: return "KayahLi";
449
0
  case UCDN_SCRIPT_REJANG: return "Rejang";
450
0
  case UCDN_SCRIPT_LYCIAN: return "Lycian";
451
0
  case UCDN_SCRIPT_CARIAN: return "Carian";
452
0
  case UCDN_SCRIPT_LYDIAN: return "Lydian";
453
0
  case UCDN_SCRIPT_CHAM: return "Cham";
454
0
  case UCDN_SCRIPT_TAI_THAM: return "TaiTham";
455
0
  case UCDN_SCRIPT_TAI_VIET: return "TaiViet";
456
0
  case UCDN_SCRIPT_AVESTAN: return "Avestan";
457
0
  case UCDN_SCRIPT_EGYPTIAN_HIEROGLYPHS: return "EgyptianHieroglyphs";
458
0
  case UCDN_SCRIPT_SAMARITAN: return "Samaritan";
459
0
  case UCDN_SCRIPT_LISU: return "Lisu";
460
0
  case UCDN_SCRIPT_BAMUM: return "Bamum";
461
0
  case UCDN_SCRIPT_JAVANESE: return "Javanese";
462
0
  case UCDN_SCRIPT_MEETEI_MAYEK: return "MeeteiMayek";
463
0
  case UCDN_SCRIPT_IMPERIAL_ARAMAIC: return "ImperialAramaic";
464
0
  case UCDN_SCRIPT_OLD_SOUTH_ARABIAN: return "OldSouthArabian";
465
0
  case UCDN_SCRIPT_INSCRIPTIONAL_PARTHIAN: return "InscriptionalParthian";
466
0
  case UCDN_SCRIPT_INSCRIPTIONAL_PAHLAVI: return "InscriptionalPahlavi";
467
0
  case UCDN_SCRIPT_OLD_TURKIC: return "OldTurkic";
468
0
  case UCDN_SCRIPT_KAITHI: return "Kaithi";
469
0
  case UCDN_SCRIPT_BATAK: return "Batak";
470
0
  case UCDN_SCRIPT_BRAHMI: return "Brahmi";
471
0
  case UCDN_SCRIPT_MANDAIC: return "Mandaic";
472
0
  case UCDN_SCRIPT_CHAKMA: return "Chakma";
473
0
  case UCDN_SCRIPT_MEROITIC_CURSIVE: return "Meroitic";
474
0
  case UCDN_SCRIPT_MEROITIC_HIEROGLYPHS: return "Meroitic";
475
0
  case UCDN_SCRIPT_MIAO: return "Miao";
476
0
  case UCDN_SCRIPT_SHARADA: return "Sharada";
477
0
  case UCDN_SCRIPT_SORA_SOMPENG: return "SoraSompeng";
478
0
  case UCDN_SCRIPT_TAKRI: return "Takri";
479
0
  case UCDN_SCRIPT_BASSA_VAH: return "BassaVah";
480
0
  case UCDN_SCRIPT_CAUCASIAN_ALBANIAN: return "CaucasianAlbanian";
481
0
  case UCDN_SCRIPT_DUPLOYAN: return "Duployan";
482
0
  case UCDN_SCRIPT_ELBASAN: return "Elbasan";
483
0
  case UCDN_SCRIPT_GRANTHA: return "Grantha";
484
0
  case UCDN_SCRIPT_KHOJKI: return "Khojki";
485
0
  case UCDN_SCRIPT_KHUDAWADI: return "Khudawadi";
486
0
  case UCDN_SCRIPT_LINEAR_A: return "LinearA";
487
0
  case UCDN_SCRIPT_MAHAJANI: return "Mahajani";
488
0
  case UCDN_SCRIPT_MANICHAEAN: return "Manichaean";
489
0
  case UCDN_SCRIPT_MENDE_KIKAKUI: return "MendeKikakui";
490
0
  case UCDN_SCRIPT_MODI: return "Modi";
491
0
  case UCDN_SCRIPT_MRO: return "Mro";
492
0
  case UCDN_SCRIPT_NABATAEAN: return "Nabataean";
493
0
  case UCDN_SCRIPT_OLD_NORTH_ARABIAN: return "OldNorthArabian";
494
0
  case UCDN_SCRIPT_OLD_PERMIC: return "OldPermic";
495
0
  case UCDN_SCRIPT_PAHAWH_HMONG: return "PahawhHmong";
496
0
  case UCDN_SCRIPT_PALMYRENE: return "Palmyrene";
497
0
  case UCDN_SCRIPT_PAU_CIN_HAU: return "PauCinHau";
498
0
  case UCDN_SCRIPT_PSALTER_PAHLAVI: return "PsalterPahlavi";
499
0
  case UCDN_SCRIPT_SIDDHAM: return "Siddham";
500
0
  case UCDN_SCRIPT_TIRHUTA: return "Tirhuta";
501
0
  case UCDN_SCRIPT_WARANG_CITI: return "WarangCiti";
502
0
  case UCDN_SCRIPT_AHOM: return "Ahom";
503
0
  case UCDN_SCRIPT_ANATOLIAN_HIEROGLYPHS: return "AnatolianHieroglyphs";
504
0
  case UCDN_SCRIPT_HATRAN: return "Hatran";
505
0
  case UCDN_SCRIPT_MULTANI: return "Multani";
506
0
  case UCDN_SCRIPT_OLD_HUNGARIAN: return "OldHungarian";
507
0
  case UCDN_SCRIPT_SIGNWRITING: return "SignWriting";
508
0
  case UCDN_SCRIPT_ADLAM: return "Adlam";
509
0
  case UCDN_SCRIPT_BHAIKSUKI: return "Bhaiksuki";
510
0
  case UCDN_SCRIPT_MARCHEN: return "Marchen";
511
0
  case UCDN_SCRIPT_NEWA: return "Newa";
512
0
  case UCDN_SCRIPT_OSAGE: return "Osage";
513
0
  case UCDN_SCRIPT_TANGUT: return "Tangut";
514
0
  case UCDN_SCRIPT_MASARAM_GONDI: return "MasaramGondi";
515
0
  case UCDN_SCRIPT_NUSHU: return "Nushu";
516
0
  case UCDN_SCRIPT_SOYOMBO: return "Soyombo";
517
0
  case UCDN_SCRIPT_ZANABAZAR_SQUARE: return "ZanabazarSquare";
518
0
  case UCDN_SCRIPT_DOGRA: return "Dogra";
519
0
  case UCDN_SCRIPT_GUNJALA_GONDI: return "GunjalaGondi";
520
0
  case UCDN_SCRIPT_HANIFI_ROHINGYA: return "HanifiRohingya";
521
0
  case UCDN_SCRIPT_MAKASAR: return "Makasar";
522
0
  case UCDN_SCRIPT_MEDEFAIDRIN: return "Medefaidrin";
523
0
  case UCDN_SCRIPT_OLD_SOGDIAN: return "OldSogdian";
524
0
  case UCDN_SCRIPT_SOGDIAN: return "Sogdian";
525
0
  case UCDN_SCRIPT_ELYMAIC: return "Elymaic";
526
0
  case UCDN_SCRIPT_NANDINAGARI: return "Nandinagari";
527
0
  case UCDN_SCRIPT_NYIAKENG_PUACHUE_HMONG: return "NyiakengPuachueHmong";
528
0
  case UCDN_SCRIPT_WANCHO: return "Wancho";
529
0
  case UCDN_SCRIPT_CHORASMIAN: return "Chorasmian";
530
0
  case UCDN_SCRIPT_DIVES_AKURU: return "DivesAkuru";
531
0
  case UCDN_SCRIPT_KHITAN_SMALL_SCRIPT: return "KhitanSmallScript";
532
0
  case UCDN_SCRIPT_YEZIDI: return "Yezidi";
533
0
  case UCDN_SCRIPT_VITHKUQI: return "Vithkuqi";
534
0
  case UCDN_SCRIPT_OLD_UYGHUR: return "OldUyghur";
535
0
  case UCDN_SCRIPT_CYPRO_MINOAN: return "CyproMinoan";
536
0
  case UCDN_SCRIPT_TANGSA: return "Tangsa";
537
0
  case UCDN_SCRIPT_TOTO: return "Toto";
538
0
  case UCDN_SCRIPT_KAWI: return "Kawi";
539
0
  case UCDN_SCRIPT_NAG_MUNDARI: return "NagMundari";
540
0
  }
541
0
}
542
543
const char *
544
fz_lookup_script_name(fz_context *ctx, int script, int language)
545
0
{
546
0
  switch (script) {
547
0
  case UCDN_SCRIPT_COMMON:
548
0
  case UCDN_SCRIPT_INHERITED:
549
0
  case UCDN_SCRIPT_UNKNOWN:
550
0
    return "Common";
551
0
  case UCDN_SCRIPT_LATIN: return "Latin";
552
0
  case UCDN_SCRIPT_GREEK: return "Greek";
553
0
  case UCDN_SCRIPT_CYRILLIC: return "Cyrillic";
554
0
  case UCDN_SCRIPT_ARABIC: return "Arabic";
555
0
  default: return fz_lookup_noto_stem_from_script(ctx, script, language);
556
0
  }
557
0
}