1 /* $NetBSD: rasops_bitops.h,v 1.12 2010/04/08 16:45:53 macallan 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 sp = NULL; /* XXX gcc */ 209 210 ri = (struct rasops_info *)cookie; 211 212 #ifdef RASOPS_CLIPPING 213 if (dst == src) 214 return; 215 216 /* Catches < 0 case too */ 217 if ((unsigned)row >= (unsigned)ri->ri_rows) 218 return; 219 220 if (src < 0) { 221 num += src; 222 src = 0; 223 } 224 225 if ((src + num) > ri->ri_cols) 226 num = ri->ri_cols - src; 227 228 if (dst < 0) { 229 num += dst; 230 dst = 0; 231 } 232 233 if ((dst + num) > ri->ri_cols) 234 num = ri->ri_cols - dst; 235 236 if (num <= 0) 237 return; 238 #endif 239 240 cnt = ri->ri_font->fontwidth << PIXEL_SHIFT; 241 src *= cnt; 242 dst *= cnt; 243 num *= cnt; 244 row *= ri->ri_yscale; 245 height = ri->ri_font->fontheight; 246 db = dst & 31; 247 248 if (db + num <= 32) { 249 /* Destination is contained within a single word */ 250 srp = (int32_t *)(ri->ri_bits + row + ((src >> 3) & ~3)); 251 drp = (int32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3)); 252 if (ri->ri_hwbits) 253 dhp = (int32_t *)(ri->ri_hwbits + row + 254 ((dst >> 3) & ~3)); 255 sb = src & 31; 256 257 while (height--) { 258 GETBITS(srp, sb, num, tmp); 259 PUTBITS(tmp, db, num, drp); 260 if (ri->ri_hwbits) { 261 PUTBITS(tmp, db, num, dhp); 262 DELTA(dhp, ri->ri_stride, int32_t *); 263 } 264 DELTA(srp, ri->ri_stride, int32_t *); 265 DELTA(drp, ri->ri_stride, int32_t *); 266 } 267 268 return; 269 } 270 271 lmask = rasops_rmask[db]; 272 rmask = rasops_lmask[(dst + num) & 31]; 273 lnum = (32 - db) & 31; 274 rnum = (dst + num) & 31; 275 276 if (lmask) 277 full = (num - (32 - (dst & 31))) >> 5; 278 else 279 full = num >> 5; 280 281 if (src < dst && src + num > dst) { 282 /* Copy right-to-left */ 283 sb = src & 31; 284 src = src + num; 285 dst = dst + num; 286 srp = (int32_t *)(ri->ri_bits + row + ((src >> 3) & ~3)); 287 drp = (int32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3)); 288 if (ri->ri_hwbits) 289 dhp = (int32_t *)(ri->ri_hwbits + row + 290 ((dst >> 3) & ~3)); 291 292 src = src & 31; 293 rnum = 32 - lnum; 294 db = dst & 31; 295 296 if ((src -= db) < 0) { 297 sp--; 298 src += 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, int32_t *); 307 } 308 DELTA(srp, ri->ri_stride, int32_t *); 309 DELTA(drp, ri->ri_stride, int32_t *); 310 311 if (db) { 312 GETBITS(sp, src, db, tmp); 313 PUTBITS(tmp, 0, db, dp); 314 if (ri->ri_hwbits) { 315 PUTBITS(tmp, 0, db, hp); 316 hp++; 317 } 318 dp--; 319 sp--; 320 } 321 322 /* Now aligned to 32-bits wrt dp */ 323 for (cnt = full; cnt; cnt--, sp--) { 324 GETBITS(sp, src, 32, tmp); 325 *dp-- = tmp; 326 if (ri->ri_hwbits) 327 *hp-- = tmp; 328 } 329 330 if (lmask) { 331 #if 0 332 if (src > sb) 333 sp++; 334 #endif 335 GETBITS(sp, sb, lnum, tmp); 336 PUTBITS(tmp, rnum, lnum, dp); 337 if (ri->ri_hwbits) 338 PUTBITS(tmp, rnum, lnum, hp); 339 } 340 } 341 } else { 342 /* Copy left-to-right */ 343 srp = (int32_t *)(ri->ri_bits + row + ((src >> 3) & ~3)); 344 drp = (int32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3)); 345 if (ri->ri_hwbits) 346 dhp = (int32_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, int32_t *); 357 } 358 DELTA(srp, ri->ri_stride, int32_t *); 359 DELTA(drp, ri->ri_stride, int32_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