Commit | Line | Data |
---|---|---|
a09e091a JB |
1 | /* |
2 | * Copyright © 1998 Keith Packard | |
3 | * | |
4 | * Permission to use, copy, modify, distribute, and sell this software and its | |
5 | * documentation for any purpose is hereby granted without fee, provided that | |
6 | * the above copyright notice appear in all copies and that both that | |
7 | * copyright notice and this permission notice appear in supporting | |
8 | * documentation, and that the name of Keith Packard not be used in | |
9 | * advertising or publicity pertaining to distribution of the software without | |
10 | * specific, written prior permission. Keith Packard makes no | |
11 | * representations about the suitability of this software for any purpose. It | |
12 | * is provided "as is" without express or implied warranty. | |
13 | * | |
14 | * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |
15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | |
16 | * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR | |
17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | |
18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |
19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |
20 | * PERFORMANCE OF THIS SOFTWARE. | |
21 | */ | |
22 | ||
23 | #ifdef HAVE_DIX_CONFIG_H | |
24 | #include <dix-config.h> | |
25 | #endif | |
26 | ||
27 | #include "fb.h" | |
28 | ||
29 | void | |
30 | fbFill(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int width, int height) | |
31 | { | |
32 | FbBits *dst; | |
33 | FbStride dstStride; | |
34 | int dstBpp; | |
35 | int dstXoff, dstYoff; | |
36 | FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); | |
37 | ||
38 | fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); | |
39 | ||
40 | switch (pGC->fillStyle) { | |
41 | case FillSolid: | |
42 | #ifndef FB_ACCESS_WRAPPER | |
43 | if (pPriv->and || !pixman_fill((uint32_t *) dst, dstStride, dstBpp, | |
44 | x + dstXoff, y + dstYoff, | |
45 | width, height, pPriv->xor)) | |
46 | #endif | |
47 | fbSolid(dst + (y + dstYoff) * dstStride, | |
48 | dstStride, | |
49 | (x + dstXoff) * dstBpp, | |
50 | dstBpp, width * dstBpp, height, pPriv->and, pPriv->xor); | |
51 | break; | |
52 | case FillStippled: | |
53 | case FillOpaqueStippled:{ | |
54 | PixmapPtr pStip = pGC->stipple; | |
55 | int stipWidth = pStip->drawable.width; | |
56 | int stipHeight = pStip->drawable.height; | |
57 | ||
58 | if (dstBpp == 1) { | |
59 | int alu; | |
60 | FbBits *stip; | |
61 | FbStride stipStride; | |
62 | int stipBpp; | |
63 | _X_UNUSED int stipXoff, stipYoff; | |
64 | ||
65 | if (pGC->fillStyle == FillStippled) | |
66 | alu = FbStipple1Rop(pGC->alu, pGC->fgPixel); | |
67 | else | |
68 | alu = FbOpaqueStipple1Rop(pGC->alu, pGC->fgPixel, pGC->bgPixel); | |
69 | fbGetDrawable(&pStip->drawable, stip, stipStride, stipBpp, stipXoff, | |
70 | stipYoff); | |
71 | fbTile(dst + (y + dstYoff) * dstStride, dstStride, x + dstXoff, | |
72 | width, height, stip, stipStride, stipWidth, stipHeight, alu, | |
73 | pPriv->pm, dstBpp, (pGC->patOrg.x + pDrawable->x + dstXoff), | |
74 | pGC->patOrg.y + pDrawable->y - y); | |
75 | fbFinishAccess(&pStip->drawable); | |
76 | } | |
77 | else { | |
78 | FbStip *stip; | |
79 | FbStride stipStride; | |
80 | int stipBpp; | |
81 | _X_UNUSED int stipXoff, stipYoff; | |
82 | FbBits fgand, fgxor, bgand, bgxor; | |
83 | ||
84 | fgand = pPriv->and; | |
85 | fgxor = pPriv->xor; | |
86 | if (pGC->fillStyle == FillStippled) { | |
87 | bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES); | |
88 | bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES); | |
89 | } | |
90 | else { | |
91 | bgand = pPriv->bgand; | |
92 | bgxor = pPriv->bgxor; | |
93 | } | |
94 | ||
95 | fbGetStipDrawable(&pStip->drawable, stip, stipStride, stipBpp, | |
96 | stipXoff, stipYoff); | |
97 | fbStipple(dst + (y + dstYoff) * dstStride, dstStride, | |
98 | (x + dstXoff) * dstBpp, dstBpp, width * dstBpp, height, | |
99 | stip, stipStride, stipWidth, stipHeight, | |
100 | pPriv->evenStipple, fgand, fgxor, bgand, bgxor, | |
101 | pGC->patOrg.x + pDrawable->x + dstXoff, | |
102 | pGC->patOrg.y + pDrawable->y - y); | |
103 | fbFinishAccess(&pStip->drawable); | |
104 | } | |
105 | break; | |
106 | } | |
107 | case FillTiled:{ | |
108 | PixmapPtr pTile = pGC->tile.pixmap; | |
109 | FbBits *tile; | |
110 | FbStride tileStride; | |
111 | int tileBpp; | |
112 | int tileWidth; | |
113 | int tileHeight; | |
114 | _X_UNUSED int tileXoff, tileYoff; | |
115 | ||
116 | fbGetDrawable(&pTile->drawable, tile, tileStride, tileBpp, tileXoff, | |
117 | tileYoff); | |
118 | tileWidth = pTile->drawable.width; | |
119 | tileHeight = pTile->drawable.height; | |
120 | fbTile(dst + (y + dstYoff) * dstStride, | |
121 | dstStride, | |
122 | (x + dstXoff) * dstBpp, | |
123 | width * dstBpp, height, | |
124 | tile, | |
125 | tileStride, | |
126 | tileWidth * tileBpp, | |
127 | tileHeight, | |
128 | pGC->alu, | |
129 | pPriv->pm, | |
130 | dstBpp, | |
131 | (pGC->patOrg.x + pDrawable->x + dstXoff) * dstBpp, | |
132 | pGC->patOrg.y + pDrawable->y - y); | |
133 | fbFinishAccess(&pTile->drawable); | |
134 | break; | |
135 | } | |
136 | } | |
137 | fbValidateDrawable(pDrawable); | |
138 | fbFinishAccess(pDrawable); | |
139 | } | |
140 | ||
141 | void | |
142 | fbSolidBoxClipped(DrawablePtr pDrawable, | |
143 | RegionPtr pClip, | |
144 | int x1, int y1, int x2, int y2, FbBits and, FbBits xor) | |
145 | { | |
146 | FbBits *dst; | |
147 | FbStride dstStride; | |
148 | int dstBpp; | |
149 | int dstXoff, dstYoff; | |
150 | BoxPtr pbox; | |
151 | int nbox; | |
152 | int partX1, partX2, partY1, partY2; | |
153 | ||
154 | fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); | |
155 | ||
156 | for (nbox = RegionNumRects(pClip), pbox = RegionRects(pClip); | |
157 | nbox--; pbox++) { | |
158 | partX1 = pbox->x1; | |
159 | if (partX1 < x1) | |
160 | partX1 = x1; | |
161 | ||
162 | partX2 = pbox->x2; | |
163 | if (partX2 > x2) | |
164 | partX2 = x2; | |
165 | ||
166 | if (partX2 <= partX1) | |
167 | continue; | |
168 | ||
169 | partY1 = pbox->y1; | |
170 | if (partY1 < y1) | |
171 | partY1 = y1; | |
172 | ||
173 | partY2 = pbox->y2; | |
174 | if (partY2 > y2) | |
175 | partY2 = y2; | |
176 | ||
177 | if (partY2 <= partY1) | |
178 | continue; | |
179 | ||
180 | #ifndef FB_ACCESS_WRAPPER | |
181 | if (and || !pixman_fill((uint32_t *) dst, dstStride, dstBpp, | |
182 | partX1 + dstXoff, partY1 + dstYoff, | |
183 | (partX2 - partX1), (partY2 - partY1), xor)) | |
184 | #endif | |
185 | fbSolid(dst + (partY1 + dstYoff) * dstStride, | |
186 | dstStride, | |
187 | (partX1 + dstXoff) * dstBpp, | |
188 | dstBpp, | |
189 | (partX2 - partX1) * dstBpp, (partY2 - partY1), and, xor); | |
190 | } | |
191 | fbFinishAccess(pDrawable); | |
192 | } |