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