Blame src/xftdpy.c

Packit b749da
/*
Packit b749da
 * Copyright © 2000 Keith Packard
Packit b749da
 *
Packit b749da
 * Permission to use, copy, modify, distribute, and sell this software and its
Packit b749da
 * documentation for any purpose is hereby granted without fee, provided that
Packit b749da
 * the above copyright notice appear in all copies and that both that
Packit b749da
 * copyright notice and this permission notice appear in supporting
Packit b749da
 * documentation, and that the name of Keith Packard not be used in
Packit b749da
 * advertising or publicity pertaining to distribution of the software without
Packit b749da
 * specific, written prior permission.  Keith Packard makes no
Packit b749da
 * representations about the suitability of this software for any purpose.  It
Packit b749da
 * is provided "as is" without express or implied warranty.
Packit b749da
 *
Packit b749da
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
Packit b749da
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
Packit b749da
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
Packit b749da
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
Packit b749da
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
Packit b749da
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
Packit b749da
 * PERFORMANCE OF THIS SOFTWARE.
Packit b749da
 */
Packit b749da
Packit b749da
#include "xftint.h"
Packit b749da
Packit b749da
_X_HIDDEN XftDisplayInfo	*_XftDisplayInfo;
Packit b749da
Packit b749da
static int
Packit b749da
_XftCloseDisplay (Display *dpy, XExtCodes *codes)
Packit b749da
{
Packit b749da
    XftDisplayInfo  *info, **prev;
Packit b749da
Packit b749da
    info = _XftDisplayInfoGet (dpy, FcFalse);
Packit b749da
    if (!info)
Packit b749da
	return 0;
Packit b749da
Packit b749da
    /*
Packit b749da
     * Get rid of any dangling unreferenced fonts
Packit b749da
     */
Packit b749da
    info->max_unref_fonts = 0;
Packit b749da
    XftFontManageMemory (dpy);
Packit b749da
Packit b749da
    /*
Packit b749da
     * Clean up the default values
Packit b749da
     */
Packit b749da
    if (info->defaults)
Packit b749da
	FcPatternDestroy (info->defaults);
Packit b749da
Packit b749da
    /*
Packit b749da
     * Unhook from the global list
Packit b749da
     */
Packit b749da
    for (prev = &_XftDisplayInfo; (info = *prev); prev = &(*prev)->next)
Packit b749da
	if (info->display == dpy)
Packit b749da
	    break;
Packit b749da
    *prev = info->next;
Packit b749da
Packit b749da
    free (info);
Packit b749da
    return 0;
Packit b749da
}
Packit b749da
Packit b749da
Packit b749da
_X_HIDDEN XftDisplayInfo *
Packit b749da
_XftDisplayInfoGet (Display *dpy, FcBool createIfNecessary)
Packit b749da
{
Packit b749da
    XftDisplayInfo	*info, **prev;
Packit b749da
    XRenderPictFormat	pf;
Packit b749da
    int			i;
Packit b749da
    int			event_base, error_base;
Packit b749da
Packit b749da
    for (prev = &_XftDisplayInfo; (info = *prev); prev = &(*prev)->next)
Packit b749da
    {
Packit b749da
	if (info->display == dpy)
Packit b749da
	{
Packit b749da
	    /*
Packit b749da
	     * MRU the list
Packit b749da
	     */
Packit b749da
	    if (prev != &_XftDisplayInfo)
Packit b749da
	    {
Packit b749da
		*prev = info->next;
Packit b749da
		info->next = _XftDisplayInfo;
Packit b749da
		_XftDisplayInfo = info;
Packit b749da
	    }
Packit b749da
	    return info;
Packit b749da
	}
Packit b749da
    }
Packit b749da
    if (!createIfNecessary)
Packit b749da
	return NULL;
Packit b749da
Packit b749da
    info = (XftDisplayInfo *) malloc (sizeof (XftDisplayInfo));
Packit b749da
    if (!info)
Packit b749da
	goto bail0;
Packit b749da
    info->codes = XAddExtension (dpy);
Packit b749da
    if (!info->codes)
Packit b749da
	goto bail1;
Packit b749da
    (void) XESetCloseDisplay (dpy, info->codes->extension, _XftCloseDisplay);
Packit b749da
Packit b749da
    info->display = dpy;
Packit b749da
    info->defaults = NULL;
Packit b749da
    info->solidFormat = NULL;
Packit b749da
    info->hasRender = (XRenderQueryExtension (dpy, &event_base, &error_base) &&
Packit b749da
		       (XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != NULL));
Packit b749da
    info->use_free_glyphs = FcTrue;
Packit b749da
    if (info->hasRender)
Packit b749da
    {
Packit b749da
	int major, minor;
Packit b749da
	XRenderQueryVersion (dpy, &major, &minor);
Packit b749da
	if (major < 0 || (major == 0 && minor <= 2))
Packit b749da
	    info->use_free_glyphs = FcFalse;
Packit b749da
Packit b749da
	info->hasSolid = FcFalse;
Packit b749da
	if (major > 0 || (major == 0 && minor >= 10))
Packit b749da
	    info->hasSolid = FcTrue;
Packit b749da
Packit b749da
	pf.type = PictTypeDirect;
Packit b749da
	pf.depth = 32;
Packit b749da
	pf.direct.redMask = 0xff;
Packit b749da
	pf.direct.greenMask = 0xff;
Packit b749da
	pf.direct.blueMask = 0xff;
Packit b749da
	pf.direct.alphaMask = 0xff;
Packit b749da
	info->solidFormat = XRenderFindFormat (dpy,
Packit b749da
					       (PictFormatType|
Packit b749da
						PictFormatDepth|
Packit b749da
						PictFormatRedMask|
Packit b749da
						PictFormatGreenMask|
Packit b749da
						PictFormatBlueMask|
Packit b749da
						PictFormatAlphaMask),
Packit b749da
					       &pf,
Packit b749da
					       0);
Packit b749da
    }
Packit b749da
    if (XftDebug () & XFT_DBG_RENDER)
Packit b749da
    {
Packit b749da
	Visual		    *visual = DefaultVisual (dpy, DefaultScreen (dpy));
Packit b749da
	XRenderPictFormat   *format = XRenderFindVisualFormat (dpy, visual);
Packit b749da
Packit b749da
	printf ("XftDisplayInfoGet Default visual 0x%x ",
Packit b749da
		(int) visual->visualid);
Packit b749da
	if (format)
Packit b749da
	{
Packit b749da
	    if (format->type == PictTypeDirect)
Packit b749da
	    {
Packit b749da
		printf ("format %d,%d,%d,%d\n",
Packit b749da
			format->direct.alpha,
Packit b749da
			format->direct.red,
Packit b749da
			format->direct.green,
Packit b749da
			format->direct.blue);
Packit b749da
	    }
Packit b749da
	    else
Packit b749da
	    {
Packit b749da
		printf ("format indexed\n");
Packit b749da
	    }
Packit b749da
	}
Packit b749da
	else
Packit b749da
	    printf ("No Render format for default visual\n");
Packit b749da
Packit b749da
	printf ("XftDisplayInfoGet initialized, hasRender set to \"%s\"\n",
Packit b749da
		info->hasRender ? "True" : "False");
Packit b749da
    }
Packit b749da
    for (i = 0; i < XFT_NUM_SOLID_COLOR; i++)
Packit b749da
    {
Packit b749da
	info->colors[i].screen = -1;
Packit b749da
	info->colors[i].pict = 0;
Packit b749da
    }
Packit b749da
    info->fonts = NULL;
Packit b749da
Packit b749da
    info->next = _XftDisplayInfo;
Packit b749da
    _XftDisplayInfo = info;
Packit b749da
Packit b749da
    info->glyph_memory = 0;
Packit b749da
    info->max_glyph_memory = XftDefaultGetInteger (dpy,
Packit b749da
						   XFT_MAX_GLYPH_MEMORY, 0,
Packit b749da
						   XFT_DPY_MAX_GLYPH_MEMORY);
Packit b749da
    if (XftDebug () & XFT_DBG_CACHE)
Packit b749da
	printf ("global max cache memory %ld\n", info->max_glyph_memory);
Packit b749da
Packit b749da
Packit b749da
    info->num_unref_fonts = 0;
Packit b749da
    info->max_unref_fonts = XftDefaultGetInteger (dpy,
Packit b749da
						  XFT_MAX_UNREF_FONTS, 0,
Packit b749da
						  XFT_DPY_MAX_UNREF_FONTS);
Packit b749da
    if (XftDebug() & XFT_DBG_CACHE)
Packit b749da
	printf ("global max unref fonts %d\n", info->max_unref_fonts);
Packit b749da
Packit b749da
    memset (info->fontHash, '\0', sizeof (XftFont *) * XFT_NUM_FONT_HASH);
Packit b749da
    return info;
Packit b749da
Packit b749da
bail1:
Packit b749da
    free (info);
Packit b749da
bail0:
Packit b749da
    if (XftDebug () & XFT_DBG_RENDER)
Packit b749da
    {
Packit b749da
	printf ("XftDisplayInfoGet failed to initialize, Xft unhappy\n");
Packit b749da
    }
Packit b749da
    return NULL;
Packit b749da
}
Packit b749da
Packit b749da
/*
Packit b749da
 * Reduce memory usage in X server
Packit b749da
 */
