1 /* $OpenBSD: rasops_bitops.h,v 1.3 2003/02/12 20:53:59 henric Exp $ */
2 /* $NetBSD: rasops_bitops.h,v 1.6 2000/04/12 14:22:30 pk Exp $ */
3
4 /*-
5 * Copyright (c) 1999 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Andrew Doran.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 #ifndef _RASOPS_BITOPS_H_
41 #define _RASOPS_BITOPS_H_ 1
42
43 /*
44 * Erase columns.
45 */
46 void
47 NAME(erasecols)(cookie, row, col, num, attr)
48 void *cookie;
49 int row, col, num;
50 long attr;
51 {
52 int lmask, rmask, lclr, rclr, clr;
53 struct rasops_info *ri;
54 int32_t *dp, *rp;
55 int height, cnt;
56
57 ri = (struct rasops_info *)cookie;
58
59 #ifdef RASOPS_CLIPPING
60 if ((unsigned)row >= (unsigned)ri->ri_rows)
61 return;
62
63 if (col < 0) {
64 num += col;
65 col = 0;
66 }
67
68 if ((col + num) > ri->ri_cols)
69 num = ri->ri_cols - col;
70
71 if (num <= 0)
72 return;
73 #endif
74 col *= ri->ri_font->fontwidth << PIXEL_SHIFT;
75 num *= ri->ri_font->fontwidth << PIXEL_SHIFT;
76 height = ri->ri_font->fontheight;
77 clr = ri->ri_devcmap[(attr >> 16) & 0xf];
78 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + ((col >> 3) & ~3));
79
80 if ((col & 31) + num <= 32) {
81 lmask = ~rasops_pmask[col & 31][num];
82 lclr = clr & ~lmask;
83
84 while (height--) {
85 dp = rp;
86 DELTA(rp, ri->ri_stride, int32_t *);
87
88 *dp = (*dp & lmask) | lclr;
89 }
90 } else {
91 lmask = rasops_rmask[col & 31];
92 rmask = rasops_lmask[(col + num) & 31];
93
94 if (lmask)
95 num = (num - (32 - (col & 31))) >> 5;
96 else
97 num = num >> 5;
98
99 lclr = clr & ~lmask;
100 rclr = clr & ~rmask;
101
102 while (height--) {
103 dp = rp;
104 DELTA(rp, ri->ri_stride, int32_t *);
105
106 if (lmask) {
107 *dp = (*dp & lmask) | lclr;
108 dp++;
109 }
110
111 for (cnt = num; cnt > 0; cnt--)
112 *dp++ = clr;
113
114 if (rmask)
115 *dp = (*dp & rmask) | rclr;
116 }
117 }
118 }
119
120 /*
121 * Actually paint the cursor.
122 */
123 void
124 NAME(do_cursor)(ri)
125 struct rasops_info *ri;
126 {
127 int lmask, rmask, height, row, col, num;
128 int32_t *dp, *rp;
129
130 row = ri->ri_crow;
131 col = ri->ri_ccol * ri->ri_font->fontwidth << PIXEL_SHIFT;
132 height = ri->ri_font->fontheight;
133 num = ri->ri_font->fontwidth << PIXEL_SHIFT;
134 rp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale + ((col >> 3) & ~3));
135
136 if ((col & 31) + num <= 32) {
137 lmask = rasops_pmask[col & 31][num];
138
139 while (height--) {
140 dp = rp;
141 DELTA(rp, ri->ri_stride, int32_t *);
142 *dp ^= lmask;
143 }
144 } else {
145 lmask = ~rasops_rmask[col & 31];
146 rmask = ~rasops_lmask[(col + num) & 31];
147
148 while (height--) {
149 dp = rp;
150 DELTA(rp, ri->ri_stride, int32_t *);
151
152 if (lmask != -1)
153 *dp++ ^= lmask;
154
155 if (rmask != -1)
156 *dp ^= rmask;
157 }
158 }
159 }
160
161 /*
162 * Copy columns. Ick!
163 */
164 void
165 NAME(copycols)(cookie, row, src, dst, num)
166 void *cookie;
167 int row, src, dst, num;
168 {
169 int tmp, lmask, rmask, height, lnum, rnum, sb, db, cnt, full;
170 int32_t *sp, *dp, *srp, *drp;
171 struct rasops_info *ri;
172
173 ri = (struct rasops_info *)cookie;
174
175 #ifdef RASOPS_CLIPPING
176 if (dst == src)
177 return;
178
179 /* Catches < 0 case too */
180 if ((unsigned)row >= (unsigned)ri->ri_rows)
181 return;
182
183 if (src < 0) {
184 num += src;
185 src = 0;
186 }
187
188 if ((src + num) > ri->ri_cols)
189 num = ri->ri_cols - src;
190
191 if (dst < 0) {
192 num += dst;
193 dst = 0;
194 }
195
196 if ((dst + num) > ri->ri_cols)
197 num = ri->ri_cols - dst;
198
199 if (num <= 0)
200 return;
201 #endif
202
203 cnt = ri->ri_font->fontwidth << PIXEL_SHIFT;
204 src *= cnt;
205 dst *= cnt;
206 num *= cnt;
207 row *= ri->ri_yscale;
208 height = ri->ri_font->fontheight;
209 db = dst & 31;
210
211 if (db + num <= 32) {
212 /* Destination is contained within a single word */
213 srp = (int32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
214 drp = (int32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
215 sb = src & 31;
216
217 while (height--) {
218 GETBITS(srp, sb, num, tmp);
219 PUTBITS(tmp, db, num, drp);
220 DELTA(srp, ri->ri_stride, int32_t *);
221 DELTA(drp, ri->ri_stride, int32_t *);
222 }
223
224 return;
225 }
226
227 lmask = rasops_rmask[db];
228 rmask = rasops_lmask[(dst + num) & 31];
229 lnum = (32 - db) & 31;
230 rnum = (dst + num) & 31;
231
232 if (lmask)
233 full = (num - (32 - (dst & 31))) >> 5;
234 else
235 full = num >> 5;
236
237 if (src < dst && src + num > dst) {
238 /* Copy right-to-left */
239 sb = src & 31;
240 src = src + num;
241 dst = dst + num;
242 srp = (int32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
243 drp = (int32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
244
245 src = src & 31;
246 rnum = 32 - lnum;
247 db = dst & 31;
248
249 if ((src -= db) < 0) {
250 sp--;
251 src += 32;
252 }
253
254 while (height--) {
255 sp = srp;
256 dp = drp;
257 DELTA(srp, ri->ri_stride, int32_t *);
258 DELTA(drp, ri->ri_stride, int32_t *);
259
260 if (db) {
261 GETBITS(sp, src, db, tmp);
262 PUTBITS(tmp, 0, db, dp);
263 dp--;
264 sp--;
265 }
266
267 /* Now aligned to 32-bits wrt dp */
268 for (cnt = full; cnt; cnt--, sp--) {
269 GETBITS(sp, src, 32, tmp);
270 *dp-- = tmp;
271 }
272
273 if (lmask) {
274 #if 0
275 if (src > sb)
276 sp++;
277 #endif
278 GETBITS(sp, sb, lnum, tmp);
279 PUTBITS(tmp, rnum, lnum, dp);
280 }
281 }
282 } else {
283 /* Copy left-to-right */
284 srp = (int32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
285 drp = (int32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
286 db = dst & 31;
287
288 while (height--) {
289 sb = src & 31;
290 sp = srp;
291 dp = drp;
292 DELTA(srp, ri->ri_stride, int32_t *);
293 DELTA(drp, ri->ri_stride, int32_t *);
294
295 if (lmask) {
296 GETBITS(sp, sb, lnum, tmp);
297 PUTBITS(tmp, db, lnum, dp);
298 dp++;
299
300 if ((sb += lnum) > 31) {
301 sp++;
302 sb -= 32;
303 }
304 }
305
306 /* Now aligned to 32-bits wrt dp */
307 for (cnt = full; cnt; cnt--, sp++) {
308 GETBITS(sp, sb, 32, tmp);
309 *dp++ = tmp;
310 }
311
312 if (rmask) {
313 GETBITS(sp, sb, rnum, tmp);
314 PUTBITS(tmp, 0, rnum, dp);
315 }
316 }
317 }
318 }
319
320 #endif /* _RASOPS_BITOPS_H_ */