1 /* $OpenBSD: rasops_bitops.h,v 1.9 2020/07/20 12:40:45 fcambus 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 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #ifndef _RASOPS_BITOPS_H_
34 #define _RASOPS_BITOPS_H_ 1
35
36 /*
37 * Erase columns.
38 */
39 int
NAME(erasecols)40 NAME(erasecols)(void *cookie, int row, int col, int num, uint32_t attr)
41 {
42 int lmask, rmask, lclr, rclr, clr;
43 struct rasops_info *ri;
44 int32_t *dp, *rp;
45 int height, cnt;
46
47 ri = (struct rasops_info *)cookie;
48
49 #ifdef RASOPS_CLIPPING
50 if ((unsigned)row >= (unsigned)ri->ri_rows)
51 return 0;
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 0;
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[(attr >> 16) & 0xf];
68 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + ((col >> 3) & ~3));
69
70 if ((col & 31) + num <= 32) {
71 lmask = ~rasops_pmask[col & 31][num];
72 lclr = clr & ~lmask;
73
74 while (height--) {
75 dp = rp;
76 DELTA(rp, ri->ri_stride, int32_t *);
77
78 *dp = (*dp & lmask) | lclr;
79 }
80 } else {
81 lmask = rasops_rmask[col & 31];
82 rmask = rasops_lmask[(col + num) & 31];
83
84 if (lmask)
85 num = (num - (32 - (col & 31))) >> 5;
86 else
87 num = num >> 5;
88
89 lclr = clr & ~lmask;
90 rclr = clr & ~rmask;
91
92 while (height--) {
93 dp = rp;
94 DELTA(rp, ri->ri_stride, int32_t *);
95
96 if (lmask) {
97 *dp = (*dp & lmask) | lclr;
98 dp++;
99 }
100
101 for (cnt = num; cnt > 0; cnt--)
102 *dp++ = clr;
103
104 if (rmask)
105 *dp = (*dp & rmask) | rclr;
106 }
107 }
108
109 return 0;
110 }
111
112 /*
113 * Actually paint the cursor.
114 */
115 int
NAME(do_cursor)116 NAME(do_cursor)(struct rasops_info *ri)
117 {
118 int lmask, rmask, height, row, col, num;
119 int32_t *dp, *rp;
120
121 row = ri->ri_crow;
122 col = ri->ri_ccol * ri->ri_font->fontwidth << PIXEL_SHIFT;
123 height = ri->ri_font->fontheight;
124 num = ri->ri_font->fontwidth << PIXEL_SHIFT;
125 rp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale + ((col >> 3) & ~3));
126
127 if ((col & 31) + num <= 32) {
128 lmask = rasops_pmask[col & 31][num];
129
130 while (height--) {
131 dp = rp;
132 DELTA(rp, ri->ri_stride, int32_t *);
133 *dp ^= lmask;
134 }
135 } else {
136 lmask = ~rasops_rmask[col & 31];
137 rmask = ~rasops_lmask[(col + num) & 31];
138
139 while (height--) {
140 dp = rp;
141 DELTA(rp, ri->ri_stride, int32_t *);
142
143 if (lmask != -1)
144 *dp++ ^= lmask;
145
146 if (rmask != -1)
147 *dp ^= rmask;
148 }
149 }
150
151 return 0;
152 }
153
154 /*
155 * Copy columns. Ick!
156 */
157 int
NAME(copycols)158 NAME(copycols)(void *cookie, int row, int src, int dst, int num)
159 {
160 int tmp, lmask, rmask, height, lnum, rnum, sb, db, cnt, full;
161 int32_t *sp, *dp, *srp, *drp;
162 struct rasops_info *ri;
163
164 ri = (struct rasops_info *)cookie;
165
166 #ifdef RASOPS_CLIPPING
167 if (dst == src)
168 return 0;
169
170 /* Catches < 0 case too */
171 if ((unsigned)row >= (unsigned)ri->ri_rows)
172 return 0;
173
174 if (src < 0) {
175 num += src;
176 src = 0;
177 }
178
179 if ((src + num) > ri->ri_cols)
180 num = ri->ri_cols - src;
181
182 if (dst < 0) {
183 num += dst;
184 dst = 0;
185 }
186
187 if ((dst + num) > ri->ri_cols)
188 num = ri->ri_cols - dst;
189
190 if (num <= 0)
191 return 0;
192 #endif
193
194 cnt = ri->ri_font->fontwidth << PIXEL_SHIFT;
195 src *= cnt;
196 dst *= cnt;
197 num *= cnt;
198 row *= ri->ri_yscale;
199 height = ri->ri_font->fontheight;
200 db = dst & 31;
201
202 if (db + num <= 32) {
203 /* Destination is contained within a single word */
204 srp = (int32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
205 drp = (int32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
206 sb = src & 31;
207
208 while (height--) {
209 GETBITS(srp, sb, num, tmp);
210 PUTBITS(tmp, db, num, drp);
211 DELTA(srp, ri->ri_stride, int32_t *);
212 DELTA(drp, ri->ri_stride, int32_t *);
213 }
214
215 return 0;
216 }
217
218 lmask = rasops_rmask[db];
219 rmask = rasops_lmask[(dst + num) & 31];
220 lnum = (32 - db) & 31;
221 rnum = (dst + num) & 31;
222
223 if (lmask)
224 full = (num - (32 - (dst & 31))) >> 5;
225 else
226 full = num >> 5;
227
228 if (src < dst && src + num > dst) {
229 /* Copy right-to-left */
230 sb = src & 31;
231 src = src + num;
232 dst = dst + num;
233 srp = (int32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
234 drp = (int32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
235
236 src = src & 31;
237 rnum = 32 - lnum;
238 db = dst & 31;
239
240 if ((src -= db) < 0)
241 src += 32;
242
243 while (height--) {
244 sp = srp;
245 dp = drp;
246 DELTA(srp, ri->ri_stride, int32_t *);
247 DELTA(drp, ri->ri_stride, int32_t *);
248
249 if (db) {
250 GETBITS(sp, src, db, tmp);
251 PUTBITS(tmp, 0, db, dp);
252 dp--;
253 sp--;
254 }
255
256 /* Now aligned to 32-bits wrt dp */
257 for (cnt = full; cnt; cnt--, sp--) {
258 GETBITS(sp, src, 32, tmp);
259 *dp-- = tmp;
260 }
261
262 if (lmask) {
263 #if 0
264 if (src > sb)
265 sp++;
266 #endif
267 GETBITS(sp, sb, lnum, tmp);
268 PUTBITS(tmp, rnum, lnum, dp);
269 }
270 }
271 } else {
272 /* Copy left-to-right */
273 srp = (int32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
274 drp = (int32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
275 db = dst & 31;
276
277 while (height--) {
278 sb = src & 31;
279 sp = srp;
280 dp = drp;
281 DELTA(srp, ri->ri_stride, int32_t *);
282 DELTA(drp, ri->ri_stride, int32_t *);
283
284 if (lmask) {
285 GETBITS(sp, sb, lnum, tmp);
286 PUTBITS(tmp, db, lnum, dp);
287 dp++;
288
289 if ((sb += lnum) > 31) {
290 sp++;
291 sb -= 32;
292 }
293 }
294
295 /* Now aligned to 32-bits wrt dp */
296 for (cnt = full; cnt; cnt--, sp++) {
297 GETBITS(sp, sb, 32, tmp);
298 *dp++ = tmp;
299 }
300
301 if (rmask) {
302 GETBITS(sp, sb, rnum, tmp);
303 PUTBITS(tmp, 0, rnum, dp);
304 }
305 }
306 }
307
308 return 0;
309 }
310
311 #endif /* _RASOPS_BITOPS_H_ */
312