rasops_bitops.h revision 1.17 1 /* $NetBSD: rasops_bitops.h,v 1.17 2019/07/28 12:06:10 rin 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 lclr, rclr, clr;
42 struct rasops_info *ri;
43 uint32_t *dp, *rp, *hrp = NULL, *hp = NULL, tmp, lmask, rmask;
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[((uint32_t)attr >> 16) & 0xf];
67 rp = (uint32_t *)(ri->ri_bits + row*ri->ri_yscale + ((col >> 3) & ~3));
68 if (ri->ri_hwbits)
69 hrp = (uint32_t *)(ri->ri_hwbits + row*ri->ri_yscale +
70 ((col >> 3) & ~3));
71 if ((col & 31) + num <= 32) {
72 lmask = ~rasops_pmask[col & 31][num];
73 lclr = clr & ~lmask;
74
75 while (height--) {
76 dp = rp;
77 DELTA(rp, ri->ri_stride, uint32_t *);
78
79 tmp = (*dp & lmask) | lclr;
80 *dp = tmp;
81 if (ri->ri_hwbits) {
82 *hrp = tmp;
83 DELTA(hrp, ri->ri_stride, uint32_t *);
84 }
85 }
86 } else {
87 lmask = rasops_rmask[col & 31];
88 rmask = rasops_lmask[(col + num) & 31];
89
90 if (lmask)
91 num = (num - (32 - (col & 31))) >> 5;
92 else
93 num = num >> 5;
94
95 lclr = clr & ~lmask;
96 rclr = clr & ~rmask;
97
98 while (height--) {
99 dp = rp;
100 DELTA(rp, ri->ri_stride, uint32_t *);
101 if (ri->ri_hwbits) {
102 hp = hrp;
103 DELTA(hrp, ri->ri_stride, uint32_t *);
104 }
105
106 if (lmask) {
107 tmp = (*dp & lmask) | lclr;
108 *dp = tmp;
109 dp++;
110 if (ri->ri_hwbits) {
111 *hp = tmp;
112 hp++;
113 }
114 }
115
116 for (cnt = num; cnt > 0; cnt--)
117 *dp++ = clr;
118 if (ri->ri_hwbits) {
119 for (cnt = num; cnt > 0; cnt--)
120 *hp++ = clr;
121 }
122
123 if (rmask) {
124 tmp = (*dp & rmask) | rclr;
125 *dp = tmp;
126 if (ri->ri_hwbits)
127 *hp = tmp;
128 }
129 }
130 }
131 }
132
133 /*
134 * Actually paint the cursor.
135 */
136 static void
137 NAME(do_cursor)(struct rasops_info *ri)
138 {
139 int height, row, col, num;
140 uint32_t *dp, *rp, *hp = NULL, *hrp = NULL, tmp, lmask, rmask;
141
142 row = ri->ri_crow;
143 col = ri->ri_ccol * ri->ri_font->fontwidth << PIXEL_SHIFT;
144 height = ri->ri_font->fontheight;
145 num = ri->ri_font->fontwidth << PIXEL_SHIFT;
146 rp = (uint32_t *)(ri->ri_bits + row * ri->ri_yscale +
147 ((col >> 3) & ~3));
148 if (ri->ri_hwbits)
149 hrp = (uint32_t *)(ri->ri_hwbits + row * ri->ri_yscale +
150 ((col >> 3) & ~3));
151
152 if ((col & 31) + num <= 32) {
153 lmask = rasops_pmask[col & 31][num];
154
155 while (height--) {
156 dp = rp;
157 DELTA(rp, ri->ri_stride, uint32_t *);
158 *dp ^= lmask;
159 }
160 if (ri->ri_hwbits) {
161 height = ri->ri_font->fontheight;
162 while (height--) {
163 hp = hrp;
164 DELTA(hrp, ri->ri_stride, uint32_t *);
165 *hp ^= lmask;
166 }
167 }
168 } else {
169 lmask = ~rasops_rmask[col & 31];
170 rmask = ~rasops_lmask[(col + num) & 31];
171
172 while (height--) {
173 dp = rp;
174 DELTA(rp, ri->ri_stride, uint32_t *);
175 if (ri->ri_hwbits) {
176 hp = hrp;
177 DELTA(hrp, ri->ri_stride, uint32_t *);
178 }
179 if (lmask != -1) {
180 tmp = *dp ^ lmask;
181 *dp = tmp;
182 dp++;
183 if (ri->ri_hwbits) {
184 *hp = tmp;
185 hp++;
186 }
187 }
188
189 if (rmask != -1) {
190 tmp = *dp ^ rmask;
191 *dp = tmp;
192 if (ri->ri_hwbits)
193 *hp = tmp;
194 }
195 }
196 }
197 }
198
199 /*
200 * Copy columns. Ick!
201 */
202 static void
203 NAME(copycols)(void *cookie, int row, int src, int dst, int num)
204 {
205 int height, lnum, rnum, sb, db, cnt, full;
206 uint32_t tmp, lmask, rmask;
207 uint32_t *sp, *dp, *srp, *drp, *dhp = NULL, *hp = NULL;
208 struct rasops_info *ri;
209
210 ri = (struct rasops_info *)cookie;
211
212 #ifdef RASOPS_CLIPPING
213 if (dst == src)
214 return;
215
216 /* Catches < 0 case too */
217 if ((unsigned)row >= (unsigned)ri->ri_rows)
218 return;
219
220 if (src < 0) {
221 num += src;
222 src = 0;
223 }
224
225 if ((src + num) > ri->ri_cols)
226 num = ri->ri_cols - src;
227
228 if (dst < 0) {
229 num += dst;
230 dst = 0;
231 }
232
233 if ((dst + num) > ri->ri_cols)
234 num = ri->ri_cols - dst;
235
236 if (num <= 0)
237 return;
238 #endif
239
240 cnt = ri->ri_font->fontwidth << PIXEL_SHIFT;
241 src *= cnt;
242 dst *= cnt;
243 num *= cnt;
244 row *= ri->ri_yscale;
245 height = ri->ri_font->fontheight;
246 db = dst & 31;
247
248 if (db + num <= 32) {
249 /* Destination is contained within a single word */
250 srp = (uint32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
251 drp = (uint32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
252 if (ri->ri_hwbits)
253 dhp = (uint32_t *)(ri->ri_hwbits + row +
254 ((dst >> 3) & ~3));
255 sb = src & 31;
256
257 while (height--) {
258 GETBITS(srp, sb, num, tmp);
259 PUTBITS(tmp, db, num, drp);
260 if (ri->ri_hwbits) {
261 PUTBITS(tmp, db, num, dhp);
262 DELTA(dhp, ri->ri_stride, uint32_t *);
263 }
264 DELTA(srp, ri->ri_stride, uint32_t *);
265 DELTA(drp, ri->ri_stride, uint32_t *);
266 }
267
268 return;
269 }
270
271 lmask = rasops_rmask[db];
272 rmask = rasops_lmask[(dst + num) & 31];
273 lnum = (32 - db) & 31;
274 rnum = (dst + num) & 31;
275
276 if (lmask)
277 full = (num - (32 - (dst & 31))) >> 5;
278 else
279 full = num >> 5;
280
281 if (src < dst && src + num > dst) {
282 /* Copy right-to-left */
283 bool sbover;
284 int sboff;
285
286 srp = (uint32_t *)(ri->ri_bits + row +
287 (((src + num) >> 3) & ~3));
288 drp = (uint32_t *)(ri->ri_bits + row +
289 (((dst + num) >> 3) & ~3));
290 if (ri->ri_hwbits)
291 dhp = (uint32_t *)(ri->ri_hwbits + row +
292 (((dst + num) >> 3) & ~3));
293
294 sb = src & 31;
295 sbover = (sb + lnum) >= 32;
296 sboff = (src + num) & 31;
297 if ((sboff -= rnum) < 0) {
298 srp--;
299 sboff += 32;
300 }
301
302 while (height--) {
303 sp = srp;
304 dp = drp;
305 if (ri->ri_hwbits) {
306 hp = dhp;
307 DELTA(dhp, ri->ri_stride, uint32_t *);
308 }
309 DELTA(srp, ri->ri_stride, uint32_t *);
310 DELTA(drp, ri->ri_stride, uint32_t *);
311
312 if (rnum) {
313 GETBITS(sp, sboff, rnum, tmp);
314 PUTBITS(tmp, 0, rnum, dp);
315 if (ri->ri_hwbits) {
316 PUTBITS(tmp, 0, rnum, hp);
317 }
318 }
319
320 /* Now aligned to 32-bits wrt dp */
321 for (cnt = full; cnt; cnt--) {
322 --dp;
323 --sp;
324 GETBITS(sp, sboff, 32, tmp);
325 *dp = tmp;
326 if (ri->ri_hwbits) {
327 --hp;
328 *hp = tmp;
329 }
330 }
331
332 if (lmask) {
333 if (sbover)
334 --sp;
335 --dp;
336 GETBITS(sp, sb, lnum, tmp);
337 PUTBITS(tmp, db, lnum, dp);
338 if (ri->ri_hwbits)
339 PUTBITS(tmp, db, lnum, hp);
340 }
341 }
342 } else {
343 /* Copy left-to-right */
344 srp = (uint32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
345 drp = (uint32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
346 if (ri->ri_hwbits)
347 dhp = (uint32_t *)(ri->ri_hwbits + row +
348 ((dst >> 3) & ~3));
349 db = dst & 31;
350
351 while (height--) {
352 sb = src & 31;
353 sp = srp;
354 dp = drp;
355 if (ri->ri_hwbits) {
356 hp = dhp;
357 DELTA(dhp, ri->ri_stride, uint32_t *);
358 }
359 DELTA(srp, ri->ri_stride, uint32_t *);
360 DELTA(drp, ri->ri_stride, uint32_t *);
361
362 if (lmask) {
363 GETBITS(sp, sb, lnum, tmp);
364 PUTBITS(tmp, db, lnum, dp);
365 dp++;
366 if (ri->ri_hwbits) {
367 PUTBITS(tmp, db, lnum, hp);
368 hp++;
369 }
370
371 if ((sb += lnum) > 31) {
372 sp++;
373 sb -= 32;
374 }
375 }
376
377 /* Now aligned to 32-bits wrt dp */
378 for (cnt = full; cnt; cnt--, sp++) {
379 GETBITS(sp, sb, 32, tmp);
380 *dp++ = tmp;
381 if (ri->ri_hwbits)
382 *hp++ = tmp;
383 }
384
385 if (rmask) {
386 GETBITS(sp, sb, rnum, tmp);
387 PUTBITS(tmp, 0, rnum, dp);
388 if (ri->ri_hwbits)
389 PUTBITS(tmp, 0, rnum, hp);
390 }
391 }
392 }
393 }
394
395 #endif /* _RASOPS_BITOPS_H_ */
396