rasops15.c revision 1.4
1/* $NetBSD: rasops15.c,v 1.4 1999/05/18 21:51:59 ad 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 Andy 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#include "opt_rasops.h" 40#include <sys/cdefs.h> 41__KERNEL_RCSID(0, "$NetBSD: rasops15.c,v 1.4 1999/05/18 21:51:59 ad Exp $"); 42 43#include <sys/types.h> 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/time.h> 47 48#include <dev/wscons/wsdisplayvar.h> 49#include <dev/wscons/wsconsio.h> 50#include <dev/rasops/rasops.h> 51 52static void rasops15_putchar __P((void *, int, int, u_int, long attr)); 53static void rasops15_putchar8 __P((void *, int, int, u_int, long attr)); 54static void rasops15_putchar12 __P((void *, int, int, u_int, long attr)); 55static void rasops15_putchar16 __P((void *, int, int, u_int, long attr)); 56static void rasops15_makestamp __P((struct rasops_info *, long)); 57 58void rasops15_init __P((struct rasops_info *ri)); 59 60/* 61 * (2x2)x1 stamp for optimized character blitting 62 */ 63static int32_t stamp[32]; 64static long stamp_attr; 65static int stamp_mutex; /* XXX see note in readme */ 66 67/* 68 * XXX this confuses the hell out of gcc2 (not egcs) which always insists 69 * that the shift count is negative. 70 * 71 * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK 72 * destination int32_t[0] = STAMP_READ(offset) 73 * destination int32_t[1] = STAMP_READ(offset + 4) 74 */ 75#define STAMP_SHIFT(fb,n) ((n*4-3) >= 0 ? (fb)>>(n*4-3):(fb)<<-(n*4-3)) 76#define STAMP_MASK (15 << 3) 77#define STAMP_READ(o) (*(int32_t *)((caddr_t)stamp + (o))) 78 79 80/* 81 * Initalize rasops_info struct for this colordepth. 82 */ 83void 84rasops15_init(ri) 85 struct rasops_info *ri; 86{ 87 88 switch (ri->ri_font->fontwidth) { 89 case 8: 90 ri->ri_ops.putchar = rasops15_putchar8; 91 break; 92 93 case 12: 94 ri->ri_ops.putchar = rasops15_putchar12; 95 break; 96 97 case 16: 98 ri->ri_ops.putchar = rasops15_putchar16; 99 break; 100 101 default: 102 ri->ri_ops.putchar = rasops15_putchar; 103 break; 104 } 105 106 if (ri->ri_rnum == 0) { 107 ri->ri_rnum = 5; 108 ri->ri_rpos = 0; 109 ri->ri_gnum = 5 + (ri->ri_depth == 16); 110 ri->ri_gpos = 5; 111 ri->ri_bnum = 5; 112 ri->ri_bpos = 10 + (ri->ri_depth == 16); 113 } 114} 115 116 117/* 118 * Paint a single character. 119 */ 120static void 121rasops15_putchar(cookie, row, col, uc, attr) 122 void *cookie; 123 int row, col; 124 u_int uc; 125 long attr; 126{ 127 struct rasops_info *ri; 128 int fb, width, height, cnt, clr[2]; 129 u_char *dp, *rp, *fr; 130 131 ri = (struct rasops_info *)cookie; 132 133#ifdef RASOPS_CLIPPING 134 /* Catches 'row < 0' case too */ 135 if ((unsigned)row >= (unsigned)ri->ri_rows) 136 return; 137 138 if ((unsigned)col >= (unsigned)ri->ri_cols) 139 return; 140#endif 141 142 rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale; 143 height = ri->ri_font->fontheight; 144 width = ri->ri_font->fontwidth; 145 146 clr[1] = ri->ri_devcmap[((u_int)attr >> 24) & 15]; 147 clr[0] = ri->ri_devcmap[((u_int)attr >> 16) & 15]; 148 149 if (uc == ' ') { 150 while (height--) { 151 dp = rp; 152 rp += ri->ri_stride; 153 154 for (cnt = width; cnt; cnt--) { 155 *(int16_t *)dp = (int16_t)clr[0]; 156 dp += 2; 157 } 158 } 159 } else { 160 uc -= ri->ri_font->firstchar; 161 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale; 162 163 while (height--) { 164 dp = rp; 165 fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) | (fr[0] << 24); 166 fr += ri->ri_font->stride; 167 rp += ri->ri_stride; 168 169 for (cnt = width; cnt; cnt--) { 170 *(int16_t *)dp = (int16_t)clr[(fb >> 31) & 1]; 171 fb <<= 1; 172 dp += 2; 173 } 174 } 175 } 176 177 /* Do underline */ 178 if (attr & 1) { 179 rp -= ri->ri_stride << 1; 180 181 while (width--) { 182 *(int16_t *)rp = clr[1]; 183 rp += 2; 184 } 185 } 186} 187 188 189/* 190 * Recompute the (2x2)x1 blitting stamp. 191 */ 192static void 193rasops15_makestamp(ri, attr) 194 struct rasops_info *ri; 195 long attr; 196{ 197 int32_t fg, bg; 198 int i; 199 200 fg = ri->ri_devcmap[((u_int)attr >> 24) & 15] & 0xffff; 201 bg = ri->ri_devcmap[((u_int)attr >> 16) & 15] & 0xffff; 202 stamp_attr = attr; 203 204 for (i = 0; i < 32; i += 2) { 205#if BYTE_ORDER == LITTLE_ENDIAN 206 stamp[i] = (i & 16 ? fg : bg); 207 stamp[i] |= ((i & 8 ? fg : bg) << 16); 208 stamp[i + 1] = (i & 4 ? fg : bg); 209 stamp[i + 1] |= ((i & 2 ? fg : bg) << 16); 210#else 211 stamp[i] = (i & 2 ? fg : bg); 212 stamp[i] |= ((i & 4 ? fg : bg) << 16); 213 stamp[i + 1] = (i & 8 ? fg : bg); 214 stamp[i + 1] |= ((i & 16 ? fg : bg) << 16); 215#endif 216 } 217} 218 219 220/* 221 * Paint a single character. This is for 8-pixel wide fonts. 222 */ 223static void 224rasops15_putchar8(cookie, row, col, uc, attr) 225 void *cookie; 226 int row, col; 227 u_int uc; 228 long attr; 229{ 230 struct rasops_info *ri; 231 int height, so, fs; 232 int32_t *rp; 233 u_char *fr; 234 235 /* Can't risk remaking the stamp if it's already in use */ 236 if (stamp_mutex++) { 237 stamp_mutex--; 238 rasops15_putchar(cookie, row, col, uc, attr); 239 return; 240 } 241 242 ri = (struct rasops_info *)cookie; 243 244#ifdef RASOPS_CLIPPING 245 if ((unsigned)row >= (unsigned)ri->ri_rows) { 246 stamp_mutex--; 247 return; 248 } 249 250 if ((unsigned)col >= (unsigned)ri->ri_cols) { 251 stamp_mutex--; 252 return; 253 } 254#endif 255 256 /* Recompute stamp? */ 257 if (attr != stamp_attr) 258 rasops15_makestamp(ri, attr); 259 260 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale); 261 height = ri->ri_font->fontheight; 262 263 if (uc == (u_int)-1) { 264 while (height--) { 265 rp[0] = stamp[0]; 266 rp[1] = stamp[0]; 267 rp[2] = stamp[0]; 268 rp[3] = stamp[0]; 269 DELTA(rp, ri->ri_stride, int32_t *); 270 } 271 } else { 272 uc -= ri->ri_font->firstchar; 273 fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale; 274 fs = ri->ri_font->stride; 275 276 while (height--) { 277 so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK; 278 rp[0] = STAMP_READ(so); 279 rp[1] = STAMP_READ(so + 4); 280 281 so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK; 282 rp[2] = STAMP_READ(so); 283 rp[3] = STAMP_READ(so + 4); 284 285 fr += fs; 286 DELTA(rp, ri->ri_stride, int32_t *); 287 } 288 } 289 290 /* Do underline */ 291 if (attr & 1) { 292 DELTA(rp, -(ri->ri_stride << 1), int32_t *); 293 rp[0] = STAMP_READ(30); 294 rp[1] = STAMP_READ(30); 295 rp[2] = STAMP_READ(30); 296 rp[3] = STAMP_READ(30); 297 } 298 299 stamp_mutex--; 300} 301 302 303/* 304 * Paint a single character. This is for 12-pixel wide fonts. 305 */ 306static void 307rasops15_putchar12(cookie, row, col, uc, attr) 308 void *cookie; 309 int row, col; 310 u_int uc; 311 long attr; 312{ 313 struct rasops_info *ri; 314 int height, so, fs; 315 int32_t *rp; 316 u_char *fr; 317 318 /* Can't risk remaking the stamp if it's already in use */ 319 if (stamp_mutex++) { 320 stamp_mutex--; 321 rasops15_putchar(cookie, row, col, uc, attr); 322 return; 323 } 324 325 ri = (struct rasops_info *)cookie; 326 327#ifdef RASOPS_CLIPPING 328 if ((unsigned)row >= (unsigned)ri->ri_rows) { 329 stamp_mutex--; 330 return; 331 } 332 333 if ((unsigned)col >= (unsigned)ri->ri_cols) { 334 stamp_mutex--; 335 return; 336 } 337#endif 338 339 /* Recompute stamp? */ 340 if (attr != stamp_attr) 341 rasops15_makestamp(ri, attr); 342 343 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale); 344 height = ri->ri_font->fontheight; 345 346 if (uc == (u_int)-1) { 347 while (height--) { 348 rp[0] = stamp[0]; 349 rp[1] = stamp[0]; 350 rp[2] = stamp[0]; 351 rp[3] = stamp[0]; 352 rp[4] = stamp[0]; 353 rp[5] = stamp[0]; 354 DELTA(rp, ri->ri_stride, int32_t *); 355 } 356 } else { 357 uc -= ri->ri_font->firstchar; 358 fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale; 359 fs = ri->ri_font->stride; 360 361 while (height--) { 362 so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK; 363 rp[0] = STAMP_READ(so); 364 rp[1] = STAMP_READ(so + 4); 365 366 so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK; 367 rp[2] = STAMP_READ(so); 368 rp[3] = STAMP_READ(so + 4); 369 370 so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK; 371 rp[4] = STAMP_READ(so); 372 rp[5] = STAMP_READ(so + 4); 373 374 fr += fs; 375 DELTA(rp, ri->ri_stride, int32_t *); 376 } 377 } 378 379 /* Do underline */ 380 if (attr & 1) { 381 DELTA(rp, -(ri->ri_stride << 1), int32_t *); 382 rp[0] = STAMP_READ(30); 383 rp[1] = STAMP_READ(30); 384 rp[2] = STAMP_READ(30); 385 rp[3] = STAMP_READ(30); 386 rp[4] = STAMP_READ(30); 387 rp[5] = STAMP_READ(30); 388 } 389 390 stamp_mutex--; 391} 392 393 394/* 395 * Paint a single character. This is for 16-pixel wide fonts. 396 */ 397static void 398rasops15_putchar16(cookie, row, col, uc, attr) 399 void *cookie; 400 int row, col; 401 u_int uc; 402 long attr; 403{ 404 struct rasops_info *ri; 405 int height, so, fs; 406 int32_t *rp; 407 u_char *fr; 408 409 /* Can't risk remaking the stamp if it's already in use */ 410 if (stamp_mutex++) { 411 stamp_mutex--; 412 rasops15_putchar(cookie, row, col, uc, attr); 413 return; 414 } 415 416 ri = (struct rasops_info *)cookie; 417 418#ifdef RASOPS_CLIPPING 419 if ((unsigned)row >= (unsigned)ri->ri_rows) { 420 stamp_mutex--; 421 return; 422 } 423 424 if ((unsigned)col >= (unsigned)ri->ri_cols) { 425 stamp_mutex--; 426 return; 427 } 428#endif 429 430 /* Recompute stamp? */ 431 if (attr != stamp_attr) 432 rasops15_makestamp(ri, attr); 433 434 rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale); 435 height = ri->ri_font->fontheight; 436 437 if (uc == (u_int)-1) { 438 while (height--) { 439 rp[0] = stamp[0]; 440 rp[1] = stamp[0]; 441 rp[2] = stamp[0]; 442 rp[3] = stamp[0]; 443 rp[4] = stamp[0]; 444 rp[5] = stamp[0]; 445 rp[6] = stamp[0]; 446 rp[7] = stamp[0]; 447 DELTA(rp, ri->ri_stride, int32_t *); 448 } 449 } else { 450 uc -= ri->ri_font->firstchar; 451 fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale; 452 fs = ri->ri_font->stride; 453 454 while (height--) { 455 so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK; 456 rp[0] = STAMP_READ(so); 457 rp[1] = STAMP_READ(so + 4); 458 459 so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK; 460 rp[2] = STAMP_READ(so); 461 rp[3] = STAMP_READ(so + 4); 462 463 so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK; 464 rp[4] = STAMP_READ(so); 465 rp[5] = STAMP_READ(so + 4); 466 467 so = STAMP_SHIFT(fr[1], 0) & STAMP_MASK; 468 rp[6] = STAMP_READ(so); 469 rp[7] = STAMP_READ(so + 4); 470 471 DELTA(rp, ri->ri_stride, int32_t *); 472 fr += fs; 473 } 474 } 475 476 /* Do underline */ 477 if (attr & 1) { 478 DELTA(rp, -(ri->ri_stride << 1), int32_t *); 479 rp[0] = STAMP_READ(30); 480 rp[1] = STAMP_READ(30); 481 rp[2] = STAMP_READ(30); 482 rp[3] = STAMP_READ(30); 483 rp[4] = STAMP_READ(30); 484 rp[5] = STAMP_READ(30); 485 rp[6] = STAMP_READ(30); 486 rp[7] = STAMP_READ(30); 487 } 488 489 stamp_mutex--; 490} 491