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