зеркало из https://github.com/mozilla/pjs.git
Update to the most recent fontconfig and Xft code from the xfree cvs repository. Not part of the default build.
This commit is contained in:
Родитель
bb81f1b8f8
Коммит
a9c75cb2c3
|
@ -1,442 +0,0 @@
|
|||
/*
|
||||
* $XFree86: xc/lib/Xft/xftdpy.c,v 1.9 2002/02/15 07:36:11 keithp Exp $
|
||||
*
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <X11/Xlibint.h>
|
||||
#include "xftint.h"
|
||||
|
||||
XftDisplayInfo *_XftDisplayInfo;
|
||||
|
||||
static int
|
||||
_XftCloseDisplay (Display *dpy, XExtCodes *codes)
|
||||
{
|
||||
XftDisplayInfo *info, **prev;
|
||||
|
||||
for (prev = &_XftDisplayInfo; (info = *prev); prev = &(*prev)->next)
|
||||
if (info->codes == codes)
|
||||
break;
|
||||
if (!info)
|
||||
return 0;
|
||||
*prev = info->next;
|
||||
if (info->defaults)
|
||||
FcPatternDestroy (info->defaults);
|
||||
free (info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
XftDisplayInfo *
|
||||
_XftDisplayInfoGet (Display *dpy)
|
||||
{
|
||||
XftDisplayInfo *info, **prev;
|
||||
XRenderPictFormat pf;
|
||||
int i;
|
||||
|
||||
for (prev = &_XftDisplayInfo; (info = *prev); prev = &(*prev)->next)
|
||||
{
|
||||
if (info->display == dpy)
|
||||
{
|
||||
/*
|
||||
* MRU the list
|
||||
*/
|
||||
if (prev != &_XftDisplayInfo)
|
||||
{
|
||||
*prev = info->next;
|
||||
info->next = _XftDisplayInfo;
|
||||
_XftDisplayInfo = info;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
}
|
||||
info = (XftDisplayInfo *) malloc (sizeof (XftDisplayInfo));
|
||||
if (!info)
|
||||
goto bail0;
|
||||
info->codes = XAddExtension (dpy);
|
||||
if (!info->codes)
|
||||
goto bail1;
|
||||
(void) XESetCloseDisplay (dpy, info->codes->extension, _XftCloseDisplay);
|
||||
|
||||
info->display = dpy;
|
||||
info->defaults = 0;
|
||||
info->hasRender = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != 0;
|
||||
info->use_free_glyphs = FcTrue;
|
||||
if (info->hasRender)
|
||||
{
|
||||
int major, minor;
|
||||
XRenderQueryVersion (dpy, &major, &minor);
|
||||
if (major < 0 || (major == 0 && minor <= 2))
|
||||
info->use_free_glyphs = FcFalse;
|
||||
}
|
||||
pf.type = PictTypeDirect;
|
||||
pf.depth = 32;
|
||||
pf.direct.redMask = 0xff;
|
||||
pf.direct.greenMask = 0xff;
|
||||
pf.direct.blueMask = 0xff;
|
||||
pf.direct.alphaMask = 0xff;
|
||||
info->solidFormat = XRenderFindFormat (dpy,
|
||||
(PictFormatType|
|
||||
PictFormatDepth|
|
||||
PictFormatRedMask|
|
||||
PictFormatGreenMask|
|
||||
PictFormatBlueMask|
|
||||
PictFormatAlphaMask),
|
||||
&pf,
|
||||
0);
|
||||
if (XftDebug () & XFT_DBG_RENDER)
|
||||
{
|
||||
Visual *visual = DefaultVisual (dpy, DefaultScreen (dpy));
|
||||
XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
|
||||
|
||||
printf ("XftDisplayInfoGet Default visual 0x%x ",
|
||||
(int) visual->visualid);
|
||||
if (format)
|
||||
{
|
||||
if (format->type == PictTypeDirect)
|
||||
{
|
||||
printf ("format %d,%d,%d,%d\n",
|
||||
format->direct.alpha,
|
||||
format->direct.red,
|
||||
format->direct.green,
|
||||
format->direct.blue);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("format indexed\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
printf ("No Render format for default visual\n");
|
||||
|
||||
printf ("XftDisplayInfoGet initialized, hasRender set to \"%s\"\n",
|
||||
info->hasRender ? "True" : "False");
|
||||
}
|
||||
for (i = 0; i < XFT_NUM_SOLID_COLOR; i++)
|
||||
{
|
||||
info->colors[i].screen = -1;
|
||||
info->colors[i].pict = 0;
|
||||
}
|
||||
info->fonts = 0;
|
||||
|
||||
info->next = _XftDisplayInfo;
|
||||
_XftDisplayInfo = info;
|
||||
|
||||
info->glyph_memory = 0;
|
||||
info->max_glyph_memory = XftDefaultGetInteger (dpy,
|
||||
XFT_MAX_GLYPH_MEMORY, 0,
|
||||
XFT_DPY_MAX_GLYPH_MEMORY);
|
||||
if (XftDebug () & XFT_DBG_CACHE)
|
||||
printf ("global max cache memory %ld\n", info->max_glyph_memory);
|
||||
return info;
|
||||
|
||||
bail1:
|
||||
free (info);
|
||||
bail0:
|
||||
if (XftDebug () & XFT_DBG_RENDER)
|
||||
{
|
||||
printf ("XftDisplayInfoGet failed to initialize, Xft unhappy\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reduce memory usage in X server
|
||||
*/
|
||||
void
|
||||
_XftDisplayManageMemory (Display *dpy)
|
||||
{
|
||||
XftDisplayInfo *info = _XftDisplayInfoGet (dpy);
|
||||
unsigned long glyph_memory;
|
||||
XftFont *public;
|
||||
XftFontInt *font;
|
||||
|
||||
if (!info || !info->max_glyph_memory)
|
||||
return;
|
||||
if (XftDebug () & XFT_DBG_CACHE)
|
||||
{
|
||||
if (info->glyph_memory > info->max_glyph_memory)
|
||||
printf ("Reduce global memory from %ld to %ld\n",
|
||||
info->glyph_memory, info->max_glyph_memory);
|
||||
}
|
||||
while (info->glyph_memory > info->max_glyph_memory)
|
||||
{
|
||||
glyph_memory = rand () % info->glyph_memory;
|
||||
public = info->fonts;
|
||||
while (public)
|
||||
{
|
||||
font = (XftFontInt *) public;
|
||||
|
||||
if (font->glyph_memory > glyph_memory)
|
||||
{
|
||||
_XftFontUncacheGlyph (dpy, public);
|
||||
break;
|
||||
}
|
||||
public = font->next;
|
||||
glyph_memory -= font->glyph_memory;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Bool
|
||||
XftDefaultHasRender (Display *dpy)
|
||||
{
|
||||
XftDisplayInfo *info = _XftDisplayInfoGet (dpy);
|
||||
|
||||
if (!info)
|
||||
return False;
|
||||
return info->hasRender;
|
||||
}
|
||||
|
||||
Bool
|
||||
XftDefaultSet (Display *dpy, FcPattern *defaults)
|
||||
{
|
||||
XftDisplayInfo *info = _XftDisplayInfoGet (dpy);
|
||||
|
||||
if (!info)
|
||||
return False;
|
||||
if (info->defaults)
|
||||
FcPatternDestroy (info->defaults);
|
||||
info->defaults = defaults;
|
||||
if (!info->max_glyph_memory)
|
||||
info->max_glyph_memory = XFT_DPY_MAX_GLYPH_MEMORY;
|
||||
info->max_glyph_memory = XftDefaultGetInteger (dpy,
|
||||
XFT_MAX_GLYPH_MEMORY, 0,
|
||||
info->max_glyph_memory);
|
||||
return True;
|
||||
}
|
||||
|
||||
int
|
||||
XftDefaultParseBool (char *v)
|
||||
{
|
||||
char c0, c1;
|
||||
|
||||
c0 = *v;
|
||||
if (isupper (c0))
|
||||
c0 = tolower (c0);
|
||||
if (c0 == 't' || c0 == 'y' || c0 == '1')
|
||||
return 1;
|
||||
if (c0 == 'f' || c0 == 'n' || c0 == '0')
|
||||
return 0;
|
||||
if (c0 == 'o')
|
||||
{
|
||||
c1 = v[1];
|
||||
if (isupper (c1))
|
||||
c1 = tolower (c1);
|
||||
if (c1 == 'n')
|
||||
return 1;
|
||||
if (c1 == 'f')
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static Bool
|
||||
_XftDefaultInitBool (Display *dpy, FcPattern *pat, char *option)
|
||||
{
|
||||
char *v;
|
||||
int i;
|
||||
|
||||
v = XGetDefault (dpy, "Xft", option);
|
||||
if (v && (i = XftDefaultParseBool (v)) >= 0)
|
||||
return FcPatternAddBool (pat, option, i != 0);
|
||||
return True;
|
||||
}
|
||||
|
||||
static Bool
|
||||
_XftDefaultInitDouble (Display *dpy, FcPattern *pat, char *option)
|
||||
{
|
||||
char *v, *e;
|
||||
double d;
|
||||
|
||||
v = XGetDefault (dpy, "Xft", option);
|
||||
if (v)
|
||||
{
|
||||
d = strtod (v, &e);
|
||||
if (e != v)
|
||||
return FcPatternAddDouble (pat, option, d);
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
static Bool
|
||||
_XftDefaultInitInteger (Display *dpy, FcPattern *pat, char *option)
|
||||
{
|
||||
char *v, *e;
|
||||
int i;
|
||||
|
||||
v = XGetDefault (dpy, "Xft", option);
|
||||
if (v)
|
||||
{
|
||||
if (FcNameConstant ((FcChar8 *) v, &i))
|
||||
return FcPatternAddInteger (pat, option, i);
|
||||
i = strtol (v, &e, 0);
|
||||
if (e != v)
|
||||
return FcPatternAddInteger (pat, option, i);
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
static FcPattern *
|
||||
_XftDefaultInit (Display *dpy)
|
||||
{
|
||||
FcPattern *pat;
|
||||
|
||||
pat = FcPatternCreate ();
|
||||
if (!pat)
|
||||
goto bail0;
|
||||
|
||||
if (!_XftDefaultInitDouble (dpy, pat, FC_SCALE))
|
||||
goto bail1;
|
||||
if (!_XftDefaultInitDouble (dpy, pat, FC_DPI))
|
||||
goto bail1;
|
||||
if (!_XftDefaultInitBool (dpy, pat, XFT_RENDER))
|
||||
goto bail1;
|
||||
if (!_XftDefaultInitInteger (dpy, pat, FC_RGBA))
|
||||
goto bail1;
|
||||
if (!_XftDefaultInitBool (dpy, pat, FC_ANTIALIAS))
|
||||
goto bail1;
|
||||
if (!_XftDefaultInitBool (dpy, pat, FC_MINSPACE))
|
||||
goto bail1;
|
||||
if (!_XftDefaultInitInteger (dpy, pat, XFT_MAX_GLYPH_MEMORY))
|
||||
goto bail1;
|
||||
|
||||
return pat;
|
||||
|
||||
bail1:
|
||||
FcPatternDestroy (pat);
|
||||
bail0:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FcResult
|
||||
_XftDefaultGet (Display *dpy, const char *object, int screen, FcValue *v)
|
||||
{
|
||||
XftDisplayInfo *info = _XftDisplayInfoGet (dpy);
|
||||
FcResult r;
|
||||
|
||||
if (!info)
|
||||
return FcResultNoMatch;
|
||||
|
||||
if (!info->defaults)
|
||||
{
|
||||
info->defaults = _XftDefaultInit (dpy);
|
||||
if (!info->defaults)
|
||||
return FcResultNoMatch;
|
||||
}
|
||||
r = FcPatternGet (info->defaults, object, screen, v);
|
||||
if (r == FcResultNoId && screen > 0)
|
||||
r = FcPatternGet (info->defaults, object, 0, v);
|
||||
return r;
|
||||
}
|
||||
|
||||
Bool
|
||||
XftDefaultGetBool (Display *dpy, const char *object, int screen, Bool def)
|
||||
{
|
||||
FcResult r;
|
||||
FcValue v;
|
||||
|
||||
r = _XftDefaultGet (dpy, object, screen, &v);
|
||||
if (r != FcResultMatch || v.type != FcTypeBool)
|
||||
return def;
|
||||
return v.u.b;
|
||||
}
|
||||
|
||||
int
|
||||
XftDefaultGetInteger (Display *dpy, const char *object, int screen, int def)
|
||||
{
|
||||
FcResult r;
|
||||
FcValue v;
|
||||
|
||||
r = _XftDefaultGet (dpy, object, screen, &v);
|
||||
if (r != FcResultMatch || v.type != FcTypeInteger)
|
||||
return def;
|
||||
return v.u.i;
|
||||
}
|
||||
|
||||
double
|
||||
XftDefaultGetDouble (Display *dpy, const char *object, int screen, double def)
|
||||
{
|
||||
FcResult r;
|
||||
FcValue v;
|
||||
|
||||
r = _XftDefaultGet (dpy, object, screen, &v);
|
||||
if (r != FcResultMatch || v.type != FcTypeDouble)
|
||||
return def;
|
||||
return v.u.d;
|
||||
}
|
||||
|
||||
void
|
||||
XftDefaultSubstitute (Display *dpy, int screen, FcPattern *pattern)
|
||||
{
|
||||
FcValue v;
|
||||
double dpi;
|
||||
|
||||
if (FcPatternGet (pattern, XFT_RENDER, 0, &v) == FcResultNoMatch)
|
||||
{
|
||||
FcPatternAddBool (pattern, XFT_RENDER,
|
||||
XftDefaultGetBool (dpy, XFT_RENDER, screen,
|
||||
XftDefaultHasRender (dpy)));
|
||||
}
|
||||
if (FcPatternGet (pattern, FC_ANTIALIAS, 0, &v) == FcResultNoMatch)
|
||||
{
|
||||
FcPatternAddBool (pattern, FC_ANTIALIAS,
|
||||
XftDefaultGetBool (dpy, FC_ANTIALIAS, screen,
|
||||
True));
|
||||
}
|
||||
if (FcPatternGet (pattern, FC_RGBA, 0, &v) == FcResultNoMatch)
|
||||
{
|
||||
FcPatternAddInteger (pattern, FC_RGBA,
|
||||
XftDefaultGetInteger (dpy, FC_RGBA, screen,
|
||||
FC_RGBA_NONE));
|
||||
}
|
||||
if (FcPatternGet (pattern, FC_MINSPACE, 0, &v) == FcResultNoMatch)
|
||||
{
|
||||
FcPatternAddBool (pattern, FC_MINSPACE,
|
||||
XftDefaultGetBool (dpy, FC_MINSPACE, screen,
|
||||
False));
|
||||
}
|
||||
if (FcPatternGet (pattern, FC_DPI, 0, &v) == FcResultNoMatch)
|
||||
{
|
||||
dpi = (((double) DisplayHeight (dpy, screen) * 25.4) /
|
||||
(double) DisplayHeightMM (dpy, screen));
|
||||
FcPatternAddDouble (pattern, FC_DPI,
|
||||
XftDefaultGetDouble (dpy, FC_DPI, screen,
|
||||
dpi));
|
||||
}
|
||||
if (FcPatternGet (pattern, FC_SCALE, 0, &v) == FcResultNoMatch)
|
||||
{
|
||||
FcPatternAddDouble (pattern, FC_SCALE,
|
||||
XftDefaultGetDouble (dpy, FC_SCALE, screen, 1.0));
|
||||
}
|
||||
if (FcPatternGet (pattern, XFT_MAX_GLYPH_MEMORY, 0, &v) == FcResultNoMatch)
|
||||
{
|
||||
FcPatternAddInteger (pattern, XFT_MAX_GLYPH_MEMORY,
|
||||
XftDefaultGetInteger (dpy, XFT_MAX_GLYPH_MEMORY,
|
||||
screen,
|
||||
XFT_FONT_MAX_GLYPH_MEMORY));
|
||||
}
|
||||
FcDefaultSubstitute (pattern);
|
||||
}
|
||||
|
|
@ -1,788 +0,0 @@
|
|||
/*
|
||||
* $XFree86: xc/lib/Xft/xftfreetype.c,v 1.18 2002/02/19 07:56:29 keithp Exp $
|
||||
*
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "xftint.h"
|
||||
#include <X11/Xlibint.h>
|
||||
|
||||
FT_Library _XftFTlibrary;
|
||||
|
||||
#define FT_Matrix_Equal(a,b) ((a)->xx == (b)->xx && \
|
||||
(a)->yy == (b)->yy && \
|
||||
(a)->xy == (b)->xy && \
|
||||
(a)->yx == (b)->yx)
|
||||
/*
|
||||
* List of all open files (each face in a file is managed separately)
|
||||
*/
|
||||
|
||||
static XftFtFile *_XftFtFiles;
|
||||
int XftMaxFreeTypeFiles = 5;
|
||||
|
||||
static XftFtFile *
|
||||
_XftGetFile (const FcChar8 *file, int id)
|
||||
{
|
||||
XftFtFile *f;
|
||||
|
||||
if (!XftInitFtLibrary ())
|
||||
return 0;
|
||||
|
||||
for (f = _XftFtFiles; f; f = f->next)
|
||||
{
|
||||
if (!strcmp (f->file, (FcChar8 *) file) && f->id == id)
|
||||
{
|
||||
++f->ref;
|
||||
if (XftDebug () & XFT_DBG_REF)
|
||||
printf ("FontFile %s/%d matches existing (%d)\n",
|
||||
file, id, f->ref);
|
||||
return f;
|
||||
}
|
||||
}
|
||||
f = malloc (sizeof (XftFtFile) + strlen ((char *) file) + 1);
|
||||
if (!f)
|
||||
return 0;
|
||||
|
||||
XftMemAlloc (XFT_MEM_FILE, sizeof (XftFtFile) + strlen ((char *) file) + 1);
|
||||
if (XftDebug () & XFT_DBG_REF)
|
||||
printf ("FontFile %s/%d matches new\n",
|
||||
file, id);
|
||||
f->next = _XftFtFiles;
|
||||
_XftFtFiles = f;
|
||||
|
||||
f->ref = 1;
|
||||
|
||||
f->file = (char *) (f+1);
|
||||
strcpy (f->file, file);
|
||||
f->id = id;
|
||||
|
||||
f->lock = 0;
|
||||
f->face = 0;
|
||||
f->size = 0;
|
||||
return f;
|
||||
}
|
||||
|
||||
static int
|
||||
_XftNumFiles (void)
|
||||
{
|
||||
XftFtFile *f;
|
||||
int count = 0;
|
||||
for (f = _XftFtFiles; f; f = f->next)
|
||||
if (f->face && !f->lock)
|
||||
++count;
|
||||
return count;
|
||||
}
|
||||
|
||||
static XftFtFile *
|
||||
_XftNthFile (int n)
|
||||
{
|
||||
XftFtFile *f;
|
||||
int count = 0;
|
||||
for (f = _XftFtFiles; f; f = f->next)
|
||||
if (f->face && !f->lock)
|
||||
if (count++ == n)
|
||||
break;
|
||||
return f;
|
||||
}
|
||||
|
||||
static void
|
||||
_XftUncacheFiles (void)
|
||||
{
|
||||
int n;
|
||||
XftFtFile *f;
|
||||
while ((n = _XftNumFiles ()) > XftMaxFreeTypeFiles)
|
||||
{
|
||||
f = _XftNthFile (rand () % n);
|
||||
if (f)
|
||||
{
|
||||
if (XftDebug() & XFT_DBG_REF)
|
||||
printf ("Discard file %s/%d from cache\n",
|
||||
f->file, f->id);
|
||||
FT_Done_Face (f->face);
|
||||
f->face = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static FT_Face
|
||||
_XftLockFile (XftFtFile *f)
|
||||
{
|
||||
++f->lock;
|
||||
if (!f->face)
|
||||
{
|
||||
if (XftDebug() & XFT_DBG_REF)
|
||||
printf ("Loading file %s/%d\n", f->file, f->id);
|
||||
if (FT_New_Face (_XftFTlibrary, f->file, f->id, &f->face))
|
||||
--f->lock;
|
||||
|
||||
f->size = 0;
|
||||
f->matrix.xx = f->matrix.xy = f->matrix.yx = f->matrix.yy = 0;
|
||||
_XftUncacheFiles ();
|
||||
}
|
||||
return f->face;
|
||||
}
|
||||
|
||||
static void
|
||||
_XftLockError (char *reason)
|
||||
{
|
||||
fprintf (stderr, "Xft: locking error %s\n", reason);
|
||||
}
|
||||
|
||||
static void
|
||||
_XftUnlockFile (XftFtFile *f)
|
||||
{
|
||||
if (--f->lock < 0)
|
||||
_XftLockError ("too many file unlocks");
|
||||
}
|
||||
|
||||
FcBool
|
||||
_XftSetFace (XftFtFile *f, FT_F26Dot6 size, FT_Matrix *matrix)
|
||||
{
|
||||
FT_Face face = f->face;
|
||||
|
||||
if (f->size != size)
|
||||
{
|
||||
if (XftDebug() & XFT_DBG_GLYPH)
|
||||
printf ("Set face size to %d (%d)\n",
|
||||
(int) (size >> 6), (int) size);
|
||||
if (FT_Set_Char_Size (face, size, size, 0, 0))
|
||||
return False;
|
||||
f->size = size;
|
||||
}
|
||||
if (!FT_Matrix_Equal (&f->matrix, matrix))
|
||||
{
|
||||
if (XftDebug() & XFT_DBG_GLYPH)
|
||||
printf ("Set face matrix to (%g,%g,%g,%g)\n",
|
||||
(double) matrix->xx / 0x10000,
|
||||
(double) matrix->xy / 0x10000,
|
||||
(double) matrix->yx / 0x10000,
|
||||
(double) matrix->yy / 0x10000);
|
||||
FT_Set_Transform (face, matrix, 0);
|
||||
f->matrix = *matrix;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
static void
|
||||
_XftReleaseFile (XftFtFile *f)
|
||||
{
|
||||
XftFtFile **prev;
|
||||
|
||||
if (--f->ref != 0)
|
||||
return;
|
||||
if (f->lock)
|
||||
_XftLockError ("Attempt to close locked file");
|
||||
for (prev = &_XftFtFiles; *prev; prev = &(*prev)->next)
|
||||
{
|
||||
if (*prev == f)
|
||||
{
|
||||
*prev = f->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (f->face)
|
||||
FT_Done_Face (f->face);
|
||||
XftMemFree (XFT_MEM_FILE, sizeof (XftFtFile) + strlen (f->file) + 1);
|
||||
free (f);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find a prime larger than the minimum reasonable hash size
|
||||
*/
|
||||
|
||||
static FcChar32
|
||||
_XftSqrt (FcChar32 a)
|
||||
{
|
||||
FcChar32 l, h, m;
|
||||
|
||||
l = 2;
|
||||
h = a/2;
|
||||
while ((h-l) > 1)
|
||||
{
|
||||
m = (h+l) >> 1;
|
||||
if (m * m < a)
|
||||
l = m;
|
||||
else
|
||||
h = m;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
static FcBool
|
||||
_XftIsPrime (FcChar32 i)
|
||||
{
|
||||
FcChar32 l, t;
|
||||
|
||||
if (i < 2)
|
||||
return FcFalse;
|
||||
if ((i & 1) == 0)
|
||||
{
|
||||
if (i == 2)
|
||||
return FcTrue;
|
||||
return FcFalse;
|
||||
}
|
||||
l = _XftSqrt (i) + 1;
|
||||
for (t = 3; t <= l; t += 2)
|
||||
if (i % t == 0)
|
||||
return FcFalse;
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
static FcChar32
|
||||
_XftHashSize (FcChar32 num_unicode)
|
||||
{
|
||||
/* at least 31.25 % extra space */
|
||||
FcChar32 hash = num_unicode + (num_unicode >> 2) + (num_unicode >> 4);
|
||||
|
||||
if ((hash & 1) == 0)
|
||||
hash++;
|
||||
while (!_XftIsPrime (hash))
|
||||
hash += 2;
|
||||
return hash;
|
||||
}
|
||||
|
||||
FT_Face
|
||||
XftLockFace (XftFont *public)
|
||||
{
|
||||
XftFontInt *font = (XftFontInt *) public;
|
||||
return _XftLockFile (font->file);
|
||||
}
|
||||
|
||||
void
|
||||
XftUnlockFace (XftFont *public)
|
||||
{
|
||||
XftFontInt *font = (XftFontInt *) public;
|
||||
_XftUnlockFile (font->file);
|
||||
}
|
||||
|
||||
XftFont *
|
||||
XftFontOpenPattern (Display *dpy, FcPattern *pattern)
|
||||
{
|
||||
XftDisplayInfo *info = _XftDisplayInfoGet (dpy);
|
||||
XftFtFile *file;
|
||||
FT_Face face;
|
||||
FcChar8 *filename;
|
||||
int id;
|
||||
double dsize;
|
||||
FT_F26Dot6 size;
|
||||
int spacing;
|
||||
int char_width;
|
||||
Bool minspace;
|
||||
XftFont *public;
|
||||
XftFontInt *font;
|
||||
FcBool render;
|
||||
int i;
|
||||
FcCharSet *charset;
|
||||
FcChar32 num_unicode;
|
||||
FcChar32 hash_value;
|
||||
FcChar32 rehash_value;
|
||||
int max_glyph_memory;
|
||||
int alloc_size;
|
||||
|
||||
/*
|
||||
* Font information placed in XftFontInt
|
||||
*/
|
||||
FcBool antialias;
|
||||
int rgba;
|
||||
FcBool transform;
|
||||
FT_Matrix matrix;
|
||||
FT_Int load_flags;
|
||||
FcBool hinting, vertical_layout, autohint, global_advance;
|
||||
|
||||
FcMatrix *font_matrix;
|
||||
|
||||
int height, ascent, descent;
|
||||
XRenderPictFormat pf, *format;
|
||||
|
||||
if (!info)
|
||||
goto bail0;
|
||||
|
||||
/*
|
||||
* Find the associated file
|
||||
*/
|
||||
if (FcPatternGetString (pattern, FC_FILE, 0, &filename) != FcResultMatch)
|
||||
goto bail0;
|
||||
|
||||
if (FcPatternGetInteger (pattern, FC_INDEX, 0, &id) != FcResultMatch)
|
||||
goto bail0;
|
||||
|
||||
file = _XftGetFile (filename, id);
|
||||
if (!file)
|
||||
goto bail0;
|
||||
|
||||
face = _XftLockFile (file);
|
||||
if (!face)
|
||||
goto bail1;
|
||||
|
||||
/*
|
||||
* Extract the glyphset information from the pattern
|
||||
*/
|
||||
if (FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &dsize) != FcResultMatch)
|
||||
goto bail2;
|
||||
|
||||
switch (FcPatternGetBool (pattern, FC_MINSPACE, 0, &minspace)) {
|
||||
case FcResultNoMatch:
|
||||
minspace = False;
|
||||
break;
|
||||
case FcResultMatch:
|
||||
break;
|
||||
default:
|
||||
goto bail2;
|
||||
}
|
||||
|
||||
switch (FcPatternGetInteger (pattern, FC_SPACING, 0, &spacing)) {
|
||||
case FcResultNoMatch:
|
||||
spacing = FC_PROPORTIONAL;
|
||||
break;
|
||||
case FcResultMatch:
|
||||
break;
|
||||
default:
|
||||
goto bail2;
|
||||
}
|
||||
|
||||
if (FcPatternGetInteger (pattern, FC_CHAR_WIDTH,
|
||||
0, &char_width) != FcResultMatch)
|
||||
{
|
||||
char_width = 0;
|
||||
}
|
||||
else if (char_width)
|
||||
spacing = FC_MONO;
|
||||
|
||||
if (face->face_flags & FT_FACE_FLAG_SCALABLE)
|
||||
{
|
||||
switch (FcPatternGetBool (pattern, FC_ANTIALIAS, 0, &antialias)) {
|
||||
case FcResultNoMatch:
|
||||
antialias = True;
|
||||
break;
|
||||
case FcResultMatch:
|
||||
break;
|
||||
default:
|
||||
goto bail2;
|
||||
}
|
||||
}
|
||||
else
|
||||
antialias = False;
|
||||
|
||||
switch (FcPatternGetInteger (pattern, FC_RGBA, 0, &rgba)) {
|
||||
case FcResultNoMatch:
|
||||
rgba = FC_RGBA_NONE;
|
||||
break;
|
||||
case FcResultMatch:
|
||||
break;
|
||||
default:
|
||||
goto bail2;
|
||||
}
|
||||
|
||||
matrix.xx = matrix.yy = 0x10000;
|
||||
matrix.xy = matrix.yx = 0;
|
||||
|
||||
switch (FcPatternGetMatrix (pattern, FC_MATRIX, 0, &font_matrix)) {
|
||||
case FcResultNoMatch:
|
||||
break;
|
||||
case FcResultMatch:
|
||||
matrix.xx = 0x10000L * font_matrix->xx;
|
||||
matrix.yy = 0x10000L * font_matrix->yy;
|
||||
matrix.xy = 0x10000L * font_matrix->xy;
|
||||
matrix.yx = 0x10000L * font_matrix->yx;
|
||||
break;
|
||||
default:
|
||||
goto bail2;
|
||||
}
|
||||
|
||||
transform = (matrix.xx != 0x10000 || matrix.xy != 0 ||
|
||||
matrix.yx != 0 || matrix.yy != 0x10000);
|
||||
|
||||
if (FcPatternGetCharSet (pattern, FC_CHARSET, 0, &charset) != FcResultMatch)
|
||||
{
|
||||
charset = 0;
|
||||
}
|
||||
|
||||
if (FcPatternGetInteger (pattern, FC_CHAR_WIDTH,
|
||||
0, &char_width) != FcResultMatch)
|
||||
{
|
||||
char_width = 0;
|
||||
}
|
||||
else if (char_width)
|
||||
spacing = FC_MONO;
|
||||
|
||||
switch (FcPatternGetBool (pattern, XFT_RENDER, 0, &render)) {
|
||||
case FcResultNoMatch:
|
||||
render = info->hasRender;
|
||||
break;
|
||||
case FcResultMatch:
|
||||
if (render && !info->hasRender)
|
||||
render = FcFalse;
|
||||
break;
|
||||
default:
|
||||
goto bail2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute glyph load flags
|
||||
*/
|
||||
load_flags = FT_LOAD_DEFAULT;
|
||||
|
||||
/* disable bitmaps when anti-aliasing or transforming glyphs */
|
||||
if (antialias || transform)
|
||||
load_flags |= FT_LOAD_NO_BITMAP;
|
||||
|
||||
/* disable hinting if requested */
|
||||
switch (FcPatternGetBool (pattern, FC_HINTING, 0, &hinting)) {
|
||||
case FcResultNoMatch:
|
||||
hinting = FcTrue;
|
||||
break;
|
||||
case FcResultMatch:
|
||||
break;
|
||||
default:
|
||||
goto bail2;
|
||||
}
|
||||
|
||||
if (!hinting)
|
||||
load_flags |= FT_LOAD_NO_HINTING;
|
||||
|
||||
/* set vertical layout if requested */
|
||||
switch (FcPatternGetBool (pattern, FC_VERTICAL_LAYOUT, 0, &vertical_layout)) {
|
||||
case FcResultNoMatch:
|
||||
vertical_layout = FcFalse;
|
||||
break;
|
||||
case FcResultMatch:
|
||||
break;
|
||||
default:
|
||||
goto bail2;
|
||||
}
|
||||
|
||||
if (vertical_layout)
|
||||
load_flags |= FT_LOAD_VERTICAL_LAYOUT;
|
||||
|
||||
/* force autohinting if requested */
|
||||
switch (FcPatternGetBool (pattern, FC_AUTOHINT, 0, &autohint)) {
|
||||
case FcResultNoMatch:
|
||||
autohint = FcFalse;
|
||||
break;
|
||||
case FcResultMatch:
|
||||
break;
|
||||
default:
|
||||
goto bail2;
|
||||
}
|
||||
|
||||
if (autohint)
|
||||
load_flags |= FT_LOAD_FORCE_AUTOHINT;
|
||||
|
||||
/* disable global advance width (for broken DynaLab TT CJK fonts) */
|
||||
switch (FcPatternGetBool (pattern, FC_GLOBAL_ADVANCE, 0, &global_advance)) {
|
||||
case FcResultNoMatch:
|
||||
global_advance = FcTrue;
|
||||
break;
|
||||
case FcResultMatch:
|
||||
break;
|
||||
default:
|
||||
goto bail2;
|
||||
}
|
||||
|
||||
if (!global_advance)
|
||||
load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
|
||||
|
||||
if (FcPatternGetInteger (pattern, XFT_MAX_GLYPH_MEMORY,
|
||||
0, &max_glyph_memory) != FcResultMatch)
|
||||
{
|
||||
max_glyph_memory = XFT_FONT_MAX_GLYPH_MEMORY;
|
||||
}
|
||||
|
||||
size = (FT_F26Dot6) (dsize * 64.0);
|
||||
|
||||
/*
|
||||
* Match an existing font
|
||||
*/
|
||||
for (public = info->fonts; public; public = font->next)
|
||||
{
|
||||
font = (XftFontInt *) public;
|
||||
if (font->file == file &&
|
||||
font->minspace == minspace &&
|
||||
font->char_width == char_width &&
|
||||
font->size == size &&
|
||||
font->spacing == spacing &&
|
||||
font->rgba == rgba &&
|
||||
font->antialias == antialias &&
|
||||
font->load_flags == load_flags &&
|
||||
(font->format != 0) == render &&
|
||||
FT_Matrix_Equal (&font->matrix, &matrix))
|
||||
{
|
||||
++font->ref;
|
||||
if (XftDebug () & XFT_DBG_REF)
|
||||
{
|
||||
printf ("Face size %g matches existing (%d)\n",
|
||||
dsize, font->ref);
|
||||
}
|
||||
_XftUnlockFile (file);
|
||||
_XftReleaseFile (file);
|
||||
FcPatternDestroy (pattern);
|
||||
return &font->public;
|
||||
}
|
||||
}
|
||||
|
||||
if (XftDebug () & XFT_DBG_REF)
|
||||
printf ("Face size %g matches new\n", dsize);
|
||||
|
||||
/*
|
||||
* No existing glyphset, create another.
|
||||
*/
|
||||
if (render)
|
||||
{
|
||||
if (antialias)
|
||||
{
|
||||
if (rgba)
|
||||
{
|
||||
pf.depth = 32;
|
||||
pf.type = PictTypeDirect;
|
||||
pf.direct.alpha = 24;
|
||||
pf.direct.alphaMask = 0xff;
|
||||
pf.direct.red = 16;
|
||||
pf.direct.redMask = 0xff;
|
||||
pf.direct.green = 8;
|
||||
pf.direct.greenMask = 0xff;
|
||||
pf.direct.blue = 0;
|
||||
pf.direct.blueMask = 0xff;
|
||||
format = XRenderFindFormat(dpy,
|
||||
PictFormatType|
|
||||
PictFormatDepth|
|
||||
PictFormatAlpha|
|
||||
PictFormatAlphaMask|
|
||||
PictFormatRed|
|
||||
PictFormatRedMask|
|
||||
PictFormatGreen|
|
||||
PictFormatGreenMask|
|
||||
PictFormatBlue|
|
||||
PictFormatBlueMask,
|
||||
&pf, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
pf.depth = 8;
|
||||
pf.type = PictTypeDirect;
|
||||
pf.direct.alpha = 0;
|
||||
pf.direct.alphaMask = 0xff;
|
||||
format = XRenderFindFormat(dpy,
|
||||
PictFormatType|
|
||||
PictFormatDepth|
|
||||
PictFormatAlpha|
|
||||
PictFormatAlphaMask,
|
||||
&pf, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pf.depth = 1;
|
||||
pf.type = PictTypeDirect;
|
||||
pf.direct.alpha = 0;
|
||||
pf.direct.alphaMask = 0x1;
|
||||
format = XRenderFindFormat(dpy,
|
||||
PictFormatType|
|
||||
PictFormatDepth|
|
||||
PictFormatAlpha|
|
||||
PictFormatAlphaMask,
|
||||
&pf, 0);
|
||||
}
|
||||
|
||||
if (!format)
|
||||
goto bail2;
|
||||
}
|
||||
else
|
||||
format = 0;
|
||||
|
||||
if (!_XftSetFace (file, size, &matrix))
|
||||
goto bail2;
|
||||
|
||||
if (charset)
|
||||
{
|
||||
num_unicode = FcCharSetCount (charset);
|
||||
hash_value = _XftHashSize (num_unicode);
|
||||
rehash_value = hash_value - 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
num_unicode = 0;
|
||||
hash_value = 0;
|
||||
rehash_value = 0;
|
||||
}
|
||||
|
||||
alloc_size = (sizeof (XftFontInt) +
|
||||
face->num_glyphs * sizeof (XftGlyph *) +
|
||||
hash_value * sizeof (XftUcsHash));
|
||||
font = malloc (alloc_size);
|
||||
|
||||
if (!font)
|
||||
goto bail2;
|
||||
|
||||
XftMemAlloc (XFT_MEM_FONT, alloc_size);
|
||||
|
||||
/*
|
||||
* Public fields
|
||||
*/
|
||||
descent = -(face->size->metrics.descender >> 6);
|
||||
ascent = face->size->metrics.ascender >> 6;
|
||||
if (minspace)
|
||||
{
|
||||
height = ascent + descent;
|
||||
}
|
||||
else
|
||||
{
|
||||
height = face->size->metrics.height >> 6;
|
||||
}
|
||||
font->public.ascent = ascent;
|
||||
font->public.descent = descent;
|
||||
font->public.height = height;
|
||||
|
||||
if (char_width)
|
||||
font->public.max_advance_width = char_width;
|
||||
else
|
||||
font->public.max_advance_width = face->size->metrics.max_advance >> 6;
|
||||
font->public.charset = charset;
|
||||
font->public.pattern = pattern;
|
||||
|
||||
/*
|
||||
* Management fields
|
||||
*/
|
||||
font->next = info->fonts;
|
||||
info->fonts = &font->public;
|
||||
font->file = file;
|
||||
font->ref = 1;
|
||||
/*
|
||||
* Per glyph information
|
||||
*/
|
||||
font->glyphs = (XftGlyph **) (font + 1);
|
||||
memset (font->glyphs, '\0', face->num_glyphs * sizeof (XftGlyph *));
|
||||
font->num_glyphs = face->num_glyphs;
|
||||
/*
|
||||
* Unicode hash table information
|
||||
*/
|
||||
font->hash_table = (XftUcsHash *) (font->glyphs + font->num_glyphs);
|
||||
for (i = 0; i < hash_value; i++)
|
||||
{
|
||||
font->hash_table[i].ucs4 = ((FcChar32) ~0);
|
||||
font->hash_table[i].glyph = 0;
|
||||
}
|
||||
font->hash_value = hash_value;
|
||||
font->rehash_value = rehash_value;
|
||||
/*
|
||||
* X specific fields
|
||||
*/
|
||||
font->glyphset = 0;
|
||||
font->format = format;
|
||||
/*
|
||||
* Rendering options
|
||||
*/
|
||||
font->size = size;
|
||||
font->antialias = antialias;
|
||||
font->rgba = rgba;
|
||||
font->transform = transform;
|
||||
font->matrix = matrix;
|
||||
font->load_flags = load_flags;
|
||||
font->minspace = minspace;
|
||||
font->char_width = char_width;
|
||||
font->spacing = spacing;
|
||||
/*
|
||||
* Glyph memory management fields
|
||||
*/
|
||||
font->glyph_memory = 0;
|
||||
font->max_glyph_memory = max_glyph_memory;
|
||||
font->use_free_glyphs = info->use_free_glyphs;
|
||||
|
||||
_XftUnlockFile (file);
|
||||
|
||||
return &font->public;
|
||||
|
||||
bail2:
|
||||
_XftUnlockFile (file);
|
||||
bail1:
|
||||
_XftReleaseFile (file);
|
||||
bail0:
|
||||
return 0;
|
||||
}
|
||||
|
||||
XftFont *
|
||||
XftFontCopy (Display *dpy, XftFont *public)
|
||||
{
|
||||
XftFontInt *font = (XftFontInt *) public;
|
||||
|
||||
font->ref++;
|
||||
return public;
|
||||
}
|
||||
|
||||
void
|
||||
XftFontClose (Display *dpy, XftFont *public)
|
||||
{
|
||||
XftFontInt *font = (XftFontInt *) public;
|
||||
XftDisplayInfo *info = _XftDisplayInfoGet (dpy);
|
||||
XftFont **prev;
|
||||
int i;
|
||||
|
||||
if (--font->ref == 0)
|
||||
{
|
||||
if (info)
|
||||
{
|
||||
/* Unhook from display list */
|
||||
for (prev = &info->fonts; *prev; prev = &(*(XftFontInt **) prev)->next)
|
||||
{
|
||||
if (*prev == public)
|
||||
{
|
||||
*prev = font->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Free resources */
|
||||
/* Dereference the file */
|
||||
_XftReleaseFile (font->file);
|
||||
/* Free the glyphset */
|
||||
if (font->glyphset)
|
||||
XRenderFreeGlyphSet (dpy, font->glyphset);
|
||||
/* Free the glyphs */
|
||||
for (i = 0; i < font->num_glyphs; i++)
|
||||
{
|
||||
XftGlyph *xftg = font->glyphs[i];
|
||||
if (xftg)
|
||||
{
|
||||
if (xftg->bitmap)
|
||||
free (xftg->bitmap);
|
||||
free (xftg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally, free the font structure */
|
||||
XftMemFree (XFT_MEM_FONT, sizeof (XftFontInt) +
|
||||
font->num_glyphs * sizeof (XftGlyph *) +
|
||||
font->hash_value * sizeof (XftUcsHash));
|
||||
free (font);
|
||||
}
|
||||
}
|
||||
|
||||
FcBool
|
||||
XftInitFtLibrary (void)
|
||||
{
|
||||
if (_XftFTlibrary)
|
||||
return FcTrue;
|
||||
if (FT_Init_FreeType (&_XftFTlibrary))
|
||||
return FcFalse;
|
||||
return FcTrue;
|
||||
}
|
|
@ -1,146 +0,0 @@
|
|||
/*
|
||||
* $XFree86: xc/lib/fontconfig/fc-cache/fc-cache.c,v 1.2 2002/02/15 07:36:14 keithp Exp $
|
||||
*
|
||||
* Copyright © 2002 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD 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.
|
||||
*/
|
||||
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#else
|
||||
#define HAVE_GETOPT 1
|
||||
#endif
|
||||
|
||||
#if HAVE_GETOPT_LONG
|
||||
#define _GNU_SOURCE
|
||||
#include <getopt.h>
|
||||
const struct option longopts[] = {
|
||||
{"version", 0, 0, 'V'},
|
||||
{"verbose", 0, 0, 'v'},
|
||||
{"help", 0, 0, '?'},
|
||||
{NULL,0,0,0},
|
||||
};
|
||||
#else
|
||||
#if HAVE_GETOPT
|
||||
extern char *optarg;
|
||||
extern int optind, opterr, optopt;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void
|
||||
usage (char *program)
|
||||
{
|
||||
fprintf (stderr, "usage: %s [-vV?] [--verbose] [--version] [--help] [dirs]\n",
|
||||
program);
|
||||
fprintf (stderr, "Build font information caches in [dirs]\n"
|
||||
"(all directories in font configuration by default).\n");
|
||||
fprintf (stderr, "\n");
|
||||
fprintf (stderr, " -v, --verbose display status information while busy\n");
|
||||
fprintf (stderr, " -V, --version display font config version and exit\n");
|
||||
fprintf (stderr, " -?, --help display this help and exit\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int ret = 0;
|
||||
FcFontSet *set;
|
||||
FcChar8 **dirs;
|
||||
int verbose = 0;
|
||||
int i;
|
||||
#if HAVE_GETOPT_LONG || HAVE_GETOPT
|
||||
int c;
|
||||
|
||||
#if HAVE_GETOPT_LONG
|
||||
while ((c = getopt_long (argc, argv, "Vv?", longopts, NULL)) != -1)
|
||||
#else
|
||||
while ((c = getopt (argc, argv, "Vv?")) != -1)
|
||||
#endif
|
||||
{
|
||||
switch (c) {
|
||||
case 'V':
|
||||
fprintf (stderr, "fontconfig version %d.%d.%d\n",
|
||||
FC_MAJOR, FC_MINOR, FC_REVISION);
|
||||
exit (0);
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
default:
|
||||
usage (argv[0]);
|
||||
}
|
||||
}
|
||||
i = optind;
|
||||
#else
|
||||
i = 1;
|
||||
#endif
|
||||
|
||||
if (!FcInitConfig ())
|
||||
{
|
||||
fprintf (stderr, "Can't init font config library\n");
|
||||
return 1;
|
||||
}
|
||||
if (argv[i])
|
||||
dirs = (FcChar8 **) (argv+i);
|
||||
else
|
||||
dirs = FcConfigGetDirs (0);
|
||||
/*
|
||||
* Now scan all of the directories into separate databases
|
||||
* and write out the results
|
||||
*/
|
||||
while (dirs && *dirs)
|
||||
{
|
||||
if (verbose)
|
||||
printf ("%s: Scanning directory \"%s\"\n", argv[0], *dirs);
|
||||
set = FcFontSetCreate ();
|
||||
if (!set)
|
||||
{
|
||||
fprintf (stderr, "Out of memory in \"%s\"\n", *dirs);
|
||||
ret++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!FcDirScan (set, 0, FcConfigGetBlanks (0), *dirs, FcTrue))
|
||||
{
|
||||
fprintf (stderr, "Can't scan directory \"%s\"\n", *dirs);
|
||||
ret++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (verbose)
|
||||
printf ("%s: Saving %d font names for \"%s\"\n",
|
||||
argv[0], set->nfont, *dirs);
|
||||
if (!FcDirSave (set, *dirs))
|
||||
{
|
||||
fprintf (stderr, "Can't save cache in \"%s\"\n", *dirs);
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
FcFontSetDestroy (set);
|
||||
}
|
||||
++dirs;
|
||||
}
|
||||
if (verbose)
|
||||
printf ("%s: %s\n", argv[0], ret ? "failed" : "succeeded");
|
||||
return ret;
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
/*
|
||||
* $XFree86: xc/lib/fontconfig/fc-list/fc-list.c,v 1.2 2002/02/15 06:01:26 keithp Exp $
|
||||
*
|
||||
* Copyright © 2002 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD 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.
|
||||
*/
|
||||
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#else
|
||||
#define HAVE_GETOPT 1
|
||||
#endif
|
||||
|
||||
#if HAVE_GETOPT_LONG
|
||||
#define _GNU_SOURCE
|
||||
#include <getopt.h>
|
||||
const struct option longopts[] = {
|
||||
{"version", 0, 0, 'V'},
|
||||
{"verbose", 0, 0, 'v'},
|
||||
{"help", 0, 0, '?'},
|
||||
{NULL,0,0,0},
|
||||
};
|
||||
#else
|
||||
#if HAVE_GETOPT
|
||||
extern char *optarg;
|
||||
extern int optind, opterr, optopt;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void usage (char *program)
|
||||
{
|
||||
fprintf (stderr, "usage: %s [-vV?] [--verbose] [--version] [--help] [dirs]\n",
|
||||
program);
|
||||
fprintf (stderr, "Build font information caches in [dirs]\n"
|
||||
"(all directories in font configuration by default).\n");
|
||||
fprintf (stderr, "\n");
|
||||
fprintf (stderr, " -v, --verbose display status information while busy\n");
|
||||
fprintf (stderr, " -V, --version display font config version and exit\n");
|
||||
fprintf (stderr, " -?, --help display this help and exit\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int verbose = 0;
|
||||
int i;
|
||||
FcObjectSet *os = FcObjectSetBuild (FC_FAMILY, FC_LANG, 0);
|
||||
FcFontSet *fs;
|
||||
FcPattern *pat;
|
||||
#if HAVE_GETOPT_LONG || HAVE_GETOPT
|
||||
int c;
|
||||
|
||||
#if HAVE_GETOPT_LONG
|
||||
while ((c = getopt_long (argc, argv, "Vv?", longopts, NULL)) != -1)
|
||||
#else
|
||||
while ((c = getopt (argc, argv, "Vv?")) != -1)
|
||||
#endif
|
||||
{
|
||||
switch (c) {
|
||||
case 'V':
|
||||
fprintf (stderr, "fontconfig version %d.%d.%d\n",
|
||||
FC_MAJOR, FC_MINOR, FC_REVISION);
|
||||
exit (0);
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
default:
|
||||
usage (argv[0]);
|
||||
}
|
||||
}
|
||||
i = optind;
|
||||
#else
|
||||
i = 1;
|
||||
#endif
|
||||
|
||||
if (!FcInit ())
|
||||
{
|
||||
fprintf (stderr, "Can't init font config library\n");
|
||||
return 1;
|
||||
}
|
||||
if (argv[i])
|
||||
pat = FcNameParse (argv[i]);
|
||||
else
|
||||
pat = FcPatternCreate ();
|
||||
|
||||
fs = FcFontList (0, pat, os);
|
||||
if (pat)
|
||||
FcPatternDestroy (pat);
|
||||
|
||||
if (fs)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < fs->nfont; j++)
|
||||
{
|
||||
FcChar8 *font;
|
||||
|
||||
font = FcNameUnparse (fs->fonts[j]);
|
||||
printf ("%s\n", font);
|
||||
free (font);
|
||||
}
|
||||
FcFontSetDestroy (fs);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -1,555 +0,0 @@
|
|||
/*
|
||||
* $XFree86: xc/lib/fontconfig/fontconfig/fontconfig.h,v 1.3 2002/02/19 07:50:43 keithp Exp $
|
||||
*
|
||||
* Copyright © 2001 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD 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.
|
||||
*/
|
||||
|
||||
#ifndef _FONTCONFIG_H_
|
||||
#define _FONTCONFIG_H_
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef unsigned char FcChar8;
|
||||
typedef unsigned short FcChar16;
|
||||
typedef unsigned int FcChar32;
|
||||
typedef int FcBool;
|
||||
|
||||
/*
|
||||
* Current Fontconfig version number
|
||||
*/
|
||||
#define FC_MAJOR 1
|
||||
#define FC_MINOR 0
|
||||
#define FC_REVISION 0
|
||||
|
||||
#define FC_VERSION ((FC_MAJOR * 10000) + (FC_MINOR * 100) + (FC_REVISION))
|
||||
|
||||
#define FcTrue 1
|
||||
#define FcFalse 0
|
||||
|
||||
#define FC_FAMILY "family" /* String */
|
||||
#define FC_STYLE "style" /* String */
|
||||
#define FC_SLANT "slant" /* Int */
|
||||
#define FC_WEIGHT "weight" /* Int */
|
||||
#define FC_SIZE "size" /* Double */
|
||||
#define FC_PIXEL_SIZE "pixelsize" /* Double */
|
||||
#define FC_SPACING "spacing" /* Int */
|
||||
#define FC_FOUNDRY "foundry" /* String */
|
||||
#define FC_ANTIALIAS "antialias" /* Bool (depends) */
|
||||
#define FC_HINTING "hinting" /* Bool (true) */
|
||||
#define FC_VERTICAL_LAYOUT "verticallayout" /* Bool (false) */
|
||||
#define FC_AUTOHINT "autohint" /* Bool (false) */
|
||||
#define FC_GLOBAL_ADVANCE "globaladvance" /* Bool (true) */
|
||||
#define FC_FILE "file" /* String */
|
||||
#define FC_INDEX "index" /* Int */
|
||||
#define FC_RASTERIZER "rasterizer" /* String */
|
||||
#define FC_OUTLINE "outline" /* Bool */
|
||||
#define FC_SCALABLE "scalable" /* Bool */
|
||||
#define FC_SCALE "scale" /* double */
|
||||
#define FC_DPI "dpi" /* double */
|
||||
#define FC_RGBA "rgba" /* Int */
|
||||
#define FC_MINSPACE "minspace" /* Bool use minimum line spacing */
|
||||
#define FC_SOURCE "source" /* String (X11, freetype) */
|
||||
#define FC_CHARSET "charset" /* CharSet */
|
||||
#define FC_LANG "lang" /* String OS/2 CodePageRange */
|
||||
|
||||
#define FC_DIR_CACHE_FILE "fonts.cache"
|
||||
#define FC_USER_CACHE_FILE ".fonts.cache"
|
||||
|
||||
/* Adjust outline rasterizer */
|
||||
#define FC_CHAR_WIDTH "charwidth" /* Int */
|
||||
#define FC_CHAR_HEIGHT "charheight"/* Int */
|
||||
#define FC_MATRIX "matrix" /* FcMatrix */
|
||||
|
||||
#define FC_WEIGHT_LIGHT 0
|
||||
#define FC_WEIGHT_MEDIUM 100
|
||||
#define FC_WEIGHT_DEMIBOLD 180
|
||||
#define FC_WEIGHT_BOLD 200
|
||||
#define FC_WEIGHT_BLACK 210
|
||||
|
||||
#define FC_SLANT_ROMAN 0
|
||||
#define FC_SLANT_ITALIC 100
|
||||
#define FC_SLANT_OBLIQUE 110
|
||||
|
||||
#define FC_PROPORTIONAL 0
|
||||
#define FC_MONO 100
|
||||
#define FC_CHARCELL 110
|
||||
|
||||
/* sub-pixel order */
|
||||
#define FC_RGBA_NONE 0
|
||||
#define FC_RGBA_RGB 1
|
||||
#define FC_RGBA_BGR 2
|
||||
#define FC_RGBA_VRGB 3
|
||||
#define FC_RGBA_VBGR 4
|
||||
|
||||
/* language groups from the OS/2 CodePageRange bits */
|
||||
#define FC_LANG_LATIN_1 "latin1" /* 0 */
|
||||
#define FC_LANG_LATIN_2_EASTERN_EUROPE "latin2easterneurope" /* 1 */
|
||||
#define FC_LANG_CYRILLIC "cyrillic" /* 2 */
|
||||
#define FC_LANG_GREEK "greek" /* 3 */
|
||||
#define FC_LANG_TURKISH "turkish" /* 4 */
|
||||
#define FC_LANG_HEBREW "hebrew" /* 5 */
|
||||
#define FC_LANG_ARABIC "arabic" /* 6 */
|
||||
#define FC_LANG_WINDOWS_BALTIC "windowsbaltic" /* 7 */
|
||||
#define FC_LANG_VIETNAMESE "vietnamese" /* 8 */
|
||||
/* 9-15 reserved for Alternate ANSI */
|
||||
#define FC_LANG_THAI "thai" /* 16 */
|
||||
#define FC_LANG_JAPANESE "japanese" /* 17 */
|
||||
#define FC_LANG_SIMPLIFIED_CHINESE "simplifiedchinese" /* 18 */
|
||||
#define FC_LANG_KOREAN_WANSUNG "koreanwansung" /* 19 */
|
||||
#define FC_LANG_TRADITIONAL_CHINESE "traditionalchinese" /* 20 */
|
||||
#define FC_LANG_KOREAN_JOHAB "koreanjohab" /* 21 */
|
||||
/* 22-28 reserved for Alternate ANSI & OEM */
|
||||
#define FC_LANG_MACINTOSH "macintosh" /* 29 */
|
||||
#define FC_LANG_OEM "oem" /* 30 */
|
||||
#define FC_LANG_SYMBOL "symbol" /* 31 */
|
||||
/* 32-47 reserved for OEM */
|
||||
#define FC_LANG_IBM_GREEK "ibmgreek" /* 48 */
|
||||
#define FC_LANG_MSDOS_RUSSIAN "msdosrussian" /* 49 */
|
||||
#define FC_LANG_MSDOS_NORDIC "msdosnordic" /* 50 */
|
||||
#define FC_LANG_ARABIC_864 "arabic864" /* 51 */
|
||||
#define FC_LANG_MSDOS_CANADIAN_FRENCH "msdoscanadianfrench" /* 52 */
|
||||
#define FC_LANG_HEBREW_862 "hebrew862" /* 53 */
|
||||
#define FC_LANG_MSDOS_ICELANDIC "msdosicelandic" /* 54 */
|
||||
#define FC_LANG_MSDOS_PORTUGUESE "msdosportuguese" /* 55 */
|
||||
#define FC_LANG_IBM_TURKISH "ibmturkish" /* 56 */
|
||||
#define FC_LANG_IBM_CYRILLIC "ibmcyrillic" /* 57 */
|
||||
#define FC_LANG_LATIN_2 "latin2" /* 58 */
|
||||
#define FC_LANG_MSDOS_BALTIC "msdosbaltic" /* 59 */
|
||||
#define FC_LANG_GREEK_437_G "greek437g" /* 60 */
|
||||
#define FC_LANG_ARABIC_ASMO_708 "arabicasmo708" /* 61 */
|
||||
#define FC_LANG_WE_LATIN_1 "welatin1" /* 62 */
|
||||
#define FC_LANG_US "us" /* 63 */
|
||||
|
||||
typedef enum _FcType {
|
||||
FcTypeVoid,
|
||||
FcTypeInteger,
|
||||
FcTypeDouble,
|
||||
FcTypeString,
|
||||
FcTypeBool,
|
||||
FcTypeMatrix,
|
||||
FcTypeCharSet
|
||||
} FcType;
|
||||
|
||||
typedef struct _FcMatrix {
|
||||
double xx, xy, yx, yy;
|
||||
} FcMatrix;
|
||||
|
||||
#define FcMatrixInit(m) ((m)->xx = (m)->yy = 1, \
|
||||
(m)->xy = (m)->yx = 0)
|
||||
|
||||
/*
|
||||
* A data structure to represent the available glyphs in a font.
|
||||
* This is represented as a sparse boolean btree.
|
||||
*/
|
||||
|
||||
typedef struct _FcCharSet FcCharSet;
|
||||
|
||||
typedef struct _FcObjectType {
|
||||
const char *object;
|
||||
FcType type;
|
||||
} FcObjectType;
|
||||
|
||||
typedef struct _FcConstant {
|
||||
const FcChar8 *name;
|
||||
const char *object;
|
||||
int value;
|
||||
} FcConstant;
|
||||
|
||||
typedef enum _FcResult {
|
||||
FcResultMatch, FcResultNoMatch, FcResultTypeMismatch, FcResultNoId
|
||||
} FcResult;
|
||||
|
||||
typedef struct _FcValue {
|
||||
FcType type;
|
||||
union {
|
||||
const FcChar8 *s;
|
||||
int i;
|
||||
FcBool b;
|
||||
double d;
|
||||
const FcMatrix *m;
|
||||
const FcCharSet *c;
|
||||
} u;
|
||||
} FcValue;
|
||||
|
||||
typedef struct _FcPattern FcPattern;
|
||||
|
||||
typedef struct _FcFontSet {
|
||||
int nfont;
|
||||
int sfont;
|
||||
FcPattern **fonts;
|
||||
} FcFontSet;
|
||||
|
||||
typedef struct _FcObjectSet {
|
||||
int nobject;
|
||||
int sobject;
|
||||
const char **objects;
|
||||
} FcObjectSet;
|
||||
|
||||
typedef enum _FcMatchKind {
|
||||
FcMatchPattern, FcMatchFont
|
||||
} FcMatchKind;
|
||||
|
||||
typedef enum _FcSetName {
|
||||
FcSetSystem = 0,
|
||||
FcSetApplication = 1
|
||||
} FcSetName;
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus) /* for C++ V2.0 */
|
||||
#define _FCFUNCPROTOBEGIN extern "C" { /* do not leave open across includes */
|
||||
#define _FCFUNCPROTOEND }
|
||||
#else
|
||||
#define _FCFUNCPROTOBEGIN
|
||||
#define _FCFUNCPROTOEND
|
||||
#endif
|
||||
|
||||
typedef struct _FcConfig FcConfig;
|
||||
|
||||
typedef struct _FcFileCache FcFileCache;
|
||||
|
||||
typedef struct _FcBlanks FcBlanks;
|
||||
|
||||
_FCFUNCPROTOBEGIN
|
||||
|
||||
/* fcblanks.c */
|
||||
FcBlanks *
|
||||
FcBlanksCreate (void);
|
||||
|
||||
void
|
||||
FcBlanksDestroy (FcBlanks *b);
|
||||
|
||||
FcBool
|
||||
FcBlanksAdd (FcBlanks *b, FcChar32 ucs4);
|
||||
|
||||
FcBool
|
||||
FcBlanksIsMember (FcBlanks *b, FcChar32 ucs4);
|
||||
|
||||
/* fccfg.c */
|
||||
FcChar8 *
|
||||
FcConfigFilename (const FcChar8 *url);
|
||||
|
||||
FcConfig *
|
||||
FcConfigCreate (void);
|
||||
|
||||
void
|
||||
FcConfigDestroy (FcConfig *config);
|
||||
|
||||
FcBool
|
||||
FcConfigSetCurrent (FcConfig *config);
|
||||
|
||||
FcConfig *
|
||||
FcConfigGetCurrent (void);
|
||||
|
||||
FcBool
|
||||
FcConfigBuildFonts (FcConfig *config);
|
||||
|
||||
FcChar8 **
|
||||
FcConfigGetDirs (FcConfig *config);
|
||||
|
||||
FcChar8 **
|
||||
FcConfigGetConfigFiles (FcConfig *config);
|
||||
|
||||
FcChar8 *
|
||||
FcConfigGetCache (FcConfig *config);
|
||||
|
||||
FcBlanks *
|
||||
FcConfigGetBlanks (FcConfig *config);
|
||||
|
||||
FcFontSet *
|
||||
FcConfigGetFonts (FcConfig *config,
|
||||
FcSetName set);
|
||||
|
||||
FcBool
|
||||
FcConfigAppFontAddFile (FcConfig *config,
|
||||
const FcChar8 *file);
|
||||
|
||||
FcBool
|
||||
FcConfigAppFontAddDir (FcConfig *config,
|
||||
const FcChar8 *dir);
|
||||
|
||||
void
|
||||
FcConfigAppFontClear (FcConfig *config);
|
||||
|
||||
FcBool
|
||||
FcConfigSubstitute (FcConfig *config,
|
||||
FcPattern *p,
|
||||
FcMatchKind kind);
|
||||
|
||||
/* fccharset.c */
|
||||
FcCharSet *
|
||||
FcCharSetCreate (void);
|
||||
|
||||
void
|
||||
FcCharSetDestroy (FcCharSet *fcs);
|
||||
|
||||
FcBool
|
||||
FcCharSetAddChar (FcCharSet *fcs, FcChar32 ucs4);
|
||||
|
||||
FcCharSet *
|
||||
FcCharSetCopy (FcCharSet *src);
|
||||
|
||||
FcBool
|
||||
FcCharSetEqual (const FcCharSet *a, const FcCharSet *b);
|
||||
|
||||
FcCharSet *
|
||||
FcCharSetIntersect (const FcCharSet *a, const FcCharSet *b);
|
||||
|
||||
FcCharSet *
|
||||
FcCharSetUnion (const FcCharSet *a, const FcCharSet *b);
|
||||
|
||||
FcCharSet *
|
||||
FcCharSetSubtract (const FcCharSet *a, const FcCharSet *b);
|
||||
|
||||
FcBool
|
||||
FcCharSetHasChar (const FcCharSet *fcs, FcChar32 ucs4);
|
||||
|
||||
FcChar32
|
||||
FcCharSetCount (const FcCharSet *a);
|
||||
|
||||
FcChar32
|
||||
FcCharSetIntersectCount (const FcCharSet *a, const FcCharSet *b);
|
||||
|
||||
FcChar32
|
||||
FcCharSetSubtractCount (const FcCharSet *a, const FcCharSet *b);
|
||||
|
||||
FcChar32
|
||||
FcCharSetCoverage (const FcCharSet *a, FcChar32 page, FcChar32 *result);
|
||||
|
||||
/* fcdbg.c */
|
||||
void
|
||||
FcPatternPrint (FcPattern *p);
|
||||
|
||||
/* fcdefault.c */
|
||||
void
|
||||
FcDefaultSubstitute (FcPattern *pattern);
|
||||
|
||||
/* fcdir.c */
|
||||
FcBool
|
||||
FcFileScan (FcFontSet *set,
|
||||
FcFileCache *cache,
|
||||
FcBlanks *blanks,
|
||||
const FcChar8 *file,
|
||||
FcBool force);
|
||||
|
||||
FcBool
|
||||
FcDirScan (FcFontSet *set,
|
||||
FcFileCache *cache,
|
||||
FcBlanks *blanks,
|
||||
const FcChar8 *dir,
|
||||
FcBool force);
|
||||
|
||||
FcBool
|
||||
FcDirSave (FcFontSet *set, const FcChar8 *dir);
|
||||
|
||||
/* fcfreetype.c */
|
||||
FcPattern *
|
||||
FcFreeTypeQuery (const FcChar8 *file, int id, FcBlanks *blanks, int *count);
|
||||
|
||||
/* fcfs.c */
|
||||
|
||||
FcFontSet *
|
||||
FcFontSetCreate (void);
|
||||
|
||||
void
|
||||
FcFontSetDestroy (FcFontSet *s);
|
||||
|
||||
FcBool
|
||||
FcFontSetAdd (FcFontSet *s, FcPattern *font);
|
||||
|
||||
/* fcinit.c */
|
||||
FcBool
|
||||
FcInitFonts (void);
|
||||
|
||||
FcBool
|
||||
FcInitConfig (void);
|
||||
|
||||
FcBool
|
||||
FcInit (void);
|
||||
|
||||
/* fclist.c */
|
||||
FcObjectSet *
|
||||
FcObjectSetCreate (void);
|
||||
|
||||
FcBool
|
||||
FcObjectSetAdd (FcObjectSet *os, const char *object);
|
||||
|
||||
void
|
||||
FcObjectSetDestroy (FcObjectSet *os);
|
||||
|
||||
FcObjectSet *
|
||||
FcObjectSetVaBuild (const char *first, va_list va);
|
||||
|
||||
FcObjectSet *
|
||||
FcObjectSetBuild (const char *first, ...);
|
||||
|
||||
FcFontSet *
|
||||
FcFontList (FcConfig *config,
|
||||
FcPattern *p,
|
||||
FcObjectSet *os);
|
||||
|
||||
/* fcmatch.c */
|
||||
FcPattern *
|
||||
FcFontMatch (FcConfig *config,
|
||||
FcPattern *p,
|
||||
FcResult *result);
|
||||
|
||||
/* fcmatrix.c */
|
||||
FcMatrix *
|
||||
FcMatrixCopy (const FcMatrix *mat);
|
||||
|
||||
FcBool
|
||||
FcMatrixEqual (const FcMatrix *mat1, const FcMatrix *mat2);
|
||||
|
||||
void
|
||||
FcMatrixMultiply (FcMatrix *result, const FcMatrix *a, const FcMatrix *b);
|
||||
|
||||
void
|
||||
FcMatrixRotate (FcMatrix *m, double c, double s);
|
||||
|
||||
void
|
||||
FcMatrixScale (FcMatrix *m, double sx, double sy);
|
||||
|
||||
void
|
||||
FcMatrixShear (FcMatrix *m, double sh, double sv);
|
||||
|
||||
/* fcname.c */
|
||||
|
||||
FcBool
|
||||
FcNameRegisterObjectTypes (const FcObjectType *types, int ntype);
|
||||
|
||||
FcBool
|
||||
FcNameUnregisterObjectTypes (const FcObjectType *types, int ntype);
|
||||
|
||||
const FcObjectType *
|
||||
FcNameGetObjectType (const char *object);
|
||||
|
||||
FcBool
|
||||
FcNameRegisterConstants (const FcConstant *consts, int nconsts);
|
||||
|
||||
FcBool
|
||||
FcNameUnregisterConstants (const FcConstant *consts, int nconsts);
|
||||
|
||||
const FcConstant *
|
||||
FcNameGetConstant (FcChar8 *string);
|
||||
|
||||
FcBool
|
||||
FcNameConstant (FcChar8 *string, int *result);
|
||||
|
||||
FcPattern *
|
||||
FcNameParse (const FcChar8 *name);
|
||||
|
||||
FcChar8 *
|
||||
FcNameUnparse (FcPattern *pat);
|
||||
|
||||
/* fcpat.c */
|
||||
FcPattern *
|
||||
FcPatternCreate (void);
|
||||
|
||||
FcPattern *
|
||||
FcPatternDuplicate (FcPattern *p);
|
||||
|
||||
void
|
||||
FcValueDestroy (FcValue v);
|
||||
|
||||
FcValue
|
||||
FcValueSave (FcValue v);
|
||||
|
||||
void
|
||||
FcPatternDestroy (FcPattern *p);
|
||||
|
||||
FcBool
|
||||
FcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append);
|
||||
|
||||
FcResult
|
||||
FcPatternGet (FcPattern *p, const char *object, int id, FcValue *v);
|
||||
|
||||
FcBool
|
||||
FcPatternDel (FcPattern *p, const char *object);
|
||||
|
||||
FcBool
|
||||
FcPatternAddInteger (FcPattern *p, const char *object, int i);
|
||||
|
||||
FcBool
|
||||
FcPatternAddDouble (FcPattern *p, const char *object, double d);
|
||||
|
||||
FcBool
|
||||
FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s);
|
||||
|
||||
FcBool
|
||||
FcPatternAddMatrix (FcPattern *p, const char *object, const FcMatrix *s);
|
||||
|
||||
FcBool
|
||||
FcPatternAddCharSet (FcPattern *p, const char *object, const FcCharSet *c);
|
||||
|
||||
FcBool
|
||||
FcPatternAddBool (FcPattern *p, const char *object, FcBool b);
|
||||
|
||||
FcResult
|
||||
FcPatternGetInteger (FcPattern *p, const char *object, int n, int *i);
|
||||
|
||||
FcResult
|
||||
FcPatternGetDouble (FcPattern *p, const char *object, int n, double *d);
|
||||
|
||||
FcResult
|
||||
FcPatternGetString (FcPattern *p, const char *object, int n, FcChar8 ** s);
|
||||
|
||||
FcResult
|
||||
FcPatternGetMatrix (FcPattern *p, const char *object, int n, FcMatrix **s);
|
||||
|
||||
FcResult
|
||||
FcPatternGetCharSet (FcPattern *p, const char *object, int n, FcCharSet **c);
|
||||
|
||||
FcResult
|
||||
FcPatternGetBool (FcPattern *p, const char *object, int n, FcBool *b);
|
||||
|
||||
FcPattern *
|
||||
FcPatternVaBuild (FcPattern *orig, va_list va);
|
||||
|
||||
FcPattern *
|
||||
FcPatternBuild (FcPattern *orig, ...);
|
||||
|
||||
/* fcstr.c */
|
||||
|
||||
FcChar8 *
|
||||
FcStrCopy (const FcChar8 *s);
|
||||
|
||||
#define FcToLower(c) (('A' <= (c) && (c) <= 'Z') ? (c) - 'A' + 'a' : (c))
|
||||
|
||||
int
|
||||
FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2);
|
||||
|
||||
int
|
||||
FcUtf8ToUcs4 (FcChar8 *src_orig,
|
||||
FcChar32 *dst,
|
||||
int len);
|
||||
|
||||
FcBool
|
||||
FcUtf8Len (FcChar8 *string,
|
||||
int len,
|
||||
int *nchar,
|
||||
int *wchar);
|
||||
|
||||
/* fcxml.c */
|
||||
FcBool
|
||||
FcConfigParseAndLoad (FcConfig *config, const FcChar8 *file, FcBool complain);
|
||||
|
||||
_FCFUNCPROTOEND
|
||||
|
||||
#endif /* _FONTCONFIG_H_ */
|
|
@ -1,46 +0,0 @@
|
|||
DEPTH = ../../../..
|
||||
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = fontconfig
|
||||
LIBRARY_NAME = fontconfig
|
||||
EXPORT_LIBRARY = 1
|
||||
|
||||
REQUIRES = \
|
||||
freetype2 \
|
||||
fontconfig \
|
||||
expat
|
||||
|
||||
CSRCS = \
|
||||
fcblanks.c \
|
||||
fccache.c \
|
||||
fccfg.c \
|
||||
fccharset.c \
|
||||
fcdbg.c \
|
||||
fcdefault.c \
|
||||
fcdir.c \
|
||||
fcfreetype.c \
|
||||
fcfs.c \
|
||||
fcinit.c \
|
||||
fclist.c \
|
||||
fcmatch.c \
|
||||
fcmatrix.c \
|
||||
fcname.c \
|
||||
fcpat.c \
|
||||
fcstr.c \
|
||||
fcxml.c
|
||||
|
||||
# make it a static lib only
|
||||
FORCE_STATIC_LIB=1
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
DEFINES +=-DFC_FALLBACK_FONTS=\"/usr/X11R6/lib/X11/fonts/Type1\"
|
||||
|
||||
ifdef MOZ_XFT_SYSTEM_FREETYPE2
|
||||
CFLAGS += $(FT2_CFLAGS)
|
||||
endif
|
|
@ -1,634 +0,0 @@
|
|||
/*
|
||||
* $XFree86: xc/lib/fontconfig/src/fccache.c,v 1.3 2002/02/19 07:50:43 keithp Exp $
|
||||
*
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD 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.
|
||||
*/
|
||||
|
||||
#include "fcint.h"
|
||||
|
||||
static unsigned int
|
||||
FcFileCacheHash (const FcChar8 *string)
|
||||
{
|
||||
unsigned int h = 0;
|
||||
FcChar8 c;
|
||||
|
||||
while ((c = *string++))
|
||||
h = (h << 1) ^ c;
|
||||
return h;
|
||||
}
|
||||
|
||||
FcChar8 *
|
||||
FcFileCacheFind (FcFileCache *cache,
|
||||
const FcChar8 *file,
|
||||
int id,
|
||||
int *count)
|
||||
{
|
||||
unsigned int hash;
|
||||
const FcChar8 *match;
|
||||
FcFileCacheEnt *c, *name;
|
||||
int maxid;
|
||||
struct stat statb;
|
||||
|
||||
match = file;
|
||||
|
||||
hash = FcFileCacheHash (match);
|
||||
name = 0;
|
||||
maxid = -1;
|
||||
for (c = cache->ents[hash % FC_FILE_CACHE_HASH_SIZE]; c; c = c->next)
|
||||
{
|
||||
if (c->hash == hash && !strcmp (match, c->file))
|
||||
{
|
||||
if (c->id > maxid)
|
||||
maxid = c->id;
|
||||
if (c->id == id)
|
||||
{
|
||||
if (stat ((char *) file, &statb) < 0)
|
||||
{
|
||||
if (FcDebug () & FC_DBG_CACHE)
|
||||
printf (" file missing\n");
|
||||
return 0;
|
||||
}
|
||||
if (statb.st_mtime != c->time)
|
||||
{
|
||||
if (FcDebug () & FC_DBG_CACHE)
|
||||
printf (" timestamp mismatch (was %d is %d)\n",
|
||||
(int) c->time, (int) statb.st_mtime);
|
||||
return 0;
|
||||
}
|
||||
if (!c->referenced)
|
||||
{
|
||||
cache->referenced++;
|
||||
c->referenced = FcTrue;
|
||||
}
|
||||
name = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!name)
|
||||
return 0;
|
||||
*count = maxid + 1;
|
||||
return name->name;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cache file syntax is quite simple:
|
||||
*
|
||||
* "file_name" id time "font_name" \n
|
||||
*/
|
||||
|
||||
static FcChar8 *
|
||||
FcFileCacheReadString (FILE *f, FcChar8 *dest, int len)
|
||||
{
|
||||
int c;
|
||||
FcBool escape;
|
||||
FcChar8 *d;
|
||||
int size;
|
||||
int i;
|
||||
|
||||
while ((c = getc (f)) != EOF)
|
||||
if (c == '"')
|
||||
break;
|
||||
if (c == EOF)
|
||||
return FcFalse;
|
||||
if (len == 0)
|
||||
return FcFalse;
|
||||
|
||||
size = len;
|
||||
i = 0;
|
||||
d = dest;
|
||||
escape = FcFalse;
|
||||
while ((c = getc (f)) != EOF)
|
||||
{
|
||||
if (!escape)
|
||||
{
|
||||
switch (c) {
|
||||
case '"':
|
||||
c = '\0';
|
||||
break;
|
||||
case '\\':
|
||||
escape = FcTrue;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (i == size)
|
||||
{
|
||||
FcChar8 *new = malloc (size * 2);
|
||||
if (!new)
|
||||
break;
|
||||
memcpy (new, d, size);
|
||||
size *= 2;
|
||||
if (d != dest)
|
||||
free (d);
|
||||
d = new;
|
||||
}
|
||||
d[i++] = c;
|
||||
if (c == '\0')
|
||||
return d;
|
||||
escape = FcFalse;
|
||||
}
|
||||
if (d != dest)
|
||||
free (d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FcBool
|
||||
FcFileCacheReadUlong (FILE *f, unsigned long *dest)
|
||||
{
|
||||
unsigned long t;
|
||||
int c;
|
||||
|
||||
while ((c = getc (f)) != EOF)
|
||||
{
|
||||
if (!isspace (c))
|
||||
break;
|
||||
}
|
||||
if (c == EOF)
|
||||
return FcFalse;
|
||||
t = 0;
|
||||
for (;;)
|
||||
{
|
||||
if (c == EOF || isspace (c))
|
||||
break;
|
||||
if (!isdigit (c))
|
||||
return FcFalse;
|
||||
t = t * 10 + (c - '0');
|
||||
c = getc (f);
|
||||
}
|
||||
*dest = t;
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
static FcBool
|
||||
FcFileCacheReadInt (FILE *f, int *dest)
|
||||
{
|
||||
unsigned long t;
|
||||
FcBool ret;
|
||||
|
||||
ret = FcFileCacheReadUlong (f, &t);
|
||||
if (ret)
|
||||
*dest = (int) t;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static FcBool
|
||||
FcFileCacheReadTime (FILE *f, time_t *dest)
|
||||
{
|
||||
unsigned long t;
|
||||
FcBool ret;
|
||||
|
||||
ret = FcFileCacheReadUlong (f, &t);
|
||||
if (ret)
|
||||
*dest = (time_t) t;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static FcBool
|
||||
FcFileCacheAdd (FcFileCache *cache,
|
||||
const FcChar8 *file,
|
||||
int id,
|
||||
time_t time,
|
||||
const FcChar8 *name,
|
||||
FcBool replace)
|
||||
{
|
||||
FcFileCacheEnt *c;
|
||||
FcFileCacheEnt **prev, *old;
|
||||
unsigned int hash;
|
||||
|
||||
if (FcDebug () & FC_DBG_CACHE)
|
||||
{
|
||||
printf ("%s face %s/%d as %s\n", replace ? "Replace" : "Add",
|
||||
file, id, name);
|
||||
}
|
||||
hash = FcFileCacheHash (file);
|
||||
for (prev = &cache->ents[hash % FC_FILE_CACHE_HASH_SIZE];
|
||||
(old = *prev);
|
||||
prev = &(*prev)->next)
|
||||
{
|
||||
if (old->hash == hash && old->id == id && !strcmp (old->file, file))
|
||||
break;
|
||||
}
|
||||
if (*prev)
|
||||
{
|
||||
if (!replace)
|
||||
return FcFalse;
|
||||
|
||||
old = *prev;
|
||||
if (old->referenced)
|
||||
cache->referenced--;
|
||||
*prev = old->next;
|
||||
free (old);
|
||||
cache->entries--;
|
||||
}
|
||||
|
||||
c = malloc (sizeof (FcFileCacheEnt) +
|
||||
strlen ((char *) file) + 1 +
|
||||
strlen ((char *) name) + 1);
|
||||
if (!c)
|
||||
return FcFalse;
|
||||
c->next = *prev;
|
||||
*prev = c;
|
||||
c->hash = hash;
|
||||
c->file = (FcChar8 *) (c + 1);
|
||||
c->id = id;
|
||||
c->name = c->file + strlen ((char *) file) + 1;
|
||||
strcpy (c->file, file);
|
||||
c->time = time;
|
||||
c->referenced = replace;
|
||||
strcpy (c->name, name);
|
||||
cache->entries++;
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
FcFileCache *
|
||||
FcFileCacheCreate (void)
|
||||
{
|
||||
FcFileCache *cache;
|
||||
int h;
|
||||
|
||||
cache = malloc (sizeof (FcFileCache));
|
||||
if (!cache)
|
||||
return 0;
|
||||
for (h = 0; h < FC_FILE_CACHE_HASH_SIZE; h++)
|
||||
cache->ents[h] = 0;
|
||||
cache->entries = 0;
|
||||
cache->referenced = 0;
|
||||
cache->updated = FcFalse;
|
||||
return cache;
|
||||
}
|
||||
|
||||
void
|
||||
FcFileCacheDestroy (FcFileCache *cache)
|
||||
{
|
||||
FcFileCacheEnt *c, *next;
|
||||
int h;
|
||||
|
||||
for (h = 0; h < FC_FILE_CACHE_HASH_SIZE; h++)
|
||||
{
|
||||
for (c = cache->ents[h]; c; c = next)
|
||||
{
|
||||
next = c->next;
|
||||
free (c);
|
||||
}
|
||||
}
|
||||
free (cache);
|
||||
}
|
||||
|
||||
void
|
||||
FcFileCacheLoad (FcFileCache *cache,
|
||||
const FcChar8 *cache_file)
|
||||
{
|
||||
FILE *f;
|
||||
FcChar8 file_buf[8192], *file;
|
||||
int id;
|
||||
time_t time;
|
||||
FcChar8 name_buf[8192], *name;
|
||||
|
||||
f = fopen ((char *) cache_file, "r");
|
||||
if (!f)
|
||||
return;
|
||||
|
||||
cache->updated = FcFalse;
|
||||
file = 0;
|
||||
name = 0;
|
||||
while ((file = FcFileCacheReadString (f, file_buf, sizeof (file_buf))) &&
|
||||
FcFileCacheReadInt (f, &id) &&
|
||||
FcFileCacheReadTime (f, &time) &&
|
||||
(name = FcFileCacheReadString (f, name_buf, sizeof (name_buf))))
|
||||
{
|
||||
(void) FcFileCacheAdd (cache, file, id, time, name, FcFalse);
|
||||
if (file != file_buf)
|
||||
free (file);
|
||||
if (name != name_buf)
|
||||
free (name);
|
||||
file = 0;
|
||||
name = 0;
|
||||
}
|
||||
if (file && file != file_buf)
|
||||
free (file);
|
||||
if (name && name != name_buf)
|
||||
free (name);
|
||||
fclose (f);
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcFileCacheUpdate (FcFileCache *cache,
|
||||
const FcChar8 *file,
|
||||
int id,
|
||||
const FcChar8 *name)
|
||||
{
|
||||
const FcChar8 *match;
|
||||
struct stat statb;
|
||||
FcBool ret;
|
||||
|
||||
match = file;
|
||||
|
||||
if (stat ((char *) file, &statb) < 0)
|
||||
return FcFalse;
|
||||
ret = FcFileCacheAdd (cache, match, id,
|
||||
statb.st_mtime, name, FcTrue);
|
||||
if (ret)
|
||||
cache->updated = FcTrue;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static FcBool
|
||||
FcFileCacheWriteString (FILE *f, const FcChar8 *string)
|
||||
{
|
||||
char c;
|
||||
|
||||
if (putc ('"', f) == EOF)
|
||||
return FcFalse;
|
||||
while ((c = *string++))
|
||||
{
|
||||
switch (c) {
|
||||
case '"':
|
||||
case '\\':
|
||||
if (putc ('\\', f) == EOF)
|
||||
return FcFalse;
|
||||
/* fall through */
|
||||
default:
|
||||
if (putc (c, f) == EOF)
|
||||
return FcFalse;
|
||||
}
|
||||
}
|
||||
if (putc ('"', f) == EOF)
|
||||
return FcFalse;
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
static FcBool
|
||||
FcFileCacheWriteUlong (FILE *f, unsigned long t)
|
||||
{
|
||||
int pow;
|
||||
unsigned long temp, digit;
|
||||
|
||||
temp = t;
|
||||
pow = 1;
|
||||
while (temp >= 10)
|
||||
{
|
||||
temp /= 10;
|
||||
pow *= 10;
|
||||
}
|
||||
temp = t;
|
||||
while (pow)
|
||||
{
|
||||
digit = temp / pow;
|
||||
if (putc ((char) digit + '0', f) == EOF)
|
||||
return FcFalse;
|
||||
temp = temp - pow * digit;
|
||||
pow = pow / 10;
|
||||
}
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
static FcBool
|
||||
FcFileCacheWriteInt (FILE *f, int i)
|
||||
{
|
||||
return FcFileCacheWriteUlong (f, (unsigned long) i);
|
||||
}
|
||||
|
||||
static FcBool
|
||||
FcFileCacheWriteTime (FILE *f, time_t t)
|
||||
{
|
||||
return FcFileCacheWriteUlong (f, (unsigned long) t);
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcFileCacheSave (FcFileCache *cache,
|
||||
const FcChar8 *cache_file)
|
||||
{
|
||||
FcChar8 *lck;
|
||||
FcChar8 *tmp;
|
||||
FILE *f;
|
||||
int h;
|
||||
FcFileCacheEnt *c;
|
||||
|
||||
if (!cache->updated && cache->referenced == cache->entries)
|
||||
return FcTrue;
|
||||
|
||||
lck = malloc (strlen ((char *) cache_file)*2 + 4);
|
||||
if (!lck)
|
||||
goto bail0;
|
||||
tmp = lck + strlen ((char *) cache_file) + 2;
|
||||
strcpy ((char *) lck, (char *) cache_file);
|
||||
strcat ((char *) lck, "L");
|
||||
strcpy ((char *) tmp, (char *) cache_file);
|
||||
strcat ((char *) tmp, "T");
|
||||
if (link ((char *) lck, (char *) cache_file) < 0 && errno != ENOENT)
|
||||
goto bail1;
|
||||
if (access ((char *) tmp, F_OK) == 0)
|
||||
goto bail2;
|
||||
f = fopen ((char *) tmp, "w");
|
||||
if (!f)
|
||||
goto bail2;
|
||||
|
||||
for (h = 0; h < FC_FILE_CACHE_HASH_SIZE; h++)
|
||||
{
|
||||
for (c = cache->ents[h]; c; c = c->next)
|
||||
{
|
||||
if (!c->referenced)
|
||||
continue;
|
||||
if (!FcFileCacheWriteString (f, c->file))
|
||||
goto bail4;
|
||||
if (putc (' ', f) == EOF)
|
||||
goto bail4;
|
||||
if (!FcFileCacheWriteInt (f, c->id))
|
||||
goto bail4;
|
||||
if (putc (' ', f) == EOF)
|
||||
goto bail4;
|
||||
if (!FcFileCacheWriteTime (f, c->time))
|
||||
goto bail4;
|
||||
if (putc (' ', f) == EOF)
|
||||
goto bail4;
|
||||
if (!FcFileCacheWriteString (f, c->name))
|
||||
goto bail4;
|
||||
if (putc ('\n', f) == EOF)
|
||||
goto bail4;
|
||||
}
|
||||
}
|
||||
|
||||
if (fclose (f) == EOF)
|
||||
goto bail3;
|
||||
|
||||
if (rename ((char *) tmp, (char *) cache_file) < 0)
|
||||
goto bail3;
|
||||
|
||||
unlink ((char *) lck);
|
||||
cache->updated = FcFalse;
|
||||
return FcTrue;
|
||||
|
||||
bail4:
|
||||
fclose (f);
|
||||
bail3:
|
||||
unlink ((char *) tmp);
|
||||
bail2:
|
||||
unlink ((char *) lck);
|
||||
bail1:
|
||||
free (lck);
|
||||
bail0:
|
||||
return FcFalse;
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcFileCacheReadDir (FcFontSet *set, const FcChar8 *cache_file)
|
||||
{
|
||||
FcPattern *font;
|
||||
FILE *f;
|
||||
FcChar8 *path;
|
||||
FcChar8 *base;
|
||||
FcChar8 file_buf[8192], *file;
|
||||
int id;
|
||||
FcChar8 name_buf[8192], *name;
|
||||
FcBool ret = FcFalse;
|
||||
|
||||
if (FcDebug () & FC_DBG_CACHE)
|
||||
{
|
||||
printf ("FcFileCacheReadDir cache_file \"%s\"\n", cache_file);
|
||||
}
|
||||
|
||||
f = fopen ((char *) cache_file, "r");
|
||||
if (!f)
|
||||
{
|
||||
if (FcDebug () & FC_DBG_CACHE)
|
||||
{
|
||||
printf (" no cache file\n");
|
||||
}
|
||||
goto bail0;
|
||||
}
|
||||
|
||||
base = (FcChar8 *) strrchr ((char *) cache_file, '/');
|
||||
if (!base)
|
||||
goto bail1;
|
||||
base++;
|
||||
path = malloc (base - cache_file + 8192 + 1);
|
||||
if (!path)
|
||||
goto bail1;
|
||||
memcpy (path, cache_file, base - cache_file);
|
||||
base = path + (base - cache_file);
|
||||
|
||||
file = 0;
|
||||
name = 0;
|
||||
while ((file = FcFileCacheReadString (f, file_buf, sizeof (file_buf))) &&
|
||||
FcFileCacheReadInt (f, &id) &&
|
||||
(name = FcFileCacheReadString (f, name_buf, sizeof (name_buf))))
|
||||
{
|
||||
font = FcNameParse (name);
|
||||
if (font)
|
||||
{
|
||||
strcpy (base, file);
|
||||
if (FcDebug () & FC_DBG_CACHEV)
|
||||
{
|
||||
printf (" dir cache file \"%s\"\n", file);
|
||||
}
|
||||
FcPatternAddString (font, FC_FILE, path);
|
||||
if (!FcFontSetAdd (set, font))
|
||||
goto bail2;
|
||||
}
|
||||
if (file != file_buf)
|
||||
free (file);
|
||||
if (name != name_buf)
|
||||
free (name);
|
||||
file = name = 0;
|
||||
}
|
||||
if (FcDebug () & FC_DBG_CACHE)
|
||||
{
|
||||
printf (" cache loaded\n");
|
||||
}
|
||||
|
||||
ret = FcTrue;
|
||||
bail2:
|
||||
free (path);
|
||||
if (file && file != file_buf)
|
||||
free (file);
|
||||
if (name && name != name_buf)
|
||||
free (name);
|
||||
bail1:
|
||||
fclose (f);
|
||||
bail0:
|
||||
return ret;
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcFileCacheWriteDir (FcFontSet *set, const FcChar8 *cache_file)
|
||||
{
|
||||
FcPattern *font;
|
||||
FILE *f;
|
||||
FcChar8 *name;
|
||||
const FcChar8 *file, *base;
|
||||
int n;
|
||||
int id;
|
||||
FcBool ret;
|
||||
|
||||
if (FcDebug () & FC_DBG_CACHE)
|
||||
printf ("FcFileCacheWriteDir cache_file \"%s\"\n", cache_file);
|
||||
|
||||
f = fopen ((char *) cache_file, "w");
|
||||
if (!f)
|
||||
{
|
||||
if (FcDebug () & FC_DBG_CACHE)
|
||||
printf (" can't create \"%s\"\n", cache_file);
|
||||
goto bail0;
|
||||
}
|
||||
for (n = 0; n < set->nfont; n++)
|
||||
{
|
||||
font = set->fonts[n];
|
||||
if (FcPatternGetString (font, FC_FILE, 0, (FcChar8 **) &file) != FcResultMatch)
|
||||
goto bail1;
|
||||
base = (FcChar8 *) strrchr ((char *) file, '/');
|
||||
if (base)
|
||||
base = base + 1;
|
||||
else
|
||||
base = file;
|
||||
if (FcPatternGetInteger (font, FC_INDEX, 0, &id) != FcResultMatch)
|
||||
goto bail1;
|
||||
if (FcDebug () & FC_DBG_CACHEV)
|
||||
printf (" write file \"%s\"\n", base);
|
||||
if (!FcFileCacheWriteString (f, base))
|
||||
goto bail1;
|
||||
if (putc (' ', f) == EOF)
|
||||
goto bail1;
|
||||
if (!FcFileCacheWriteInt (f, id))
|
||||
goto bail1;
|
||||
if (putc (' ', f) == EOF)
|
||||
goto bail1;
|
||||
name = FcNameUnparse (font);
|
||||
if (!name)
|
||||
goto bail1;
|
||||
ret = FcFileCacheWriteString (f, name);
|
||||
free (name);
|
||||
if (!ret)
|
||||
goto bail1;
|
||||
if (putc ('\n', f) == EOF)
|
||||
goto bail1;
|
||||
}
|
||||
if (fclose (f) == EOF)
|
||||
goto bail0;
|
||||
|
||||
if (FcDebug () & FC_DBG_CACHE)
|
||||
printf (" cache written\n");
|
||||
return FcTrue;
|
||||
|
||||
bail1:
|
||||
fclose (f);
|
||||
bail0:
|
||||
unlink ((char *) cache_file);
|
||||
return FcFalse;
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,178 +0,0 @@
|
|||
/*
|
||||
* $XFree86: xc/lib/fontconfig/src/fcdir.c,v 1.2 2002/02/15 06:01:28 keithp Exp $
|
||||
*
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD 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.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "fcint.h"
|
||||
|
||||
#define FC_INVALID_FONT_FILE "."
|
||||
|
||||
FcBool
|
||||
FcFileScan (FcFontSet *set,
|
||||
FcFileCache *cache,
|
||||
FcBlanks *blanks,
|
||||
const FcChar8 *file,
|
||||
FcBool force)
|
||||
{
|
||||
int id;
|
||||
FcChar8 *name;
|
||||
FcPattern *font;
|
||||
FcBool ret = FcTrue;
|
||||
int count;
|
||||
|
||||
id = 0;
|
||||
do
|
||||
{
|
||||
if (!force && cache)
|
||||
name = FcFileCacheFind (cache, file, id, &count);
|
||||
else
|
||||
name = 0;
|
||||
if (name)
|
||||
{
|
||||
/* "." means the file doesn't contain a font */
|
||||
if (strcmp (name, FC_INVALID_FONT_FILE) != 0)
|
||||
{
|
||||
font = FcNameParse (name);
|
||||
if (font)
|
||||
FcPatternAddString (font, FC_FILE, file);
|
||||
}
|
||||
else
|
||||
font = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FcDebug () & FC_DBG_SCAN)
|
||||
{
|
||||
printf ("\tScanning file %s...", file);
|
||||
fflush (stdout);
|
||||
}
|
||||
font = FcFreeTypeQuery (file, id, blanks, &count);
|
||||
if (FcDebug () & FC_DBG_SCAN)
|
||||
printf ("done\n");
|
||||
if (!force && cache)
|
||||
{
|
||||
if (font)
|
||||
{
|
||||
FcChar8 *unparse;
|
||||
|
||||
unparse = FcNameUnparse (font);
|
||||
if (unparse)
|
||||
{
|
||||
(void) FcFileCacheUpdate (cache, file, id, unparse);
|
||||
free (unparse);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* negative cache files not containing fonts */
|
||||
FcFileCacheUpdate (cache, file, id, (FcChar8 *) FC_INVALID_FONT_FILE);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (font)
|
||||
{
|
||||
if (!FcFontSetAdd (set, font))
|
||||
{
|
||||
FcPatternDestroy (font);
|
||||
font = 0;
|
||||
ret = FcFalse;
|
||||
}
|
||||
}
|
||||
id++;
|
||||
} while (font && ret && id < count);
|
||||
return ret;
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcDirScan (FcFontSet *set,
|
||||
FcFileCache *cache,
|
||||
FcBlanks *blanks,
|
||||
const FcChar8 *dir,
|
||||
FcBool force)
|
||||
{
|
||||
DIR *d;
|
||||
struct dirent *e;
|
||||
FcChar8 *file;
|
||||
FcChar8 *base;
|
||||
FcBool ret = FcTrue;
|
||||
|
||||
file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + 256 + 1);
|
||||
if (!file)
|
||||
return FcFalse;
|
||||
|
||||
strcpy ((char *) file, (char *) dir);
|
||||
strcat ((char *) file, "/");
|
||||
base = file + strlen ((char *) file);
|
||||
if (!force)
|
||||
{
|
||||
strcpy ((char *) base, FC_DIR_CACHE_FILE);
|
||||
|
||||
if (FcFileCacheReadDir (set, file))
|
||||
{
|
||||
free (file);
|
||||
return FcTrue;
|
||||
}
|
||||
}
|
||||
|
||||
d = opendir ((char *) dir);
|
||||
if (!d)
|
||||
{
|
||||
free (file);
|
||||
return FcFalse;
|
||||
}
|
||||
while (ret && (e = readdir (d)))
|
||||
{
|
||||
if (e->d_name[0] != '.')
|
||||
{
|
||||
strcpy ((char *) base, (char *) e->d_name);
|
||||
FcFileScan (set, cache, blanks, file, force);
|
||||
}
|
||||
}
|
||||
free (file);
|
||||
closedir (d);
|
||||
return ret;
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcDirSave (FcFontSet *set, const FcChar8 *dir)
|
||||
{
|
||||
FcChar8 *file;
|
||||
FcChar8 *base;
|
||||
FcBool ret;
|
||||
|
||||
file = (FcChar8 *) malloc (strlen ((char *) dir) + 1 + 256 + 1);
|
||||
if (!file)
|
||||
return FcFalse;
|
||||
|
||||
strcpy ((char *) file, (char *) dir);
|
||||
strcat ((char *) file, "/");
|
||||
base = file + strlen ((char *) file);
|
||||
strcpy ((char *) base, FC_DIR_CACHE_FILE);
|
||||
ret = FcFileCacheWriteDir (set, file);
|
||||
free (file);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1,471 +0,0 @@
|
|||
/*
|
||||
* $XFree86: xc/lib/fontconfig/src/fcint.h,v 1.5 2002/02/22 18:54:07 keithp Exp $
|
||||
*
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD 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.
|
||||
*/
|
||||
|
||||
#ifndef _FCINT_H_
|
||||
#define _FCINT_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#include <fontconfig/fcprivate.h>
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
typedef struct _FcMatcher {
|
||||
char *object;
|
||||
double (*compare) (char *object, FcValue value1, FcValue value2);
|
||||
} FcMatcher;
|
||||
|
||||
typedef struct _FcSymbolic {
|
||||
const char *name;
|
||||
int value;
|
||||
} FcSymbolic;
|
||||
|
||||
#ifndef FC_CONFIG_PATH
|
||||
#define FC_CONFIG_PATH "fonts.conf"
|
||||
#endif
|
||||
|
||||
#define FC_DBG_MATCH 1
|
||||
#define FC_DBG_MATCHV 2
|
||||
#define FC_DBG_EDIT 4
|
||||
#define FC_DBG_FONTSET 8
|
||||
#define FC_DBG_CACHE 16
|
||||
#define FC_DBG_CACHEV 32
|
||||
#define FC_DBG_PARSE 64
|
||||
#define FC_DBG_SCAN 128
|
||||
#define FC_DBG_MEMORY 512
|
||||
|
||||
#define FC_MEM_CHARSET 0
|
||||
#define FC_MEM_CHARNODE 1
|
||||
#define FC_MEM_FONTSET 2
|
||||
#define FC_MEM_FONTPTR 3
|
||||
#define FC_MEM_OBJECTSET 4
|
||||
#define FC_MEM_OBJECTPTR 5
|
||||
#define FC_MEM_MATRIX 6
|
||||
#define FC_MEM_PATTERN 7
|
||||
#define FC_MEM_PATELT 8
|
||||
#define FC_MEM_VALLIST 9
|
||||
#define FC_MEM_SUBSTATE 10
|
||||
#define FC_MEM_STRING 11
|
||||
#define FC_MEM_LISTBUCK 12
|
||||
#define FC_MEM_NUM 13
|
||||
|
||||
typedef struct _FcValueList {
|
||||
struct _FcValueList *next;
|
||||
FcValue value;
|
||||
} FcValueList;
|
||||
|
||||
typedef struct _FcPatternElt {
|
||||
const char *object;
|
||||
FcValueList *values;
|
||||
} FcPatternElt;
|
||||
|
||||
struct _FcPattern {
|
||||
int num;
|
||||
int size;
|
||||
FcPatternElt *elts;
|
||||
};
|
||||
|
||||
typedef enum _FcOp {
|
||||
FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpBool, FcOpCharSet,
|
||||
FcOpNil,
|
||||
FcOpField, FcOpConst,
|
||||
FcOpAssign, FcOpAssignReplace,
|
||||
FcOpPrependFirst, FcOpPrepend, FcOpAppend, FcOpAppendLast,
|
||||
FcOpQuest,
|
||||
FcOpOr, FcOpAnd, FcOpEqual, FcOpNotEqual, FcOpContains,
|
||||
FcOpLess, FcOpLessEqual, FcOpMore, FcOpMoreEqual,
|
||||
FcOpPlus, FcOpMinus, FcOpTimes, FcOpDivide,
|
||||
FcOpNot, FcOpComma, FcOpInvalid
|
||||
} FcOp;
|
||||
|
||||
typedef struct _FcExpr {
|
||||
FcOp op;
|
||||
union {
|
||||
int ival;
|
||||
double dval;
|
||||
FcChar8 *sval;
|
||||
FcMatrix *mval;
|
||||
FcBool bval;
|
||||
FcCharSet *cval;
|
||||
char *field;
|
||||
FcChar8 *constant;
|
||||
struct {
|
||||
struct _FcExpr *left, *right;
|
||||
} tree;
|
||||
} u;
|
||||
} FcExpr;
|
||||
|
||||
typedef enum _FcQual {
|
||||
FcQualAny, FcQualAll
|
||||
} FcQual;
|
||||
|
||||
typedef struct _FcTest {
|
||||
struct _FcTest *next;
|
||||
FcQual qual;
|
||||
const char *field;
|
||||
FcOp op;
|
||||
FcExpr *expr;
|
||||
} FcTest;
|
||||
|
||||
typedef struct _FcEdit {
|
||||
struct _FcEdit *next;
|
||||
const char *field;
|
||||
FcOp op;
|
||||
FcExpr *expr;
|
||||
} FcEdit;
|
||||
|
||||
typedef struct _FcSubst {
|
||||
struct _FcSubst *next;
|
||||
FcTest *test;
|
||||
FcEdit *edit;
|
||||
} FcSubst;
|
||||
|
||||
typedef struct _FcCharLeaf FcCharLeaf;
|
||||
typedef struct _FcCharBranch FcCharBranch;
|
||||
typedef union _FcCharNode FcCharNode;
|
||||
|
||||
struct _FcCharLeaf {
|
||||
FcChar32 map[256/32];
|
||||
};
|
||||
|
||||
union _FcCharNode {
|
||||
FcCharBranch *branch;
|
||||
FcCharLeaf *leaf;
|
||||
};
|
||||
|
||||
struct _FcCharBranch {
|
||||
FcCharNode nodes[256];
|
||||
};
|
||||
|
||||
struct _FcCharSet {
|
||||
int levels;
|
||||
int ref; /* reference count */
|
||||
FcBool constant; /* shared constant */
|
||||
FcCharNode node;
|
||||
};
|
||||
|
||||
typedef struct _FcStrBuf {
|
||||
FcChar8 *buf;
|
||||
FcBool allocated;
|
||||
FcBool failed;
|
||||
int len;
|
||||
int size;
|
||||
} FcStrBuf;
|
||||
|
||||
typedef struct _FcFileCacheEnt {
|
||||
struct _FcFileCacheEnt *next;
|
||||
unsigned int hash;
|
||||
FcChar8 *file;
|
||||
int id;
|
||||
time_t time;
|
||||
FcChar8 *name;
|
||||
FcBool referenced;
|
||||
} FcFileCacheEnt;
|
||||
|
||||
#define FC_FILE_CACHE_HASH_SIZE 509
|
||||
|
||||
struct _FcFileCache {
|
||||
FcFileCacheEnt *ents[FC_FILE_CACHE_HASH_SIZE];
|
||||
FcBool updated;
|
||||
int entries;
|
||||
int referenced;
|
||||
};
|
||||
|
||||
struct _FcBlanks {
|
||||
int nblank;
|
||||
int sblank;
|
||||
FcChar32 *blanks;
|
||||
};
|
||||
|
||||
struct _FcConfig {
|
||||
/*
|
||||
* File names loaded from the configuration -- saved here as the
|
||||
* cache file must be consulted before the directories are scanned,
|
||||
* and those directives may occur in any order
|
||||
*/
|
||||
FcChar8 **dirs; /* directories containing fonts */
|
||||
FcChar8 *cache; /* name of per-user cache file */
|
||||
/*
|
||||
* Set of allowed blank chars -- used to
|
||||
* trim fonts of bogus glyphs
|
||||
*/
|
||||
FcBlanks *blanks;
|
||||
/*
|
||||
* Names of all of the configuration files used
|
||||
* to create this configuration
|
||||
*/
|
||||
FcChar8 **configFiles; /* config files loaded */
|
||||
/*
|
||||
* Substitution instructions for patterns and fonts;
|
||||
* maxObjects is used to allocate appropriate intermediate storage
|
||||
* while performing a whole set of substitutions
|
||||
*/
|
||||
FcSubst *substPattern; /* substitutions for patterns */
|
||||
FcSubst *substFont; /* substitutions for fonts */
|
||||
int maxObjects; /* maximum number of tests in all substs */
|
||||
/*
|
||||
* The set of fonts loaded from the listed directories; the
|
||||
* order within the set does not determine the font selection,
|
||||
* except in the case of identical matches in which case earlier fonts
|
||||
* match preferrentially
|
||||
*/
|
||||
FcFontSet *fonts[FcSetApplication + 1];
|
||||
};
|
||||
|
||||
extern FcConfig *_fcConfig;
|
||||
|
||||
/* fcblanks.c */
|
||||
|
||||
/* fccache.c */
|
||||
|
||||
FcFileCache *
|
||||
FcFileCacheCreate (void);
|
||||
|
||||
FcChar8 *
|
||||
FcFileCacheFind (FcFileCache *cache,
|
||||
const FcChar8 *file,
|
||||
int id,
|
||||
int *count);
|
||||
|
||||
void
|
||||
FcFileCacheDestroy (FcFileCache *cache);
|
||||
|
||||
void
|
||||
FcFileCacheLoad (FcFileCache *cache,
|
||||
const FcChar8 *cache_file);
|
||||
|
||||
FcBool
|
||||
FcFileCacheUpdate (FcFileCache *cache,
|
||||
const FcChar8 *file,
|
||||
int id,
|
||||
const FcChar8 *name);
|
||||
|
||||
FcBool
|
||||
FcFileCacheSave (FcFileCache *cache,
|
||||
const FcChar8 *cache_file);
|
||||
|
||||
FcBool
|
||||
FcFileCacheReadDir (FcFontSet *set, const FcChar8 *cache_file);
|
||||
|
||||
FcBool
|
||||
FcFileCacheWriteDir (FcFontSet *set, const FcChar8 *cache_file);
|
||||
|
||||
/* fccfg.c */
|
||||
|
||||
FcBool
|
||||
FcConfigAddDir (FcConfig *config,
|
||||
const FcChar8 *d);
|
||||
|
||||
FcBool
|
||||
FcConfigAddConfigFile (FcConfig *config,
|
||||
const FcChar8 *f);
|
||||
|
||||
FcBool
|
||||
FcConfigSetCache (FcConfig *config,
|
||||
const FcChar8 *c);
|
||||
|
||||
FcBool
|
||||
FcConfigAddBlank (FcConfig *config,
|
||||
FcChar32 blank);
|
||||
|
||||
FcBool
|
||||
FcConfigAddEdit (FcConfig *config,
|
||||
FcTest *test,
|
||||
FcEdit *edit,
|
||||
FcMatchKind kind);
|
||||
|
||||
void
|
||||
FcConfigSetFonts (FcConfig *config,
|
||||
FcFontSet *fonts,
|
||||
FcSetName set);
|
||||
|
||||
FcBool
|
||||
FcConfigCompareValue (const FcValue m,
|
||||
FcOp op,
|
||||
const FcValue v);
|
||||
|
||||
/* fccharset.c */
|
||||
FcBool
|
||||
FcNameUnparseCharSet (FcStrBuf *buf, const FcCharSet *c);
|
||||
|
||||
FcCharSet *
|
||||
FcNameParseCharSet (FcChar8 *string);
|
||||
|
||||
/* fcdbg.c */
|
||||
void
|
||||
FcValuePrint (FcValue v);
|
||||
|
||||
void
|
||||
FcValueListPrint (FcValueList *l);
|
||||
|
||||
void
|
||||
FcOpPrint (FcOp op);
|
||||
|
||||
void
|
||||
FcTestPrint (FcTest *test);
|
||||
|
||||
void
|
||||
FcExprPrint (FcExpr *expr);
|
||||
|
||||
void
|
||||
FcEditPrint (FcEdit *edit);
|
||||
|
||||
void
|
||||
FcSubstPrint (FcSubst *subst);
|
||||
|
||||
void
|
||||
FcFontSetPrint (FcFontSet *s);
|
||||
|
||||
int
|
||||
FcDebug (void);
|
||||
|
||||
/* fcdir.c */
|
||||
|
||||
/* fcfont.c */
|
||||
int
|
||||
FcFontDebug (void);
|
||||
|
||||
/* fcfs.c */
|
||||
/* fcgram.y */
|
||||
int
|
||||
FcConfigparse (void);
|
||||
|
||||
int
|
||||
FcConfigwrap (void);
|
||||
|
||||
void
|
||||
FcConfigerror (char *fmt, ...);
|
||||
|
||||
char *
|
||||
FcConfigSaveField (const char *field);
|
||||
|
||||
FcTest *
|
||||
FcTestCreate (FcQual qual, const FcChar8 *field, FcOp compare, FcExpr *expr);
|
||||
|
||||
void
|
||||
FcTestDestroy (FcTest *test);
|
||||
|
||||
FcExpr *
|
||||
FcExprCreateInteger (int i);
|
||||
|
||||
FcExpr *
|
||||
FcExprCreateDouble (double d);
|
||||
|
||||
FcExpr *
|
||||
FcExprCreateString (const FcChar8 *s);
|
||||
|
||||
FcExpr *
|
||||
FcExprCreateMatrix (const FcMatrix *m);
|
||||
|
||||
FcExpr *
|
||||
FcExprCreateBool (FcBool b);
|
||||
|
||||
FcExpr *
|
||||
FcExprCreateNil (void);
|
||||
|
||||
FcExpr *
|
||||
FcExprCreateField (const char *field);
|
||||
|
||||
FcExpr *
|
||||
FcExprCreateConst (const FcChar8 *constant);
|
||||
|
||||
FcExpr *
|
||||
FcExprCreateOp (FcExpr *left, FcOp op, FcExpr *right);
|
||||
|
||||
void
|
||||
FcExprDestroy (FcExpr *e);
|
||||
|
||||
FcEdit *
|
||||
FcEditCreate (const char *field, FcOp op, FcExpr *expr);
|
||||
|
||||
void
|
||||
FcEditDestroy (FcEdit *e);
|
||||
|
||||
/* fcinit.c */
|
||||
|
||||
void
|
||||
FcMemReport (void);
|
||||
|
||||
void
|
||||
FcMemAlloc (int kind, int size);
|
||||
|
||||
void
|
||||
FcMemFree (int kind, int size);
|
||||
|
||||
/* fclist.c */
|
||||
|
||||
/* fcmatch.c */
|
||||
|
||||
/* fcname.c */
|
||||
|
||||
FcBool
|
||||
FcNameBool (FcChar8 *v, FcBool *result);
|
||||
|
||||
/* fcpat.c */
|
||||
void
|
||||
FcValueListDestroy (FcValueList *l);
|
||||
|
||||
FcPatternElt *
|
||||
FcPatternFind (FcPattern *p, const char *object, FcBool insert);
|
||||
|
||||
/* fcrender.c */
|
||||
|
||||
/* fcmatrix.c */
|
||||
void
|
||||
FcMatrixFree (FcMatrix *mat);
|
||||
|
||||
/* fcstr.c */
|
||||
FcChar8 *
|
||||
FcStrPlus (const FcChar8 *s1, const FcChar8 *s2);
|
||||
|
||||
void
|
||||
FcStrFree (FcChar8 *s);
|
||||
|
||||
void
|
||||
FcStrBufInit (FcStrBuf *buf, FcChar8 *init, int size);
|
||||
|
||||
void
|
||||
FcStrBufDestroy (FcStrBuf *buf);
|
||||
|
||||
FcChar8 *
|
||||
FcStrBufDone (FcStrBuf *buf);
|
||||
|
||||
FcBool
|
||||
FcStrBufChar (FcStrBuf *buf, FcChar8 c);
|
||||
|
||||
FcBool
|
||||
FcStrBufString (FcStrBuf *buf, const FcChar8 *s);
|
||||
|
||||
FcBool
|
||||
FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len);
|
||||
|
||||
#endif /* _FC_INT_H_ */
|
|
@ -1,442 +0,0 @@
|
|||
/*
|
||||
* $XFree86: xc/lib/fontconfig/src/fclist.c,v 1.1.1.1 2002/02/14 23:34:12 keithp Exp $
|
||||
*
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "fcint.h"
|
||||
|
||||
FcObjectSet *
|
||||
FcObjectSetCreate (void)
|
||||
{
|
||||
FcObjectSet *os;
|
||||
|
||||
os = (FcObjectSet *) malloc (sizeof (FcObjectSet));
|
||||
if (!os)
|
||||
return 0;
|
||||
FcMemAlloc (FC_MEM_OBJECTSET, sizeof (FcObjectSet));
|
||||
os->nobject = 0;
|
||||
os->sobject = 0;
|
||||
os->objects = 0;
|
||||
return os;
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcObjectSetAdd (FcObjectSet *os, const char *object)
|
||||
{
|
||||
int s;
|
||||
const char **objects;
|
||||
|
||||
if (os->nobject == os->sobject)
|
||||
{
|
||||
s = os->sobject + 4;
|
||||
if (os->objects)
|
||||
objects = (const char **) realloc ((void *) os->objects,
|
||||
s * sizeof (const char *));
|
||||
else
|
||||
objects = (const char **) malloc (s * sizeof (const char *));
|
||||
if (!objects)
|
||||
return FcFalse;
|
||||
if (os->sobject)
|
||||
FcMemFree (FC_MEM_OBJECTPTR, os->sobject * sizeof (const char *));
|
||||
FcMemAlloc (FC_MEM_OBJECTPTR, s * sizeof (const char *));
|
||||
os->objects = objects;
|
||||
os->sobject = s;
|
||||
}
|
||||
os->objects[os->nobject++] = object;
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
void
|
||||
FcObjectSetDestroy (FcObjectSet *os)
|
||||
{
|
||||
if (os->objects)
|
||||
{
|
||||
FcMemFree (FC_MEM_OBJECTPTR, os->sobject * sizeof (const char *));
|
||||
free ((void *) os->objects);
|
||||
}
|
||||
FcMemFree (FC_MEM_OBJECTSET, sizeof (FcObjectSet));
|
||||
free (os);
|
||||
}
|
||||
|
||||
FcObjectSet *
|
||||
FcObjectSetVaBuild (const char *first, va_list va)
|
||||
{
|
||||
FcObjectSet *ret;
|
||||
|
||||
FcObjectSetVapBuild (ret, first, va);
|
||||
return ret;
|
||||
}
|
||||
|
||||
FcObjectSet *
|
||||
FcObjectSetBuild (const char *first, ...)
|
||||
{
|
||||
va_list va;
|
||||
FcObjectSet *os;
|
||||
|
||||
va_start (va, first);
|
||||
FcObjectSetVapBuild (os, first, va);
|
||||
va_end (va);
|
||||
return os;
|
||||
}
|
||||
|
||||
static FcBool
|
||||
FcListValueListMatchAny (FcValueList *v1orig,
|
||||
FcValueList *v2orig)
|
||||
{
|
||||
FcValueList *v1, *v2;
|
||||
|
||||
for (v1 = v1orig; v1; v1 = v1->next)
|
||||
for (v2 = v2orig; v2; v2 = v2->next)
|
||||
if (FcConfigCompareValue (v2->value, FcOpContains, v1->value))
|
||||
return FcTrue;
|
||||
return FcFalse;
|
||||
}
|
||||
|
||||
static FcBool
|
||||
FcListValueListEqual (FcValueList *v1orig,
|
||||
FcValueList *v2orig)
|
||||
{
|
||||
FcValueList *v1, *v2;
|
||||
|
||||
for (v1 = v1orig; v1; v1 = v1->next)
|
||||
{
|
||||
for (v2 = v2orig; v2; v2 = v2->next)
|
||||
if (FcConfigCompareValue (v1->value, FcOpEqual, v2->value))
|
||||
break;
|
||||
if (!v2)
|
||||
return FcFalse;
|
||||
}
|
||||
for (v2 = v2orig; v2; v2 = v2->next)
|
||||
{
|
||||
for (v1 = v1orig; v1; v1 = v1->next)
|
||||
if (FcConfigCompareValue (v1->value, FcOpEqual, v2->value))
|
||||
break;
|
||||
if (!v1)
|
||||
return FcFalse;
|
||||
}
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
/*
|
||||
* FcTrue iff all objects in "p" match "font"
|
||||
*/
|
||||
|
||||
static FcBool
|
||||
FcListPatternMatchAny (FcPattern *p,
|
||||
FcPattern *font)
|
||||
{
|
||||
int i;
|
||||
FcPatternElt *e;
|
||||
|
||||
for (i = 0; i < p->num; i++)
|
||||
{
|
||||
e = FcPatternFind (font, p->elts[i].object, FcFalse);
|
||||
if (!e)
|
||||
return FcFalse;
|
||||
if (!FcListValueListMatchAny (p->elts[i].values, e->values))
|
||||
return FcFalse;
|
||||
}
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
static FcBool
|
||||
FcListPatternEqual (FcPattern *p1,
|
||||
FcPattern *p2,
|
||||
FcObjectSet *os)
|
||||
{
|
||||
int i;
|
||||
FcPatternElt *e1, *e2;
|
||||
|
||||
for (i = 0; i < os->nobject; i++)
|
||||
{
|
||||
e1 = FcPatternFind (p1, os->objects[i], FcFalse);
|
||||
e2 = FcPatternFind (p2, os->objects[i], FcFalse);
|
||||
if (!e1 && !e2)
|
||||
return FcTrue;
|
||||
if (!e1 || !e2)
|
||||
return FcFalse;
|
||||
if (!FcListValueListEqual (e1->values, e2->values))
|
||||
return FcFalse;
|
||||
}
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
static FcChar32
|
||||
FcListStringHash (const FcChar8 *s)
|
||||
{
|
||||
FcChar32 h = 0;
|
||||
FcChar8 c;
|
||||
|
||||
while ((c = *s++))
|
||||
{
|
||||
c = FcToLower (c);
|
||||
h = ((h << 3) ^ (h >> 3)) ^ c;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
static FcChar32
|
||||
FcListMatrixHash (const FcMatrix *m)
|
||||
{
|
||||
int xx = (int) (m->xx * 100),
|
||||
xy = (int) (m->xy * 100),
|
||||
yx = (int) (m->yx * 100),
|
||||
yy = (int) (m->yy * 100);
|
||||
|
||||
return ((FcChar32) xx) ^ ((FcChar32) xy) ^ ((FcChar32) yx) ^ ((FcChar32) yy);
|
||||
}
|
||||
|
||||
static FcChar32
|
||||
FcListValueHash (FcValue v)
|
||||
{
|
||||
switch (v.type) {
|
||||
case FcTypeVoid:
|
||||
return 0;
|
||||
case FcTypeInteger:
|
||||
return (FcChar32) v.u.i;
|
||||
case FcTypeDouble:
|
||||
return (FcChar32) (int) v.u.d;
|
||||
case FcTypeString:
|
||||
return FcListStringHash (v.u.s);
|
||||
case FcTypeBool:
|
||||
return (FcChar32) v.u.b;
|
||||
case FcTypeMatrix:
|
||||
return FcListMatrixHash (v.u.m);
|
||||
case FcTypeCharSet:
|
||||
return FcCharSetCount (v.u.c);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FcChar32
|
||||
FcListValueListHash (FcValueList *list)
|
||||
{
|
||||
FcChar32 h = 0;
|
||||
|
||||
while (list)
|
||||
{
|
||||
h = h ^ FcListValueHash (list->value);
|
||||
list = list->next;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
static FcChar32
|
||||
FcListPatternHash (FcPattern *font,
|
||||
FcObjectSet *os)
|
||||
{
|
||||
int n;
|
||||
FcPatternElt *e;
|
||||
FcChar32 h = 0;
|
||||
|
||||
for (n = 0; n < os->nobject; n++)
|
||||
{
|
||||
e = FcPatternFind (font, os->objects[n], FcFalse);
|
||||
if (e)
|
||||
h = h ^ FcListValueListHash (e->values);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
typedef struct _FcListBucket {
|
||||
struct _FcListBucket *next;
|
||||
FcChar32 hash;
|
||||
FcPattern *pattern;
|
||||
} FcListBucket;
|
||||
|
||||
#define FC_LIST_HASH_SIZE 4099
|
||||
|
||||
typedef struct _FcListHashTable {
|
||||
int entries;
|
||||
FcListBucket *buckets[FC_LIST_HASH_SIZE];
|
||||
} FcListHashTable;
|
||||
|
||||
static void
|
||||
FcListHashTableInit (FcListHashTable *table)
|
||||
{
|
||||
table->entries = 0;
|
||||
memset (table->buckets, '\0', sizeof (table->buckets));
|
||||
}
|
||||
|
||||
static void
|
||||
FcListHashTableCleanup (FcListHashTable *table)
|
||||
{
|
||||
int i;
|
||||
FcListBucket *bucket, *next;
|
||||
|
||||
for (i = 0; i < FC_LIST_HASH_SIZE; i++)
|
||||
{
|
||||
for (bucket = table->buckets[i]; bucket; bucket = next)
|
||||
{
|
||||
next = bucket->next;
|
||||
FcPatternDestroy (bucket->pattern);
|
||||
FcMemFree (FC_MEM_LISTBUCK, sizeof (FcListBucket));
|
||||
free (bucket);
|
||||
}
|
||||
table->buckets[i] = 0;
|
||||
}
|
||||
table->entries = 0;
|
||||
}
|
||||
|
||||
static FcBool
|
||||
FcListAppend (FcListHashTable *table,
|
||||
FcPattern *font,
|
||||
FcObjectSet *os)
|
||||
{
|
||||
int o;
|
||||
FcPatternElt *e;
|
||||
FcValueList *v;
|
||||
FcChar32 hash;
|
||||
FcListBucket **prev, *bucket;
|
||||
|
||||
hash = FcListPatternHash (font, os);
|
||||
for (prev = &table->buckets[hash % FC_LIST_HASH_SIZE];
|
||||
(bucket = *prev); prev = &(bucket->next))
|
||||
{
|
||||
if (bucket->hash == hash &&
|
||||
FcListPatternEqual (bucket->pattern, font, os))
|
||||
return FcTrue;
|
||||
}
|
||||
bucket = (FcListBucket *) malloc (sizeof (FcListBucket));
|
||||
if (!bucket)
|
||||
goto bail0;
|
||||
FcMemAlloc (FC_MEM_LISTBUCK, sizeof (FcListBucket));
|
||||
bucket->next = 0;
|
||||
bucket->hash = hash;
|
||||
bucket->pattern = FcPatternCreate ();
|
||||
if (!bucket->pattern)
|
||||
goto bail1;
|
||||
|
||||
for (o = 0; o < os->nobject; o++)
|
||||
{
|
||||
e = FcPatternFind (font, os->objects[o], FcFalse);
|
||||
if (e)
|
||||
{
|
||||
for (v = e->values; v; v = v->next)
|
||||
{
|
||||
if (!FcPatternAdd (bucket->pattern,
|
||||
os->objects[o],
|
||||
v->value, FcTrue))
|
||||
goto bail2;
|
||||
}
|
||||
}
|
||||
}
|
||||
*prev = bucket;
|
||||
++table->entries;
|
||||
|
||||
return FcTrue;
|
||||
|
||||
bail2:
|
||||
FcPatternDestroy (bucket->pattern);
|
||||
bail1:
|
||||
FcMemFree (FC_MEM_LISTBUCK, sizeof (FcListBucket));
|
||||
free (bucket);
|
||||
bail0:
|
||||
return FcFalse;
|
||||
}
|
||||
|
||||
FcFontSet *
|
||||
FcFontList (FcConfig *config,
|
||||
FcPattern *p,
|
||||
FcObjectSet *os)
|
||||
{
|
||||
FcFontSet *ret;
|
||||
FcFontSet *s;
|
||||
int f;
|
||||
FcSetName set;
|
||||
FcListHashTable table;
|
||||
int i;
|
||||
FcListBucket *bucket;
|
||||
|
||||
if (!config)
|
||||
{
|
||||
config = FcConfigGetCurrent ();
|
||||
if (!config)
|
||||
goto bail0;
|
||||
}
|
||||
FcListHashTableInit (&table);
|
||||
/*
|
||||
* Walk all available fonts adding those that
|
||||
* match to the hash table
|
||||
*/
|
||||
for (set = FcSetSystem; set <= FcSetApplication; set++)
|
||||
{
|
||||
s = config->fonts[set];
|
||||
if (!s)
|
||||
continue;
|
||||
for (f = 0; f < s->nfont; f++)
|
||||
if (FcListPatternMatchAny (p, s->fonts[f]))
|
||||
if (!FcListAppend (&table, s->fonts[f], os))
|
||||
goto bail1;
|
||||
}
|
||||
#if 0
|
||||
{
|
||||
int max = 0;
|
||||
int full = 0;
|
||||
int ents = 0;
|
||||
int len;
|
||||
for (i = 0; i < FC_LIST_HASH_SIZE; i++)
|
||||
{
|
||||
if ((bucket = table.buckets[i]))
|
||||
{
|
||||
len = 0;
|
||||
for (; bucket; bucket = bucket->next)
|
||||
{
|
||||
ents++;
|
||||
len++;
|
||||
}
|
||||
if (len > max)
|
||||
max = len;
|
||||
full++;
|
||||
}
|
||||
}
|
||||
printf ("used: %d max: %d avg: %g\n", full, max,
|
||||
(double) ents / FC_LIST_HASH_SIZE);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Walk the hash table and build
|
||||
* a font set
|
||||
*/
|
||||
ret = FcFontSetCreate ();
|
||||
if (!ret)
|
||||
goto bail0;
|
||||
for (i = 0; i < FC_LIST_HASH_SIZE; i++)
|
||||
while ((bucket = table.buckets[i]))
|
||||
{
|
||||
if (!FcFontSetAdd (ret, bucket->pattern))
|
||||
goto bail2;
|
||||
table.buckets[i] = bucket->next;
|
||||
FcMemFree (FC_MEM_LISTBUCK, sizeof (FcListBucket));
|
||||
free (bucket);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
bail2:
|
||||
FcFontSetDestroy (ret);
|
||||
bail1:
|
||||
FcListHashTableCleanup (&table);
|
||||
bail0:
|
||||
return 0;
|
||||
}
|
|
@ -1,348 +0,0 @@
|
|||
/*
|
||||
* $XFree86: xc/lib/fontconfig/src/fcmatch.c,v 1.2 2002/02/15 06:01:28 keithp Exp $
|
||||
*
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "fcint.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static double
|
||||
FcCompareInteger (char *object, FcValue value1, FcValue value2)
|
||||
{
|
||||
int v;
|
||||
|
||||
if (value2.type != FcTypeInteger || value1.type != FcTypeInteger)
|
||||
return -1.0;
|
||||
v = value2.u.i - value1.u.i;
|
||||
if (v < 0)
|
||||
v = -v;
|
||||
return (double) v;
|
||||
}
|
||||
|
||||
static double
|
||||
FcCompareString (char *object, FcValue value1, FcValue value2)
|
||||
{
|
||||
if (value2.type != FcTypeString || value1.type != FcTypeString)
|
||||
return -1.0;
|
||||
return (double) FcStrCmpIgnoreCase (value1.u.s, value2.u.s) != 0;
|
||||
}
|
||||
|
||||
static double
|
||||
FcCompareBool (char *object, FcValue value1, FcValue value2)
|
||||
{
|
||||
if (value2.type != FcTypeBool || value1.type != FcTypeBool)
|
||||
return -1.0;
|
||||
return (double) value2.u.b != value1.u.b;
|
||||
}
|
||||
|
||||
static double
|
||||
FcCompareCharSet (char *object, FcValue value1, FcValue value2)
|
||||
{
|
||||
if (value2.type != FcTypeCharSet || value1.type != FcTypeCharSet)
|
||||
return -1.0;
|
||||
return (double) FcCharSetSubtractCount (value1.u.c, value2.u.c);
|
||||
}
|
||||
|
||||
static double
|
||||
FcCompareSize (char *object, FcValue value1, FcValue value2)
|
||||
{
|
||||
double v1, v2, v;
|
||||
|
||||
switch (value1.type) {
|
||||
case FcTypeInteger:
|
||||
v1 = value1.u.i;
|
||||
break;
|
||||
case FcTypeDouble:
|
||||
v1 = value1.u.d;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
switch (value2.type) {
|
||||
case FcTypeInteger:
|
||||
v2 = value2.u.i;
|
||||
break;
|
||||
case FcTypeDouble:
|
||||
v2 = value2.u.d;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
if (v2 == 0)
|
||||
return 0;
|
||||
v = v2 - v1;
|
||||
if (v < 0)
|
||||
v = -v;
|
||||
return v;
|
||||
}
|
||||
|
||||
/*
|
||||
* Order is significant, it defines the precedence of
|
||||
* each value, earlier values are more significant than
|
||||
* later values
|
||||
*/
|
||||
static FcMatcher _FcMatchers [] = {
|
||||
{ FC_FOUNDRY, FcCompareString, },
|
||||
{ FC_CHARSET, FcCompareCharSet },
|
||||
{ FC_ANTIALIAS, FcCompareBool, },
|
||||
{ FC_LANG, FcCompareString },
|
||||
{ FC_FAMILY, FcCompareString, },
|
||||
{ FC_SPACING, FcCompareInteger, },
|
||||
{ FC_PIXEL_SIZE, FcCompareSize, },
|
||||
{ FC_STYLE, FcCompareString, },
|
||||
{ FC_SLANT, FcCompareInteger, },
|
||||
{ FC_WEIGHT, FcCompareInteger, },
|
||||
{ FC_RASTERIZER, FcCompareString, },
|
||||
{ FC_OUTLINE, FcCompareBool, },
|
||||
};
|
||||
|
||||
#define NUM_MATCHER (sizeof _FcMatchers / sizeof _FcMatchers[0])
|
||||
|
||||
static FcBool
|
||||
FcCompareValueList (const char *object,
|
||||
FcValueList *v1orig, /* pattern */
|
||||
FcValueList *v2orig, /* target */
|
||||
FcValue *bestValue,
|
||||
double *value,
|
||||
FcResult *result)
|
||||
{
|
||||
FcValueList *v1, *v2;
|
||||
double v, best;
|
||||
int j;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_MATCHER; i++)
|
||||
{
|
||||
if (!FcStrCmpIgnoreCase ((FcChar8 *) _FcMatchers[i].object,
|
||||
(FcChar8 *) object))
|
||||
break;
|
||||
}
|
||||
if (i == NUM_MATCHER)
|
||||
{
|
||||
if (bestValue)
|
||||
*bestValue = v2orig->value;
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
best = 1e99;
|
||||
j = 0;
|
||||
for (v1 = v1orig; v1; v1 = v1->next)
|
||||
{
|
||||
for (v2 = v2orig; v2; v2 = v2->next)
|
||||
{
|
||||
v = (*_FcMatchers[i].compare) (_FcMatchers[i].object,
|
||||
v1->value,
|
||||
v2->value);
|
||||
if (v < 0)
|
||||
{
|
||||
*result = FcResultTypeMismatch;
|
||||
return FcFalse;
|
||||
}
|
||||
if (FcDebug () & FC_DBG_MATCHV)
|
||||
printf (" v %g j %d ", v, j);
|
||||
v = v * 100 + j;
|
||||
if (v < best)
|
||||
{
|
||||
if (bestValue)
|
||||
*bestValue = v2->value;
|
||||
best = v;
|
||||
}
|
||||
}
|
||||
j++;
|
||||
}
|
||||
if (FcDebug () & FC_DBG_MATCHV)
|
||||
{
|
||||
printf (" %s: %g ", object, best);
|
||||
FcValueListPrint (v1orig);
|
||||
printf (", ");
|
||||
FcValueListPrint (v2orig);
|
||||
printf ("\n");
|
||||
}
|
||||
value[i] += best;
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a value indicating the distance between the two lists of
|
||||
* values
|
||||
*/
|
||||
|
||||
static FcBool
|
||||
FcCompare (FcPattern *pat,
|
||||
FcPattern *fnt,
|
||||
double *value,
|
||||
FcResult *result)
|
||||
{
|
||||
int i, i1, i2;
|
||||
|
||||
for (i = 0; i < NUM_MATCHER; i++)
|
||||
value[i] = 0.0;
|
||||
|
||||
for (i1 = 0; i1 < pat->num; i1++)
|
||||
{
|
||||
for (i2 = 0; i2 < fnt->num; i2++)
|
||||
{
|
||||
if (!FcStrCmpIgnoreCase ((FcChar8 *) pat->elts[i1].object,
|
||||
(FcChar8 *) fnt->elts[i2].object))
|
||||
{
|
||||
if (!FcCompareValueList (pat->elts[i1].object,
|
||||
pat->elts[i1].values,
|
||||
fnt->elts[i2].values,
|
||||
0,
|
||||
value,
|
||||
result))
|
||||
return FcFalse;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
/*
|
||||
* Overspecified patterns are slightly penalized in
|
||||
* case some other font includes the requested field
|
||||
*/
|
||||
if (i2 == fnt->num)
|
||||
{
|
||||
for (i2 = 0; i2 < NUM_MATCHER; i2++)
|
||||
{
|
||||
if (!FcStrCmpIgnoreCase (_FcMatchers[i2].object,
|
||||
pat->elts[i1].object))
|
||||
{
|
||||
value[i2] = 1.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
FcPattern *
|
||||
FcFontMatch (FcConfig *config,
|
||||
FcPattern *p,
|
||||
FcResult *result)
|
||||
{
|
||||
double score[NUM_MATCHER], bestscore[NUM_MATCHER];
|
||||
int f;
|
||||
FcFontSet *s;
|
||||
FcPattern *best;
|
||||
FcPattern *new;
|
||||
FcPatternElt *fe, *pe;
|
||||
FcValue v;
|
||||
int i;
|
||||
FcSetName set;
|
||||
|
||||
for (i = 0; i < NUM_MATCHER; i++)
|
||||
bestscore[i] = 0;
|
||||
best = 0;
|
||||
if (FcDebug () & FC_DBG_MATCH)
|
||||
{
|
||||
printf ("Match ");
|
||||
FcPatternPrint (p);
|
||||
}
|
||||
if (!config)
|
||||
{
|
||||
config = FcConfigGetCurrent ();
|
||||
if (!config)
|
||||
return 0;
|
||||
}
|
||||
for (set = FcSetSystem; set <= FcSetApplication; set++)
|
||||
{
|
||||
s = config->fonts[set];
|
||||
if (!s)
|
||||
continue;
|
||||
for (f = 0; f < s->nfont; f++)
|
||||
{
|
||||
if (FcDebug () & FC_DBG_MATCHV)
|
||||
{
|
||||
printf ("Font %d ", f);
|
||||
FcPatternPrint (s->fonts[f]);
|
||||
}
|
||||
if (!FcCompare (p, s->fonts[f], score, result))
|
||||
return 0;
|
||||
if (FcDebug () & FC_DBG_MATCHV)
|
||||
{
|
||||
printf ("Score");
|
||||
for (i = 0; i < NUM_MATCHER; i++)
|
||||
{
|
||||
printf (" %g", score[i]);
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
for (i = 0; i < NUM_MATCHER; i++)
|
||||
{
|
||||
if (best && bestscore[i] < score[i])
|
||||
break;
|
||||
if (!best || score[i] < bestscore[i])
|
||||
{
|
||||
for (i = 0; i < NUM_MATCHER; i++)
|
||||
bestscore[i] = score[i];
|
||||
best = s->fonts[f];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (FcDebug () & FC_DBG_MATCH)
|
||||
{
|
||||
printf ("Best score");
|
||||
for (i = 0; i < NUM_MATCHER; i++)
|
||||
printf (" %g", bestscore[i]);
|
||||
FcPatternPrint (best);
|
||||
}
|
||||
if (!best)
|
||||
{
|
||||
*result = FcResultNoMatch;
|
||||
return 0;
|
||||
}
|
||||
new = FcPatternCreate ();
|
||||
if (!new)
|
||||
return 0;
|
||||
for (i = 0; i < best->num; i++)
|
||||
{
|
||||
fe = &best->elts[i];
|
||||
pe = FcPatternFind (p, fe->object, FcFalse);
|
||||
if (pe)
|
||||
{
|
||||
if (!FcCompareValueList (pe->object, pe->values,
|
||||
fe->values, &v, score, result))
|
||||
{
|
||||
FcPatternDestroy (new);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
v = fe->values->value;
|
||||
FcPatternAdd (new, fe->object, v, FcTrue);
|
||||
}
|
||||
for (i = 0; i < p->num; i++)
|
||||
{
|
||||
pe = &p->elts[i];
|
||||
fe = FcPatternFind (best, pe->object, FcFalse);
|
||||
if (!fe)
|
||||
FcPatternAdd (new, pe->object, pe->values->value, FcTrue);
|
||||
}
|
||||
FcConfigSubstitute (config, new, FcMatchFont);
|
||||
return new;
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Загрузка…
Ссылка в новой задаче