X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=src%2Ffccfg.c;h=3c3681a100620e9c803e811aae0f55195121e340;hb=db50cbdaf592349c204ab0af0e7061ea72237044;hp=709cd42337c23b88c650b57acef7d07b82483534;hpb=92af858f2a7dcc972bf482397ac75d7e0ca38dd9;p=fontconfig.git diff --git a/src/fccfg.c b/src/fccfg.c index 709cd42..3c3681a 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -1,7 +1,7 @@ /* * $RCSId: xc/lib/fontconfig/src/fccfg.c,v 1.23 2002/08/31 22:17:32 keithp Exp $ * - * Copyright © 2000 Keith Packard + * Copyright © 2000 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -23,6 +23,8 @@ */ #include "fcint.h" +#include +#include #if defined (_WIN32) && (defined (PIC) || defined (DLL_EXPORT)) #define STRICT @@ -67,11 +69,48 @@ FcConfigCreate (void) if (!config->rejectGlobs) goto bail5; + config->acceptPatterns = FcFontSetCreate (); + if (!config->acceptPatterns) + goto bail6; + + config->rejectPatterns = FcFontSetCreate (); + if (!config->rejectPatterns) + goto bail7; + config->cache = 0; if (FcConfigHome()) if (!FcConfigSetCache (config, (FcChar8 *) ("~/" FC_USER_CACHE_FILE))) - goto bail6; + goto bail8; + +#ifdef _WIN32 + if (config->cache == 0) + { + /* If no home, use the temp folder. */ + FcChar8 dummy[1]; + int templen = GetTempPath (1, dummy); + FcChar8 *temp = malloc (templen + 1); + + if (temp) + { + FcChar8 *cache_dir; + + GetTempPath (templen + 1, temp); + cache_dir = FcStrPlus (temp, FC_USER_CACHE_FILE); + free (temp); + if (!FcConfigSetCache (config, cache_dir)) + { + FcStrFree (cache_dir); + goto bail8; + } + FcStrFree (cache_dir); + } + } +#endif + config->cacheDirs = FcStrSetCreate (); + if (!config->cacheDirs) + goto bail9; + config->blanks = 0; config->substPattern = 0; @@ -85,6 +124,12 @@ FcConfigCreate (void) return config; +bail9: + FcStrFree (config->cache); +bail8: + FcFontSetDestroy (config->rejectPatterns); +bail7: + FcFontSetDestroy (config->acceptPatterns); bail6: FcStrSetDestroy (config->rejectGlobs); bail5: @@ -102,11 +147,6 @@ bail0: return 0; } -typedef struct _FcFileTime { - time_t time; - FcBool set; -} FcFileTime; - static FcFileTime FcConfigNewestFile (FcStrSet *files) { @@ -120,12 +160,28 @@ FcConfigNewestFile (FcStrSet *files) while ((file = FcStrListNext (list))) if (stat ((char *) file, &statb) == 0) if (!newest.set || statb.st_mtime - newest.time > 0) + { + newest.set = FcTrue; newest.time = statb.st_mtime; + } FcStrListDone (list); } return newest; } +FcFileTime +FcConfigModifiedTime (FcConfig *config) +{ + if (!config) + { + FcFileTime v = { 0, FcFalse }; + config = FcConfigGetCurrent (); + if (!config) + return v; + } + return FcConfigNewestFile (config->configFiles); +} + FcBool FcConfigUptoDate (FcConfig *config) { @@ -138,9 +194,9 @@ FcConfigUptoDate (FcConfig *config) return FcFalse; } config_time = FcConfigNewestFile (config->configFiles); - font_time = FcConfigNewestFile (config->configDirs); + font_time = FcConfigNewestFile (config->fontDirs); if ((config_time.set && config_time.time - config->rescanTime > 0) || - (font_time.set && font_time.time - config->rescanTime) > 0) + (font_time.set && (font_time.time - config->rescanTime) > 0)) { return FcFalse; } @@ -160,6 +216,8 @@ FcSubstDestroy (FcSubst *s) FcTestDestroy (s->test); if (s->edit) FcEditDestroy (s->edit); + free (s); + FcMemFree (FC_MEM_SUBST, sizeof (FcSubst)); s = n; } } @@ -174,17 +232,25 @@ FcConfigDestroy (FcConfig *config) FcStrSetDestroy (config->configDirs); FcStrSetDestroy (config->fontDirs); + FcStrSetDestroy (config->cacheDirs); FcStrSetDestroy (config->configFiles); FcStrSetDestroy (config->acceptGlobs); FcStrSetDestroy (config->rejectGlobs); + FcFontSetDestroy (config->acceptPatterns); + FcFontSetDestroy (config->rejectPatterns); - FcStrFree (config->cache); + if (config->blanks) + FcBlanksDestroy (config->blanks); + + if (config->cache) + FcStrFree (config->cache); FcSubstDestroy (config->substPattern); FcSubstDestroy (config->substFont); for (set = FcSetSystem; set <= FcSetApplication; set++) if (config->fonts[set]) FcFontSetDestroy (config->fonts[set]); + free (config); FcMemFree (FC_MEM_CONFIG, sizeof (FcConfig)); } @@ -198,9 +264,10 @@ FcConfigDestroy (FcConfig *config) FcBool FcConfigBuildFonts (FcConfig *config) { - FcFontSet *fonts; + FcFontSet *fonts, *cached_fonts; FcGlobalCache *cache; FcStrList *list; + FcStrSet *oldDirs; FcChar8 *dir; fonts = FcFontSetCreate (); @@ -211,31 +278,73 @@ FcConfigBuildFonts (FcConfig *config) if (!cache) goto bail1; - FcGlobalCacheLoad (cache, config->cache); + oldDirs = FcStrSetCreate (); + if (!oldDirs) + goto bail2; - list = FcConfigGetFontDirs (config); - if (!list) - goto bail1; + if (config->cache) + FcGlobalCacheLoad (cache, oldDirs, config->cache, config); - while ((dir = FcStrListNext (list))) + cached_fonts = FcCacheRead(config, cache); + if (!cached_fonts) { - if (FcDebug () & FC_DBG_FONTSET) - printf ("scan dir %s\n", dir); - FcDirScanConfig (fonts, config->fontDirs, cache, - config->blanks, dir, FcFalse, config); + list = FcConfigGetFontDirs (config); + if (!list) + goto bail3; + + while ((dir = FcStrListNext (list))) + { + if (FcDebug () & FC_DBG_FONTSET) + printf ("build scan dir %s\n", dir); + FcDirScanConfig (fonts, config->fontDirs, cache, + config->blanks, dir, FcFalse, config); + } + + FcStrListDone (list); + } + else + { + int i; + + for (i = 0; i < oldDirs->num; i++) + { + if (FcDebug () & FC_DBG_FONTSET) + printf ("scan dir %s\n", oldDirs->strs[i]); + FcDirScanConfig (fonts, config->fontDirs, cache, + config->blanks, oldDirs->strs[i], + FcFalse, config); + } + + for (i = 0; i < cached_fonts->nfont; i++) + { + FcChar8 *cfn; + FcPatternGetString (cached_fonts->fonts[i], FC_FILE, 0, &cfn); + + if (FcConfigAcceptFont (config, cached_fonts->fonts[i]) && + (cfn && FcConfigAcceptFilename (config, cfn))) + FcFontSetAdd (fonts, cached_fonts->fonts[i]); + + cached_fonts->fonts[i] = 0; /* prevent free in FcFontSetDestroy */ + } + cached_fonts->nfont = 0; + FcFontSetDestroy (cached_fonts); } - - FcStrListDone (list); if (FcDebug () & FC_DBG_FONTSET) FcFontSetPrint (fonts); - FcGlobalCacheSave (cache, config->cache); + if (config->cache) + FcGlobalCacheSave (cache, config->cache, config); FcGlobalCacheDestroy (cache); + FcStrSetDestroy (oldDirs); FcConfigSetFonts (config, fonts, FcSetSystem); return FcTrue; +bail3: + FcStrSetDestroy (oldDirs); +bail2: + FcGlobalCacheDestroy (cache); bail1: FcFontSetDestroy (fonts); bail0: @@ -310,6 +419,25 @@ FcConfigGetFontDirs (FcConfig *config) return FcStrListCreate (config->fontDirs); } +FcBool +FcConfigAddCacheDir (FcConfig *config, + const FcChar8 *d) +{ + return FcStrSetAddFilename (config->cacheDirs, d); +} + +FcStrList * +FcConfigGetCacheDirs (FcConfig *config) +{ + if (!config) + { + config = FcConfigGetCurrent (); + if (!config) + return 0; + } + return FcStrListCreate (config->cacheDirs); +} + FcBool FcConfigAddConfigFile (FcConfig *config, const FcChar8 *f) @@ -404,17 +532,21 @@ FcBool FcConfigAddBlank (FcConfig *config, FcChar32 blank) { - FcBlanks *b; + FcBlanks *b, *freeme = 0; b = config->blanks; if (!b) { - b = FcBlanksCreate (); + freeme = b = FcBlanksCreate (); if (!b) return FcFalse; } if (!FcBlanksAdd (b, blank)) + { + if (freeme) + FcBlanksDestroy (freeme); return FcFalse; + } config->blanks = b; return FcTrue; } @@ -511,42 +643,43 @@ FcConfigPromote (FcValue v, FcValue u) } FcBool -FcConfigCompareValue (const FcValue m_o, +FcConfigCompareValue (const FcValue *left_o, FcOp op, - const FcValue v_o) + const FcValue *right_o) { - FcValue m = m_o; - FcValue v = v_o; + FcValue left = FcValueCanonicalize(left_o); + FcValue right = FcValueCanonicalize(right_o); FcBool ret = FcFalse; - m = FcConfigPromote (m, v); - v = FcConfigPromote (v, m); - if (m.type == v.type) + left = FcConfigPromote (left, right); + right = FcConfigPromote (right, left); + if (left.type == right.type) { - switch (m.type) { + switch (left.type) { case FcTypeInteger: break; /* FcConfigPromote prevents this from happening */ case FcTypeDouble: switch (op) { case FcOpEqual: case FcOpContains: - ret = m.u.d == v.u.d; + case FcOpListing: + ret = left.u.d == right.u.d; break; case FcOpNotEqual: case FcOpNotContains: - ret = m.u.d != v.u.d; + ret = left.u.d != right.u.d; break; case FcOpLess: - ret = m.u.d < v.u.d; + ret = left.u.d < right.u.d; break; case FcOpLessEqual: - ret = m.u.d <= v.u.d; + ret = left.u.d <= right.u.d; break; case FcOpMore: - ret = m.u.d > v.u.d; + ret = left.u.d > right.u.d; break; case FcOpMoreEqual: - ret = m.u.d >= v.u.d; + ret = left.u.d >= right.u.d; break; default: break; @@ -556,11 +689,12 @@ FcConfigCompareValue (const FcValue m_o, switch (op) { case FcOpEqual: case FcOpContains: - ret = m.u.b == v.u.b; + case FcOpListing: + ret = left.u.b == right.u.b; break; case FcOpNotEqual: case FcOpNotContains: - ret = m.u.b != v.u.b; + ret = left.u.b != right.u.b; break; default: break; @@ -569,16 +703,17 @@ FcConfigCompareValue (const FcValue m_o, case FcTypeString: switch (op) { case FcOpEqual: - ret = FcStrCmpIgnoreCase (m.u.s, v.u.s) == 0; + case FcOpListing: + ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) == 0; break; case FcOpContains: - ret = FcStrStrIgnoreCase (m.u.s, v.u.s) != 0; + ret = FcStrStrIgnoreCase (left.u.s, right.u.s) != 0; break; case FcOpNotEqual: - ret = FcStrCmpIgnoreCase (m.u.s, v.u.s) != 0; + ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) != 0; break; case FcOpNotContains: - ret = FcStrStrIgnoreCase (m.u.s, v.u.s) == 0; + ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) == 0; break; default: break; @@ -588,11 +723,12 @@ FcConfigCompareValue (const FcValue m_o, switch (op) { case FcOpEqual: case FcOpContains: - ret = FcMatrixEqual (m.u.m, v.u.m); + case FcOpListing: + ret = FcMatrixEqual (left.u.m, right.u.m); break; case FcOpNotEqual: case FcOpNotContains: - ret = !FcMatrixEqual (m.u.m, v.u.m); + ret = !FcMatrixEqual (left.u.m, right.u.m); break; default: break; @@ -601,18 +737,19 @@ FcConfigCompareValue (const FcValue m_o, case FcTypeCharSet: switch (op) { case FcOpContains: - /* v contains m if m is a subset of v */ - ret = FcCharSetIsSubset (m.u.c, v.u.c); + case FcOpListing: + /* left contains right if right is a subset of left */ + ret = FcCharSetIsSubset (right.u.c, left.u.c); break; case FcOpNotContains: - /* v contains m if m is a subset of v */ - ret = !FcCharSetIsSubset (m.u.c, v.u.c); + /* left contains right if right is a subset of left */ + ret = !FcCharSetIsSubset (right.u.c, left.u.c); break; case FcOpEqual: - ret = FcCharSetEqual (m.u.c, v.u.c); + ret = FcCharSetEqual (left.u.c, right.u.c); break; case FcOpNotEqual: - ret = !FcCharSetEqual (m.u.c, v.u.c); + ret = !FcCharSetEqual (left.u.c, right.u.c); break; default: break; @@ -621,16 +758,17 @@ FcConfigCompareValue (const FcValue m_o, case FcTypeLangSet: switch (op) { case FcOpContains: - ret = FcLangSetContains (m.u.l, v.u.l); + case FcOpListing: + ret = FcLangSetContains (left.u.l, right.u.l); break; case FcOpNotContains: - ret = FcLangSetContains (m.u.l, v.u.l); + ret = !FcLangSetContains (left.u.l, right.u.l); break; case FcOpEqual: - ret = FcLangSetEqual (m.u.l, v.u.l); + ret = FcLangSetEqual (left.u.l, right.u.l); break; case FcOpNotEqual: - ret = !FcLangSetEqual (m.u.l, v.u.l); + ret = !FcLangSetEqual (left.u.l, right.u.l); break; default: break; @@ -640,6 +778,7 @@ FcConfigCompareValue (const FcValue m_o, switch (op) { case FcOpEqual: case FcOpContains: + case FcOpListing: ret = FcTrue; break; default: @@ -650,11 +789,12 @@ FcConfigCompareValue (const FcValue m_o, switch (op) { case FcOpEqual: case FcOpContains: - ret = m.u.f == v.u.f; + case FcOpListing: + ret = left.u.f == right.u.f; break; case FcOpNotEqual: case FcOpNotContains: - ret = m.u.f != v.u.f; + ret = left.u.f != right.u.f; break; default: break; @@ -684,6 +824,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) FcValue v, vl, vr; FcResult r; FcMatrix *m; + FcChar8 *str; switch (e->op) { case FcOpInteger: @@ -696,8 +837,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) break; case FcOpString: v.type = FcTypeString; - v.u.s = e->u.sval; - v = FcValueSave (v); + v.u.s = FcStrStaticName(e->u.sval); break; case FcOpMatrix: v.type = FcTypeMatrix; @@ -717,6 +857,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) r = FcPatternGet (p, e->u.field, 0, &v); if (r != FcResultMatch) v.type = FcTypeVoid; + v = FcValueSave (v); break; case FcOpConst: if (FcNameConstant (e->u.constant, &v.u.i)) @@ -745,10 +886,11 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) case FcOpMoreEqual: case FcOpContains: case FcOpNotContains: + case FcOpListing: vl = FcConfigEvaluate (p, e->u.tree.left); vr = FcConfigEvaluate (p, e->u.tree.right); v.type = FcTypeBool; - v.u.b = FcConfigCompareValue (vl, e->op, vr); + v.u.b = FcConfigCompareValue (&vl, e->op, &vr); FcValueDestroy (vl); FcValueDestroy (vr); break; @@ -813,7 +955,10 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) switch (e->op) { case FcOpPlus: v.type = FcTypeString; - v.u.s = FcStrPlus (vl.u.s, vr.u.s); + str = FcStrPlus (vl.u.s, vr.u.s); + v.u.s = FcStrStaticName (str); + FcStrFree (str); + if (!v.u.s) v.type = FcTypeVoid; break; @@ -949,6 +1094,7 @@ FcConfigMatchValueList (FcPattern *p, while (e) { + /* Compute the value of the match expression */ if (e->op == FcOpComma) { value = FcConfigEvaluate (p, e->u.tree.left); @@ -960,9 +1106,10 @@ FcConfigMatchValueList (FcPattern *p, e = 0; } - for (v = values; v; v = v->next) + for (v = values; v; v = FcValueListPtrU(v->next)) { - if (FcConfigCompareValue (v->value, t->op, value)) + /* Compare the pattern value to the match expression value */ + if (FcConfigCompareValue (&v->value, t->op, &value)) { if (!ret) ret = v; @@ -995,56 +1142,60 @@ FcConfigValues (FcPattern *p, FcExpr *e, FcValueBinding binding) if (e->op == FcOpComma) { l->value = FcConfigEvaluate (p, e->u.tree.left); - l->next = FcConfigValues (p, e->u.tree.right, binding); + l->next = FcValueListPtrCreateDynamic(FcConfigValues (p, e->u.tree.right, binding)); } else { l->value = FcConfigEvaluate (p, e); - l->next = 0; + l->next = FcValueListPtrCreateDynamic(0); } l->binding = binding; - while (l && l->value.type == FcTypeVoid) + if (l->value.type == FcTypeVoid) { - FcValueList *next = l->next; - + FcValueList *next = FcValueListPtrU(l->next); + FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList)); free (l); l = next; } + return l; } static FcBool -FcConfigAdd (FcValueList **head, +FcConfigAdd (FcValueListPtr *head, FcValueList *position, FcBool append, FcValueList *new) { - FcValueList **prev, *last, *v; + FcValueListPtr *prev, last, v; FcValueBinding sameBinding; if (position) sameBinding = position->binding; else sameBinding = FcValueBindingWeak; - for (v = new; v; v = v->next) - if (v->binding == FcValueBindingSame) - v->binding = sameBinding; + for (v = FcValueListPtrCreateDynamic(new); FcValueListPtrU(v); + v = FcValueListPtrU(v)->next) + if (FcValueListPtrU(v)->binding == FcValueBindingSame) + FcValueListPtrU(v)->binding = sameBinding; if (append) { if (position) prev = &position->next; else - for (prev = head; *prev; prev = &(*prev)->next) + for (prev = head; FcValueListPtrU(*prev); + prev = &(FcValueListPtrU(*prev)->next)) ; } else { if (position) { - for (prev = head; *prev; prev = &(*prev)->next) + for (prev = head; FcValueListPtrU(*prev); + prev = &(FcValueListPtrU(*prev)->next)) { - if (*prev == position) + if (FcValueListPtrU(*prev) == position) break; } } @@ -1053,7 +1204,7 @@ FcConfigAdd (FcValueList **head, if (FcDebug () & FC_DBG_EDIT) { - if (!*prev) + if (!FcValueListPtrU(*prev)) printf ("position not on list\n"); } } @@ -1067,12 +1218,12 @@ FcConfigAdd (FcValueList **head, if (new) { - last = new; - while (last->next) - last = last->next; + last = FcValueListPtrCreateDynamic(new); + while (FcValueListPtrU(FcValueListPtrU(last)->next)) + last = FcValueListPtrU(last)->next; - last->next = *prev; - *prev = new; + FcValueListPtrU(last)->next = *prev; + *prev = FcValueListPtrCreateDynamic(new); } if (FcDebug () & FC_DBG_EDIT) @@ -1086,18 +1237,19 @@ FcConfigAdd (FcValueList **head, } static void -FcConfigDel (FcValueList **head, +FcConfigDel (FcValueListPtr *head, FcValueList *position) { - FcValueList **prev; + FcValueListPtr *prev; - for (prev = head; *prev; prev = &(*prev)->next) + for (prev = head; FcValueListPtrU(*prev); + prev = &(FcValueListPtrU(*prev)->next)) { - if (*prev == position) + if (FcValueListPtrU(*prev) == position) { *prev = position->next; - position->next = 0; - FcValueListDestroy (position); + position->next = FcValueListPtrCreateDynamic(0); + FcValueListDestroy (FcValueListPtrCreateDynamic(position)); break; } } @@ -1129,8 +1281,8 @@ FcConfigPatternDel (FcPattern *p, FcPatternElt *e = FcPatternFindElt (p, object); if (!e) return; - while (e->values) - FcConfigDel (&e->values, e->values); + while (FcValueListPtrU(e->values)) + FcConfigDel (&e->values, FcValueListPtrU(e->values)); } static void @@ -1140,7 +1292,7 @@ FcConfigPatternCanon (FcPattern *p, FcPatternElt *e = FcPatternFindElt (p, object); if (!e) return; - if (!e->values) + if (!FcValueListPtrU(e->values)) FcPatternDel (p, object); } @@ -1219,12 +1371,12 @@ FcConfigSubstituteWithPat (FcConfig *config, * Check to see if there is a match, mark the location * to apply match-relative edits */ - st[i].value = FcConfigMatchValueList (m, t, st[i].elt->values); + st[i].value = FcConfigMatchValueList (m, t, FcValueListPtrU(st[i].elt->values)); if (!st[i].value) break; - if (t->qual == FcQualFirst && st[i].value != st[i].elt->values) + if (t->qual == FcQualFirst && st[i].value != FcValueListPtrU(st[i].elt->values)) break; - if (t->qual == FcQualNotFirst && st[i].value == st[i].elt->values) + if (t->qual == FcQualNotFirst && st[i].value == FcValueListPtrU(st[i].elt->values)) break; } if (t) @@ -1277,7 +1429,7 @@ FcConfigSubstituteWithPat (FcConfig *config, if (t) { FcValueList *thisValue = st[i].value; - FcValueList *nextValue = thisValue ? thisValue->next : 0; + FcValueList *nextValue = thisValue ? FcValueListPtrU(thisValue->next) : 0; /* * Append the new list of values after the current value @@ -1286,7 +1438,8 @@ FcConfigSubstituteWithPat (FcConfig *config, /* * Delete the marked value */ - FcConfigDel (&st[i].elt->values, thisValue); + if (thisValue) + FcConfigDel (&st[i].elt->values, thisValue); /* * Adjust any pointers into the value list to ensure * future edits occur at the same place @@ -1341,6 +1494,7 @@ FcConfigSubstituteWithPat (FcConfig *config, FcConfigPatternAdd (p, e->field, l, FcTrue); break; default: + FcValueListDestroy (FcValueListPtrCreateDynamic(l)); break; } } @@ -1443,7 +1597,9 @@ FcConfigFileExists (const FcChar8 *dir, const FcChar8 *file) #ifdef _WIN32 if ((!path[0] || (path[strlen((char *) path)-1] != '/' && path[strlen((char *) path)-1] != '\\')) && - (file[0] != '/' && file[0] != '\\')) + !(file[0] == '/' || + file[0] == '\\' || + (isalpha (file[0]) && file[1] == ':' && (file[2] == '/' || file[2] == '\\')))) strcat ((char *) path, "\\"); #else if ((!path[0] || path[strlen((char *) path)-1] != '/') && file[0] != '/') @@ -1543,7 +1699,7 @@ FcConfigHome (void) home = getenv ("USERPROFILE"); #endif - return home; + return (FcChar8 *) home; } return 0; } @@ -1656,6 +1812,7 @@ FcConfigAppFontAddFile (FcConfig *config, } FcStrListDone (sublist); } + FcStrSetDestroy (subdirs); return FcTrue; } @@ -1703,12 +1860,20 @@ FcConfigAppFontAddDir (FcConfig *config, } FcStrListDone (sublist); } + FcStrSetDestroy (subdirs); return FcTrue; } void FcConfigAppFontClear (FcConfig *config) { + if (!config) + { + config = FcConfigGetCurrent (); + if (!config) + return; + } + FcConfigSetFonts (config, 0, FcSetApplication); } @@ -1784,3 +1949,40 @@ FcConfigAcceptFilename (FcConfig *config, return FcFalse; return FcTrue; } + +/* + * Manage font-pattern based font source selectors + */ + +FcBool +FcConfigPatternsAdd (FcConfig *config, + FcPattern *pattern, + FcBool accept) +{ + FcFontSet *set = accept ? config->acceptPatterns : config->rejectPatterns; + + return FcFontSetAdd (set, pattern); +} + +static FcBool +FcConfigPatternsMatch (const FcFontSet *patterns, + const FcPattern *font) +{ + int i; + + for (i = 0; i < patterns->nfont; i++) + if (FcListPatternMatchAny (patterns->fonts[i], font)) + return FcTrue; + return FcFalse; +} + +FcBool +FcConfigAcceptFont (FcConfig *config, + const FcPattern *font) +{ + if (FcConfigPatternsMatch (config->acceptPatterns, font)) + return FcTrue; + if (FcConfigPatternsMatch (config->rejectPatterns, font)) + return FcFalse; + return FcTrue; +}