1706f2543Smrg/*
2706f2543Smrg * Copyright © 1998 Keith Packard
3706f2543Smrg *
4706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its
5706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that
6706f2543Smrg * the above copyright notice appear in all copies and that both that
7706f2543Smrg * copyright notice and this permission notice appear in supporting
8706f2543Smrg * documentation, and that the name of Keith Packard not be used in
9706f2543Smrg * advertising or publicity pertaining to distribution of the software without
10706f2543Smrg * specific, written prior permission.  Keith Packard makes no
11706f2543Smrg * representations about the suitability of this software for any purpose.  It
12706f2543Smrg * is provided "as is" without express or implied warranty.
13706f2543Smrg *
14706f2543Smrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16706f2543Smrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20706f2543Smrg * PERFORMANCE OF THIS SOFTWARE.
21706f2543Smrg */
22706f2543Smrg
23706f2543Smrg#ifdef HAVE_DIX_CONFIG_H
24706f2543Smrg#include <dix-config.h>
25706f2543Smrg#endif
26706f2543Smrg
27706f2543Smrg#include "fb.h"
28706f2543Smrg
29706f2543Smrgvoid
30706f2543SmrgfbFill (DrawablePtr pDrawable,
31706f2543Smrg	GCPtr	    pGC,
32706f2543Smrg	int	    x,
33706f2543Smrg	int	    y,
34706f2543Smrg	int	    width,
35706f2543Smrg	int	    height)
36706f2543Smrg{
37706f2543Smrg    FbBits	    *dst;
38706f2543Smrg    FbStride	    dstStride;
39706f2543Smrg    int		    dstBpp;
40706f2543Smrg    int		    dstXoff, dstYoff;
41706f2543Smrg    FbGCPrivPtr	    pPriv = fbGetGCPrivate(pGC);
42706f2543Smrg
43706f2543Smrg    fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
44706f2543Smrg
45706f2543Smrg    switch (pGC->fillStyle) {
46706f2543Smrg    case FillSolid:
47706f2543Smrg#ifndef FB_ACCESS_WRAPPER
48706f2543Smrg	if (pPriv->and || !pixman_fill ((uint32_t *)dst, dstStride, dstBpp,
49706f2543Smrg					x + dstXoff, y + dstYoff,
50706f2543Smrg					width, height,
51706f2543Smrg					pPriv->xor))
52706f2543Smrg#endif
53706f2543Smrg	    fbSolid (dst + (y + dstYoff) * dstStride,
54706f2543Smrg		     dstStride,
55706f2543Smrg		     (x + dstXoff) * dstBpp,
56706f2543Smrg		     dstBpp,
57706f2543Smrg		     width * dstBpp, height,
58706f2543Smrg		     pPriv->and, pPriv->xor);
59706f2543Smrg	break;
60706f2543Smrg    case FillStippled:
61706f2543Smrg    case FillOpaqueStippled: {
62706f2543Smrg	PixmapPtr   pStip = pGC->stipple;
63706f2543Smrg	int	    stipWidth = pStip->drawable.width;
64706f2543Smrg	int	    stipHeight = pStip->drawable.height;
65706f2543Smrg
66706f2543Smrg	if (dstBpp == 1)
67706f2543Smrg	{
68706f2543Smrg	    int		alu;
69706f2543Smrg	    FbBits	*stip;
70706f2543Smrg	    FbStride    stipStride;
71706f2543Smrg	    int		stipBpp;
72706f2543Smrg	    int		stipXoff, stipYoff; /* XXX assumed to be zero */
73706f2543Smrg
74706f2543Smrg	    if (pGC->fillStyle == FillStippled)
75706f2543Smrg		alu = FbStipple1Rop(pGC->alu,pGC->fgPixel);
76706f2543Smrg	    else
77706f2543Smrg		alu = FbOpaqueStipple1Rop(pGC->alu,pGC->fgPixel,pGC->bgPixel);
78706f2543Smrg	    fbGetDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
79706f2543Smrg	    fbTile (dst + (y + dstYoff) * dstStride,
80706f2543Smrg		    dstStride,
81706f2543Smrg		    x + dstXoff,
82706f2543Smrg		    width, height,
83706f2543Smrg		    stip,
84706f2543Smrg		    stipStride,
85706f2543Smrg		    stipWidth,
86706f2543Smrg		    stipHeight,
87706f2543Smrg		    alu,
88706f2543Smrg		    pPriv->pm,
89706f2543Smrg		    dstBpp,
90706f2543Smrg
91706f2543Smrg		    (pGC->patOrg.x + pDrawable->x + dstXoff),
92706f2543Smrg		    pGC->patOrg.y + pDrawable->y - y);
93706f2543Smrg	    fbFinishAccess (&pStip->drawable);
94706f2543Smrg	}
95706f2543Smrg	else
96706f2543Smrg	{
97706f2543Smrg	    FbStip	*stip;
98706f2543Smrg	    FbStride    stipStride;
99706f2543Smrg	    int		stipBpp;
100706f2543Smrg	    int		stipXoff, stipYoff; /* XXX assumed to be zero */
101706f2543Smrg	    FbBits	fgand, fgxor, bgand, bgxor;
102706f2543Smrg
103706f2543Smrg	    fgand = pPriv->and;
104706f2543Smrg	    fgxor = pPriv->xor;
105706f2543Smrg	    if (pGC->fillStyle == FillStippled)
106706f2543Smrg	    {
107706f2543Smrg		bgand = fbAnd(GXnoop,(FbBits) 0,FB_ALLONES);
108706f2543Smrg		bgxor = fbXor(GXnoop,(FbBits) 0,FB_ALLONES);
109706f2543Smrg	    }
110706f2543Smrg	    else
111706f2543Smrg	    {
112706f2543Smrg		bgand = pPriv->bgand;
113706f2543Smrg		bgxor = pPriv->bgxor;
114706f2543Smrg	    }
115706f2543Smrg
116706f2543Smrg	    fbGetStipDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
117706f2543Smrg	    fbStipple (dst + (y + dstYoff) * dstStride,
118706f2543Smrg		       dstStride,
119706f2543Smrg		       (x + dstXoff) * dstBpp,
120706f2543Smrg		       dstBpp,
121706f2543Smrg		       width * dstBpp, height,
122706f2543Smrg		       stip,
123706f2543Smrg		       stipStride,
124706f2543Smrg		       stipWidth,
125706f2543Smrg		       stipHeight,
126706f2543Smrg		       pPriv->evenStipple,
127706f2543Smrg		       fgand, fgxor,
128706f2543Smrg		       bgand, bgxor,
129706f2543Smrg		       pGC->patOrg.x + pDrawable->x + dstXoff,
130706f2543Smrg		       pGC->patOrg.y + pDrawable->y - y);
131706f2543Smrg	    fbFinishAccess (&pStip->drawable);
132706f2543Smrg	}
133706f2543Smrg	break;
134706f2543Smrg    }
135706f2543Smrg    case FillTiled: {
136706f2543Smrg	PixmapPtr   pTile = pGC->tile.pixmap;
137706f2543Smrg	FbBits	    *tile;
138706f2543Smrg	FbStride    tileStride;
139706f2543Smrg	int	    tileBpp;
140706f2543Smrg	int	    tileWidth;
141706f2543Smrg	int	    tileHeight;
142706f2543Smrg	int	    tileXoff, tileYoff; /* XXX assumed to be zero */
143706f2543Smrg
144706f2543Smrg	fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp, tileXoff, tileYoff);
145706f2543Smrg	tileWidth = pTile->drawable.width;
146706f2543Smrg	tileHeight = pTile->drawable.height;
147706f2543Smrg	fbTile (dst + (y + dstYoff) * dstStride,
148706f2543Smrg		dstStride,
149706f2543Smrg		(x + dstXoff) * dstBpp,
150706f2543Smrg		width * dstBpp, height,
151706f2543Smrg		tile,
152706f2543Smrg		tileStride,
153706f2543Smrg		tileWidth * tileBpp,
154706f2543Smrg		tileHeight,
155706f2543Smrg		pGC->alu,
156706f2543Smrg		pPriv->pm,
157706f2543Smrg		dstBpp,
158706f2543Smrg		(pGC->patOrg.x + pDrawable->x + dstXoff) * dstBpp,
159706f2543Smrg		pGC->patOrg.y + pDrawable->y - y);
160706f2543Smrg	fbFinishAccess (&pTile->drawable);
161706f2543Smrg	break;
162706f2543Smrg    }
163706f2543Smrg    }
164706f2543Smrg    fbValidateDrawable (pDrawable);
165706f2543Smrg    fbFinishAccess (pDrawable);
166706f2543Smrg}
167706f2543Smrg
168706f2543Smrgvoid
169706f2543SmrgfbSolidBoxClipped (DrawablePtr	pDrawable,
170706f2543Smrg		   RegionPtr	pClip,
171706f2543Smrg		   int		x1,
172706f2543Smrg		   int		y1,
173706f2543Smrg		   int		x2,
174706f2543Smrg		   int		y2,
175706f2543Smrg		   FbBits	and,
176706f2543Smrg		   FbBits	xor)
177706f2543Smrg{
178706f2543Smrg    FbBits	*dst;
179706f2543Smrg    FbStride	dstStride;
180706f2543Smrg    int		dstBpp;
181706f2543Smrg    int		dstXoff, dstYoff;
182706f2543Smrg    BoxPtr	pbox;
183706f2543Smrg    int		nbox;
184706f2543Smrg    int		partX1, partX2, partY1, partY2;
185706f2543Smrg
186706f2543Smrg    fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
187706f2543Smrg
188706f2543Smrg    for (nbox = RegionNumRects(pClip), pbox = RegionRects(pClip);
189706f2543Smrg	 nbox--;
190706f2543Smrg	 pbox++)
191706f2543Smrg    {
192706f2543Smrg	partX1 = pbox->x1;
193706f2543Smrg	if (partX1 < x1)
194706f2543Smrg	    partX1 = x1;
195706f2543Smrg
196706f2543Smrg	partX2 = pbox->x2;
197706f2543Smrg	if (partX2 > x2)
198706f2543Smrg	    partX2 = x2;
199706f2543Smrg
200706f2543Smrg	if (partX2 <= partX1)
201706f2543Smrg	    continue;
202706f2543Smrg
203706f2543Smrg	partY1 = pbox->y1;
204706f2543Smrg	if (partY1 < y1)
205706f2543Smrg	    partY1 = y1;
206706f2543Smrg
207706f2543Smrg	partY2 = pbox->y2;
208706f2543Smrg	if (partY2 > y2)
209706f2543Smrg	    partY2 = y2;
210706f2543Smrg
211706f2543Smrg	if (partY2 <= partY1)
212706f2543Smrg	    continue;
213706f2543Smrg
214706f2543Smrg#ifndef FB_ACCESS_WRAPPER
215706f2543Smrg	if (and || !pixman_fill ((uint32_t *)dst, dstStride, dstBpp,
216706f2543Smrg				 partX1 + dstXoff, partY1 + dstYoff,
217706f2543Smrg				 (partX2 - partX1), (partY2 - partY1),
218706f2543Smrg				 xor))
219706f2543Smrg#endif
220706f2543Smrg	    fbSolid (dst + (partY1 + dstYoff) * dstStride,
221706f2543Smrg		     dstStride,
222706f2543Smrg		     (partX1 + dstXoff) * dstBpp,
223706f2543Smrg		     dstBpp,
224706f2543Smrg
225706f2543Smrg		     (partX2 - partX1) * dstBpp,
226706f2543Smrg		     (partY2 - partY1),
227706f2543Smrg		     and, xor);
228706f2543Smrg    }
229706f2543Smrg    fbFinishAccess (pDrawable);
230706f2543Smrg}
231