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
30fbPushPattern (DrawablePtr  pDrawable,
31	       GCPtr	    pGC,
32
33	       FbStip	    *src,
34	       FbStride	    srcStride,
35	       int	    srcX,
36
37	       int	    x,
38	       int	    y,
39
40	       int	    width,
41	       int	    height)
42{
43    FbStip	    *s, bitsMask, bitsMask0, bits;
44    int		    xspan;
45    int		    w;
46    int		    lenspan;
47
48    src += srcX >> FB_STIP_SHIFT;
49    srcX &= FB_STIP_MASK;
50
51    bitsMask0 = FbStipMask (srcX, 1);
52
53    while (height--)
54    {
55	bitsMask = bitsMask0;
56	w = width;
57	s = src;
58	src += srcStride;
59	bits = READ(s++);
60	xspan = x;
61	while (w)
62	{
63	    if (bits & bitsMask)
64	    {
65		lenspan = 0;
66		do
67		{
68		    lenspan++;
69		    if (lenspan == w)
70			break;
71		    bitsMask = FbStipRight (bitsMask, 1);
72		    if (!bitsMask)
73		    {
74			bits = READ(s++);
75			bitsMask = FbBitsMask(0,1);
76		    }
77		} while (bits & bitsMask);
78		fbFill (pDrawable, pGC, xspan, y, lenspan, 1);
79		xspan += lenspan;
80		w -= lenspan;
81	    }
82	    else
83	    {
84		do
85		{
86		    w--;
87		    xspan++;
88		    if (!w)
89			break;
90		    bitsMask = FbStipRight (bitsMask, 1);
91		    if (!bitsMask)
92		    {
93			bits = READ(s++);
94			bitsMask = FbBitsMask(0,1);
95		    }
96		} while (!(bits & bitsMask));
97	    }
98	}
99	y++;
100    }
101}
102
103void
104fbPushFill (DrawablePtr	pDrawable,
105	    GCPtr	pGC,
106
107	    FbStip	*src,
108	    FbStride	srcStride,
109	    int		srcX,
110
111	    int		x,
112	    int		y,
113	    int		width,
114	    int		height)
115{
116    FbGCPrivPtr	pPriv = fbGetGCPrivate(pGC);
117
118    if (pGC->fillStyle == FillSolid)
119    {
120	FbBits	    *dst;
121	FbStride    dstStride;
122	int	    dstBpp;
123	int	    dstXoff, dstYoff;
124	int	    dstX;
125	int	    dstWidth;
126
127	fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
128	dst = dst + (y + dstYoff) * dstStride;
129	dstX = (x + dstXoff) * dstBpp;
130	dstWidth = width * dstBpp;
131	if (dstBpp == 1)
132	{
133	    fbBltStip (src,
134		       srcStride,
135		       srcX,
136
137		       (FbStip *) dst,
138		       FbBitsStrideToStipStride (dstStride),
139		       dstX,
140
141		       dstWidth,
142		       height,
143
144		       FbStipple1Rop(pGC->alu,pGC->fgPixel),
145		       pPriv->pm,
146		       dstBpp);
147	}
148	else
149	{
150	    fbBltOne (src,
151		      srcStride,
152		      srcX,
153
154		      dst,
155		      dstStride,
156		      dstX,
157		      dstBpp,
158
159		      dstWidth,
160		      height,
161
162		      pPriv->and, pPriv->xor,
163		      fbAnd(GXnoop,(FbBits) 0,FB_ALLONES),
164		      fbXor(GXnoop,(FbBits) 0,FB_ALLONES));
165	}
166	fbFinishAccess (pDrawable);
167    }
168    else
169    {
170	fbPushPattern (pDrawable, pGC, src, srcStride, srcX,
171		       x, y, width, height);
172    }
173}
174
175void
176fbPushImage (DrawablePtr    pDrawable,
177	     GCPtr	    pGC,
178
179	     FbStip	    *src,
180	     FbStride	    srcStride,
181	     int	    srcX,
182
183	     int	    x,
184	     int	    y,
185	     int	    width,
186	     int	    height)
187{
188    RegionPtr	pClip = fbGetCompositeClip (pGC);
189    int		nbox;
190    BoxPtr	pbox;
191    int		x1, y1, x2, y2;
192
193    for (nbox = RegionNumRects (pClip),
194	 pbox = RegionRects(pClip);
195	 nbox--;
196	 pbox++)
197    {
198	x1 = x;
199	y1 = y;
200	x2 = x + width;
201	y2 = y + height;
202	if (x1 < pbox->x1)
203	    x1 = pbox->x1;
204	if (y1 < pbox->y1)
205	    y1 = pbox->y1;
206	if (x2 > pbox->x2)
207	    x2 = pbox->x2;
208	if (y2 > pbox->y2)
209	    y2 = pbox->y2;
210	if (x1 >= x2 || y1 >= y2)
211	    continue;
212	fbPushFill (pDrawable,
213		    pGC,
214
215		    src + (y1 - y) * srcStride,
216		    srcStride,
217		    srcX + (x1 - x),
218
219		    x1,
220		    y1,
221		    x2 - x1,
222		    y2 - y1);
223    }
224}
225
226void
227fbPushPixels (GCPtr	    pGC,
228	      PixmapPtr	    pBitmap,
229	      DrawablePtr   pDrawable,
230	      int	    dx,
231	      int	    dy,
232	      int	    xOrg,
233	      int	    yOrg)
234{
235    FbStip	*stip;
236    FbStride	stipStride;
237    int		stipBpp;
238    int		stipXoff, stipYoff; /* Assumed to be zero */
239
240    fbGetStipDrawable (&pBitmap->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
241
242    fbPushImage (pDrawable, pGC,
243		 stip, stipStride, 0,
244		 xOrg, yOrg, dx, dy);
245}
246