/*
- * $XFree86: xc/lib/fontconfig/src/fccfg.c,v 1.11 2002/06/08 17:32:04 keithp Exp $
+ * $XFree86: xc/lib/fontconfig/src/fccfg.c,v 1.19 2002/08/11 18:10:42 keithp Exp $
*
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
*
return 0;
}
-static time_t
+typedef struct _FcFileTime {
+ time_t time;
+ FcBool set;
+} FcFileTime;
+
+static FcFileTime
FcConfigNewestFile (FcStrSet *files)
{
FcStrList *list = FcStrListCreate (files);
- FcBool set = FcFalse;
- time_t newest = 0;
+ FcFileTime newest = { 0, FcFalse };
FcChar8 *file;
struct stat statb;
if (list)
{
while ((file = FcStrListNext (list)))
- {
if (stat ((char *) file, &statb) == 0)
- {
- if (!set)
- newest = statb.st_mtime;
- else if (statb.st_mtime - newest > 0)
- newest = statb.st_mtime;
- }
- }
+ if (!newest.set || statb.st_mtime - newest.time > 0)
+ newest.time = statb.st_mtime;
FcStrListDone (list);
}
return newest;
FcBool
FcConfigUptoDate (FcConfig *config)
{
- time_t config_time;
- time_t font_time;
- time_t now = time(0);
+ FcFileTime config_time, font_time;
+ time_t now = time(0);
if (!config)
{
config = FcConfigGetCurrent ();
}
config_time = FcConfigNewestFile (config->configFiles);
font_time = FcConfigNewestFile (config->configDirs);
- if (config_time - config->rescanTime > 0 ||
- font_time - config->rescanTime > 0)
+ if ((config_time.set && config_time.time - config->rescanTime > 0) ||
+ (font_time.set && font_time.time - config->rescanTime) > 0)
{
return FcFalse;
}
FcBool
FcConfigBuildFonts (FcConfig *config)
{
- FcFontSet *fonts;
- FcFileCache *cache;
- FcStrList *list;
- FcChar8 *dir;
+ FcFontSet *fonts;
+ FcGlobalCache *cache;
+ FcStrList *list;
+ FcChar8 *dir;
fonts = FcFontSetCreate ();
if (!fonts)
goto bail0;
- cache = FcFileCacheCreate ();
+ cache = FcGlobalCacheCreate ();
if (!cache)
goto bail1;
- FcFileCacheLoad (cache, config->cache);
+ FcGlobalCacheLoad (cache, config->cache);
list = FcConfigGetFontDirs (config);
if (!list)
if (FcDebug () & FC_DBG_FONTSET)
FcFontSetPrint (fonts);
- FcFileCacheSave (cache, config->cache);
- FcFileCacheDestroy (cache);
+ FcGlobalCacheSave (cache, config->cache);
+ FcGlobalCacheDestroy (cache);
FcConfigSetFonts (config, fonts, FcSetSystem);
subst->next = 0;
subst->test = test;
subst->edit = edit;
- if (FcDebug () & FC_DBG_EDIT)
- {
- printf ("Add Subst ");
- FcSubstPrint (subst);
- }
num = 0;
for (t = test; t; t = t->next)
+ {
+ if (t->kind == FcMatchDefault)
+ t->kind = kind;
num++;
+ }
if (config->maxObjects < num)
config->maxObjects = num;
+ if (FcDebug () & FC_DBG_EDIT)
+ {
+ printf ("Add Subst ");
+ FcSubstPrint (subst);
+ }
return FcTrue;
}
FcValueList *value;
} FcSubState;
-static const FcMatrix FcIdentityMatrix = { 1, 0, 0, 1 };
-
static FcValue
FcConfigPromote (FcValue v, FcValue u)
{
}
else if (v.type == FcTypeVoid && u.type == FcTypeMatrix)
{
- v.u.m = FcMatrixCopy (&FcIdentityMatrix);
- if (v.u.m)
- v.type = FcTypeMatrix;
+ v.u.m = &FcIdentityMatrix;
+ v.type = FcTypeMatrix;
}
return v;
}
v = FcConfigPromote (v, m);
if (m.type == v.type)
{
- ret = FcFalse;
switch (m.type) {
case FcTypeInteger:
break; /* FcConfigPromote prevents this from happening */
default:
break;
}
+ break;
}
}
else
v.type = FcTypeVoid;
FcValueDestroy (vl);
break;
- case FcOpOr:
- case FcOpAnd:
- case FcOpEqual:
case FcOpContains:
case FcOpNotEqual:
case FcOpLess:
case FcOpLessEqual:
case FcOpMore:
case FcOpMoreEqual:
+ 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);
+ FcValueDestroy (vl);
+ FcValueDestroy (vr);
+ break;
+ case FcOpOr:
+ case FcOpAnd:
+ case FcOpEqual:
case FcOpPlus:
case FcOpMinus:
case FcOpTimes:
v.type = FcTypeDouble;
v.u.d = vl.u.d / vr.u.d;
break;
- case FcOpEqual:
- case FcOpContains:
- v.type = FcTypeBool;
- v.u.b = vl.u.d == vr.u.d;
- break;
- case FcOpNotEqual:
- v.type = FcTypeBool;
- v.u.b = vl.u.d != vr.u.d;
- break;
- case FcOpLess:
- v.type = FcTypeBool;
- v.u.b = vl.u.d < vr.u.d;
- break;
- case FcOpLessEqual:
- v.type = FcTypeBool;
- v.u.b = vl.u.d <= vr.u.d;
- break;
- case FcOpMore:
- v.type = FcTypeBool;
- v.u.b = vl.u.d > vr.u.d;
- break;
- case FcOpMoreEqual:
- v.type = FcTypeBool;
- v.u.b = vl.u.d >= vr.u.d;
- break;
default:
v.type = FcTypeVoid;
break;
v.type = FcTypeBool;
v.u.b = vl.u.b && vr.u.b;
break;
- case FcOpEqual:
- case FcOpContains:
- v.type = FcTypeBool;
- v.u.b = vl.u.b == vr.u.b;
- break;
- case FcOpNotEqual:
- v.type = FcTypeBool;
- v.u.b = vl.u.b != vr.u.b;
- break;
default:
v.type = FcTypeVoid;
break;
break;
case FcTypeString:
switch (e->op) {
- case FcOpEqual:
- case FcOpContains:
- v.type = FcTypeBool;
- v.u.b = FcStrCmpIgnoreCase (vl.u.s, vr.u.s) == 0;
- break;
- case FcOpNotEqual:
- v.type = FcTypeBool;
- v.u.b = FcStrCmpIgnoreCase (vl.u.s, vr.u.s) != 0;
- break;
case FcOpPlus:
v.type = FcTypeString;
v.u.s = FcStrPlus (vl.u.s, vr.u.s);
v.type = FcTypeVoid;
break;
}
+ break;
case FcTypeMatrix:
switch (e->op) {
- case FcOpEqual:
- case FcOpContains:
- v.type = FcTypeBool;
- v.u.b = FcMatrixEqual (vl.u.m, vr.u.m);
- break;
- case FcOpNotEqual:
- v.type = FcTypeBool;
- v.u.b = FcMatrixEqual (vl.u.m, vr.u.m);
- break;
case FcOpTimes:
v.type = FcTypeMatrix;
m = malloc (sizeof (FcMatrix));
break;
}
break;
- case FcTypeCharSet:
- switch (e->op) {
- case FcOpContains:
- /* vl contains vr if vr is a subset of vl */
- v.type = FcTypeBool;
- v.u.b = FcCharSetIsSubset (vr.u.c, vl.u.c);
- break;
- case FcOpEqual:
- v.type = FcTypeBool;
- v.u.b = FcCharSetEqual (vl.u.c, vr.u.c);
- break;
- case FcOpNotEqual:
- v.type = FcTypeBool;
- v.u.b = !FcCharSetEqual (vl.u.c, vr.u.c);
- break;
- default:
- v.type = FcTypeVoid;
- break;
- }
- break;
default:
v.type = FcTypeVoid;
break;
}
static FcValueList *
-FcConfigValues (FcPattern *p, FcExpr *e)
+FcConfigValues (FcPattern *p, FcExpr *e, FcValueBinding binding)
{
FcValueList *l;
if (e->op == FcOpComma)
{
l->value = FcConfigEvaluate (p, e->u.tree.left);
- l->next = FcConfigValues (p, e->u.tree.right);
+ l->next = FcConfigValues (p, e->u.tree.right, binding);
}
else
{
l->value = FcConfigEvaluate (p, e);
l->next = 0;
}
+ l->binding = binding;
while (l && l->value.type == FcTypeVoid)
{
FcValueList *next = l->next;
}
FcBool
-FcConfigSubstitute (FcConfig *config,
- FcPattern *p,
- FcMatchKind kind)
+FcConfigSubstituteWithPat (FcConfig *config,
+ FcPattern *p,
+ FcPattern *p_pat,
+ FcMatchKind kind)
{
FcSubst *s;
FcSubState *st;
FcTest *t;
FcEdit *e;
FcValueList *l;
+ FcPattern *m;
if (!config)
{
printf ("FcConfigSubstitute test ");
FcTestPrint (t);
}
- st[i].elt = FcPatternFindElt (p, t->field);
+ st[i].elt = 0;
+ if (kind == FcMatchFont && t->kind == FcMatchPattern)
+ m = p_pat;
+ else
+ m = p;
+ if (m)
+ st[i].elt = FcPatternFindElt (m, t->field);
+ else
+ st[i].elt = 0;
/*
* If there's no such field in the font,
* then FcQualAll matches while FcQualAny does not
* Check to see if there is a match, mark the location
* to apply match-relative edits
*/
- st[i].value = FcConfigMatchValueList (p, t, st[i].elt->values);
+ st[i].value = FcConfigMatchValueList (m, t, st[i].elt->values);
if (!st[i].value)
break;
+ if (t->qual == FcQualFirst && st[i].value != st[i].elt->values)
+ break;
+ if (t->qual == FcQualNotFirst && st[i].value == st[i].elt->values)
+ break;
}
if (t)
{
/*
* Evaluate the list of expressions
*/
- l = FcConfigValues (p, e->expr);
+ l = FcConfigValues (p, e->expr, e->binding);
/*
- * Locate any test associated with this field
+ * Locate any test associated with this field, skipping
+ * tests associated with the pattern when substituting in
+ * the font
*/
for (t = s->test, i = 0; t; t = t->next, i++)
- if (!FcStrCmpIgnoreCase ((FcChar8 *) t->field, (FcChar8 *) e->field))
+ {
+ if ((t->kind == FcMatchFont || kind == FcMatchPattern) &&
+ !FcStrCmpIgnoreCase ((FcChar8 *) t->field,
+ (FcChar8 *) e->field))
break;
+ }
switch (e->op) {
case FcOpAssign:
/*
return FcTrue;
}
+FcBool
+FcConfigSubstitute (FcConfig *config,
+ FcPattern *p,
+ FcMatchKind kind)
+{
+ return FcConfigSubstituteWithPat (config, p, 0, kind);
+}
+
#ifndef FONTCONFIG_PATH
#define FONTCONFIG_PATH "/etc/fonts"
#endif