FcStrSet *FcGetDefaultLangs(void) { FcStrSet *result; retry: result = (FcStrSet *)fc_atomic_ptr_get(&default_langs); if (!result) { char *langs; result = FcStrSetCreate(); langs = getenv("FC_LANG"); if (!langs || !langs[0]) langs = getenv("LC_ALL"); if (!langs || !langs[0]) langs = getenv("LC_CTYPE"); if (!langs || !langs[0]) langs = getenv("LANG"); if (langs && langs[0]) { if (!FcStrSetAddLangs(result, langs)) FcStrSetAdd(result, (const FcChar8 *)"en"); } else FcStrSetAdd(result, (const FcChar8 *)"en"); FcRefSetConst(&result->ref); if (!fc_atomic_ptr_cmpexch(&default_langs, NULL, result)) { FcRefInit(&result->ref, 1); FcStrSetDestroy(result); goto retry; } } return result; }
FcPattern *FcPatternCreate(void) { FcPattern *p; p = (FcPattern *)malloc(sizeof(FcPattern)); if (!p) return 0; memset(p, 0, sizeof(FcPattern)); p->num = 0; p->size = 0; p->elts_offset = FcPtrToOffset(p, NULL); FcRefInit(&p->ref, 1); return p; }
void FcDefaultFini (void) { FcChar8 *lang; FcStrSet *langs; lang = fc_atomic_ptr_get (&default_lang); if (lang && fc_atomic_ptr_cmpexch (&default_lang, lang, NULL)) { free (lang); } langs = fc_atomic_ptr_get (&default_langs); if (langs && fc_atomic_ptr_cmpexch (&default_langs, langs, NULL)) { FcRefInit (&langs->ref, 1); FcStrSetDestroy (langs); } }
FcConfig * FcConfigCreate (void) { FcSetName set; FcConfig *config; config = malloc (sizeof (FcConfig)); if (!config) goto bail0; config->configDirs = FcStrSetCreate (); if (!config->configDirs) goto bail1; config->configFiles = FcStrSetCreate (); if (!config->configFiles) goto bail2; config->fontDirs = FcStrSetCreate (); if (!config->fontDirs) goto bail3; config->acceptGlobs = FcStrSetCreate (); if (!config->acceptGlobs) goto bail4; config->rejectGlobs = FcStrSetCreate (); if (!config->rejectGlobs) goto bail5; config->acceptPatterns = FcFontSetCreate (); if (!config->acceptPatterns) goto bail6; config->rejectPatterns = FcFontSetCreate (); if (!config->rejectPatterns) goto bail7; config->cacheDirs = FcStrSetCreate (); if (!config->cacheDirs) goto bail8; config->blanks = 0; config->substPattern = 0; config->substFont = 0; config->substScan = 0; config->maxObjects = 0; for (set = FcSetSystem; set <= FcSetApplication; set++) config->fonts[set] = 0; config->rescanTime = time(0); config->rescanInterval = 30; config->expr_pool = NULL; config->sysRoot = NULL; FcRefInit (&config->ref, 1); return config; bail8: FcFontSetDestroy (config->rejectPatterns); bail7: FcFontSetDestroy (config->acceptPatterns); bail6: FcStrSetDestroy (config->rejectGlobs); bail5: FcStrSetDestroy (config->acceptGlobs); bail4: FcStrSetDestroy (config->fontDirs); bail3: FcStrSetDestroy (config->configFiles); bail2: FcStrSetDestroy (config->configDirs); bail1: free (config); bail0: return 0; }
/* * Insert cache into the list */ static FcBool FcCacheInsert (FcCache *cache, struct stat *cache_stat) { FcCacheSkip **update[FC_CACHE_MAX_LEVEL]; FcCacheSkip *s, **next; int i, level; lock_cache (); /* * Find links along each chain */ next = fcCacheChains; for (i = fcCacheMaxLevel; --i >= 0; ) { for (; (s = next[i]); next = s->next) if (s->cache > cache) break; update[i] = &next[i]; } /* * Create new list element */ level = random_level (); if (level > fcCacheMaxLevel) { level = fcCacheMaxLevel + 1; update[fcCacheMaxLevel] = &fcCacheChains[fcCacheMaxLevel]; fcCacheMaxLevel = level; } s = malloc (sizeof (FcCacheSkip) + (level - 1) * sizeof (FcCacheSkip *)); if (!s) return FcFalse; s->cache = cache; s->size = cache->size; FcRefInit (&s->ref, 1); if (cache_stat) { s->cache_dev = cache_stat->st_dev; s->cache_ino = cache_stat->st_ino; s->cache_mtime = cache_stat->st_mtime; #ifdef HAVE_STRUCT_STAT_ST_MTIM s->cache_mtime_nano = cache_stat->st_mtim.tv_nsec; #else s->cache_mtime_nano = 0; #endif } else { s->cache_dev = 0; s->cache_ino = 0; s->cache_mtime = 0; s->cache_mtime_nano = 0; } /* * Insert into all fcCacheChains */ for (i = 0; i < level; i++) { s->next[i] = *update[i]; *update[i] = s; } unlock_cache (); return FcTrue; }