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