Add support for XDG_DATA_DIRS
Add dirs from XDG_DATA_DIRS when <dir prefix="xdg"> appears in fonts.conf Fixes https://gitlab.freedesktop.org/fontconfig/fontconfig/-/issues/271
This commit is contained in:
parent
b03140c14e
commit
6f27f42e61
59
src/fccfg.c
59
src/fccfg.c
|
@ -2614,6 +2614,65 @@ FcConfigXdgDataHome (void)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FcStrSet *
|
||||||
|
FcConfigXdgDataDirs (void)
|
||||||
|
{
|
||||||
|
const char *env = getenv ("XDG_DATA_DIRS");
|
||||||
|
FcStrSet *ret = FcStrSetCreate ();
|
||||||
|
|
||||||
|
if (env)
|
||||||
|
{
|
||||||
|
FcChar8 *ee, *e = ee = FcStrCopy ((const FcChar8 *) env);
|
||||||
|
|
||||||
|
/* We don't intentionally use FC_SEARCH_PATH_SEPARATOR here because of:
|
||||||
|
* The directories in $XDG_DATA_DIRS should be seperated with a colon ':'.
|
||||||
|
* in doc.
|
||||||
|
*/
|
||||||
|
while (e)
|
||||||
|
{
|
||||||
|
FcChar8 *p = (FcChar8 *) strchr ((const char *) e, ':');
|
||||||
|
FcChar8 *s;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (!p)
|
||||||
|
{
|
||||||
|
s = FcStrCopy (e);
|
||||||
|
e = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*p = 0;
|
||||||
|
s = FcStrCopy (e);
|
||||||
|
e = p + 1;
|
||||||
|
}
|
||||||
|
len = strlen ((const char *) s);
|
||||||
|
if (s[len - 1] == FC_DIR_SEPARATOR)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
while (len > 1 && s[len - 1] == FC_DIR_SEPARATOR);
|
||||||
|
s[len] = 0;
|
||||||
|
}
|
||||||
|
FcStrSetAdd (ret, s);
|
||||||
|
FcStrFree (s);
|
||||||
|
}
|
||||||
|
FcStrFree (ee);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* From spec doc at https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html#variables
|
||||||
|
*
|
||||||
|
* If $XDG_DATA_DIRS is either not set or empty, a value equal to /usr/local/share/:/usr/share/ should be used.
|
||||||
|
*/
|
||||||
|
FcStrSetAdd (ret, (const FcChar8 *) "/usr/local/share");
|
||||||
|
FcStrSetAdd (ret, (const FcChar8 *) "/usr/share");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
FcBool
|
FcBool
|
||||||
FcConfigEnableHome (FcBool enable)
|
FcConfigEnableHome (FcBool enable)
|
||||||
{
|
{
|
||||||
|
|
|
@ -664,6 +664,9 @@ FcConfigXdgConfigHome (void);
|
||||||
FcPrivate FcChar8 *
|
FcPrivate FcChar8 *
|
||||||
FcConfigXdgDataHome (void);
|
FcConfigXdgDataHome (void);
|
||||||
|
|
||||||
|
FcPrivate FcStrSet *
|
||||||
|
FcConfigXdgDataDirs (void);
|
||||||
|
|
||||||
FcPrivate FcExpr *
|
FcPrivate FcExpr *
|
||||||
FcConfigAllocExpr (FcConfig *config);
|
FcConfigAllocExpr (FcConfig *config);
|
||||||
|
|
||||||
|
@ -1257,6 +1260,9 @@ FcIsFsMtimeBroken (const FcChar8 *dir);
|
||||||
FcPrivate FcStrSet *
|
FcPrivate FcStrSet *
|
||||||
FcStrSetCreateEx (unsigned int control);
|
FcStrSetCreateEx (unsigned int control);
|
||||||
|
|
||||||
|
FcPrivate FcBool
|
||||||
|
FcStrSetInsert (FcStrSet *set, const FcChar8 *s, int pos);
|
||||||
|
|
||||||
FcPrivate FcBool
|
FcPrivate FcBool
|
||||||
FcStrSetAddLangs (FcStrSet *strs, const char *languages);
|
FcStrSetAddLangs (FcStrSet *strs, const char *languages);
|
||||||
|
|
||||||
|
|
35
src/fcstr.c
35
src/fcstr.c
|
@ -1252,7 +1252,7 @@ _FcStrSetGrow (FcStrSet *set, int growElements)
|
||||||
}
|
}
|
||||||
|
|
||||||
static FcBool
|
static FcBool
|
||||||
_FcStrSetAppend (FcStrSet *set, FcChar8 *s)
|
_FcStrSetInsert (FcStrSet *set, FcChar8 *s, int pos)
|
||||||
{
|
{
|
||||||
if (!FcStrSetHasControlBit (set, FCSS_ALLOW_DUPLICATES))
|
if (!FcStrSetHasControlBit (set, FCSS_ALLOW_DUPLICATES))
|
||||||
{
|
{
|
||||||
|
@ -1268,8 +1268,21 @@ _FcStrSetAppend (FcStrSet *set, FcChar8 *s)
|
||||||
if (!_FcStrSetGrow(set, growElements))
|
if (!_FcStrSetGrow(set, growElements))
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
}
|
}
|
||||||
|
if (pos >= set->num)
|
||||||
|
{
|
||||||
set->strs[set->num++] = s;
|
set->strs[set->num++] = s;
|
||||||
set->strs[set->num] = 0;
|
set->strs[set->num] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
set->num++;
|
||||||
|
set->strs[set->num] = 0;
|
||||||
|
for (i = set->num - 1; i > pos; i--)
|
||||||
|
set->strs[i] = set->strs[i - 1];
|
||||||
|
set->strs[pos] = s;
|
||||||
|
}
|
||||||
return FcTrue;
|
return FcTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1354,7 +1367,21 @@ FcStrSetAdd (FcStrSet *set, const FcChar8 *s)
|
||||||
FcChar8 *new = FcStrCopy (s);
|
FcChar8 *new = FcStrCopy (s);
|
||||||
if (!new)
|
if (!new)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
if (!_FcStrSetAppend (set, new))
|
if (!_FcStrSetInsert (set, new, set->num))
|
||||||
|
{
|
||||||
|
FcStrFree (new);
|
||||||
|
return FcFalse;
|
||||||
|
}
|
||||||
|
return FcTrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FcBool
|
||||||
|
FcStrSetInsert (FcStrSet *set, const FcChar8 *s, int pos)
|
||||||
|
{
|
||||||
|
FcChar8 *new = FcStrCopy (s);
|
||||||
|
if (!new)
|
||||||
|
return FcFalse;
|
||||||
|
if (!_FcStrSetInsert (set, new, pos))
|
||||||
{
|
{
|
||||||
FcStrFree (new);
|
FcStrFree (new);
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
|
@ -1368,7 +1395,7 @@ FcStrSetAddTriple (FcStrSet *set, const FcChar8 *a, const FcChar8 *b, const FcCh
|
||||||
FcChar8 *new = FcStrMakeTriple (a, b, c);
|
FcChar8 *new = FcStrMakeTriple (a, b, c);
|
||||||
if (!new)
|
if (!new)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
if (!_FcStrSetAppend (set, new))
|
if (!_FcStrSetInsert (set, new, set->num))
|
||||||
{
|
{
|
||||||
FcStrFree (new);
|
FcStrFree (new);
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
|
@ -1403,7 +1430,7 @@ FcStrSetAddFilename (FcStrSet *set, const FcChar8 *s)
|
||||||
FcChar8 *new = FcStrCopyFilename (s);
|
FcChar8 *new = FcStrCopyFilename (s);
|
||||||
if (!new)
|
if (!new)
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
if (!_FcStrSetAppend (set, new))
|
if (!_FcStrSetInsert (set, new, set->num))
|
||||||
{
|
{
|
||||||
FcStrFree (new);
|
FcStrFree (new);
|
||||||
return FcFalse;
|
return FcFalse;
|
||||||
|
|
66
src/fcxml.c
66
src/fcxml.c
|
@ -1285,20 +1285,22 @@ FcConfigGetAttribute (FcConfigParse *parse, const char *attr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FcChar8 *
|
static FcStrSet *
|
||||||
_get_real_path_from_prefix(FcConfigParse *parse, const FcChar8 *path, const FcChar8 *prefix)
|
_get_real_paths_from_prefix(FcConfigParse *parse, const FcChar8 *path, const FcChar8 *prefix)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
FcChar8 buffer[1000] = { 0 };
|
FcChar8 buffer[1000] = { 0 };
|
||||||
#endif
|
#endif
|
||||||
FcChar8 *parent = NULL, *retval = NULL;
|
FcChar8 *parent = NULL, *retval = NULL;
|
||||||
|
FcStrSet *e = NULL;
|
||||||
|
|
||||||
if (prefix)
|
if (prefix)
|
||||||
{
|
{
|
||||||
if (FcStrCmp (prefix, (const FcChar8 *) "xdg") == 0)
|
if (FcStrCmp (prefix, (const FcChar8 *) "xdg") == 0)
|
||||||
{
|
{
|
||||||
parent = FcConfigXdgDataHome ();
|
parent = FcConfigXdgDataHome ();
|
||||||
if (!parent)
|
e = FcConfigXdgDataDirs ();
|
||||||
|
if (!parent || !e)
|
||||||
{
|
{
|
||||||
/* Home directory might be disabled */
|
/* Home directory might be disabled */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1388,8 +1390,28 @@ _get_real_path_from_prefix(FcConfigParse *parse, const FcChar8 *path, const FcCh
|
||||||
{
|
{
|
||||||
retval = FcStrdup (path);
|
retval = FcStrdup (path);
|
||||||
}
|
}
|
||||||
|
if (!e)
|
||||||
|
e = FcStrSetCreate ();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FcChar8 *s;
|
||||||
|
int i;
|
||||||
|
|
||||||
return retval;
|
for (i = 0; i < e->num; i++)
|
||||||
|
{
|
||||||
|
s = FcStrBuildFilename (e->strs[i], path, NULL);
|
||||||
|
FcStrFree (e->strs[i]);
|
||||||
|
e->strs[i] = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!FcStrSetInsert (e, retval, 0))
|
||||||
|
{
|
||||||
|
FcStrSetDestroy (e);
|
||||||
|
e = NULL;
|
||||||
|
}
|
||||||
|
FcStrFree (retval);
|
||||||
|
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2062,7 +2084,7 @@ static void
|
||||||
FcParseRemapDir (FcConfigParse *parse)
|
FcParseRemapDir (FcConfigParse *parse)
|
||||||
{
|
{
|
||||||
const FcChar8 *path, *attr, *data, *salt;
|
const FcChar8 *path, *attr, *data, *salt;
|
||||||
FcChar8 *prefix = NULL;
|
FcStrSet *prefix_dirs = NULL;
|
||||||
|
|
||||||
data = FcStrBufDoneStatic (&parse->pstack->str);
|
data = FcStrBufDoneStatic (&parse->pstack->str);
|
||||||
if (!data)
|
if (!data)
|
||||||
|
@ -2083,7 +2105,15 @@ FcParseRemapDir (FcConfigParse *parse)
|
||||||
}
|
}
|
||||||
attr = FcConfigGetAttribute (parse, "prefix");
|
attr = FcConfigGetAttribute (parse, "prefix");
|
||||||
salt = FcConfigGetAttribute (parse, "salt");
|
salt = FcConfigGetAttribute (parse, "salt");
|
||||||
prefix = _get_real_path_from_prefix (parse, data, attr);
|
prefix_dirs = _get_real_paths_from_prefix (parse, data, attr);
|
||||||
|
if (prefix_dirs)
|
||||||
|
{
|
||||||
|
FcStrList *l = FcStrListCreate (prefix_dirs);
|
||||||
|
FcChar8 *prefix;
|
||||||
|
|
||||||
|
FcStrSetDestroy (prefix_dirs);
|
||||||
|
while ((prefix = FcStrListNext (l)))
|
||||||
|
{
|
||||||
if (!prefix || prefix[0] == 0)
|
if (!prefix || prefix[0] == 0)
|
||||||
{
|
{
|
||||||
/* nop */
|
/* nop */
|
||||||
|
@ -2094,9 +2124,9 @@ FcParseRemapDir (FcConfigParse *parse)
|
||||||
FcConfigMessage (parse, FcSevereError, "out of memory; cannot create remap data for %s as %s", prefix, path);
|
FcConfigMessage (parse, FcSevereError, "out of memory; cannot create remap data for %s as %s", prefix, path);
|
||||||
}
|
}
|
||||||
FcStrBufDestroy (&parse->pstack->str);
|
FcStrBufDestroy (&parse->pstack->str);
|
||||||
|
}
|
||||||
if (prefix)
|
FcStrListDone (l);
|
||||||
FcStrFree (prefix);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2250,7 +2280,7 @@ static void
|
||||||
FcParseDir (FcConfigParse *parse)
|
FcParseDir (FcConfigParse *parse)
|
||||||
{
|
{
|
||||||
const FcChar8 *attr, *data, *salt;
|
const FcChar8 *attr, *data, *salt;
|
||||||
FcChar8 *prefix = NULL;
|
FcStrSet *prefix_dirs = NULL;
|
||||||
|
|
||||||
data = FcStrBufDoneStatic (&parse->pstack->str);
|
data = FcStrBufDoneStatic (&parse->pstack->str);
|
||||||
if (!data)
|
if (!data)
|
||||||
|
@ -2265,7 +2295,15 @@ FcParseDir (FcConfigParse *parse)
|
||||||
}
|
}
|
||||||
attr = FcConfigGetAttribute (parse, "prefix");
|
attr = FcConfigGetAttribute (parse, "prefix");
|
||||||
salt = FcConfigGetAttribute (parse, "salt");
|
salt = FcConfigGetAttribute (parse, "salt");
|
||||||
prefix = _get_real_path_from_prefix (parse, data, attr);
|
prefix_dirs = _get_real_paths_from_prefix (parse, data, attr);
|
||||||
|
if (prefix_dirs)
|
||||||
|
{
|
||||||
|
FcStrList *l = FcStrListCreate (prefix_dirs);
|
||||||
|
FcChar8 *prefix;
|
||||||
|
|
||||||
|
FcStrSetDestroy (prefix_dirs);
|
||||||
|
while ((prefix = FcStrListNext (l)))
|
||||||
|
{
|
||||||
if (!prefix || prefix[0] == 0)
|
if (!prefix || prefix[0] == 0)
|
||||||
{
|
{
|
||||||
/* nop */
|
/* nop */
|
||||||
|
@ -2276,9 +2314,9 @@ FcParseDir (FcConfigParse *parse)
|
||||||
FcConfigMessage (parse, FcSevereError, "out of memory; cannot add directory %s", prefix);
|
FcConfigMessage (parse, FcSevereError, "out of memory; cannot add directory %s", prefix);
|
||||||
}
|
}
|
||||||
FcStrBufDestroy (&parse->pstack->str);
|
FcStrBufDestroy (&parse->pstack->str);
|
||||||
|
}
|
||||||
if (prefix)
|
FcStrListDone (l);
|
||||||
FcStrFree (prefix);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in New Issue