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