[PATCH libXfont] Add a new 'catalogue' FPE, which takes font paths from symlinks in a dir.
Ademar de Souza Reis Jr.
ademar at mandriva.com.br
Tue Jun 19 14:40:58 PDT 2007
Good work!
After an initial test/review everything looks fine. I'll add it
to our package to get additional tests. Do you know if someone is
working on adding support for catalogue's dir into chkfontpath?
:-)
Thanks,
- Ademar
On Tue, Jun 19, 2007 at 11:00:05AM -0400, Kristian Høgsberg wrote:
> This patch adds a new FPE type, which will match font path elements of the
> form
>
> catalogue:<dir>
>
> The dir specified after the catalogue: prefix will be scanned for symlinks
> and each symlink destination will be added as a local fontfile FPE.
> The symlink can be suffixed by attributes, such as 'unscaled', which
> will be passed through to the underlying fontfile FPE. Except the new
> attribute 'pri' which will be used for ordering the fontfile FPEs.
>
> An example configuration:
>
> 75dpi:unscaled:pri=20 -> /usr/share/X11/fonts/75dpi
> ghostscript:pri=60 -> /usr/share/fonts/default/ghostscript
> misc:unscaled:pri=10 -> /usr/share/X11/fonts/misc
> type1:pri=40 -> /usr/share/X11/fonts/Type1
> type1:pri=50 -> /usr/share/fonts/default/Type1
>
> will add /usr/share/X11/fonts/misc as the first FPE with the attribute
> 'unscaled', second FPE will be /usr/share/X11/fonts/75dpi, also with
> the attribute unscaled etc. This is functionally equivalent to setting
> the following font path:
>
> /usr/share/X11/fonts/misc:unscaled,
> /usr/share/X11/fonts/75dpi:unscaled,
> /usr/share/X11/fonts/Type1,
> /usr/share/fonts/default/Type1,
> /usr/share/fonts/default/ghostscript
>
> The motivation is to let font packages add a symlink to the new font
> directory they provide instead of rewriting either the Xorg config file
> or the xfs config file.
> ---
> include/X11/fonts/fntfil.h | 4 +
> src/fontfile/Makefile.am | 3 +-
> src/fontfile/catalogue.c | 391 ++++++++++++++++++++++++++++++++++++++++++++
> src/fontfile/fontfile.c | 41 ++---
> src/fontfile/register.c | 1 +
> 5 files changed, 413 insertions(+), 27 deletions(-)
> create mode 100644 src/fontfile/catalogue.c
>
> diff --git a/include/X11/fonts/fntfil.h b/include/X11/fonts/fntfil.h
> index 81d2cbc..074f2d0 100644
> --- a/include/X11/fonts/fntfil.h
> +++ b/include/X11/fonts/fntfil.h
> @@ -92,6 +92,9 @@ extern int FontFileOpenBitmap ( FontPathElementPtr fpe, FontPtr *pFont,
> extern int FontFileListFonts ( pointer client, FontPathElementPtr fpe,
> char *pat, int len, int max,
> FontNamesPtr names );
> +extern int FontFileStartListFonts ( pointer client, FontPathElementPtr fpe,
> + char *pat, int len, int max,
> + pointer *privatep, int mark_aliases );
> extern int FontFileStartListFontsWithInfo ( pointer client,
> FontPathElementPtr fpe,
> char *pat, int len, int max,
> @@ -111,6 +114,7 @@ extern int FontFileListNextFontOrAlias ( pointer client,
> char **resolvedp, int *resolvedlenp,
> pointer private );
> extern void FontFileRegisterLocalFpeFunctions ( void );
> +extern void CatalogueRegisterLocalFpeFunctions ( void );
>
>
> extern FontEntryPtr FontFileAddEntry ( FontTablePtr table,
> diff --git a/src/fontfile/Makefile.am b/src/fontfile/Makefile.am
> index a80f437..8c361bd 100644
> --- a/src/fontfile/Makefile.am
> +++ b/src/fontfile/Makefile.am
> @@ -26,4 +26,5 @@ libfontfile_la_SOURCES = \
> gunzip.c \
> printerfont.c \
> register.c \
> - renderers.c
> + renderers.c \
> + catalogue.c
> diff --git a/src/fontfile/catalogue.c b/src/fontfile/catalogue.c
> new file mode 100644
> index 0000000..aa88133
> --- /dev/null
> +++ b/src/fontfile/catalogue.c
> @@ -0,0 +1,391 @@
> +/*
> + * Copyright © 2007 Red Hat, Inc
> + *
> + * Permission to use, copy, modify, distribute, and sell this software
> + * and its documentation for any purpose is hereby granted without
> + * fee, provided that the above copyright notice appear in all copies
> + * and that both that copyright notice and this permission notice
> + * appear in supporting documentation, and that the name of Red Hat,
> + * Inc not be used in advertising or publicity pertaining to
> + * distribution of the software without specific, written prior
> + * permission. Red Hat, Inc makes no representations about the
> + * suitability of this software for any purpose. It is provided "as
> + * is" without express or implied warranty.
> + *
> + * RED HAT, INC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
> + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
> + * NO EVENT SHALL RED HAT, INC BE LIABLE FOR ANY SPECIAL, INDIRECT OR
> + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
> + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
> + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
> + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +#include <X11/fonts/fntfilst.h>
> +#include <sys/types.h>
> +#include <dirent.h>
> +#include <unistd.h>
> +
> +static const char CataloguePrefix[] = "catalogue:";
> +
> +static int CatalogueFreeFPE (FontPathElementPtr fpe);
> +
> +static int
> +CatalogueNameCheck (char *name)
> +{
> + return strncmp(name, CataloguePrefix, sizeof(CataloguePrefix) - 1) == 0;
> +}
> +
> +typedef struct _CatalogueRec {
> + int fpeCount, fpeAlloc;
> + FontPathElementPtr *fpeList;
> +} CatalogueRec, *CataloguePtr;
> +
> +static int
> +CatalogueAddFPE (CataloguePtr cat, FontPathElementPtr fpe)
> +{
> + FontPathElementPtr *new;
> +
> + if (cat->fpeCount >= cat->fpeAlloc)
> + {
> + if (cat->fpeAlloc == 0)
> + cat->fpeAlloc = 16;
> + else
> + cat->fpeAlloc *= 2;
> +
> + new = xrealloc(cat->fpeList,
> + cat->fpeAlloc * sizeof(FontPathElementPtr));
> + if (new == NULL)
> + return AllocError;
> +
> + cat->fpeList = new;
> + }
> +
> + cat->fpeList[cat->fpeCount++] = fpe;
> +
> + return Successful;
> +}
> +
> +static const char PriorityAttribute[] = "pri=";
> +
> +static int
> +ComparePriority(const void *p1, const void *p2)
> +{
> + FontDirectoryPtr dir1 = (*(FontPathElementPtr*) p1)->private;
> + FontDirectoryPtr dir2 = (*(FontPathElementPtr*) p2)->private;
> + const char *pri1 = strstr(dir1->attributes, PriorityAttribute);
> + const char *pri2 = strstr(dir2->attributes, PriorityAttribute);
> +
> + if (pri1 == NULL && pri2 == NULL)
> + return 0;
> + else if (pri1 == NULL)
> + return 1;
> + else if (pri2 == NULL)
> + return -1;
> + else
> + return
> + atoi(pri1 + strlen(PriorityAttribute)) -
> + atoi(pri2 + strlen(PriorityAttribute));
> +}
> +
> +static int
> +CatalogueInitFPE (FontPathElementPtr fpe)
> +{
> + int len;
> + CataloguePtr cat;
> + DIR *dir;
> + struct dirent *entry;
> + const char *path;
> + char link[MAXFONTFILENAMELEN];
> + char dest[MAXFONTFILENAMELEN];
> + char *attrib;
> + FontPathElementPtr subfpe;
> +
> + cat = (CataloguePtr) xalloc(sizeof *cat);
> + if (cat == NULL)
> + return AllocError;
> +
> + path = fpe->name + strlen(CataloguePrefix);
> + dir = opendir(path);
> + if (dir == NULL)
> + {
> + xfree(cat);
> + return BadFontPath;
> + }
> +
> + cat->fpeCount = 0;
> + cat->fpeAlloc = 0;
> + cat->fpeList = NULL;
> +
> + while (entry = readdir(dir), entry != NULL)
> + {
> + snprintf(link, sizeof link, "%s/%s", path, entry->d_name);
> + len = readlink(link, dest, sizeof dest);
> + if (len < 0)
> + continue;
> +
> + attrib = strchr(link, ':');
> + if (attrib && len + strlen(attrib) < sizeof dest)
> + {
> + memcpy(dest + len, attrib, strlen(attrib));
> + len += strlen(attrib);
> + }
> +
> + subfpe = xalloc(sizeof *subfpe + len + 1);
> + if (subfpe == NULL)
> + continue;
> +
> + /* The fonts returned by OpenFont will point back to the
> + * subfpe they come from. So set the type of the subfpe to
> + * what the catalogue fpe was assigned, so calls to CloseFont
> + * (which uses font->fpe->type) goes to CatalogueCloseFont. */
> + subfpe->type = fpe->type;
> + subfpe->name_length = len;
> + subfpe->name = (char *) (subfpe + 1);
> + memcpy(subfpe->name, dest, len);
> + subfpe->name[len] = '\0';
> +
> + /* The X server will manipulate the subfpe ref counts
> + * associated with the font in OpenFont and CloseFont, so we
> + * have to make sure it's valid. */
> + subfpe->refcount = 1;
> +
> + if (FontFileInitFPE (subfpe) != Successful)
> + {
> + xfree(subfpe);
> + continue;
> + }
> +
> + if (CatalogueAddFPE(cat, subfpe) != Successful)
> + {
> + FontFileFreeFPE (subfpe);
> + xfree(subfpe);
> + continue;
> + }
> + }
> +
> + qsort(cat->fpeList,
> + cat->fpeCount, sizeof cat->fpeList[0], ComparePriority);
> + fpe->private = (pointer) cat;
> +
> + return Successful;
> +}
> +
> +static int
> +CatalogueResetFPE (FontPathElementPtr fpe)
> +{
> + /* Always just tell the caller to close and re-open */
> + return FPEResetFailed;
> +}
> +
> +static int
> +CatalogueFreeFPE (FontPathElementPtr fpe)
> +{
> + CataloguePtr cat = fpe->private;
> + int i;
> +
> + for (i = 0; i < cat->fpeCount; i++)
> + FontFileFreeFPE (cat->fpeList[i]);
> +
> + xfree(cat->fpeList);
> + xfree(cat);
> +
> + return Successful;
> +}
> +
> +static int
> +CatalogueOpenFont (pointer client, FontPathElementPtr fpe, Mask flags,
> + char *name, int namelen,
> + fsBitmapFormat format, fsBitmapFormatMask fmask,
> + XID id, FontPtr *pFont, char **aliasName,
> + FontPtr non_cachable_font)
> +{
> + CataloguePtr cat = fpe->private;
> + FontPathElementPtr subfpe;
> + FontDirectoryPtr dir;
> + int i, status;
> +
> + for (i = 0; i < cat->fpeCount; i++)
> + {
> + subfpe = cat->fpeList[i];
> + dir = subfpe->private;
> + status = FontFileOpenFont(client, subfpe, flags,
> + name, namelen, format, fmask, id,
> + pFont, aliasName, non_cachable_font);
> + if (status == Successful || status == FontNameAlias)
> + return status;
> + }
> +
> + return BadFontName;
> +}
> +
> +static void
> +CatalogueCloseFont (FontPathElementPtr fpe, FontPtr pFont)
> +{
> + /* Note: this gets called with the actual subfpe where we found
> + * the font, not the catalogue fpe. */
> +
> + FontFileCloseFont(fpe, pFont);
> +}
> +
> +static int
> +CatalogueListFonts (pointer client, FontPathElementPtr fpe, char *pat,
> + int len, int max, FontNamesPtr names)
> +{
> + CataloguePtr cat = fpe->private;
> + FontPathElementPtr subfpe;
> + FontDirectoryPtr dir;
> + int i;
> +
> + for (i = 0; i < cat->fpeCount; i++)
> + {
> + subfpe = cat->fpeList[i];
> + dir = subfpe->private;
> + FontFileListFonts(client, subfpe, pat, len, max, names);
> + }
> +
> + return Successful;
> +}
> +
> +int
> +FontFileStartListFonts(pointer client, FontPathElementPtr fpe,
> + char *pat, int len, int max,
> + pointer *privatep, int mark_aliases);
> +
> +typedef struct _LFWIData {
> + pointer *privates;
> + int current;
> +} LFWIDataRec, *LFWIDataPtr;
> +
> +static int
> +CatalogueStartListFonts(pointer client, FontPathElementPtr fpe,
> + char *pat, int len, int max, pointer *privatep,
> + int mark_aliases)
> +{
> + CataloguePtr cat = fpe->private;
> + LFWIDataPtr data;
> + int ret, i, j;
> +
> + data = (LFWIDataPtr) xalloc (sizeof *data +
> + sizeof data->privates[0] * cat->fpeCount);
> + if (!data)
> + return AllocError;
> + data->privates = (pointer *) (data + 1);
> +
> + for (i = 0; i < cat->fpeCount; i++)
> + {
> + ret = FontFileStartListFonts(client, cat->fpeList[i], pat, len,
> + max, &data->privates[i], mark_aliases);
> + if (ret != Successful)
> + goto bail;
> + }
> +
> + data->current = 0;
> + *privatep = (pointer) data;
> + return Successful;
> +
> + bail:
> + for (j = 0; j < i; j++)
> + /* FIXME: we have no way to free the per-fpe privates. */;
> + xfree (data);
> +
> + return AllocError;
> +}
> +
> +static int
> +CatalogueStartListFontsWithInfo(pointer client, FontPathElementPtr fpe,
> + char *pat, int len, int max,
> + pointer *privatep)
> +{
> + return CatalogueStartListFonts(client, fpe, pat, len, max, privatep, 0);
> +}
> +
> +static int
> +CatalogueListNextFontWithInfo(pointer client, FontPathElementPtr fpe,
> + char **namep, int *namelenp,
> + FontInfoPtr *pFontInfo,
> + int *numFonts, pointer private)
> +{
> + LFWIDataPtr data = private;
> + CataloguePtr cat = fpe->private;
> + int ret;
> +
> + if (data->current == cat->fpeCount)
> + {
> + xfree(data);
> + return BadFontName;
> + }
> +
> + ret = FontFileListNextFontWithInfo(client, cat->fpeList[data->current],
> + namep, namelenp,
> + pFontInfo, numFonts,
> + data->privates[data->current]);
> + if (ret == BadFontName)
> + {
> + data->current++;
> + return CatalogueListNextFontWithInfo(client, fpe, namep, namelenp,
> + pFontInfo, numFonts, private);
> + }
> +
> + return ret;
> +}
> +
> +static int
> +CatalogueStartListFontsAndAliases(pointer client, FontPathElementPtr fpe,
> + char *pat, int len, int max,
> + pointer *privatep)
> +{
> + return CatalogueStartListFonts(client, fpe, pat, len, max, privatep, 1);
> +}
> +
> +static int
> +CatalogueListNextFontOrAlias(pointer client, FontPathElementPtr fpe,
> + char **namep, int *namelenp, char **resolvedp,
> + int *resolvedlenp, pointer private)
> +{
> + LFWIDataPtr data = private;
> + CataloguePtr cat = fpe->private;
> + int ret;
> +
> + if (data->current == cat->fpeCount)
> + {
> + xfree(data);
> + return BadFontName;
> + }
> +
> + ret = FontFileListNextFontOrAlias(client, cat->fpeList[data->current],
> + namep, namelenp,
> + resolvedp, resolvedlenp,
> + data->privates[data->current]);
> + if (ret == BadFontName)
> + {
> + data->current++;
> + return CatalogueListNextFontOrAlias(client, fpe, namep, namelenp,
> + resolvedp, resolvedlenp, private);
> + }
> +
> + return ret;
> +}
> +
> +void
> +CatalogueRegisterLocalFpeFunctions (void)
> +{
> + RegisterFPEFunctions(CatalogueNameCheck,
> + CatalogueInitFPE,
> + CatalogueFreeFPE,
> + CatalogueResetFPE,
> + CatalogueOpenFont,
> + CatalogueCloseFont,
> + CatalogueListFonts,
> + CatalogueStartListFontsWithInfo,
> + CatalogueListNextFontWithInfo,
> + NULL,
> + NULL,
> + NULL,
> + CatalogueStartListFontsAndAliases,
> + CatalogueListNextFontOrAlias,
> + FontFileEmptyBitmapSource);
> +}
> diff --git a/src/fontfile/fontfile.c b/src/fontfile/fontfile.c
> index 914f8cd..f900f75 100644
> --- a/src/fontfile/fontfile.c
> +++ b/src/fontfile/fontfile.c
> @@ -795,9 +795,9 @@ FontFileListFonts (pointer client, FontPathElementPtr fpe, char *pat,
> }
>
> int
> -FontFileStartListFontsWithInfo(pointer client, FontPathElementPtr fpe,
> - char *pat, int len, int max,
> - pointer *privatep)
> +FontFileStartListFonts(pointer client, FontPathElementPtr fpe,
> + char *pat, int len, int max,
> + pointer *privatep, int mark_aliases)
> {
> LFWIDataPtr data;
> int ret;
> @@ -811,7 +811,8 @@ FontFileStartListFontsWithInfo(pointer client, FontPathElementPtr fpe,
> xfree (data);
> return AllocError;
> }
> - ret = FontFileListFonts (client, fpe, pat, len, max, data->names);
> + ret = _FontFileListFonts (client, fpe, pat, len,
> + max, data->names, mark_aliases);
> if (ret != Successful)
> {
> FreeFontNames (data->names);
> @@ -823,6 +824,15 @@ FontFileStartListFontsWithInfo(pointer client, FontPathElementPtr fpe,
> return Successful;
> }
>
> +
> +int
> +FontFileStartListFontsWithInfo(pointer client, FontPathElementPtr fpe,
> + char *pat, int len, int max,
> + pointer *privatep)
> +{
> + return FontFileStartListFonts(client, fpe, pat, len, max, privatep, 0);
> +}
> +
> /* ARGSUSED */
> static int
> FontFileListOneFontWithInfo (pointer client, FontPathElementPtr fpe,
> @@ -1076,28 +1086,7 @@ FontFileStartListFontsAndAliases(pointer client, FontPathElementPtr fpe,
> char *pat, int len, int max,
> pointer *privatep)
> {
> - LFWIDataPtr data;
> - int ret;
> -
> - data = (LFWIDataPtr) xalloc (sizeof *data);
> - if (!data)
> - return AllocError;
> - data->names = MakeFontNamesRecord (0);
> - if (!data->names)
> - {
> - xfree (data);
> - return AllocError;
> - }
> - ret = _FontFileListFonts (client, fpe, pat, len, max, data->names, 1);
> - if (ret != Successful)
> - {
> - FreeFontNames (data->names);
> - xfree (data);
> - return ret;
> - }
> - data->current = 0;
> - *privatep = (pointer) data;
> - return Successful;
> + return FontFileStartListFonts(client, fpe, pat, len, max, privatep, 1);
> }
>
> int
> diff --git a/src/fontfile/register.c b/src/fontfile/register.c
> index 53016b2..7969dde 100644
> --- a/src/fontfile/register.c
> +++ b/src/fontfile/register.c
> @@ -99,5 +99,6 @@ FontFileRegisterFpeFunctions(void)
> #endif
>
> FontFileRegisterLocalFpeFunctions ();
> + CatalogueRegisterLocalFpeFunctions ();
> }
>
> --
> 1.5.2.GIT
>
--
Ademar de Souza Reis Jr.
Mandriva - http://www.mandriva.com.br
^[:wq!
More information about the xorg
mailing list