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