diff options
author | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2015-02-02 15:02:49 +0100 |
---|---|---|
committer | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2015-02-02 15:02:49 +0100 |
commit | b16b9e4656e7199c2aec74a4c8ebc7a875d3ba73 (patch) | |
tree | 4361edef0d42d5bf5ac984ef72b4fac35426eae7 /nx-X11/lib/Xft/xftfreetype.c | |
parent | 0d5a83e986f39982c0924652a3662e60b1f23162 (diff) | |
download | nx-libs-b16b9e4656e7199c2aec74a4c8ebc7a875d3ba73.tar.gz nx-libs-b16b9e4656e7199c2aec74a4c8ebc7a875d3ba73.tar.bz2 nx-libs-b16b9e4656e7199c2aec74a4c8ebc7a875d3ba73.zip |
massive reduction of unneeded files
Diffstat (limited to 'nx-X11/lib/Xft/xftfreetype.c')
-rw-r--r-- | nx-X11/lib/Xft/xftfreetype.c | 1156 |
1 files changed, 0 insertions, 1156 deletions
diff --git a/nx-X11/lib/Xft/xftfreetype.c b/nx-X11/lib/Xft/xftfreetype.c deleted file mode 100644 index abc7c8556..000000000 --- a/nx-X11/lib/Xft/xftfreetype.c +++ /dev/null @@ -1,1156 +0,0 @@ -/* - * $Id: xftfreetype.c,v 1.5 2005/07/03 07:00:57 daniels Exp $ - * - * Copyright © 2000 Keith Packard - * - * 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 "xftint.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, (char *) 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, (char *) file); - f->id = id; - - f->lock = 0; - f->face = 0; - f->xsize = 0; - f->ysize = 0; - f->matrix.xx = f->matrix.xy = f->matrix.yx = f->matrix.yy = 0; - return f; -} - -static XftFtFile * -_XftGetFaceFile (FT_Face face) -{ - XftFtFile *f; - - f = malloc (sizeof (XftFtFile)); - if (!f) - return 0; - XftMemAlloc (XFT_MEM_FILE, sizeof(XftFtFile)); - f->next = 0; - - f->ref = 1; - - f->file = 0; - f->id = 0; - f->lock = 0; - f->face = face; - f->xsize = 0; - f->ysize = 0; - f->matrix.xx = f->matrix.xy = f->matrix.yx = f->matrix.yy = 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->xsize = 0; - f->ysize = 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"); -} - -#if HAVE_FT_BITMAP_SIZE_Y_PPEM -#define X_SIZE(face,i) ((face)->available_sizes[i].x_ppem) -#define Y_SIZE(face,i) ((face)->available_sizes[i].y_ppem) -#else -#define X_SIZE(face,i) ((face)->available_sizes[i].width << 6) -#define Y_SIZE(face,i) ((face)->available_sizes[i].height << 6) -#endif - -FcBool -_XftSetFace (XftFtFile *f, FT_F26Dot6 xsize, FT_F26Dot6 ysize, FT_Matrix *matrix) -{ - FT_Face face = f->face; - - if (f->xsize != xsize || f->ysize != ysize) - { - if (XftDebug() & XFT_DBG_GLYPH) - printf ("Set face size to %dx%d (%dx%d)\n", - (int) (xsize >> 6), (int) (ysize >> 6), (int) xsize, (int) ysize); - /* - * Bitmap only faces must match exactly, so find the closest - * one (height dominant search) - */ - if (!(face->face_flags & FT_FACE_FLAG_SCALABLE)) - { - int i, best = 0; - -#define xft_abs(a) ((a) < 0 ? -(a) : (a)) -#define dist(a,b) (xft_abs((a)-(b))) - - for (i = 1; i < face->num_fixed_sizes; i++) - { - if (dist (ysize, Y_SIZE(face,i)) < - dist (ysize, Y_SIZE(face, best)) || - (dist (ysize, Y_SIZE(face, i)) == - dist (ysize, Y_SIZE(face, best)) && - dist (xsize, X_SIZE(face, i)) < - dist (xsize, X_SIZE(face, best)))) - { - best = i; - } - } - /* - * Freetype 2.1.7 and earlier used width/height - * for matching sizes in the BDF and PCF loaders. - * This has been fixed for 2.1.8. Because BDF and PCF - * files have but a single strike per file, we can - * simply try both sizes. - */ - if ( -#if HAVE_FT_BITMAP_SIZE_Y_PPEM - FT_Set_Char_Size (face, face->available_sizes[best].x_ppem, - face->available_sizes[best].y_ppem, 0, 0) != 0 - && -#endif - FT_Set_Char_Size (face, face->available_sizes[best].width << 6, - face->available_sizes[best].height << 6, - 0, 0) != 0) - { - return False; - } - } - else - { - if (FT_Set_Char_Size (face, xsize, ysize, 0, 0)) - { - return False; - } - } - f->xsize = xsize; - f->ysize = ysize; - } - 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"); - if (f->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) + (f->file ? strlen (f->file) + 1 : 0)); - 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; - XftFontInfo *fi = &font->info; - FT_Face face; - - face = _XftLockFile (fi->file); - /* - * Make sure the face is usable at the requested size - */ - if (face && !_XftSetFace (fi->file, fi->xsize, fi->ysize, &fi->matrix)) - { - _XftUnlockFile (fi->file); - face = 0; - } - return face; -} - -void -XftUnlockFace (XftFont *public) -{ - XftFontInt *font = (XftFontInt *) public; - _XftUnlockFile (font->info.file); -} - -static FcBool -XftFontInfoFill (Display *dpy, _Xconst FcPattern *pattern, XftFontInfo *fi) -{ - XftDisplayInfo *info = _XftDisplayInfoGet (dpy, True); - FcChar8 *filename; - int id; - double dsize; - double aspect; - FcMatrix *font_matrix; - FcBool hinting, vertical_layout, autohint, global_advance; -#ifdef FC_HINT_STYLE - int hint_style; -#endif - FcChar32 hash, *hashp; - FT_Face face; - int nhash; - - if (!info) - return FcFalse; - - /* - * Find the associated file - */ - switch (FcPatternGetString (pattern, FC_FILE, 0, &filename)) { - case FcResultNoMatch: - filename = 0; - break; - case FcResultMatch: - break; - default: - goto bail0; - } - - switch (FcPatternGetInteger (pattern, FC_INDEX, 0, &id)) { - case FcResultNoMatch: - id = 0; - break; - case FcResultMatch: - break; - default: - goto bail0; - } - - if (filename) - fi->file = _XftGetFile (filename, id); - else if (FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &face) == FcResultMatch - && face) - fi->file = _XftGetFaceFile (face); - else - fi->file = 0; - if (!fi->file) - goto bail0; - - /* - * Compute pixel size - */ - if (FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &dsize) != FcResultMatch) - goto bail1; - - if (FcPatternGetDouble (pattern, FC_ASPECT, 0, &aspect) != FcResultMatch) - aspect = 1.0; - - fi->ysize = (FT_F26Dot6) (dsize * 64.0); - fi->xsize = (FT_F26Dot6) (dsize * aspect * 64.0); - - if (XftDebug() & XFT_DBG_OPEN) - printf ("XftFontInfoFill: %s: %d (%g pixels)\n", - (filename ? filename : (FcChar8 *) "<none>"), id, dsize); - /* - * Get antialias value - */ - switch (FcPatternGetBool (pattern, FC_ANTIALIAS, 0, &fi->antialias)) { - case FcResultNoMatch: - fi->antialias = True; - break; - case FcResultMatch: - break; - default: - goto bail1; - } - - /* - * Get rgba value - */ - switch (FcPatternGetInteger (pattern, FC_RGBA, 0, &fi->rgba)) { - case FcResultNoMatch: - fi->rgba = FC_RGBA_UNKNOWN; - break; - case FcResultMatch: - break; - default: - goto bail1; - } - - /* - * Get matrix and transform values - */ - switch (FcPatternGetMatrix (pattern, FC_MATRIX, 0, &font_matrix)) { - case FcResultNoMatch: - fi->matrix.xx = fi->matrix.yy = 0x10000; - fi->matrix.xy = fi->matrix.yx = 0; - break; - case FcResultMatch: - fi->matrix.xx = 0x10000L * font_matrix->xx; - fi->matrix.yy = 0x10000L * font_matrix->yy; - fi->matrix.xy = 0x10000L * font_matrix->xy; - fi->matrix.yx = 0x10000L * font_matrix->yx; - break; - default: - goto bail1; - } - - fi->transform = (fi->matrix.xx != 0x10000 || fi->matrix.xy != 0 || - fi->matrix.yx != 0 || fi->matrix.yy != 0x10000); - - /* - * Get render value, set to false if no Render extension present - */ - if (info->hasRender) - { - switch (FcPatternGetBool (pattern, XFT_RENDER, 0, &fi->render)) { - case FcResultNoMatch: - fi->render = info->hasRender; - break; - case FcResultMatch: - break; - default: - goto bail1; - } - } - else - fi->render = FcFalse; - - /* - * Compute glyph load flags - */ - fi->load_flags = FT_LOAD_DEFAULT; - - /* disable bitmaps when anti-aliasing or transforming glyphs */ - if (fi->antialias || fi->transform) - fi->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 bail1; - } - -#ifdef FC_EMBOLDEN - switch (FcPatternGetBool (pattern, FC_EMBOLDEN, 0, &fi->embolden)) { - case FcResultNoMatch: - fi->embolden = FcFalse; - break; - case FcResultMatch: - break; - default: - goto bail1; - } -#else - fi->embolden = FcFalse; -#endif - -#ifdef FC_HINT_STYLE - switch (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hint_style)) { - case FcResultNoMatch: - hint_style = FC_HINT_FULL; - break; - case FcResultMatch: - break; - default: - goto bail1; - } -#endif - - if (!hinting -#ifdef FC_HINT_STYLE - || hint_style == FC_HINT_NONE -#endif - ) - { - fi->load_flags |= FT_LOAD_NO_HINTING; - } - - /* Figure out the load target, which modifies the hinting - * behavior of FreeType based on the intended use of the glyphs. - */ - if (fi->antialias) - { -#ifdef FC_HINT_STYLE -#ifdef FT_LOAD_TARGET_LIGHT - if (FC_HINT_NONE < hint_style && hint_style < FC_HINT_FULL) - { - fi->load_flags |= FT_LOAD_TARGET_LIGHT; - } - else -#endif -#endif - { - /* autohinter will snap stems to integer widths, when - * the LCD targets are used. - */ - switch (fi->rgba) { - case FC_RGBA_RGB: - case FC_RGBA_BGR: -#ifdef FT_LOAD_TARGET_LCD - fi->load_flags |= FT_LOAD_TARGET_LCD; -#endif - break; - case FC_RGBA_VRGB: - case FC_RGBA_VBGR: -#ifdef FT_LOAD_TARGET_LCD_V - fi->load_flags |= FT_LOAD_TARGET_LCD_V; -#endif - break; - } - } - } -#ifdef FT_LOAD_TARGET_MONO - else - fi->load_flags |= FT_LOAD_TARGET_MONO; -#endif - - /* 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 bail1; - } - - if (vertical_layout) - fi->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 bail1; - } - - if (autohint) - fi->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 bail1; - } - - if (!global_advance) - fi->load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH; - - /* - * Get requested spacing value - */ - switch (FcPatternGetInteger (pattern, FC_SPACING, 0, &fi->spacing)) { - case FcResultNoMatch: - fi->spacing = FC_PROPORTIONAL; - break; - case FcResultMatch: - break; - default: - goto bail1; - } - - /* - * Check for minspace - */ - - switch (FcPatternGetBool (pattern, FC_MINSPACE, 0, &fi->minspace)) { - case FcResultNoMatch: - fi->minspace = FcFalse; - break; - case FcResultMatch: - break; - default: - goto bail1; - } - /* - * Check for fixed pixel spacing - */ - switch (FcPatternGetInteger (pattern, FC_CHAR_WIDTH, 0, &fi->char_width)) { - case FcResultNoMatch: - fi->char_width = 0; - break; - case FcResultMatch: - if (fi->char_width) - fi->spacing = FC_MONO; - break; - default: - goto bail1; - } - - /* - * Step over hash value in the structure - */ - hash = 0; - hashp = (FcChar32 *) fi + 1; - nhash = (sizeof (XftFontInfo) / sizeof (FcChar32)) - 1; - - while (nhash--) - hash += *hashp++; - fi->hash = hash; - - /* - * All done - */ - return FcTrue; - -bail1: - _XftReleaseFile (fi->file); - fi->file = 0; -bail0: - return FcFalse; -} - -static void -XftFontInfoEmpty (Display *dpy, XftFontInfo *fi) -{ - if (fi->file) - _XftReleaseFile (fi->file); -} - -XftFontInfo * -XftFontInfoCreate (Display *dpy, _Xconst FcPattern *pattern) -{ - XftFontInfo *fi = malloc (sizeof (XftFontInfo)); - - if (!fi) - return 0; - - if (!XftFontInfoFill (dpy, pattern, fi)) - { - free (fi); - fi = 0; - } - XftMemAlloc (XFT_MEM_FONT, sizeof (XftFontInfo)); - return fi; -} - -void -XftFontInfoDestroy (Display *dpy, XftFontInfo *fi) -{ - XftFontInfoEmpty (dpy, fi); - XftMemFree (XFT_MEM_FONT, sizeof (XftFontInfo)); - free (fi); -} - -FcChar32 -XftFontInfoHash (_Xconst XftFontInfo *fi) -{ - return fi->hash; -} - -FcBool -XftFontInfoEqual (_Xconst XftFontInfo *a, _Xconst XftFontInfo *b) -{ - return memcmp ((void *) a, (void *) b, sizeof (XftFontInfo)) == 0; -} - -XftFont * -XftFontOpenInfo (Display *dpy, - FcPattern *pattern, - XftFontInfo *fi) -{ - XftDisplayInfo *info = _XftDisplayInfoGet (dpy, True); - FT_Face face; - XftFont **bucket; - XftFontInt *font; - XRenderPictFormat *format; - FcCharSet *charset; - FcChar32 num_unicode; - FcChar32 hash_value; - FcChar32 rehash_value; - FcBool antialias; - int max_glyph_memory; - int alloc_size; - int ascent, descent, height; - int i; - int num_glyphs; - - if (!info) - return 0; - /* - * Find a matching previously opened font - */ - bucket = &info->fontHash[fi->hash % XFT_NUM_FONT_HASH]; - for (font = (XftFontInt *) *bucket; font; font = (XftFontInt *) font->hash_next) - if (XftFontInfoEqual (&font->info, fi)) - { - if (!font->ref++) - --info->num_unref_fonts; - FcPatternDestroy (pattern); - return &font->public; - } - - /* - * No existing font, create another. - */ - - if (XftDebug () & XFT_DBG_CACHE) - printf ("New font %s/%d size %dx%d\n", - fi->file->file, fi->file->id, - (int) fi->xsize >> 6, (int) fi->ysize >> 6); - - if (FcPatternGetInteger (pattern, XFT_MAX_GLYPH_MEMORY, 0, - &max_glyph_memory) != FcResultMatch) - max_glyph_memory = XFT_FONT_MAX_GLYPH_MEMORY; - - face = _XftLockFile (fi->file); - if (!face) - goto bail0; - - if (!_XftSetFace (fi->file, fi->xsize, fi->ysize, &fi->matrix)) - goto bail1; - - /* - * Get the set of Unicode codepoints covered by the font. - * If the incoming pattern doesn't provide this data, go - * off and compute it. Yes, this is expensive, but it's - * required to map Unicode to glyph indices. - */ - if (FcPatternGetCharSet (pattern, FC_CHARSET, 0, &charset) == FcResultMatch) - charset = FcCharSetCopy (charset); - else - charset = FcFreeTypeCharSet (face, FcConfigGetBlanks (0)); - - antialias = fi->antialias; - if (!(face->face_flags & FT_FACE_FLAG_SCALABLE)) - antialias = FcFalse; - - /* - * Find the appropriate picture format - */ - if (fi->render) - { - if (antialias) - { - switch (fi->rgba) { - case FC_RGBA_RGB: - case FC_RGBA_BGR: - case FC_RGBA_VRGB: - case FC_RGBA_VBGR: - format = XRenderFindStandardFormat (dpy, PictStandardARGB32); - break; - default: - format = XRenderFindStandardFormat (dpy, PictStandardA8); - break; - } - } - else - { - format = XRenderFindStandardFormat (dpy, PictStandardA1); - } - - if (!format) - goto bail2; - } - else - format = 0; - - 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; - } - - /* - * Sometimes the glyphs are numbered 1..n, other times 0..n-1, - * accept either numbering scheme by making room in the table - */ - num_glyphs = face->num_glyphs + 1; - alloc_size = (sizeof (XftFontInt) + - num_glyphs * sizeof (XftGlyph *) + - hash_value * sizeof (XftUcsHash)); - font = malloc (alloc_size); - - if (!font) - goto bail2; - - XftMemAlloc (XFT_MEM_FONT, alloc_size); - - /* - * Public fields - */ - if (fi->transform) - { - FT_Vector vector; - - vector.x = 0; - vector.y = face->size->metrics.descender; - FT_Vector_Transform (&vector, &fi->matrix); - descent = -(vector.y >> 6); - - vector.x = 0; - vector.y = face->size->metrics.ascender; - FT_Vector_Transform (&vector, &fi->matrix); - ascent = vector.y >> 6; - - if (fi->minspace) - height = ascent + descent; - else - { - vector.x = 0; - vector.y = face->size->metrics.height; - FT_Vector_Transform (&vector, &fi->matrix); - height = vector.y >> 6; - } - } - else - { - descent = -(face->size->metrics.descender >> 6); - ascent = face->size->metrics.ascender >> 6; - if (fi->minspace) - height = ascent + descent; - else - height = face->size->metrics.height >> 6; - } - font->public.ascent = ascent; - font->public.descent = descent; - font->public.height = height; - - if (fi->char_width) - font->public.max_advance_width = fi->char_width; - else - { - if (fi->transform) - { - FT_Vector vector; - vector.x = face->size->metrics.max_advance; - vector.y = 0; - FT_Vector_Transform (&vector, &fi->matrix); - font->public.max_advance_width = vector.x >> 6; - } - else - font->public.max_advance_width = face->size->metrics.max_advance >> 6; - } - font->public.charset = charset; - font->public.pattern = pattern; - - /* - * Management fields - */ - font->ref = 1; - - font->next = info->fonts; - info->fonts = &font->public; - - font->hash_next = *bucket; - *bucket = &font->public; - - /* - * Copy the info over - */ - font->info = *fi; - /* - * reset the antialias field. It can't - * be set correctly until the font is opened, - * which doesn't happen in XftFontInfoFill - */ - font->info.antialias = antialias; - /* - * bump XftFile reference count - */ - font->info.file->ref++; - - /* - * Per glyph information - */ - font->glyphs = (XftGlyph **) (font + 1); - memset (font->glyphs, '\0', num_glyphs * sizeof (XftGlyph *)); - font->num_glyphs = 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; - - /* - * Glyph memory management fields - */ - font->glyph_memory = 0; - font->max_glyph_memory = max_glyph_memory; - font->use_free_glyphs = info->use_free_glyphs; - - _XftUnlockFile (fi->file); - - return &font->public; - -bail2: - FcCharSetDestroy (charset); -bail1: - _XftUnlockFile (fi->file); -bail0: - return 0; -} - -XftFont * -XftFontOpenPattern (Display *dpy, FcPattern *pattern) -{ - XftFontInfo info; - XftFont *font; - - if (!XftFontInfoFill (dpy, pattern, &info)) - return 0; - - font = XftFontOpenInfo (dpy, pattern, &info); - XftFontInfoEmpty (dpy, &info); - return font; -} - -XftFont * -XftFontCopy (Display *dpy, XftFont *public) -{ - XftFontInt *font = (XftFontInt *) public; - - font->ref++; - return public; -} - -static void -XftFontDestroy (Display *dpy, XftFont *public) -{ - XftDisplayInfo *info = _XftDisplayInfoGet (dpy, False); - XftFontInt *font = (XftFontInt *) public; - int i; - - /* note reduction in memory use */ - if (info) - info->glyph_memory -= font->glyph_memory; - /* Clean up the info */ - XftFontInfoEmpty (dpy, &font->info); - /* 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); - } - } - - /* Free the pattern and the charset */ - FcPatternDestroy (font->public.pattern); - FcCharSetDestroy (font->public.charset); - - /* Finally, free the font structure */ - XftMemFree (XFT_MEM_FONT, sizeof (XftFontInt) + - font->num_glyphs * sizeof (XftGlyph *) + - font->hash_value * sizeof (XftUcsHash)); - free (font); -} - -static XftFont * -XftFontFindNthUnref (XftDisplayInfo *info, int n) -{ - XftFont *public; - XftFontInt *font; - - for (public = info->fonts; public; public = font->next) - { - font = (XftFontInt*) public; - if (!font->ref && !n--) - break; - } - return public; -} - -void -XftFontManageMemory (Display *dpy) -{ - XftDisplayInfo *info = _XftDisplayInfoGet (dpy, False); - XftFont **prev; - XftFont *public; - XftFontInt *font; - - if (!info) - return; - while (info->num_unref_fonts > info->max_unref_fonts) - { - public = XftFontFindNthUnref (info, rand() % info->num_unref_fonts); - font = (XftFontInt *) public; - - if (XftDebug () & XFT_DBG_CACHE) - printf ("freeing unreferenced font %s/%d size %dx%d\n", - font->info.file->file, font->info.file->id, - (int) font->info.xsize >> 6, (int) font->info.ysize >> 6); - - /* Unhook from display list */ - for (prev = &info->fonts; *prev; prev = &(*(XftFontInt **) prev)->next) - { - if (*prev == public) - { - *prev = font->next; - break; - } - } - /* Unhook from hash list */ - for (prev = &info->fontHash[font->info.hash % XFT_NUM_FONT_HASH]; - *prev; - prev = &(*(XftFontInt **) prev)->hash_next) - { - if (*prev == public) - { - *prev = font->hash_next; - break; - } - } - /* Destroy the font */ - XftFontDestroy (dpy, public); - --info->num_unref_fonts; - } -} - -void -XftFontClose (Display *dpy, XftFont *public) -{ - XftDisplayInfo *info = _XftDisplayInfoGet (dpy, False); - XftFontInt *font = (XftFontInt *) public; - - if (--font->ref != 0) - return; - - if (info) - { - ++info->num_unref_fonts; - XftFontManageMemory (dpy); - } - else - { - XftFontDestroy (dpy, public); - } -} - -FcBool -XftInitFtLibrary (void) -{ - if (_XftFTlibrary) - return FcTrue; - if (FT_Init_FreeType (&_XftFTlibrary)) - return FcFalse; - return FcTrue; -} |