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 bail6;
+ }
+ FcStrFree (cache_dir);
+ }
+ }
+#endif
config->blanks = 0;
return config;
+bail8:
+ FcFontSetDestroy (config->rejectPatterns);
+bail7:
+ FcFontSetDestroy (config->acceptPatterns);
bail6:
FcStrSetDestroy (config->rejectGlobs);
bail5:
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;
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;
}
FcTestDestroy (s->test);
if (s->edit)
FcEditDestroy (s->edit);
+ free (s);
+ FcMemFree (FC_MEM_SUBST, sizeof (FcSubst));
s = n;
}
}
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));
}
if (!cache)
goto bail1;
- FcGlobalCacheLoad (cache, config->cache);
+ if (config->cache)
+ FcGlobalCacheLoad (cache, config->cache);
list = FcConfigGetFontDirs (config);
if (!list)
if (FcDebug () & FC_DBG_FONTSET)
FcFontSetPrint (fonts);
- FcGlobalCacheSave (cache, config->cache);
+ if (config->cache)
+ FcGlobalCacheSave (cache, config->cache);
FcGlobalCacheDestroy (cache);
FcConfigSetFonts (config, fonts, FcSetSystem);
}
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 = left_o;
+ FcValue right = 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;
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;
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;
- break;
case FcOpNotContains:
- ret = FcStrStrIgnoreCase (m.u.s, v.u.s) == 0;
+ ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) != 0;
break;
default:
break;
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;
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;
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;
switch (op) {
case FcOpEqual:
case FcOpContains:
+ case FcOpListing:
ret = FcTrue;
break;
default:
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;
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;
while (e)
{
+ /* Compute the value of the match expression */
if (e->op == FcOpComma)
{
value = FcConfigEvaluate (p, e->u.tree.left);
for (v = values; v; v = v->next)
{
+ /* Compare the pattern value to the match expression value */
if (FcConfigCompareValue (v->value, t->op, value))
{
if (!ret)
void
FcConfigAppFontClear (FcConfig *config)
{
+ if (!config)
+ {
+ config = FcConfigGetCurrent ();
+ if (!config)
+ return;
+ }
+
FcConfigSetFonts (config, 0, FcSetApplication);
}
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;
+}