Add new element remap-dir instead of extending dir element
This commit is contained in:
parent
9d3fb5b385
commit
a563a1802e
|
@ -310,15 +310,9 @@ following structure:
|
|||
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.
|
||||
</para></refsect2>
|
||||
<refsect2><title><literal><dir prefix="default" map=""></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
|
||||
to include in the set of available fonts. If 'prefix' is set to "default" or "cwd", the current working directory will be added as the path prefix prior to the value. 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. If 'prefix' is set to "relative", the path of current file will be added prior to the value.
|
||||
</para><para>
|
||||
If a 'map' attribute is specified, its value will replace the
|
||||
directory path when matching cached information for fonts contained in
|
||||
this directory. This is useful if the directory name is an alias
|
||||
(via a bind mount or symlink) to another directory in the system for
|
||||
which cached font information is likely to exist.
|
||||
</para></refsect2>
|
||||
<refsect2><title><literal><cachedir prefix="default"></literal></title><para>
|
||||
This element contains a directory name that is supposed to be stored or read
|
||||
|
@ -357,6 +351,13 @@ drawn as blanks on the screen. Within the <literal><blank></literal> elem
|
|||
Unicode characters which is supposed to be blank in an <literal><int></literal> element.
|
||||
Characters outside of this set which are drawn as blank will be elided from
|
||||
the set of characters supported by the font.
|
||||
</para></refsect2>
|
||||
<refsect2><title><literal><remap-dir prefix="default" as-path=""<</literal></title><para>
|
||||
This element contains a directory name where will be mapped
|
||||
as the path 'as-path' in cached information.
|
||||
This is useful if the directory name is an alias
|
||||
(via a bind mount or symlink) to another directory in the system for
|
||||
which cached font information is likely to exist.
|
||||
</para></refsect2>
|
||||
<refsect2><title><literal><rescan></literal></title><para>
|
||||
The <literal><rescan></literal> element holds an <literal><int></literal> element which indicates the default
|
||||
|
|
11
fonts.dtd
11
fonts.dtd
|
@ -7,6 +7,7 @@
|
|||
dir |
|
||||
include |
|
||||
match |
|
||||
remap-dir |
|
||||
selectfont)* >
|
||||
|
||||
<!--
|
||||
|
@ -14,7 +15,6 @@
|
|||
-->
|
||||
<!ELEMENT dir (#PCDATA)>
|
||||
<!ATTLIST dir
|
||||
map CDATA #IMPLIED
|
||||
prefix (default|xdg|relative|cwd) "default"
|
||||
xml:space (default|preserve) 'preserve'>
|
||||
|
||||
|
@ -110,6 +110,15 @@
|
|||
</edit>
|
||||
</match>
|
||||
-->
|
||||
|
||||
<!--
|
||||
Map a font path as the path "as-path"
|
||||
-->
|
||||
<!ELEMENT remap-dir
|
||||
as-path CDATA #REQUIRED
|
||||
prefix (default|xdg|relative|cwd) "default"
|
||||
xml:space (default|preserve) "preserve">
|
||||
|
||||
<!--
|
||||
Periodically rescan the font configuration and
|
||||
directories to synch internal state with filesystem
|
||||
|
|
279
src/fcxml.c
279
src/fcxml.c
|
@ -358,6 +358,7 @@ typedef enum _FcElement {
|
|||
FcElementMatch,
|
||||
FcElementAlias,
|
||||
FcElementDescription,
|
||||
FcElementRemapDir,
|
||||
|
||||
FcElementRescan,
|
||||
|
||||
|
@ -421,6 +422,7 @@ static const struct {
|
|||
{ "match", FcElementMatch },
|
||||
{ "alias", FcElementAlias },
|
||||
{ "description", FcElementDescription },
|
||||
{ "remap-dir", FcElementRemapDir },
|
||||
|
||||
{ "rescan", FcElementRescan },
|
||||
|
||||
|
@ -490,6 +492,19 @@ FcElementMap (const XML_Char *name)
|
|||
return FcElementUnknown;
|
||||
}
|
||||
|
||||
static const char *
|
||||
FcElementReverseMap (FcElement e)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_ELEMENT_MAPS; i++)
|
||||
if (fcElementMap[i].element == e)
|
||||
return fcElementMap[i].name;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
typedef struct _FcPStack {
|
||||
struct _FcPStack *prev;
|
||||
FcElement element;
|
||||
|
@ -1265,6 +1280,112 @@ FcConfigGetAttribute (FcConfigParse *parse, const char *attr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static FcChar8 *
|
||||
_get_real_path_from_prefix(FcConfigParse *parse, const FcChar8 *path, const FcChar8 *prefix)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
const FcChar8 *data;
|
||||
FcChar8 buffer[1000];
|
||||
#endif
|
||||
FcChar8 *parent = NULL, *retval = NULL;
|
||||
|
||||
if (prefix)
|
||||
{
|
||||
if (FcStrCmp (prefix, (const FcChar8 *) "xdg") == 0)
|
||||
{
|
||||
parent = FcConfigXdgDataHome ();
|
||||
if (!parent)
|
||||
{
|
||||
/* Home directory might be disabled */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (FcStrCmp (prefix, (const FcChar8 *) "default") == 0 ||
|
||||
FcStrCmp (prefix, (const FcChar8 *) "cwd") == 0)
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
else if (FcStrCmp (prefix, (const FcChar8 *) "relative") == 0)
|
||||
{
|
||||
parent = FcStrDirname (parse->name);
|
||||
if (!parent)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#ifndef _WIN32
|
||||
/* For Win32, check this later for dealing with special cases */
|
||||
else
|
||||
{
|
||||
if (!FcStrIsAbsoluteFilename (path) && path[0] != '~')
|
||||
FcConfigMessage (parse, FcSevereWarning, "Use of ambiguous path in <%s> element. please add prefix=\"cwd\" if current behavior is desired.", FcElementReverseMap (parse->pstack->element));
|
||||
}
|
||||
#endif
|
||||
if (parent)
|
||||
{
|
||||
retval = FcStrBuildFilename (parent, path, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
retval = FcStrdup (path);
|
||||
}
|
||||
#ifdef _WIN32
|
||||
if (strcmp ((const char *) path, "CUSTOMFONTDIR") == 0)
|
||||
{
|
||||
FcChar8 *p;
|
||||
data = buffer;
|
||||
if (!GetModuleFileName (NULL, (LPCH) buffer, sizeof (buffer) - 20))
|
||||
{
|
||||
FcConfigMessage (parse, FcSevereError, "GetModuleFileName failed");
|
||||
goto bail;
|
||||
}
|
||||
/*
|
||||
* 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 ((char *) data, "\\fonts");
|
||||
}
|
||||
else if (strcmp ((const char *) path, "APPSHAREFONTDIR") == 0)
|
||||
{
|
||||
FcChar8 *p;
|
||||
data = buffer;
|
||||
if (!GetModuleFileName (NULL, (LPCH) buffer, sizeof (buffer) - 20))
|
||||
{
|
||||
FcConfigMessage (parse, FcSevereError, "GetModuleFileName failed");
|
||||
goto bail;
|
||||
}
|
||||
p = _mbsrchr (data, '\\');
|
||||
if (p) *p = '\0';
|
||||
strcat ((char *) data, "\\..\\share\\fonts");
|
||||
}
|
||||
else if (strcmp ((const char *) path, "WINDOWSFONTDIR") == 0)
|
||||
{
|
||||
int rc;
|
||||
data = buffer;
|
||||
rc = pGetSystemWindowsDirectory ((LPSTR) buffer, sizeof (buffer) - 20);
|
||||
if (rc == 0 || rc > sizeof (buffer) - 20)
|
||||
{
|
||||
FcConfigMessage (parse, FcSevereError, "GetSystemWindowsDirectory failed");
|
||||
goto bail;
|
||||
}
|
||||
if (data [strlen ((const char *) data) - 1] != '\\')
|
||||
strcat ((char *) data, "\\");
|
||||
strcat ((char *) data, "fonts");
|
||||
}
|
||||
else if (!prefix)
|
||||
{
|
||||
if (!FcStrIsAbsoluteFilename (path) && path[0] != '~')
|
||||
FcConfigMessage (parse, FcSevereWarning, "Use of ambiguous path in <%s> element. please add prefix=\"cwd\" if current behavior is desired.", FcElementReverseMap (parse->pstack->element));
|
||||
}
|
||||
retval = FcStrdup (data);
|
||||
#endif
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
FcStartElement(void *userData, const XML_Char *name, const XML_Char **attr)
|
||||
{
|
||||
|
@ -1931,6 +2052,39 @@ FcParseDescription (FcConfigParse *parse)
|
|||
FcStrFree (desc);
|
||||
}
|
||||
|
||||
static void
|
||||
FcParseRemapDir (FcConfigParse *parse)
|
||||
{
|
||||
const FcChar8 *path, *attr, *data;
|
||||
FcChar8 *prefix = NULL;
|
||||
|
||||
data = FcStrBufDoneStatic (&parse->pstack->str);
|
||||
if (!data)
|
||||
{
|
||||
FcConfigMessage (parse, FcSevereError, "out of memory");
|
||||
return;
|
||||
}
|
||||
path = FcConfigGetAttribute (parse, "as-path");
|
||||
if (!path)
|
||||
{
|
||||
FcConfigMessage (parse, FcSevereWarning, "Missing as-path in remap-dir");
|
||||
return;
|
||||
}
|
||||
attr = FcConfigGetAttribute (parse, "prefix");
|
||||
prefix = _get_real_path_from_prefix (parse, data, attr);
|
||||
if (!prefix || prefix[0] == 0)
|
||||
FcConfigMessage (parse, FcSevereWarning, "empty font directory name for remap ignored");
|
||||
else if (!parse->scanOnly && (!FcStrUsesHome (prefix) || FcConfigHome ()))
|
||||
{
|
||||
if (!FcConfigAddFontDir (parse->config, prefix, path))
|
||||
FcConfigMessage (parse, FcSevereError, "out of memory; cannot create remap data for %s as %s", prefix, path);
|
||||
}
|
||||
FcStrBufDestroy (&parse->pstack->str);
|
||||
|
||||
if (prefix)
|
||||
FcStrFree (prefix);
|
||||
}
|
||||
|
||||
static FcExpr *
|
||||
FcPopExpr (FcConfigParse *parse)
|
||||
{
|
||||
|
@ -2071,130 +2225,26 @@ FcParseUnary (FcConfigParse *parse, FcOp op)
|
|||
static void
|
||||
FcParseDir (FcConfigParse *parse)
|
||||
{
|
||||
const FcChar8 *attr, *data, *map;
|
||||
FcChar8 *prefix = NULL, *p;
|
||||
#ifdef _WIN32
|
||||
FcChar8 buffer[1000];
|
||||
#endif
|
||||
const FcChar8 *attr, *data;
|
||||
FcChar8 *prefix = NULL;
|
||||
|
||||
attr = FcConfigGetAttribute (parse, "prefix");
|
||||
map = FcConfigGetAttribute (parse, "map");
|
||||
data = FcStrBufDoneStatic (&parse->pstack->str);
|
||||
if (attr)
|
||||
{
|
||||
if (FcStrCmp (attr, (const FcChar8 *)"xdg") == 0)
|
||||
{
|
||||
prefix = FcConfigXdgDataHome ();
|
||||
/* home directory might be disabled.
|
||||
* simply ignore this element.
|
||||
*/
|
||||
if (!prefix)
|
||||
goto bail;
|
||||
}
|
||||
else if (FcStrCmp (attr, (const FcChar8 *)"default") == 0 || FcStrCmp (attr, (const FcChar8 *)"cwd") == 0)
|
||||
{
|
||||
}
|
||||
else if (FcStrCmp (attr, (const FcChar8 *)"relative") == 0)
|
||||
{
|
||||
prefix = FcStrDirname (parse->name);
|
||||
if (!prefix)
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
#ifndef _WIN32
|
||||
/* For Win32, check this later for dealing with special cases */
|
||||
else
|
||||
{
|
||||
if (!FcStrIsAbsoluteFilename (data) && data[0] != '~')
|
||||
FcConfigMessage (parse, FcSevereWarning, "Use of ambiguous <dir> element. please add prefix=\"cwd\" if current behavior is desired.");
|
||||
}
|
||||
#endif
|
||||
if (!data)
|
||||
{
|
||||
FcConfigMessage (parse, FcSevereError, "out of memory");
|
||||
data = prefix;
|
||||
goto bail;
|
||||
return;
|
||||
}
|
||||
if (prefix)
|
||||
{
|
||||
size_t plen = strlen ((const char *)prefix);
|
||||
size_t dlen = strlen ((const char *)data);
|
||||
|
||||
p = realloc (prefix, plen + 1 + dlen + 1);
|
||||
if (!p)
|
||||
{
|
||||
FcConfigMessage (parse, FcSevereError, "out of memory");
|
||||
goto bail;
|
||||
}
|
||||
prefix = p;
|
||||
prefix[plen] = FC_DIR_SEPARATOR;
|
||||
memcpy (&prefix[plen + 1], data, dlen);
|
||||
prefix[plen + 1 + dlen] = 0;
|
||||
data = prefix;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
if (strcmp ((const char *) data, "CUSTOMFONTDIR") == 0)
|
||||
{
|
||||
FcChar8 *p;
|
||||
data = buffer;
|
||||
if (!GetModuleFileName (NULL, (LPCH) buffer, sizeof (buffer) - 20))
|
||||
{
|
||||
FcConfigMessage (parse, FcSevereError, "GetModuleFileName failed");
|
||||
goto bail;
|
||||
}
|
||||
/*
|
||||
* 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 ((char *) data, "\\fonts");
|
||||
}
|
||||
else if (strcmp ((const char *) data, "APPSHAREFONTDIR") == 0)
|
||||
{
|
||||
FcChar8 *p;
|
||||
data = buffer;
|
||||
if (!GetModuleFileName (NULL, (LPCH) buffer, sizeof (buffer) - 20))
|
||||
{
|
||||
FcConfigMessage (parse, FcSevereError, "GetModuleFileName failed");
|
||||
goto bail;
|
||||
}
|
||||
p = _mbsrchr (data, '\\');
|
||||
if (p) *p = '\0';
|
||||
strcat ((char *) data, "\\..\\share\\fonts");
|
||||
}
|
||||
else if (strcmp ((const char *) data, "WINDOWSFONTDIR") == 0)
|
||||
{
|
||||
int rc;
|
||||
data = buffer;
|
||||
rc = pGetSystemWindowsDirectory ((LPSTR) buffer, sizeof (buffer) - 20);
|
||||
if (rc == 0 || rc > sizeof (buffer) - 20)
|
||||
{
|
||||
FcConfigMessage (parse, FcSevereError, "GetSystemWindowsDirectory failed");
|
||||
goto bail;
|
||||
}
|
||||
if (data [strlen ((const char *) data) - 1] != '\\')
|
||||
strcat ((char *) data, "\\");
|
||||
strcat ((char *) data, "fonts");
|
||||
}
|
||||
else if (!attr)
|
||||
{
|
||||
if (!FcStrIsAbsoluteFilename (data) && data[0] != '~')
|
||||
FcConfigMessage (parse, FcSevereWarning, "Use of ambiguous <dir> element. please add prefix=\"cwd\" if current behavior is desired.");
|
||||
}
|
||||
#endif
|
||||
if (strlen ((char *) data) == 0)
|
||||
attr = FcConfigGetAttribute (parse, "prefix");
|
||||
prefix = _get_real_path_from_prefix (parse, data, attr);
|
||||
if (!prefix || prefix[0] == 0)
|
||||
FcConfigMessage (parse, FcSevereWarning, "empty font directory name ignored");
|
||||
else if (!parse->scanOnly && (!FcStrUsesHome (data) || FcConfigHome ()))
|
||||
else if (!parse->scanOnly && (!FcStrUsesHome (prefix) || FcConfigHome ()))
|
||||
{
|
||||
if (!FcConfigAddFontDir (parse->config, data, map))
|
||||
FcConfigMessage (parse, FcSevereError, "out of memory; cannot add directory %s", data);
|
||||
if (!FcConfigAddFontDir (parse->config, prefix, NULL))
|
||||
FcConfigMessage (parse, FcSevereError, "out of memory; cannot add directory %s", prefix);
|
||||
}
|
||||
FcStrBufDestroy (&parse->pstack->str);
|
||||
|
||||
bail:
|
||||
if (prefix)
|
||||
FcStrFree (prefix);
|
||||
}
|
||||
|
@ -3012,6 +3062,9 @@ FcEndElement(void *userData, const XML_Char *name FC_UNUSED)
|
|||
case FcElementDescription:
|
||||
FcParseDescription (parse);
|
||||
break;
|
||||
case FcElementRemapDir:
|
||||
FcParseRemapDir (parse);
|
||||
break;
|
||||
|
||||
case FcElementRescan:
|
||||
FcParseRescan (parse);
|
||||
|
|
Loading…
Reference in New Issue