1 /* $OpenBSD: rasops1.c,v 1.1 2001/03/18 04:32:44 nate Exp $ */ 2 /* $NetBSD: rasops1.c,v 1.11 2000/04/12 14:22:29 pk Exp $ */ 3 4 /*- 5 * Copyright (c) 1999 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Andrew Doran. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 #include <sys/cdefs.h> 41 //__KERNEL_RCSID(0, "$NetBSD: rasops1.c,v 1.11 2000/04/12 14:22:29 pk Exp $"); 42 43 #include <sys/types.h> 44 #include <sys/param.h> 45 #include <sys/systm.h> 46 #include <sys/time.h> 47 #include <machine/endian.h> 48 49 #include <dev/wscons/wsdisplayvar.h> 50 #include <dev/wscons/wsconsio.h> 51 #include <dev/rasops/rasops.h> 52 #include <dev/rasops/rasops_masks.h> 53 54 static void rasops1_copycols __P((void *, int, int, int, int)); 55 static void rasops1_erasecols __P((void *, int, int, int, long)); 56 static void rasops1_do_cursor __P((struct rasops_info *)); 57 static void rasops1_putchar __P((void *, int, int col, u_int, long)); 58 #ifndef RASOPS_SMALL 59 static void rasops1_putchar8 __P((void *, int, int col, u_int, long)); 60 static void rasops1_putchar16 __P((void *, int, int col, u_int, long)); 61 #endif 62 63 /* 64 * Initalize rasops_info struct for this colordepth. 65 */ 66 void 67 rasops1_init(ri) 68 struct rasops_info *ri; 69 { 70 71 switch (ri->ri_font->fontwidth) { 72 #ifndef RASOPS_SMALL 73 case 8: 74 ri->ri_ops.putchar = rasops1_putchar8; 75 break; 76 case 16: 77 ri->ri_ops.putchar = rasops1_putchar16; 78 break; 79 #endif 80 default: 81 ri->ri_ops.putchar = rasops1_putchar; 82 break; 83 } 84 85 if ((ri->ri_font->fontwidth & 7) != 0) { 86 ri->ri_ops.erasecols = rasops1_erasecols; 87 ri->ri_ops.copycols = rasops1_copycols; 88 ri->ri_do_cursor = rasops1_do_cursor; 89 } 90 } 91 92 /* 93 * Paint a single character. This is the generic version, this is ugly. 94 */ 95 static void 96 rasops1_putchar(cookie, row, col, uc, attr) 97 void *cookie; 98 int row, col; 99 u_int uc; 100 long attr; 101 { 102 u_int fs, rs, fb, bg, fg, lmask, rmask; 103 u_int32_t height, width; 104 struct rasops_info *ri; 105 int32_t *rp; 106 u_char *fr; 107 108 ri = (struct rasops_info *)cookie; 109 110 #ifdef RASOPS_CLIPPING 111 /* Catches 'row < 0' case too */ 112 if ((unsigned)row >= (unsigned)ri->ri_rows) 113 return; 114 115 if ((unsigned)col >= (unsigned)ri->ri_cols) 116 return; 117 #endif 118 119 col *= ri->ri_font->fontwidth; 120 rp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale + ((col >> 3) & ~3)); 121 height = ri->ri_font->fontheight; 122 width = ri->ri_font->fontwidth; 123 col = col & 31; 124 rs = ri->ri_stride; 125 126 bg = (attr & 0x000f0000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0]; 127 fg = (attr & 0x0f000000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0]; 128 129 /* If fg and bg match this becomes a space character */ 130 if (fg == bg || uc == ' ') { 131 uc = (u_int)-1; 132 fr = 0; /* shutup gcc */ 133 fs = 0; /* shutup gcc */ 134 } else { 135 uc -= ri->ri_font->firstchar; 136 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale; 137 fs = ri->ri_font->stride; 138 } 139 140 /* Single word, one mask */ 141 if ((col + width) <= 32) { 142 rmask = rasops_pmask[col][width]; 143 lmask = ~rmask; 144 145 if (uc == (u_int)-1) { 146 bg &= rmask; 147 148 while (height--) { 149 *rp = (*rp & lmask) | bg; 150 DELTA(rp, rs, int32_t *); 151 } 152 } else { 153 /* NOT fontbits if bg is white */ 154 if (bg) { 155 while (height--) { 156 fb = ~(fr[3] | (fr[2] << 8) | 157 (fr[1] << 16) | (fr[0] << 24)); 158 *rp = (*rp & lmask) 159 | (MBE(fb >> col) & rmask); 160 161 fr += fs; 162 DELTA(rp, rs, int32_t *); 163 } 164 } else { 165 while (height--) { 166 fb = (fr[3] | (fr[2] << 8) | 167 (fr[1] << 16) | (fr[0] << 24)); 168 *rp = (*rp & lmask) 169 | (MBE(fb >> col) & rmask); 170 171 fr += fs; 172 DELTA(rp, rs, int32_t *); 173 } 174 } 175 } 176 177 /* Do underline */ 178 if ((attr & 1) != 0) { 179 DELTA(rp, -(ri->ri_stride << 1), int32_t *); 180 *rp = (*rp & lmask) | (fg & rmask); 181 } 182 } else { 183 lmask = ~rasops_lmask[col]; 184 rmask = ~rasops_rmask[(col + width) & 31]; 185 186 if (uc == (u_int)-1) { 187 width = bg & ~rmask; 188 bg = bg & ~lmask; 189 190 while (height--) { 191 rp[0] = (rp[0] & lmask) | bg; 192 rp[1] = (rp[1] & rmask) | width; 193 DELTA(rp, rs, int32_t *); 194 } 195 } else { 196 width = 32 - col; 197 198 /* NOT fontbits if bg is white */ 199 if (bg) { 200 while (height--) { 201 fb = ~(fr[3] | (fr[2] << 8) | 202 (fr[1] << 16) | (fr[0] << 24)); 203 204 rp[0] = (rp[0] & lmask) 205 | MBE((u_int)fb >> col); 206 207 rp[1] = (rp[1] & rmask) 208 | (MBE((u_int)fb << width) & ~rmask); 209 210 fr += fs; 211 DELTA(rp, rs, int32_t *); 212 } 213 } else { 214 while (height--) { 215 fb = (fr[3] | (fr[2] << 8) | 216 (fr[1] << 16) | (fr[0] << 24)); 217 218 rp[0] = (rp[0] & lmask) 219 | MBE(fb >> col); 220 221 rp[1] = (rp[1] & rmask) 222 | (MBE(fb << width) & ~rmask); 223 224 fr += fs; 225 DELTA(rp, rs, int32_t *); 226 } 227 } 228 } 229 230 /* Do underline */ 231 if ((attr & 1) != 0) { 232 DELTA(rp, -(ri->ri_stride << 1), int32_t *); 233 rp[0] = (rp[0] & lmask) | (fg & ~lmask); 234 rp[1] = (rp[1] & rmask) | (fg & ~rmask); 235 } 236 } 237 } 238 239 #ifndef RASOPS_SMALL 240 /* 241 * Paint a single character. This is for 8-pixel wide fonts. 242 */ 243 static void 244 rasops1_putchar8(cookie, row, col, uc, attr) 245 void *cookie; 246 int row, col; 247 u_int uc; 248 long attr; 249 { 250 int height, fs, rs, bg, fg; 251 struct rasops_info *ri; 252 u_char *fr, *rp; 253 254 ri = (struct rasops_info *)cookie; 255 256 #ifdef RASOPS_CLIPPING 257 /* Catches 'row < 0' case too */ 258 if ((unsigned)row >= (unsigned)ri->ri_rows) 259 return; 260 261 if ((unsigned)col >= (unsigned)ri->ri_cols) 262 return; 263 #endif 264 265 rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale; 266 height = ri->ri_font->fontheight; 267 rs = ri->ri_stride; 268 269 bg = (attr & 0x000f0000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0]; 270 fg = (attr & 0x0f000000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0]; 271 272 /* If fg and bg match this becomes a space character */ 273 if (fg == bg || uc == ' ') { 274 while (height--) { 275 *rp = bg; 276 rp += rs; 277 } 278 } else { 279 uc -= ri->ri_font->firstchar; 280 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale; 281 fs = ri->ri_font->stride; 282 283 /* NOT fontbits if bg is white */ 284 if (bg) { 285 while (height--) { 286 *rp = ~*fr; 287 fr += fs; 288 rp += rs; 289 } 290 } else { 291 while (height--) { 292 *rp = *fr; 293 fr += fs; 294 rp += rs; 295 } 296 } 297 298 } 299 300 /* Do underline */ 301 if ((attr & 1) != 0) 302 rp[-(ri->ri_stride << 1)] = fg; 303 } 304 305 /* 306 * Paint a single character. This is for 16-pixel wide fonts. 307 */ 308 static void 309 rasops1_putchar16(cookie, row, col, uc, attr) 310 void *cookie; 311 int row, col; 312 u_int uc; 313 long attr; 314 { 315 int height, fs, rs, bg, fg; 316 struct rasops_info *ri; 317 u_char *fr, *rp; 318 319 ri = (struct rasops_info *)cookie; 320 321 #ifdef RASOPS_CLIPPING 322 /* Catches 'row < 0' case too */ 323 if ((unsigned)row >= (unsigned)ri->ri_rows) 324 return; 325 326 if ((unsigned)col >= (unsigned)ri->ri_cols) 327 return; 328 #endif 329 330 rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale; 331 height = ri->ri_font->fontheight; 332 rs = ri->ri_stride; 333 334 bg = (attr & 0x000f0000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0]; 335 fg = (attr & 0x0f000000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0]; 336 337 /* If fg and bg match this becomes a space character */ 338 if (fg == bg || uc == ' ') { 339 while (height--) { 340 *(int16_t *)rp = bg; 341 rp += rs; 342 } 343 } else { 344 uc -= ri->ri_font->firstchar; 345 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale; 346 fs = ri->ri_font->stride; 347 348 /* NOT fontbits if bg is white */ 349 if (bg) { 350 while (height--) { 351 rp[0] = ~fr[0]; 352 rp[1] = ~fr[1]; 353 fr += fs; 354 rp += rs; 355 } 356 } else { 357 while (height--) { 358 rp[0] = fr[0]; 359 rp[1] = fr[1]; 360 fr += fs; 361 rp += rs; 362 } 363 } 364 } 365 366 /* Do underline */ 367 if ((attr & 1) != 0) 368 *(int16_t *)(rp - (ri->ri_stride << 1)) = fg; 369 } 370 #endif /* !RASOPS_SMALL */ 371 372 /* 373 * Grab routines common to depths where (bpp < 8) 374 */ 375 #define NAME(ident) rasops1_##ident 376 #define PIXEL_SHIFT 0 377 378 #include <dev/rasops/rasops_bitops.h> 379