Imported Upstream version 1.15.1
[deb_xorg-server.git] / render / mirect.c
1 /*
2 *
3 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of Keith Packard not be used in
10 * advertising or publicity pertaining to distribution of the software without
11 * specific, written prior permission. Keith Packard makes no
12 * representations about the suitability of this software for any purpose. It
13 * is provided "as is" without express or implied warranty.
14 *
15 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21 * PERFORMANCE OF THIS SOFTWARE.
22 */
23
24 #ifdef HAVE_DIX_CONFIG_H
25 #include <dix-config.h>
26 #endif
27
28 #include "scrnintstr.h"
29 #include "gcstruct.h"
30 #include "pixmapstr.h"
31 #include "windowstr.h"
32 #include "mi.h"
33 #include "picturestr.h"
34 #include "mipict.h"
35
36 static void
37 miColorRects(PicturePtr pDst,
38 PicturePtr pClipPict,
39 xRenderColor * color,
40 int nRect, xRectangle *rects, int xoff, int yoff)
41 {
42 CARD32 pixel;
43 GCPtr pGC;
44 ChangeGCVal tmpval[5];
45 RegionPtr pClip;
46 unsigned long mask;
47
48 miRenderColorToPixel(pDst->pFormat, color, &pixel);
49
50 pGC = GetScratchGC(pDst->pDrawable->depth, pDst->pDrawable->pScreen);
51 if (!pGC)
52 return;
53 tmpval[0].val = GXcopy;
54 tmpval[1].val = pixel;
55 tmpval[2].val = pDst->subWindowMode;
56 mask = GCFunction | GCForeground | GCSubwindowMode;
57 if (pClipPict->clientClipType == CT_REGION) {
58 tmpval[3].val = pDst->clipOrigin.x - xoff;
59 tmpval[4].val = pDst->clipOrigin.y - yoff;
60 mask |= GCClipXOrigin | GCClipYOrigin;
61
62 pClip = RegionCreate(NULL, 1);
63 RegionCopy(pClip, (RegionPtr) pClipPict->clientClip);
64 (*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0);
65 }
66
67 ChangeGC(NullClient, pGC, mask, tmpval);
68 ValidateGC(pDst->pDrawable, pGC);
69 if (xoff || yoff) {
70 int i;
71
72 for (i = 0; i < nRect; i++) {
73 rects[i].x -= xoff;
74 rects[i].y -= yoff;
75 }
76 }
77 (*pGC->ops->PolyFillRect) (pDst->pDrawable, pGC, nRect, rects);
78 if (xoff || yoff) {
79 int i;
80
81 for (i = 0; i < nRect; i++) {
82 rects[i].x += xoff;
83 rects[i].y += yoff;
84 }
85 }
86 FreeScratchGC(pGC);
87 }
88
89 void
90 miCompositeRects(CARD8 op,
91 PicturePtr pDst,
92 xRenderColor * color, int nRect, xRectangle *rects)
93 {
94 ScreenPtr pScreen = pDst->pDrawable->pScreen;
95
96 if (color->alpha == 0xffff) {
97 if (op == PictOpOver)
98 op = PictOpSrc;
99 }
100 if (op == PictOpClear)
101 color->red = color->green = color->blue = color->alpha = 0;
102
103 if (op == PictOpSrc || op == PictOpClear) {
104 miColorRects(pDst, pDst, color, nRect, rects, 0, 0);
105 if (pDst->alphaMap)
106 miColorRects(pDst->alphaMap, pDst,
107 color, nRect, rects,
108 pDst->alphaOrigin.x, pDst->alphaOrigin.y);
109 }
110 else {
111 PictFormatPtr rgbaFormat;
112 PixmapPtr pPixmap;
113 PicturePtr pSrc;
114 xRectangle one;
115 int error;
116 Pixel pixel;
117 GCPtr pGC;
118 ChangeGCVal gcvals[2];
119 XID tmpval[1];
120
121 rgbaFormat = PictureMatchFormat(pScreen, 32, PICT_a8r8g8b8);
122 if (!rgbaFormat)
123 goto bail1;
124
125 pPixmap = (*pScreen->CreatePixmap) (pScreen, 1, 1, rgbaFormat->depth,
126 CREATE_PIXMAP_USAGE_SCRATCH);
127 if (!pPixmap)
128 goto bail2;
129
130 miRenderColorToPixel(rgbaFormat, color, &pixel);
131
132 pGC = GetScratchGC(rgbaFormat->depth, pScreen);
133 if (!pGC)
134 goto bail3;
135 gcvals[0].val = GXcopy;
136 gcvals[1].val = pixel;
137
138 ChangeGC(NullClient, pGC, GCFunction | GCForeground, gcvals);
139 ValidateGC(&pPixmap->drawable, pGC);
140 one.x = 0;
141 one.y = 0;
142 one.width = 1;
143 one.height = 1;
144 (*pGC->ops->PolyFillRect) (&pPixmap->drawable, pGC, 1, &one);
145
146 tmpval[0] = xTrue;
147 pSrc = CreatePicture(0, &pPixmap->drawable, rgbaFormat,
148 CPRepeat, tmpval, serverClient, &error);
149
150 if (!pSrc)
151 goto bail4;
152
153 while (nRect--) {
154 CompositePicture(op, pSrc, 0, pDst, 0, 0, 0, 0,
155 rects->x, rects->y, rects->width, rects->height);
156 rects++;
157 }
158
159 FreePicture((pointer) pSrc, 0);
160 bail4:
161 FreeScratchGC(pGC);
162 bail3:
163 (*pScreen->DestroyPixmap) (pPixmap);
164 bail2:
165 bail1:
166 ;
167 }
168 }