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