rasops_bitops.h revision 1.21 1 /* $NetBSD: rasops_bitops.h,v 1.21 2019/08/02 04:31: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 #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
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
190 DELTA(rp, ri->ri_stride, uint32_t *);
191 }
192 }
193 }
194
195 /*
196 * Copy columns. Ick!
197 */
198 static void
199 NAME(copycols)(void *cookie, int row, int src, int dst, int num)
200 {
201 struct rasops_info *ri = (struct rasops_info *)cookie;
202 int height, lnum, rnum, sb, db, cnt, full;
203 uint32_t tmp, lmask, rmask;
204 uint32_t *sp, *dp, *srp, *drp, *dhp, *hp;
205
206 dhp = hp = NULL; /* XXX GCC */
207
208 #ifdef RASOPS_CLIPPING
209 if (dst == src)
210 return;
211
212 /* Catches < 0 case too */
213 if ((unsigned)row >= (unsigned)ri->ri_rows)
214 return;
215
216 if (src < 0) {
217 num += src;
218 src = 0;
219 }
220
221 if (src + num > ri->ri_cols)
222 num = ri->ri_cols - src;
223
224 if (dst < 0) {
225 num += dst;
226 dst = 0;
227 }
228
229 if (dst + num > ri->ri_cols)
230 num = ri->ri_cols - dst;
231
232 if (num <= 0)
233 return;
234 #endif
235
236 cnt = ri->ri_font->fontwidth << PIXEL_SHIFT;
237 src *= cnt;
238 dst *= cnt;
239 num *= cnt;
240 row *= ri->ri_yscale;
241 height = ri->ri_font->fontheight;
242 db = dst & 31;
243
244 if (db + num <= 32) {
245 /* Destination is contained within a single word */
246 srp = (uint32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
247 drp = (uint32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
248 if (ri->ri_hwbits)
249 dhp = (uint32_t *)(ri->ri_hwbits + row +
250 ((dst >> 3) & ~3));
251 sb = src & 31;
252
253 while (height--) {
254 GETBITS(srp, sb, num, tmp);
255 PUTBITS(tmp, db, num, drp);
256 if (ri->ri_hwbits) {
257 PUTBITS(tmp, db, num, dhp);
258 DELTA(dhp, ri->ri_stride, uint32_t *);
259 }
260 DELTA(srp, ri->ri_stride, uint32_t *);
261 DELTA(drp, ri->ri_stride, uint32_t *);
262 }
263
264 return;
265 }
266
267 lmask = rasops_rmask[db];
268 rmask = rasops_lmask[(dst + num) & 31];
269 lnum = (32 - db) & 31;
270 rnum = (dst + num) & 31;
271
272 if (lmask)
273 full = (num - lnum) >> 5;
274 else
275 full = num >> 5;
276
277 if (src < dst && src + num > dst) {
278 /* Copy right-to-left */
279 bool sbover;
280 int sboff;
281
282 srp = (uint32_t *)(ri->ri_bits + row +
283 (((src + num) >> 3) & ~3));
284 drp = (uint32_t *)(ri->ri_bits + row +
285 (((dst + num) >> 3) & ~3));
286 if (ri->ri_hwbits)
287 dhp = (uint32_t *)(ri->ri_hwbits + row +
288 (((dst + num) >> 3) & ~3));
289
290 sb = src & 31;
291 sbover = (sb + lnum) >= 32;
292 sboff = (src + num) & 31;
293 if ((sboff -= rnum) < 0) {
294 srp--;
295 sboff += 32;
296 }
297
298 while (height--) {
299 sp = srp;
300 dp = drp;
301 DELTA(srp, ri->ri_stride, uint32_t *);
302 DELTA(drp, ri->ri_stride, uint32_t *);
303
304 if (rnum) {
305 GETBITS(sp, sboff, rnum, tmp);
306 PUTBITS(tmp, 0, rnum, dp);
307 }
308
309 /* Now aligned to 32-bits wrt dp */
310 for (cnt = full; cnt; cnt--) {
311 --dp;
312 --sp;
313 GETBITS(sp, sboff, 32, tmp);
314 *dp = tmp;
315 }
316
317 if (lmask) {
318 if (sbover)
319 --sp;
320 --dp;
321 GETBITS(sp, sb, lnum, tmp);
322 PUTBITS(tmp, db, lnum, dp);
323 }
324
325 if (ri->ri_hwbits) {
326 hp = dhp;
327 hp -= full + (lmask != 0);
328 memcpy(hp, dp, ((rmask != 0) + cnt +
329 (lmask != 0)) << 2);
330 DELTA(dhp, ri->ri_stride, uint32_t *);
331 }
332 }
333 } else {
334 /* Copy left-to-right */
335 srp = (uint32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
336 drp = (uint32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
337 if (ri->ri_hwbits)
338 dhp = (uint32_t *)(ri->ri_hwbits + row +
339 ((dst >> 3) & ~3));
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 sb += lnum;
352 if (sb > 31) {
353 sp++;
354 sb -= 32;
355 }
356 }
357
358 /* Now aligned to 32-bits wrt dp */
359 for (cnt = full; cnt; cnt--, sp++) {
360 GETBITS(sp, sb, 32, tmp);
361 *dp++ = tmp;
362 }
363
364 if (rmask) {
365 GETBITS(sp, sb, rnum, tmp);
366 PUTBITS(tmp, 0, rnum, dp);
367 }
368
369 if (ri->ri_hwbits) {
370 memcpy(dhp, drp, ((lmask != 0) + full +
371 (rmask != 0)) << 2);
372 DELTA(dhp, ri->ri_stride, uint32_t *);
373 }
374
375 DELTA(srp, ri->ri_stride, uint32_t *);
376 DELTA(drp, ri->ri_stride, uint32_t *);
377 }
378 }
379 }
380
381 #endif /* _RASOPS_BITOPS_H_ */
382