static gboolean language_has_font (const gchar *locale) { const FcCharSet *charset; FcPattern *pattern; FcObjectSet *object_set; FcFontSet *font_set; gchar *language_code; gboolean is_displayable; is_displayable = FALSE; pattern = NULL; object_set = NULL; font_set = NULL; if (!gdm_parse_language_name (locale, &language_code, NULL, NULL, NULL)) return FALSE; charset = FcLangGetCharSet ((FcChar8 *) language_code); if (!charset) { /* fontconfig does not know about this language */ is_displayable = TRUE; } else { /* see if any fonts support rendering it */ pattern = FcPatternBuild (NULL, FC_LANG, FcTypeString, language_code, NULL); if (pattern == NULL) goto done; object_set = FcObjectSetCreate (); if (object_set == NULL) goto done; font_set = FcFontList (NULL, pattern, object_set); if (font_set == NULL) goto done; is_displayable = (font_set->nfont > 0); } done: if (font_set != NULL) FcFontSetDestroy (font_set); if (object_set != NULL) FcObjectSetDestroy (object_set); if (pattern != NULL) FcPatternDestroy (pattern); g_free (language_code); return is_displayable; }
FcLangSet * FcFreeTypeLangSet (const FcCharSet *charset, const FcChar8 *exclusiveLang) { int i, j; FcChar32 missing; const FcCharSet *exclusiveCharset = 0; FcLangSet *ls; if (exclusiveLang) exclusiveCharset = FcLangGetCharSet (exclusiveLang); ls = FcLangSetCreate (); if (!ls) return 0; if (FcDebug() & FC_DBG_LANGSET) { printf ("font charset\n"); FcCharSetPrint (charset); printf ("\n"); } for (i = 0; i < NUM_LANG_CHAR_SET; i++) { if (FcDebug() & FC_DBG_LANGSET) { printf ("%s charset\n", fcLangCharSets[i].lang); FcCharSetPrint (&fcLangCharSets[i].charset); printf ("\n"); } /* * Check for Han charsets to make fonts * which advertise support for a single language * not support other Han languages */ if (exclusiveCharset && FcFreeTypeIsExclusiveLang (fcLangCharSets[i].lang)) { if (fcLangCharSets[i].charset.num != exclusiveCharset->num) continue; for (j = 0; j < fcLangCharSets[i].charset.num; j++) if (FcCharSetLeaf(&fcLangCharSets[i].charset, j) != FcCharSetLeaf(exclusiveCharset, j)) continue; } missing = FcCharSetSubtractCount (&fcLangCharSets[i].charset, charset); if (FcDebug() & FC_DBG_SCANV) { if (missing && missing < 10) { FcCharSet *missed = FcCharSetSubtract (&fcLangCharSets[i].charset, charset); FcChar32 ucs4; FcChar32 map[FC_CHARSET_MAP_SIZE]; FcChar32 next; printf ("\n%s(%u) ", fcLangCharSets[i].lang, missing); printf ("{"); for (ucs4 = FcCharSetFirstPage (missed, map, &next); ucs4 != FC_CHARSET_DONE; ucs4 = FcCharSetNextPage (missed, map, &next)) { int i, j; for (i = 0; i < FC_CHARSET_MAP_SIZE; i++) if (map[i]) { for (j = 0; j < 32; j++) if (map[i] & (1 << j)) printf (" %04x", ucs4 + i * 32 + j); } } printf (" }\n\t"); FcCharSetDestroy (missed); } else printf ("%s(%u) ", fcLangCharSets[i].lang, missing); } if (!missing) FcLangSetBitSet (ls, i); } if (FcDebug() & FC_DBG_SCANV) printf ("\n"); return ls; }
int main (int argc, char **argv) { int index_set = 0; int set_index = 0; FcChar8 *lang = NULL; const FcCharSet *fcs_lang = NULL; int err = 0; int i; FT_Library ftlib; FcBool verbose = FcFalse; #if HAVE_GETOPT_LONG || HAVE_GETOPT int c; setlocale (LC_ALL, ""); #if HAVE_GETOPT_LONG while ((c = getopt_long (argc, argv, "i:l:mVhv", longopts, NULL)) != -1) #else while ((c = getopt (argc, argv, "i:l:mVhv")) != -1) #endif { switch (c) { case 'i': index_set = 1; set_index = atoi (optarg); break; case 'l': lang = (FcChar8 *) FcLangNormalize ((const FcChar8 *) optarg); break; case 'v': verbose = FcTrue; break; case 'V': fprintf (stderr, "fontconfig version %d.%d.%d\n", FC_MAJOR, FC_MINOR, FC_REVISION); exit (0); case 'h': usage (argv[0], 0); default: usage (argv[0], 1); } } i = optind; #else i = 1; verbose = FcTrue; #endif if (i == argc) usage (argv[0], 1); if (!lang) lang = FcLangNormalize ((const FcChar8 *) setlocale (LC_CTYPE, NULL)); if (lang) fcs_lang = FcLangGetCharSet (lang); if (FT_Init_FreeType (&ftlib)) { fprintf (stderr, _("Can't initalize FreeType library\n")); return 1; } for (; i < argc; i++) { int index; index = set_index; do { FT_Face face; FcCharSet *fcs, *fcs_sub; if (FT_New_Face (ftlib, argv[i], index, &face)) { if (!index_set && index > 0) break; fprintf (stderr, _("Unable to open %s\n"), argv[i]); err = 1; } else { FcChar32 count; fcs = FcFreeTypeCharSet (face, NULL); fcs_sub = FcCharSetSubtract (fcs_lang, fcs); count = FcCharSetCount (fcs_sub); if (count > 0) { FcChar32 ucs4, pos, map[FC_CHARSET_MAP_SIZE]; printf (_("%s:%d Missing %d glyph(s) to satisfy the coverage for %s language\n"), argv[i], index, count, lang); if (verbose) { for (ucs4 = FcCharSetFirstPage (fcs_sub, map, &pos); ucs4 != FC_CHARSET_DONE; ucs4 = FcCharSetNextPage (fcs_sub, map, &pos)) { int j; for (j = 0; j < FC_CHARSET_MAP_SIZE; j++) { FcChar32 bits = map[j]; FcChar32 base = ucs4 + j * 32; int b = 0; while (bits) { if (bits & 1) printf (" 0x%04x\n", base + b); bits >>= 1; b++; } } } } } else { printf (_("%s:%d Satisfy the coverage for %s language\n"), argv[i], index, lang); } FcCharSetDestroy (fcs); FcCharSetDestroy (fcs_sub); FT_Done_Face (face); } index++; } while (index_set == 0);