if (!config->fontDirs)
goto bail3;
+ config->acceptGlobs = FcStrSetCreate ();
+ if (!config->acceptGlobs)
+ goto bail4;
+
+ config->rejectGlobs = FcStrSetCreate ();
+ if (!config->rejectGlobs)
+ goto bail5;
+
config->cache = 0;
if (FcConfigHome())
if (!FcConfigSetCache (config, (FcChar8 *) ("~/" FC_USER_CACHE_FILE)))
- goto bail4;
+ goto bail6;
config->blanks = 0;
return config;
+bail6:
+ FcStrSetDestroy (config->rejectGlobs);
+bail5:
+ FcStrSetDestroy (config->acceptGlobs);
bail4:
FcStrSetDestroy (config->fontDirs);
bail3:
FcStrSetDestroy (config->configDirs);
FcStrSetDestroy (config->fontDirs);
FcStrSetDestroy (config->configFiles);
+ FcStrSetDestroy (config->acceptGlobs);
+ FcStrSetDestroy (config->rejectGlobs);
FcStrFree (config->cache);
{
if (FcDebug () & FC_DBG_FONTSET)
printf ("scan dir %s\n", dir);
- FcDirScan (fonts, config->fontDirs, cache, config->blanks, dir, FcFalse);
+ FcDirScanConfig (fonts, config->fontDirs, cache,
+ config->blanks, dir, FcFalse, config);
}
FcStrListDone (list);
case FcTypeString:
switch (op) {
case FcOpEqual:
- case FcOpContains:
ret = FcStrCmpIgnoreCase (m.u.s, v.u.s) == 0;
break;
+ case FcOpContains:
+ ret = FcStrStrIgnoreCase (m.u.s, v.u.s) != 0;
+ break;
case FcOpNotEqual:
- case FcOpNotContains:
ret = FcStrCmpIgnoreCase (m.u.s, v.u.s) != 0;
break;
+ case FcOpNotContains:
+ ret = FcStrStrIgnoreCase (m.u.s, v.u.s) == 0;
+ break;
default:
break;
}
case FcTypeCharSet:
switch (op) {
case FcOpContains:
- /* m contains v if v is a subset of m */
- ret = FcCharSetIsSubset (v.u.c, m.u.c);
+ /* v contains m if m is a subset of v */
+ ret = FcCharSetIsSubset (m.u.c, v.u.c);
break;
case FcOpNotContains:
- /* m contains v if v is a subset of m */
- ret = !FcCharSetIsSubset (v.u.c, m.u.c);
+ /* v contains m if m is a subset of v */
+ ret = !FcCharSetIsSubset (m.u.c, v.u.c);
break;
case FcOpEqual:
ret = FcCharSetEqual (m.u.c, v.u.c);
case FcTypeLangSet:
switch (op) {
case FcOpContains:
- ret = FcLangSetContains (v.u.l, m.u.l);
+ ret = FcLangSetContains (m.u.l, v.u.l);
break;
case FcOpNotContains:
- ret = FcLangSetContains (v.u.l, m.u.l);
+ ret = FcLangSetContains (m.u.l, v.u.l);
break;
case FcOpEqual:
- ret = FcLangSetEqual (v.u.l, m.u.l);
+ ret = FcLangSetEqual (m.u.l, v.u.l);
break;
case FcOpNotEqual:
- ret = !FcLangSetEqual (v.u.l, m.u.l);
+ ret = !FcLangSetEqual (m.u.l, v.u.l);
break;
default:
break;
}
+#define _FcDoubleFloor(d) ((int) (d))
+#define _FcDoubleCeil(d) ((double) (int) (d) == (d) ? (int) (d) : (int) ((d) + 1))
+#define FcDoubleFloor(d) ((d) >= 0 ? _FcDoubleFloor(d) : -_FcDoubleCeil(-(d)))
+#define FcDoubleCeil(d) ((d) >= 0 ? _FcDoubleCeil(d) : -_FcDoubleFloor(-(d)))
+#define FcDoubleRound(d) FcDoubleFloor ((d) + 0.5)
+#define FcDoubleTrunc(d) ((d) >= 0 ? _FcDoubleFloor (d) : -_FcDoubleFloor (-(d)))
+
static FcValue
FcConfigEvaluate (FcPattern *p, FcExpr *e)
{
}
FcValueDestroy (vl);
break;
+ case FcOpFloor:
+ vl = FcConfigEvaluate (p, e->u.tree.left);
+ switch (vl.type) {
+ case FcTypeInteger:
+ v = vl;
+ break;
+ case FcTypeDouble:
+ v.type = FcTypeInteger;
+ v.u.i = FcDoubleFloor (vl.u.d);
+ break;
+ default:
+ v.type = FcTypeVoid;
+ break;
+ }
+ FcValueDestroy (vl);
+ break;
+ case FcOpCeil:
+ vl = FcConfigEvaluate (p, e->u.tree.left);
+ switch (vl.type) {
+ case FcTypeInteger:
+ v = vl;
+ break;
+ case FcTypeDouble:
+ v.type = FcTypeInteger;
+ v.u.i = FcDoubleCeil (vl.u.d);
+ break;
+ default:
+ v.type = FcTypeVoid;
+ break;
+ }
+ FcValueDestroy (vl);
+ break;
+ case FcOpRound:
+ vl = FcConfigEvaluate (p, e->u.tree.left);
+ switch (vl.type) {
+ case FcTypeInteger:
+ v = vl;
+ break;
+ case FcTypeDouble:
+ v.type = FcTypeInteger;
+ v.u.i = FcDoubleRound (vl.u.d);
+ break;
+ default:
+ v.type = FcTypeVoid;
+ break;
+ }
+ FcValueDestroy (vl);
+ break;
+ case FcOpTrunc:
+ vl = FcConfigEvaluate (p, e->u.tree.left);
+ switch (vl.type) {
+ case FcTypeInteger:
+ v = vl;
+ break;
+ case FcTypeDouble:
+ v.type = FcTypeInteger;
+ v.u.i = FcDoubleTrunc (vl.u.d);
+ break;
+ default:
+ v.type = FcTypeVoid;
+ break;
+ }
+ FcValueDestroy (vl);
+ break;
default:
v.type = FcTypeVoid;
break;
!FcStrCmpIgnoreCase ((FcChar8 *) t->field,
(FcChar8 *) e->field))
{
+ /*
+ * KLUDGE - the pattern may have been reallocated or
+ * things may have been inserted or deleted above
+ * this element by other edits. Go back and find
+ * the element again
+ */
+ if (e != s->edit && st[i].elt)
+ st[i].elt = FcPatternFindElt (p, t->field);
if (!st[i].elt)
t = 0;
break;
#else /* !(_WIN32 && PIC) */
-#ifndef FONTCONFIG_PATH
-#define FONTCONFIG_PATH "/etc/fonts"
-#endif
-
#endif /* !(_WIN32 && PIC) */
#ifndef FONTCONFIG_FILE
FcConfigSetFonts (config, set, FcSetApplication);
}
- if (!FcFileScan (set, subdirs, 0, config->blanks, file, FcFalse))
+ if (!FcFileScanConfig (set, subdirs, 0, config->blanks, file, FcFalse, config))
{
FcStrSetDestroy (subdirs);
return FcFalse;
FcConfigSetFonts (config, set, FcSetApplication);
}
- if (!FcDirScan (set, subdirs, 0, config->blanks, dir, FcFalse))
+ if (!FcDirScanConfig (set, subdirs, 0, config->blanks, dir, FcFalse, config))
{
FcStrSetDestroy (subdirs);
return FcFalse;
{
FcConfigSetFonts (config, 0, FcSetApplication);
}
+
+/*
+ * Manage filename-based font source selectors
+ */
+
+FcBool
+FcConfigGlobAdd (FcConfig *config,
+ const FcChar8 *glob,
+ FcBool accept)
+{
+ FcStrSet *set = accept ? config->acceptGlobs : config->rejectGlobs;
+
+ return FcStrSetAdd (set, glob);
+}
+
+static FcBool
+FcConfigGlobMatch (const FcChar8 *glob,
+ const FcChar8 *string)
+{
+ FcChar8 c;
+
+ while ((c = *glob++))
+ {
+ switch (c) {
+ case '*':
+ /* short circuit common case */
+ if (!*glob)
+ return FcTrue;
+ /* short circuit another common case */
+ if (strchr ((char *) glob, '*') == 0)
+ string += strlen ((char *) string) - strlen ((char *) glob);
+ while (*string)
+ {
+ if (FcConfigGlobMatch (glob, string))
+ return FcTrue;
+ string++;
+ }
+ return FcFalse;
+ case '?':
+ if (*string++ == '\0')
+ return FcFalse;
+ break;
+ default:
+ if (*string++ != c)
+ return FcFalse;
+ break;
+ }
+ }
+ return *string == '\0';
+}
+
+static FcBool
+FcConfigGlobsMatch (const FcStrSet *globs,
+ const FcChar8 *string)
+{
+ int i;
+
+ for (i = 0; i < globs->num; i++)
+ if (FcConfigGlobMatch (globs->strs[i], string))
+ return FcTrue;
+ return FcFalse;
+}
+
+FcBool
+FcConfigAcceptFilename (FcConfig *config,
+ const FcChar8 *filename)
+{
+ if (FcConfigGlobsMatch (config->acceptGlobs, filename))
+ return FcTrue;
+ if (FcConfigGlobsMatch (config->rejectGlobs, filename))
+ return FcFalse;
+ return FcTrue;
+}