From dafebc5bb70303f0b5baf0b087cf4d9a64b5c7f0 Mon Sep 17 00:00:00 2001 From: marha Date: Mon, 12 Sep 2011 11:27:51 +0200 Subject: Synchronised line endinge with release branch --- libXft/src/xftdpy.c | 1104 +++++++++++++++++++++++++-------------------------- 1 file changed, 552 insertions(+), 552 deletions(-) (limited to 'libXft/src/xftdpy.c') diff --git a/libXft/src/xftdpy.c b/libXft/src/xftdpy.c index 862c7e8ab..cd50358d2 100644 --- a/libXft/src/xftdpy.c +++ b/libXft/src/xftdpy.c @@ -1,552 +1,552 @@ -/* - * 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" - -_X_HIDDEN XftDisplayInfo *_XftDisplayInfo; - -static int -_XftCloseDisplay (Display *dpy, XExtCodes *codes) -{ - XftDisplayInfo *info, **prev; - - info = _XftDisplayInfoGet (dpy, FcFalse); - if (!info) - return 0; - - /* - * Get rid of any dangling unreferenced fonts - */ - info->max_unref_fonts = 0; - XftFontManageMemory (dpy); - - /* - * Clean up the default values - */ - if (info->defaults) - FcPatternDestroy (info->defaults); - - /* - * Unhook from the global list - */ - for (prev = &_XftDisplayInfo; (info = *prev); prev = &(*prev)->next) - if (info->display == dpy) - break; - *prev = info->next; - - free (info); - return 0; -} - - -_X_HIDDEN XftDisplayInfo * -_XftDisplayInfoGet (Display *dpy, FcBool createIfNecessary) -{ - XftDisplayInfo *info, **prev; - XRenderPictFormat pf; - int i; - int event_base, error_base; - - 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; - } - } - if (!createIfNecessary) - return NULL; - - 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 = NULL; - info->solidFormat = NULL; - info->hasRender = (XRenderQueryExtension (dpy, &event_base, &error_base) && - (XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != NULL)); - 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 = NULL; - - 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); - - - info->num_unref_fonts = 0; - info->max_unref_fonts = XftDefaultGetInteger (dpy, - XFT_MAX_UNREF_FONTS, 0, - XFT_DPY_MAX_UNREF_FONTS); - if (XftDebug() & XFT_DBG_CACHE) - printf ("global max unref fonts %d\n", info->max_unref_fonts); - - memset (info->fontHash, '\0', sizeof (XftFont *) * XFT_NUM_FONT_HASH); - return info; - -bail1: - free (info); -bail0: - if (XftDebug () & XFT_DBG_RENDER) - { - printf ("XftDisplayInfoGet failed to initialize, Xft unhappy\n"); - } - return NULL; -} - -/* - * Reduce memory usage in X server - */ - -static void -_XftDisplayValidateMemory (XftDisplayInfo *info) -{ - XftFont *public; - XftFontInt *font; - unsigned long glyph_memory; - - glyph_memory = 0; - for (public = info->fonts; public; public = font->next) - { - font = (XftFontInt *) public; - glyph_memory += font->glyph_memory; - } - if (glyph_memory != info->glyph_memory) - printf ("Display glyph cache incorrect has %ld bytes, should have %ld\n", - info->glyph_memory, glyph_memory); -} - -_X_HIDDEN void -_XftDisplayManageMemory (Display *dpy) -{ - XftDisplayInfo *info = _XftDisplayInfoGet (dpy, False); - 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); - _XftDisplayValidateMemory (info); - } - 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; - } - } - if (XftDebug () & XFT_DBG_CACHE) - _XftDisplayValidateMemory (info); -} - -_X_EXPORT Bool -XftDefaultHasRender (Display *dpy) -{ - XftDisplayInfo *info = _XftDisplayInfoGet (dpy, True); - - if (!info) - return False; - return info->hasRender; -} - -_X_EXPORT Bool -XftDefaultSet (Display *dpy, FcPattern *defaults) -{ - XftDisplayInfo *info = _XftDisplayInfoGet (dpy, True); - - 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); - if (!info->max_unref_fonts) - info->max_unref_fonts = XFT_DPY_MAX_UNREF_FONTS; - info->max_unref_fonts = XftDefaultGetInteger (dpy, - XFT_MAX_UNREF_FONTS, 0, - info->max_unref_fonts); - return True; -} - -_X_HIDDEN int -XftDefaultParseBool (char *v) -{ - char c0, c1; - - c0 = *v; - if (isupper ((int)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 ((int)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; -#ifdef FC_EMBOLDEN - if (!_XftDefaultInitBool (dpy, pat, FC_EMBOLDEN)) - goto bail1; -#endif - if (!_XftDefaultInitBool (dpy, pat, FC_AUTOHINT)) - goto bail1; -#ifdef FC_HINT_STYLE - if (!_XftDefaultInitInteger (dpy, pat, FC_HINT_STYLE)) - goto bail1; -#endif - if (!_XftDefaultInitBool (dpy, pat, FC_HINTING)) - 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 NULL; -} - -static FcResult -_XftDefaultGet (Display *dpy, const char *object, int screen, FcValue *v) -{ - XftDisplayInfo *info = _XftDisplayInfoGet (dpy, True); - 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; -} - -_X_HIDDEN 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; -} - -_X_HIDDEN 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; -} - -_X_HIDDEN 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; -} - -_X_EXPORT 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)); - } -#ifdef FC_EMBOLDEN - if (FcPatternGet (pattern, FC_EMBOLDEN, 0, &v) == FcResultNoMatch) - { - FcPatternAddBool (pattern, FC_EMBOLDEN, - XftDefaultGetBool (dpy, FC_EMBOLDEN, screen, - False)); - } -#endif - if (FcPatternGet (pattern, FC_HINTING, 0, &v) == FcResultNoMatch) - { - FcPatternAddBool (pattern, FC_HINTING, - XftDefaultGetBool (dpy, FC_HINTING, screen, - True)); - } -#ifdef FC_HINT_STYLE - if (FcPatternGet (pattern, FC_HINT_STYLE, 0, &v) == FcResultNoMatch) - { - FcPatternAddInteger (pattern, FC_HINT_STYLE, - XftDefaultGetInteger (dpy, FC_HINT_STYLE, screen, - FC_HINT_FULL)); - } -#endif - if (FcPatternGet (pattern, FC_AUTOHINT, 0, &v) == FcResultNoMatch) - { - FcPatternAddBool (pattern, FC_AUTOHINT, - XftDefaultGetBool (dpy, FC_AUTOHINT, screen, - False)); - } - if (FcPatternGet (pattern, FC_RGBA, 0, &v) == FcResultNoMatch) - { - int subpixel = FC_RGBA_UNKNOWN; -#if RENDER_MAJOR > 0 || RENDER_MINOR >= 6 - if (XftDefaultHasRender (dpy)) - { - int render_order = XRenderQuerySubpixelOrder (dpy, screen); - switch (render_order) { - default: - case SubPixelUnknown: subpixel = FC_RGBA_UNKNOWN; break; - case SubPixelHorizontalRGB: subpixel = FC_RGBA_RGB; break; - case SubPixelHorizontalBGR: subpixel = FC_RGBA_BGR; break; - case SubPixelVerticalRGB: subpixel = FC_RGBA_VRGB; break; - case SubPixelVerticalBGR: subpixel = FC_RGBA_VBGR; break; - case SubPixelNone: subpixel = FC_RGBA_NONE; break; - } - } -#endif - FcPatternAddInteger (pattern, FC_RGBA, - XftDefaultGetInteger (dpy, FC_RGBA, screen, - subpixel)); - } - 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); -} - +/* + * 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" + +_X_HIDDEN XftDisplayInfo *_XftDisplayInfo; + +static int +_XftCloseDisplay (Display *dpy, XExtCodes *codes) +{ + XftDisplayInfo *info, **prev; + + info = _XftDisplayInfoGet (dpy, FcFalse); + if (!info) + return 0; + + /* + * Get rid of any dangling unreferenced fonts + */ + info->max_unref_fonts = 0; + XftFontManageMemory (dpy); + + /* + * Clean up the default values + */ + if (info->defaults) + FcPatternDestroy (info->defaults); + + /* + * Unhook from the global list + */ + for (prev = &_XftDisplayInfo; (info = *prev); prev = &(*prev)->next) + if (info->display == dpy) + break; + *prev = info->next; + + free (info); + return 0; +} + + +_X_HIDDEN XftDisplayInfo * +_XftDisplayInfoGet (Display *dpy, FcBool createIfNecessary) +{ + XftDisplayInfo *info, **prev; + XRenderPictFormat pf; + int i; + int event_base, error_base; + + 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; + } + } + if (!createIfNecessary) + return NULL; + + 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 = NULL; + info->solidFormat = NULL; + info->hasRender = (XRenderQueryExtension (dpy, &event_base, &error_base) && + (XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != NULL)); + 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 = NULL; + + 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); + + + info->num_unref_fonts = 0; + info->max_unref_fonts = XftDefaultGetInteger (dpy, + XFT_MAX_UNREF_FONTS, 0, + XFT_DPY_MAX_UNREF_FONTS); + if (XftDebug() & XFT_DBG_CACHE) + printf ("global max unref fonts %d\n", info->max_unref_fonts); + + memset (info->fontHash, '\0', sizeof (XftFont *) * XFT_NUM_FONT_HASH); + return info; + +bail1: + free (info); +bail0: + if (XftDebug () & XFT_DBG_RENDER) + { + printf ("XftDisplayInfoGet failed to initialize, Xft unhappy\n"); + } + return NULL; +} + +/* + * Reduce memory usage in X server + */ + +static void +_XftDisplayValidateMemory (XftDisplayInfo *info) +{ + XftFont *public; + XftFontInt *font; + unsigned long glyph_memory; + + glyph_memory = 0; + for (public = info->fonts; public; public = font->next) + { + font = (XftFontInt *) public; + glyph_memory += font->glyph_memory; + } + if (glyph_memory != info->glyph_memory) + printf ("Display glyph cache incorrect has %ld bytes, should have %ld\n", + info->glyph_memory, glyph_memory); +} + +_X_HIDDEN void +_XftDisplayManageMemory (Display *dpy) +{ + XftDisplayInfo *info = _XftDisplayInfoGet (dpy, False); + 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); + _XftDisplayValidateMemory (info); + } + 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; + } + } + if (XftDebug () & XFT_DBG_CACHE) + _XftDisplayValidateMemory (info); +} + +_X_EXPORT Bool +XftDefaultHasRender (Display *dpy) +{ + XftDisplayInfo *info = _XftDisplayInfoGet (dpy, True); + + if (!info) + return False; + return info->hasRender; +} + +_X_EXPORT Bool +XftDefaultSet (Display *dpy, FcPattern *defaults) +{ + XftDisplayInfo *info = _XftDisplayInfoGet (dpy, True); + + 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); + if (!info->max_unref_fonts) + info->max_unref_fonts = XFT_DPY_MAX_UNREF_FONTS; + info->max_unref_fonts = XftDefaultGetInteger (dpy, + XFT_MAX_UNREF_FONTS, 0, + info->max_unref_fonts); + return True; +} + +_X_HIDDEN int +XftDefaultParseBool (char *v) +{ + char c0, c1; + + c0 = *v; + if (isupper ((int)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 ((int)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; +#ifdef FC_EMBOLDEN + if (!_XftDefaultInitBool (dpy, pat, FC_EMBOLDEN)) + goto bail1; +#endif + if (!_XftDefaultInitBool (dpy, pat, FC_AUTOHINT)) + goto bail1; +#ifdef FC_HINT_STYLE + if (!_XftDefaultInitInteger (dpy, pat, FC_HINT_STYLE)) + goto bail1; +#endif + if (!_XftDefaultInitBool (dpy, pat, FC_HINTING)) + 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 NULL; +} + +static FcResult +_XftDefaultGet (Display *dpy, const char *object, int screen, FcValue *v) +{ + XftDisplayInfo *info = _XftDisplayInfoGet (dpy, True); + 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; +} + +_X_HIDDEN 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; +} + +_X_HIDDEN 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; +} + +_X_HIDDEN 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; +} + +_X_EXPORT 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)); + } +#ifdef FC_EMBOLDEN + if (FcPatternGet (pattern, FC_EMBOLDEN, 0, &v) == FcResultNoMatch) + { + FcPatternAddBool (pattern, FC_EMBOLDEN, + XftDefaultGetBool (dpy, FC_EMBOLDEN, screen, + False)); + } +#endif + if (FcPatternGet (pattern, FC_HINTING, 0, &v) == FcResultNoMatch) + { + FcPatternAddBool (pattern, FC_HINTING, + XftDefaultGetBool (dpy, FC_HINTING, screen, + True)); + } +#ifdef FC_HINT_STYLE + if (FcPatternGet (pattern, FC_HINT_STYLE, 0, &v) == FcResultNoMatch) + { + FcPatternAddInteger (pattern, FC_HINT_STYLE, + XftDefaultGetInteger (dpy, FC_HINT_STYLE, screen, + FC_HINT_FULL)); + } +#endif + if (FcPatternGet (pattern, FC_AUTOHINT, 0, &v) == FcResultNoMatch) + { + FcPatternAddBool (pattern, FC_AUTOHINT, + XftDefaultGetBool (dpy, FC_AUTOHINT, screen, + False)); + } + if (FcPatternGet (pattern, FC_RGBA, 0, &v) == FcResultNoMatch) + { + int subpixel = FC_RGBA_UNKNOWN; +#if RENDER_MAJOR > 0 || RENDER_MINOR >= 6 + if (XftDefaultHasRender (dpy)) + { + int render_order = XRenderQuerySubpixelOrder (dpy, screen); + switch (render_order) { + default: + case SubPixelUnknown: subpixel = FC_RGBA_UNKNOWN; break; + case SubPixelHorizontalRGB: subpixel = FC_RGBA_RGB; break; + case SubPixelHorizontalBGR: subpixel = FC_RGBA_BGR; break; + case SubPixelVerticalRGB: subpixel = FC_RGBA_VRGB; break; + case SubPixelVerticalBGR: subpixel = FC_RGBA_VBGR; break; + case SubPixelNone: subpixel = FC_RGBA_NONE; break; + } + } +#endif + FcPatternAddInteger (pattern, FC_RGBA, + XftDefaultGetInteger (dpy, FC_RGBA, screen, + subpixel)); + } + 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); +} + -- cgit v1.2.3