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, &region, box, 1);
210d514b0f3Smrg
211d514b0f3Smrg    add_region (existing, &region, drawable, subwindow_mode);
212d514b0f3Smrg
213d514b0f3Smrg    REGION_UNINIT (pDrawable->pScreen, &region);
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