xref: /netbsd-src/sys/dev/rasops/rasops_bitops.h (revision 404fbe5fb94ca1e054339640cabb2801ce52dd30)
1 /* 	$NetBSD: rasops_bitops.h,v 1.10 2008/04/28 20:23:56 martin 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)(cookie, row, col, num, attr)
40 	void *cookie;
41 	int row, col, num;
42 	long attr;
43 {
44 	int lmask, rmask, lclr, rclr, clr;
45 	struct rasops_info *ri;
46 	int32_t *dp, *rp;
47 	int height, cnt;
48 
49 	ri = (struct rasops_info *)cookie;
50 
51 #ifdef RASOPS_CLIPPING
52 	if ((unsigned)row >= (unsigned)ri->ri_rows)
53 		return;
54 
55 	if (col < 0) {
56 		num += col;
57 		col = 0;
58 	}
59 
60 	if ((col + num) > ri->ri_cols)
61 		num = ri->ri_cols - col;
62 
63 	if (num <= 0)
64 		return;
65 #endif
66 	col *= ri->ri_font->fontwidth << PIXEL_SHIFT;
67 	num *= ri->ri_font->fontwidth << PIXEL_SHIFT;
68 	height = ri->ri_font->fontheight;
69 	clr = ri->ri_devcmap[(attr >> 16) & 0xf];
70 	rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + ((col >> 3) & ~3));
71 
72 	if ((col & 31) + num <= 32) {
73 		lmask = ~rasops_pmask[col & 31][num];
74 		lclr = clr & ~lmask;
75 
76 		while (height--) {
77 			dp = rp;
78 			DELTA(rp, ri->ri_stride, int32_t *);
79 
80 			*dp = (*dp & lmask) | lclr;
81 		}
82 	} else {
83 		lmask = rasops_rmask[col & 31];
84 		rmask = rasops_lmask[(col + num) & 31];
85 
86 		if (lmask)
87 			num = (num - (32 - (col & 31))) >> 5;
88 		else
89 			num = num >> 5;
90 
91 		lclr = clr & ~lmask;
92 		rclr = clr & ~rmask;
93 
94 		while (height--) {
95 			dp = rp;
96 			DELTA(rp, ri->ri_stride, int32_t *);
97 
98 			if (lmask) {
99 				*dp = (*dp & lmask) | lclr;
100 				dp++;
101 			}
102 
103 			for (cnt = num; cnt > 0; cnt--)
104 				*dp++ = clr;
105 
106 			if (rmask)
107 				*dp = (*dp & rmask) | rclr;
108 		}
109 	}
110 }
111 
112 /*
113  * Actually paint the cursor.
114  */
115 static void
116 NAME(do_cursor)(ri)
117 	struct rasops_info *ri;
118 {
119 	int lmask, rmask, height, row, col, num;
120 	int32_t *dp, *rp;
121 
122 	row = ri->ri_crow;
123 	col = ri->ri_ccol * ri->ri_font->fontwidth << PIXEL_SHIFT;
124 	height = ri->ri_font->fontheight;
125 	num = ri->ri_font->fontwidth << PIXEL_SHIFT;
126 	rp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale + ((col >> 3) & ~3));
127 
128 	if ((col & 31) + num <= 32) {
129 		lmask = rasops_pmask[col & 31][num];
130 
131 		while (height--) {
132 			dp = rp;
133 			DELTA(rp, ri->ri_stride, int32_t *);
134 			*dp ^= lmask;
135 		}
136 	} else {
137 		lmask = ~rasops_rmask[col & 31];
138 		rmask = ~rasops_lmask[(col + num) & 31];
139 
140 		while (height--) {
141 			dp = rp;
142 			DELTA(rp, ri->ri_stride, int32_t *);
143 
144 			if (lmask != -1)
145 				*dp++ ^= lmask;
146 
147 			if (rmask != -1)
148 				*dp ^= rmask;
149 		}
150 	}
151 }
152 
153 /*
154  * Copy columns. Ick!
155  */
156 static void
157 NAME(copycols)(cookie, row, src, dst, num)
158 	void *cookie;
159 	int row, src, dst, num;
160 {
161 	int tmp, lmask, rmask, height, lnum, rnum, sb, db, cnt, full;
162 	int32_t *sp, *dp, *srp, *drp;
163 	struct rasops_info *ri;
164 
165 	sp = NULL;	/* XXX gcc */
166 
167 	ri = (struct rasops_info *)cookie;
168 
169 #ifdef RASOPS_CLIPPING
170 	if (dst == src)
171 		return;
172 
173 	/* Catches < 0 case too */
174 	if ((unsigned)row >= (unsigned)ri->ri_rows)
175 		return;
176 
177 	if (src < 0) {
178 		num += src;
179 		src = 0;
180 	}
181 
182 	if ((src + num) > ri->ri_cols)
183 		num = ri->ri_cols - src;
184 
185 	if (dst < 0) {
186 		num += dst;
187 		dst = 0;
188 	}
189 
190 	if ((dst + num) > ri->ri_cols)
191 		num = ri->ri_cols - dst;
192 
193 	if (num <= 0)
194 		return;
195 #endif
196 
197 	cnt = ri->ri_font->fontwidth << PIXEL_SHIFT;
198 	src *= cnt;
199 	dst *= cnt;
200 	num *= cnt;
201 	row *= ri->ri_yscale;
202 	height = ri->ri_font->fontheight;
203 	db = dst & 31;
204 
205 	if (db + num <= 32) {
206 		/* Destination is contained within a single word */
207 		srp = (int32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
208 		drp = (int32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
209 		sb = src & 31;
210 
211 		while (height--) {
212 			GETBITS(srp, sb, num, tmp);
213 			PUTBITS(tmp, db, num, drp);
214 			DELTA(srp, ri->ri_stride, int32_t *);
215 			DELTA(drp, ri->ri_stride, int32_t *);
216 		}
217 
218 		return;
219 	}
220 
221 	lmask = rasops_rmask[db];
222 	rmask = rasops_lmask[(dst + num) & 31];
223 	lnum = (32 - db) & 31;
224 	rnum = (dst + num) & 31;
225 
226 	if (lmask)
227 		full = (num - (32 - (dst & 31))) >> 5;
228 	else
229 		full = num >> 5;
230 
231 	if (src < dst && src + num > dst) {
232 		/* Copy right-to-left */
233 		sb = src & 31;
234 		src = src + num;
235 		dst = dst + num;
236 		srp = (int32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
237 		drp = (int32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
238 
239 		src = src & 31;
240 		rnum = 32 - lnum;
241 		db = dst & 31;
242 
243 		if ((src -= db) < 0) {
244 			sp--;
245 			src += 32;
246 		}
247 
248 		while (height--) {
249 			sp = srp;
250 			dp = drp;
251 			DELTA(srp, ri->ri_stride, int32_t *);
252 			DELTA(drp, ri->ri_stride, int32_t *);
253 
254 			if (db) {
255 				GETBITS(sp, src, db, tmp);
256 				PUTBITS(tmp, 0, db, dp);
257 				dp--;
258 				sp--;
259 			}
260 
261 			/* Now aligned to 32-bits wrt dp */
262 			for (cnt = full; cnt; cnt--, sp--) {
263 				GETBITS(sp, src, 32, tmp);
264 				*dp-- = tmp;
265 			}
266 
267 			if (lmask) {
268 #if 0
269 				if (src > sb)
270 					sp++;
271 #endif
272 				GETBITS(sp, sb, lnum, tmp);
273 				PUTBITS(tmp, rnum, lnum, dp);
274  			}
275  		}
276 	} else {
277 		/* Copy left-to-right */
278 		srp = (int32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
279 		drp = (int32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
280 		db = dst & 31;
281 
282 		while (height--) {
283 			sb = src & 31;
284 			sp = srp;
285 			dp = drp;
286 			DELTA(srp, ri->ri_stride, int32_t *);
287 			DELTA(drp, ri->ri_stride, int32_t *);
288 
289 			if (lmask) {
290 				GETBITS(sp, sb, lnum, tmp);
291 				PUTBITS(tmp, db, lnum, dp);
292 				dp++;
293 
294 				if ((sb += lnum) > 31) {
295 					sp++;
296 					sb -= 32;
297 				}
298 			}
299 
300 			/* Now aligned to 32-bits wrt dp */
301 			for (cnt = full; cnt; cnt--, sp++) {
302 				GETBITS(sp, sb, 32, tmp);
303 				*dp++ = tmp;
304 			}
305 
306 			if (rmask) {
307 				GETBITS(sp, sb, rnum, tmp);
308 				PUTBITS(tmp, 0, rnum, dp);
309  			}
310  		}
311  	}
312 }
313 
314 #endif /* _RASOPS_BITOPS_H_ */
315