Blame src/xftdraw.c

Packit Service 1b8107
/*
Packit Service 1b8107
 * Copyright © 2000 Keith Packard
Packit Service 1b8107
 *
Packit Service 1b8107
 * Permission to use, copy, modify, distribute, and sell this software and its
Packit Service 1b8107
 * documentation for any purpose is hereby granted without fee, provided that
Packit Service 1b8107
 * the above copyright notice appear in all copies and that both that
Packit Service 1b8107
 * copyright notice and this permission notice appear in supporting
Packit Service 1b8107
 * documentation, and that the name of Keith Packard not be used in
Packit Service 1b8107
 * advertising or publicity pertaining to distribution of the software without
Packit Service 1b8107
 * specific, written prior permission.  Keith Packard makes no
Packit Service 1b8107
 * representations about the suitability of this software for any purpose.  It
Packit Service 1b8107
 * is provided "as is" without express or implied warranty.
Packit Service 1b8107
 *
Packit Service 1b8107
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
Packit Service 1b8107
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
Packit Service 1b8107
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
Packit Service 1b8107
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
Packit Service 1b8107
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
Packit Service 1b8107
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
Packit Service 1b8107
 * PERFORMANCE OF THIS SOFTWARE.
Packit Service 1b8107
 */
Packit Service 1b8107
Packit Service 1b8107
#include "xftint.h"
Packit Service 1b8107
Packit Service 1b8107
/*
Packit Service 1b8107
 * Ok, this is a pain.  To share source pictures across multiple destinations,
Packit Service 1b8107
 * the screen for each drawable must be discovered.
Packit Service 1b8107
 */
