Commit | Line | Data |
---|---|---|
a09e091a JB |
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 | } |