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#define FbSelectPart(xor,o,t)    xor
24
25#ifdef HAVE_DIX_CONFIG_H
26#include <dix-config.h>
27#endif
28
29#include "fb.h"
30
31void
32fbSolid (FbBits	    *dst,
33	 FbStride   dstStride,
34	 int	    dstX,
35	 int	    bpp,
36
37	 int	    width,
38	 int	    height,
39
40	 FbBits	    and,
41	 FbBits	    xor)
42{
43    FbBits  startmask, endmask;
44    int	    n, nmiddle;
45    int	    startbyte, endbyte;
46
47#ifdef FB_24BIT
48    if (bpp == 24 && (!FbCheck24Pix(and) || !FbCheck24Pix(xor)))
49    {
50	fbSolid24 (dst, dstStride, dstX, width, height, and, xor);
51	return;
52    }
53#endif
54    dst += dstX >> FB_SHIFT;
55    dstX &= FB_MASK;
56    FbMaskBitsBytes(dstX, width, and == 0, startmask, startbyte,
57		    nmiddle, endmask, endbyte);
58    if (startmask)
59	dstStride--;
60    dstStride -= nmiddle;
61    while (height--)
62    {
63	if (startmask)
64	{
65	    FbDoLeftMaskByteRRop(dst,startbyte,startmask,and,xor);
66	    dst++;
67	}
68	n = nmiddle;
69	if (!and)
70	    while (n--)
71		WRITE(dst++, xor);
72	else
73	    while (n--)
74	    {
75		WRITE(dst, FbDoRRop (READ(dst), and, xor));
76                dst++;
77	    }
78	if (endmask)
79	    FbDoRightMaskByteRRop(dst,endbyte,endmask,and,xor);
80	dst += dstStride;
81    }
82}
83
84#ifdef FB_24BIT
85void
86fbSolid24 (FbBits   *dst,
87	   FbStride dstStride,
88	   int	    dstX,
89
90	   int	    width,
91	   int	    height,
92
93	   FbBits   and,
94	   FbBits   xor)
95{
96    FbBits  startmask, endmask;
97    FbBits  xor0 = 0, xor1 = 0, xor2 = 0;
98    FbBits  and0 = 0, and1 = 0, and2 = 0;
99    FbBits  xorS = 0, andS = 0, xorE = 0, andE = 0;
100    int	    n, nmiddle;
101    int	    rotS, rot;
102
103    dst += dstX >> FB_SHIFT;
104    dstX &= FB_MASK;
105    /*
106     * Rotate pixel values this far across the word to align on
107     * screen pixel boundaries
108     */
109    rot = FbFirst24Rot (dstX);
110    FbMaskBits (dstX, width, startmask, nmiddle, endmask);
111    if (startmask)
112	dstStride--;
113    dstStride -= nmiddle;
114
115    /*
116     * Precompute rotated versions of the rasterop values
117     */
118    rotS = rot;
119    xor = FbRot24(xor,rotS);
120    and = FbRot24(and,rotS);
121    if (startmask)
122    {
123	xorS = xor;
124	andS = and;
125	xor = FbNext24Pix(xor);
126	and = FbNext24Pix(and);
127    }
128
129    if (nmiddle)
130    {
131	xor0 = xor;
132	and0 = and;
133	xor1 = FbNext24Pix(xor0);
134	and1 = FbNext24Pix(and0);
135	xor2 = FbNext24Pix(xor1);
136	and2 = FbNext24Pix(and1);
137    }
138
139    if (endmask)
140    {
141	switch (nmiddle % 3) {
142	case 0:
143	    xorE = xor;
144	    andE = and;
145	    break;
146	case 1:
147	    xorE = xor1;
148	    andE = and1;
149	    break;
150	case 2:
151	    xorE = xor2;
152	    andE = and2;
153	    break;
154	}
155    }
156
157    while (height--)
158    {
159	if (startmask)
160	{
161	    WRITE(dst, FbDoMaskRRop(READ(dst), andS, xorS, startmask));
162            dst++;
163	}
164	n = nmiddle;
165	if (!and0)
166	{
167	    while (n >= 3)
168	    {
169		WRITE(dst++, xor0);
170		WRITE(dst++, xor1);
171		WRITE(dst++, xor2);
172		n -= 3;
173	    }
174	    if (n)
175	    {
176		WRITE(dst++, xor0);
177		n--;
178		if (n)
179		{
180		    WRITE(dst++, xor1);
181		}
182	    }
183	}
184	else
185	{
186	    while (n >= 3)
187	    {
188		WRITE(dst, FbDoRRop (READ(dst), and0, xor0));
189                dst++;
190		WRITE(dst, FbDoRRop (READ(dst), and1, xor1));
191                dst++;
192		WRITE(dst, FbDoRRop (READ(dst), and2, xor2));
193                dst++;
194		n -= 3;
195	    }
196	    if (n)
197	    {
198		WRITE(dst, FbDoRRop (READ(dst), and0, xor0));
199                dst++;
200		n--;
201		if (n)
202		{
203		    WRITE(dst, FbDoRRop (READ(dst), and1, xor1));
204                    dst++;
205		}
206	    }
207	}
208	if (endmask)
209	    WRITE(dst, FbDoMaskRRop (READ(dst), andE, xorE, endmask));
210	dst += dstStride;
211    }
212}
213#endif
214