xftdraw.c revision 0d590c07
1c76ae52dSmrg/* 2c76ae52dSmrg * Copyright © 2000 Keith Packard 3c76ae52dSmrg * 4c76ae52dSmrg * Permission to use, copy, modify, distribute, and sell this software and its 5c76ae52dSmrg * documentation for any purpose is hereby granted without fee, provided that 6c76ae52dSmrg * the above copyright notice appear in all copies and that both that 7c76ae52dSmrg * copyright notice and this permission notice appear in supporting 8c76ae52dSmrg * documentation, and that the name of Keith Packard not be used in 9c76ae52dSmrg * advertising or publicity pertaining to distribution of the software without 10c76ae52dSmrg * specific, written prior permission. Keith Packard makes no 11c76ae52dSmrg * representations about the suitability of this software for any purpose. It 12c76ae52dSmrg * is provided "as is" without express or implied warranty. 13c76ae52dSmrg * 14c76ae52dSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15c76ae52dSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16c76ae52dSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17c76ae52dSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18c76ae52dSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19c76ae52dSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20c76ae52dSmrg * PERFORMANCE OF THIS SOFTWARE. 21c76ae52dSmrg */ 22c76ae52dSmrg 23c76ae52dSmrg#include "xftint.h" 24c76ae52dSmrg 25c76ae52dSmrg/* 26c76ae52dSmrg * Ok, this is a pain. To share source pictures across multiple destinations, 27c76ae52dSmrg * the screen for each drawable must be discovered. 28c76ae52dSmrg */ 29c76ae52dSmrg 30c76ae52dSmrgstatic int 31c76ae52dSmrg_XftDrawScreen (Display *dpy, Drawable drawable, Visual *visual) 32c76ae52dSmrg{ 33c76ae52dSmrg int s; 34c76ae52dSmrg Window root; 35c76ae52dSmrg int x, y; 36c76ae52dSmrg unsigned int width, height, borderWidth, depth; 37c76ae52dSmrg /* Special case the most common environment */ 38c76ae52dSmrg if (ScreenCount (dpy) == 1) 39c76ae52dSmrg return 0; 40c76ae52dSmrg /* 41c76ae52dSmrg * If we've got a visual, look for the screen that points at it. 42c76ae52dSmrg * This requires no round trip. 43c76ae52dSmrg */ 44c76ae52dSmrg if (visual) 45c76ae52dSmrg { 46c76ae52dSmrg for (s = 0; s < ScreenCount (dpy); s++) 47c76ae52dSmrg { 48c76ae52dSmrg XVisualInfo template, *ret; 49c76ae52dSmrg int nret; 50c76ae52dSmrg 51c76ae52dSmrg template.visualid = visual->visualid; 52c76ae52dSmrg template.screen = s; 53c76ae52dSmrg ret = XGetVisualInfo (dpy, VisualIDMask|VisualScreenMask, 54c76ae52dSmrg &template, &nret); 55c76ae52dSmrg if (ret) 56c76ae52dSmrg { 57c76ae52dSmrg XFree (ret); 58c76ae52dSmrg return s; 59c76ae52dSmrg } 60c76ae52dSmrg } 61c76ae52dSmrg } 62c76ae52dSmrg /* 63c76ae52dSmrg * Otherwise, as the server for the drawable geometry and find 64c76ae52dSmrg * the screen from the root window. 65c76ae52dSmrg * This takes a round trip. 66c76ae52dSmrg */ 67c76ae52dSmrg if (XGetGeometry (dpy, drawable, &root, &x, &y, &width, &height, 68c76ae52dSmrg &borderWidth, &depth)) 69c76ae52dSmrg { 70c76ae52dSmrg for (s = 0; s < ScreenCount (dpy); s++) 71c76ae52dSmrg { 72c76ae52dSmrg if (RootWindow (dpy, s) == root) 73c76ae52dSmrg return s; 74c76ae52dSmrg } 75c76ae52dSmrg } 76c76ae52dSmrg /* 77c76ae52dSmrg * Make a guess -- it's probably wrong, but then the app probably 78c76ae52dSmrg * handed us a bogus drawable in this case 79c76ae52dSmrg */ 80c76ae52dSmrg return 0; 81c76ae52dSmrg} 82c76ae52dSmrg 83c76ae52dSmrg_X_HIDDEN unsigned int 84c76ae52dSmrgXftDrawDepth (XftDraw *draw) 85c76ae52dSmrg{ 86c76ae52dSmrg if (!draw->depth) 87c76ae52dSmrg { 88c76ae52dSmrg Window root; 89c76ae52dSmrg int x, y; 90c76ae52dSmrg unsigned int width, height, borderWidth, depth; 91c76ae52dSmrg if (XGetGeometry (draw->dpy, draw->drawable, 92c76ae52dSmrg &root, &x, &y, &width, &height, 93c76ae52dSmrg &borderWidth, &depth)) 94c76ae52dSmrg draw->depth = depth; 95c76ae52dSmrg } 96c76ae52dSmrg return draw->depth; 97c76ae52dSmrg} 98c76ae52dSmrg 99c76ae52dSmrg_X_HIDDEN unsigned int 100c76ae52dSmrgXftDrawBitsPerPixel (XftDraw *draw) 101c76ae52dSmrg{ 102c76ae52dSmrg if (!draw->bits_per_pixel) 103c76ae52dSmrg { 104c76ae52dSmrg XPixmapFormatValues *formats; 105c76ae52dSmrg int nformats; 106c76ae52dSmrg unsigned int depth; 107c76ae52dSmrg 108c76ae52dSmrg if ((depth = XftDrawDepth (draw)) && 109c76ae52dSmrg (formats = XListPixmapFormats (draw->dpy, &nformats))) 110c76ae52dSmrg { 111c76ae52dSmrg int i; 112c76ae52dSmrg 113c76ae52dSmrg for (i = 0; i < nformats; i++) 114c76ae52dSmrg { 115c76ae52dSmrg if (formats[i].depth == depth) 116c76ae52dSmrg { 117c76ae52dSmrg draw->bits_per_pixel = formats[i].bits_per_pixel; 118c76ae52dSmrg break; 119c76ae52dSmrg } 120c76ae52dSmrg } 121c76ae52dSmrg XFree (formats); 122c76ae52dSmrg } 123c76ae52dSmrg } 124c76ae52dSmrg return draw->bits_per_pixel; 125c76ae52dSmrg} 126c76ae52dSmrg 127c76ae52dSmrg_X_EXPORT XftDraw * 128c76ae52dSmrgXftDrawCreate (Display *dpy, 129c76ae52dSmrg Drawable drawable, 130c76ae52dSmrg Visual *visual, 131c76ae52dSmrg Colormap colormap) 132c76ae52dSmrg{ 133c76ae52dSmrg XftDraw *draw; 134c76ae52dSmrg 135c76ae52dSmrg draw = (XftDraw *) malloc (sizeof (XftDraw)); 136c76ae52dSmrg if (!draw) 1370d590c07Smrg return NULL; 138c76ae52dSmrg 139c76ae52dSmrg draw->dpy = dpy; 140c76ae52dSmrg draw->drawable = drawable; 141c76ae52dSmrg draw->screen = _XftDrawScreen (dpy, drawable, visual); 142c76ae52dSmrg draw->depth = 0; /* don't find out unless we need to know */ 143c76ae52dSmrg draw->bits_per_pixel = 0; /* don't find out unless we need to know */ 144c76ae52dSmrg draw->visual = visual; 145c76ae52dSmrg draw->colormap = colormap; 146c76ae52dSmrg draw->render.pict = 0; 1470d590c07Smrg draw->core.gc = NULL; 148c76ae52dSmrg draw->core.use_pixmap = 0; 149c76ae52dSmrg draw->clip_type = XftClipTypeNone; 150c76ae52dSmrg draw->subwindow_mode = ClipByChildren; 151c76ae52dSmrg XftMemAlloc (XFT_MEM_DRAW, sizeof (XftDraw)); 152c76ae52dSmrg return draw; 153c76ae52dSmrg} 154c76ae52dSmrg 155c76ae52dSmrg_X_EXPORT XftDraw * 156c76ae52dSmrgXftDrawCreateBitmap (Display *dpy, 157c76ae52dSmrg Pixmap bitmap) 158c76ae52dSmrg{ 159c76ae52dSmrg XftDraw *draw; 160c76ae52dSmrg 161c76ae52dSmrg draw = (XftDraw *) malloc (sizeof (XftDraw)); 162c76ae52dSmrg if (!draw) 1630d590c07Smrg return NULL; 164c76ae52dSmrg draw->dpy = dpy; 165c76ae52dSmrg draw->drawable = (Drawable) bitmap; 1660d590c07Smrg draw->screen = _XftDrawScreen (dpy, bitmap, NULL); 167c76ae52dSmrg draw->depth = 1; 168c76ae52dSmrg draw->bits_per_pixel = 1; 1690d590c07Smrg draw->visual = NULL; 170c76ae52dSmrg draw->colormap = 0; 171c76ae52dSmrg draw->render.pict = 0; 1720d590c07Smrg draw->core.gc = NULL; 173c76ae52dSmrg draw->core.use_pixmap = 0; 174c76ae52dSmrg draw->clip_type = XftClipTypeNone; 175c76ae52dSmrg draw->subwindow_mode = ClipByChildren; 176c76ae52dSmrg XftMemAlloc (XFT_MEM_DRAW, sizeof (XftDraw)); 177c76ae52dSmrg return draw; 178c76ae52dSmrg} 179c76ae52dSmrg 180c76ae52dSmrg_X_EXPORT XftDraw * 181c76ae52dSmrgXftDrawCreateAlpha (Display *dpy, 182c76ae52dSmrg Pixmap pixmap, 183c76ae52dSmrg int depth) 184c76ae52dSmrg{ 185c76ae52dSmrg XftDraw *draw; 186c76ae52dSmrg 187c76ae52dSmrg draw = (XftDraw *) malloc (sizeof (XftDraw)); 188c76ae52dSmrg if (!draw) 1890d590c07Smrg return NULL; 190c76ae52dSmrg draw->dpy = dpy; 191c76ae52dSmrg draw->drawable = (Drawable) pixmap; 1920d590c07Smrg draw->screen = _XftDrawScreen (dpy, pixmap, NULL); 193c76ae52dSmrg draw->depth = depth; 194c76ae52dSmrg draw->bits_per_pixel = 0; /* don't find out until we need it */ 1950d590c07Smrg draw->visual = NULL; 196c76ae52dSmrg draw->colormap = 0; 197c76ae52dSmrg draw->render.pict = 0; 1980d590c07Smrg draw->core.gc = NULL; 199c76ae52dSmrg draw->core.use_pixmap = 0; 200c76ae52dSmrg draw->clip_type = XftClipTypeNone; 201c76ae52dSmrg draw->subwindow_mode = ClipByChildren; 202c76ae52dSmrg XftMemAlloc (XFT_MEM_DRAW, sizeof (XftDraw)); 203c76ae52dSmrg return draw; 204c76ae52dSmrg} 205c76ae52dSmrg 206c76ae52dSmrgstatic XRenderPictFormat * 207c76ae52dSmrg_XftDrawFormat (XftDraw *draw) 208c76ae52dSmrg{ 209c76ae52dSmrg XftDisplayInfo *info = _XftDisplayInfoGet (draw->dpy, True); 210c76ae52dSmrg 211c76ae52dSmrg if (!info || !info->hasRender) 2120d590c07Smrg return NULL; 213c76ae52dSmrg 2140d590c07Smrg if (draw->visual == NULL) 215c76ae52dSmrg { 216c76ae52dSmrg XRenderPictFormat pf; 217c76ae52dSmrg 218c76ae52dSmrg pf.type = PictTypeDirect; 219c76ae52dSmrg pf.depth = XftDrawDepth (draw); 220c76ae52dSmrg pf.direct.alpha = 0; 221c76ae52dSmrg pf.direct.alphaMask = (1 << pf.depth) - 1; 222c76ae52dSmrg return XRenderFindFormat (draw->dpy, 223c76ae52dSmrg (PictFormatType| 224c76ae52dSmrg PictFormatDepth| 225c76ae52dSmrg PictFormatAlpha| 226c76ae52dSmrg PictFormatAlphaMask), 227c76ae52dSmrg &pf, 228c76ae52dSmrg 0); 229c76ae52dSmrg } 230c76ae52dSmrg else 231c76ae52dSmrg return XRenderFindVisualFormat (draw->dpy, draw->visual); 232c76ae52dSmrg} 233c76ae52dSmrg 234c76ae52dSmrg_X_EXPORT void 235c76ae52dSmrgXftDrawChange (XftDraw *draw, 236c76ae52dSmrg Drawable drawable) 237c76ae52dSmrg{ 238c76ae52dSmrg draw->drawable = drawable; 239c76ae52dSmrg if (draw->render.pict) 240c76ae52dSmrg { 241c76ae52dSmrg XRenderFreePicture (draw->dpy, draw->render.pict); 242c76ae52dSmrg draw->render.pict = 0; 243c76ae52dSmrg } 244c76ae52dSmrg if (draw->core.gc) 245c76ae52dSmrg { 246c76ae52dSmrg XFreeGC (draw->dpy, draw->core.gc); 2470d590c07Smrg draw->core.gc = NULL; 248c76ae52dSmrg } 249c76ae52dSmrg} 250c76ae52dSmrg 251c76ae52dSmrg_X_EXPORT Display * 252c76ae52dSmrgXftDrawDisplay (XftDraw *draw) 253c76ae52dSmrg{ 254c76ae52dSmrg return draw->dpy; 255c76ae52dSmrg} 256c76ae52dSmrg 257c76ae52dSmrg_X_EXPORT Drawable 258c76ae52dSmrgXftDrawDrawable (XftDraw *draw) 259c76ae52dSmrg{ 260c76ae52dSmrg return draw->drawable; 261c76ae52dSmrg} 262c76ae52dSmrg 263c76ae52dSmrg_X_EXPORT Colormap 264c76ae52dSmrgXftDrawColormap (XftDraw *draw) 265c76ae52dSmrg{ 266c76ae52dSmrg return draw->colormap; 267c76ae52dSmrg} 268c76ae52dSmrg 269c76ae52dSmrg_X_EXPORT Visual * 270c76ae52dSmrgXftDrawVisual (XftDraw *draw) 271c76ae52dSmrg{ 272c76ae52dSmrg return draw->visual; 273c76ae52dSmrg} 274c76ae52dSmrg 275c76ae52dSmrg_X_EXPORT void 276c76ae52dSmrgXftDrawDestroy (XftDraw *draw) 277c76ae52dSmrg{ 278c76ae52dSmrg if (draw->render.pict) 279c76ae52dSmrg XRenderFreePicture (draw->dpy, draw->render.pict); 280c76ae52dSmrg if (draw->core.gc) 281c76ae52dSmrg XFreeGC (draw->dpy, draw->core.gc); 282c76ae52dSmrg switch (draw->clip_type) { 283c76ae52dSmrg case XftClipTypeRegion: 284c76ae52dSmrg XDestroyRegion (draw->clip.region); 285c76ae52dSmrg break; 286c76ae52dSmrg case XftClipTypeRectangles: 287c76ae52dSmrg free (draw->clip.rect); 288c76ae52dSmrg break; 289c76ae52dSmrg case XftClipTypeNone: 290c76ae52dSmrg break; 291c76ae52dSmrg } 292c76ae52dSmrg XftMemFree (XFT_MEM_DRAW, sizeof (XftDraw)); 293c76ae52dSmrg free (draw); 294c76ae52dSmrg} 295c76ae52dSmrg 296c76ae52dSmrg_X_EXPORT Picture 297c76ae52dSmrgXftDrawSrcPicture (XftDraw *draw, _Xconst XftColor *color) 298c76ae52dSmrg{ 299c76ae52dSmrg Display *dpy = draw->dpy; 300c76ae52dSmrg XftDisplayInfo *info = _XftDisplayInfoGet (dpy, True); 301c76ae52dSmrg int i; 302c76ae52dSmrg XftColor bitmapColor; 303c76ae52dSmrg 304c76ae52dSmrg if (!info) 305c76ae52dSmrg return 0; 306c76ae52dSmrg 307c76ae52dSmrg /* 308c76ae52dSmrg * Monochrome targets require special handling; the PictOp controls 309c76ae52dSmrg * the color, and the color must be opaque 310c76ae52dSmrg */ 311c76ae52dSmrg if (!draw->visual && draw->depth == 1) 312c76ae52dSmrg { 313c76ae52dSmrg bitmapColor.color.alpha = 0xffff; 314c76ae52dSmrg bitmapColor.color.red = 0xffff; 315c76ae52dSmrg bitmapColor.color.green = 0xffff; 316c76ae52dSmrg bitmapColor.color.blue = 0xffff; 317c76ae52dSmrg color = &bitmapColor; 318c76ae52dSmrg } 319c76ae52dSmrg 320c76ae52dSmrg /* 321c76ae52dSmrg * See if there's one already available 322c76ae52dSmrg */ 323c76ae52dSmrg for (i = 0; i < XFT_NUM_SOLID_COLOR; i++) 324c76ae52dSmrg { 325c76ae52dSmrg if (info->colors[i].pict && 326c76ae52dSmrg info->colors[i].screen == draw->screen && 327c76ae52dSmrg !memcmp ((void *) &color->color, 328c76ae52dSmrg (void *) &info->colors[i].color, 329c76ae52dSmrg sizeof (XRenderColor))) 330c76ae52dSmrg return info->colors[i].pict; 331c76ae52dSmrg } 332c76ae52dSmrg /* 333c76ae52dSmrg * Pick one to replace at random 334c76ae52dSmrg */ 335c76ae52dSmrg i = (unsigned int) rand () % XFT_NUM_SOLID_COLOR; 336c76ae52dSmrg /* 337c76ae52dSmrg * Recreate if it was for the wrong screen 338c76ae52dSmrg */ 339c76ae52dSmrg if (info->colors[i].screen != draw->screen && info->colors[i].pict) 340c76ae52dSmrg { 341c76ae52dSmrg XRenderFreePicture (dpy, info->colors[i].pict); 342c76ae52dSmrg info->colors[i].pict = 0; 343c76ae52dSmrg } 344c76ae52dSmrg /* 345c76ae52dSmrg * Create picture if necessary 346c76ae52dSmrg */ 347c76ae52dSmrg if (!info->colors[i].pict) 348c76ae52dSmrg { 349c76ae52dSmrg Pixmap pix; 350c76ae52dSmrg XRenderPictureAttributes pa; 351c76ae52dSmrg 352c76ae52dSmrg pix = XCreatePixmap (dpy, RootWindow (dpy, draw->screen), 1, 1, 353c76ae52dSmrg info->solidFormat->depth); 354c76ae52dSmrg pa.repeat = True; 355c76ae52dSmrg info->colors[i].pict = XRenderCreatePicture (draw->dpy, 356c76ae52dSmrg pix, 357c76ae52dSmrg info->solidFormat, 358c76ae52dSmrg CPRepeat, &pa); 359c76ae52dSmrg XFreePixmap (dpy, pix); 360c76ae52dSmrg } 361c76ae52dSmrg /* 362c76ae52dSmrg * Set to the new color 363c76ae52dSmrg */ 364c76ae52dSmrg info->colors[i].color = color->color; 365c76ae52dSmrg info->colors[i].screen = draw->screen; 366c76ae52dSmrg XRenderFillRectangle (dpy, PictOpSrc, 367c76ae52dSmrg info->colors[i].pict, 368c76ae52dSmrg &color->color, 0, 0, 1, 1); 369c76ae52dSmrg return info->colors[i].pict; 370c76ae52dSmrg} 371c76ae52dSmrg 372c76ae52dSmrgstatic int 373c76ae52dSmrg_XftDrawOp (_Xconst XftDraw *draw, _Xconst XftColor *color) 374c76ae52dSmrg{ 375c76ae52dSmrg if (draw->visual || draw->depth != 1) 376c76ae52dSmrg return PictOpOver; 377c76ae52dSmrg if (color->color.alpha >= 0x8000) 378c76ae52dSmrg return PictOpOver; 379c76ae52dSmrg return PictOpOutReverse; 380c76ae52dSmrg} 381c76ae52dSmrg 382c76ae52dSmrgstatic FcBool 383c76ae52dSmrg_XftDrawRenderPrepare (XftDraw *draw) 384c76ae52dSmrg{ 385c76ae52dSmrg if (!draw->render.pict) 386c76ae52dSmrg { 387c76ae52dSmrg XRenderPictFormat *format; 388c76ae52dSmrg XRenderPictureAttributes pa; 389c76ae52dSmrg unsigned long mask = 0; 390c76ae52dSmrg 391c76ae52dSmrg format = _XftDrawFormat (draw); 392c76ae52dSmrg if (!format) 393c76ae52dSmrg return FcFalse; 394c76ae52dSmrg 395c76ae52dSmrg if (draw->subwindow_mode == IncludeInferiors) 396c76ae52dSmrg { 397c76ae52dSmrg pa.subwindow_mode = IncludeInferiors; 398c76ae52dSmrg mask |= CPSubwindowMode; 399c76ae52dSmrg } 400c76ae52dSmrg draw->render.pict = XRenderCreatePicture (draw->dpy, draw->drawable, 401c76ae52dSmrg format, mask, &pa); 402c76ae52dSmrg if (!draw->render.pict) 403c76ae52dSmrg return FcFalse; 404c76ae52dSmrg switch (draw->clip_type) { 405c76ae52dSmrg case XftClipTypeRegion: 406c76ae52dSmrg XRenderSetPictureClipRegion (draw->dpy, draw->render.pict, 407c76ae52dSmrg draw->clip.region); 408c76ae52dSmrg break; 409c76ae52dSmrg case XftClipTypeRectangles: 410c76ae52dSmrg XRenderSetPictureClipRectangles (draw->dpy, draw->render.pict, 411c76ae52dSmrg draw->clip.rect->xOrigin, 412c76ae52dSmrg draw->clip.rect->yOrigin, 413c76ae52dSmrg XftClipRects(draw->clip.rect), 414c76ae52dSmrg draw->clip.rect->n); 415c76ae52dSmrg break; 416c76ae52dSmrg case XftClipTypeNone: 417c76ae52dSmrg break; 418c76ae52dSmrg } 419c76ae52dSmrg } 420c76ae52dSmrg return FcTrue; 421c76ae52dSmrg} 422c76ae52dSmrg 423c76ae52dSmrgstatic FcBool 424c76ae52dSmrg_XftDrawCorePrepare (XftDraw *draw, _Xconst XftColor *color) 425c76ae52dSmrg{ 426c76ae52dSmrg if (!draw->core.gc) 427c76ae52dSmrg { 428c76ae52dSmrg XGCValues gcv; 429c76ae52dSmrg unsigned long mask = 0; 430c76ae52dSmrg if (draw->subwindow_mode == IncludeInferiors) 431c76ae52dSmrg { 432c76ae52dSmrg gcv.subwindow_mode = IncludeInferiors; 433c76ae52dSmrg mask |= GCSubwindowMode; 434c76ae52dSmrg } 435c76ae52dSmrg draw->core.gc = XCreateGC (draw->dpy, draw->drawable, mask, &gcv); 436c76ae52dSmrg if (!draw->core.gc) 437c76ae52dSmrg return FcFalse; 438c76ae52dSmrg switch (draw->clip_type) { 439c76ae52dSmrg case XftClipTypeRegion: 440c76ae52dSmrg XSetRegion (draw->dpy, draw->core.gc, draw->clip.region); 441c76ae52dSmrg break; 442c76ae52dSmrg case XftClipTypeRectangles: 443c76ae52dSmrg XSetClipRectangles (draw->dpy, draw->core.gc, 444c76ae52dSmrg draw->clip.rect->xOrigin, 445c76ae52dSmrg draw->clip.rect->yOrigin, 446c76ae52dSmrg XftClipRects (draw->clip.rect), 447c76ae52dSmrg draw->clip.rect->n, 448c76ae52dSmrg Unsorted); 449c76ae52dSmrg break; 450c76ae52dSmrg case XftClipTypeNone: 451c76ae52dSmrg break; 452c76ae52dSmrg } 453c76ae52dSmrg } 454c76ae52dSmrg XSetForeground (draw->dpy, draw->core.gc, color->pixel); 455c76ae52dSmrg return FcTrue; 456c76ae52dSmrg} 457c76ae52dSmrg 458c76ae52dSmrg_X_EXPORT Picture 459c76ae52dSmrgXftDrawPicture (XftDraw *draw) 460c76ae52dSmrg{ 461c76ae52dSmrg if (!_XftDrawRenderPrepare (draw)) 462c76ae52dSmrg return 0; 463c76ae52dSmrg return draw->render.pict; 464c76ae52dSmrg} 465c76ae52dSmrg 466c76ae52dSmrg#define NUM_LOCAL 1024 467c76ae52dSmrg 468c76ae52dSmrg_X_EXPORT void 469c76ae52dSmrgXftDrawGlyphs (XftDraw *draw, 470c76ae52dSmrg _Xconst XftColor *color, 471c76ae52dSmrg XftFont *pub, 472c76ae52dSmrg int x, 473c76ae52dSmrg int y, 474c76ae52dSmrg _Xconst FT_UInt *glyphs, 475c76ae52dSmrg int nglyphs) 476c76ae52dSmrg{ 477c76ae52dSmrg XftFontInt *font = (XftFontInt *) pub; 478c76ae52dSmrg 479c76ae52dSmrg if (font->format) 480c76ae52dSmrg { 481c76ae52dSmrg Picture src; 482c76ae52dSmrg 483c76ae52dSmrg if (_XftDrawRenderPrepare (draw) && 484c76ae52dSmrg (src = XftDrawSrcPicture (draw, color))) 485c76ae52dSmrg XftGlyphRender (draw->dpy, _XftDrawOp (draw, color), 486c76ae52dSmrg src, pub, draw->render.pict, 487c76ae52dSmrg 0, 0, x, y, glyphs, nglyphs); 488c76ae52dSmrg } 489c76ae52dSmrg else 490c76ae52dSmrg { 491c76ae52dSmrg if (_XftDrawCorePrepare (draw, color)) 492c76ae52dSmrg XftGlyphCore (draw, color, pub, x, y, glyphs, nglyphs); 493c76ae52dSmrg } 494c76ae52dSmrg} 495c76ae52dSmrg 496c76ae52dSmrg_X_EXPORT void 497c76ae52dSmrgXftDrawString8 (XftDraw *draw, 498c76ae52dSmrg _Xconst XftColor *color, 499c76ae52dSmrg XftFont *pub, 500c76ae52dSmrg int x, 501c76ae52dSmrg int y, 502c76ae52dSmrg _Xconst FcChar8 *string, 503c76ae52dSmrg int len) 504c76ae52dSmrg{ 505c76ae52dSmrg FT_UInt *glyphs, glyphs_local[NUM_LOCAL]; 506c76ae52dSmrg int i; 507c76ae52dSmrg 508c76ae52dSmrg if (XftDebug () & XFT_DBG_DRAW) 509c76ae52dSmrg printf ("DrawString \"%*.*s\"\n", len, len, string); 510c76ae52dSmrg 511c76ae52dSmrg if (len <= NUM_LOCAL) 512c76ae52dSmrg glyphs = glyphs_local; 513c76ae52dSmrg else 514c76ae52dSmrg { 515c76ae52dSmrg glyphs = malloc (len * sizeof (FT_UInt)); 516c76ae52dSmrg if (!glyphs) 517c76ae52dSmrg return; 518c76ae52dSmrg } 519c76ae52dSmrg for (i = 0; i < len; i++) 520c76ae52dSmrg glyphs[i] = XftCharIndex (draw->dpy, pub, string[i]); 521c76ae52dSmrg XftDrawGlyphs (draw, color, pub, x, y, glyphs, len); 522c76ae52dSmrg if (glyphs != glyphs_local) 523c76ae52dSmrg free (glyphs); 524c76ae52dSmrg} 525c76ae52dSmrg 526c76ae52dSmrg_X_EXPORT void 527c76ae52dSmrgXftDrawString16 (XftDraw *draw, 528c76ae52dSmrg _Xconst XftColor *color, 529c76ae52dSmrg XftFont *pub, 530c76ae52dSmrg int x, 531c76ae52dSmrg int y, 532c76ae52dSmrg _Xconst FcChar16 *string, 533c76ae52dSmrg int len) 534c76ae52dSmrg{ 535c76ae52dSmrg FT_UInt *glyphs, glyphs_local[NUM_LOCAL]; 536c76ae52dSmrg int i; 537c76ae52dSmrg 538c76ae52dSmrg if (len <= NUM_LOCAL) 539c76ae52dSmrg glyphs = glyphs_local; 540c76ae52dSmrg else 541c76ae52dSmrg { 542c76ae52dSmrg glyphs = malloc (len * sizeof (FT_UInt)); 543c76ae52dSmrg if (!glyphs) 544c76ae52dSmrg return; 545c76ae52dSmrg } 546c76ae52dSmrg for (i = 0; i < len; i++) 547c76ae52dSmrg glyphs[i] = XftCharIndex (draw->dpy, pub, string[i]); 548c76ae52dSmrg 549c76ae52dSmrg XftDrawGlyphs (draw, color, pub, x, y, glyphs, len); 550c76ae52dSmrg if (glyphs != glyphs_local) 551c76ae52dSmrg free (glyphs); 552c76ae52dSmrg} 553c76ae52dSmrg 554c76ae52dSmrg_X_EXPORT void 555c76ae52dSmrgXftDrawString32 (XftDraw *draw, 556c76ae52dSmrg _Xconst XftColor *color, 557c76ae52dSmrg XftFont *pub, 558c76ae52dSmrg int x, 559c76ae52dSmrg int y, 560c76ae52dSmrg _Xconst FcChar32 *string, 561c76ae52dSmrg int len) 562c76ae52dSmrg{ 563c76ae52dSmrg FT_UInt *glyphs, glyphs_local[NUM_LOCAL]; 564c76ae52dSmrg int i; 565c76ae52dSmrg 566c76ae52dSmrg if (len <= NUM_LOCAL) 567c76ae52dSmrg glyphs = glyphs_local; 568c76ae52dSmrg else 569c76ae52dSmrg { 570c76ae52dSmrg glyphs = malloc (len * sizeof (FT_UInt)); 571c76ae52dSmrg if (!glyphs) 572c76ae52dSmrg return; 573c76ae52dSmrg } 574c76ae52dSmrg for (i = 0; i < len; i++) 575c76ae52dSmrg glyphs[i] = XftCharIndex (draw->dpy, pub, string[i]); 576c76ae52dSmrg 577c76ae52dSmrg XftDrawGlyphs (draw, color, pub, x, y, glyphs, len); 578c76ae52dSmrg if (glyphs != glyphs_local) 579c76ae52dSmrg free (glyphs); 580c76ae52dSmrg} 581c76ae52dSmrg 582c76ae52dSmrg_X_EXPORT void 583c76ae52dSmrgXftDrawStringUtf8 (XftDraw *draw, 584c76ae52dSmrg _Xconst XftColor *color, 585c76ae52dSmrg XftFont *pub, 586c76ae52dSmrg int x, 587c76ae52dSmrg int y, 588c76ae52dSmrg _Xconst FcChar8 *string, 589c76ae52dSmrg int len) 590c76ae52dSmrg{ 591c76ae52dSmrg FT_UInt *glyphs, *glyphs_new, glyphs_local[NUM_LOCAL]; 592c76ae52dSmrg FcChar32 ucs4; 593c76ae52dSmrg int i; 594c76ae52dSmrg int l; 595c76ae52dSmrg int size; 596c76ae52dSmrg 597c76ae52dSmrg i = 0; 598c76ae52dSmrg glyphs = glyphs_local; 599c76ae52dSmrg size = NUM_LOCAL; 600c76ae52dSmrg while (len && (l = FcUtf8ToUcs4 (string, &ucs4, len)) > 0) 601c76ae52dSmrg { 602c76ae52dSmrg if (i == size) 603c76ae52dSmrg { 604c76ae52dSmrg glyphs_new = malloc (size * 2 * sizeof (FT_UInt)); 605c76ae52dSmrg if (!glyphs_new) 606c76ae52dSmrg { 607c76ae52dSmrg if (glyphs != glyphs_local) 608c76ae52dSmrg free (glyphs); 609c76ae52dSmrg return; 610c76ae52dSmrg } 611c76ae52dSmrg memcpy (glyphs_new, glyphs, size * sizeof (FT_UInt)); 612c76ae52dSmrg size *= 2; 613c76ae52dSmrg if (glyphs != glyphs_local) 614c76ae52dSmrg free (glyphs); 615c76ae52dSmrg glyphs = glyphs_new; 616c76ae52dSmrg } 617c76ae52dSmrg glyphs[i++] = XftCharIndex (draw->dpy, pub, ucs4); 618c76ae52dSmrg string += l; 619c76ae52dSmrg len -= l; 620c76ae52dSmrg } 621c76ae52dSmrg XftDrawGlyphs (draw, color, pub, x, y, glyphs, i); 622c76ae52dSmrg if (glyphs != glyphs_local) 623c76ae52dSmrg free (glyphs); 624c76ae52dSmrg} 625c76ae52dSmrg 626c76ae52dSmrg_X_EXPORT void 627c76ae52dSmrgXftDrawStringUtf16 (XftDraw *draw, 628c76ae52dSmrg _Xconst XftColor *color, 629c76ae52dSmrg XftFont *pub, 630c76ae52dSmrg int x, 631c76ae52dSmrg int y, 632c76ae52dSmrg _Xconst FcChar8 *string, 633c76ae52dSmrg FcEndian endian, 634c76ae52dSmrg int len) 635c76ae52dSmrg{ 636c76ae52dSmrg FT_UInt *glyphs, *glyphs_new, glyphs_local[NUM_LOCAL]; 637c76ae52dSmrg FcChar32 ucs4; 638c76ae52dSmrg int i; 639c76ae52dSmrg int l; 640c76ae52dSmrg int size; 641c76ae52dSmrg 642c76ae52dSmrg i = 0; 643c76ae52dSmrg glyphs = glyphs_local; 644c76ae52dSmrg size = NUM_LOCAL; 645c76ae52dSmrg while (len && (l = FcUtf16ToUcs4 (string, endian, &ucs4, len)) > 0) 646c76ae52dSmrg { 647c76ae52dSmrg if (i == size) 648c76ae52dSmrg { 649c76ae52dSmrg glyphs_new = malloc (size * 2 * sizeof (FT_UInt)); 650c76ae52dSmrg if (!glyphs_new) 651c76ae52dSmrg { 652c76ae52dSmrg if (glyphs != glyphs_local) 653c76ae52dSmrg free (glyphs); 654c76ae52dSmrg return; 655c76ae52dSmrg } 656c76ae52dSmrg memcpy (glyphs_new, glyphs, size * sizeof (FT_UInt)); 657c76ae52dSmrg size *= 2; 658c76ae52dSmrg if (glyphs != glyphs_local) 659c76ae52dSmrg free (glyphs); 660c76ae52dSmrg glyphs = glyphs_new; 661c76ae52dSmrg } 662c76ae52dSmrg glyphs[i++] = XftCharIndex (draw->dpy, pub, ucs4); 663c76ae52dSmrg string += l; 664c76ae52dSmrg len -= l; 665c76ae52dSmrg } 666c76ae52dSmrg XftDrawGlyphs (draw, color, pub, x, y, glyphs, i); 667c76ae52dSmrg if (glyphs != glyphs_local) 668c76ae52dSmrg free (glyphs); 669c76ae52dSmrg} 670c76ae52dSmrg 671c76ae52dSmrg_X_EXPORT void 672c76ae52dSmrgXftDrawGlyphSpec (XftDraw *draw, 673c76ae52dSmrg _Xconst XftColor *color, 674c76ae52dSmrg XftFont *pub, 675c76ae52dSmrg _Xconst XftGlyphSpec *glyphs, 676c76ae52dSmrg int len) 677c76ae52dSmrg{ 678c76ae52dSmrg XftFontInt *font = (XftFontInt *) pub; 679c76ae52dSmrg 680c76ae52dSmrg if (font->format) 681c76ae52dSmrg { 682c76ae52dSmrg Picture src; 683c76ae52dSmrg 684c76ae52dSmrg if (_XftDrawRenderPrepare (draw) && 685c76ae52dSmrg (src = XftDrawSrcPicture (draw, color))) 686c76ae52dSmrg { 687c76ae52dSmrg XftGlyphSpecRender (draw->dpy, _XftDrawOp (draw, color), 688c76ae52dSmrg src, pub, draw->render.pict, 689c76ae52dSmrg 0, 0, glyphs, len); 690c76ae52dSmrg } 691c76ae52dSmrg } 692c76ae52dSmrg else 693c76ae52dSmrg { 694c76ae52dSmrg if (_XftDrawCorePrepare (draw, color)) 695c76ae52dSmrg XftGlyphSpecCore (draw, color, pub, glyphs, len); 696c76ae52dSmrg } 697c76ae52dSmrg} 698c76ae52dSmrg 699c76ae52dSmrg_X_EXPORT void 700c76ae52dSmrgXftDrawGlyphFontSpec (XftDraw *draw, 701c76ae52dSmrg _Xconst XftColor *color, 702c76ae52dSmrg _Xconst XftGlyphFontSpec *glyphs, 703c76ae52dSmrg int len) 704c76ae52dSmrg{ 705c76ae52dSmrg int i; 706c76ae52dSmrg int start; 707c76ae52dSmrg 708c76ae52dSmrg i = 0; 709c76ae52dSmrg while (i < len) 710c76ae52dSmrg { 711c76ae52dSmrg start = i; 712c76ae52dSmrg if (((XftFontInt *) glyphs[i].font)->format) 713c76ae52dSmrg { 714c76ae52dSmrg Picture src; 715c76ae52dSmrg while (i < len && ((XftFontInt *) glyphs[i].font)->format) 716c76ae52dSmrg i++; 717c76ae52dSmrg if (_XftDrawRenderPrepare (draw) && 718c76ae52dSmrg (src = XftDrawSrcPicture (draw, color))) 719c76ae52dSmrg { 720c76ae52dSmrg XftGlyphFontSpecRender (draw->dpy, _XftDrawOp (draw, color), 721c76ae52dSmrg src, draw->render.pict, 722c76ae52dSmrg 0, 0, glyphs + start , i - start); 723c76ae52dSmrg } 724c76ae52dSmrg } 725c76ae52dSmrg else 726c76ae52dSmrg { 727c76ae52dSmrg while (i < len && !((XftFontInt *) glyphs[i].font)->format) 728c76ae52dSmrg i++; 729c76ae52dSmrg if (_XftDrawCorePrepare (draw, color)) 730c76ae52dSmrg XftGlyphFontSpecCore (draw, color, glyphs + start, i - start); 731c76ae52dSmrg } 732c76ae52dSmrg } 733c76ae52dSmrg} 734c76ae52dSmrg 735c76ae52dSmrg_X_EXPORT void 736c76ae52dSmrgXftDrawCharSpec (XftDraw *draw, 737c76ae52dSmrg _Xconst XftColor *color, 738c76ae52dSmrg XftFont *pub, 739c76ae52dSmrg _Xconst XftCharSpec *chars, 740c76ae52dSmrg int len) 741c76ae52dSmrg{ 742c76ae52dSmrg XftGlyphSpec *glyphs, glyphs_local[NUM_LOCAL]; 743c76ae52dSmrg int i; 744c76ae52dSmrg 745c76ae52dSmrg if (len <= NUM_LOCAL) 746c76ae52dSmrg glyphs = glyphs_local; 747c76ae52dSmrg else 748c76ae52dSmrg { 749c76ae52dSmrg glyphs = malloc (len * sizeof (XftGlyphSpec)); 750c76ae52dSmrg if (!glyphs) 751c76ae52dSmrg return; 752c76ae52dSmrg } 753c76ae52dSmrg for (i = 0; i < len; i++) 754c76ae52dSmrg { 755c76ae52dSmrg glyphs[i].glyph = XftCharIndex(draw->dpy, pub, chars[i].ucs4); 756c76ae52dSmrg glyphs[i].x = chars[i].x; 757c76ae52dSmrg glyphs[i].y = chars[i].y; 758c76ae52dSmrg } 759c76ae52dSmrg 760c76ae52dSmrg XftDrawGlyphSpec (draw, color, pub, glyphs, len); 761c76ae52dSmrg if (glyphs != glyphs_local) 762c76ae52dSmrg free (glyphs); 763c76ae52dSmrg} 764c76ae52dSmrg 765c76ae52dSmrg_X_EXPORT void 766c76ae52dSmrgXftDrawCharFontSpec (XftDraw *draw, 767c76ae52dSmrg _Xconst XftColor *color, 768c76ae52dSmrg _Xconst XftCharFontSpec *chars, 769c76ae52dSmrg int len) 770c76ae52dSmrg{ 771c76ae52dSmrg XftGlyphFontSpec *glyphs, glyphs_local[NUM_LOCAL]; 772c76ae52dSmrg int i; 773c76ae52dSmrg 774c76ae52dSmrg if (len <= NUM_LOCAL) 775c76ae52dSmrg glyphs = glyphs_local; 776c76ae52dSmrg else 777c76ae52dSmrg { 778c76ae52dSmrg glyphs = malloc (len * sizeof (XftGlyphFontSpec)); 779c76ae52dSmrg if (!glyphs) 780c76ae52dSmrg return; 781c76ae52dSmrg } 782c76ae52dSmrg for (i = 0; i < len; i++) 783c76ae52dSmrg { 784c76ae52dSmrg glyphs[i].font = chars[i].font; 785c76ae52dSmrg glyphs[i].glyph = XftCharIndex(draw->dpy, glyphs[i].font, chars[i].ucs4); 786c76ae52dSmrg glyphs[i].x = chars[i].x; 787c76ae52dSmrg glyphs[i].y = chars[i].y; 788c76ae52dSmrg } 789c76ae52dSmrg 790c76ae52dSmrg XftDrawGlyphFontSpec (draw, color, glyphs, len); 791c76ae52dSmrg if (glyphs != glyphs_local) 792c76ae52dSmrg free (glyphs); 793c76ae52dSmrg} 794c76ae52dSmrg 795c76ae52dSmrg_X_EXPORT void 796c76ae52dSmrgXftDrawRect (XftDraw *draw, 797c76ae52dSmrg _Xconst XftColor *color, 798c76ae52dSmrg int x, 799c76ae52dSmrg int y, 800c76ae52dSmrg unsigned int width, 801c76ae52dSmrg unsigned int height) 802c76ae52dSmrg{ 803c76ae52dSmrg if (_XftDrawRenderPrepare (draw)) 804c76ae52dSmrg { 805c76ae52dSmrg XRenderFillRectangle (draw->dpy, PictOpSrc, draw->render.pict, 806c76ae52dSmrg &color->color, x, y, width, height); 807c76ae52dSmrg } 808c76ae52dSmrg else if (_XftDrawCorePrepare (draw, color)) 809c76ae52dSmrg { 8100d590c07Smrg /* note: not XftRectCore() */ 8110d590c07Smrg XSetForeground (draw->dpy, draw->core.gc, color->pixel); 8120d590c07Smrg XFillRectangle (draw->dpy, draw->drawable, draw->core.gc, 8130d590c07Smrg x, y, width, height); 814c76ae52dSmrg } 815c76ae52dSmrg} 816c76ae52dSmrg 817c76ae52dSmrg_X_EXPORT Bool 818c76ae52dSmrgXftDrawSetClip (XftDraw *draw, 819c76ae52dSmrg Region r) 820c76ae52dSmrg{ 8210d590c07Smrg Region n = NULL; 822c76ae52dSmrg 823c76ae52dSmrg /* 824c76ae52dSmrg * Check for quick exits 825c76ae52dSmrg */ 826c76ae52dSmrg if (!r && draw->clip_type == XftClipTypeNone) 827c76ae52dSmrg return True; 828c76ae52dSmrg 829c76ae52dSmrg if (r && 830c76ae52dSmrg draw->clip_type == XftClipTypeRegion && 831c76ae52dSmrg XEqualRegion (r, draw->clip.region)) 832c76ae52dSmrg { 833c76ae52dSmrg return True; 834c76ae52dSmrg } 835c76ae52dSmrg 836c76ae52dSmrg /* 837c76ae52dSmrg * Duplicate the region so future changes can be short circuited 838c76ae52dSmrg */ 839c76ae52dSmrg if (r) 840c76ae52dSmrg { 841c76ae52dSmrg n = XCreateRegion (); 842c76ae52dSmrg if (n) 843c76ae52dSmrg { 844c76ae52dSmrg if (!XUnionRegion (n, r, n)) 845c76ae52dSmrg { 846c76ae52dSmrg XDestroyRegion (n); 847c76ae52dSmrg return False; 848c76ae52dSmrg } 849c76ae52dSmrg } 850c76ae52dSmrg } 851c76ae52dSmrg 852c76ae52dSmrg /* 853c76ae52dSmrg * Destroy existing clip 854c76ae52dSmrg */ 855c76ae52dSmrg switch (draw->clip_type) { 856c76ae52dSmrg case XftClipTypeRegion: 857c76ae52dSmrg XDestroyRegion (draw->clip.region); 858c76ae52dSmrg break; 859c76ae52dSmrg case XftClipTypeRectangles: 860c76ae52dSmrg free (draw->clip.rect); 861c76ae52dSmrg break; 862c76ae52dSmrg case XftClipTypeNone: 863c76ae52dSmrg break; 864c76ae52dSmrg } 865c76ae52dSmrg 866c76ae52dSmrg /* 867c76ae52dSmrg * Set the clip 868c76ae52dSmrg */ 869c76ae52dSmrg if (n) 870c76ae52dSmrg { 871c76ae52dSmrg draw->clip_type = XftClipTypeRegion; 872c76ae52dSmrg draw->clip.region = n; 873c76ae52dSmrg } 874c76ae52dSmrg else 875c76ae52dSmrg { 876c76ae52dSmrg draw->clip_type = XftClipTypeNone; 877c76ae52dSmrg } 878c76ae52dSmrg /* 879c76ae52dSmrg * Apply new clip to existing objects 880c76ae52dSmrg */ 881c76ae52dSmrg if (draw->render.pict) 882c76ae52dSmrg { 883c76ae52dSmrg if (n) 884c76ae52dSmrg XRenderSetPictureClipRegion (draw->dpy, draw->render.pict, n); 885c76ae52dSmrg else 886c76ae52dSmrg { 887c76ae52dSmrg XRenderPictureAttributes pa; 888c76ae52dSmrg pa.clip_mask = None; 889c76ae52dSmrg XRenderChangePicture (draw->dpy, draw->render.pict, 890c76ae52dSmrg CPClipMask, &pa); 891c76ae52dSmrg } 892c76ae52dSmrg } 893c76ae52dSmrg if (draw->core.gc) 894c76ae52dSmrg { 895c76ae52dSmrg if (n) 896c76ae52dSmrg XSetRegion (draw->dpy, draw->core.gc, draw->clip.region); 897c76ae52dSmrg else 898c76ae52dSmrg XSetClipMask (draw->dpy, draw->core.gc, None); 899c76ae52dSmrg } 900c76ae52dSmrg return True; 901c76ae52dSmrg} 902c76ae52dSmrg 903c76ae52dSmrg_X_EXPORT Bool 904c76ae52dSmrgXftDrawSetClipRectangles (XftDraw *draw, 905c76ae52dSmrg int xOrigin, 906c76ae52dSmrg int yOrigin, 907c76ae52dSmrg _Xconst XRectangle *rects, 908c76ae52dSmrg int n) 909c76ae52dSmrg{ 9100d590c07Smrg XftClipRect *new = NULL; 911c76ae52dSmrg 912c76ae52dSmrg /* 913c76ae52dSmrg * Check for quick exit 914c76ae52dSmrg */ 915c76ae52dSmrg if (draw->clip_type == XftClipTypeRectangles && 916c76ae52dSmrg draw->clip.rect->n == n && 917c76ae52dSmrg (n == 0 || (draw->clip.rect->xOrigin == xOrigin && 918c76ae52dSmrg draw->clip.rect->yOrigin == yOrigin)) && 919c76ae52dSmrg !memcmp (XftClipRects (draw->clip.rect), rects, n * sizeof (XRectangle))) 920c76ae52dSmrg { 921c76ae52dSmrg return True; 922c76ae52dSmrg } 923c76ae52dSmrg 924c76ae52dSmrg /* 925c76ae52dSmrg * Duplicate the region so future changes can be short circuited 926c76ae52dSmrg */ 927c76ae52dSmrg new = malloc (sizeof (XftClipRect) + n * sizeof (XRectangle)); 928c76ae52dSmrg if (!new) 929c76ae52dSmrg return False; 930c76ae52dSmrg 931c76ae52dSmrg new->n = n; 932c76ae52dSmrg new->xOrigin = xOrigin; 933c76ae52dSmrg new->yOrigin = yOrigin; 934c76ae52dSmrg memcpy (XftClipRects (new), rects, n * sizeof (XRectangle)); 935c76ae52dSmrg 936c76ae52dSmrg /* 937c76ae52dSmrg * Destroy existing clip 938c76ae52dSmrg */ 939c76ae52dSmrg switch (draw->clip_type) { 940c76ae52dSmrg case XftClipTypeRegion: 941c76ae52dSmrg XDestroyRegion (draw->clip.region); 942c76ae52dSmrg break; 943c76ae52dSmrg case XftClipTypeRectangles: 944c76ae52dSmrg free (draw->clip.rect); 945c76ae52dSmrg break; 946c76ae52dSmrg case XftClipTypeNone: 947c76ae52dSmrg break; 948c76ae52dSmrg } 949c76ae52dSmrg 950c76ae52dSmrg /* 951c76ae52dSmrg * Set the clip 952c76ae52dSmrg */ 953c76ae52dSmrg draw->clip_type = XftClipTypeRectangles; 954c76ae52dSmrg draw->clip.rect = new; 955c76ae52dSmrg /* 956c76ae52dSmrg * Apply new clip to existing objects 957c76ae52dSmrg */ 958c76ae52dSmrg if (draw->render.pict) 959c76ae52dSmrg { 960c76ae52dSmrg XRenderSetPictureClipRectangles (draw->dpy, draw->render.pict, 961c76ae52dSmrg new->xOrigin, 962c76ae52dSmrg new->yOrigin, 963c76ae52dSmrg XftClipRects(new), 964c76ae52dSmrg new->n); 965c76ae52dSmrg } 966c76ae52dSmrg if (draw->core.gc) 967c76ae52dSmrg { 968c76ae52dSmrg XSetClipRectangles (draw->dpy, draw->core.gc, 969c76ae52dSmrg new->xOrigin, 970c76ae52dSmrg new->yOrigin, 971c76ae52dSmrg XftClipRects (new), 972c76ae52dSmrg new->n, 973c76ae52dSmrg Unsorted); 974c76ae52dSmrg } 975c76ae52dSmrg return True; 976c76ae52dSmrg} 977c76ae52dSmrg 978c76ae52dSmrg_X_EXPORT void 979c76ae52dSmrgXftDrawSetSubwindowMode (XftDraw *draw, int mode) 980c76ae52dSmrg{ 981c76ae52dSmrg if (mode == draw->subwindow_mode) 982c76ae52dSmrg return; 983c76ae52dSmrg draw->subwindow_mode = mode; 984c76ae52dSmrg if (draw->render.pict) 985c76ae52dSmrg { 986c76ae52dSmrg XRenderPictureAttributes pa; 987c76ae52dSmrg 988c76ae52dSmrg pa.subwindow_mode = mode; 989c76ae52dSmrg XRenderChangePicture (draw->dpy, draw->render.pict, 990c76ae52dSmrg CPSubwindowMode, &pa); 991c76ae52dSmrg } 992c76ae52dSmrg if (draw->core.gc) 993c76ae52dSmrg XSetSubwindowMode (draw->dpy, draw->core.gc, mode); 994c76ae52dSmrg} 995