Packit Service 1b8107
Packit Service 1b8107
static int
Packit Service 1b8107
_XftDrawScreen (Display *dpy, Drawable drawable, Visual *visual)
Packit Service 1b8107
{
Packit Service 1b8107
    int		    s;
Packit Service 1b8107
    Window	    root;
Packit Service 1b8107
    int		    x, y;
Packit Service 1b8107
    unsigned int    width, height, borderWidth, depth;
Packit Service 1b8107
    /* Special case the most common environment */
Packit Service 1b8107
    if (ScreenCount (dpy) == 1)
Packit Service 1b8107
	return 0;
Packit Service 1b8107
    /*
Packit Service 1b8107
     * If we've got a visual, look for the screen that points at it.
Packit Service 1b8107
     * This requires no round trip.
Packit Service 1b8107
     */
Packit Service 1b8107
    if (visual)
Packit Service 1b8107
    {
Packit Service 1b8107
	for (s = 0; s < ScreenCount (dpy); s++)
Packit Service 1b8107
	{
Packit Service 1b8107
	    XVisualInfo	template, *ret;
Packit Service 1b8107
	    int		nret;
Packit Service 1b8107
Packit Service 1b8107
	    template.visualid = visual->visualid;
Packit Service 1b8107
	    template.screen = s;
Packit Service 1b8107
	    ret = XGetVisualInfo (dpy, VisualIDMask|VisualScreenMask,
Packit Service 1b8107
				  &template, &nret);
Packit Service 1b8107
	    if (ret)
Packit Service 1b8107
	    {
Packit Service 1b8107
		XFree (ret);
Packit Service 1b8107
		return s;
Packit Service 1b8107
	    }
Packit Service 1b8107
	}
Packit Service 1b8107
    }
Packit Service 1b8107
    /*
Packit Service 1b8107
     * Otherwise, as the server for the drawable geometry and find
Packit Service 1b8107
     * the screen from the root window.
Packit Service 1b8107
     * This takes a round trip.
Packit Service 1b8107
     */
Packit Service 1b8107
    if (XGetGeometry (dpy, drawable, &root, &x, &y, &width, &height,
Packit Service 1b8107
		      &borderWidth, &depth))
Packit Service 1b8107
    {
Packit Service 1b8107
	for (s = 0; s < ScreenCount (dpy); s++)
Packit Service 1b8107
	{
Packit Service 1b8107
	    if (RootWindow (dpy, s) == root)
Packit Service 1b8107
		return s;
Packit Service 1b8107
	}
Packit Service 1b8107
    }
Packit Service 1b8107
    /*
Packit Service 1b8107
     * Make a guess -- it's probably wrong, but then the app probably
Packit Service 1b8107
     * handed us a bogus drawable in this case
Packit Service 1b8107
     */
Packit Service 1b8107
    return 0;
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_HIDDEN unsigned int
Packit Service 1b8107
XftDrawDepth (XftDraw *draw)
Packit Service 1b8107
{
Packit Service 1b8107
    if (!draw->depth)
Packit Service 1b8107
    {
Packit Service 1b8107
	Window		    root;
Packit Service 1b8107
	int		    x, y;
Packit Service 1b8107
	unsigned int	    width, height, borderWidth, depth;
Packit Service 1b8107
	if (XGetGeometry (draw->dpy, draw->drawable,
Packit Service 1b8107
			  &root, &x, &y, &width, &height,
Packit Service 1b8107
			  &borderWidth, &depth))
Packit Service 1b8107
	    draw->depth = depth;
Packit Service 1b8107
    }
Packit Service 1b8107
    return draw->depth;
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_HIDDEN unsigned int
Packit Service 1b8107
XftDrawBitsPerPixel (XftDraw	*draw)
Packit Service 1b8107
{
Packit Service 1b8107
    if (!draw->bits_per_pixel)
Packit Service 1b8107
    {
Packit Service 1b8107
	XPixmapFormatValues *formats;
Packit Service 1b8107
	int		    nformats;
Packit Service 1b8107
	unsigned int	    depth;
Packit Service 1b8107
Packit Service 1b8107
	if ((depth = XftDrawDepth (draw)) &&
Packit Service 1b8107
	    (formats = XListPixmapFormats (draw->dpy, &nformats)))
Packit Service 1b8107
	{
Packit Service 1b8107
	    int	i;
Packit Service 1b8107
Packit Service 1b8107
	    for (i = 0; i < nformats; i++)
Packit Service 1b8107
	    {
Packit Service 1b8107
		if (formats[i].depth == depth)
Packit Service 1b8107
		{
Packit Service 1b8107
		    draw->bits_per_pixel = formats[i].bits_per_pixel;
Packit Service 1b8107
		    break;
Packit Service 1b8107
		}
Packit Service 1b8107
	    }
Packit Service 1b8107
	    XFree (formats);
Packit Service 1b8107
	}
Packit Service 1b8107
    }
Packit Service 1b8107
    return draw->bits_per_pixel;
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT XftDraw *
Packit Service 1b8107
XftDrawCreate (Display   *dpy,
Packit Service 1b8107
	       Drawable  drawable,
Packit Service 1b8107
	       Visual    *visual,
Packit Service 1b8107
	       Colormap  colormap)
Packit Service 1b8107
{
Packit Service 1b8107
    XftDraw	*draw;
Packit Service 1b8107
Packit Service 1b8107
    draw = (XftDraw *) malloc (sizeof (XftDraw));
Packit Service 1b8107
    if (!draw)
Packit Service 1b8107
	return NULL;
Packit Service 1b8107
Packit Service 1b8107
    draw->dpy = dpy;
Packit Service 1b8107
    draw->drawable = drawable;
Packit Service 1b8107
    draw->screen = _XftDrawScreen (dpy, drawable, visual);
Packit Service 1b8107
    draw->depth = 0;		/* don't find out unless we need to know */
Packit Service 1b8107
    draw->bits_per_pixel = 0;	/* don't find out unless we need to know */
Packit Service 1b8107
    draw->visual = visual;
Packit Service 1b8107
    draw->colormap = colormap;
Packit Service 1b8107
    draw->render.pict = 0;
Packit Service 1b8107
    draw->core.gc = NULL;
Packit Service 1b8107
    draw->core.use_pixmap = 0;
Packit Service 1b8107
    draw->clip_type = XftClipTypeNone;
Packit Service 1b8107
    draw->subwindow_mode = ClipByChildren;
Packit Service 1b8107
    XftMemAlloc (XFT_MEM_DRAW, sizeof (XftDraw));
Packit Service 1b8107
    return draw;
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT XftDraw *
Packit Service 1b8107
XftDrawCreateBitmap (Display	*dpy,
Packit Service 1b8107
		     Pixmap	bitmap)
Packit Service 1b8107
{
Packit Service 1b8107
    XftDraw	*draw;
Packit Service 1b8107
Packit Service 1b8107
    draw = (XftDraw *) malloc (sizeof (XftDraw));
Packit Service 1b8107
    if (!draw)
Packit Service 1b8107
	return NULL;
Packit Service 1b8107
    draw->dpy = dpy;
Packit Service 1b8107
    draw->drawable = (Drawable) bitmap;
Packit Service 1b8107
    draw->screen = _XftDrawScreen (dpy, bitmap, NULL);
Packit Service 1b8107
    draw->depth = 1;
Packit Service 1b8107
    draw->bits_per_pixel = 1;
Packit Service 1b8107
    draw->visual = NULL;
Packit Service 1b8107
    draw->colormap = 0;
Packit Service 1b8107
    draw->render.pict = 0;
Packit Service 1b8107
    draw->core.gc = NULL;
Packit Service 1b8107
    draw->core.use_pixmap = 0;
Packit Service 1b8107
    draw->clip_type = XftClipTypeNone;
Packit Service 1b8107
    draw->subwindow_mode = ClipByChildren;
Packit Service 1b8107
    XftMemAlloc (XFT_MEM_DRAW, sizeof (XftDraw));
Packit Service 1b8107
    return draw;
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT XftDraw *
Packit Service 1b8107
XftDrawCreateAlpha (Display *dpy,
Packit Service 1b8107
		    Pixmap  pixmap,
Packit Service 1b8107
		    int	    depth)
Packit Service 1b8107
{
Packit Service 1b8107
    XftDraw	*draw;
Packit Service 1b8107
Packit Service 1b8107
    draw = (XftDraw *) malloc (sizeof (XftDraw));
Packit Service 1b8107
    if (!draw)
Packit Service 1b8107
	return NULL;
Packit Service 1b8107
    draw->dpy = dpy;
Packit Service 1b8107
    draw->drawable = (Drawable) pixmap;
Packit Service 1b8107
    draw->screen = _XftDrawScreen (dpy, pixmap, NULL);
Packit Service 1b8107
    draw->depth = depth;
Packit Service 1b8107
    draw->bits_per_pixel = 0;	/* don't find out until we need it */
Packit Service 1b8107
    draw->visual = NULL;
Packit Service 1b8107
    draw->colormap = 0;
Packit Service 1b8107
    draw->render.pict = 0;
Packit Service 1b8107
    draw->core.gc = NULL;
Packit Service 1b8107
    draw->core.use_pixmap = 0;
Packit Service 1b8107
    draw->clip_type = XftClipTypeNone;
Packit Service 1b8107
    draw->subwindow_mode = ClipByChildren;
Packit Service 1b8107
    XftMemAlloc (XFT_MEM_DRAW, sizeof (XftDraw));
Packit Service 1b8107
    return draw;
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
static XRenderPictFormat *
Packit Service 1b8107
_XftDrawFormat (XftDraw	*draw)
Packit Service 1b8107
{
Packit Service 1b8107
    XftDisplayInfo  *info = _XftDisplayInfoGet (draw->dpy, True);
Packit Service 1b8107
Packit Service 1b8107
    if (!info || !info->hasRender)
Packit Service 1b8107
	return NULL;
Packit Service 1b8107
Packit Service 1b8107
    if (draw->visual == NULL)
Packit Service 1b8107
    {
Packit Service 1b8107
	XRenderPictFormat   pf;
Packit Service 1b8107
Packit Service 1b8107
	pf.type = PictTypeDirect;
Packit Service 1b8107
	pf.depth = XftDrawDepth (draw);
Packit Service 1b8107
	pf.direct.alpha = 0;
Packit Service 1b8107
	pf.direct.alphaMask = (1 << pf.depth) - 1;
Packit Service 1b8107
	return XRenderFindFormat (draw->dpy,
Packit Service 1b8107
				  (PictFormatType|
Packit Service 1b8107
				   PictFormatDepth|
Packit Service 1b8107
				   PictFormatAlpha|
Packit Service 1b8107
				   PictFormatAlphaMask),
Packit Service 1b8107
				  &pf,
Packit Service 1b8107
				  0);
Packit Service 1b8107
    }
Packit Service 1b8107
    else
Packit Service 1b8107
	return XRenderFindVisualFormat (draw->dpy, draw->visual);
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT void
Packit Service 1b8107
XftDrawChange (XftDraw	*draw,
Packit Service 1b8107
	       Drawable	drawable)
Packit Service 1b8107
{
Packit Service 1b8107
    draw->drawable = drawable;
Packit Service 1b8107
    if (draw->render.pict)
Packit Service 1b8107
    {
Packit Service 1b8107
	XRenderFreePicture (draw->dpy, draw->render.pict);
Packit Service 1b8107
	draw->render.pict = 0;
Packit Service 1b8107
    }
Packit Service 1b8107
    if (draw->core.gc)
Packit Service 1b8107
    {
Packit Service 1b8107
	XFreeGC (draw->dpy, draw->core.gc);
Packit Service 1b8107
	draw->core.gc = NULL;
Packit Service 1b8107
    }
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT Display *
Packit Service 1b8107
XftDrawDisplay (XftDraw *draw)
Packit Service 1b8107
{
Packit Service 1b8107
    return draw->dpy;
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT Drawable
Packit Service 1b8107
XftDrawDrawable (XftDraw *draw)
Packit Service 1b8107
{
Packit Service 1b8107
    return draw->drawable;
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT Colormap
Packit Service 1b8107
XftDrawColormap (XftDraw *draw)
Packit Service 1b8107
{
Packit Service 1b8107
    return draw->colormap;
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT Visual *
Packit Service 1b8107
XftDrawVisual (XftDraw *draw)
Packit Service 1b8107
{
Packit Service 1b8107
    return draw->visual;
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT void
Packit Service 1b8107
XftDrawDestroy (XftDraw	*draw)
Packit Service 1b8107
{
Packit Service 1b8107
    if (draw->render.pict)
Packit Service 1b8107
	XRenderFreePicture (draw->dpy, draw->render.pict);
Packit Service 1b8107
    if (draw->core.gc)
Packit Service 1b8107
	XFreeGC (draw->dpy, draw->core.gc);
Packit Service 1b8107
    switch (draw->clip_type) {
Packit Service 1b8107
    case XftClipTypeRegion:
Packit Service 1b8107
	XDestroyRegion (draw->clip.region);
Packit Service 1b8107
	break;
Packit Service 1b8107
    case XftClipTypeRectangles:
Packit Service 1b8107
	free (draw->clip.rect);
Packit Service 1b8107
	break;
Packit Service 1b8107
    case XftClipTypeNone:
Packit Service 1b8107
	break;
Packit Service 1b8107
    }
Packit Service 1b8107
    XftMemFree (XFT_MEM_DRAW, sizeof (XftDraw));
Packit Service 1b8107
    free (draw);
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT Picture
Packit Service 1b8107
XftDrawSrcPicture (XftDraw *draw, _Xconst XftColor *color)
Packit Service 1b8107
{
Packit Service 1b8107
    Display	    *dpy = draw->dpy;
Packit Service 1b8107
    XftDisplayInfo  *info = _XftDisplayInfoGet (dpy, True);
Packit Service 1b8107
    int		    i;
Packit Service 1b8107
    XftColor	    bitmapColor;
Packit Service 1b8107
Packit Service 1b8107
    if (!info || !info->solidFormat)
Packit Service 1b8107
	return 0;
Packit Service 1b8107
Packit Service 1b8107
    /*
Packit Service 1b8107
     * Monochrome targets require special handling; the PictOp controls
Packit Service 1b8107
     * the color, and the color must be opaque
Packit Service 1b8107
     */
Packit Service 1b8107
    if (!draw->visual && draw->depth == 1)
Packit Service 1b8107
    {
Packit Service 1b8107
	bitmapColor.color.alpha = 0xffff;
Packit Service 1b8107
	bitmapColor.color.red   = 0xffff;
Packit Service 1b8107
	bitmapColor.color.green = 0xffff;
Packit Service 1b8107
	bitmapColor.color.blue  = 0xffff;
Packit Service 1b8107
	color = &bitmapColor;
Packit Service 1b8107
    }
Packit Service 1b8107
Packit Service 1b8107
    /*
Packit Service 1b8107
     * See if there's one already available
Packit Service 1b8107
     */
Packit Service 1b8107
    for (i = 0; i < XFT_NUM_SOLID_COLOR; i++)
Packit Service 1b8107
    {
Packit Service 1b8107
	if (info->colors[i].pict &&
Packit Service 1b8107
	    info->colors[i].screen == draw->screen &&
Packit Service 1b8107
	    !memcmp ((void *) &color->color,
Packit Service 1b8107
		     (void *) &info->colors[i].color,
Packit Service 1b8107
		     sizeof (XRenderColor)))
Packit Service 1b8107
	    return info->colors[i].pict;
Packit Service 1b8107
    }
Packit Service 1b8107
    /*
Packit Service 1b8107
     * Pick one to replace at random
Packit Service 1b8107
     */
Packit Service 1b8107
    i = (unsigned int) rand () % XFT_NUM_SOLID_COLOR;
Packit Service 1b8107
Packit Service 1b8107
    if (info->hasSolid) {
Packit Service 1b8107
	/*
Packit Service 1b8107
	 * Free any existing entry
Packit Service 1b8107
	 */
Packit Service 1b8107
	if (info->colors[i].pict)
Packit Service 1b8107
	    XRenderFreePicture (dpy, info->colors[i].pict);
Packit Service 1b8107
	/*
Packit Service 1b8107
	 * Create picture
Packit Service 1b8107
	 */
Packit Service 1b8107
	info->colors[i].pict = XRenderCreateSolidFill (draw->dpy, &color->color);
Packit Service 1b8107
    } else {
Packit Service 1b8107
	if (info->colors[i].screen != draw->screen && info->colors[i].pict)
Packit Service 1b8107
	{
Packit Service 1b8107
	    XRenderFreePicture (dpy, info->colors[i].pict);
Packit Service 1b8107
	    info->colors[i].pict = 0;
Packit Service 1b8107
	}
Packit Service 1b8107
	/*
Packit Service 1b8107
	 * Create picture if necessary
Packit Service 1b8107
	 */
Packit Service 1b8107
	if (!info->colors[i].pict)
Packit Service 1b8107
	{
Packit Service 1b8107
	    Pixmap			    pix;
Packit Service 1b8107
	    XRenderPictureAttributes    pa;
Packit Service 1b8107
Packit Service 1b8107
	    pix = XCreatePixmap (dpy, RootWindow (dpy, draw->screen), 1, 1,
Packit Service 1b8107
				 info->solidFormat->depth);
Packit Service 1b8107
	    pa.repeat = True;
Packit Service 1b8107
	    info->colors[i].pict = XRenderCreatePicture (draw->dpy,
Packit Service 1b8107
							 pix,
Packit Service 1b8107
							 info->solidFormat,
Packit Service 1b8107
							 CPRepeat, &pa);
Packit Service 1b8107
	    XFreePixmap (dpy, pix);
Packit Service 1b8107
	}
Packit Service 1b8107
	/*
Packit Service 1b8107
	 * Set to the new color
Packit Service 1b8107
	 */
Packit Service 1b8107
	info->colors[i].color = color->color;
Packit Service 1b8107
	info->colors[i].screen = draw->screen;
Packit Service 1b8107
	XRenderFillRectangle (dpy, PictOpSrc,
Packit Service 1b8107
			      info->colors[i].pict,
Packit Service 1b8107
			      &color->color, 0, 0, 1, 1);
Packit Service 1b8107
    }
Packit Service 1b8107
    info->colors[i].color = color->color;
Packit Service 1b8107
    info->colors[i].screen = draw->screen;
Packit Service 1b8107
Packit Service 1b8107
    return info->colors[i].pict;
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
static int
Packit Service 1b8107
_XftDrawOp (_Xconst XftDraw *draw, _Xconst XftColor *color)
Packit Service 1b8107
{
Packit Service 1b8107
    if (draw->visual || draw->depth != 1)
Packit Service 1b8107
	return PictOpOver;
Packit Service 1b8107
    if (color->color.alpha >= 0x8000)
Packit Service 1b8107
	return PictOpOver;
Packit Service 1b8107
    return PictOpOutReverse;
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
static FcBool
Packit Service 1b8107
_XftDrawRenderPrepare (XftDraw	*draw)
Packit Service 1b8107
{
Packit Service 1b8107
    if (!draw->render.pict)
Packit Service 1b8107
    {
Packit Service 1b8107
	XRenderPictFormat	    *format;
Packit Service 1b8107
	XRenderPictureAttributes    pa;
Packit Service 1b8107
	unsigned long		    mask = 0;
Packit Service 1b8107
Packit Service 1b8107
	format = _XftDrawFormat (draw);
Packit Service 1b8107
	if (!format)
Packit Service 1b8107
	    return FcFalse;
Packit Service 1b8107
Packit Service 1b8107
	if (draw->subwindow_mode == IncludeInferiors)
Packit Service 1b8107
	{
Packit Service 1b8107
	    pa.subwindow_mode = IncludeInferiors;
Packit Service 1b8107
	    mask |= CPSubwindowMode;
Packit Service 1b8107
	}
Packit Service 1b8107
	draw->render.pict = XRenderCreatePicture (draw->dpy, draw->drawable,
Packit Service 1b8107
						  format, mask, &pa);
Packit Service 1b8107
	if (!draw->render.pict)
Packit Service 1b8107
	    return FcFalse;
Packit Service 1b8107
	switch (draw->clip_type) {
Packit Service 1b8107
	case XftClipTypeRegion:
Packit Service 1b8107
	    XRenderSetPictureClipRegion (draw->dpy, draw->render.pict,
Packit Service 1b8107
					 draw->clip.region);
Packit Service 1b8107
	    break;
Packit Service 1b8107
	case XftClipTypeRectangles:
Packit Service 1b8107
	    XRenderSetPictureClipRectangles (draw->dpy, draw->render.pict,
Packit Service 1b8107
					     draw->clip.rect->xOrigin,
Packit Service 1b8107
					     draw->clip.rect->yOrigin,
Packit Service 1b8107
					     XftClipRects(draw->clip.rect),
Packit Service 1b8107
					     draw->clip.rect->n);
Packit Service 1b8107
	    break;
Packit Service 1b8107
	case XftClipTypeNone:
Packit Service 1b8107
	    break;
Packit Service 1b8107
	}
Packit Service 1b8107
    }
Packit Service 1b8107
    return FcTrue;
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
static FcBool
Packit Service 1b8107
_XftDrawCorePrepare (XftDraw *draw, _Xconst XftColor *color)
Packit Service 1b8107
{
Packit Service 1b8107
    if (!draw->core.gc)
Packit Service 1b8107
    {
Packit Service 1b8107
	XGCValues	gcv;
Packit Service 1b8107
	unsigned long	mask = 0;
Packit Service 1b8107
	if (draw->subwindow_mode == IncludeInferiors)
Packit Service 1b8107
	{
Packit Service 1b8107
	    gcv.subwindow_mode = IncludeInferiors;
Packit Service 1b8107
	    mask |= GCSubwindowMode;
Packit Service 1b8107
	}
Packit Service 1b8107
	draw->core.gc = XCreateGC (draw->dpy, draw->drawable, mask, &gcv;;
Packit Service 1b8107
	if (!draw->core.gc)
Packit Service 1b8107
	    return FcFalse;
Packit Service 1b8107
	switch (draw->clip_type) {
Packit Service 1b8107
	case XftClipTypeRegion:
Packit Service 1b8107
	    XSetRegion (draw->dpy, draw->core.gc, draw->clip.region);
Packit Service 1b8107
	    break;
Packit Service 1b8107
	case XftClipTypeRectangles:
Packit Service 1b8107
	    XSetClipRectangles (draw->dpy, draw->core.gc,
Packit Service 1b8107
				draw->clip.rect->xOrigin,
Packit Service 1b8107
				draw->clip.rect->yOrigin,
Packit Service 1b8107
				XftClipRects (draw->clip.rect),
Packit Service 1b8107
				draw->clip.rect->n,
Packit Service 1b8107
				Unsorted);
Packit Service 1b8107
	    break;
Packit Service 1b8107
	case XftClipTypeNone:
Packit Service 1b8107
	    break;
Packit Service 1b8107
	}
Packit Service 1b8107
    }
Packit Service 1b8107
    XSetForeground (draw->dpy, draw->core.gc, color->pixel);
Packit Service 1b8107
    return FcTrue;
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT Picture
Packit Service 1b8107
XftDrawPicture (XftDraw *draw)
Packit Service 1b8107
{
Packit Service 1b8107
    if (!_XftDrawRenderPrepare (draw))
Packit Service 1b8107
	return 0;
Packit Service 1b8107
    return draw->render.pict;
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
#define NUM_LOCAL   1024
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT void
Packit Service 1b8107
XftDrawGlyphs (XftDraw		*draw,
Packit Service 1b8107
	       _Xconst XftColor	*color,
Packit Service 1b8107
	       XftFont		*pub,
Packit Service 1b8107
	       int		x,
Packit Service 1b8107
	       int		y,
Packit Service 1b8107
	       _Xconst FT_UInt	*glyphs,
Packit Service 1b8107
	       int		nglyphs)
Packit Service 1b8107
{
Packit Service 1b8107
    XftFontInt	*font = (XftFontInt *) pub;
Packit Service 1b8107
Packit Service 1b8107
    if (font->format)
Packit Service 1b8107
    {
Packit Service 1b8107
	Picture	    src;
Packit Service 1b8107
Packit Service 1b8107
	if (_XftDrawRenderPrepare (draw) &&
Packit Service 1b8107
	    (src = XftDrawSrcPicture (draw, color)))
Packit Service 1b8107
	    XftGlyphRender (draw->dpy, _XftDrawOp (draw, color),
Packit Service 1b8107
			     src, pub, draw->render.pict,
Packit Service 1b8107
			     0, 0, x, y, glyphs, nglyphs);
Packit Service 1b8107
    }
Packit Service 1b8107
    else
Packit Service 1b8107
    {
Packit Service 1b8107
	if (_XftDrawCorePrepare (draw, color))
Packit Service 1b8107
	    XftGlyphCore (draw, color, pub, x, y, glyphs, nglyphs);
Packit Service 1b8107
    }
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT void
Packit Service 1b8107
XftDrawString8 (XftDraw		    *draw,
Packit Service 1b8107
		_Xconst XftColor    *color,
Packit Service 1b8107
		XftFont		    *pub,
Packit Service 1b8107
		int		    x,
Packit Service 1b8107
		int		    y,
Packit Service 1b8107
		_Xconst FcChar8	    *string,
Packit Service 1b8107
		int		    len)
Packit Service 1b8107
{
Packit Service 1b8107
    FT_UInt	    *glyphs, glyphs_local[NUM_LOCAL];
Packit Service 1b8107
    int		    i;
Packit Service 1b8107
Packit Service 1b8107
    if (XftDebug () & XFT_DBG_DRAW)
Packit Service 1b8107
	printf ("DrawString \"%*.*s\"\n", len, len, string);
Packit Service 1b8107
Packit Service 1b8107
    if (len <= NUM_LOCAL)
Packit Service 1b8107
	glyphs = glyphs_local;
Packit Service 1b8107
    else
Packit Service 1b8107
    {
Packit Service 1b8107
	glyphs = malloc (len * sizeof (FT_UInt));
Packit Service 1b8107
	if (!glyphs)
Packit Service 1b8107
	    return;
Packit Service 1b8107
    }
Packit Service 1b8107
    for (i = 0; i < len; i++)
Packit Service 1b8107
	glyphs[i] = XftCharIndex (draw->dpy, pub, string[i]);
Packit Service 1b8107
    XftDrawGlyphs (draw, color, pub, x, y, glyphs, len);
Packit Service 1b8107
    if (glyphs != glyphs_local)
Packit Service 1b8107
	free (glyphs);
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT void
Packit Service 1b8107
XftDrawString16 (XftDraw	    *draw,
Packit Service 1b8107
		 _Xconst XftColor   *color,
Packit Service 1b8107
		 XftFont	    *pub,
Packit Service 1b8107
		 int		    x,
Packit Service 1b8107
		 int		    y,
Packit Service 1b8107
		 _Xconst FcChar16   *string,
Packit Service 1b8107
		 int		    len)
Packit Service 1b8107
{
Packit Service 1b8107
    FT_UInt	    *glyphs, glyphs_local[NUM_LOCAL];
Packit Service 1b8107
    int		    i;
Packit Service 1b8107
Packit Service 1b8107
    if (len <= NUM_LOCAL)
Packit Service 1b8107
	glyphs = glyphs_local;
Packit Service 1b8107
    else
Packit Service 1b8107
    {
Packit Service 1b8107
	glyphs = malloc (len * sizeof (FT_UInt));
Packit Service 1b8107
	if (!glyphs)
Packit Service 1b8107
	    return;
Packit Service 1b8107
    }
Packit Service 1b8107
    for (i = 0; i < len; i++)
Packit Service 1b8107
	glyphs[i] = XftCharIndex (draw->dpy, pub, string[i]);
Packit Service 1b8107
Packit Service 1b8107
    XftDrawGlyphs (draw, color, pub, x, y, glyphs, len);
Packit Service 1b8107
    if (glyphs != glyphs_local)
Packit Service 1b8107
	free (glyphs);
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT void
Packit Service 1b8107
XftDrawString32 (XftDraw	    *draw,
Packit Service 1b8107
		 _Xconst XftColor   *color,
Packit Service 1b8107
		 XftFont	    *pub,
Packit Service 1b8107
		 int		    x,
Packit Service 1b8107
		 int		    y,
Packit Service 1b8107
		 _Xconst FcChar32   *string,
Packit Service 1b8107
		 int		    len)
Packit Service 1b8107
{
Packit Service 1b8107
    FT_UInt	    *glyphs, glyphs_local[NUM_LOCAL];
Packit Service 1b8107
    int		    i;
Packit Service 1b8107
Packit Service 1b8107
    if (len <= NUM_LOCAL)
Packit Service 1b8107
	glyphs = glyphs_local;
Packit Service 1b8107
    else
Packit Service 1b8107
    {
Packit Service 1b8107
	glyphs = malloc (len * sizeof (FT_UInt));
Packit Service 1b8107
	if (!glyphs)
Packit Service 1b8107
	    return;
Packit Service 1b8107
    }
Packit Service 1b8107
    for (i = 0; i < len; i++)
Packit Service 1b8107
	glyphs[i] = XftCharIndex (draw->dpy, pub, string[i]);
Packit Service 1b8107
Packit Service 1b8107
    XftDrawGlyphs (draw, color, pub, x, y, glyphs, len);
Packit Service 1b8107
    if (glyphs != glyphs_local)
Packit Service 1b8107
	free (glyphs);
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT void
Packit Service 1b8107
XftDrawStringUtf8 (XftDraw	    *draw,
Packit Service 1b8107
		   _Xconst XftColor *color,
Packit Service 1b8107
		   XftFont	    *pub,
Packit Service 1b8107
		   int		    x,
Packit Service 1b8107
		   int		    y,
Packit Service 1b8107
		   _Xconst FcChar8  *string,
Packit Service 1b8107
		   int		    len)
Packit Service 1b8107
{
Packit Service 1b8107
    FT_UInt	    *glyphs, *glyphs_new, glyphs_local[NUM_LOCAL];
Packit Service 1b8107
    FcChar32	    ucs4;
Packit Service 1b8107
    int		    i;
Packit Service 1b8107
    int		    l;
Packit Service 1b8107
    int		    size;
Packit Service 1b8107
Packit Service 1b8107
    i = 0;
Packit Service 1b8107
    glyphs = glyphs_local;
Packit Service 1b8107
    size = NUM_LOCAL;
Packit Service 1b8107
    while (len && (l = FcUtf8ToUcs4 (string, &ucs4, len)) > 0)
Packit Service 1b8107
    {
Packit Service 1b8107
	if (i == size)
Packit Service 1b8107
	{
Packit Service 1b8107
	    glyphs_new = malloc (size * 2 * sizeof (FT_UInt));
Packit Service 1b8107
	    if (!glyphs_new)
Packit Service 1b8107
	    {
Packit Service 1b8107
		if (glyphs != glyphs_local)
Packit Service 1b8107
		    free (glyphs);
Packit Service 1b8107
		return;
Packit Service 1b8107
	    }
Packit Service 1b8107
	    memcpy (glyphs_new, glyphs, size * sizeof (FT_UInt));
Packit Service 1b8107
	    size *= 2;
Packit Service 1b8107
	    if (glyphs != glyphs_local)
Packit Service 1b8107
		free (glyphs);
Packit Service 1b8107
	    glyphs = glyphs_new;
Packit Service 1b8107
	}
Packit Service 1b8107
	glyphs[i++] = XftCharIndex (draw->dpy, pub, ucs4);
Packit Service 1b8107
	string += l;
Packit Service 1b8107
	len -= l;
Packit Service 1b8107
    }
Packit Service 1b8107
    XftDrawGlyphs (draw, color, pub, x, y, glyphs, i);
Packit Service 1b8107
    if (glyphs != glyphs_local)
Packit Service 1b8107
	free (glyphs);
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT void
Packit Service 1b8107
XftDrawStringUtf16 (XftDraw		*draw,
Packit Service 1b8107
		    _Xconst XftColor	*color,
Packit Service 1b8107
		    XftFont		*pub,
Packit Service 1b8107
		    int			x,
Packit Service 1b8107
		    int			y,
Packit Service 1b8107
		    _Xconst FcChar8	*string,
Packit Service 1b8107
		    FcEndian		endian,
Packit Service 1b8107
		    int			len)
Packit Service 1b8107
{
Packit Service 1b8107
    FT_UInt	    *glyphs, *glyphs_new, glyphs_local[NUM_LOCAL];
Packit Service 1b8107
    FcChar32	    ucs4;
Packit Service 1b8107
    int		    i;
Packit Service 1b8107
    int		    l;
Packit Service 1b8107
    int		    size;
Packit Service 1b8107
Packit Service 1b8107
    i = 0;
Packit Service 1b8107
    glyphs = glyphs_local;
Packit Service 1b8107
    size = NUM_LOCAL;
Packit Service 1b8107
    while (len && (l = FcUtf16ToUcs4 (string, endian, &ucs4, len)) > 0)
Packit Service 1b8107
    {
Packit Service 1b8107
	if (i == size)
Packit Service 1b8107
	{
Packit Service 1b8107
	    glyphs_new = malloc (size * 2 * sizeof (FT_UInt));
Packit Service 1b8107
	    if (!glyphs_new)
Packit Service 1b8107
	    {
Packit Service 1b8107
		if (glyphs != glyphs_local)
Packit Service 1b8107
		    free (glyphs);
Packit Service 1b8107
		return;
Packit Service 1b8107
	    }
Packit Service 1b8107
	    memcpy (glyphs_new, glyphs, size * sizeof (FT_UInt));
Packit Service 1b8107
	    size *= 2;
Packit Service 1b8107
	    if (glyphs != glyphs_local)
Packit Service 1b8107
		free (glyphs);
Packit Service 1b8107
	    glyphs = glyphs_new;
Packit Service 1b8107
	}
Packit Service 1b8107
	glyphs[i++] = XftCharIndex (draw->dpy, pub, ucs4);
Packit Service 1b8107
	string += l;
Packit Service 1b8107
	len -= l;
Packit Service 1b8107
    }
Packit Service 1b8107
    XftDrawGlyphs (draw, color, pub, x, y, glyphs, i);
Packit Service 1b8107
    if (glyphs != glyphs_local)
Packit Service 1b8107
	free (glyphs);
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT void
Packit Service 1b8107
XftDrawGlyphSpec (XftDraw		*draw,
Packit Service 1b8107
		  _Xconst XftColor	*color,
Packit Service 1b8107
		  XftFont		*pub,
Packit Service 1b8107
		  _Xconst XftGlyphSpec	*glyphs,
Packit Service 1b8107
		  int			len)
Packit Service 1b8107
{
Packit Service 1b8107
    XftFontInt	*font = (XftFontInt *) pub;
Packit Service 1b8107
Packit Service 1b8107
    if (font->format)
Packit Service 1b8107
    {
Packit Service 1b8107
	Picture	src;
Packit Service 1b8107
Packit Service 1b8107
	if (_XftDrawRenderPrepare (draw) &&
Packit Service 1b8107
	    (src = XftDrawSrcPicture (draw, color)))
Packit Service 1b8107
	{
Packit Service 1b8107
	    XftGlyphSpecRender (draw->dpy, _XftDrawOp (draw, color),
Packit Service 1b8107
				src, pub, draw->render.pict,
Packit Service 1b8107
				0, 0, glyphs, len);
Packit Service 1b8107
	}
Packit Service 1b8107
    }
Packit Service 1b8107
    else
Packit Service 1b8107
    {
Packit Service 1b8107
	if (_XftDrawCorePrepare (draw, color))
Packit Service 1b8107
	    XftGlyphSpecCore (draw, color, pub, glyphs, len);
Packit Service 1b8107
    }
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT void
Packit Service 1b8107
XftDrawGlyphFontSpec (XftDraw			*draw,
Packit Service 1b8107
		      _Xconst XftColor		*color,
Packit Service 1b8107
		      _Xconst XftGlyphFontSpec	*glyphs,
Packit Service 1b8107
		      int			len)
Packit Service 1b8107
{
Packit Service 1b8107
    int		i;
Packit Service 1b8107
    int		start;
Packit Service 1b8107
Packit Service 1b8107
    i = 0;
Packit Service 1b8107
    while (i < len)
Packit Service 1b8107
    {
Packit Service 1b8107
	start = i;
Packit Service 1b8107
	if (((XftFontInt *) glyphs[i].font)->format)
Packit Service 1b8107
	{
Packit Service 1b8107
	    Picture	src;
Packit Service 1b8107
	    while (i < len && ((XftFontInt *) glyphs[i].font)->format)
Packit Service 1b8107
		i++;
Packit Service 1b8107
	    if (_XftDrawRenderPrepare (draw) &&
Packit Service 1b8107
		(src = XftDrawSrcPicture (draw, color)))
Packit Service 1b8107
	    {
Packit Service 1b8107
		XftGlyphFontSpecRender (draw->dpy, _XftDrawOp (draw, color),
Packit Service 1b8107
					src, draw->render.pict,
Packit Service 1b8107
					0, 0, glyphs + start , i - start);
Packit Service 1b8107
	    }
Packit Service 1b8107
	}
Packit Service 1b8107
	else
Packit Service 1b8107
	{
Packit Service 1b8107
	    while (i < len && !((XftFontInt *) glyphs[i].font)->format)
Packit Service 1b8107
		i++;
Packit Service 1b8107
	    if (_XftDrawCorePrepare (draw, color))
Packit Service 1b8107
		XftGlyphFontSpecCore (draw, color, glyphs + start, i - start);
Packit Service 1b8107
	}
Packit Service 1b8107
    }
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT void
Packit Service 1b8107
XftDrawCharSpec (XftDraw		*draw,
Packit Service 1b8107
		 _Xconst XftColor	*color,
Packit Service 1b8107
		 XftFont		*pub,
Packit Service 1b8107
		 _Xconst XftCharSpec	*chars,
Packit Service 1b8107
		 int			len)
Packit Service 1b8107
{
Packit Service 1b8107
    XftGlyphSpec    *glyphs, glyphs_local[NUM_LOCAL];
Packit Service 1b8107
    int		    i;
Packit Service 1b8107
Packit Service 1b8107
    if (len <= NUM_LOCAL)
Packit Service 1b8107
	glyphs = glyphs_local;
Packit Service 1b8107
    else
Packit Service 1b8107
    {
Packit Service 1b8107
	glyphs = malloc (len * sizeof (XftGlyphSpec));
Packit Service 1b8107
	if (!glyphs)
Packit Service 1b8107
	    return;
Packit Service 1b8107
    }
Packit Service 1b8107
    for (i = 0; i < len; i++)
Packit Service 1b8107
    {
Packit Service 1b8107
	glyphs[i].glyph = XftCharIndex(draw->dpy, pub, chars[i].ucs4);
Packit Service 1b8107
	glyphs[i].x = chars[i].x;
Packit Service 1b8107
	glyphs[i].y = chars[i].y;
Packit Service 1b8107
    }
Packit Service 1b8107
Packit Service 1b8107
    XftDrawGlyphSpec (draw, color, pub, glyphs, len);
Packit Service 1b8107
    if (glyphs != glyphs_local)
Packit Service 1b8107
	free (glyphs);
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT void
Packit Service 1b8107
XftDrawCharFontSpec (XftDraw			*draw,
Packit Service 1b8107
		     _Xconst XftColor		*color,
Packit Service 1b8107
		     _Xconst XftCharFontSpec	*chars,
Packit Service 1b8107
		     int			len)
Packit Service 1b8107
{
Packit Service 1b8107
    XftGlyphFontSpec	*glyphs, glyphs_local[NUM_LOCAL];
Packit Service 1b8107
    int			i;
Packit Service 1b8107
Packit Service 1b8107
    if (len <= NUM_LOCAL)
Packit Service 1b8107
	glyphs = glyphs_local;
Packit Service 1b8107
    else
Packit Service 1b8107
    {
Packit Service 1b8107
	glyphs = malloc (len * sizeof (XftGlyphFontSpec));
Packit Service 1b8107
	if (!glyphs)
Packit Service 1b8107
	    return;
Packit Service 1b8107
    }
Packit Service 1b8107
    for (i = 0; i < len; i++)
Packit Service 1b8107
    {
Packit Service 1b8107
	glyphs[i].font = chars[i].font;
Packit Service 1b8107
	glyphs[i].glyph = XftCharIndex(draw->dpy, glyphs[i].font, chars[i].ucs4);
Packit Service 1b8107
	glyphs[i].x = chars[i].x;
Packit Service 1b8107
	glyphs[i].y = chars[i].y;
Packit Service 1b8107
    }
Packit Service 1b8107
Packit Service 1b8107
    XftDrawGlyphFontSpec (draw, color, glyphs, len);
Packit Service 1b8107
    if (glyphs != glyphs_local)
Packit Service 1b8107
	free (glyphs);
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT void
Packit Service 1b8107
XftDrawRect (XftDraw		*draw,
Packit Service 1b8107
	     _Xconst XftColor	*color,
Packit Service 1b8107
	     int		x,
Packit Service 1b8107
	     int		y,
Packit Service 1b8107
	     unsigned int	width,
Packit Service 1b8107
	     unsigned int	height)
Packit Service 1b8107
{
Packit Service 1b8107
    if (_XftDrawRenderPrepare (draw))
Packit Service 1b8107
    {
Packit Service 1b8107
	XRenderFillRectangle (draw->dpy, PictOpSrc, draw->render.pict,
Packit Service 1b8107
			      &color->color, x, y, width, height);
Packit Service 1b8107
    }
Packit Service 1b8107
    else if (_XftDrawCorePrepare (draw, color))
Packit Service 1b8107
    {
Packit Service 1b8107
	/* note: not XftRectCore() */
Packit Service 1b8107
	XSetForeground (draw->dpy, draw->core.gc, color->pixel);
Packit Service 1b8107
	XFillRectangle (draw->dpy, draw->drawable, draw->core.gc,
Packit Service 1b8107
			x, y, width, height);
Packit Service 1b8107
    }
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT Bool
Packit Service 1b8107
XftDrawSetClip (XftDraw	*draw,
Packit Service 1b8107
		Region	r)
Packit Service 1b8107
{
Packit Service 1b8107
    Region			n = NULL;
Packit Service 1b8107
Packit Service 1b8107
    /*
Packit Service 1b8107
     * Check for quick exits
Packit Service 1b8107
     */
Packit Service 1b8107
    if (!r && draw->clip_type == XftClipTypeNone)
Packit Service 1b8107
	return True;
Packit Service 1b8107
Packit Service 1b8107
    if (r &&
Packit Service 1b8107
	draw->clip_type == XftClipTypeRegion &&
Packit Service 1b8107
	XEqualRegion (r, draw->clip.region))
Packit Service 1b8107
    {
Packit Service 1b8107
	return True;
Packit Service 1b8107
    }
Packit Service 1b8107
Packit Service 1b8107
    /*
Packit Service 1b8107
     * Duplicate the region so future changes can be short circuited
Packit Service 1b8107
     */
Packit Service 1b8107
    if (r)
Packit Service 1b8107
    {
Packit Service 1b8107
	n = XCreateRegion ();
Packit Service 1b8107
	if (n)
Packit Service 1b8107
	{
Packit Service 1b8107
	    if (!XUnionRegion (n, r, n))
Packit Service 1b8107
	    {
Packit Service 1b8107
		XDestroyRegion (n);
Packit Service 1b8107
		return False;
Packit Service 1b8107
	    }
Packit Service 1b8107
	}
Packit Service 1b8107
    }
Packit Service 1b8107
Packit Service 1b8107
    /*
Packit Service 1b8107
     * Destroy existing clip
Packit Service 1b8107
     */
Packit Service 1b8107
    switch (draw->clip_type) {
Packit Service 1b8107
    case XftClipTypeRegion:
Packit Service 1b8107
	XDestroyRegion (draw->clip.region);
Packit Service 1b8107
	break;
Packit Service 1b8107
    case XftClipTypeRectangles:
Packit Service 1b8107
	free (draw->clip.rect);
Packit Service 1b8107
	break;
Packit Service 1b8107
    case XftClipTypeNone:
Packit Service 1b8107
	break;
Packit Service 1b8107
    }
Packit Service 1b8107
Packit Service 1b8107
    /*
Packit Service 1b8107
     * Set the clip
Packit Service 1b8107
     */
Packit Service 1b8107
    if (n)
Packit Service 1b8107
    {
Packit Service 1b8107
	draw->clip_type = XftClipTypeRegion;
Packit Service 1b8107
	draw->clip.region = n;
Packit Service 1b8107
    }
Packit Service 1b8107
    else
Packit Service 1b8107
    {
Packit Service 1b8107
	draw->clip_type = XftClipTypeNone;
Packit Service 1b8107
    }
Packit Service 1b8107
    /*
Packit Service 1b8107
     * Apply new clip to existing objects
Packit Service 1b8107
     */
Packit Service 1b8107
    if (draw->render.pict)
Packit Service 1b8107
    {
Packit Service 1b8107
	if (n)
Packit Service 1b8107
	    XRenderSetPictureClipRegion (draw->dpy, draw->render.pict, n);
Packit Service 1b8107
	else
Packit Service 1b8107
	{
Packit Service 1b8107
	    XRenderPictureAttributes	pa;
Packit Service 1b8107
	    pa.clip_mask = None;
Packit Service 1b8107
	    XRenderChangePicture (draw->dpy, draw->render.pict,
Packit Service 1b8107
				  CPClipMask, &pa);
Packit Service 1b8107
	}
Packit Service 1b8107
    }
Packit Service 1b8107
    if (draw->core.gc)
Packit Service 1b8107
    {
Packit Service 1b8107
	if (n)
Packit Service 1b8107
	    XSetRegion (draw->dpy, draw->core.gc, draw->clip.region);
Packit Service 1b8107
	else
Packit Service 1b8107
	    XSetClipMask (draw->dpy, draw->core.gc, None);
Packit Service 1b8107
    }
Packit Service 1b8107
    return True;
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT Bool
Packit Service 1b8107
XftDrawSetClipRectangles (XftDraw		*draw,
Packit Service 1b8107
			  int			xOrigin,
Packit Service 1b8107
			  int			yOrigin,
Packit Service 1b8107
			  _Xconst XRectangle	*rects,
Packit Service 1b8107
			  int			n)
Packit Service 1b8107
{
Packit Service 1b8107
    XftClipRect	*new = NULL;
Packit Service 1b8107
Packit Service 1b8107
    /*
Packit Service 1b8107
     * Check for quick exit
Packit Service 1b8107
     */
Packit Service 1b8107
    if (draw->clip_type == XftClipTypeRectangles &&
Packit Service 1b8107
	draw->clip.rect->n == n &&
Packit Service 1b8107
	(n == 0 || (draw->clip.rect->xOrigin == xOrigin &&
Packit Service 1b8107
		    draw->clip.rect->yOrigin == yOrigin)) &&
Packit Service 1b8107
	!memcmp (XftClipRects (draw->clip.rect), rects, n * sizeof (XRectangle)))
Packit Service 1b8107
    {
Packit Service 1b8107
	return True;
Packit Service 1b8107
    }
Packit Service 1b8107
Packit Service 1b8107
    /*
Packit Service 1b8107
     * Duplicate the region so future changes can be short circuited
Packit Service 1b8107
     */
Packit Service 1b8107
    new = malloc (sizeof (XftClipRect) + n * sizeof (XRectangle));
Packit Service 1b8107
    if (!new)
Packit Service 1b8107
	return False;
Packit Service 1b8107
Packit Service 1b8107
    new->n = n;
Packit Service 1b8107
    new->xOrigin = xOrigin;
Packit Service 1b8107
    new->yOrigin = yOrigin;
Packit Service 1b8107
    memcpy (XftClipRects (new), rects, n * sizeof (XRectangle));
Packit Service 1b8107
Packit Service 1b8107
    /*
Packit Service 1b8107
     * Destroy existing clip
Packit Service 1b8107
     */
Packit Service 1b8107
    switch (draw->clip_type) {
Packit Service 1b8107
    case XftClipTypeRegion:
Packit Service 1b8107
	XDestroyRegion (draw->clip.region);
Packit Service 1b8107
	break;
Packit Service 1b8107
    case XftClipTypeRectangles:
Packit Service 1b8107
	free (draw->clip.rect);
Packit Service 1b8107
	break;
Packit Service 1b8107
    case XftClipTypeNone:
Packit Service 1b8107
	break;
Packit Service 1b8107
    }
Packit Service 1b8107
Packit Service 1b8107
    /*
Packit Service 1b8107
     * Set the clip
Packit Service 1b8107
     */
Packit Service 1b8107
    draw->clip_type = XftClipTypeRectangles;
Packit Service 1b8107
    draw->clip.rect = new;
Packit Service 1b8107
    /*
Packit Service 1b8107
     * Apply new clip to existing objects
Packit Service 1b8107
     */
Packit Service 1b8107
    if (draw->render.pict)
Packit Service 1b8107
    {
Packit Service 1b8107
	XRenderSetPictureClipRectangles (draw->dpy, draw->render.pict,
Packit Service 1b8107
					 new->xOrigin,
Packit Service 1b8107
					 new->yOrigin,
Packit Service 1b8107
					 XftClipRects(new),
Packit Service 1b8107
					 new->n);
Packit Service 1b8107
    }
Packit Service 1b8107
    if (draw->core.gc)
Packit Service 1b8107
    {
Packit Service 1b8107
	XSetClipRectangles (draw->dpy, draw->core.gc,
Packit Service 1b8107
			    new->xOrigin,
Packit Service 1b8107
			    new->yOrigin,
Packit Service 1b8107
			    XftClipRects (new),
Packit Service 1b8107
			    new->n,
Packit Service 1b8107
			    Unsorted);
Packit Service 1b8107
    }
Packit Service 1b8107
    return True;
Packit Service 1b8107
}
Packit Service 1b8107
Packit Service 1b8107
_X_EXPORT void
Packit Service 1b8107
XftDrawSetSubwindowMode (XftDraw *draw, int mode)
Packit Service 1b8107
{
Packit Service 1b8107
    if (mode == draw->subwindow_mode)
Packit Service 1b8107
	return;
Packit Service 1b8107
    draw->subwindow_mode = mode;
Packit Service 1b8107
    if (draw->render.pict)
Packit Service 1b8107
    {
Packit Service 1b8107
	XRenderPictureAttributes    pa;
Packit Service 1b8107
Packit Service 1b8107
	pa.subwindow_mode = mode;
Packit Service 1b8107
	XRenderChangePicture (draw->dpy, draw->render.pict,
Packit Service 1b8107
			      CPSubwindowMode, &pa);
Packit Service 1b8107
    }
Packit Service 1b8107
    if (draw->core.gc)
Packit Service 1b8107
	XSetSubwindowMode (draw->dpy, draw->core.gc, mode);
Packit Service 1b8107
}