/*
* $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
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);
+
+ if (config->blanks)
+ FcBlanksDestroy (config->blanks);
if (config->cache)
FcStrFree (config->cache);
for (set = FcSetSystem; set <= FcSetApplication; set++)
if (config->fonts[set])
FcFontSetDestroy (config->fonts[set]);
+
free (config);
FcMemFree (FC_MEM_CONFIG, sizeof (FcConfig));
}
}
else if (v.type == FcTypeVoid && u.type == FcTypeMatrix)
{
- v.u.m = &FcIdentityMatrix;
+ v.u.mi = FcIdentityMatrix;
v.type = FcTypeMatrix;
}
else if (v.type == FcTypeString && u.type == FcTypeLangSet)
{
- v.u.l = FcLangSetPromote (v.u.s);
+ v.u.li = FcLangSetPtrCreateDynamic(FcLangSetPromote
+ (FcObjectPtrU(v.u.si)));
v.type = FcTypeLangSet;
}
return v;
switch (op) {
case FcOpEqual:
case FcOpListing:
- ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) == 0;
+ ret = FcStrCmpIgnoreCase (FcObjectPtrU(left.u.si),
+ FcObjectPtrU(right.u.si)) == 0;
break;
case FcOpContains:
- ret = FcStrStrIgnoreCase (left.u.s, right.u.s) != 0;
+ ret = FcStrStrIgnoreCase (FcObjectPtrU(left.u.si),
+ FcObjectPtrU(right.u.si)) != 0;
break;
case FcOpNotEqual:
- case FcOpNotContains:
ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) != 0;
break;
+ case FcOpNotContains:
+ ret = FcStrCmpIgnoreCase (FcObjectPtrU(left.u.si),
+ FcObjectPtrU(right.u.si)) == 0;
+ break;
default:
break;
}
case FcOpEqual:
case FcOpContains:
case FcOpListing:
- ret = FcMatrixEqual (left.u.m, right.u.m);
+ ret = FcMatrixEqual (FcMatrixPtrU(left.u.mi), FcMatrixPtrU(right.u.mi));
break;
case FcOpNotEqual:
case FcOpNotContains:
- ret = !FcMatrixEqual (left.u.m, right.u.m);
+ ret = !FcMatrixEqual (FcMatrixPtrU(left.u.mi), FcMatrixPtrU(right.u.mi));
break;
default:
break;
case FcOpContains:
case FcOpListing:
/* left contains right if right is a subset of left */
- ret = FcCharSetIsSubset (right.u.c, left.u.c);
+ ret = FcCharSetIsSubset (FcCharSetPtrU(right.u.ci), FcCharSetPtrU(left.u.ci));
break;
case FcOpNotContains:
/* left contains right if right is a subset of left */
- ret = !FcCharSetIsSubset (right.u.c, left.u.c);
+ ret = !FcCharSetIsSubset (FcCharSetPtrU(right.u.ci), FcCharSetPtrU(left.u.ci));
break;
case FcOpEqual:
- ret = FcCharSetEqual (left.u.c, right.u.c);
+ ret = FcCharSetEqual (FcCharSetPtrU(left.u.ci), FcCharSetPtrU(right.u.ci));
break;
case FcOpNotEqual:
- ret = !FcCharSetEqual (left.u.c, right.u.c);
+ ret = !FcCharSetEqual (FcCharSetPtrU(left.u.ci), FcCharSetPtrU(right.u.ci));
break;
default:
break;
switch (op) {
case FcOpContains:
case FcOpListing:
- ret = FcLangSetContains (left.u.l, right.u.l);
+ ret = FcLangSetContains (FcLangSetPtrU(left.u.li), FcLangSetPtrU(right.u.li));
break;
case FcOpNotContains:
- ret = FcLangSetContains (left.u.l, right.u.l);
+ ret = !FcLangSetContains (FcLangSetPtrU(left.u.li), FcLangSetPtrU(right.u.li));
break;
case FcOpEqual:
- ret = FcLangSetEqual (left.u.l, right.u.l);
+ ret = FcLangSetEqual (FcLangSetPtrU(left.u.li), FcLangSetPtrU(right.u.li));
break;
case FcOpNotEqual:
- ret = !FcLangSetEqual (left.u.l, right.u.l);
+ ret = !FcLangSetEqual (FcLangSetPtrU(left.u.li), FcLangSetPtrU(right.u.li));
break;
default:
break;
break;
case FcOpString:
v.type = FcTypeString;
- v.u.s = e->u.sval;
+ v.u.si = FcObjectPtrCreateDynamic(e->u.sval);
v = FcValueSave (v);
break;
case FcOpMatrix:
v.type = FcTypeMatrix;
- v.u.m = e->u.mval;
+ v.u.mi = FcMatrixPtrCreateDynamic(e->u.mval);
v = FcValueSave (v);
break;
case FcOpCharSet:
v.type = FcTypeCharSet;
- v.u.c = e->u.cval;
+ v.u.ci = FcCharSetPtrCreateDynamic(e->u.cval);
v = FcValueSave (v);
break;
case FcOpBool:
switch (e->op) {
case FcOpPlus:
v.type = FcTypeString;
- v.u.s = FcStrPlus (vl.u.s, vr.u.s);
- if (!v.u.s)
+ v.u.si = FcObjectPtrCreateDynamic
+ (FcStrPlus (FcObjectPtrU(vl.u.si),
+ FcObjectPtrU(vr.u.si)));
+
+ if (!FcObjectPtrU(v.u.si))
v.type = FcTypeVoid;
break;
default:
if (m)
{
FcMemAlloc (FC_MEM_MATRIX, sizeof (FcMatrix));
- FcMatrixMultiply (m, vl.u.m, vr.u.m);
- v.u.m = m;
+ FcMatrixMultiply (m, FcMatrixPtrU(vl.u.mi),
+ FcMatrixPtrU(vr.u.mi));
+ v.u.mi = FcMatrixPtrCreateDynamic(m);
}
else
{
e = 0;
}
- for (v = values; v; v = v->next)
+ for (v = values; v; v = FcValueListPtrU(v->next))
{
/* Compare the pattern value to the match expression value */
if (FcConfigCompareValue (v->value, t->op, value))
FcConfigValues (FcPattern *p, FcExpr *e, FcValueBinding binding)
{
FcValueList *l;
+ FcValueListPtr lp;
if (!e)
return 0;
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)
+ lp = FcValueListPtrCreateDynamic(l);
+ while (FcValueListPtrU(lp) && FcValueListPtrU(lp)->value.type == FcTypeVoid)
{
- FcValueList *next = l->next;
-
- FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
- free (l);
- l = next;
+ FcValueListPtr next = FcValueListPtrU(lp)->next;
+
+ if (lp.storage == FcStorageDynamic)
+ {
+ FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
+ free (l);
+ }
+ lp = 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;
}
}
if (FcDebug () & FC_DBG_EDIT)
{
- if (!*prev)
+ if (!FcValueListPtrU(*prev))
printf ("position not on list\n");
}
}
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)
}
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;
}
}
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
FcPatternElt *e = FcPatternFindElt (p, object);
if (!e)
return;
- if (!e->values)
+ if (!FcValueListPtrU(e->values))
FcPatternDel (p, object);
}
* 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)
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
#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] != '/')
void
FcConfigAppFontClear (FcConfig *config)
{
+ if (!config)
+ {
+ config = FcConfigGetCurrent ();
+ if (!config)
+ return;
+ }
+
FcConfigSetFonts (config, 0, FcSetApplication);
}
int i;
for (i = 0; i < globs->num; i++)
- if (FcConfigGlobMatch (globs->strs[i], string))
+ if (FcConfigGlobMatch (FcStrSetGet(globs, i), string))
return FcTrue;
return FcFalse;
}
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;
+}