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