diff options
Diffstat (limited to 'libXft/src/xftdpy.c')
-rw-r--r-- | libXft/src/xftdpy.c | 1104 |
1 files changed, 552 insertions, 552 deletions
diff --git a/libXft/src/xftdpy.c b/libXft/src/xftdpy.c index cd50358d2..862c7e8ab 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);
+}
+
|