xref: /openbsd-src/sys/dev/rasops/rasops_bitops.h (revision db3296cf5c1dd9058ceecc3a29fe4aaa0bd26000)
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_ */
321