Packit b749da
Packit b749da
static void
Packit b749da
_XftDisplayValidateMemory (XftDisplayInfo *info)
Packit b749da
{
Packit b749da
    XftFont	    *public;
Packit b749da
    XftFontInt	    *font;
Packit b749da
    unsigned long   glyph_memory;
Packit b749da
Packit b749da
    glyph_memory = 0;
Packit b749da
    for (public = info->fonts; public; public = font->next)
Packit b749da
    {
Packit b749da
	font = (XftFontInt *) public;
Packit b749da
	glyph_memory += font->glyph_memory;
Packit b749da
    }
Packit b749da
    if (glyph_memory != info->glyph_memory)
Packit b749da
	printf ("Display glyph cache incorrect has %ld bytes, should have %ld\n",
Packit b749da
		info->glyph_memory, glyph_memory);
Packit b749da
}
Packit b749da
Packit b749da
_X_HIDDEN void
Packit b749da
_XftDisplayManageMemory (Display *dpy)
Packit b749da
{
Packit b749da
    XftDisplayInfo  *info = _XftDisplayInfoGet (dpy, False);
Packit b749da
    unsigned long   glyph_memory;
Packit b749da
    XftFont	    *public;
Packit b749da
    XftFontInt	    *font;
Packit b749da
Packit b749da
    if (!info || !info->max_glyph_memory)
Packit b749da
	return;
Packit b749da
    if (XftDebug () & XFT_DBG_CACHE)
Packit b749da
    {
Packit b749da
	if (info->glyph_memory > info->max_glyph_memory)
Packit b749da
	    printf ("Reduce global memory from %ld to %ld\n",
Packit b749da
		    info->glyph_memory, info->max_glyph_memory);
Packit b749da
	_XftDisplayValidateMemory (info);
Packit b749da
    }
Packit b749da
    while (info->glyph_memory > info->max_glyph_memory)
Packit b749da
    {
Packit b749da
	glyph_memory = rand () % info->glyph_memory;
Packit b749da
	public = info->fonts;
Packit b749da
	while (public)
Packit b749da
	{
Packit b749da
	    font = (XftFontInt *) public;
Packit b749da
Packit b749da
	    if (font->glyph_memory > glyph_memory)
Packit b749da
	    {
Packit b749da
		_XftFontUncacheGlyph (dpy, public);
Packit b749da
		break;
Packit b749da
	    }
Packit b749da
	    public = font->next;
Packit b749da
	    glyph_memory -= font->glyph_memory;
Packit b749da
	}
Packit b749da
    }
Packit b749da
    if (XftDebug () & XFT_DBG_CACHE)
Packit b749da
	_XftDisplayValidateMemory (info);
Packit b749da
}
Packit b749da
Packit b749da
_X_EXPORT Bool
Packit b749da
XftDefaultHasRender (Display *dpy)
Packit b749da
{
Packit b749da
    XftDisplayInfo  *info = _XftDisplayInfoGet (dpy, True);
Packit b749da
Packit b749da
    if (!info)
Packit b749da
	return False;
Packit b749da
    return info->hasRender;
Packit b749da
}
Packit b749da
Packit b749da
_X_EXPORT Bool
Packit b749da
XftDefaultSet (Display *dpy, FcPattern *defaults)
Packit b749da
{
Packit b749da
    XftDisplayInfo  *info = _XftDisplayInfoGet (dpy, True);
Packit b749da
Packit b749da
    if (!info)
Packit b749da
	return False;
Packit b749da
    if (info->defaults)
Packit b749da
	FcPatternDestroy (info->defaults);
Packit b749da
    info->defaults = defaults;
Packit b749da
    if (!info->max_glyph_memory)
Packit b749da
	info->max_glyph_memory = XFT_DPY_MAX_GLYPH_MEMORY;
Packit b749da
    info->max_glyph_memory = XftDefaultGetInteger (dpy,
Packit b749da
						   XFT_MAX_GLYPH_MEMORY, 0,
Packit b749da
						   info->max_glyph_memory);
Packit b749da
    if (!info->max_unref_fonts)
Packit b749da
	info->max_unref_fonts = XFT_DPY_MAX_UNREF_FONTS;
Packit b749da
    info->max_unref_fonts = XftDefaultGetInteger (dpy,
Packit b749da
						  XFT_MAX_UNREF_FONTS, 0,
Packit b749da
						  info->max_unref_fonts);
Packit b749da
    return True;
Packit b749da
}
Packit b749da
Packit b749da
_X_HIDDEN int
Packit b749da
XftDefaultParseBool (const char *v)
Packit b749da
{
Packit b749da
    char    c0, c1;
Packit b749da
Packit b749da
    c0 = *v;
Packit b749da
    if (isupper ((int)c0))
Packit b749da
	c0 = tolower (c0);
Packit b749da
    if (c0 == 't' || c0 == 'y' || c0 == '1')
Packit b749da
	return 1;
Packit b749da
    if (c0 == 'f' || c0 == 'n' || c0 == '0')
Packit b749da
	return 0;
Packit b749da
    if (c0 == 'o')
Packit b749da
    {
Packit b749da
	c1 = v[1];
Packit b749da
	if (isupper ((int)c1))
Packit b749da
	    c1 = tolower (c1);
Packit b749da
	if (c1 == 'n')
Packit b749da
	    return 1;
Packit b749da
	if (c1 == 'f')
Packit b749da
	    return 0;
Packit b749da
    }
Packit b749da
    return -1;
Packit b749da
}
Packit b749da
Packit b749da
static Bool
Packit b749da
_XftDefaultInitBool (Display *dpy, FcPattern *pat, const char *option)
Packit b749da
{
Packit b749da
    char    *v;
Packit b749da
    int	    i;
Packit b749da
Packit b749da
    v = XGetDefault (dpy, "Xft", option);
Packit b749da
    if (v && (i = XftDefaultParseBool (v)) >= 0)
Packit b749da
	return FcPatternAddBool (pat, option, i != 0);
Packit b749da
    return True;
Packit b749da
}
Packit b749da
Packit b749da
static Bool
Packit b749da
_XftDefaultInitDouble (Display *dpy, FcPattern *pat, const char *option)
Packit b749da
{
Packit b749da
    char    *v, *e;
Packit b749da
    double  d;
Packit b749da
Packit b749da
    v = XGetDefault (dpy, "Xft", option);
Packit b749da
    if (v)
Packit b749da
    {
Packit b749da
	d = strtod (v, &e);
Packit b749da
	if (e != v)
Packit b749da
	    return FcPatternAddDouble (pat, option, d);
Packit b749da
    }
Packit b749da
    return True;
Packit b749da
}
Packit b749da
Packit b749da
static Bool
Packit b749da
_XftDefaultInitInteger (Display *dpy, FcPattern *pat, const char *option)
Packit b749da
{
Packit b749da
    char    *v, *e;
Packit b749da
    int	    i;
Packit b749da
Packit b749da
    v = XGetDefault (dpy, "Xft", option);
Packit b749da
    if (v)
Packit b749da
    {
Packit b749da
	if (FcNameConstant ((FcChar8 *) v, &i))
Packit b749da
	    return FcPatternAddInteger (pat, option, i);
Packit b749da
	i = strtol (v, &e, 0);
Packit b749da
	if (e != v)
Packit b749da
	    return FcPatternAddInteger (pat, option, i);
Packit b749da
    }
Packit b749da
    return True;
Packit b749da
}
Packit b749da
Packit b749da
static FcPattern *
Packit b749da
_XftDefaultInit (Display *dpy)
Packit b749da
{
Packit b749da
    FcPattern	*pat;
Packit b749da
Packit b749da
    pat = FcPatternCreate ();
Packit b749da
    if (!pat)
Packit b749da
	goto bail0;
Packit b749da
Packit b749da
    if (!_XftDefaultInitDouble (dpy, pat, FC_SCALE))
Packit b749da
	goto bail1;
Packit b749da
    if (!_XftDefaultInitDouble (dpy, pat, FC_DPI))
Packit b749da
	goto bail1;
Packit b749da
    if (!_XftDefaultInitBool (dpy, pat, XFT_RENDER))
Packit b749da
	goto bail1;
Packit b749da
    if (!_XftDefaultInitInteger (dpy, pat, FC_RGBA))
Packit b749da
	goto bail1;
Packit b749da
    if (!_XftDefaultInitInteger (dpy, pat, FC_LCD_FILTER))
Packit b749da
	goto bail1;
Packit b749da
    if (!_XftDefaultInitBool (dpy, pat, FC_ANTIALIAS))
Packit b749da
	goto bail1;
Packit b749da
    if (!_XftDefaultInitBool (dpy, pat, FC_EMBOLDEN))
Packit b749da
	goto bail1;
Packit b749da
    if (!_XftDefaultInitBool (dpy, pat, FC_AUTOHINT))
Packit b749da
	goto bail1;
Packit b749da
    if (!_XftDefaultInitInteger (dpy, pat, FC_HINT_STYLE))
Packit b749da
	goto bail1;
Packit b749da
    if (!_XftDefaultInitBool (dpy, pat, FC_HINTING))
Packit b749da
	goto bail1;
Packit b749da
    if (!_XftDefaultInitBool (dpy, pat, FC_MINSPACE))
Packit b749da
	goto bail1;
Packit b749da
    if (!_XftDefaultInitInteger (dpy, pat, XFT_MAX_GLYPH_MEMORY))
Packit b749da
	goto bail1;
Packit b749da
Packit b749da
    return pat;
Packit b749da
Packit b749da
bail1:
Packit b749da
    FcPatternDestroy (pat);
Packit b749da
bail0:
Packit b749da
    return NULL;
Packit b749da
}
Packit b749da
Packit b749da
static FcResult
Packit b749da
_XftDefaultGet (Display *dpy, const char *object, int screen, FcValue *v)
Packit b749da
{
Packit b749da
    XftDisplayInfo  *info = _XftDisplayInfoGet (dpy, True);
Packit b749da
    FcResult	    r;
Packit b749da
Packit b749da
    if (!info)
Packit b749da
	return FcResultNoMatch;
Packit b749da
Packit b749da
    if (!info->defaults)
Packit b749da
    {
Packit b749da
	info->defaults = _XftDefaultInit (dpy);
Packit b749da
	if (!info->defaults)
Packit b749da
	    return FcResultNoMatch;
Packit b749da
    }
Packit b749da
    r = FcPatternGet (info->defaults, object, screen, v);
Packit b749da
    if (r == FcResultNoId && screen > 0)
Packit b749da
	r = FcPatternGet (info->defaults, object, 0, v);
Packit b749da
    return r;
Packit b749da
}
Packit b749da
Packit b749da
_X_HIDDEN Bool
Packit b749da
XftDefaultGetBool (Display *dpy, const char *object, int screen, Bool def)
Packit b749da
{
Packit b749da
    FcResult	    r;
Packit b749da
    FcValue	    v;
Packit b749da
Packit b749da
    r = _XftDefaultGet (dpy, object, screen, &v);
Packit b749da
    if (r != FcResultMatch || v.type != FcTypeBool)
Packit b749da
	return def;
Packit b749da
    return v.u.b;
Packit b749da
}
Packit b749da
Packit b749da
_X_HIDDEN int
Packit b749da
XftDefaultGetInteger (Display *dpy, const char *object, int screen, int def)
Packit b749da
{
Packit b749da
    FcResult	    r;
Packit b749da
    FcValue	    v;
Packit b749da
Packit b749da
    r = _XftDefaultGet (dpy, object, screen, &v);
Packit b749da
    if (r != FcResultMatch || v.type != FcTypeInteger)
Packit b749da
	return def;
Packit b749da
    return v.u.i;
Packit b749da
}
Packit b749da
Packit b749da
_X_HIDDEN double
Packit b749da
XftDefaultGetDouble (Display *dpy, const char *object, int screen, double def)
Packit b749da
{
Packit b749da
    FcResult	    r;
Packit b749da
    FcValue	    v;
Packit b749da
Packit b749da
    r = _XftDefaultGet (dpy, object, screen, &v);
Packit b749da
    if (r != FcResultMatch || v.type != FcTypeDouble)
Packit b749da
	return def;
Packit b749da
    return v.u.d;
Packit b749da
}
Packit b749da
Packit b749da
_X_EXPORT void
Packit b749da
XftDefaultSubstitute (Display *dpy, int screen, FcPattern *pattern)
Packit b749da
{
Packit b749da
    FcValue	v;
Packit b749da
    double	dpi;
Packit b749da
Packit b749da
    if (FcPatternGet (pattern, XFT_RENDER, 0, &v) == FcResultNoMatch)
Packit b749da
    {
Packit b749da
	FcPatternAddBool (pattern, XFT_RENDER,
Packit b749da
			   XftDefaultGetBool (dpy, XFT_RENDER, screen,
Packit b749da
					      XftDefaultHasRender (dpy)));
Packit b749da
    }
Packit b749da
    if (FcPatternGet (pattern, FC_ANTIALIAS, 0, &v) == FcResultNoMatch)
Packit b749da
    {
Packit b749da
	FcPatternAddBool (pattern, FC_ANTIALIAS,
Packit b749da
			   XftDefaultGetBool (dpy, FC_ANTIALIAS, screen,
Packit b749da
					      True));
Packit b749da
    }
Packit b749da
    if (FcPatternGet (pattern, FC_EMBOLDEN, 0, &v) == FcResultNoMatch)
Packit b749da
    {
Packit b749da
	FcPatternAddBool (pattern, FC_EMBOLDEN,
Packit b749da
			   XftDefaultGetBool (dpy, FC_EMBOLDEN, screen,
Packit b749da
					      False));
Packit b749da
    }
Packit b749da
    if (FcPatternGet (pattern, FC_HINTING, 0, &v) == FcResultNoMatch)
Packit b749da
    {
Packit b749da
	FcPatternAddBool (pattern, FC_HINTING,
Packit b749da
			  XftDefaultGetBool (dpy, FC_HINTING, screen,
Packit b749da
					     True));
Packit b749da
    }
Packit b749da
    if (FcPatternGet (pattern, FC_HINT_STYLE, 0, &v) == FcResultNoMatch)
Packit b749da
    {
Packit b749da
	FcPatternAddInteger (pattern, FC_HINT_STYLE,
Packit b749da
			     XftDefaultGetInteger (dpy, FC_HINT_STYLE, screen,
Packit b749da
						   FC_HINT_FULL));
Packit b749da
    }
Packit b749da
    if (FcPatternGet (pattern, FC_AUTOHINT, 0, &v) == FcResultNoMatch)
Packit b749da
    {
Packit b749da
	FcPatternAddBool (pattern, FC_AUTOHINT,
Packit b749da
			  XftDefaultGetBool (dpy, FC_AUTOHINT, screen,
Packit b749da
					     False));
Packit b749da
    }
Packit b749da
    if (FcPatternGet (pattern, FC_RGBA, 0, &v) == FcResultNoMatch)
Packit b749da
    {
Packit b749da
	int	subpixel = FC_RGBA_UNKNOWN;
Packit b749da
#if RENDER_MAJOR > 0 || RENDER_MINOR >= 6
Packit b749da
	if (XftDefaultHasRender (dpy))
Packit b749da
	{
Packit b749da
	    int render_order = XRenderQuerySubpixelOrder (dpy, screen);
Packit b749da
	    switch (render_order) {
Packit b749da
	    default:
Packit b749da
	    case SubPixelUnknown:	subpixel = FC_RGBA_UNKNOWN; break;
Packit b749da
	    case SubPixelHorizontalRGB:	subpixel = FC_RGBA_RGB; break;
Packit b749da
	    case SubPixelHorizontalBGR:	subpixel = FC_RGBA_BGR; break;
Packit b749da
	    case SubPixelVerticalRGB:	subpixel = FC_RGBA_VRGB; break;
Packit b749da
	    case SubPixelVerticalBGR:	subpixel = FC_RGBA_VBGR; break;
Packit b749da
	    case SubPixelNone:		subpixel = FC_RGBA_NONE; break;
Packit b749da
	    }
Packit b749da
	}
Packit b749da
#endif
Packit b749da
	FcPatternAddInteger (pattern, FC_RGBA,
Packit b749da
			      XftDefaultGetInteger (dpy, FC_RGBA, screen,
Packit b749da
						    subpixel));
Packit b749da
    }
Packit b749da
    if (FcPatternGet (pattern, FC_LCD_FILTER, 0, &v) == FcResultNoMatch)
Packit b749da
    {
Packit b749da
	FcPatternAddInteger (pattern, FC_LCD_FILTER,
Packit b749da
			     XftDefaultGetInteger (dpy, FC_LCD_FILTER, screen,
Packit b749da
						   FC_LCD_DEFAULT));
Packit b749da
    }
Packit b749da
    if (FcPatternGet (pattern, FC_MINSPACE, 0, &v) == FcResultNoMatch)
Packit b749da
    {
Packit b749da
	FcPatternAddBool (pattern, FC_MINSPACE,
Packit b749da
			   XftDefaultGetBool (dpy, FC_MINSPACE, screen,
Packit b749da
					      False));
Packit b749da
    }
Packit b749da
    if (FcPatternGet (pattern, FC_DPI, 0, &v) == FcResultNoMatch)
Packit b749da
    {
Packit b749da
	dpi = (((double) DisplayHeight (dpy, screen) * 25.4) /
Packit b749da
	       (double) DisplayHeightMM (dpy, screen));
Packit b749da
	FcPatternAddDouble (pattern, FC_DPI,
Packit b749da
			    XftDefaultGetDouble (dpy, FC_DPI, screen,
Packit b749da
						 dpi));
Packit b749da
    }
Packit b749da
    if (FcPatternGet (pattern, FC_SCALE, 0, &v) == FcResultNoMatch)
Packit b749da
    {
Packit b749da
	FcPatternAddDouble (pattern, FC_SCALE,
Packit b749da
			    XftDefaultGetDouble (dpy, FC_SCALE, screen, 1.0));
Packit b749da
    }
Packit b749da
    if (FcPatternGet (pattern, XFT_MAX_GLYPH_MEMORY, 0, &v) == FcResultNoMatch)
Packit b749da
    {
Packit b749da
	FcPatternAddInteger (pattern, XFT_MAX_GLYPH_MEMORY,
Packit b749da
			     XftDefaultGetInteger (dpy, XFT_MAX_GLYPH_MEMORY,
Packit b749da
						   screen,
Packit b749da
						   XFT_FONT_MAX_GLYPH_MEMORY));
Packit b749da
    }
Packit b749da
    FcDefaultSubstitute (pattern);
Packit b749da
}
Packit b749da