1 | /* $NetBSD: rasops_bitops.h,v 1.15 2013/12/02 14:05:51 tsutsui 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[(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 + ((col >> 3) & ~3)); |
147 | if (ri->ri_hwbits) |
148 | hrp = (uint32_t *)(ri->ri_hwbits + row * ri->ri_yscale + |
149 | ((col >> 3) & ~3)); |
150 | |
151 | if ((col & 31) + num <= 32) { |
152 | lmask = rasops_pmask[col & 31][num]; |
153 | |
154 | while (height--) { |
155 | dp = rp; |
156 | DELTA(rp, ri->ri_stride, uint32_t *); |
157 | *dp ^= lmask; |
158 | } |
159 | if (ri->ri_hwbits) { |
160 | height = ri->ri_font->fontheight; |
161 | while (height--) { |
162 | hp = hrp; |
163 | DELTA(hrp, ri->ri_stride, uint32_t *); |
164 | *hp ^= lmask; |
165 | } |
166 | } |
167 | } else { |
168 | lmask = ~rasops_rmask[col & 31]; |
169 | rmask = ~rasops_lmask[(col + num) & 31]; |
170 | |
171 | while (height--) { |
172 | dp = rp; |
173 | DELTA(rp, ri->ri_stride, uint32_t *); |
174 | if (ri->ri_hwbits) { |
175 | hp = hrp; |
176 | DELTA(hrp, ri->ri_stride, uint32_t *); |
177 | } |
178 | if (lmask != -1) { |
179 | tmp = *dp ^ lmask; |
180 | *dp = tmp; |
181 | dp++; |
182 | if (ri->ri_hwbits) { |
183 | *hp = tmp; |
184 | hp++; |
185 | } |
186 | } |
187 | |
188 | if (rmask != -1) { |
189 | tmp = *dp ^ rmask; |
190 | *dp = tmp; |
191 | if (ri->ri_hwbits) |
192 | *hp = tmp; |
193 | } |
194 | } |
195 | } |
196 | } |
197 | |
198 | /* |
199 | * Copy columns. Ick! |
200 | */ |
201 | static void |
202 | NAME(copycols)(void *cookie, int row, int src, int dst, int num) |
203 | { |
204 | int height, lnum, rnum, sb, db, cnt, full; |
205 | uint32_t tmp, lmask, rmask; |
206 | uint32_t *sp, *dp, *srp, *drp, *dhp = NULL, *hp = NULL; |
207 | struct rasops_info *ri; |
208 | |
209 | ri = (struct rasops_info *)cookie; |
210 | |
211 | #ifdef RASOPS_CLIPPING |
212 | if (dst == src) |
213 | return; |
214 | |
215 | /* Catches < 0 case too */ |
216 | if ((unsigned)row >= (unsigned)ri->ri_rows) |
217 | return; |
218 | |
219 | if (src < 0) { |
220 | num += src; |
221 | src = 0; |
222 | } |
223 | |
224 | if ((src + num) > ri->ri_cols) |
225 | num = ri->ri_cols - src; |
226 | |
227 | if (dst < 0) { |
228 | num += dst; |
229 | dst = 0; |
230 | } |
231 | |
232 | if ((dst + num) > ri->ri_cols) |
233 | num = ri->ri_cols - dst; |
234 | |
235 | if (num <= 0) |
236 | return; |
237 | #endif |
238 | |
239 | cnt = ri->ri_font->fontwidth << PIXEL_SHIFT; |
240 | src *= cnt; |
241 | dst *= cnt; |
242 | num *= cnt; |
243 | row *= ri->ri_yscale; |
244 | height = ri->ri_font->fontheight; |
245 | db = dst & 31; |
246 | |
247 | if (db + num <= 32) { |
248 | /* Destination is contained within a single word */ |
249 | srp = (uint32_t *)(ri->ri_bits + row + ((src >> 3) & ~3)); |
250 | drp = (uint32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3)); |
251 | if (ri->ri_hwbits) |
252 | dhp = (uint32_t *)(ri->ri_hwbits + row + |
253 | ((dst >> 3) & ~3)); |
254 | sb = src & 31; |
255 | |
256 | while (height--) { |
257 | GETBITS(srp, sb, num, tmp); |
258 | PUTBITS(tmp, db, num, drp); |
259 | if (ri->ri_hwbits) { |
260 | PUTBITS(tmp, db, num, dhp); |
261 | DELTA(dhp, ri->ri_stride, uint32_t *); |
262 | } |
263 | DELTA(srp, ri->ri_stride, uint32_t *); |
264 | DELTA(drp, ri->ri_stride, uint32_t *); |
265 | } |
266 | |
267 | return; |
268 | } |
269 | |
270 | lmask = rasops_rmask[db]; |
271 | rmask = rasops_lmask[(dst + num) & 31]; |
272 | lnum = (32 - db) & 31; |
273 | rnum = (dst + num) & 31; |
274 | |
275 | if (lmask) |
276 | full = (num - (32 - (dst & 31))) >> 5; |
277 | else |
278 | full = num >> 5; |
279 | |
280 | if (src < dst && src + num > dst) { |
281 | /* Copy right-to-left */ |
282 | bool sbover; |
283 | int sboff; |
284 | |
285 | srp = (uint32_t *)(ri->ri_bits + row + |
286 | (((src + num) >> 3) & ~3)); |
287 | drp = (uint32_t *)(ri->ri_bits + row + |
288 | (((dst + num) >> 3) & ~3)); |
289 | if (ri->ri_hwbits) |
290 | dhp = (uint32_t *)(ri->ri_hwbits + row + |
291 | (((dst + num) >> 3) & ~3)); |
292 | |
293 | sb = src & 31; |
294 | sbover = (sb + lnum) >= 32; |
295 | sboff = (src + num) & 31; |
296 | if ((sboff -= rnum) < 0) { |
297 | srp--; |
298 | sboff += 32; |
299 | } |
300 | |
301 | while (height--) { |
302 | sp = srp; |
303 | dp = drp; |
304 | if (ri->ri_hwbits) { |
305 | hp = dhp; |
306 | DELTA(dhp, ri->ri_stride, uint32_t *); |
307 | } |
308 | DELTA(srp, ri->ri_stride, uint32_t *); |
309 | DELTA(drp, ri->ri_stride, uint32_t *); |
310 | |
311 | if (rnum) { |
312 | GETBITS(sp, sboff, rnum, tmp); |
313 | PUTBITS(tmp, 0, rnum, dp); |
314 | if (ri->ri_hwbits) { |
315 | PUTBITS(tmp, 0, rnum, hp); |
316 | } |
317 | } |
318 | |
319 | /* Now aligned to 32-bits wrt dp */ |
320 | for (cnt = full; cnt; cnt--) { |
321 | --dp; |
322 | --sp; |
323 | GETBITS(sp, sboff, 32, tmp); |
324 | *dp = tmp; |
325 | if (ri->ri_hwbits) { |
326 | --hp; |
327 | *hp = tmp; |
328 | } |
329 | } |
330 | |
331 | if (lmask) { |
332 | if (sbover) |
333 | --sp; |
334 | --dp; |
335 | GETBITS(sp, sb, lnum, tmp); |
336 | PUTBITS(tmp, db, lnum, dp); |
337 | if (ri->ri_hwbits) |
338 | PUTBITS(tmp, db, lnum, hp); |
339 | } |
340 | } |
341 | } else { |
342 | /* Copy left-to-right */ |
343 | srp = (uint32_t *)(ri->ri_bits + row + ((src >> 3) & ~3)); |
344 | drp = (uint32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3)); |
345 | if (ri->ri_hwbits) |
346 | dhp = (uint32_t *)(ri->ri_hwbits + row + |
347 | ((dst >> 3) & ~3)); |
348 | db = dst & 31; |
349 | |
350 | while (height--) { |
351 | sb = src & 31; |
352 | sp = srp; |
353 | dp = drp; |
354 | if (ri->ri_hwbits) { |
355 | hp = dhp; |
356 | DELTA(dhp, ri->ri_stride, uint32_t *); |
357 | } |
358 | DELTA(srp, ri->ri_stride, uint32_t *); |
359 | DELTA(drp, ri->ri_stride, uint32_t *); |
360 | |
361 | if (lmask) { |
362 | GETBITS(sp, sb, lnum, tmp); |
363 | PUTBITS(tmp, db, lnum, dp); |
364 | dp++; |
365 | if (ri->ri_hwbits) { |
366 | PUTBITS(tmp, db, lnum, hp); |
367 | hp++; |
368 | } |
369 | |
370 | if ((sb += lnum) > 31) { |
371 | sp++; |
372 | sb -= 32; |
373 | } |
374 | } |
375 | |
376 | /* Now aligned to 32-bits wrt dp */ |
377 | for (cnt = full; cnt; cnt--, sp++) { |
378 | GETBITS(sp, sb, 32, tmp); |
379 | *dp++ = tmp; |
380 | if (ri->ri_hwbits) |
381 | *hp++ = tmp; |
382 | } |
383 | |
384 | if (rmask) { |
385 | GETBITS(sp, sb, rnum, tmp); |
386 | PUTBITS(tmp, 0, rnum, dp); |
387 | if (ri->ri_hwbits) |
388 | PUTBITS(tmp, 0, rnum, hp); |
389 | } |
390 | } |
391 | } |
392 | } |
393 | |
394 | #endif /* _RASOPS_BITOPS_H_ */ |
395 | |