]>
Piment Noir Git Repositories - deb_xorg-server.git/blob - fb/fbgc.c
f4d7f3a99556868d92c8c74d015e9f423ed0661d
2 * Copyright © 1998 Keith Packard
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.
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.
23 #ifdef HAVE_DIX_CONFIG_H
24 #include <dix-config.h>
31 const GCFuncs fbGCFuncs
= {
41 const GCOps fbGCOps
= {
67 pGC
->ops
= (GCOps
*) &fbGCOps
;
68 pGC
->funcs
= (GCFuncs
*) &fbGCFuncs
;
70 /* fb wants to translate before scan conversion */
74 fbGetGCPrivate(pGC
)->bpp
= BitsPerPixel(pGC
->depth
);
79 * Pad pixmap to FB_UNIT bits wide
82 fbPadPixmap(PixmapPtr pPixmap
)
92 _X_UNUSED
int xOff
, yOff
;
94 fbGetDrawable(&pPixmap
->drawable
, bits
, stride
, bpp
, xOff
, yOff
);
96 width
= pPixmap
->drawable
.width
* pPixmap
->drawable
.bitsPerPixel
;
97 height
= pPixmap
->drawable
.height
;
98 mask
= FbBitsMask(0, width
);
100 b
= READ(bits
) & mask
;
102 while (w
< FB_UNIT
) {
103 b
= b
| FbScrRight(b
, w
);
110 fbFinishAccess(&pPixmap
->drawable
);
114 * Verify that 'bits' repeats every 'len' bits
117 fbBitsRepeat(FbBits bits
, int len
, int width
)
119 FbBits mask
= FbBitsMask(0, len
);
120 FbBits orig
= bits
& mask
;
125 for (i
= 0; i
< width
/ len
; i
++) {
126 if ((bits
& mask
) != orig
)
128 bits
= FbScrLeft(bits
, len
);
134 * Check whether an entire bitmap line is a repetition of
135 * the first 'len' bits
138 fbLineRepeat(FbBits
* bits
, int len
, int width
)
140 FbBits first
= bits
[0];
142 if (!fbBitsRepeat(first
, len
, width
))
144 width
= (width
+ FB_UNIT
- 1) >> FB_SHIFT
;
147 if (READ(bits
) != first
)
153 * The even stipple code wants the first FB_UNIT/bpp bits on
154 * each scanline to represent the entire stipple
157 fbCanEvenStipple(PixmapPtr pStipple
, int bpp
)
159 int len
= FB_UNIT
/ bpp
;
163 _X_UNUSED
int stipXoff
, stipYoff
;
166 /* can't even stipple 24bpp drawables */
167 if ((bpp
& (bpp
- 1)) != 0)
169 /* make sure the stipple width is a multiple of the even stipple width */
170 if (pStipple
->drawable
.width
% len
!= 0)
172 fbGetDrawable(&pStipple
->drawable
, bits
, stride
, stip_bpp
, stipXoff
,
174 h
= pStipple
->drawable
.height
;
175 /* check to see that the stipple repeats horizontally */
177 if (!fbLineRepeat(bits
, len
, pStipple
->drawable
.width
)) {
178 fbFinishAccess(&pStipple
->drawable
);
183 fbFinishAccess(&pStipple
->drawable
);
188 fbValidateGC(GCPtr pGC
, unsigned long changes
, DrawablePtr pDrawable
)
190 FbGCPrivPtr pPriv
= fbGetGCPrivate(pGC
);
194 * if the client clip is different or moved OR the subwindowMode has
195 * changed OR the window's clip has changed since the last validation
196 * we need to recompute the composite clip
200 (GCClipXOrigin
| GCClipYOrigin
| GCClipMask
| GCSubwindowMode
)) ||
201 (pDrawable
->serialNumber
!= (pGC
->serialNumber
& DRAWABLE_SERIAL_BITS
))
203 miComputeCompositeClip(pGC
, pDrawable
);
206 if (pPriv
->bpp
!= pDrawable
->bitsPerPixel
) {
207 changes
|= GCStipple
| GCForeground
| GCBackground
| GCPlaneMask
;
208 pPriv
->bpp
= pDrawable
->bitsPerPixel
;
210 if ((changes
& GCTile
) && fbGetRotatedPixmap(pGC
)) {
211 (*pGC
->pScreen
->DestroyPixmap
) (fbGetRotatedPixmap(pGC
));
212 fbGetRotatedPixmap(pGC
) = 0;
215 if (pGC
->fillStyle
== FillTiled
) {
216 PixmapPtr pOldTile
, pNewTile
;
218 pOldTile
= pGC
->tile
.pixmap
;
219 if (pOldTile
->drawable
.bitsPerPixel
!= pDrawable
->bitsPerPixel
) {
220 pNewTile
= fbGetRotatedPixmap(pGC
);
222 pNewTile
->drawable
.bitsPerPixel
!= pDrawable
->bitsPerPixel
) {
224 (*pGC
->pScreen
->DestroyPixmap
) (pNewTile
);
226 fb24_32ReformatTile(pOldTile
, pDrawable
->bitsPerPixel
);
229 fbGetRotatedPixmap(pGC
) = pOldTile
;
230 pGC
->tile
.pixmap
= pNewTile
;
235 if (changes
& GCTile
) {
236 if (!pGC
->tileIsPixel
&&
237 FbEvenTile(pGC
->tile
.pixmap
->drawable
.width
*
238 pDrawable
->bitsPerPixel
))
239 fbPadPixmap(pGC
->tile
.pixmap
);
241 if (changes
& GCStipple
) {
242 pPriv
->evenStipple
= FALSE
;
246 /* can we do an even stipple ?? */
247 if (FbEvenStip(pGC
->stipple
->drawable
.width
,
248 pDrawable
->bitsPerPixel
) &&
249 (fbCanEvenStipple(pGC
->stipple
, pDrawable
->bitsPerPixel
)))
250 pPriv
->evenStipple
= TRUE
;
252 if (pGC
->stipple
->drawable
.width
* pDrawable
->bitsPerPixel
<
254 fbPadPixmap(pGC
->stipple
);
258 * Recompute reduced rop values
260 if (changes
& (GCForeground
| GCBackground
| GCPlaneMask
| GCFunction
)) {
264 mask
= FbFullMask(pDrawable
->bitsPerPixel
);
265 depthMask
= FbFullMask(pDrawable
->depth
);
267 pPriv
->fg
= pGC
->fgPixel
& mask
;
268 pPriv
->bg
= pGC
->bgPixel
& mask
;
270 if ((pGC
->planemask
& depthMask
) == depthMask
)
273 pPriv
->pm
= pGC
->planemask
& mask
;
275 s
= pDrawable
->bitsPerPixel
;
276 while (s
< FB_UNIT
) {
277 pPriv
->fg
|= pPriv
->fg
<< s
;
278 pPriv
->bg
|= pPriv
->bg
<< s
;
279 pPriv
->pm
|= pPriv
->pm
<< s
;
282 pPriv
->and = fbAnd(pGC
->alu
, pPriv
->fg
, pPriv
->pm
);
283 pPriv
->xor = fbXor(pGC
->alu
, pPriv
->fg
, pPriv
->pm
);
284 pPriv
->bgand
= fbAnd(pGC
->alu
, pPriv
->bg
, pPriv
->pm
);
285 pPriv
->bgxor
= fbXor(pGC
->alu
, pPriv
->bg
, pPriv
->pm
);
287 if (changes
& GCDashList
) {
288 unsigned short n
= pGC
->numInDashList
;
289 unsigned char *dash
= pGC
->dash
;
290 unsigned int dashLength
= 0;
293 dashLength
+= (unsigned int) *dash
++;
294 pPriv
->dashLength
= dashLength
;