aboutsummaryrefslogtreecommitdiff
path: root/fontconfig
diff options
context:
space:
mode:
Diffstat (limited to 'fontconfig')
-rw-r--r--fontconfig/src/fccache.c28
-rw-r--r--fontconfig/src/fccfg.c102
-rw-r--r--fontconfig/src/fccompat.c27
-rw-r--r--fontconfig/src/fcdir.c10
-rw-r--r--fontconfig/src/fcint.h11
-rw-r--r--fontconfig/src/fcmatch.c2
-rw-r--r--fontconfig/src/fcobjs.c2
-rw-r--r--fontconfig/src/fcobjs.h4
-rw-r--r--fontconfig/src/fcxml.c59
9 files changed, 178 insertions, 67 deletions
diff --git a/fontconfig/src/fccache.c b/fontconfig/src/fccache.c
index 9f1c29827..e02d49e8f 100644
--- a/fontconfig/src/fccache.c
+++ b/fontconfig/src/fccache.c
@@ -830,34 +830,6 @@ bail1:
return NULL;
}
-
-#ifdef _WIN32
-#include <direct.h>
-#define mkdir(path,mode) _mkdir(path)
-#endif
-
-static FcBool
-FcMakeDirectory (const FcChar8 *dir)
-{
- FcChar8 *parent;
- FcBool ret;
-
- if (strlen ((char *) dir) == 0)
- return FcFalse;
-
- parent = FcStrDirname (dir);
- if (!parent)
- return FcFalse;
- if (access ((char *) parent, F_OK) == 0)
- ret = mkdir ((char *) dir, 0755) == 0 && chmod ((char *) dir, 0755) == 0;
- else if (access ((char *) parent, F_OK) == -1)
- ret = FcMakeDirectory (parent) && (mkdir ((char *) dir, 0755) == 0) && chmod ((char *) dir, 0755) == 0;
- else
- ret = FcFalse;
- FcStrFree (parent);
- return ret;
-}
-
/* write serialized state to the cache file */
FcBool
FcDirCacheWrite (FcCache *cache, FcConfig *config)
diff --git a/fontconfig/src/fccfg.c b/fontconfig/src/fccfg.c
index 7ea94b846..be738d53d 100644
--- a/fontconfig/src/fccfg.c
+++ b/fontconfig/src/fccfg.c
@@ -674,12 +674,21 @@ FcConfigAddRule (FcConfig *config,
num = 0;
for (r = rule; r; r = r->next)
{
- if (r->type == FcRuleTest)
+ switch (r->type)
{
+ case FcRuleTest:
if (r->u.test &&
r->u.test->kind == FcMatchDefault)
r->u.test->kind = kind;
- num++;
+ if (r->u.test->object > FC_MAX_BASE_OBJECT)
+ num++;
+ break;
+ case FcRuleEdit:
+ if (r->u.edit->object > FC_MAX_BASE_OBJECT)
+ num++;
+ break;
+ default:
+ break;
}
}
if (config->maxObjects < num)
@@ -1486,11 +1495,15 @@ FcConfigSubstituteWithPat (FcConfig *config,
FcValue v;
FcSubst *s;
FcRule *r;
- FcValueList *l, *value = NULL;
+ FcValueList *l, **value = NULL;
FcPattern *m;
FcStrSet *strs;
- FcPatternElt *elt = NULL;
FcObject object = FC_INVALID_OBJECT;
+ FcPatternElt **elt = NULL;
+ int i, nobjs;
+ FcBool retval = FcTrue;
+
+#define FC_OBJ_ID(_n_) ((_n_) > FC_MAX_BASE_OBJECT ? ((_n_) - FC_EXT_OBJ_INDEX) : (_n_))
if (!config)
{
@@ -1535,6 +1548,20 @@ FcConfigSubstituteWithPat (FcConfig *config,
return FcFalse;
}
+ nobjs = FC_MAX_BASE_OBJECT + config->maxObjects + 2;
+ value = (FcValueList **) malloc (SIZEOF_VOID_P * nobjs);
+ if (!value)
+ {
+ retval = FcFalse;
+ goto bail1;
+ }
+ elt = (FcPatternElt **) malloc (SIZEOF_VOID_P * nobjs);
+ if (!elt)
+ {
+ retval = FcFalse;
+ goto bail1;
+ }
+
if (FcDebug () & FC_DBG_EDIT)
{
printf ("FcConfigSubstitute ");
@@ -1543,6 +1570,11 @@ FcConfigSubstituteWithPat (FcConfig *config,
for (; s; s = s->next)
{
r = s->rule;
+ for (i = 0; i < nobjs; i++)
+ {
+ elt[i] = NULL;
+ value[i] = NULL;
+ }
for (; r; r = r->next)
{
switch (r->type) {
@@ -1550,6 +1582,7 @@ FcConfigSubstituteWithPat (FcConfig *config,
/* shouldn't be reached */
break;
case FcRuleTest:
+ object = FC_OBJ_ID (r->u.test->object);
/*
* Check the tests to see if
* they all match the pattern
@@ -1564,18 +1597,16 @@ FcConfigSubstituteWithPat (FcConfig *config,
else
m = p;
if (m)
- elt = FcPatternObjectFindElt (m, r->u.test->object);
- else
- elt = NULL;
+ elt[object] = FcPatternObjectFindElt (m, r->u.test->object);
/*
* If there's no such field in the font,
* then FcQualAll matches while FcQualAny does not
*/
- if (!elt)
+ if (!elt[object])
{
if (r->u.test->qual == FcQualAll)
{
- value = NULL;
+ value[object] = NULL;
continue;
}
else
@@ -1589,18 +1620,18 @@ FcConfigSubstituteWithPat (FcConfig *config,
* Check to see if there is a match, mark the location
* to apply match-relative edits
*/
- value = FcConfigMatchValueList (m, p_pat, kind, r->u.test, elt->values);
- if (!value ||
- (r->u.test->qual == FcQualFirst && value != elt->values) ||
- (r->u.test->qual == FcQualNotFirst && value == elt->values))
+ value[object] = FcConfigMatchValueList (m, p_pat, kind, r->u.test, elt[object]->values);
+ if (!value[object] ||
+ (r->u.test->qual == FcQualFirst && value[object] != elt[object]->values) ||
+ (r->u.test->qual == FcQualNotFirst && value[object] == elt[object]->values))
{
if (FcDebug () & FC_DBG_EDIT)
printf ("No match\n");
goto bail;
}
- object = r->u.test->object;
break;
case FcRuleEdit:
+ object = FC_OBJ_ID (r->u.edit->object);
if (FcDebug () & FC_DBG_EDIT)
{
printf ("Substitute ");
@@ -1611,13 +1642,6 @@ FcConfigSubstituteWithPat (FcConfig *config,
* Evaluate the list of expressions
*/
l = FcConfigValues (p, p_pat,kind, r->u.edit->expr, r->u.edit->binding);
- /*
- * Locate any test associated with this field, skipping
- * tests associated with the pattern when substituting in
- * the font
- */
- if (object != r->u.edit->object)
- value = NULL;
switch (FC_OP_GET_OP (r->u.edit->op)) {
case FcOpAssign:
@@ -1625,25 +1649,25 @@ FcConfigSubstituteWithPat (FcConfig *config,
* If there was a test, then replace the matched
* value with the new list of values
*/
- if (value)
+ if (value[object])
{
- FcValueList *thisValue = value;
- FcValueList *nextValue = thisValue;
+ FcValueList *thisValue = value[object];
+ FcValueList *nextValue = l;
/*
* Append the new list of values after the current value
*/
- FcConfigAdd (&elt->values, thisValue, FcTrue, l, r->u.edit->object);
+ FcConfigAdd (&elt[object]->values, thisValue, FcTrue, l, r->u.edit->object);
/*
* Delete the marked value
*/
if (thisValue)
- FcConfigDel (&elt->values, thisValue);
+ FcConfigDel (&elt[object]->values, thisValue);
/*
* Adjust a pointer into the value list to ensure
* future edits occur at the same place
*/
- value = nextValue;
+ value[object] = nextValue;
break;
}
/* fall through ... */
@@ -1658,12 +1682,12 @@ FcConfigSubstituteWithPat (FcConfig *config,
* Adjust a pointer into the value list as they no
* longer point to anything valid
*/
- value = NULL;
+ value[object] = NULL;
break;
case FcOpPrepend:
- if (value)
+ if (value[object])
{
- FcConfigAdd (&elt->values, value, FcFalse, l, r->u.edit->object);
+ FcConfigAdd (&elt[object]->values, value[object], FcFalse, l, r->u.edit->object);
break;
}
/* fall through ... */
@@ -1671,9 +1695,9 @@ FcConfigSubstituteWithPat (FcConfig *config,
FcConfigPatternAdd (p, r->u.edit->object, l, FcFalse);
break;
case FcOpAppend:
- if (value)
+ if (value[object])
{
- FcConfigAdd (&elt->values, value, FcTrue, l, r->u.edit->object);
+ FcConfigAdd (&elt[object]->values, value[object], FcTrue, l, r->u.edit->object);
break;
}
/* fall through ... */
@@ -1681,9 +1705,9 @@ FcConfigSubstituteWithPat (FcConfig *config,
FcConfigPatternAdd (p, r->u.edit->object, l, FcTrue);
break;
case FcOpDelete:
- if (value)
+ if (value[object])
{
- FcConfigDel (&elt->values, value);
+ FcConfigDel (&elt[object]->values, value[object]);
break;
}
/* fall through ... */
@@ -1715,7 +1739,15 @@ FcConfigSubstituteWithPat (FcConfig *config,
printf ("FcConfigSubstitute done");
FcPatternPrint (p);
}
- return FcTrue;
+bail1:
+ if (elt)
+ free (elt);
+ if (value)
+ free (value);
+
+#undef FC_OBJ_ID
+
+ return retval;
}
FcBool
diff --git a/fontconfig/src/fccompat.c b/fontconfig/src/fccompat.c
index a2171607c..d4f88c83f 100644
--- a/fontconfig/src/fccompat.c
+++ b/fontconfig/src/fccompat.c
@@ -219,3 +219,30 @@ FcRandom(void)
return result;
}
+
+#ifdef _WIN32
+#include <direct.h>
+#define mkdir(path,mode) _mkdir(path)
+#endif
+
+FcBool
+FcMakeDirectory (const FcChar8 *dir)
+{
+ FcChar8 *parent;
+ FcBool ret;
+
+ if (strlen ((char *) dir) == 0)
+ return FcFalse;
+
+ parent = FcStrDirname (dir);
+ if (!parent)
+ return FcFalse;
+ if (access ((char *) parent, F_OK) == 0)
+ ret = mkdir ((char *) dir, 0755) == 0 && chmod ((char *) dir, 0755) == 0;
+ else if (access ((char *) parent, F_OK) == -1)
+ ret = FcMakeDirectory (parent) && (mkdir ((char *) dir, 0755) == 0) && chmod ((char *) dir, 0755) == 0;
+ else
+ ret = FcFalse;
+ FcStrFree (parent);
+ return ret;
+}
diff --git a/fontconfig/src/fcdir.c b/fontconfig/src/fcdir.c
index dc580bb6f..b040a285a 100644
--- a/fontconfig/src/fcdir.c
+++ b/fontconfig/src/fcdir.c
@@ -49,6 +49,16 @@ FcFileIsLink (const FcChar8 *file)
#endif
}
+FcBool
+FcFileIsFile (const FcChar8 *file)
+{
+ struct stat statb;
+
+ if (FcStat (file, &statb) != 0)
+ return FcFalse;
+ return S_ISREG (statb.st_mode);
+}
+
static FcBool
FcFileScanFontConfig (FcFontSet *set,
FcBlanks *blanks,
diff --git a/fontconfig/src/fcint.h b/fontconfig/src/fcint.h
index fe523fb7c..ec0c67470 100644
--- a/fontconfig/src/fcint.h
+++ b/fontconfig/src/fcint.h
@@ -174,6 +174,11 @@ typedef struct _FcValueList {
typedef int FcObject;
+/* The 1000 is to leave some room for future added internal objects, such
+ * that caches from newer fontconfig can still be used with older fontconfig
+ * without getting confused. */
+#define FC_EXT_OBJ_INDEX 1000
+
typedef struct _FcPatternElt *FcPatternEltPtr;
/*
@@ -742,6 +747,9 @@ FcMakeTempfile (char *template);
FcPrivate int32_t
FcRandom (void);
+FcPrivate FcBool
+FcMakeDirectory (const FcChar8 *dir);
+
/* fcdbg.c */
FcPrivate void
@@ -800,6 +808,9 @@ FcPrivate FcBool
FcFileIsLink (const FcChar8 *file);
FcPrivate FcBool
+FcFileIsFile (const FcChar8 *file);
+
+FcPrivate FcBool
FcFileScanConfig (FcFontSet *set,
FcStrSet *dirs,
FcBlanks *blanks,
diff --git a/fontconfig/src/fcmatch.c b/fontconfig/src/fcmatch.c
index 10976d6e8..dec92b9cf 100644
--- a/fontconfig/src/fcmatch.c
+++ b/fontconfig/src/fcmatch.c
@@ -245,6 +245,8 @@ typedef enum _FcMatcherPriorityDummy {
typedef enum _FcMatcherPriority {
PRI1(HASH),
PRI1(FILE),
+ PRI1(FONTFORMAT),
+ PRI1(SCALABLE),
PRI1(FOUNDRY),
PRI1(CHARSET),
PRI_FAMILY_STRONG,
diff --git a/fontconfig/src/fcobjs.c b/fontconfig/src/fcobjs.c
index 1d3af73be..bad9824d4 100644
--- a/fontconfig/src/fcobjs.c
+++ b/fontconfig/src/fcobjs.c
@@ -37,7 +37,7 @@ FcObjectTypeLookup (register const char *str, register unsigned int len);
/* The 1000 is to leave some room for future added internal objects, such
* that caches from newer fontconfig can still be used with older fontconfig
* without getting confused. */
-static fc_atomic_int_t next_id = FC_MAX_BASE_OBJECT + 1000;
+static fc_atomic_int_t next_id = FC_MAX_BASE_OBJECT + FC_EXT_OBJ_INDEX;
struct FcObjectOtherTypeInfo {
struct FcObjectOtherTypeInfo *next;
FcObjectType object;
diff --git a/fontconfig/src/fcobjs.h b/fontconfig/src/fcobjs.h
index 682fe6ad3..87c7319e3 100644
--- a/fontconfig/src/fcobjs.h
+++ b/fontconfig/src/fcobjs.h
@@ -23,7 +23,7 @@ FC_OBJECT (FILE, FcTypeString, FcCompareFilename)
FC_OBJECT (INDEX, FcTypeInteger, NULL)
FC_OBJECT (RASTERIZER, FcTypeString, FcCompareString)
FC_OBJECT (OUTLINE, FcTypeBool, FcCompareBool)
-FC_OBJECT (SCALABLE, FcTypeBool, NULL)
+FC_OBJECT (SCALABLE, FcTypeBool, FcCompareBool)
FC_OBJECT (DPI, FcTypeDouble, NULL)
FC_OBJECT (RGBA, FcTypeInteger, NULL)
FC_OBJECT (SCALE, FcTypeDouble, NULL)
@@ -35,7 +35,7 @@ FC_OBJECT (CHARSET, FcTypeCharSet, FcCompareCharSet)
FC_OBJECT (LANG, FcTypeLangSet, FcCompareLang)
FC_OBJECT (FONTVERSION, FcTypeInteger, FcCompareNumber)
FC_OBJECT (CAPABILITY, FcTypeString, NULL)
-FC_OBJECT (FONTFORMAT, FcTypeString, NULL)
+FC_OBJECT (FONTFORMAT, FcTypeString, FcCompareString)
FC_OBJECT (EMBOLDEN, FcTypeBool, NULL)
FC_OBJECT (EMBEDDED_BITMAP, FcTypeBool, NULL)
FC_OBJECT (DECORATIVE, FcTypeBool, FcCompareBool)
diff --git a/fontconfig/src/fcxml.c b/fontconfig/src/fcxml.c
index 6a2af85e3..2cdf0ad0a 100644
--- a/fontconfig/src/fcxml.c
+++ b/fontconfig/src/fcxml.c
@@ -2182,6 +2182,8 @@ FcParseInclude (FcConfigParse *parse)
FcBool ignore_missing = FcFalse;
FcBool deprecated = FcFalse;
FcChar8 *prefix = NULL, *p;
+ static FcChar8 *userdir = NULL;
+ static FcChar8 *userconf = NULL;
s = FcStrBufDoneStatic (&parse->pstack->str);
if (!s)
@@ -2214,23 +2216,78 @@ FcParseInclude (FcConfigParse *parse)
memcpy (&prefix[plen + 1], s, dlen);
prefix[plen + 1 + dlen] = 0;
s = prefix;
+ if (FcFileIsDir (s))
+ {
+ userdir:
+ if (!userdir)
+ userdir = FcStrdup (s);
+ }
+ else if (FcFileIsFile (s))
+ {
+ userconf:
+ if (!userconf)
+ userconf = FcStrdup (s);
+ }
+ else
+ {
+ /* No config dir nor file on the XDG directory spec compliant place
+ * so need to guess what it is supposed to be.
+ */
+ FcChar8 *parent = FcStrDirname (s);
+
+ if (!FcFileIsDir (parent))
+ FcMakeDirectory (parent);
+ FcStrFree (parent);
+ if (FcStrStr (s, (const FcChar8 *)"conf.d") != NULL)
+ goto userdir;
+ else
+ goto userconf;
+ }
}
if (!FcConfigParseAndLoad (parse->config, s, !ignore_missing))
parse->error = FcTrue;
+#ifndef _WIN32
else
{
FcChar8 *filename;
+ static FcBool warn_conf = FcFalse, warn_confd = FcFalse;
filename = FcConfigFilename(s);
if (deprecated == FcTrue &&
filename != NULL &&
!FcFileIsLink (filename))
{
- FcConfigMessage (parse, FcSevereWarning, "reading configurations from %s is deprecated.", s);
+ if (FcFileIsDir (filename))
+ {
+ if (FcFileIsDir (userdir) ||
+ rename ((const char *)filename, (const char *)userdir) != 0 ||
+ symlink ((const char *)userdir, (const char *)filename) != 0)
+ {
+ if (!warn_confd)
+ {
+ FcConfigMessage (parse, FcSevereWarning, "reading configurations from %s is deprecated. please move it to %s manually", s, userdir);
+ warn_confd = FcTrue;
+ }
+ }
+ }
+ else
+ {
+ if (FcFileIsFile (userconf) ||
+ rename ((const char *)filename, (const char *)userconf) != 0 ||
+ symlink ((const char *)userconf, (const char *)filename) != 0)
+ {
+ if (!warn_conf)
+ {
+ FcConfigMessage (parse, FcSevereWarning, "reading configurations from %s is deprecated. please move it to %s manually", s, userconf);
+ warn_conf = FcTrue;
+ }
+ }
+ }
}
if(filename)
FcStrFree(filename);
}
+#endif
FcStrBufDestroy (&parse->pstack->str);
bail: