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