diff options
Diffstat (limited to 'fontconfig/src')
-rw-r--r-- | fontconfig/src/fccfg.c | 78 | ||||
-rw-r--r-- | fontconfig/src/fcinit.c | 20 | ||||
-rw-r--r-- | fontconfig/src/fcint.h | 11 | ||||
-rw-r--r-- | fontconfig/src/fcstr.c | 5 | ||||
-rw-r--r-- | fontconfig/src/fcxml.c | 344 |
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) |