1 /* $NetBSD: rasops_bitops.h,v 1.14 2013/05/21 15:57:21 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 lmask, rmask, lclr, rclr, clr; 42 struct rasops_info *ri; 43 int32_t *dp, *rp, *hrp = NULL, *hp = NULL, tmp; 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 = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + ((col >> 3) & ~3)); 68 if (ri->ri_hwbits) 69 hrp = (int32_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, int32_t *); 78 79 tmp = (*dp & lmask) | lclr; 80 *dp = tmp; 81 if (ri->ri_hwbits) { 82 *hrp = tmp; 83 DELTA(hrp, ri->ri_stride, int32_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, int32_t *); 101 if (ri->ri_hwbits) { 102 hp = hrp; 103 DELTA(hrp, ri->ri_stride, int32_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 lmask, rmask, height, row, col, num; 140 int32_t *dp, *rp, *hp = NULL, *hrp = NULL, tmp; 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 = (int32_t *)(ri->ri_bits + row * ri->ri_yscale + ((col >> 3) & ~3)); 147 if (ri->ri_hwbits) 148 hrp = (int32_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, int32_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, int32_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, int32_t *); 174 if (ri->ri_hwbits) { 175 hp = hrp; 176 DELTA(hrp, ri->ri_stride, int32_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 tmp, lmask, rmask, height, lnum, rnum, sb, db, cnt, full; 205 int32_t *sp, *dp, *srp, *drp, *dhp = NULL, *hp = NULL; 206 struct rasops_info *ri; 207 208 ri = (struct rasops_info *)cookie; 209 210 #ifdef RASOPS_CLIPPING 211 if (dst == src) 212 return; 213 214 /* Catches < 0 case too */ 215 if ((unsigned)row >= (unsigned)ri->ri_rows) 216 return; 217 218 if (src < 0) { 219 num += src; 220 src = 0; 221 } 222 223 if ((src + num) > ri->ri_cols) 224 num = ri->ri_cols - src; 225 226 if (dst < 0) { 227 num += dst; 228 dst = 0; 229 } 230 231 if ((dst + num) > ri->ri_cols) 232 num = ri->ri_cols - dst; 233 234 if (num <= 0) 235 return; 236 #endif 237 238 cnt = ri->ri_font->fontwidth << PIXEL_SHIFT; 239 src *= cnt; 240 dst *= cnt; 241 num *= cnt; 242 row *= ri->ri_yscale; 243 height = ri->ri_font->fontheight; 244 db = dst & 31; 245 246 if (db + num <= 32) { 247 /* Destination is contained within a single word */ 248 srp = (int32_t *)(ri->ri_bits + row + ((src >> 3) & ~3)); 249 drp = (int32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3)); 250 if (ri->ri_hwbits) 251 dhp = (int32_t *)(ri->ri_hwbits + row + 252 ((dst >> 3) & ~3)); 253 sb = src & 31; 254 255 while (height--) { 256 GETBITS(srp, sb, num, tmp); 257 PUTBITS(tmp, db, num, drp); 258 if (ri->ri_hwbits) { 259 PUTBITS(tmp, db, num, dhp); 260 DELTA(dhp, ri->ri_stride, int32_t *); 261 } 262 DELTA(srp, ri->ri_stride, int32_t *); 263 DELTA(drp, ri->ri_stride, int32_t *); 264 } 265 266 return; 267 } 268 269 lmask = rasops_rmask[db]; 270 rmask = rasops_lmask[(dst + num) & 31]; 271 lnum = (32 - db) & 31; 272 rnum = (dst + num) & 31; 273 274 if (lmask) 275 full = (num - (32 - (dst & 31))) >> 5; 276 else 277 full = num >> 5; 278 279 if (src < dst && src + num > dst) { 280 /* Copy right-to-left */ 281 sb = src & 31; 282 src = src + num; 283 dst = dst + num; 284 srp = (int32_t *)(ri->ri_bits + row + ((src >> 3) & ~3)); 285 drp = (int32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3)); 286 if (ri->ri_hwbits) 287 dhp = (int32_t *)(ri->ri_hwbits + row + 288 ((dst >> 3) & ~3)); 289 290 src = src & 31; 291 rnum = 32 - lnum; 292 db = dst & 31; 293 294 if ((src -= db) < 0) { 295 srp--; 296 src += 32; 297 } 298 299 while (height--) { 300 sp = srp; 301 dp = drp; 302 if (ri->ri_hwbits) { 303 hp = dhp; 304 DELTA(dhp, ri->ri_stride, int32_t *); 305 } 306 DELTA(srp, ri->ri_stride, int32_t *); 307 DELTA(drp, ri->ri_stride, int32_t *); 308 309 if (db) { 310 GETBITS(sp, src, db, tmp); 311 PUTBITS(tmp, 0, db, dp); 312 if (ri->ri_hwbits) { 313 PUTBITS(tmp, 0, db, hp); 314 hp--; 315 } 316 dp--; 317 sp--; 318 } 319 320 /* Now aligned to 32-bits wrt dp */ 321 for (cnt = full; cnt; cnt--, sp--) { 322 GETBITS(sp, src, 32, tmp); 323 *dp-- = tmp; 324 if (ri->ri_hwbits) 325 *hp-- = tmp; 326 } 327 328 if (lmask) { 329 #if 0 330 if (src > sb) 331 sp++; 332 #endif 333 GETBITS(sp, sb, lnum, tmp); 334 PUTBITS(tmp, rnum, lnum, dp); 335 if (ri->ri_hwbits) 336 PUTBITS(tmp, rnum, lnum, hp); 337 } 338 } 339 } else { 340 /* Copy left-to-right */ 341 srp = (int32_t *)(ri->ri_bits + row + ((src >> 3) & ~3)); 342 drp = (int32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3)); 343 if (ri->ri_hwbits) 344 dhp = (int32_t *)(ri->ri_hwbits + row + 345 ((dst >> 3) & ~3)); 346 db = dst & 31; 347 348 while (height--) { 349 sb = src & 31; 350 sp = srp; 351 dp = drp; 352 if (ri->ri_hwbits) { 353 hp = dhp; 354 DELTA(dhp, ri->ri_stride, int32_t *); 355 } 356 DELTA(srp, ri->ri_stride, int32_t *); 357 DELTA(drp, ri->ri_stride, int32_t *); 358 359 if (lmask) { 360 GETBITS(sp, sb, lnum, tmp); 361 PUTBITS(tmp, db, lnum, dp); 362 dp++; 363 if (ri->ri_hwbits) { 364 PUTBITS(tmp, db, lnum, hp); 365 hp++; 366 } 367 368 if ((sb += lnum) > 31) { 369 sp++; 370 sb -= 32; 371 } 372 } 373 374 /* Now aligned to 32-bits wrt dp */ 375 for (cnt = full; cnt; cnt--, sp++) { 376 GETBITS(sp, sb, 32, tmp); 377 *dp++ = tmp; 378 if (ri->ri_hwbits) 379 *hp++ = tmp; 380 } 381 382 if (rmask) { 383 GETBITS(sp, sb, rnum, tmp); 384 PUTBITS(tmp, 0, rnum, dp); 385 if (ri->ri_hwbits) 386 PUTBITS(tmp, 0, rnum, hp); 387 } 388 } 389 } 390 } 391 392 #endif /* _RASOPS_BITOPS_H_ */ 393