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