|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Copyright © 2000 Keith Packard
|
|
Packit Service |
1b8107 |
*
|
|
Packit Service |
1b8107 |
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
Packit Service |
1b8107 |
* documentation for any purpose is hereby granted without fee, provided that
|
|
Packit Service |
1b8107 |
* the above copyright notice appear in all copies and that both that
|
|
Packit Service |
1b8107 |
* copyright notice and this permission notice appear in supporting
|
|
Packit Service |
1b8107 |
* documentation, and that the name of Keith Packard not be used in
|
|
Packit Service |
1b8107 |
* advertising or publicity pertaining to distribution of the software without
|
|
Packit Service |
1b8107 |
* specific, written prior permission. Keith Packard makes no
|
|
Packit Service |
1b8107 |
* representations about the suitability of this software for any purpose. It
|
|
Packit Service |
1b8107 |
* is provided "as is" without express or implied warranty.
|
|
Packit Service |
1b8107 |
*
|
|
Packit Service |
1b8107 |
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
Packit Service |
1b8107 |
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
Packit Service |
1b8107 |
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
Packit Service |
1b8107 |
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
Packit Service |
1b8107 |
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
Packit Service |
1b8107 |
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
Packit Service |
1b8107 |
* PERFORMANCE OF THIS SOFTWARE.
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
#include "xftint.h"
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
_X_HIDDEN FT_Library _XftFTlibrary;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
#define FT_Matrix_Equal(a,b) ((a)->xx == (b)->xx && \
|
|
Packit Service |
1b8107 |
(a)->yy == (b)->yy && \
|
|
Packit Service |
1b8107 |
(a)->xy == (b)->xy && \
|
|
Packit Service |
1b8107 |
(a)->yx == (b)->yx)
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* List of all open files (each face in a file is managed separately)
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
static XftFtFile *_XftFtFiles;
|
|
Packit Service |
1b8107 |
static int XftMaxFreeTypeFiles = 5;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
static XftFtFile *
|
|
Packit Service |
1b8107 |
_XftGetFile (const FcChar8 *file, int id)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
XftFtFile *f;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (!XftInitFtLibrary ())
|
|
Packit Service |
1b8107 |
return NULL;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
for (f = _XftFtFiles; f; f = f->next)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
if (!strcmp (f->file, (char *) file) && f->id == id)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
++f->ref;
|
|
Packit Service |
1b8107 |
if (XftDebug () & XFT_DBG_REF)
|
|
Packit Service |
1b8107 |
printf ("FontFile %s/%d matches existing (%d)\n",
|
|
Packit Service |
1b8107 |
file, id, f->ref);
|
|
Packit Service |
1b8107 |
return f;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
f = malloc (sizeof (XftFtFile) + strlen ((char *) file) + 1);
|
|
Packit Service |
1b8107 |
if (!f)
|
|
Packit Service |
1b8107 |
return NULL;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
XftMemAlloc (XFT_MEM_FILE, sizeof (XftFtFile) + strlen ((char *) file) + 1);
|
|
Packit Service |
1b8107 |
if (XftDebug () & XFT_DBG_REF)
|
|
Packit Service |
1b8107 |
printf ("FontFile %s/%d matches new\n",
|
|
Packit Service |
1b8107 |
file, id);
|
|
Packit Service |
1b8107 |
f->next = _XftFtFiles;
|
|
Packit Service |
1b8107 |
_XftFtFiles = f;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
f->ref = 1;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
f->file = (char *) (f+1);
|
|
Packit Service |
1b8107 |
strcpy (f->file, (char *) file);
|
|
Packit Service |
1b8107 |
f->id = id;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
f->lock = 0;
|
|
Packit Service |
1b8107 |
f->face = NULL;
|
|
Packit Service |
1b8107 |
f->xsize = 0;
|
|
Packit Service |
1b8107 |
f->ysize = 0;
|
|
Packit Service |
1b8107 |
f->matrix.xx = f->matrix.xy = f->matrix.yx = f->matrix.yy = 0;
|
|
Packit Service |
1b8107 |
return f;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
static XftFtFile *
|
|
Packit Service |
1b8107 |
_XftGetFaceFile (FT_Face face)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
XftFtFile *f;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
f = malloc (sizeof (XftFtFile));
|
|
Packit Service |
1b8107 |
if (!f)
|
|
Packit Service |
1b8107 |
return NULL;
|
|
Packit Service |
1b8107 |
XftMemAlloc (XFT_MEM_FILE, sizeof(XftFtFile));
|
|
Packit Service |
1b8107 |
f->next = NULL;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
f->ref = 1;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
f->file = NULL;
|
|
Packit Service |
1b8107 |
f->id = 0;
|
|
Packit Service |
1b8107 |
f->lock = 0;
|
|
Packit Service |
1b8107 |
f->face = face;
|
|
Packit Service |
1b8107 |
f->xsize = 0;
|
|
Packit Service |
1b8107 |
f->ysize = 0;
|
|
Packit Service |
1b8107 |
f->matrix.xx = f->matrix.xy = f->matrix.yx = f->matrix.yy = 0;
|
|
Packit Service |
1b8107 |
return f;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
static int
|
|
Packit Service |
1b8107 |
_XftNumFiles (void)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
XftFtFile *f;
|
|
Packit Service |
1b8107 |
int count = 0;
|
|
Packit Service |
1b8107 |
for (f = _XftFtFiles; f; f = f->next)
|
|
Packit Service |
1b8107 |
if (f->face && !f->lock)
|
|
Packit Service |
1b8107 |
++count;
|
|
Packit Service |
1b8107 |
return count;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
static XftFtFile *
|
|
Packit Service |
1b8107 |
_XftNthFile (int n)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
XftFtFile *f;
|
|
Packit Service |
1b8107 |
int count = 0;
|
|
Packit Service |
1b8107 |
for (f = _XftFtFiles; f; f = f->next)
|
|
Packit Service |
1b8107 |
if (f->face && !f->lock)
|
|
Packit Service |
1b8107 |
if (count++ == n)
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
return f;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
static void
|
|
Packit Service |
1b8107 |
_XftUncacheFiles (void)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
int n;
|
|
Packit Service |
1b8107 |
XftFtFile *f;
|
|
Packit Service |
1b8107 |
while ((n = _XftNumFiles ()) > XftMaxFreeTypeFiles)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
f = _XftNthFile (rand () % n);
|
|
Packit Service |
1b8107 |
if (f)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
if (XftDebug() & XFT_DBG_REF)
|
|
Packit Service |
1b8107 |
printf ("Discard file %s/%d from cache\n",
|
|
Packit Service |
1b8107 |
f->file, f->id);
|
|
Packit Service |
1b8107 |
FT_Done_Face (f->face);
|
|
Packit Service |
1b8107 |
f->face = NULL;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
static FT_Face
|
|
Packit Service |
1b8107 |
_XftLockFile (XftFtFile *f)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
++f->lock;
|
|
Packit Service |
1b8107 |
if (!f->face)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
if (XftDebug() & XFT_DBG_REF)
|
|
Packit Service |
1b8107 |
printf ("Loading file %s/%d\n", f->file, f->id);
|
|
Packit Service |
1b8107 |
if (FT_New_Face (_XftFTlibrary, f->file, f->id, &f->face))
|
|
Packit Service |
1b8107 |
--f->lock;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
f->xsize = 0;
|
|
Packit Service |
1b8107 |
f->ysize = 0;
|
|
Packit Service |
1b8107 |
f->matrix.xx = f->matrix.xy = f->matrix.yx = f->matrix.yy = 0;
|
|
Packit Service |
1b8107 |
_XftUncacheFiles ();
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
return f->face;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
static void
|
|
Packit Service |
1b8107 |
_XftLockError (const char *reason)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
fprintf (stderr, "Xft: locking error %s\n", reason);
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
static void
|
|
Packit Service |
1b8107 |
_XftUnlockFile (XftFtFile *f)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
if (--f->lock < 0)
|
|
Packit Service |
1b8107 |
_XftLockError ("too many file unlocks");
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
#define X_SIZE(face,i) ((face)->available_sizes[i].x_ppem)
|
|
Packit Service |
1b8107 |
#define Y_SIZE(face,i) ((face)->available_sizes[i].y_ppem)
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
_X_HIDDEN FcBool
|
|
Packit Service |
1b8107 |
_XftSetFace (XftFtFile *f, FT_F26Dot6 xsize, FT_F26Dot6 ysize, FT_Matrix *matrix)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
FT_Face face = f->face;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (f->xsize != xsize || f->ysize != ysize)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
if (XftDebug() & XFT_DBG_GLYPH)
|
|
Packit Service |
1b8107 |
printf ("Set face size to %dx%d (%dx%d)\n",
|
|
Packit Service |
1b8107 |
(int) (xsize >> 6), (int) (ysize >> 6), (int) xsize, (int) ysize);
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Bitmap only faces must match exactly, so find the closest
|
|
Packit Service |
1b8107 |
* one (height dominant search)
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
if (!(face->face_flags & FT_FACE_FLAG_SCALABLE))
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
int i, best = 0;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
#define xft_abs(a) ((a) < 0 ? -(a) : (a))
|
|
Packit Service |
1b8107 |
#define dist(a,b) (xft_abs((a)-(b)))
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
for (i = 1; i < face->num_fixed_sizes; i++)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
if (dist (ysize, Y_SIZE(face,i)) <
|
|
Packit Service |
1b8107 |
dist (ysize, Y_SIZE(face, best)) ||
|
|
Packit Service |
1b8107 |
(dist (ysize, Y_SIZE(face, i)) ==
|
|
Packit Service |
1b8107 |
dist (ysize, Y_SIZE(face, best)) &&
|
|
Packit Service |
1b8107 |
dist (xsize, X_SIZE(face, i)) <
|
|
Packit Service |
1b8107 |
dist (xsize, X_SIZE(face, best))))
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
best = i;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Freetype 2.1.7 and earlier used width/height
|
|
Packit Service |
1b8107 |
* for matching sizes in the BDF and PCF loaders.
|
|
Packit Service |
1b8107 |
* This has been fixed for 2.1.8. Because BDF and PCF
|
|
Packit Service |
1b8107 |
* files have but a single strike per file, we can
|
|
Packit Service |
1b8107 |
* simply try both sizes.
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
if (FT_Set_Char_Size (face, face->available_sizes[best].x_ppem,
|
|
Packit Service |
1b8107 |
face->available_sizes[best].y_ppem, 0, 0) != 0
|
|
Packit Service |
1b8107 |
&&
|
|
Packit Service |
1b8107 |
FT_Set_Char_Size (face, face->available_sizes[best].width << 6,
|
|
Packit Service |
1b8107 |
face->available_sizes[best].height << 6,
|
|
Packit Service |
1b8107 |
0, 0) != 0)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
return False;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
else
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
if (FT_Set_Char_Size (face, xsize, ysize, 0, 0))
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
return False;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
f->xsize = xsize;
|
|
Packit Service |
1b8107 |
f->ysize = ysize;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
if (!FT_Matrix_Equal (&f->matrix, matrix))
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
if (XftDebug() & XFT_DBG_GLYPH)
|
|
Packit Service |
1b8107 |
printf ("Set face matrix to (%g,%g,%g,%g)\n",
|
|
Packit Service |
1b8107 |
(double) matrix->xx / 0x10000,
|
|
Packit Service |
1b8107 |
(double) matrix->xy / 0x10000,
|
|
Packit Service |
1b8107 |
(double) matrix->yx / 0x10000,
|
|
Packit Service |
1b8107 |
(double) matrix->yy / 0x10000);
|
|
Packit Service |
1b8107 |
FT_Set_Transform (face, matrix, NULL);
|
|
Packit Service |
1b8107 |
f->matrix = *matrix;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
return True;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
static void
|
|
Packit Service |
1b8107 |
_XftReleaseFile (XftFtFile *f)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
XftFtFile **prev;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (--f->ref != 0)
|
|
Packit Service |
1b8107 |
return;
|
|
Packit Service |
1b8107 |
if (f->lock)
|
|
Packit Service |
1b8107 |
_XftLockError ("Attempt to close locked file");
|
|
Packit Service |
1b8107 |
if (f->file)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
for (prev = &_XftFtFiles; *prev; prev = &(*prev)->next)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
if (*prev == f)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
*prev = f->next;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
if (f->face)
|
|
Packit Service |
1b8107 |
FT_Done_Face (f->face);
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
XftMemFree (XFT_MEM_FILE,
|
|
Packit Service |
1b8107 |
sizeof (XftFtFile) + (f->file ? strlen (f->file) + 1 : 0));
|
|
Packit Service |
1b8107 |
free (f);
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Find a prime larger than the minimum reasonable hash size
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
static FcChar32
|
|
Packit Service |
1b8107 |
_XftSqrt (FcChar32 a)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
FcChar32 l, h, m;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
l = 2;
|
|
Packit Service |
1b8107 |
h = a/2;
|
|
Packit Service |
1b8107 |
while ((h-l) > 1)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
m = (h+l) >> 1;
|
|
Packit Service |
1b8107 |
if (m * m < a)
|
|
Packit Service |
1b8107 |
l = m;
|
|
Packit Service |
1b8107 |
else
|
|
Packit Service |
1b8107 |
h = m;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
return h;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
static FcBool
|
|
Packit Service |
1b8107 |
_XftIsPrime (FcChar32 i)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
FcChar32 l, t;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (i < 2)
|
|
Packit Service |
1b8107 |
return FcFalse;
|
|
Packit Service |
1b8107 |
if ((i & 1) == 0)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
if (i == 2)
|
|
Packit Service |
1b8107 |
return FcTrue;
|
|
Packit Service |
1b8107 |
return FcFalse;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
l = _XftSqrt (i) + 1;
|
|
Packit Service |
1b8107 |
for (t = 3; t <= l; t += 2)
|
|
Packit Service |
1b8107 |
if (i % t == 0)
|
|
Packit Service |
1b8107 |
return FcFalse;
|
|
Packit Service |
1b8107 |
return FcTrue;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
static FcChar32
|
|
Packit Service |
1b8107 |
_XftHashSize (FcChar32 num_unicode)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
/* at least 31.25 % extra space */
|
|
Packit Service |
1b8107 |
FcChar32 hash = num_unicode + (num_unicode >> 2) + (num_unicode >> 4);
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if ((hash & 1) == 0)
|
|
Packit Service |
1b8107 |
hash++;
|
|
Packit Service |
1b8107 |
while (!_XftIsPrime (hash))
|
|
Packit Service |
1b8107 |
hash += 2;
|
|
Packit Service |
1b8107 |
return hash;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
_X_EXPORT FT_Face
|
|
Packit Service |
1b8107 |
XftLockFace (XftFont *public)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
XftFontInt *font = (XftFontInt *) public;
|
|
Packit Service |
1b8107 |
XftFontInfo *fi = &font->info;
|
|
Packit Service |
1b8107 |
FT_Face face;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
face = _XftLockFile (fi->file);
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Make sure the face is usable at the requested size
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
if (face && !_XftSetFace (fi->file, fi->xsize, fi->ysize, &fi->matrix))
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
_XftUnlockFile (fi->file);
|
|
Packit Service |
1b8107 |
face = NULL;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
return face;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
_X_EXPORT void
|
|
Packit Service |
1b8107 |
XftUnlockFace (XftFont *public)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
XftFontInt *font = (XftFontInt *) public;
|
|
Packit Service |
1b8107 |
_XftUnlockFile (font->info.file);
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
static FcBool
|
|
Packit Service |
1b8107 |
XftFontInfoFill (Display *dpy, _Xconst FcPattern *pattern, XftFontInfo *fi)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
XftDisplayInfo *info = _XftDisplayInfoGet (dpy, True);
|
|
Packit Service |
1b8107 |
FcChar8 *filename;
|
|
Packit Service |
1b8107 |
int id;
|
|
Packit Service |
1b8107 |
double dsize;
|
|
Packit Service |
1b8107 |
double aspect;
|
|
Packit Service |
1b8107 |
FcMatrix *font_matrix;
|
|
Packit Service |
1b8107 |
FcBool hinting, vertical_layout, autohint, global_advance;
|
|
Packit Service |
1b8107 |
int hint_style;
|
|
Packit Service |
1b8107 |
FcChar32 hash, *hashp;
|
|
Packit Service |
1b8107 |
FT_Face face;
|
|
Packit Service |
1b8107 |
int nhash;
|
|
Packit Service |
1b8107 |
FcBool bitmap;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (!info)
|
|
Packit Service |
1b8107 |
return FcFalse;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Initialize the whole XftFontInfo so that padding doesn't interfere with
|
|
Packit Service |
1b8107 |
* hash or XftFontInfoEqual().
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
memset (fi, '\0', sizeof(*fi));
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Find the associated file
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
switch (FcPatternGetString (pattern, FC_FILE, 0, &filename)) {
|
|
Packit Service |
1b8107 |
case FcResultNoMatch:
|
|
Packit Service |
1b8107 |
filename = NULL;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
case FcResultMatch:
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
default:
|
|
Packit Service |
1b8107 |
goto bail0;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
switch (FcPatternGetInteger (pattern, FC_INDEX, 0, &id)) {
|
|
Packit Service |
1b8107 |
case FcResultNoMatch:
|
|
Packit Service |
1b8107 |
id = 0;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
case FcResultMatch:
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
default:
|
|
Packit Service |
1b8107 |
goto bail0;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (filename)
|
|
Packit Service |
1b8107 |
fi->file = _XftGetFile (filename, id);
|
|
Packit Service |
1b8107 |
else if (FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &face) == FcResultMatch
|
|
Packit Service |
1b8107 |
&& face)
|
|
Packit Service |
1b8107 |
fi->file = _XftGetFaceFile (face);
|
|
Packit Service |
1b8107 |
if (!fi->file)
|
|
Packit Service |
1b8107 |
goto bail0;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Compute pixel size
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
if (FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &dsize) != FcResultMatch)
|
|
Packit Service |
1b8107 |
goto bail1;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (FcPatternGetDouble (pattern, FC_ASPECT, 0, &aspect) != FcResultMatch)
|
|
Packit Service |
1b8107 |
aspect = 1.0;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
fi->ysize = (FT_F26Dot6) (dsize * 64.0);
|
|
Packit Service |
1b8107 |
fi->xsize = (FT_F26Dot6) (dsize * aspect * 64.0);
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (XftDebug() & XFT_DBG_OPEN)
|
|
Packit Service |
1b8107 |
printf ("XftFontInfoFill: %s: %d (%g pixels)\n",
|
|
Packit Service |
1b8107 |
(filename ? filename : (FcChar8 *) "<none>"), id, dsize);
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Get antialias value
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
switch (FcPatternGetBool (pattern, FC_ANTIALIAS, 0, &fi->antialias)) {
|
|
Packit Service |
1b8107 |
case FcResultNoMatch:
|
|
Packit Service |
1b8107 |
fi->antialias = True;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
case FcResultMatch:
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
default:
|
|
Packit Service |
1b8107 |
goto bail1;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Get rgba value
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
switch (FcPatternGetInteger (pattern, FC_RGBA, 0, &fi->rgba)) {
|
|
Packit Service |
1b8107 |
case FcResultNoMatch:
|
|
Packit Service |
1b8107 |
fi->rgba = FC_RGBA_UNKNOWN;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
case FcResultMatch:
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
default:
|
|
Packit Service |
1b8107 |
goto bail1;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Get lcd_filter value
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
switch (FcPatternGetInteger (pattern, FC_LCD_FILTER, 0, &fi->lcd_filter)) {
|
|
Packit Service |
1b8107 |
case FcResultNoMatch:
|
|
Packit Service |
1b8107 |
fi->lcd_filter = FC_LCD_DEFAULT;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
case FcResultMatch:
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
default:
|
|
Packit Service |
1b8107 |
goto bail1;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Get matrix and transform values
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
switch (FcPatternGetMatrix (pattern, FC_MATRIX, 0, &font_matrix)) {
|
|
Packit Service |
1b8107 |
case FcResultNoMatch:
|
|
Packit Service |
1b8107 |
fi->matrix.xx = fi->matrix.yy = 0x10000;
|
|
Packit Service |
1b8107 |
fi->matrix.xy = fi->matrix.yx = 0;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
case FcResultMatch:
|
|
Packit Service |
1b8107 |
fi->matrix.xx = 0x10000L * font_matrix->xx;
|
|
Packit Service |
1b8107 |
fi->matrix.yy = 0x10000L * font_matrix->yy;
|
|
Packit Service |
1b8107 |
fi->matrix.xy = 0x10000L * font_matrix->xy;
|
|
Packit Service |
1b8107 |
fi->matrix.yx = 0x10000L * font_matrix->yx;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
default:
|
|
Packit Service |
1b8107 |
goto bail1;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
fi->transform = (fi->matrix.xx != 0x10000 || fi->matrix.xy != 0 ||
|
|
Packit Service |
1b8107 |
fi->matrix.yx != 0 || fi->matrix.yy != 0x10000);
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Get render value, set to false if no Render extension present
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
if (info->hasRender)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
switch (FcPatternGetBool (pattern, XFT_RENDER, 0, &fi->render)) {
|
|
Packit Service |
1b8107 |
case FcResultNoMatch:
|
|
Packit Service |
1b8107 |
fi->render = info->hasRender;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
case FcResultMatch:
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
default:
|
|
Packit Service |
1b8107 |
goto bail1;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
else
|
|
Packit Service |
1b8107 |
fi->render = FcFalse;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Compute glyph load flags
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
fi->load_flags = FT_LOAD_DEFAULT;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
#ifndef XFT_EMBEDDED_BITMAP
|
|
Packit Service |
1b8107 |
#define XFT_EMBEDDED_BITMAP "embeddedbitmap"
|
|
Packit Service |
1b8107 |
#endif
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
switch (FcPatternGetBool (pattern, XFT_EMBEDDED_BITMAP, 0, &bitmap)) {
|
|
Packit Service |
1b8107 |
case FcResultNoMatch:
|
|
Packit Service |
1b8107 |
bitmap = FcFalse;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
case FcResultMatch:
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
default:
|
|
Packit Service |
1b8107 |
goto bail1;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/* disable bitmaps when anti-aliasing or transforming glyphs */
|
|
Packit Service |
1b8107 |
if ((!bitmap && fi->antialias) || fi->transform)
|
|
Packit Service |
1b8107 |
fi->load_flags |= FT_LOAD_NO_BITMAP;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/* disable hinting if requested */
|
|
Packit Service |
1b8107 |
switch (FcPatternGetBool (pattern, FC_HINTING, 0, &hinting)) {
|
|
Packit Service |
1b8107 |
case FcResultNoMatch:
|
|
Packit Service |
1b8107 |
hinting = FcTrue;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
case FcResultMatch:
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
default:
|
|
Packit Service |
1b8107 |
goto bail1;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
switch (FcPatternGetBool (pattern, FC_EMBOLDEN, 0, &fi->embolden)) {
|
|
Packit Service |
1b8107 |
case FcResultNoMatch:
|
|
Packit Service |
1b8107 |
fi->embolden = FcFalse;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
case FcResultMatch:
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
default:
|
|
Packit Service |
1b8107 |
goto bail1;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
switch (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hint_style)) {
|
|
Packit Service |
1b8107 |
case FcResultNoMatch:
|
|
Packit Service |
1b8107 |
hint_style = FC_HINT_FULL;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
case FcResultMatch:
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
default:
|
|
Packit Service |
1b8107 |
goto bail1;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (!hinting
|
|
Packit Service |
1b8107 |
|| hint_style == FC_HINT_NONE
|
|
Packit Service |
1b8107 |
)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
fi->load_flags |= FT_LOAD_NO_HINTING;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/* Figure out the load target, which modifies the hinting
|
|
Packit Service |
1b8107 |
* behavior of FreeType based on the intended use of the glyphs.
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
if (fi->antialias)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
if (FC_HINT_NONE < hint_style && hint_style < FC_HINT_FULL)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
fi->load_flags |= FT_LOAD_TARGET_LIGHT;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
else
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
/* autohinter will snap stems to integer widths, when
|
|
Packit Service |
1b8107 |
* the LCD targets are used.
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
switch (fi->rgba) {
|
|
Packit Service |
1b8107 |
case FC_RGBA_RGB:
|
|
Packit Service |
1b8107 |
case FC_RGBA_BGR:
|
|
Packit Service |
1b8107 |
fi->load_flags |= FT_LOAD_TARGET_LCD;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
case FC_RGBA_VRGB:
|
|
Packit Service |
1b8107 |
case FC_RGBA_VBGR:
|
|
Packit Service |
1b8107 |
fi->load_flags |= FT_LOAD_TARGET_LCD_V;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
else
|
|
Packit Service |
1b8107 |
fi->load_flags |= FT_LOAD_TARGET_MONO;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/* set vertical layout if requested */
|
|
Packit Service |
1b8107 |
switch (FcPatternGetBool (pattern, FC_VERTICAL_LAYOUT, 0, &vertical_layout)) {
|
|
Packit Service |
1b8107 |
case FcResultNoMatch:
|
|
Packit Service |
1b8107 |
vertical_layout = FcFalse;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
case FcResultMatch:
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
default:
|
|
Packit Service |
1b8107 |
goto bail1;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (vertical_layout)
|
|
Packit Service |
1b8107 |
fi->load_flags |= FT_LOAD_VERTICAL_LAYOUT;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/* force autohinting if requested */
|
|
Packit Service |
1b8107 |
switch (FcPatternGetBool (pattern, FC_AUTOHINT, 0, &autohint)) {
|
|
Packit Service |
1b8107 |
case FcResultNoMatch:
|
|
Packit Service |
1b8107 |
autohint = FcFalse;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
case FcResultMatch:
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
default:
|
|
Packit Service |
1b8107 |
goto bail1;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (autohint)
|
|
Packit Service |
1b8107 |
fi->load_flags |= FT_LOAD_FORCE_AUTOHINT;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/* disable global advance width (for broken DynaLab TT CJK fonts) */
|
|
Packit Service |
1b8107 |
switch (FcPatternGetBool (pattern, FC_GLOBAL_ADVANCE, 0, &global_advance)) {
|
|
Packit Service |
1b8107 |
case FcResultNoMatch:
|
|
Packit Service |
1b8107 |
global_advance = FcTrue;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
case FcResultMatch:
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
default:
|
|
Packit Service |
1b8107 |
goto bail1;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (!global_advance)
|
|
Packit Service |
1b8107 |
fi->load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Get requested spacing value
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
switch (FcPatternGetInteger (pattern, FC_SPACING, 0, &fi->spacing)) {
|
|
Packit Service |
1b8107 |
case FcResultNoMatch:
|
|
Packit Service |
1b8107 |
fi->spacing = FC_PROPORTIONAL;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
case FcResultMatch:
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
default:
|
|
Packit Service |
1b8107 |
goto bail1;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Check for minspace
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
switch (FcPatternGetBool (pattern, FC_MINSPACE, 0, &fi->minspace)) {
|
|
Packit Service |
1b8107 |
case FcResultNoMatch:
|
|
Packit Service |
1b8107 |
fi->minspace = FcFalse;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
case FcResultMatch:
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
default:
|
|
Packit Service |
1b8107 |
goto bail1;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Check for fixed pixel spacing
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
switch (FcPatternGetInteger (pattern, FC_CHAR_WIDTH, 0, &fi->char_width)) {
|
|
Packit Service |
1b8107 |
case FcResultNoMatch:
|
|
Packit Service |
1b8107 |
fi->char_width = 0;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
case FcResultMatch:
|
|
Packit Service |
1b8107 |
if (fi->char_width)
|
|
Packit Service |
1b8107 |
fi->spacing = FC_MONO;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
default:
|
|
Packit Service |
1b8107 |
goto bail1;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Step over hash value in the structure
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
hash = 0;
|
|
Packit Service |
1b8107 |
hashp = (FcChar32 *) fi + 1;
|
|
Packit Service |
1b8107 |
nhash = (sizeof (XftFontInfo) / sizeof (FcChar32)) - 1;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
while (nhash--)
|
|
Packit Service |
1b8107 |
hash += *hashp++;
|
|
Packit Service |
1b8107 |
fi->hash = hash;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* All done
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
return FcTrue;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
bail1:
|
|
Packit Service |
1b8107 |
_XftReleaseFile (fi->file);
|
|
Packit Service |
1b8107 |
fi->file = NULL;
|
|
Packit Service |
1b8107 |
bail0:
|
|
Packit Service |
1b8107 |
return FcFalse;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
static void
|
|
Packit Service |
1b8107 |
XftFontInfoEmpty (Display *dpy, XftFontInfo *fi)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
if (fi->file)
|
|
Packit Service |
1b8107 |
_XftReleaseFile (fi->file);
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
XftFontInfo *
|
|
Packit Service |
1b8107 |
XftFontInfoCreate (Display *dpy, _Xconst FcPattern *pattern)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
XftFontInfo *fi = malloc (sizeof (XftFontInfo));
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (!fi)
|
|
Packit Service |
1b8107 |
return NULL;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (!XftFontInfoFill (dpy, pattern, fi))
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
free (fi);
|
|
Packit Service |
1b8107 |
fi = NULL;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
XftMemAlloc (XFT_MEM_FONT, sizeof (XftFontInfo));
|
|
Packit Service |
1b8107 |
return fi;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
_X_EXPORT void
|
|
Packit Service |
1b8107 |
XftFontInfoDestroy (Display *dpy, XftFontInfo *fi)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
XftFontInfoEmpty (dpy, fi);
|
|
Packit Service |
1b8107 |
XftMemFree (XFT_MEM_FONT, sizeof (XftFontInfo));
|
|
Packit Service |
1b8107 |
free (fi);
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
_X_EXPORT FcChar32
|
|
Packit Service |
1b8107 |
XftFontInfoHash (_Xconst XftFontInfo *fi)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
return fi->hash;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
_X_EXPORT FcBool
|
|
Packit Service |
1b8107 |
XftFontInfoEqual (_Xconst XftFontInfo *a, _Xconst XftFontInfo *b)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
return memcmp ((void *) a, (void *) b, sizeof (XftFontInfo)) == 0;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
_X_EXPORT XftFont *
|
|
Packit Service |
1b8107 |
XftFontOpenInfo (Display *dpy,
|
|
Packit Service |
1b8107 |
FcPattern *pattern,
|
|
Packit Service |
1b8107 |
XftFontInfo *fi)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
XftDisplayInfo *info = _XftDisplayInfoGet (dpy, True);
|
|
Packit Service |
1b8107 |
FT_Face face;
|
|
Packit Service |
1b8107 |
XftFont **bucket;
|
|
Packit Service |
1b8107 |
XftFontInt *font;
|
|
Packit Service |
1b8107 |
XRenderPictFormat *format;
|
|
Packit Service |
1b8107 |
FcCharSet *charset;
|
|
Packit Service |
1b8107 |
FcChar32 num_unicode;
|
|
Packit Service |
1b8107 |
FcChar32 hash_value;
|
|
Packit Service |
1b8107 |
FcChar32 rehash_value;
|
|
Packit Service |
1b8107 |
FcBool antialias;
|
|
Packit Service |
1b8107 |
int max_glyph_memory;
|
|
Packit Service |
1b8107 |
int alloc_size;
|
|
Packit Service |
1b8107 |
int ascent, descent, height;
|
|
Packit Service |
1b8107 |
int i;
|
|
Packit Service |
1b8107 |
int num_glyphs;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (!info)
|
|
Packit Service |
1b8107 |
return NULL;
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Find a matching previously opened font
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
bucket = &info->fontHash[fi->hash % XFT_NUM_FONT_HASH];
|
|
Packit Service |
1b8107 |
for (font = (XftFontInt *) *bucket; font; font = (XftFontInt *) font->hash_next)
|
|
Packit Service |
1b8107 |
if (XftFontInfoEqual (&font->info, fi))
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
if (!font->ref++)
|
|
Packit Service |
1b8107 |
--info->num_unref_fonts;
|
|
Packit Service |
1b8107 |
FcPatternDestroy (pattern);
|
|
Packit Service |
1b8107 |
return &font->public;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* No existing font, create another.
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (XftDebug () & XFT_DBG_CACHE)
|
|
Packit Service |
1b8107 |
printf ("New font %s/%d size %dx%d\n",
|
|
Packit Service |
1b8107 |
fi->file->file, fi->file->id,
|
|
Packit Service |
1b8107 |
(int) fi->xsize >> 6, (int) fi->ysize >> 6);
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (FcPatternGetInteger (pattern, XFT_MAX_GLYPH_MEMORY, 0,
|
|
Packit Service |
1b8107 |
&max_glyph_memory) != FcResultMatch)
|
|
Packit Service |
1b8107 |
max_glyph_memory = XFT_FONT_MAX_GLYPH_MEMORY;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
face = _XftLockFile (fi->file);
|
|
Packit Service |
1b8107 |
if (!face)
|
|
Packit Service |
1b8107 |
goto bail0;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (!_XftSetFace (fi->file, fi->xsize, fi->ysize, &fi->matrix))
|
|
Packit Service |
1b8107 |
goto bail1;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Get the set of Unicode codepoints covered by the font.
|
|
Packit Service |
1b8107 |
* If the incoming pattern doesn't provide this data, go
|
|
Packit Service |
1b8107 |
* off and compute it. Yes, this is expensive, but it's
|
|
Packit Service |
1b8107 |
* required to map Unicode to glyph indices.
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
if (FcPatternGetCharSet (pattern, FC_CHARSET, 0, &charset) == FcResultMatch)
|
|
Packit Service |
1b8107 |
charset = FcCharSetCopy (charset);
|
|
Packit Service |
1b8107 |
else
|
|
Packit Service |
1b8107 |
charset = FcFreeTypeCharSet (face, FcConfigGetBlanks (NULL));
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
antialias = fi->antialias;
|
|
Packit Service |
1b8107 |
if (!(face->face_flags & FT_FACE_FLAG_SCALABLE))
|
|
Packit Service |
1b8107 |
antialias = FcFalse;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Find the appropriate picture format
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
if (fi->render)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
if (antialias)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
switch (fi->rgba) {
|
|
Packit Service |
1b8107 |
case FC_RGBA_RGB:
|
|
Packit Service |
1b8107 |
case FC_RGBA_BGR:
|
|
Packit Service |
1b8107 |
case FC_RGBA_VRGB:
|
|
Packit Service |
1b8107 |
case FC_RGBA_VBGR:
|
|
Packit Service |
1b8107 |
format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
default:
|
|
Packit Service |
1b8107 |
format = XRenderFindStandardFormat (dpy, PictStandardA8);
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
else
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
format = XRenderFindStandardFormat (dpy, PictStandardA1);
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (!format)
|
|
Packit Service |
1b8107 |
goto bail2;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
else
|
|
Packit Service |
1b8107 |
format = NULL;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (charset)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
num_unicode = FcCharSetCount (charset);
|
|
Packit Service |
1b8107 |
hash_value = _XftHashSize (num_unicode);
|
|
Packit Service |
1b8107 |
rehash_value = hash_value - 2;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
else
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
num_unicode = 0;
|
|
Packit Service |
1b8107 |
hash_value = 0;
|
|
Packit Service |
1b8107 |
rehash_value = 0;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Sometimes the glyphs are numbered 1..n, other times 0..n-1,
|
|
Packit Service |
1b8107 |
* accept either numbering scheme by making room in the table
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
num_glyphs = face->num_glyphs + 1;
|
|
Packit Service |
1b8107 |
alloc_size = (sizeof (XftFontInt) +
|
|
Packit Service |
1b8107 |
num_glyphs * sizeof (XftGlyph *) +
|
|
Packit Service |
1b8107 |
hash_value * sizeof (XftUcsHash));
|
|
Packit Service |
1b8107 |
font = malloc (alloc_size);
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (!font)
|
|
Packit Service |
1b8107 |
goto bail2;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
XftMemAlloc (XFT_MEM_FONT, alloc_size);
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Public fields
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
if (fi->transform)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
FT_Vector vector;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
vector.x = 0;
|
|
Packit Service |
1b8107 |
vector.y = face->size->metrics.descender;
|
|
Packit Service |
1b8107 |
FT_Vector_Transform (&vector, &fi->matrix);
|
|
Packit Service |
1b8107 |
descent = -(vector.y >> 6);
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
vector.x = 0;
|
|
Packit Service |
1b8107 |
vector.y = face->size->metrics.ascender;
|
|
Packit Service |
1b8107 |
FT_Vector_Transform (&vector, &fi->matrix);
|
|
Packit Service |
1b8107 |
ascent = vector.y >> 6;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (fi->minspace)
|
|
Packit Service |
1b8107 |
height = ascent + descent;
|
|
Packit Service |
1b8107 |
else
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
vector.x = 0;
|
|
Packit Service |
1b8107 |
vector.y = face->size->metrics.height;
|
|
Packit Service |
1b8107 |
FT_Vector_Transform (&vector, &fi->matrix);
|
|
Packit Service |
1b8107 |
height = vector.y >> 6;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
else
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
descent = -(face->size->metrics.descender >> 6);
|
|
Packit Service |
1b8107 |
ascent = face->size->metrics.ascender >> 6;
|
|
Packit Service |
1b8107 |
if (fi->minspace)
|
|
Packit Service |
1b8107 |
height = ascent + descent;
|
|
Packit Service |
1b8107 |
else
|
|
Packit Service |
1b8107 |
height = face->size->metrics.height >> 6;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
font->public.ascent = ascent;
|
|
Packit Service |
1b8107 |
font->public.descent = descent;
|
|
Packit Service |
1b8107 |
font->public.height = height;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (fi->char_width)
|
|
Packit Service |
1b8107 |
font->public.max_advance_width = fi->char_width;
|
|
Packit Service |
1b8107 |
else
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
if (fi->transform)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
FT_Vector vector;
|
|
Packit Service |
1b8107 |
vector.x = face->size->metrics.max_advance;
|
|
Packit Service |
1b8107 |
vector.y = 0;
|
|
Packit Service |
1b8107 |
FT_Vector_Transform (&vector, &fi->matrix);
|
|
Packit Service |
1b8107 |
font->public.max_advance_width = vector.x >> 6;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
else
|
|
Packit Service |
1b8107 |
font->public.max_advance_width = face->size->metrics.max_advance >> 6;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
font->public.charset = charset;
|
|
Packit Service |
1b8107 |
font->public.pattern = pattern;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Management fields
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
font->ref = 1;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
font->next = info->fonts;
|
|
Packit Service |
1b8107 |
info->fonts = &font->public;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
font->hash_next = *bucket;
|
|
Packit Service |
1b8107 |
*bucket = &font->public;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Copy the info over
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
font->info = *fi;
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* reset the antialias field. It can't
|
|
Packit Service |
1b8107 |
* be set correctly until the font is opened,
|
|
Packit Service |
1b8107 |
* which doesn't happen in XftFontInfoFill
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
font->info.antialias = antialias;
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* bump XftFile reference count
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
font->info.file->ref++;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Per glyph information
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
font->glyphs = (XftGlyph **) (font + 1);
|
|
Packit Service |
1b8107 |
memset (font->glyphs, '\0', num_glyphs * sizeof (XftGlyph *));
|
|
Packit Service |
1b8107 |
font->num_glyphs = num_glyphs;
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Unicode hash table information
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
font->hash_table = (XftUcsHash *) (font->glyphs + font->num_glyphs);
|
|
Packit Service |
1b8107 |
for (i = 0; i < hash_value; i++)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
font->hash_table[i].ucs4 = ((FcChar32) ~0);
|
|
Packit Service |
1b8107 |
font->hash_table[i].glyph = 0;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
font->hash_value = hash_value;
|
|
Packit Service |
1b8107 |
font->rehash_value = rehash_value;
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* X specific fields
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
font->glyphset = 0;
|
|
Packit Service |
1b8107 |
font->format = format;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/*
|
|
Packit Service |
1b8107 |
* Glyph memory management fields
|
|
Packit Service |
1b8107 |
*/
|
|
Packit Service |
1b8107 |
font->glyph_memory = 0;
|
|
Packit Service |
1b8107 |
font->max_glyph_memory = max_glyph_memory;
|
|
Packit Service |
1b8107 |
font->use_free_glyphs = info->use_free_glyphs;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
_XftUnlockFile (fi->file);
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
return &font->public;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
bail2:
|
|
Packit Service |
1b8107 |
FcCharSetDestroy (charset);
|
|
Packit Service |
1b8107 |
bail1:
|
|
Packit Service |
1b8107 |
_XftUnlockFile (fi->file);
|
|
Packit Service |
1b8107 |
bail0:
|
|
Packit Service |
1b8107 |
return NULL;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
_X_EXPORT XftFont *
|
|
Packit Service |
1b8107 |
XftFontOpenPattern (Display *dpy, FcPattern *pattern)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
XftFontInfo info;
|
|
Packit Service |
1b8107 |
XftFont *font;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (!XftFontInfoFill (dpy, pattern, &info))
|
|
Packit Service |
1b8107 |
return NULL;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
font = XftFontOpenInfo (dpy, pattern, &info;;
|
|
Packit Service |
1b8107 |
XftFontInfoEmpty (dpy, &info;;
|
|
Packit Service |
1b8107 |
return font;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
_X_EXPORT XftFont *
|
|
Packit Service |
1b8107 |
XftFontCopy (Display *dpy, XftFont *public)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
XftFontInt *font = (XftFontInt *) public;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
font->ref++;
|
|
Packit Service |
1b8107 |
return public;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
static void
|
|
Packit Service |
1b8107 |
XftFontDestroy (Display *dpy, XftFont *public)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
XftDisplayInfo *info = _XftDisplayInfoGet (dpy, False);
|
|
Packit Service |
1b8107 |
XftFontInt *font = (XftFontInt *) public;
|
|
Packit Service |
1b8107 |
int i;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/* note reduction in memory use */
|
|
Packit Service |
1b8107 |
if (info)
|
|
Packit Service |
1b8107 |
info->glyph_memory -= font->glyph_memory;
|
|
Packit Service |
1b8107 |
/* Clean up the info */
|
|
Packit Service |
1b8107 |
XftFontInfoEmpty (dpy, &font->info);
|
|
Packit Service |
1b8107 |
/* Free the glyphset */
|
|
Packit Service |
1b8107 |
if (font->glyphset)
|
|
Packit Service |
1b8107 |
XRenderFreeGlyphSet (dpy, font->glyphset);
|
|
Packit Service |
1b8107 |
/* Free the glyphs */
|
|
Packit Service |
1b8107 |
for (i = 0; i < font->num_glyphs; i++)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
XftGlyph *xftg = font->glyphs[i];
|
|
Packit Service |
1b8107 |
if (xftg)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
if (xftg->bitmap)
|
|
Packit Service |
1b8107 |
free (xftg->bitmap);
|
|
Packit Service |
1b8107 |
free (xftg);
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/* Free the pattern and the charset */
|
|
Packit Service |
1b8107 |
FcPatternDestroy (font->public.pattern);
|
|
Packit Service |
1b8107 |
FcCharSetDestroy (font->public.charset);
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/* Finally, free the font structure */
|
|
Packit Service |
1b8107 |
XftMemFree (XFT_MEM_FONT, sizeof (XftFontInt) +
|
|
Packit Service |
1b8107 |
font->num_glyphs * sizeof (XftGlyph *) +
|
|
Packit Service |
1b8107 |
font->hash_value * sizeof (XftUcsHash));
|
|
Packit Service |
1b8107 |
free (font);
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
static XftFont *
|
|
Packit Service |
1b8107 |
XftFontFindNthUnref (XftDisplayInfo *info, int n)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
XftFont *public;
|
|
Packit Service |
1b8107 |
XftFontInt *font;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
for (public = info->fonts; public; public = font->next)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
font = (XftFontInt*) public;
|
|
Packit Service |
1b8107 |
if (!font->ref && !n--)
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
return public;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
_X_HIDDEN void
|
|
Packit Service |
1b8107 |
XftFontManageMemory (Display *dpy)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
XftDisplayInfo *info = _XftDisplayInfoGet (dpy, False);
|
|
Packit Service |
1b8107 |
XftFont **prev;
|
|
Packit Service |
1b8107 |
XftFont *public;
|
|
Packit Service |
1b8107 |
XftFontInt *font;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (!info)
|
|
Packit Service |
1b8107 |
return;
|
|
Packit Service |
1b8107 |
while (info->num_unref_fonts > info->max_unref_fonts)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
public = XftFontFindNthUnref (info, rand() % info->num_unref_fonts);
|
|
Packit Service |
1b8107 |
font = (XftFontInt *) public;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (XftDebug () & XFT_DBG_CACHE)
|
|
Packit Service |
1b8107 |
printf ("freeing unreferenced font %s/%d size %dx%d\n",
|
|
Packit Service |
1b8107 |
font->info.file->file, font->info.file->id,
|
|
Packit Service |
1b8107 |
(int) font->info.xsize >> 6, (int) font->info.ysize >> 6);
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
/* Unhook from display list */
|
|
Packit Service |
1b8107 |
for (prev = &info->fonts; *prev; prev = &(*(XftFontInt **) prev)->next)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
if (*prev == public)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
*prev = font->next;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
/* Unhook from hash list */
|
|
Packit Service |
1b8107 |
for (prev = &info->fontHash[font->info.hash % XFT_NUM_FONT_HASH];
|
|
Packit Service |
1b8107 |
*prev;
|
|
Packit Service |
1b8107 |
prev = &(*(XftFontInt **) prev)->hash_next)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
if (*prev == public)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
*prev = font->hash_next;
|
|
Packit Service |
1b8107 |
break;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
/* Destroy the font */
|
|
Packit Service |
1b8107 |
XftFontDestroy (dpy, public);
|
|
Packit Service |
1b8107 |
--info->num_unref_fonts;
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
_X_EXPORT void
|
|
Packit Service |
1b8107 |
XftFontClose (Display *dpy, XftFont *public)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
XftDisplayInfo *info = _XftDisplayInfoGet (dpy, False);
|
|
Packit Service |
1b8107 |
XftFontInt *font = (XftFontInt *) public;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (--font->ref != 0)
|
|
Packit Service |
1b8107 |
return;
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
if (info)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
++info->num_unref_fonts;
|
|
Packit Service |
1b8107 |
XftFontManageMemory (dpy);
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
else
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
XftFontDestroy (dpy, public);
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
}
|
|
Packit Service |
1b8107 |
|
|
Packit Service |
1b8107 |
_X_EXPORT FcBool
|
|
Packit Service |
1b8107 |
XftInitFtLibrary (void)
|
|
Packit Service |
1b8107 |
{
|
|
Packit Service |
1b8107 |
if (_XftFTlibrary)
|
|
Packit Service |
1b8107 |
return FcTrue;
|
|
Packit Service |
1b8107 |
if (FT_Init_FreeType (&_XftFTlibrary))
|
|
Packit Service |
1b8107 |
return FcFalse;
|
|
Packit Service |
1b8107 |
return FcTrue;
|
|
Packit Service |
1b8107 |
}
|