aboutsummaryrefslogtreecommitdiff
path: root/fontconfig/src
diff options
context:
space:
mode:
Diffstat (limited to 'fontconfig/src')
-rw-r--r--fontconfig/src/fccfg.c78
-rw-r--r--fontconfig/src/fcinit.c20
-rw-r--r--fontconfig/src/fcint.h11
-rw-r--r--fontconfig/src/fcstr.c5
-rw-r--r--fontconfig/src/fcxml.c344
5 files changed, 329 insertions, 129 deletions
diff --git a/fontconfig/src/fccfg.c b/fontconfig/src/fccfg.c
index 31c427636..5b7249201 100644
--- a/fontconfig/src/fccfg.c
+++ b/fontconfig/src/fccfg.c
@@ -1837,6 +1837,81 @@ FcConfigHome (void)
return 0;
}
+FcChar8 *
+FcConfigXdgCacheHome (void)
+{
+ const char *env = getenv ("XDG_CACHE_HOME");
+ FcChar8 *ret = NULL;
+
+ if (env)
+ ret = FcStrCopy ((const FcChar8 *)env);
+ else
+ {
+ const FcChar8 *home = FcConfigHome ();
+ size_t len = home ? strlen ((const char *)home) : 0;
+
+ ret = malloc (len + 7 + 1);
+ if (ret)
+ {
+ memcpy (ret, home, len);
+ memcpy (&ret[len], FC_DIR_SEPARATOR_S ".cache", 7);
+ ret[len + 7] = 0;
+ }
+ }
+
+ return ret;
+}
+
+FcChar8 *
+FcConfigXdgConfigHome (void)
+{
+ const char *env = getenv ("XDG_CONFIG_HOME");
+ FcChar8 *ret = NULL;
+
+ if (env)
+ ret = FcStrCopy ((const FcChar8 *)env);
+ else
+ {
+ const FcChar8 *home = FcConfigHome ();
+ size_t len = home ? strlen ((const char *)home) : 0;
+
+ ret = malloc (len + 8 + 1);
+ if (ret)
+ {
+ memcpy (ret, home, len);
+ memcpy (&ret[len], FC_DIR_SEPARATOR_S ".config", 8);
+ ret[len + 8] = 0;
+ }
+ }
+
+ return ret;
+}
+
+FcChar8 *
+FcConfigXdgDataHome (void)
+{
+ const char *env = getenv ("XDG_DATA_HOME");
+ FcChar8 *ret = NULL;
+
+ if (env)
+ ret = FcStrCopy ((const FcChar8 *)env);
+ else
+ {
+ const FcChar8 *home = FcConfigHome ();
+ size_t len = home ? strlen ((const char *)home) : 0;
+
+ ret = malloc (len + 13 + 1);
+ if (ret)
+ {
+ memcpy (ret, home, len);
+ memcpy (&ret[len], FC_DIR_SEPARATOR_S ".local" FC_DIR_SEPARATOR_S "share", 13);
+ ret[len + 13] = 0;
+ }
+ }
+
+ return ret;
+}
+
FcBool
FcConfigEnableHome (FcBool enable)
{
@@ -1883,7 +1958,7 @@ FcConfigFilename (const FcChar8 *url)
default:
path = FcConfigGetPath ();
if (!path)
- return 0;
+ return NULL;
for (p = path; *p; p++)
{
file = FcConfigFileExists (*p, url);
@@ -1893,6 +1968,7 @@ FcConfigFilename (const FcChar8 *url)
FcConfigFreePath (path);
break;
}
+
return file;
}
diff --git a/fontconfig/src/fcinit.c b/fontconfig/src/fcinit.c
index abf64b57f..ab6401215 100644
--- a/fontconfig/src/fcinit.c
+++ b/fontconfig/src/fcinit.c
@@ -72,21 +72,37 @@ FcInitLoadConfig (void)
if (config->cacheDirs && config->cacheDirs->num == 0)
{
+ FcChar8 *prefix;
+ size_t plen;
+
fprintf (stderr,
"Fontconfig warning: no <cachedir> elements found. Check configuration.\n");
fprintf (stderr,
"Fontconfig warning: adding <cachedir>%s</cachedir>\n",
FC_CACHEDIR);
+ prefix = FcConfigXdgCacheHome ();
+ plen = prefix ? strlen ((const char *)prefix) : 0;
+ if (!prefix)
+ goto bail;
+ prefix = realloc (prefix, plen + 12);
+ if (!prefix)
+ goto bail;
+ memcpy (&prefix[plen], FC_DIR_SEPARATOR_S "fontconfig", 11);
+ prefix[plen + 11] = 0;
fprintf (stderr,
- "Fontconfig warning: adding <cachedir>~/.fontconfig</cachedir>\n");
+ "Fontconfig warning: adding <cachedir prefix=\"xdg\">fontconfig</cachedir>\n");
+
if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR) ||
- !FcConfigAddCacheDir (config, (FcChar8 *) "~/.fontconfig"))
+ !FcConfigAddCacheDir (config, (FcChar8 *) prefix))
{
+ bail:
fprintf (stderr,
"Fontconfig error: out of memory");
+ free (prefix);
FcConfigDestroy (config);
return FcInitFallbackConfig ();
}
+ free (prefix);
}
return config;
diff --git a/fontconfig/src/fcint.h b/fontconfig/src/fcint.h
index defbd7acb..46562c4ca 100644
--- a/fontconfig/src/fcint.h
+++ b/fontconfig/src/fcint.h
@@ -66,9 +66,11 @@ typedef HRESULT (WINAPI *pfnSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR);
extern pfnGetSystemWindowsDirectory pGetSystemWindowsDirectory;
extern pfnSHGetFolderPathA pSHGetFolderPathA;
# define FC_SEARCH_PATH_SEPARATOR ';'
+# define FC_DIR_SEPARATOR '\\'
# define FC_DIR_SEPARATOR_S "\\"
#else
# define FC_SEARCH_PATH_SEPARATOR ':'
+# define FC_DIR_SEPARATOR '/'
# define FC_DIR_SEPARATOR_S "/"
#endif
@@ -572,6 +574,15 @@ FcStat (const FcChar8 *file, struct stat *statb);
/* fccfg.c */
+FcPrivate FcChar8 *
+FcConfigXdgCacheHome (void);
+
+FcPrivate FcChar8 *
+FcConfigXdgConfigHome (void);
+
+FcPrivate FcChar8 *
+FcConfigXdgDataHome (void);
+
FcPrivate FcExpr *
FcConfigAllocExpr (FcConfig *config);
diff --git a/fontconfig/src/fcstr.c b/fontconfig/src/fcstr.c
index ae37ff00a..f20d05e7d 100644
--- a/fontconfig/src/fcstr.c
+++ b/fontconfig/src/fcstr.c
@@ -896,11 +896,11 @@ FcStrCopyFilename (const FcChar8 *s)
FcChar8 *full;
int size;
if (!home)
- return 0;
+ return NULL;
size = strlen ((char *) home) + strlen ((char *) s);
full = (FcChar8 *) malloc (size);
if (!full)
- return 0;
+ return NULL;
strcpy ((char *) full, (char *) home);
strcat ((char *) full, (char *) s + 1);
new = FcStrCanonFilename (full);
@@ -908,6 +908,7 @@ FcStrCopyFilename (const FcChar8 *s)
}
else
new = FcStrCanonFilename (s);
+
return new;
}
diff --git a/fontconfig/src/fcxml.c b/fontconfig/src/fcxml.c
index c49529a81..f0272705d 100644
--- a/fontconfig/src/fcxml.c
+++ b/fontconfig/src/fcxml.c
@@ -1844,24 +1844,238 @@ FcParseUnary (FcConfigParse *parse, FcOp op)
}
static void
+FcParseDir (FcConfigParse *parse)
+{
+ const FcChar8 *attr, *data;
+ FcChar8 *prefix = NULL;
+
+ attr = FcConfigGetAttribute (parse, "prefix");
+ if (attr && FcStrCmp (attr, (const FcChar8 *)"xdg") == 0)
+ prefix = FcConfigXdgDataHome ();
+ data = FcStrBufDoneStatic (&parse->pstack->str);
+ if (!data)
+ {
+ FcConfigMessage (parse, FcSevereError, "out of memory");
+ goto bail;
+ }
+ if (prefix)
+ {
+ size_t plen = strlen ((const char *)prefix);
+ size_t dlen = strlen ((const char *)data);
+
+ prefix = realloc (prefix, plen + 1 + dlen + 1);
+ if (!prefix)
+ {
+ FcConfigMessage (parse, FcSevereError, "out of memory");
+ goto bail;
+ }
+ prefix[plen] = FC_DIR_SEPARATOR;
+ memcpy (&prefix[plen + 1], data, dlen);
+ prefix[plen + 1 + dlen] = 0;
+ data = prefix;
+ }
+#ifdef _WIN32
+ if (strcmp (data, "CUSTOMFONTDIR") == 0)
+ {
+ char *p;
+ data = buffer;
+ if (!GetModuleFileName (NULL, buffer, sizeof (buffer) - 20))
+ {
+ FcConfigMessage (parse, FcSevereError, "GetModuleFileName failed");
+ break;
+ }
+ /*
+ * Must use the multi-byte aware function to search
+ * for backslash because East Asian double-byte code
+ * pages have characters with backslash as the second
+ * byte.
+ */
+ p = _mbsrchr (data, '\\');
+ if (p) *p = '\0';
+ strcat (data, "\\fonts");
+ }
+ else if (strcmp (data, "APPSHAREFONTDIR") == 0)
+ {
+ char *p;
+ data = buffer;
+ if (!GetModuleFileName (NULL, buffer, sizeof (buffer) - 20))
+ {
+ FcConfigMessage (parse, FcSevereError, "GetModuleFileName failed");
+ break;
+ }
+ p = _mbsrchr (data, '\\');
+ if (p) *p = '\0';
+ strcat (data, "\\..\\share\\fonts");
+ }
+ else if (strcmp (data, "WINDOWSFONTDIR") == 0)
+ {
+ int rc;
+ data = buffer;
+ rc = pGetSystemWindowsDirectory (buffer, sizeof (buffer) - 20);
+ if (rc == 0 || rc > sizeof (buffer) - 20)
+ {
+ FcConfigMessage (parse, FcSevereError, "GetSystemWindowsDirectory failed");
+ break;
+ }
+ if (data [strlen (data) - 1] != '\\')
+ strcat (data, "\\");
+ strcat (data, "fonts");
+ }
+#endif
+ if (strlen ((char *) data) == 0)
+ FcConfigMessage (parse, FcSevereWarning, "empty font directory name ignored");
+ else if (!FcStrUsesHome (data) || FcConfigHome ())
+ {
+ if (!FcConfigAddDir (parse->config, data))
+ FcConfigMessage (parse, FcSevereError, "out of memory; cannot add directory %s", data);
+ }
+ FcStrBufDestroy (&parse->pstack->str);
+
+ bail:
+ if (prefix)
+ free (prefix);
+}
+
+static void
+FcParseCacheDir (FcConfigParse *parse)
+{
+ const FcChar8 *attr;
+ FcChar8 *prefix = NULL, *data;
+
+ attr = FcConfigGetAttribute (parse, "prefix");
+ if (attr && FcStrCmp (attr, (const FcChar8 *)"xdg") == 0)
+ prefix = FcConfigXdgCacheHome ();
+ data = FcStrBufDone (&parse->pstack->str);
+ if (!data)
+ {
+ FcConfigMessage (parse, FcSevereError, "out of memory");
+ goto bail;
+ }
+ if (prefix)
+ {
+ size_t plen = strlen ((const char *)prefix);
+ size_t dlen = strlen ((const char *)data);
+
+ prefix = realloc (prefix, plen + 1 + dlen + 1);
+ if (!prefix)
+ {
+ FcConfigMessage (parse, FcSevereError, "out of memory");
+ goto bail;
+ }
+ prefix[plen] = FC_DIR_SEPARATOR;
+ memcpy (&prefix[plen + 1], data, dlen);
+ prefix[plen + 1 + dlen] = 0;
+ FcStrFree (data);
+ data = prefix;
+ }
+#ifdef _WIN32
+ if (strcmp (data, "WINDOWSTEMPDIR_FONTCONFIG_CACHE") == 0)
+ {
+ int rc;
+ FcStrFree (data);
+ data = malloc (1000);
+ if (!data)
+ {
+ FcConfigMessage (parse, FcSevereError, "out of memory");
+ goto bail;
+ }
+ FcMemAlloc (FC_MEM_STRING, 1000);
+ rc = GetTempPath (800, data);
+ if (rc == 0 || rc > 800)
+ {
+ FcConfigMessage (parse, FcSevereError, "GetTempPath failed");
+ goto bail;
+ }
+ if (data [strlen (data) - 1] != '\\')
+ strcat (data, "\\");
+ strcat (data, "fontconfig\\cache");
+ }
+ else if (strcmp (data, "LOCAL_APPDATA_FONTCONFIG_CACHE") == 0)
+ {
+ char szFPath[MAX_PATH + 1];
+ size_t len;
+
+ if (!(pSHGetFolderPathA && SUCCEEDED(pSHGetFolderPathA(NULL, /* CSIDL_LOCAL_APPDATA */ 28, NULL, 0, szFPath))))
+ {
+ FcConfigMessage (parse, FcSevereError, "SHGetFolderPathA failed");
+ goto bail;
+ }
+ strncat(szFPath, "\\fontconfig\\cache", MAX_PATH - 1 - strlen(szFPath));
+ len = strlen(szFPath) + 1;
+ FcStrFree (data);
+ data = malloc(len);
+ if (!data)
+ {
+ FcConfigMessage (parse, FcSevereError, "out of memory");
+ goto bail;
+ }
+ FcMemAlloc (FC_MEM_STRING, len);
+ strncpy(data, szFPath, len);
+ }
+#endif
+ if (strlen ((char *) data) == 0)
+ FcConfigMessage (parse, FcSevereWarning, "empty cache directory name ignored");
+ else if (!FcStrUsesHome (data) || FcConfigHome ())
+ {
+ if (!FcConfigAddCacheDir (parse->config, data))
+ FcConfigMessage (parse, FcSevereError, "out of memory; cannot add cache directory %s", data);
+ }
+ FcStrBufDestroy (&parse->pstack->str);
+
+ bail:
+ if (data)
+ FcStrFree (data);
+}
+
+static void
FcParseInclude (FcConfigParse *parse)
{
FcChar8 *s;
- const FcChar8 *i;
+ const FcChar8 *attr;
FcBool ignore_missing = FcFalse;
+ FcChar8 *prefix = NULL;
s = FcStrBufDoneStatic (&parse->pstack->str);
if (!s)
{
FcConfigMessage (parse, FcSevereError, "out of memory");
- return;
+ goto bail;
}
- i = FcConfigGetAttribute (parse, "ignore_missing");
- if (i && FcConfigLexBool (parse, (FcChar8 *) i) == FcTrue)
+ attr = FcConfigGetAttribute (parse, "ignore_missing");
+ if (attr && FcConfigLexBool (parse, (FcChar8 *) attr) == FcTrue)
ignore_missing = FcTrue;
+ attr = FcConfigGetAttribute (parse, "prefix");
+ if (attr && FcStrCmp (attr, (const FcChar8 *)"xdg") == 0)
+ prefix = FcConfigXdgConfigHome ();
+ if (prefix)
+ {
+ size_t plen = strlen ((const char *)prefix);
+ size_t dlen = strlen ((const char *)s);
+
+ prefix = realloc (prefix, plen + 1 + dlen + 1);
+ if (!prefix)
+ {
+ FcConfigMessage (parse, FcSevereError, "out of memory");
+ goto bail;
+ }
+ prefix[plen] = FC_DIR_SEPARATOR;
+ memcpy (&prefix[plen + 1], s, dlen);
+ prefix[plen + 1 + dlen] = 0;
+ s = prefix;
+ }
if (!FcConfigParseAndLoad (parse->config, s, !ignore_missing))
parse->error = FcTrue;
+ else
+ {
+ attr = FcConfigGetAttribute (parse, "deprecated");
+ if (attr && FcConfigLexBool (parse, (FcChar8 *) attr) == FcTrue)
+ FcConfigMessage (parse, FcSevereWarning, "reading configurations from %s is deprecated.\n", s);
+ }
FcStrBufDestroy (&parse->pstack->str);
+
+ bail:
+ if (prefix)
+ free (prefix);
}
typedef struct _FcOpMap {
@@ -2296,129 +2510,11 @@ FcEndElement(void *userData, const XML_Char *name)
case FcElementFontconfig:
break;
case FcElementDir:
- data = FcStrBufDoneStatic (&parse->pstack->str);
- if (!data)
- {
- FcConfigMessage (parse, FcSevereError, "out of memory");
- break;
- }
-#ifdef _WIN32
- if (strcmp (data, "CUSTOMFONTDIR") == 0)
- {
- char *p;
- data = buffer;
- if (!GetModuleFileName (NULL, buffer, sizeof (buffer) - 20))
- {
- FcConfigMessage (parse, FcSevereError, "GetModuleFileName failed");
- break;
- }
- /*
- * Must use the multi-byte aware function to search
- * for backslash because East Asian double-byte code
- * pages have characters with backslash as the second
- * byte.
- */
- p = _mbsrchr (data, '\\');
- if (p) *p = '\0';
- strcat (data, "\\fonts");
- }
- else if (strcmp (data, "APPSHAREFONTDIR") == 0)
- {
- char *p;
- data = buffer;
- if (!GetModuleFileName (NULL, buffer, sizeof (buffer) - 20))
- {
- FcConfigMessage (parse, FcSevereError, "GetModuleFileName failed");
- break;
- }
- p = _mbsrchr (data, '\\');
- if (p) *p = '\0';
- strcat (data, "\\..\\share\\fonts");
- }
- else if (strcmp (data, "WINDOWSFONTDIR") == 0)
- {
- int rc;
- data = buffer;
- rc = pGetSystemWindowsDirectory (buffer, sizeof (buffer) - 20);
- if (rc == 0 || rc > sizeof (buffer) - 20)
- {
- FcConfigMessage (parse, FcSevereError, "GetSystemWindowsDirectory failed");
- break;
- }
- if (data [strlen (data) - 1] != '\\')
- strcat (data, "\\");
- strcat (data, "fonts");
- }
-#endif
- if (strlen ((char *) data) == 0)
- FcConfigMessage (parse, FcSevereWarning, "empty font directory name ignored");
- else if (!FcStrUsesHome (data) || FcConfigHome ())
- {
- if (!FcConfigAddDir (parse->config, data))
- FcConfigMessage (parse, FcSevereError, "out of memory; cannot add directory %s", data);
- }
- FcStrBufDestroy (&parse->pstack->str);
+ FcParseDir (parse);
break;
case FcElementCacheDir:
- data = FcStrBufDone (&parse->pstack->str);
- if (!data)
- {
- FcConfigMessage (parse, FcSevereError, "out of memory");
- break;
- }
-#ifdef _WIN32
- if (strcmp (data, "WINDOWSTEMPDIR_FONTCONFIG_CACHE") == 0)
- {
- int rc;
- FcStrFree (data);
- data = malloc (1000);
- if (!data)
- {
- FcConfigMessage (parse, FcSevereError, "out of memory");
- break;
- }
- FcMemAlloc (FC_MEM_STRING, 1000);
- rc = GetTempPath (800, data);
- if (rc == 0 || rc > 800)
- {
- FcConfigMessage (parse, FcSevereError, "GetTempPath failed");
- FcStrFree (data);
- break;
- }
- if (data [strlen (data) - 1] != '\\')
- strcat (data, "\\");
- strcat (data, "fontconfig\\cache");
- }
- else if (strcmp (data, "LOCAL_APPDATA_FONTCONFIG_CACHE") == 0)
- {
- char szFPath[MAX_PATH + 1];
- size_t len;
- FcStrFree (data);
- if (!(pSHGetFolderPathA && SUCCEEDED(pSHGetFolderPathA(NULL, /* CSIDL_LOCAL_APPDATA */ 28, NULL, 0, szFPath))))
- {
- FcConfigMessage (parse, FcSevereError, "SHGetFolderPathA failed");
- break;
- }
- strncat(szFPath, "\\fontconfig\\cache", MAX_PATH - 1 - strlen(szFPath));
- len = strlen(szFPath) + 1;
- data = malloc(len);
- if (!data)
- {
- FcConfigMessage (parse, FcSevereError, "out of memory");
- break;
- }
- FcMemAlloc (FC_MEM_STRING, len);
- strncpy(data, szFPath, len);
- }
-#endif
- if (!FcStrUsesHome (data) || FcConfigHome ())
- {
- if (!FcConfigAddCacheDir (parse->config, data))
- FcConfigMessage (parse, FcSevereError, "out of memory; cannot add cache directory %s", data);
- }
- FcStrFree (data);
+ FcParseCacheDir (parse);
break;
-
case FcElementCache:
data = FcStrBufDoneStatic (&parse->pstack->str);
if (!data)