FcBool FcConfigAddCache (FcConfig *config, FcCache *cache, FcSetName set, FcStrSet *dirSet) { FcFontSet *fs; intptr_t *dirs; int i; /* * Add fonts */ fs = FcCacheSet (cache); if (fs) { int nref = 0; for (i = 0; i < fs->nfont; i++) { FcPattern *font = FcFontSetFont (fs, i); FcChar8 *font_file; /* * Check to see if font is banned by filename */ if (FcPatternObjectGetString (font, FC_FILE_OBJECT, 0, &font_file) == FcResultMatch && !FcConfigAcceptFilename (config, font_file)) { continue; } /* * Check to see if font is banned by pattern */ if (!FcConfigAcceptFont (config, font)) continue; if (FcFontSetAdd (config->fonts[set], font)) nref++; } FcDirCacheReference (cache, nref); } /* * Add directories */ dirs = FcCacheDirs (cache); if (dirs) { for (i = 0; i < cache->dirs_count; i++) { FcChar8 *dir = FcOffsetToPtr (dirs, dirs[i], FcChar8); if (FcConfigAcceptFilename (config, dir)) FcStrSetAddFilename (dirSet, dir); } } return FcTrue; }
FcFontSet * FcFontSetList (FcConfig *config, FcFontSet **sets, int nsets, FcPattern *p, FcObjectSet *os) { FcFontSet *ret; FcFontSet *s; int f; int set; FcListHashTable table; int i; FcListBucket *bucket; int destroy_os = 0; if (!config) { if (!FcInitBringUptoDate ()) goto bail0; config = FcConfigGetCurrent (); if (!config) goto bail0; } FcListHashTableInit (&table); if (!os) { os = FcObjectGetSet (); destroy_os = 1; } /* * Walk all available fonts adding those that * match to the hash table */ for (set = 0; set < nsets; set++) { s = sets[set]; if (!s) continue; for (f = 0; f < s->nfont; f++) if (FcListPatternMatchAny (p, /* pattern */ s->fonts[f])) /* font */ { FcChar8 *lang; if (FcPatternObjectGetString (p, FC_NAMELANG_OBJECT, 0, &lang) != FcResultMatch) { lang = FcGetDefaultLang (); } if (!FcListAppend (&table, s->fonts[f], os, lang)) goto bail1; } } #if 0 { int max = 0; int full = 0; int ents = 0; int len; for (i = 0; i < FC_LIST_HASH_SIZE; i++) { if ((bucket = table.buckets[i])) { len = 0; for (; bucket; bucket = bucket->next) { ents++; len++; } if (len > max) max = len; full++; } } printf ("used: %d max: %d avg: %g\n", full, max, (double) ents / FC_LIST_HASH_SIZE); } #endif /* * Walk the hash table and build * a font set */ ret = FcFontSetCreate (); if (!ret) goto bail0; for (i = 0; i < FC_LIST_HASH_SIZE; i++) while ((bucket = table.buckets[i])) { if (!FcFontSetAdd (ret, bucket->pattern)) goto bail2; table.buckets[i] = bucket->next; FcMemFree (FC_MEM_LISTBUCK, sizeof (FcListBucket)); free (bucket); } return ret; bail2: FcFontSetDestroy (ret); bail1: FcListHashTableCleanup (&table); bail0: if (destroy_os) FcObjectSetDestroy (os); return 0; }