Bug 20411 - fontconfig doesn't match FreeDesktop directories specs
Allows reading configuration files, fonts and cache files from the directories where the XDG Base Directory Specification defines. the old directories are still in the configuration files for the backward compatibility.
This commit is contained in:
parent
bc4517d8e5
commit
8c255fb185
|
@ -2,6 +2,9 @@
|
||||||
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
|
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
|
||||||
<fontconfig>
|
<fontconfig>
|
||||||
<!-- Load per-user customization file -->
|
<!-- Load per-user customization file -->
|
||||||
<include ignore_missing="yes">~/.fonts.conf.d</include>
|
<include ignore_missing="yes" prefix="xdg">fontconfig/conf.d</include>
|
||||||
<include ignore_missing="yes">~/.fonts.conf</include>
|
<include ignore_missing="yes" prefix="xdg">fontconfig/fonts.conf</include>
|
||||||
|
<!-- the following elements will be removed in the future -->
|
||||||
|
<include ignore_missing="yes" deprecated="yes">~/.fonts.conf.d</include>
|
||||||
|
<include ignore_missing="yes" deprecated="yes">~/.fonts.conf</include>
|
||||||
</fontconfig>
|
</fontconfig>
|
||||||
|
|
|
@ -37,6 +37,8 @@
|
||||||
&confdir;/fonts.conf
|
&confdir;/fonts.conf
|
||||||
&confdir;/fonts.dtd
|
&confdir;/fonts.dtd
|
||||||
&confdir;/conf.d
|
&confdir;/conf.d
|
||||||
|
$XDG_CONFIG_HOME/fontconfig/conf.d
|
||||||
|
$XDG_CONFIG_HOME/fontconfig/fonts.conf
|
||||||
~/.fonts.conf.d
|
~/.fonts.conf.d
|
||||||
~/.fonts.conf
|
~/.fonts.conf
|
||||||
</synopsis>
|
</synopsis>
|
||||||
|
@ -299,21 +301,22 @@ following structure:
|
||||||
This is the top level element for a font configuration and can contain
|
This is the top level element for a font configuration and can contain
|
||||||
<literal><dir></literal>, <literal><cachedir></literal>, <literal><include></literal>, <literal><match></literal> and <literal><alias></literal> elements in any order.
|
<literal><dir></literal>, <literal><cachedir></literal>, <literal><include></literal>, <literal><match></literal> and <literal><alias></literal> elements in any order.
|
||||||
</para></refsect2>
|
</para></refsect2>
|
||||||
<refsect2><title><literal><dir></literal></title><para>
|
<refsect2><title><literal><dir prefix="default"></literal></title><para>
|
||||||
This element contains a directory name which will be scanned for font files
|
This element contains a directory name which will be scanned for font files
|
||||||
to include in the set of available fonts.
|
to include in the set of available fonts. If 'prefix' is set to "xdg", the value in the XDG_DATA_HOME environment variable will be added as the path prefix. please see XDG Base Directory Specification for more details.
|
||||||
</para></refsect2>
|
</para></refsect2>
|
||||||
<refsect2><title><literal><cachedir></literal></title><para>
|
<refsect2><title><literal><cachedir prefix="default"></literal></title><para>
|
||||||
This element contains a directory name that is supposed to be stored or read
|
This element contains a directory name that is supposed to be stored or read
|
||||||
the cache of font information. If multiple elements are specified in
|
the cache of font information. If multiple elements are specified in
|
||||||
the configuration file, the directory that can be accessed first in the list
|
the configuration file, the directory that can be accessed first in the list
|
||||||
will be used to store the cache files. If it starts with '~', it refers to
|
will be used to store the cache files. If it starts with '~', it refers to
|
||||||
a directory in the users home directory. The default directory is ``~/.fontconfig''
|
a directory in the users home directory. If 'prefix' is set to "xdg", the value in the XDG_CACHE_HOME environment variable will be added as the path prefix. please see XDG Base Directory Specification for more details.
|
||||||
and it contains the cache files named ``<literal><hash value></literal>-<literal><architecture></literal>.cache-<literal><version</literal>'',
|
The default directory is ``$XDG_CACHE_HOME/fontconfig'' and it contains the cache files
|
||||||
|
named ``<literal><hash value></literal>-<literal><architecture></literal>.cache-<literal><version</literal>'',
|
||||||
where <literal><version></literal> is the font configureation file
|
where <literal><version></literal> is the font configureation file
|
||||||
version number (currently 3).
|
version number (currently 3).
|
||||||
</para></refsect2>
|
</para></refsect2>
|
||||||
<refsect2><title><literal><include ignore_missing="no"></literal></title><para>
|
<refsect2><title><literal><include ignore_missing="no" prefix="default"></literal></title><para>
|
||||||
This element contains the name of an additional configuration file or
|
This element contains the name of an additional configuration file or
|
||||||
directory. If a directory, every file within that directory starting with an
|
directory. If a directory, every file within that directory starting with an
|
||||||
ASCII digit (U+0030 - U+0039) and ending with the string ``.conf'' will be processed in sorted order. When
|
ASCII digit (U+0030 - U+0039) and ending with the string ``.conf'' will be processed in sorted order. When
|
||||||
|
@ -321,7 +324,7 @@ the XML datatype is traversed by FcConfigParse, the contents of the file(s)
|
||||||
will also be incorporated into the configuration by passing the filename(s) to
|
will also be incorporated into the configuration by passing the filename(s) to
|
||||||
FcConfigLoadAndParse. If 'ignore_missing' is set to "yes" instead of the
|
FcConfigLoadAndParse. If 'ignore_missing' is set to "yes" instead of the
|
||||||
default "no", a missing file or directory will elicit no warning message from
|
default "no", a missing file or directory will elicit no warning message from
|
||||||
the library.
|
the library. If 'prefix' is set to "xdg", the value in the XDG_CONFIG_HOME environment variable will be added as the path prefix. please see XDG Base Directory Specification for more details.
|
||||||
</para></refsect2>
|
</para></refsect2>
|
||||||
<refsect2><title><literal><config></literal></title><para>
|
<refsect2><title><literal><config></literal></title><para>
|
||||||
This element provides a place to consolidate additional configuration
|
This element provides a place to consolidate additional configuration
|
||||||
|
@ -577,7 +580,7 @@ This is an example of a system-wide configuration file
|
||||||
Load per-user customization file, but don't complain
|
Load per-user customization file, but don't complain
|
||||||
if it doesn't exist
|
if it doesn't exist
|
||||||
-->
|
-->
|
||||||
<include ignore_missing="yes">~/.fonts.conf</include>
|
<include ignore_missing="yes" prefix="xdg">fontconfig/fonts.conf</include>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Load local customization files, but don't complain
|
Load local customization files, but don't complain
|
||||||
|
@ -630,18 +633,18 @@ This is an example of a system-wide configuration file
|
||||||
<refsect2><title>User configuration file</title>
|
<refsect2><title>User configuration file</title>
|
||||||
<para>
|
<para>
|
||||||
This is an example of a per-user configuration file that lives in
|
This is an example of a per-user configuration file that lives in
|
||||||
~/.fonts.conf
|
$XDG_CONFIG_HOME/fontconfig/fonts.conf
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
|
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
|
||||||
<!-- ~/.fonts.conf for per-user font configuration -->
|
<!-- $XDG_CONFIG_HOME/fontconfig/fonts.conf for per-user font configuration -->
|
||||||
<fontconfig>
|
<fontconfig>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Private font directory
|
Private font directory
|
||||||
-->
|
-->
|
||||||
<dir>~/.fonts</dir>
|
<dir prefix="xdg">fonts</dir>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
use rgb sub-pixel ordering to improve glyph appearance on
|
use rgb sub-pixel ordering to improve glyph appearance on
|
||||||
|
@ -677,20 +680,20 @@ format. The master fonts.conf file references this directory in an
|
||||||
is a DTD that describes the format of the configuration files.
|
is a DTD that describes the format of the configuration files.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
<emphasis>~/.fonts.conf.d</emphasis>
|
<emphasis>$XDG_CONFIG_HOME/fontconfig/conf.d</emphasis> and <emphasis>~/.fonts.conf.d</emphasis>
|
||||||
is the conventional name for a per-user directory of (typically
|
is the conventional name for a per-user directory of (typically
|
||||||
auto-generated) configuration files, although the
|
auto-generated) configuration files, although the
|
||||||
actual location is specified in the global fonts.conf file.
|
actual location is specified in the global fonts.conf file. please note that ~/.fonts.conf.d is deprecated now. it will not be read by default in the future version.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
<emphasis>~/.fonts.conf</emphasis>
|
<emphasis>$XDG_CONFIG_HOME/fontconfig/fonts.conf</emphasis> and <emphasis>~/.fonts.conf</emphasis>
|
||||||
is the conventional location for per-user font configuration, although the
|
is the conventional location for per-user font configuration, although the
|
||||||
actual location is specified in the global fonts.conf file.
|
actual location is specified in the global fonts.conf file. please note that ~/.fonts.conf is deprecated now. it will not be read by default in the future version.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
<emphasis> ~/.fontconfig/*.cache-*</emphasis>
|
<emphasis>$XDG_CACHE_HOME/fontconfig/*.cache-*</emphasis> and <emphasis> ~/.fontconfig/*.cache-*</emphasis>
|
||||||
is the conventional repository of font information that isn't found in the
|
is the conventional repository of font information that isn't found in the
|
||||||
per-directory caches. This file is automatically maintained by fontconfig.
|
per-directory caches. This file is automatically maintained by fontconfig. please note that ~/.fontconfig/*.cache-* is deprecated now. it will not be read by default in the future version.
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
<refsect1><title>Environment variables</title>
|
<refsect1><title>Environment variables</title>
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
<dir>@FC_DEFAULT_FONTS@</dir>
|
<dir>@FC_DEFAULT_FONTS@</dir>
|
||||||
@FC_FONTPATH@
|
@FC_FONTPATH@
|
||||||
|
<dir prefix="xdg">fonts</dir>
|
||||||
|
<!-- the following element will be removed in the future -->
|
||||||
<dir>~/.fonts</dir>
|
<dir>~/.fonts</dir>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
@ -71,6 +73,8 @@
|
||||||
<!-- Font cache directory list -->
|
<!-- Font cache directory list -->
|
||||||
|
|
||||||
<cachedir>@FC_CACHEDIR@</cachedir>
|
<cachedir>@FC_CACHEDIR@</cachedir>
|
||||||
|
<cachedir prefix="xdg">fontconfig</cachedir>
|
||||||
|
<!-- the following element will be removed in the future -->
|
||||||
<cachedir>~/.fontconfig</cachedir>
|
<cachedir>~/.fontconfig</cachedir>
|
||||||
|
|
||||||
<config>
|
<config>
|
||||||
|
|
10
fonts.dtd
10
fonts.dtd
|
@ -12,7 +12,9 @@
|
||||||
Add a directory that provides fonts
|
Add a directory that provides fonts
|
||||||
-->
|
-->
|
||||||
<!ELEMENT dir (#PCDATA)>
|
<!ELEMENT dir (#PCDATA)>
|
||||||
<!ATTLIST dir xml:space (default|preserve) 'preserve'>
|
<!ATTLIST dir
|
||||||
|
prefix (#PCDATA) "default"
|
||||||
|
xml:space (default|preserve) 'preserve'>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Define the per-user file that holds cache font information.
|
Define the per-user file that holds cache font information.
|
||||||
|
@ -33,7 +35,9 @@
|
||||||
home directory path.
|
home directory path.
|
||||||
-->
|
-->
|
||||||
<!ELEMENT cachedir (#PCDATA)>
|
<!ELEMENT cachedir (#PCDATA)>
|
||||||
<!ATTLIST cachedir xml:space (default|preserve) 'preserve'>
|
<!ATTLIST cachedir
|
||||||
|
prefix (#PCDATA) "default"
|
||||||
|
xml:space (default|preserve) 'preserve'>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Reference another configuration file; note that this
|
Reference another configuration file; note that this
|
||||||
|
@ -48,6 +52,8 @@
|
||||||
<!ELEMENT include (#PCDATA)>
|
<!ELEMENT include (#PCDATA)>
|
||||||
<!ATTLIST include
|
<!ATTLIST include
|
||||||
ignore_missing (no|yes) "no"
|
ignore_missing (no|yes) "no"
|
||||||
|
prefix (#PCDATA) "default"
|
||||||
|
deprecated (#PCDATA) "no"
|
||||||
xml:space (default|preserve) "preserve">
|
xml:space (default|preserve) "preserve">
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
|
78
src/fccfg.c
78
src/fccfg.c
|
@ -1837,6 +1837,81 @@ FcConfigHome (void)
|
||||||
return 0;
|
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
|
FcBool
|
||||||
FcConfigEnableHome (FcBool enable)
|
FcConfigEnableHome (FcBool enable)
|
||||||
{
|
{
|
||||||
|
@ -1883,7 +1958,7 @@ FcConfigFilename (const FcChar8 *url)
|
||||||
default:
|
default:
|
||||||
path = FcConfigGetPath ();
|
path = FcConfigGetPath ();
|
||||||
if (!path)
|
if (!path)
|
||||||
return 0;
|
return NULL;
|
||||||
for (p = path; *p; p++)
|
for (p = path; *p; p++)
|
||||||
{
|
{
|
||||||
file = FcConfigFileExists (*p, url);
|
file = FcConfigFileExists (*p, url);
|
||||||
|
@ -1893,6 +1968,7 @@ FcConfigFilename (const FcChar8 *url)
|
||||||
FcConfigFreePath (path);
|
FcConfigFreePath (path);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
20
src/fcinit.c
20
src/fcinit.c
|
@ -72,21 +72,37 @@ FcInitLoadConfig (void)
|
||||||
|
|
||||||
if (config->cacheDirs && config->cacheDirs->num == 0)
|
if (config->cacheDirs && config->cacheDirs->num == 0)
|
||||||
{
|
{
|
||||||
|
FcChar8 *prefix;
|
||||||
|
size_t plen;
|
||||||
|
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"Fontconfig warning: no <cachedir> elements found. Check configuration.\n");
|
"Fontconfig warning: no <cachedir> elements found. Check configuration.\n");
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"Fontconfig warning: adding <cachedir>%s</cachedir>\n",
|
"Fontconfig warning: adding <cachedir>%s</cachedir>\n",
|
||||||
FC_CACHEDIR);
|
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,
|
fprintf (stderr,
|
||||||
"Fontconfig warning: adding <cachedir>~/.fontconfig</cachedir>\n");
|
"Fontconfig warning: adding <cachedir prefix=\"xdg\">fontconfig</cachedir>\n");
|
||||||
|
|
||||||
if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR) ||
|
if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR) ||
|
||||||
!FcConfigAddCacheDir (config, (FcChar8 *) "~/.fontconfig"))
|
!FcConfigAddCacheDir (config, (FcChar8 *) prefix))
|
||||||
{
|
{
|
||||||
|
bail:
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"Fontconfig error: out of memory");
|
"Fontconfig error: out of memory");
|
||||||
|
free (prefix);
|
||||||
FcConfigDestroy (config);
|
FcConfigDestroy (config);
|
||||||
return FcInitFallbackConfig ();
|
return FcInitFallbackConfig ();
|
||||||
}
|
}
|
||||||
|
free (prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
|
|
11
src/fcint.h
11
src/fcint.h
|
@ -64,9 +64,11 @@ typedef HRESULT (WINAPI *pfnSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR);
|
||||||
extern pfnGetSystemWindowsDirectory pGetSystemWindowsDirectory;
|
extern pfnGetSystemWindowsDirectory pGetSystemWindowsDirectory;
|
||||||
extern pfnSHGetFolderPathA pSHGetFolderPathA;
|
extern pfnSHGetFolderPathA pSHGetFolderPathA;
|
||||||
# define FC_SEARCH_PATH_SEPARATOR ';'
|
# define FC_SEARCH_PATH_SEPARATOR ';'
|
||||||
|
# define FC_DIR_SEPARATOR '\\'
|
||||||
# define FC_DIR_SEPARATOR_S "\\"
|
# define FC_DIR_SEPARATOR_S "\\"
|
||||||
#else
|
#else
|
||||||
# define FC_SEARCH_PATH_SEPARATOR ':'
|
# define FC_SEARCH_PATH_SEPARATOR ':'
|
||||||
|
# define FC_DIR_SEPARATOR '/'
|
||||||
# define FC_DIR_SEPARATOR_S "/"
|
# define FC_DIR_SEPARATOR_S "/"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -570,6 +572,15 @@ FcStat (const FcChar8 *file, struct stat *statb);
|
||||||
|
|
||||||
/* fccfg.c */
|
/* fccfg.c */
|
||||||
|
|
||||||
|
FcPrivate FcChar8 *
|
||||||
|
FcConfigXdgCacheHome (void);
|
||||||
|
|
||||||
|
FcPrivate FcChar8 *
|
||||||
|
FcConfigXdgConfigHome (void);
|
||||||
|
|
||||||
|
FcPrivate FcChar8 *
|
||||||
|
FcConfigXdgDataHome (void);
|
||||||
|
|
||||||
FcPrivate FcExpr *
|
FcPrivate FcExpr *
|
||||||
FcConfigAllocExpr (FcConfig *config);
|
FcConfigAllocExpr (FcConfig *config);
|
||||||
|
|
||||||
|
|
|
@ -896,11 +896,11 @@ FcStrCopyFilename (const FcChar8 *s)
|
||||||
FcChar8 *full;
|
FcChar8 *full;
|
||||||
int size;
|
int size;
|
||||||
if (!home)
|
if (!home)
|
||||||
return 0;
|
return NULL;
|
||||||
size = strlen ((char *) home) + strlen ((char *) s);
|
size = strlen ((char *) home) + strlen ((char *) s);
|
||||||
full = (FcChar8 *) malloc (size);
|
full = (FcChar8 *) malloc (size);
|
||||||
if (!full)
|
if (!full)
|
||||||
return 0;
|
return NULL;
|
||||||
strcpy ((char *) full, (char *) home);
|
strcpy ((char *) full, (char *) home);
|
||||||
strcat ((char *) full, (char *) s + 1);
|
strcat ((char *) full, (char *) s + 1);
|
||||||
new = FcStrCanonFilename (full);
|
new = FcStrCanonFilename (full);
|
||||||
|
@ -908,6 +908,7 @@ FcStrCopyFilename (const FcChar8 *s)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
new = FcStrCanonFilename (s);
|
new = FcStrCanonFilename (s);
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
344
src/fcxml.c
344
src/fcxml.c
|
@ -1843,25 +1843,239 @@ FcParseUnary (FcConfigParse *parse, FcOp op)
|
||||||
FcVStackPushExpr (parse, FcVStackExpr, expr);
|
FcVStackPushExpr (parse, FcVStackExpr, expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static void
|
||||||
FcParseInclude (FcConfigParse *parse)
|
FcParseInclude (FcConfigParse *parse)
|
||||||
{
|
{
|
||||||
FcChar8 *s;
|
FcChar8 *s;
|
||||||
const FcChar8 *i;
|
const FcChar8 *attr;
|
||||||
FcBool ignore_missing = FcFalse;
|
FcBool ignore_missing = FcFalse;
|
||||||
|
FcChar8 *prefix = NULL;
|
||||||
|
|
||||||
s = FcStrBufDoneStatic (&parse->pstack->str);
|
s = FcStrBufDoneStatic (&parse->pstack->str);
|
||||||
if (!s)
|
if (!s)
|
||||||
{
|
{
|
||||||
FcConfigMessage (parse, FcSevereError, "out of memory");
|
FcConfigMessage (parse, FcSevereError, "out of memory");
|
||||||
return;
|
goto bail;
|
||||||
}
|
}
|
||||||
i = FcConfigGetAttribute (parse, "ignore_missing");
|
attr = FcConfigGetAttribute (parse, "ignore_missing");
|
||||||
if (i && FcConfigLexBool (parse, (FcChar8 *) i) == FcTrue)
|
if (attr && FcConfigLexBool (parse, (FcChar8 *) attr) == FcTrue)
|
||||||
ignore_missing = 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))
|
if (!FcConfigParseAndLoad (parse->config, s, !ignore_missing))
|
||||||
parse->error = FcTrue;
|
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);
|
FcStrBufDestroy (&parse->pstack->str);
|
||||||
|
|
||||||
|
bail:
|
||||||
|
if (prefix)
|
||||||
|
free (prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct _FcOpMap {
|
typedef struct _FcOpMap {
|
||||||
|
@ -2296,129 +2510,11 @@ FcEndElement(void *userData, const XML_Char *name)
|
||||||
case FcElementFontconfig:
|
case FcElementFontconfig:
|
||||||
break;
|
break;
|
||||||
case FcElementDir:
|
case FcElementDir:
|
||||||
data = FcStrBufDoneStatic (&parse->pstack->str);
|
FcParseDir (parse);
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
case FcElementCacheDir:
|
case FcElementCacheDir:
|
||||||
data = FcStrBufDone (&parse->pstack->str);
|
FcParseCacheDir (parse);
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FcElementCache:
|
case FcElementCache:
|
||||||
data = FcStrBufDoneStatic (&parse->pstack->str);
|
data = FcStrBufDoneStatic (&parse->pstack->str);
|
||||||
if (!data)
|
if (!data)
|
||||||
|
|
Loading…
Reference in New Issue