diff options
Diffstat (limited to 'fontconfig')
-rw-r--r-- | fontconfig/src/fccache.c | 28 | ||||
-rw-r--r-- | fontconfig/src/fccfg.c | 102 | ||||
-rw-r--r-- | fontconfig/src/fccompat.c | 27 | ||||
-rw-r--r-- | fontconfig/src/fcdir.c | 10 | ||||
-rw-r--r-- | fontconfig/src/fcint.h | 11 | ||||
-rw-r--r-- | fontconfig/src/fcmatch.c | 2 | ||||
-rw-r--r-- | fontconfig/src/fcobjs.c | 2 | ||||
-rw-r--r-- | fontconfig/src/fcobjs.h | 4 | ||||
-rw-r--r-- | fontconfig/src/fcxml.c | 59 |
9 files changed, 178 insertions, 67 deletions
diff --git a/fontconfig/src/fccache.c b/fontconfig/src/fccache.c index fab2c1f2c..e02d49e8f 100644 --- a/fontconfig/src/fccache.c +++ b/fontconfig/src/fccache.c @@ -830,34 +830,6 @@ bail1: return NULL; } - -#ifdef _WIN32 -#undef mkdir -#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 1cac9a8b3..eb8d26ac0 100644 --- a/fontconfig/src/fcxml.c +++ b/fontconfig/src/fcxml.c @@ -2183,6 +2183,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) @@ -2215,23 +2217,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: |