1d514b0f3Smrg/* 2d514b0f3Smrg * Copyright © 2003 Keith Packard 3d514b0f3Smrg * 4d514b0f3Smrg * Permission to use, copy, modify, distribute, and sell this software and its 5d514b0f3Smrg * documentation for any purpose is hereby granted without fee, provided that 6d514b0f3Smrg * the above copyright notice appear in all copies and that both that 7d514b0f3Smrg * copyright notice and this permission notice appear in supporting 8d514b0f3Smrg * documentation, and that the name of Keith Packard not be used in 9d514b0f3Smrg * advertising or publicity pertaining to distribution of the software without 10d514b0f3Smrg * specific, written prior permission. Keith Packard makes no 11d514b0f3Smrg * representations about the suitability of this software for any purpose. It 12d514b0f3Smrg * is provided "as is" without express or implied warranty. 13d514b0f3Smrg * 14d514b0f3Smrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15d514b0f3Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16d514b0f3Smrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17d514b0f3Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18d514b0f3Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19d514b0f3Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20d514b0f3Smrg * PERFORMANCE OF THIS SOFTWARE. 21d514b0f3Smrg */ 22d514b0f3Smrg 23d514b0f3Smrg#ifdef HAVE_DIX_CONFIG_H 24d514b0f3Smrg#include <dix-config.h> 25d514b0f3Smrg#endif 26d514b0f3Smrg 27d514b0f3Smrg#include <stdlib.h> 28d514b0f3Smrg#include "uxa-priv.h" 29d514b0f3Smrg 30d514b0f3Smrg#include <dixfontstr.h> 31d514b0f3Smrg#include <gcstruct.h> 32d514b0f3Smrg#include <picturestr.h> 33d514b0f3Smrg#include <scrnintstr.h> 34d514b0f3Smrg#include <windowstr.h> 35d514b0f3Smrg#include <X11/X.h> 36d514b0f3Smrg#include <X11/fonts/font.h> 37d514b0f3Smrg#include <X11/fonts/fontstruct.h> 38d514b0f3Smrg#ifdef HAVE_XFONT2 39d514b0f3Smrg#include <X11/fonts/libxfont2.h> 40d514b0f3Smrg#else 41d514b0f3Smrg#include <X11/fonts/fontutil.h> 42d514b0f3Smrg#endif 43d514b0f3Smrg 44d514b0f3Smrg#include "uxa-damage.h" 45d514b0f3Smrg 46d514b0f3Smrgtypedef struct _damageGCPriv { 47d514b0f3Smrg GCOps *ops; 48d514b0f3Smrg GCFuncs *funcs; 49d514b0f3Smrg} DamageGCPrivRec, *DamageGCPrivPtr; 50d514b0f3Smrg 51d514b0f3Smrg#define DAMAGE_VALIDATE_ENABLE 0 52d514b0f3Smrg#define DAMAGE_DEBUG_ENABLE 0 53d514b0f3Smrg#if DAMAGE_DEBUG_ENABLE 54d514b0f3Smrg#define DAMAGE_DEBUG(x) ErrorF x 55d514b0f3Smrg#else 56d514b0f3Smrg#define DAMAGE_DEBUG(x) 57d514b0f3Smrg#endif 58d514b0f3Smrg 59d514b0f3Smrg#define TRIM_BOX(box, pGC) if (pGC->pCompositeClip) { \ 60d514b0f3Smrg BoxPtr extents = &pGC->pCompositeClip->extents; \ 61d514b0f3Smrg if(box.x1 < extents->x1) box.x1 = extents->x1; \ 62d514b0f3Smrg if(box.x2 > extents->x2) box.x2 = extents->x2; \ 63d514b0f3Smrg if(box.y1 < extents->y1) box.y1 = extents->y1; \ 64d514b0f3Smrg if(box.y2 > extents->y2) box.y2 = extents->y2; \ 65d514b0f3Smrg } 66d514b0f3Smrg 67d514b0f3Smrg#define TRANSLATE_BOX(box, pDrawable) { \ 68d514b0f3Smrg box.x1 += pDrawable->x; \ 69d514b0f3Smrg box.x2 += pDrawable->x; \ 70d514b0f3Smrg box.y1 += pDrawable->y; \ 71d514b0f3Smrg box.y2 += pDrawable->y; \ 72d514b0f3Smrg } 73d514b0f3Smrg 74d514b0f3Smrg#define TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC) { \ 75d514b0f3Smrg TRANSLATE_BOX(box, pDrawable); \ 76d514b0f3Smrg TRIM_BOX(box, pGC); \ 77d514b0f3Smrg } 78d514b0f3Smrg 79d514b0f3Smrg#define BOX_NOT_EMPTY(box) \ 80d514b0f3Smrg (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0)) 81d514b0f3Smrg 82d514b0f3Smrg#define checkGCDamage(g) ((!g->pCompositeClip || \ 83d514b0f3Smrg REGION_NOTEMPTY(d->pScreen, \ 84d514b0f3Smrg g->pCompositeClip))) 85d514b0f3Smrg 86d514b0f3Smrg#define TRIM_PICTURE_BOX(box, pDst) { \ 87d514b0f3Smrg BoxPtr extents = &pDst->pCompositeClip->extents; \ 88d514b0f3Smrg if(box.x1 < extents->x1) box.x1 = extents->x1; \ 89d514b0f3Smrg if(box.x2 > extents->x2) box.x2 = extents->x2; \ 90d514b0f3Smrg if(box.y1 < extents->y1) box.y1 = extents->y1; \ 91d514b0f3Smrg if(box.y2 > extents->y2) box.y2 = extents->y2; \ 92d514b0f3Smrg } 93d514b0f3Smrg 94d514b0f3Smrg#define checkPictureDamage(p) (REGION_NOTEMPTY(pScreen, p->pCompositeClip)) 95d514b0f3Smrg 96d514b0f3Smrgstatic void 97d514b0f3Smrgtrim_region (RegionPtr pRegion, 98d514b0f3Smrg DrawablePtr pDrawable, 99d514b0f3Smrg int subWindowMode) 100d514b0f3Smrg{ 101d514b0f3Smrg RegionRec pixClip; 102d514b0f3Smrg int draw_x = 0; 103d514b0f3Smrg int draw_y = 0; 104d514b0f3Smrg#ifdef COMPOSITE 105d514b0f3Smrg int screen_x = 0, screen_y = 0; 106d514b0f3Smrg#endif 107d514b0f3Smrg 108d514b0f3Smrg /* short circuit for empty regions */ 109d514b0f3Smrg if (!REGION_NOTEMPTY(pScreen, pRegion)) 110d514b0f3Smrg return; 111d514b0f3Smrg 112d514b0f3Smrg#ifdef COMPOSITE 113d514b0f3Smrg /* 114d514b0f3Smrg * When drawing to a pixmap which is storing window contents, 115d514b0f3Smrg * the region presented is in pixmap relative coordinates which 116d514b0f3Smrg * need to be converted to screen relative coordinates 117d514b0f3Smrg */ 118d514b0f3Smrg if (pDrawable->type != DRAWABLE_WINDOW) 119d514b0f3Smrg { 120d514b0f3Smrg screen_x = ((PixmapPtr) pDrawable)->screen_x - pDrawable->x; 121d514b0f3Smrg screen_y = ((PixmapPtr) pDrawable)->screen_y - pDrawable->y; 122d514b0f3Smrg } 123d514b0f3Smrg if (screen_x || screen_y) 124d514b0f3Smrg REGION_TRANSLATE (pScreen, pRegion, screen_x, screen_y); 125d514b0f3Smrg#endif 126d514b0f3Smrg 127d514b0f3Smrg /* Clip against any children */ 128d514b0f3Smrg if (pDrawable->type == DRAWABLE_WINDOW && 129d514b0f3Smrg ((WindowPtr)(pDrawable))->backingStore == NotUseful) 130d514b0f3Smrg { 131d514b0f3Smrg if (subWindowMode == ClipByChildren) 132d514b0f3Smrg { 133d514b0f3Smrg REGION_INTERSECT(pScreen, pRegion, pRegion, 134d514b0f3Smrg &((WindowPtr)(pDrawable))->clipList); 135d514b0f3Smrg } 136d514b0f3Smrg else if (subWindowMode == IncludeInferiors) 137d514b0f3Smrg { 138d514b0f3Smrg RegionPtr pTempRegion = 139d514b0f3Smrg NotClippedByChildren((WindowPtr)(pDrawable)); 140d514b0f3Smrg REGION_INTERSECT(pScreen, pRegion, pRegion, pTempRegion); 141d514b0f3Smrg REGION_DESTROY(pScreen, pTempRegion); 142d514b0f3Smrg } 143d514b0f3Smrg /* If subWindowMode is set to an invalid value, don't perform 144d514b0f3Smrg * any drawable-based clipping. */ 145d514b0f3Smrg } 146d514b0f3Smrg 147d514b0f3Smrg /* Clip against border or pixmap bounds */ 148d514b0f3Smrg if (pDrawable->type == DRAWABLE_WINDOW) 149d514b0f3Smrg { 150d514b0f3Smrg REGION_INTERSECT (pScreen, pRegion, pRegion, 151d514b0f3Smrg &((WindowPtr)(pDrawable))->borderClip); 152d514b0f3Smrg } 153d514b0f3Smrg else 154d514b0f3Smrg { 155d514b0f3Smrg BoxRec box; 156d514b0f3Smrg 157d514b0f3Smrg draw_x = pDrawable->x; 158d514b0f3Smrg draw_y = pDrawable->y; 159d514b0f3Smrg#ifdef COMPOSITE 160d514b0f3Smrg /* 161d514b0f3Smrg * Need to move everyone to screen coordinates 162d514b0f3Smrg * XXX what about off-screen pixmaps with non-zero x/y? 163d514b0f3Smrg */ 164d514b0f3Smrg if (!WindowDrawable(pDrawable->type)) 165d514b0f3Smrg { 166d514b0f3Smrg draw_x += ((PixmapPtr) pDrawable)->screen_x; 167d514b0f3Smrg draw_y += ((PixmapPtr) pDrawable)->screen_y; 168d514b0f3Smrg } 169d514b0f3Smrg#endif 170d514b0f3Smrg 171d514b0f3Smrg box.x1 = draw_x; 172d514b0f3Smrg box.y1 = draw_y; 173d514b0f3Smrg box.x2 = draw_x + pDrawable->width; 174d514b0f3Smrg box.y2 = draw_y + pDrawable->height; 175d514b0f3Smrg 176d514b0f3Smrg REGION_INIT(pScreen, &pixClip, &box, 1); 177d514b0f3Smrg REGION_INTERSECT (pScreen, pRegion, pRegion, &pixClip); 178d514b0f3Smrg REGION_UNINIT(pScreen, &pixClip); 179d514b0f3Smrg } 180d514b0f3Smrg 181d514b0f3Smrg /* 182d514b0f3Smrg * Move region to target coordinate space 183d514b0f3Smrg */ 184d514b0f3Smrg if (draw_x || draw_y) 185d514b0f3Smrg REGION_TRANSLATE (pScreen, pRegion, -draw_x, -draw_y); 186d514b0f3Smrg 187d514b0f3Smrg /* Now do something with the damage */ 188d514b0f3Smrg} 189d514b0f3Smrg 190d514b0f3Smrgstatic void 191d514b0f3Smrgadd_region (RegionPtr existing, 192d514b0f3Smrg RegionPtr new, 193d514b0f3Smrg DrawablePtr pDrawable, 194d514b0f3Smrg int subWindowMode) 195d514b0f3Smrg{ 196d514b0f3Smrg trim_region (new, pDrawable, subWindowMode); 197d514b0f3Smrg 198d514b0f3Smrg REGION_UNION (pDrawable->pScreen, existing, existing, new); 199d514b0f3Smrg} 200d514b0f3Smrg 201d514b0f3Smrgstatic void 202d514b0f3Smrgadd_box (RegionPtr existing, 203d514b0f3Smrg BoxPtr box, 204d514b0f3Smrg DrawablePtr drawable, 205d514b0f3Smrg int subwindow_mode) 206d514b0f3Smrg{ 207d514b0f3Smrg RegionRec region; 208d514b0f3Smrg 209d514b0f3Smrg REGION_INIT (pDrawable->pScreen, ®ion, box, 1); 210d514b0f3Smrg 211d514b0f3Smrg add_region (existing, ®ion, drawable, subwindow_mode); 212d514b0f3Smrg 213d514b0f3Smrg REGION_UNINIT (pDrawable->pScreen, ®ion); 214d514b0f3Smrg} 215d514b0f3Smrg 216d514b0f3Smrg 217d514b0f3Smrgvoid 218d514b0f3Smrguxa_damage_composite (RegionPtr region, 219d514b0f3Smrg CARD8 op, 220d514b0f3Smrg PicturePtr pSrc, 221d514b0f3Smrg PicturePtr pMask, 222d514b0f3Smrg PicturePtr pDst, 223d514b0f3Smrg INT16 xSrc, 224d514b0f3Smrg INT16 ySrc, 225d514b0f3Smrg INT16 xMask, 226d514b0f3Smrg INT16 yMask, 227d514b0f3Smrg INT16 xDst, 228d514b0f3Smrg INT16 yDst, 229d514b0f3Smrg CARD16 width, 230d514b0f3Smrg CARD16 height) 231d514b0f3Smrg{ 232d514b0f3Smrg if (checkPictureDamage (pDst)) 233d514b0f3Smrg { 234d514b0f3Smrg BoxRec box; 235d514b0f3Smrg 236d514b0f3Smrg box.x1 = xDst + pDst->pDrawable->x; 237d514b0f3Smrg box.y1 = yDst + pDst->pDrawable->y; 238d514b0f3Smrg box.x2 = box.x1 + width; 239d514b0f3Smrg box.y2 = box.y1 + height; 240d514b0f3Smrg 241d514b0f3Smrg TRIM_PICTURE_BOX(box, pDst); 242d514b0f3Smrg 243d514b0f3Smrg if (BOX_NOT_EMPTY(box)) 244d514b0f3Smrg add_box (region, &box, pDst->pDrawable, pDst->subWindowMode); 245d514b0f3Smrg } 246d514b0f3Smrg} 247d514b0f3Smrg 248d514b0f3Smrgvoid 249d514b0f3Smrguxa_damage_glyphs (RegionPtr region, 250d514b0f3Smrg CARD8 op, 251d514b0f3Smrg PicturePtr pSrc, 252d514b0f3Smrg PicturePtr pDst, 253d514b0f3Smrg PictFormatPtr maskFormat, 254d514b0f3Smrg INT16 xSrc, 255d514b0f3Smrg INT16 ySrc, 256d514b0f3Smrg int nlist, 257d514b0f3Smrg GlyphListPtr list, 258d514b0f3Smrg GlyphPtr *glyphs) 259d514b0f3Smrg{ 260d514b0f3Smrg if (checkPictureDamage (pDst)) 261d514b0f3Smrg { 262d514b0f3Smrg int nlistTmp = nlist; 263d514b0f3Smrg GlyphListPtr listTmp = list; 264d514b0f3Smrg GlyphPtr *glyphsTmp = glyphs; 265d514b0f3Smrg int x, y; 266d514b0f3Smrg int n; 267d514b0f3Smrg GlyphPtr glyph; 268d514b0f3Smrg BoxRec box; 269d514b0f3Smrg int x1, y1, x2, y2; 270d514b0f3Smrg 271d514b0f3Smrg box.x1 = 32767; 272d514b0f3Smrg box.y1 = 32767; 273d514b0f3Smrg box.x2 = -32767; 274d514b0f3Smrg box.y2 = -32767; 275d514b0f3Smrg x = pDst->pDrawable->x; 276d514b0f3Smrg y = pDst->pDrawable->y; 277d514b0f3Smrg while (nlistTmp--) 278d514b0f3Smrg { 279d514b0f3Smrg x += listTmp->xOff; 280d514b0f3Smrg y += listTmp->yOff; 281d514b0f3Smrg n = listTmp->len; 282d514b0f3Smrg while (n--) 283d514b0f3Smrg { 284d514b0f3Smrg glyph = *glyphsTmp++; 285d514b0f3Smrg x1 = x - glyph->info.x; 286d514b0f3Smrg y1 = y - glyph->info.y; 287d514b0f3Smrg x2 = x1 + glyph->info.width; 288d514b0f3Smrg y2 = y1 + glyph->info.height; 289d514b0f3Smrg if (x1 < box.x1) 290d514b0f3Smrg box.x1 = x1; 291d514b0f3Smrg if (y1 < box.y1) 292d514b0f3Smrg box.y1 = y1; 293d514b0f3Smrg if (x2 > box.x2) 294d514b0f3Smrg box.x2 = x2; 295d514b0f3Smrg if (y2 > box.y2) 296d514b0f3Smrg box.y2 = y2; 297d514b0f3Smrg x += glyph->info.xOff; 298d514b0f3Smrg y += glyph->info.yOff; 299d514b0f3Smrg } 300d514b0f3Smrg listTmp++; 301d514b0f3Smrg } 302d514b0f3Smrg TRIM_PICTURE_BOX (box, pDst); 303d514b0f3Smrg if (BOX_NOT_EMPTY(box)) 304d514b0f3Smrg add_box (region, &box, pDst->pDrawable, pDst->subWindowMode); 305d514b0f3Smrg } 306d514b0f3Smrg} 307d514b0f3Smrg 308d514b0f3Smrgvoid 309d514b0f3Smrguxa_damage_add_traps (RegionPtr region, 310d514b0f3Smrg PicturePtr pPicture, 311d514b0f3Smrg INT16 x_off, 312d514b0f3Smrg INT16 y_off, 313d514b0f3Smrg int ntrap, 314d514b0f3Smrg xTrap *traps) 315d514b0f3Smrg{ 316d514b0f3Smrg if (checkPictureDamage (pPicture)) 317d514b0f3Smrg { 318d514b0f3Smrg BoxRec box; 319d514b0f3Smrg int i; 320d514b0f3Smrg int x, y; 321d514b0f3Smrg xTrap *t = traps; 322d514b0f3Smrg 323d514b0f3Smrg box.x1 = 32767; 324d514b0f3Smrg box.y1 = 32767; 325d514b0f3Smrg box.x2 = -32767; 326d514b0f3Smrg box.y2 = -32767; 327d514b0f3Smrg x = pPicture->pDrawable->x + x_off; 328d514b0f3Smrg y = pPicture->pDrawable->y + y_off; 329d514b0f3Smrg for (i = 0; i < ntrap; i++) 330d514b0f3Smrg { 331d514b0f3Smrg pixman_fixed_t l = min (t->top.l, t->bot.l); 332d514b0f3Smrg pixman_fixed_t r = max (t->top.r, t->bot.r); 333d514b0f3Smrg int x1 = x + pixman_fixed_to_int (l); 334d514b0f3Smrg int x2 = x + pixman_fixed_to_int (pixman_fixed_ceil (r)); 335d514b0f3Smrg int y1 = y + pixman_fixed_to_int (t->top.y); 336d514b0f3Smrg int y2 = y + pixman_fixed_to_int (pixman_fixed_ceil (t->bot.y)); 337d514b0f3Smrg 338d514b0f3Smrg if (x1 < box.x1) 339d514b0f3Smrg box.x1 = x1; 340d514b0f3Smrg if (x2 > box.x2) 341d514b0f3Smrg box.x2 = x2; 342d514b0f3Smrg if (y1 < box.y1) 343d514b0f3Smrg box.y1 = y1; 344d514b0f3Smrg if (y2 > box.y2) 345d514b0f3Smrg box.y2 = y2; 346d514b0f3Smrg } 347d514b0f3Smrg TRIM_PICTURE_BOX (box, pPicture); 348d514b0f3Smrg if (BOX_NOT_EMPTY(box)) 349d514b0f3Smrg add_box (region, &box, pPicture->pDrawable, pPicture->subWindowMode); 350d514b0f3Smrg } 351d514b0f3Smrg} 352d514b0f3Smrg 353d514b0f3Smrg/**********************************************************/ 354d514b0f3Smrg 355d514b0f3Smrg 356d514b0f3Smrgvoid 357d514b0f3Smrguxa_damage_fill_spans (RegionPtr region, 358d514b0f3Smrg DrawablePtr pDrawable, 359d514b0f3Smrg GC *pGC, 360d514b0f3Smrg int npt, 361d514b0f3Smrg DDXPointPtr ppt, 362d514b0f3Smrg int *pwidth, 363d514b0f3Smrg int fSorted) 364d514b0f3Smrg{ 365d514b0f3Smrg if (npt && checkGCDamage (pGC)) 366d514b0f3Smrg { 367d514b0f3Smrg int nptTmp = npt; 368d514b0f3Smrg DDXPointPtr pptTmp = ppt; 369d514b0f3Smrg int *pwidthTmp = pwidth; 370d514b0f3Smrg BoxRec box; 371d514b0f3Smrg 372d514b0f3Smrg box.x1 = pptTmp->x; 373d514b0f3Smrg box.x2 = box.x1 + *pwidthTmp; 374d514b0f3Smrg box.y2 = box.y1 = pptTmp->y; 375d514b0f3Smrg 376d514b0f3Smrg while(--nptTmp) 377d514b0f3Smrg { 378d514b0f3Smrg pptTmp++; 379d514b0f3Smrg pwidthTmp++; 380d514b0f3Smrg if(box.x1 > pptTmp->x) box.x1 = pptTmp->x; 381d514b0f3Smrg if(box.x2 < (pptTmp->x + *pwidthTmp)) 382d514b0f3Smrg box.x2 = pptTmp->x + *pwidthTmp; 383d514b0f3Smrg if(box.y1 > pptTmp->y) box.y1 = pptTmp->y; 384d514b0f3Smrg else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y; 385d514b0f3Smrg } 386d514b0f3Smrg 387d514b0f3Smrg box.y2++; 388d514b0f3Smrg 389d514b0f3Smrg if(!pGC->miTranslate) { 390d514b0f3Smrg TRANSLATE_BOX(box, pDrawable); 391d514b0f3Smrg } 392d514b0f3Smrg TRIM_BOX(box, pGC); 393d514b0f3Smrg 394d514b0f3Smrg if(BOX_NOT_EMPTY(box)) 395d514b0f3Smrg add_box (region, &box, pDrawable, pGC->subWindowMode); 396d514b0f3Smrg } 397d514b0f3Smrg} 398d514b0f3Smrg 399d514b0f3Smrgvoid 400d514b0f3Smrguxa_damage_set_spans (RegionPtr region, 401d514b0f3Smrg DrawablePtr pDrawable, 402d514b0f3Smrg GCPtr pGC, 403d514b0f3Smrg char *pcharsrc, 404d514b0f3Smrg DDXPointPtr ppt, 405d514b0f3Smrg int *pwidth, 406d514b0f3Smrg int npt, 407d514b0f3Smrg int fSorted) 408d514b0f3Smrg{ 409d514b0f3Smrg if (npt && checkGCDamage (pGC)) 410d514b0f3Smrg { 411d514b0f3Smrg DDXPointPtr pptTmp = ppt; 412d514b0f3Smrg int *pwidthTmp = pwidth; 413d514b0f3Smrg int nptTmp = npt; 414d514b0f3Smrg BoxRec box; 415d514b0f3Smrg 416d514b0f3Smrg box.x1 = pptTmp->x; 417d514b0f3Smrg box.x2 = box.x1 + *pwidthTmp; 418d514b0f3Smrg box.y2 = box.y1 = pptTmp->y; 419d514b0f3Smrg 420d514b0f3Smrg while(--nptTmp) 421d514b0f3Smrg { 422d514b0f3Smrg pptTmp++; 423d514b0f3Smrg pwidthTmp++; 424d514b0f3Smrg if(box.x1 > pptTmp->x) box.x1 = pptTmp->x; 425d514b0f3Smrg if(box.x2 < (pptTmp->x + *pwidthTmp)) 426d514b0f3Smrg box.x2 = pptTmp->x + *pwidthTmp; 427d514b0f3Smrg if(box.y1 > pptTmp->y) box.y1 = pptTmp->y; 428d514b0f3Smrg else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y; 429d514b0f3Smrg } 430d514b0f3Smrg 431d514b0f3Smrg box.y2++; 432d514b0f3Smrg 433d514b0f3Smrg if(!pGC->miTranslate) { 434d514b0f3Smrg TRANSLATE_BOX(box, pDrawable); 435d514b0f3Smrg } 436d514b0f3Smrg TRIM_BOX(box, pGC); 437d514b0f3Smrg 438d514b0f3Smrg if(BOX_NOT_EMPTY(box)) 439d514b0f3Smrg add_box (region, &box, pDrawable, pGC->subWindowMode); 440d514b0f3Smrg } 441d514b0f3Smrg} 442d514b0f3Smrg 443d514b0f3Smrgvoid 444d514b0f3Smrguxa_damage_put_image (RegionPtr region, 445d514b0f3Smrg DrawablePtr pDrawable, 446d514b0f3Smrg GCPtr pGC, 447d514b0f3Smrg int depth, 448d514b0f3Smrg int x, 449d514b0f3Smrg int y, 450d514b0f3Smrg int w, 451d514b0f3Smrg int h, 452d514b0f3Smrg int leftPad, 453d514b0f3Smrg int format, 454d514b0f3Smrg char *pImage) 455d514b0f3Smrg{ 456d514b0f3Smrg if (checkGCDamage (pGC)) 457d514b0f3Smrg { 458d514b0f3Smrg BoxRec box; 459d514b0f3Smrg 460d514b0f3Smrg box.x1 = x + pDrawable->x; 461d514b0f3Smrg box.x2 = box.x1 + w; 462d514b0f3Smrg box.y1 = y + pDrawable->y; 463d514b0f3Smrg box.y2 = box.y1 + h; 464d514b0f3Smrg 465d514b0f3Smrg TRIM_BOX(box, pGC); 466d514b0f3Smrg if(BOX_NOT_EMPTY(box)) 467d514b0f3Smrg add_box (region, &box, pDrawable, pGC->subWindowMode); 468d514b0f3Smrg } 469d514b0f3Smrg} 470d514b0f3Smrg 471d514b0f3Smrgvoid 472d514b0f3Smrguxa_damage_copy_area(RegionPtr region, 473d514b0f3Smrg DrawablePtr pSrc, 474d514b0f3Smrg DrawablePtr pDst, 475d514b0f3Smrg GC *pGC, 476d514b0f3Smrg int srcx, 477d514b0f3Smrg int srcy, 478d514b0f3Smrg int width, 479d514b0f3Smrg int height, 480d514b0f3Smrg int dstx, 481d514b0f3Smrg int dsty) 482d514b0f3Smrg{ 483d514b0f3Smrg if (checkGCDamage (pGC)) 484d514b0f3Smrg { 485d514b0f3Smrg BoxRec box; 486d514b0f3Smrg 487d514b0f3Smrg box.x1 = dstx + pDst->x; 488d514b0f3Smrg box.x2 = box.x1 + width; 489d514b0f3Smrg box.y1 = dsty + pDst->y; 490d514b0f3Smrg box.y2 = box.y1 + height; 491d514b0f3Smrg 492d514b0f3Smrg TRIM_BOX(box, pGC); 493d514b0f3Smrg if(BOX_NOT_EMPTY(box)) 494d514b0f3Smrg add_box (region, &box, pDst, pGC->subWindowMode); 495d514b0f3Smrg } 496d514b0f3Smrg} 497d514b0f3Smrg 498d514b0f3Smrgvoid 499d514b0f3Smrguxa_damage_copy_plane (RegionPtr region, 500d514b0f3Smrg DrawablePtr pSrc, 501d514b0f3Smrg DrawablePtr pDst, 502d514b0f3Smrg GCPtr pGC, 503d514b0f3Smrg int srcx, 504d514b0f3Smrg int srcy, 505d514b0f3Smrg int width, 506d514b0f3Smrg int height, 507d514b0f3Smrg int dstx, 508d514b0f3Smrg int dsty, 509d514b0f3Smrg unsigned long bitPlane) 510d514b0f3Smrg{ 511d514b0f3Smrg if (checkGCDamage (pGC)) 512d514b0f3Smrg { 513d514b0f3Smrg BoxRec box; 514d514b0f3Smrg 515d514b0f3Smrg box.x1 = dstx + pDst->x; 516d514b0f3Smrg box.x2 = box.x1 + width; 517d514b0f3Smrg box.y1 = dsty + pDst->y; 518d514b0f3Smrg box.y2 = box.y1 + height; 519d514b0f3Smrg 520d514b0f3Smrg TRIM_BOX(box, pGC); 521d514b0f3Smrg if(BOX_NOT_EMPTY(box)) 522d514b0f3Smrg add_box (region, &box, pDst, pGC->subWindowMode); 523d514b0f3Smrg } 524d514b0f3Smrg} 525d514b0f3Smrg 526d514b0f3Smrgvoid 527d514b0f3Smrguxa_damage_poly_point (RegionPtr region, 528d514b0f3Smrg DrawablePtr pDrawable, 529d514b0f3Smrg GCPtr pGC, 530d514b0f3Smrg int mode, 531d514b0f3Smrg int npt, 532d514b0f3Smrg xPoint *ppt) 533d514b0f3Smrg{ 534d514b0f3Smrg if (npt && checkGCDamage (pGC)) 535d514b0f3Smrg { 536d514b0f3Smrg BoxRec box; 537d514b0f3Smrg int nptTmp = npt; 538d514b0f3Smrg xPoint *pptTmp = ppt; 539d514b0f3Smrg 540d514b0f3Smrg box.x2 = box.x1 = pptTmp->x; 541d514b0f3Smrg box.y2 = box.y1 = pptTmp->y; 542d514b0f3Smrg 543d514b0f3Smrg /* this could be slow if the points were spread out */ 544d514b0f3Smrg 545d514b0f3Smrg while(--nptTmp) 546d514b0f3Smrg { 547d514b0f3Smrg pptTmp++; 548d514b0f3Smrg if(box.x1 > pptTmp->x) box.x1 = pptTmp->x; 549d514b0f3Smrg else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x; 550d514b0f3Smrg if(box.y1 > pptTmp->y) box.y1 = pptTmp->y; 551d514b0f3Smrg else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y; 552d514b0f3Smrg } 553d514b0f3Smrg 554d514b0f3Smrg box.x2++; 555d514b0f3Smrg box.y2++; 556d514b0f3Smrg 557d514b0f3Smrg TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); 558d514b0f3Smrg if(BOX_NOT_EMPTY(box)) 559d514b0f3Smrg add_box (region, &box, pDrawable, pGC->subWindowMode); 560d514b0f3Smrg } 561d514b0f3Smrg} 562d514b0f3Smrg 563d514b0f3Smrgvoid 564d514b0f3Smrguxa_damage_poly_lines (RegionPtr region, 565d514b0f3Smrg DrawablePtr pDrawable, 566d514b0f3Smrg GCPtr pGC, 567d514b0f3Smrg int mode, 568d514b0f3Smrg int npt, 569d514b0f3Smrg DDXPointPtr ppt) 570d514b0f3Smrg{ 571d514b0f3Smrg if (npt && checkGCDamage (pGC)) 572d514b0f3Smrg { 573d514b0f3Smrg int nptTmp = npt; 574d514b0f3Smrg DDXPointPtr pptTmp = ppt; 575d514b0f3Smrg BoxRec box; 576d514b0f3Smrg int extra = pGC->lineWidth >> 1; 577d514b0f3Smrg 578d514b0f3Smrg box.x2 = box.x1 = pptTmp->x; 579d514b0f3Smrg box.y2 = box.y1 = pptTmp->y; 580d514b0f3Smrg 581d514b0f3Smrg if(nptTmp > 1) 582d514b0f3Smrg { 583d514b0f3Smrg if(pGC->joinStyle == JoinMiter) 584d514b0f3Smrg extra = 6 * pGC->lineWidth; 585d514b0f3Smrg else if(pGC->capStyle == CapProjecting) 586d514b0f3Smrg extra = pGC->lineWidth; 587d514b0f3Smrg } 588d514b0f3Smrg 589d514b0f3Smrg if(mode == CoordModePrevious) 590d514b0f3Smrg { 591d514b0f3Smrg int x = box.x1; 592d514b0f3Smrg int y = box.y1; 593d514b0f3Smrg while(--nptTmp) 594d514b0f3Smrg { 595d514b0f3Smrg pptTmp++; 596d514b0f3Smrg x += pptTmp->x; 597d514b0f3Smrg y += pptTmp->y; 598d514b0f3Smrg if(box.x1 > x) box.x1 = x; 599d514b0f3Smrg else if(box.x2 < x) box.x2 = x; 600d514b0f3Smrg if(box.y1 > y) box.y1 = y; 601d514b0f3Smrg else if(box.y2 < y) box.y2 = y; 602d514b0f3Smrg } 603d514b0f3Smrg } 604d514b0f3Smrg else 605d514b0f3Smrg { 606d514b0f3Smrg while(--nptTmp) 607d514b0f3Smrg { 608d514b0f3Smrg pptTmp++; 609d514b0f3Smrg if(box.x1 > pptTmp->x) box.x1 = pptTmp->x; 610d514b0f3Smrg else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x; 611d514b0f3Smrg if(box.y1 > pptTmp->y) box.y1 = pptTmp->y; 612d514b0f3Smrg else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y; 613d514b0f3Smrg } 614d514b0f3Smrg } 615d514b0f3Smrg 616d514b0f3Smrg box.x2++; 617d514b0f3Smrg box.y2++; 618d514b0f3Smrg 619d514b0f3Smrg if(extra) 620d514b0f3Smrg { 621d514b0f3Smrg box.x1 -= extra; 622d514b0f3Smrg box.x2 += extra; 623d514b0f3Smrg box.y1 -= extra; 624d514b0f3Smrg box.y2 += extra; 625d514b0f3Smrg } 626d514b0f3Smrg 627d514b0f3Smrg TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); 628d514b0f3Smrg if(BOX_NOT_EMPTY(box)) 629d514b0f3Smrg add_box (region, &box, pDrawable, pGC->subWindowMode); 630d514b0f3Smrg } 631d514b0f3Smrg} 632d514b0f3Smrg 633d514b0f3Smrgvoid 634d514b0f3Smrguxa_damage_poly_segment (RegionPtr region, 635d514b0f3Smrg DrawablePtr pDrawable, 636d514b0f3Smrg GCPtr pGC, 637d514b0f3Smrg int nSeg, 638d514b0f3Smrg xSegment *pSeg) 639d514b0f3Smrg{ 640d514b0f3Smrg if (nSeg && checkGCDamage (pGC)) 641d514b0f3Smrg { 642d514b0f3Smrg BoxRec box; 643d514b0f3Smrg int extra = pGC->lineWidth; 644d514b0f3Smrg int nsegTmp = nSeg; 645d514b0f3Smrg xSegment *pSegTmp = pSeg; 646d514b0f3Smrg 647d514b0f3Smrg if(pGC->capStyle != CapProjecting) 648d514b0f3Smrg extra >>= 1; 649d514b0f3Smrg 650d514b0f3Smrg if(pSegTmp->x2 > pSegTmp->x1) { 651d514b0f3Smrg box.x1 = pSegTmp->x1; 652d514b0f3Smrg box.x2 = pSegTmp->x2; 653d514b0f3Smrg } else { 654d514b0f3Smrg box.x2 = pSegTmp->x1; 655d514b0f3Smrg box.x1 = pSegTmp->x2; 656d514b0f3Smrg } 657d514b0f3Smrg 658d514b0f3Smrg if(pSegTmp->y2 > pSegTmp->y1) { 659d514b0f3Smrg box.y1 = pSegTmp->y1; 660d514b0f3Smrg box.y2 = pSegTmp->y2; 661d514b0f3Smrg } else { 662d514b0f3Smrg box.y2 = pSegTmp->y1; 663d514b0f3Smrg box.y1 = pSegTmp->y2; 664d514b0f3Smrg } 665d514b0f3Smrg 666d514b0f3Smrg while(--nsegTmp) 667d514b0f3Smrg { 668d514b0f3Smrg pSegTmp++; 669d514b0f3Smrg if(pSegTmp->x2 > pSegTmp->x1) 670d514b0f3Smrg { 671d514b0f3Smrg if(pSegTmp->x1 < box.x1) box.x1 = pSegTmp->x1; 672d514b0f3Smrg if(pSegTmp->x2 > box.x2) box.x2 = pSegTmp->x2; 673d514b0f3Smrg } 674d514b0f3Smrg else 675d514b0f3Smrg { 676d514b0f3Smrg if(pSegTmp->x2 < box.x1) box.x1 = pSegTmp->x2; 677d514b0f3Smrg if(pSegTmp->x1 > box.x2) box.x2 = pSegTmp->x1; 678d514b0f3Smrg } 679d514b0f3Smrg if(pSegTmp->y2 > pSegTmp->y1) 680d514b0f3Smrg { 681d514b0f3Smrg if(pSegTmp->y1 < box.y1) box.y1 = pSegTmp->y1; 682d514b0f3Smrg if(pSegTmp->y2 > box.y2) box.y2 = pSegTmp->y2; 683d514b0f3Smrg } 684d514b0f3Smrg else 685d514b0f3Smrg { 686d514b0f3Smrg if(pSegTmp->y2 < box.y1) box.y1 = pSegTmp->y2; 687d514b0f3Smrg if(pSegTmp->y1 > box.y2) box.y2 = pSegTmp->y1; 688d514b0f3Smrg } 689d514b0f3Smrg } 690d514b0f3Smrg 691d514b0f3Smrg box.x2++; 692d514b0f3Smrg box.y2++; 693d514b0f3Smrg 694d514b0f3Smrg if(extra) 695d514b0f3Smrg { 696d514b0f3Smrg box.x1 -= extra; 697d514b0f3Smrg box.x2 += extra; 698d514b0f3Smrg box.y1 -= extra; 699d514b0f3Smrg box.y2 += extra; 700d514b0f3Smrg } 701d514b0f3Smrg 702d514b0f3Smrg TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); 703d514b0f3Smrg if(BOX_NOT_EMPTY(box)) 704d514b0f3Smrg add_box (region, &box, pDrawable, pGC->subWindowMode); 705d514b0f3Smrg } 706d514b0f3Smrg} 707d514b0f3Smrg 708d514b0f3Smrgvoid 709d514b0f3Smrguxa_damage_poly_rectangle (RegionPtr region, 710d514b0f3Smrg DrawablePtr pDrawable, 711d514b0f3Smrg GCPtr pGC, 712d514b0f3Smrg int nRects, 713d514b0f3Smrg xRectangle *pRects) 714d514b0f3Smrg{ 715d514b0f3Smrg if (nRects && checkGCDamage (pGC)) 716d514b0f3Smrg { 717d514b0f3Smrg BoxRec box; 718d514b0f3Smrg int offset1, offset2, offset3; 719d514b0f3Smrg int nRectsTmp = nRects; 720d514b0f3Smrg xRectangle *pRectsTmp = pRects; 721d514b0f3Smrg 722d514b0f3Smrg offset2 = pGC->lineWidth; 723d514b0f3Smrg if(!offset2) offset2 = 1; 724d514b0f3Smrg offset1 = offset2 >> 1; 725d514b0f3Smrg offset3 = offset2 - offset1; 726d514b0f3Smrg 727d514b0f3Smrg while(nRectsTmp--) 728d514b0f3Smrg { 729d514b0f3Smrg box.x1 = pRectsTmp->x - offset1; 730d514b0f3Smrg box.y1 = pRectsTmp->y - offset1; 731d514b0f3Smrg box.x2 = box.x1 + pRectsTmp->width + offset2; 732d514b0f3Smrg box.y2 = box.y1 + offset2; 733d514b0f3Smrg TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); 734d514b0f3Smrg if(BOX_NOT_EMPTY(box)) 735d514b0f3Smrg add_box (region, &box, pDrawable, pGC->subWindowMode); 736d514b0f3Smrg 737d514b0f3Smrg box.x1 = pRectsTmp->x - offset1; 738d514b0f3Smrg box.y1 = pRectsTmp->y + offset3; 739d514b0f3Smrg box.x2 = box.x1 + offset2; 740d514b0f3Smrg box.y2 = box.y1 + pRectsTmp->height - offset2; 741d514b0f3Smrg TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); 742d514b0f3Smrg if(BOX_NOT_EMPTY(box)) 743d514b0f3Smrg add_box (region, &box, pDrawable, pGC->subWindowMode); 744d514b0f3Smrg 745d514b0f3Smrg box.x1 = pRectsTmp->x + pRectsTmp->width - offset1; 746d514b0f3Smrg box.y1 = pRectsTmp->y + offset3; 747d514b0f3Smrg box.x2 = box.x1 + offset2; 748d514b0f3Smrg box.y2 = box.y1 + pRectsTmp->height - offset2; 749d514b0f3Smrg TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); 750d514b0f3Smrg if(BOX_NOT_EMPTY(box)) 751d514b0f3Smrg add_box (region, &box, pDrawable, pGC->subWindowMode); 752d514b0f3Smrg 753d514b0f3Smrg box.x1 = pRectsTmp->x - offset1; 754d514b0f3Smrg box.y1 = pRectsTmp->y + pRectsTmp->height - offset1; 755d514b0f3Smrg box.x2 = box.x1 + pRectsTmp->width + offset2; 756d514b0f3Smrg box.y2 = box.y1 + offset2; 757d514b0f3Smrg TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); 758d514b0f3Smrg if(BOX_NOT_EMPTY(box)) 759d514b0f3Smrg add_box (region, &box, pDrawable, pGC->subWindowMode); 760d514b0f3Smrg 761d514b0f3Smrg pRectsTmp++; 762d514b0f3Smrg } 763d514b0f3Smrg } 764d514b0f3Smrg} 765d514b0f3Smrg 766d514b0f3Smrgvoid 767d514b0f3Smrguxa_damage_poly_arc (RegionPtr region, 768d514b0f3Smrg DrawablePtr pDrawable, 769d514b0f3Smrg GCPtr pGC, 770d514b0f3Smrg int nArcs, 771d514b0f3Smrg xArc *pArcs) 772d514b0f3Smrg{ 773d514b0f3Smrg if (nArcs && checkGCDamage (pGC)) 774d514b0f3Smrg { 775d514b0f3Smrg int extra = pGC->lineWidth >> 1; 776d514b0f3Smrg BoxRec box; 777d514b0f3Smrg int nArcsTmp = nArcs; 778d514b0f3Smrg xArc *pArcsTmp = pArcs; 779d514b0f3Smrg 780d514b0f3Smrg box.x1 = pArcsTmp->x; 781d514b0f3Smrg box.x2 = box.x1 + pArcsTmp->width; 782d514b0f3Smrg box.y1 = pArcsTmp->y; 783d514b0f3Smrg box.y2 = box.y1 + pArcsTmp->height; 784d514b0f3Smrg 785d514b0f3Smrg while(--nArcsTmp) 786d514b0f3Smrg { 787d514b0f3Smrg pArcsTmp++; 788d514b0f3Smrg if(box.x1 > pArcsTmp->x) 789d514b0f3Smrg box.x1 = pArcsTmp->x; 790d514b0f3Smrg if(box.x2 < (pArcsTmp->x + pArcsTmp->width)) 791d514b0f3Smrg box.x2 = pArcsTmp->x + pArcsTmp->width; 792d514b0f3Smrg if(box.y1 > pArcsTmp->y) 793d514b0f3Smrg box.y1 = pArcsTmp->y; 794d514b0f3Smrg if(box.y2 < (pArcsTmp->y + pArcsTmp->height)) 795d514b0f3Smrg box.y2 = pArcsTmp->y + pArcsTmp->height; 796d514b0f3Smrg } 797d514b0f3Smrg 798d514b0f3Smrg if(extra) 799d514b0f3Smrg { 800d514b0f3Smrg box.x1 -= extra; 801d514b0f3Smrg box.x2 += extra; 802d514b0f3Smrg box.y1 -= extra; 803d514b0f3Smrg box.y2 += extra; 804d514b0f3Smrg } 805d514b0f3Smrg 806d514b0f3Smrg box.x2++; 807d514b0f3Smrg box.y2++; 808d514b0f3Smrg 809d514b0f3Smrg TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); 810d514b0f3Smrg if(BOX_NOT_EMPTY(box)) 811d514b0f3Smrg add_box (region, &box, pDrawable, pGC->subWindowMode); 812d514b0f3Smrg } 813d514b0f3Smrg} 814d514b0f3Smrg 815d514b0f3Smrgvoid 816d514b0f3Smrguxa_damage_fill_polygon (RegionPtr region, 817d514b0f3Smrg DrawablePtr pDrawable, 818d514b0f3Smrg GCPtr pGC, 819d514b0f3Smrg int shape, 820d514b0f3Smrg int mode, 821d514b0f3Smrg int npt, 822d514b0f3Smrg DDXPointPtr ppt) 823d514b0f3Smrg{ 824d514b0f3Smrg if (npt > 2 && checkGCDamage (pGC)) 825d514b0f3Smrg { 826d514b0f3Smrg DDXPointPtr pptTmp = ppt; 827d514b0f3Smrg int nptTmp = npt; 828d514b0f3Smrg BoxRec box; 829d514b0f3Smrg 830d514b0f3Smrg box.x2 = box.x1 = pptTmp->x; 831d514b0f3Smrg box.y2 = box.y1 = pptTmp->y; 832d514b0f3Smrg 833d514b0f3Smrg if(mode != CoordModeOrigin) 834d514b0f3Smrg { 835d514b0f3Smrg int x = box.x1; 836d514b0f3Smrg int y = box.y1; 837d514b0f3Smrg while(--nptTmp) 838d514b0f3Smrg { 839d514b0f3Smrg pptTmp++; 840d514b0f3Smrg x += pptTmp->x; 841d514b0f3Smrg y += pptTmp->y; 842d514b0f3Smrg if(box.x1 > x) box.x1 = x; 843d514b0f3Smrg else if(box.x2 < x) box.x2 = x; 844d514b0f3Smrg if(box.y1 > y) box.y1 = y; 845d514b0f3Smrg else if(box.y2 < y) box.y2 = y; 846d514b0f3Smrg } 847d514b0f3Smrg } 848d514b0f3Smrg else 849d514b0f3Smrg { 850d514b0f3Smrg while(--nptTmp) 851d514b0f3Smrg { 852d514b0f3Smrg pptTmp++; 853d514b0f3Smrg if(box.x1 > pptTmp->x) box.x1 = pptTmp->x; 854d514b0f3Smrg else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x; 855d514b0f3Smrg if(box.y1 > pptTmp->y) box.y1 = pptTmp->y; 856d514b0f3Smrg else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y; 857d514b0f3Smrg } 858d514b0f3Smrg } 859d514b0f3Smrg 860d514b0f3Smrg box.x2++; 861d514b0f3Smrg box.y2++; 862d514b0f3Smrg 863d514b0f3Smrg TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); 864d514b0f3Smrg if(BOX_NOT_EMPTY(box)) 865d514b0f3Smrg add_box (region, &box, pDrawable, pGC->subWindowMode); 866d514b0f3Smrg } 867d514b0f3Smrg} 868d514b0f3Smrg 869d514b0f3Smrg 870d514b0f3Smrgvoid 871d514b0f3Smrguxa_damage_poly_fill_rect (RegionPtr region, 872d514b0f3Smrg DrawablePtr pDrawable, 873d514b0f3Smrg GCPtr pGC, 874d514b0f3Smrg int nRects, 875d514b0f3Smrg xRectangle *pRects) 876d514b0f3Smrg{ 877d514b0f3Smrg if (nRects && checkGCDamage (pGC)) 878d514b0f3Smrg { 879d514b0f3Smrg int i; 880d514b0f3Smrg 881d514b0f3Smrg for (i = 0; i < nRects; ++i) 882d514b0f3Smrg { 883d514b0f3Smrg xRectangle *rect = &(pRects[i]); 884d514b0f3Smrg BoxRec box; 885d514b0f3Smrg 886d514b0f3Smrg box.x1 = rect->x; 887d514b0f3Smrg box.x2 = rect->x + rect->width; 888d514b0f3Smrg box.y1 = rect->y; 889d514b0f3Smrg box.y2 = rect->y + rect->height; 890d514b0f3Smrg 891d514b0f3Smrg TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); 892d514b0f3Smrg if(BOX_NOT_EMPTY(box)) 893d514b0f3Smrg add_box (region, &box, pDrawable, pGC->subWindowMode); 894d514b0f3Smrg } 895d514b0f3Smrg } 896d514b0f3Smrg} 897d514b0f3Smrg 898d514b0f3Smrg 899d514b0f3Smrgvoid 900d514b0f3Smrguxa_damage_poly_fill_arc (RegionPtr region, 901d514b0f3Smrg DrawablePtr pDrawable, 902d514b0f3Smrg GCPtr pGC, 903d514b0f3Smrg int nArcs, 904d514b0f3Smrg xArc *pArcs) 905d514b0f3Smrg{ 906d514b0f3Smrg if (nArcs && checkGCDamage (pGC)) 907d514b0f3Smrg { 908d514b0f3Smrg BoxRec box; 909d514b0f3Smrg int nArcsTmp = nArcs; 910d514b0f3Smrg xArc *pArcsTmp = pArcs; 911d514b0f3Smrg 912d514b0f3Smrg box.x1 = pArcsTmp->x; 913d514b0f3Smrg box.x2 = box.x1 + pArcsTmp->width; 914d514b0f3Smrg box.y1 = pArcsTmp->y; 915d514b0f3Smrg box.y2 = box.y1 + pArcsTmp->height; 916d514b0f3Smrg 917d514b0f3Smrg while(--nArcsTmp) 918d514b0f3Smrg { 919d514b0f3Smrg pArcsTmp++; 920d514b0f3Smrg if(box.x1 > pArcsTmp->x) 921d514b0f3Smrg box.x1 = pArcsTmp->x; 922d514b0f3Smrg if(box.x2 < (pArcsTmp->x + pArcsTmp->width)) 923d514b0f3Smrg box.x2 = pArcsTmp->x + pArcsTmp->width; 924d514b0f3Smrg if(box.y1 > pArcsTmp->y) 925d514b0f3Smrg box.y1 = pArcsTmp->y; 926d514b0f3Smrg if(box.y2 < (pArcsTmp->y + pArcsTmp->height)) 927d514b0f3Smrg box.y2 = pArcsTmp->y + pArcsTmp->height; 928d514b0f3Smrg } 929d514b0f3Smrg 930d514b0f3Smrg TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); 931d514b0f3Smrg if(BOX_NOT_EMPTY(box)) 932d514b0f3Smrg add_box (region, &box, pDrawable, pGC->subWindowMode); 933d514b0f3Smrg } 934d514b0f3Smrg} 935d514b0f3Smrg 936d514b0f3Smrg/* 937d514b0f3Smrg * general Poly/Image text function. Extract glyph information, 938d514b0f3Smrg * compute bounding box and remove cursor if it is overlapped. 939d514b0f3Smrg */ 940d514b0f3Smrg 941d514b0f3Smrgvoid 942d514b0f3Smrguxa_damage_chars (RegionPtr region, 943d514b0f3Smrg DrawablePtr pDrawable, 944d514b0f3Smrg FontPtr font, 945d514b0f3Smrg int x, 946d514b0f3Smrg int y, 947d514b0f3Smrg unsigned int n, 948d514b0f3Smrg CharInfoPtr *charinfo, 949d514b0f3Smrg Bool imageblt, 950d514b0f3Smrg int subWindowMode) 951d514b0f3Smrg{ 952d514b0f3Smrg ExtentInfoRec extents; 953d514b0f3Smrg BoxRec box; 954d514b0f3Smrg 955d514b0f3Smrg#ifdef HAVE_XFONT2 956d514b0f3Smrg xfont2_query_glyph_extents(font, charinfo, n, &extents); 957d514b0f3Smrg#else 958d514b0f3Smrg QueryGlyphExtents(font, charinfo, n, &extents); 959d514b0f3Smrg#endif 960d514b0f3Smrg if (imageblt) 961d514b0f3Smrg { 962d514b0f3Smrg if (extents.overallWidth > extents.overallRight) 963d514b0f3Smrg extents.overallRight = extents.overallWidth; 964d514b0f3Smrg if (extents.overallWidth < extents.overallLeft) 965d514b0f3Smrg extents.overallLeft = extents.overallWidth; 966d514b0f3Smrg if (extents.overallLeft > 0) 967d514b0f3Smrg extents.overallLeft = 0; 968d514b0f3Smrg if (extents.fontAscent > extents.overallAscent) 969d514b0f3Smrg extents.overallAscent = extents.fontAscent; 970d514b0f3Smrg if (extents.fontDescent > extents.overallDescent) 971d514b0f3Smrg extents.overallDescent = extents.fontDescent; 972d514b0f3Smrg } 973d514b0f3Smrg box.x1 = x + extents.overallLeft; 974d514b0f3Smrg box.y1 = y - extents.overallAscent; 975d514b0f3Smrg box.x2 = x + extents.overallRight; 976d514b0f3Smrg box.y2 = y + extents.overallDescent; 977d514b0f3Smrg add_box (region, &box, pDrawable, subWindowMode); 978d514b0f3Smrg} 979d514b0f3Smrg 980d514b0f3Smrg/* 981d514b0f3Smrg * values for textType: 982d514b0f3Smrg */ 983d514b0f3Smrg#define TT_POLY8 0 984d514b0f3Smrg#define TT_IMAGE8 1 985d514b0f3Smrg#define TT_POLY16 2 986d514b0f3Smrg#define TT_IMAGE16 3 987d514b0f3Smrg 988d514b0f3Smrgint 989d514b0f3Smrguxa_damage_text (RegionPtr region, 990d514b0f3Smrg DrawablePtr pDrawable, 991d514b0f3Smrg GCPtr pGC, 992d514b0f3Smrg int x, 993d514b0f3Smrg int y, 994d514b0f3Smrg unsigned long count, 995d514b0f3Smrg char *chars, 996d514b0f3Smrg FontEncoding fontEncoding, 997d514b0f3Smrg Bool textType) 998d514b0f3Smrg{ 999d514b0f3Smrg CharInfoPtr *charinfo; 1000d514b0f3Smrg CharInfoPtr *info; 1001d514b0f3Smrg unsigned long i; 1002d514b0f3Smrg unsigned int n; 1003d514b0f3Smrg int w; 1004d514b0f3Smrg Bool imageblt; 1005d514b0f3Smrg 1006d514b0f3Smrg imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16); 1007d514b0f3Smrg 1008d514b0f3Smrg charinfo = malloc(count * sizeof(CharInfoPtr)); 1009d514b0f3Smrg if (!charinfo) 1010d514b0f3Smrg return x; 1011d514b0f3Smrg 1012d514b0f3Smrg GetGlyphs(pGC->font, count, (unsigned char *)chars, 1013d514b0f3Smrg fontEncoding, &i, charinfo); 1014d514b0f3Smrg n = (unsigned int)i; 1015d514b0f3Smrg w = 0; 1016d514b0f3Smrg if (!imageblt) 1017d514b0f3Smrg for (info = charinfo; i--; info++) 1018d514b0f3Smrg w += (*info)->metrics.characterWidth; 1019d514b0f3Smrg 1020d514b0f3Smrg if (n != 0) { 1021d514b0f3Smrg uxa_damage_chars (region, 1022d514b0f3Smrg pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, n, 1023d514b0f3Smrg charinfo, imageblt, pGC->subWindowMode); 1024d514b0f3Smrg } 1025d514b0f3Smrg free(charinfo); 1026d514b0f3Smrg return x + w; 1027d514b0f3Smrg} 1028d514b0f3Smrg 1029d514b0f3Smrgint 1030d514b0f3Smrguxa_damage_poly_text_8(RegionPtr region, 1031d514b0f3Smrg DrawablePtr pDrawable, 1032d514b0f3Smrg GCPtr pGC, 1033d514b0f3Smrg int x, 1034d514b0f3Smrg int y, 1035d514b0f3Smrg int count, 1036d514b0f3Smrg char *chars) 1037d514b0f3Smrg{ 1038d514b0f3Smrg if (checkGCDamage (pGC)) 1039d514b0f3Smrg x = uxa_damage_text (region, 1040d514b0f3Smrg pDrawable, pGC, x, y, (unsigned long) count, chars, 1041d514b0f3Smrg Linear8Bit, TT_POLY8); 1042d514b0f3Smrg return x; 1043d514b0f3Smrg} 1044d514b0f3Smrg 1045d514b0f3Smrgint 1046d514b0f3Smrguxa_damage_poly_text_16 (RegionPtr region, 1047d514b0f3Smrg DrawablePtr pDrawable, 1048d514b0f3Smrg GCPtr pGC, 1049d514b0f3Smrg int x, 1050d514b0f3Smrg int y, 1051d514b0f3Smrg int count, 1052d514b0f3Smrg unsigned short *chars) 1053d514b0f3Smrg{ 1054d514b0f3Smrg if (checkGCDamage (pGC)) 1055d514b0f3Smrg x = uxa_damage_text (region, 1056d514b0f3Smrg pDrawable, pGC, x, y, (unsigned long) count, (char *) chars, 1057d514b0f3Smrg FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit, 1058d514b0f3Smrg TT_POLY16); 1059d514b0f3Smrg 1060d514b0f3Smrg return x; 1061d514b0f3Smrg} 1062d514b0f3Smrg 1063d514b0f3Smrgvoid 1064d514b0f3Smrguxa_damage_image_text_8(RegionPtr region, 1065d514b0f3Smrg DrawablePtr pDrawable, 1066d514b0f3Smrg GCPtr pGC, 1067d514b0f3Smrg int x, 1068d514b0f3Smrg int y, 1069d514b0f3Smrg int count, 1070d514b0f3Smrg char *chars) 1071d514b0f3Smrg{ 1072d514b0f3Smrg if (checkGCDamage (pGC)) 1073d514b0f3Smrg uxa_damage_text (region, 1074d514b0f3Smrg pDrawable, pGC, x, y, (unsigned long) count, chars, 1075d514b0f3Smrg Linear8Bit, TT_IMAGE8); 1076d514b0f3Smrg} 1077d514b0f3Smrg 1078d514b0f3Smrgvoid 1079d514b0f3Smrguxa_damage_image_text_16 (RegionPtr region, 1080d514b0f3Smrg DrawablePtr pDrawable, 1081d514b0f3Smrg GCPtr pGC, 1082d514b0f3Smrg int x, 1083d514b0f3Smrg int y, 1084d514b0f3Smrg int count, 1085d514b0f3Smrg unsigned short *chars) 1086d514b0f3Smrg{ 1087d514b0f3Smrg if (checkGCDamage (pGC)) 1088d514b0f3Smrg uxa_damage_text (region, 1089d514b0f3Smrg pDrawable, pGC, x, y, (unsigned long) count, (char *) chars, 1090d514b0f3Smrg FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit, 1091d514b0f3Smrg TT_IMAGE16); 1092d514b0f3Smrg} 1093d514b0f3Smrg 1094d514b0f3Smrg 1095d514b0f3Smrgvoid 1096d514b0f3Smrguxa_damage_image_glyph_blt(RegionPtr region, 1097d514b0f3Smrg DrawablePtr pDrawable, 1098d514b0f3Smrg GCPtr pGC, 1099d514b0f3Smrg int x, 1100d514b0f3Smrg int y, 1101d514b0f3Smrg unsigned int nglyph, 1102d514b0f3Smrg CharInfoPtr *ppci, 1103d514b0f3Smrg pointer pglyphBase) 1104d514b0f3Smrg{ 1105d514b0f3Smrg uxa_damage_chars (region, 1106d514b0f3Smrg pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, 1107d514b0f3Smrg nglyph, ppci, TRUE, pGC->subWindowMode); 1108d514b0f3Smrg} 1109d514b0f3Smrg 1110d514b0f3Smrgvoid 1111d514b0f3Smrguxa_damage_poly_glyph_blt(RegionPtr region, 1112d514b0f3Smrg DrawablePtr pDrawable, 1113d514b0f3Smrg GCPtr pGC, 1114d514b0f3Smrg int x, 1115d514b0f3Smrg int y, 1116d514b0f3Smrg unsigned int nglyph, 1117d514b0f3Smrg CharInfoPtr *ppci, 1118d514b0f3Smrg pointer pglyphBase) 1119d514b0f3Smrg{ 1120d514b0f3Smrg uxa_damage_chars (region, 1121d514b0f3Smrg pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, 1122d514b0f3Smrg nglyph, ppci, FALSE, pGC->subWindowMode); 1123d514b0f3Smrg} 1124d514b0f3Smrg 1125d514b0f3Smrgvoid 1126d514b0f3Smrguxa_damage_push_pixels (RegionPtr region, 1127d514b0f3Smrg GCPtr pGC, 1128d514b0f3Smrg PixmapPtr pBitMap, 1129d514b0f3Smrg DrawablePtr pDrawable, 1130d514b0f3Smrg int dx, 1131d514b0f3Smrg int dy, 1132d514b0f3Smrg int xOrg, 1133d514b0f3Smrg int yOrg) 1134d514b0f3Smrg{ 1135d514b0f3Smrg if(checkGCDamage (pGC)) 1136d514b0f3Smrg { 1137d514b0f3Smrg BoxRec box; 1138d514b0f3Smrg 1139d514b0f3Smrg box.x1 = xOrg; 1140d514b0f3Smrg box.y1 = yOrg; 1141d514b0f3Smrg 1142d514b0f3Smrg if(!pGC->miTranslate) { 1143d514b0f3Smrg box.x1 += pDrawable->x; 1144d514b0f3Smrg box.y1 += pDrawable->y; 1145d514b0f3Smrg } 1146d514b0f3Smrg 1147d514b0f3Smrg box.x2 = box.x1 + dx; 1148d514b0f3Smrg box.y2 = box.y1 + dy; 1149d514b0f3Smrg 1150d514b0f3Smrg TRIM_BOX(box, pGC); 1151d514b0f3Smrg if(BOX_NOT_EMPTY(box)) 1152d514b0f3Smrg add_box (region, &box, pDrawable, pGC->subWindowMode); 1153d514b0f3Smrg } 1154d514b0f3Smrg} 1155d514b0f3Smrg 1156d514b0f3Smrgvoid 1157d514b0f3Smrguxa_damage_copy_window(RegionPtr region, 1158d514b0f3Smrg WindowPtr pWindow, 1159d514b0f3Smrg DDXPointRec ptOldOrg, 1160d514b0f3Smrg RegionPtr prgnSrc) 1161d514b0f3Smrg{ 1162d514b0f3Smrg#if 0 1163d514b0f3Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 1164d514b0f3Smrg damageScrPriv(pScreen); 1165d514b0f3Smrg int dx = pWindow->drawable.x - ptOldOrg.x; 1166d514b0f3Smrg int dy = pWindow->drawable.y - ptOldOrg.y; 1167d514b0f3Smrg 1168d514b0f3Smrg /* 1169d514b0f3Smrg * The region comes in source relative, but the damage occurs 1170d514b0f3Smrg * at the destination location. Translate back and forth. 1171d514b0f3Smrg */ 1172d514b0f3Smrg REGION_TRANSLATE (pScreen, prgnSrc, dx, dy); 1173d514b0f3Smrg damageRegionAppend (&pWindow->drawable, prgnSrc, FALSE, -1); 1174d514b0f3Smrg REGION_TRANSLATE (pScreen, prgnSrc, -dx, -dy); 1175d514b0f3Smrg#endif 1176d514b0f3Smrg 1177d514b0f3Smrg /* FIXME */ 1178d514b0f3Smrg} 1179