fbfill.c revision 706f2543
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
29void
30fbFill (DrawablePtr pDrawable,
31	GCPtr	    pGC,
32	int	    x,
33	int	    y,
34	int	    width,
35	int	    height)
36{
37    FbBits	    *dst;
38    FbStride	    dstStride;
39    int		    dstBpp;
40    int		    dstXoff, dstYoff;
41    FbGCPrivPtr	    pPriv = fbGetGCPrivate(pGC);
42
43    fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
44
45    switch (pGC->fillStyle) {
46    case FillSolid:
47#ifndef FB_ACCESS_WRAPPER
48	if (pPriv->and || !pixman_fill ((uint32_t *)dst, dstStride, dstBpp,
49					x + dstXoff, y + dstYoff,
50					width, height,
51					pPriv->xor))
52#endif
53	    fbSolid (dst + (y + dstYoff) * dstStride,
54		     dstStride,
55		     (x + dstXoff) * dstBpp,
56		     dstBpp,
57		     width * dstBpp, height,
58		     pPriv->and, pPriv->xor);
59	break;
60    case FillStippled:
61    case FillOpaqueStippled: {
62	PixmapPtr   pStip = pGC->stipple;
63	int	    stipWidth = pStip->drawable.width;
64	int	    stipHeight = pStip->drawable.height;
65
66	if (dstBpp == 1)
67	{
68	    int		alu;
69	    FbBits	*stip;
70	    FbStride    stipStride;
71	    int		stipBpp;
72	    int		stipXoff, stipYoff; /* XXX assumed to be zero */
73
74	    if (pGC->fillStyle == FillStippled)
75		alu = FbStipple1Rop(pGC->alu,pGC->fgPixel);
76	    else
77		alu = FbOpaqueStipple1Rop(pGC->alu,pGC->fgPixel,pGC->bgPixel);
78	    fbGetDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
79	    fbTile (dst + (y + dstYoff) * dstStride,
80		    dstStride,
81		    x + dstXoff,
82		    width, height,
83		    stip,
84		    stipStride,
85		    stipWidth,
86		    stipHeight,
87		    alu,
88		    pPriv->pm,
89		    dstBpp,
90
91		    (pGC->patOrg.x + pDrawable->x + dstXoff),
92		    pGC->patOrg.y + pDrawable->y - y);
93	    fbFinishAccess (&pStip->drawable);
94	}
95	else
96	{
97	    FbStip	*stip;
98	    FbStride    stipStride;
99	    int		stipBpp;
100	    int		stipXoff, stipYoff; /* XXX assumed to be zero */
101	    FbBits	fgand, fgxor, bgand, bgxor;
102
103	    fgand = pPriv->and;
104	    fgxor = pPriv->xor;
105	    if (pGC->fillStyle == FillStippled)
106	    {
107		bgand = fbAnd(GXnoop,(FbBits) 0,FB_ALLONES);
108		bgxor = fbXor(GXnoop,(FbBits) 0,FB_ALLONES);
109	    }
110	    else
111	    {
112		bgand = pPriv->bgand;
113		bgxor = pPriv->bgxor;
114	    }
115
116	    fbGetStipDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
117	    fbStipple (dst + (y + dstYoff) * dstStride,
118		       dstStride,
119		       (x + dstXoff) * dstBpp,
120		       dstBpp,
121		       width * dstBpp, height,
122		       stip,
123		       stipStride,
124		       stipWidth,
125		       stipHeight,
126		       pPriv->evenStipple,
127		       fgand, fgxor,
128		       bgand, bgxor,
129		       pGC->patOrg.x + pDrawable->x + dstXoff,
130		       pGC->patOrg.y + pDrawable->y - y);
131	    fbFinishAccess (&pStip->drawable);
132	}
133	break;
134    }
135    case FillTiled: {
136	PixmapPtr   pTile = pGC->tile.pixmap;
137	FbBits	    *tile;
138	FbStride    tileStride;
139	int	    tileBpp;
140	int	    tileWidth;
141	int	    tileHeight;
142	int	    tileXoff, tileYoff; /* XXX assumed to be zero */
143
144	fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp, tileXoff, tileYoff);
145	tileWidth = pTile->drawable.width;
146	tileHeight = pTile->drawable.height;
147	fbTile (dst + (y + dstYoff) * dstStride,
148		dstStride,
149		(x + dstXoff) * dstBpp,
150		width * dstBpp, height,
151		tile,
152		tileStride,
153		tileWidth * tileBpp,
154		tileHeight,
155		pGC->alu,
156		pPriv->pm,
157		dstBpp,
158		(pGC->patOrg.x + pDrawable->x + dstXoff) * dstBpp,
159		pGC->patOrg.y + pDrawable->y - y);
160	fbFinishAccess (&pTile->drawable);
161	break;
162    }
163    }
164    fbValidateDrawable (pDrawable);
165    fbFinishAccess (pDrawable);
166}
167
168void
169fbSolidBoxClipped (DrawablePtr	pDrawable,
170		   RegionPtr	pClip,
171		   int		x1,
172		   int		y1,
173		   int		x2,
174		   int		y2,
175		   FbBits	and,
176		   FbBits	xor)
177{
178    FbBits	*dst;
179    FbStride	dstStride;
180    int		dstBpp;
181    int		dstXoff, dstYoff;
182    BoxPtr	pbox;
183    int		nbox;
184    int		partX1, partX2, partY1, partY2;
185
186    fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
187
188    for (nbox = RegionNumRects(pClip), pbox = RegionRects(pClip);
189	 nbox--;
190	 pbox++)
191    {
192	partX1 = pbox->x1;
193	if (partX1 < x1)
194	    partX1 = x1;
195
196	partX2 = pbox->x2;
197	if (partX2 > x2)
198	    partX2 = x2;
199
200	if (partX2 <= partX1)
201	    continue;
202
203	partY1 = pbox->y1;
204	if (partY1 < y1)
205	    partY1 = y1;
206
207	partY2 = pbox->y2;
208	if (partY2 > y2)
209	    partY2 = y2;
210
211	if (partY2 <= partY1)
212	    continue;
213
214#ifndef FB_ACCESS_WRAPPER
215	if (and || !pixman_fill ((uint32_t *)dst, dstStride, dstBpp,
216				 partX1 + dstXoff, partY1 + dstYoff,
217				 (partX2 - partX1), (partY2 - partY1),
218				 xor))
219#endif
220	    fbSolid (dst + (partY1 + dstYoff) * dstStride,
221		     dstStride,
222		     (partX1 + dstXoff) * dstBpp,
223		     dstBpp,
224
225		     (partX2 - partX1) * dstBpp,
226		     (partY2 - partY1),
227		     and, xor);
228    }
229    fbFinishAccess (pDrawable);
230}
231