1 /* $OpenBSD: wsfont.c,v 1.40 2015/03/14 03:38:50 jsg Exp $ */ 2 /* $NetBSD: wsfont.c,v 1.17 2001/02/07 13:59:24 ad 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/types.h> 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/time.h> 37 #include <sys/malloc.h> 38 #include <sys/queue.h> 39 40 #include <dev/wscons/wsconsio.h> 41 #include <dev/wsfont/wsfont.h> 42 43 #include "wsfont_glue.h" /* NRASOPS_ROTATION */ 44 45 #undef HAVE_FONT 46 47 #ifdef FONT_QVSS8x15 48 #define HAVE_FONT 1 49 #include <dev/wsfont/qvss8x15.h> 50 #endif 51 52 #ifdef FONT_LUCIDA16x29 53 #define HAVE_FONT 1 54 #include <dev/wsfont/lucida16x29.h> 55 #endif 56 57 #ifdef FONT_VT220L8x8 58 #define HAVE_FONT 1 59 #include <dev/wsfont/vt220l8x8.h> 60 #endif 61 62 #ifdef FONT_VT220L8x10 63 #define HAVE_FONT 1 64 #include <dev/wsfont/vt220l8x10.h> 65 #endif 66 67 #ifdef FONT_SONY8x16 68 #define HAVE_FONT 1 69 #include <dev/wsfont/sony8x16.h> 70 #endif 71 72 #ifdef FONT_SONY12x24 73 #define HAVE_FONT 1 74 #include <dev/wsfont/sony12x24.h> 75 #endif 76 77 #ifdef FONT_OMRON12x20 78 #define HAVE_FONT 1 79 #include <dev/wsfont/omron12x20.h> 80 #endif 81 82 #ifdef FONT_BOLD8x16 83 #define HAVE_FONT 1 84 #include <dev/wsfont/bold8x16.h> 85 #endif 86 87 #ifdef FONT_GALLANT12x22 88 #define HAVE_FONT 1 89 #endif 90 91 #ifdef FONT_BOLD8x16_ISO1 92 #define HAVE_FONT 1 93 #endif 94 95 /* 96 * Make sure we always have at least one font. 97 * Some platforms (currently luna88k, sgi, sparc and sparc64) always provide 98 * a 8x16 font and a larger 12x22 font. 99 * Other platforms also provide both, but the 12x22 font is omitted if 100 * option SMALL_KERNEL. 101 */ 102 #ifndef HAVE_FONT 103 #define HAVE_FONT 1 104 105 #define FONT_BOLD8x16_ISO1 106 #if defined(__luna88k__) || defined(__sgi__) || defined(__sparc__) || \ 107 defined(__sparc64__) || !defined(SMALL_KERNEL) 108 #define FONT_GALLANT12x22 109 #endif 110 111 #endif /* HAVE_FONT */ 112 113 #ifdef FONT_BOLD8x16_ISO1 114 #include <dev/wsfont/bold8x16-iso1.h> 115 #endif 116 117 #ifdef FONT_GALLANT12x22 118 #include <dev/wsfont/gallant12x22.h> 119 #endif 120 121 struct font { 122 TAILQ_ENTRY(font) chain; 123 struct wsdisplay_font *font; 124 u_short lockcount; 125 u_short cookie; 126 u_short flg; 127 }; 128 TAILQ_HEAD(, font) fontlist; 129 130 /* Our list of built-in fonts */ 131 static struct font builtin_fonts[] = { 132 #define BUILTIN_FONT(f, c) \ 133 { .font = &(f), .cookie = (c), .lockcount = 0, \ 134 .flg = WSFONT_STATIC | WSFONT_BUILTIN } 135 #ifdef FONT_BOLD8x16 136 BUILTIN_FONT(bold8x16, 1), 137 #endif 138 #ifdef FONT_BOLD8x16_ISO1 139 BUILTIN_FONT(bold8x16_iso1, 2), 140 #endif 141 #ifdef FONT_COURIER11x18 142 BUILTIN_FONT(courier11x18, 3), 143 #endif 144 #ifdef FONT_GALLANT12x22 145 BUILTIN_FONT(gallant12x22, 4), 146 #endif 147 #ifdef FONT_LUCIDA16x29 148 BUILTIN_FONT(lucida16x29, 5), 149 #endif 150 #ifdef FONT_QVSS8x15 151 BUILTIN_FONT(qvss8x15, 6), 152 #endif 153 #ifdef FONT_VT220L8x8 154 BUILTIN_FONT(vt220l8x8, 7), 155 #endif 156 #ifdef FONT_VT220L8x10 157 BUILTIN_FONT(vt220l8x10, 8), 158 #endif 159 #ifdef FONT_SONY8x16 160 BUILTIN_FONT(sony8x16, 9), 161 #endif 162 #ifdef FONT_SONY12x24 163 BUILTIN_FONT(sony12x24, 10), 164 #endif 165 #ifdef FONT_OMRON12x20 166 BUILTIN_FONT(omron12x20, 11), 167 #endif 168 #undef BUILTIN_FONT 169 }; 170 171 #if !defined(SMALL_KERNEL) || defined(__alpha__) 172 173 /* Reverse the bit order in a byte */ 174 static const u_char reverse[256] = { 175 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 176 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 177 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 178 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 179 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 180 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 181 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 182 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 183 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 184 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 185 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 186 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 187 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 188 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 189 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 190 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 191 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 192 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 193 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 194 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 195 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 196 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 197 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 198 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 199 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 200 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 201 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 202 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 203 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 204 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 205 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 206 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, 207 }; 208 209 #endif 210 211 static struct font *wsfont_find0(int); 212 213 #if !defined(SMALL_KERNEL) || defined(__alpha__) 214 215 /* 216 * Reverse the bit order of a font 217 */ 218 static void wsfont_revbit(struct wsdisplay_font *); 219 static void 220 wsfont_revbit(struct wsdisplay_font *font) 221 { 222 u_char *p, *m; 223 224 p = (u_char *)font->data; 225 m = p + font->stride * font->numchars * font->fontheight; 226 227 for (; p < m; p++) 228 *p = reverse[*p]; 229 } 230 231 #endif 232 233 #if !defined(SMALL_KERNEL) 234 235 /* 236 * Reverse the byte order of a font 237 */ 238 static void wsfont_revbyte(struct wsdisplay_font *); 239 static void 240 wsfont_revbyte(struct wsdisplay_font *font) 241 { 242 int x, l, r, nr; 243 u_char *rp; 244 245 if (font->stride == 1) 246 return; 247 248 rp = (u_char *)font->data; 249 nr = font->numchars * font->fontheight; 250 251 while (nr--) { 252 l = 0; 253 r = font->stride - 1; 254 255 while (l < r) { 256 x = rp[l]; 257 rp[l] = rp[r]; 258 rp[r] = x; 259 l++, r--; 260 } 261 262 rp += font->stride; 263 } 264 } 265 266 #endif 267 268 /* 269 * Enumerate the list of fonts 270 */ 271 void 272 wsfont_enum(int (*cb)(void *, struct wsdisplay_font *), void *cbarg) 273 { 274 struct font *ent; 275 int s; 276 277 s = splhigh(); 278 279 TAILQ_FOREACH(ent, &fontlist, chain) 280 if (cb(cbarg, ent->font) != 0) 281 break; 282 283 splx(s); 284 } 285 286 #if NRASOPS_ROTATION > 0 287 288 struct wsdisplay_font *wsfont_rotate_internal(struct wsdisplay_font *); 289 290 struct wsdisplay_font * 291 wsfont_rotate_internal(struct wsdisplay_font *font) 292 { 293 int b, n, r, newstride; 294 struct wsdisplay_font *newfont; 295 char *newbits; 296 297 /* Duplicate the existing font... */ 298 newfont = malloc(sizeof *font, M_DEVBUF, M_WAITOK); 299 300 bcopy(font, newfont, sizeof *font); 301 newfont->cookie = NULL; 302 303 /* Allocate a buffer big enough for the rotated font. */ 304 newstride = (font->fontheight + 7) / 8; 305 newbits = mallocarray(font->numchars, newstride * font->fontwidth, 306 M_DEVBUF, M_WAITOK | M_ZERO); 307 308 /* Rotate the font a bit at a time. */ 309 for (n = 0; n < font->numchars; n++) { 310 char *ch = font->data + (n * font->stride * font->fontheight); 311 312 for (r = 0; r < font->fontheight; r++) { 313 for (b = 0; b < font->fontwidth; b++) { 314 unsigned char *rb; 315 316 rb = ch + (font->stride * r) + (b / 8); 317 if (*rb & (0x80 >> (b % 8))) { 318 unsigned char *rrb; 319 320 rrb = newbits + newstride - 1 - (r / 8) 321 + (n * newstride * font->fontwidth) 322 + (newstride * b); 323 *rrb |= (1 << (r % 8)); 324 } 325 } 326 } 327 } 328 329 newfont->data = newbits; 330 331 /* Update font sizes. */ 332 newfont->stride = newstride; 333 newfont->fontwidth = font->fontheight; 334 newfont->fontheight = font->fontwidth; 335 336 if (wsfont_add(newfont, 0) != 0) { 337 /* 338 * If we seem to have rotated this font already, drop the 339 * new one... 340 */ 341 free(newbits, M_DEVBUF, 0); 342 free(newfont, M_DEVBUF, 0); 343 newfont = NULL; 344 } 345 346 return (newfont); 347 } 348 349 int 350 wsfont_rotate(int cookie) 351 { 352 int s, ncookie; 353 struct wsdisplay_font *font; 354 struct font *origfont; 355 356 s = splhigh(); 357 origfont = wsfont_find0(cookie); 358 splx(s); 359 360 font = wsfont_rotate_internal(origfont->font); 361 if (font == NULL) 362 return (-1); 363 364 ncookie = wsfont_find(font->name, font->fontwidth, font->fontheight, 365 font->stride); 366 367 return (ncookie); 368 } 369 370 #endif /* NRASOPS_ROTATION */ 371 372 /* 373 * Initialize list with WSFONT_BUILTIN fonts 374 */ 375 void 376 wsfont_init(void) 377 { 378 static int again; 379 unsigned int i; 380 381 if (again != 0) 382 return; 383 again = 1; 384 385 TAILQ_INIT(&fontlist); 386 387 for (i = 0; i < nitems(builtin_fonts); i++) { 388 TAILQ_INSERT_TAIL(&fontlist, &builtin_fonts[i], chain); 389 } 390 } 391 392 /* 393 * Find a font by cookie. Called at splhigh. 394 */ 395 static struct font * 396 wsfont_find0(int cookie) 397 { 398 struct font *ent; 399 400 TAILQ_FOREACH(ent, &fontlist, chain) 401 if (ent->cookie == cookie) 402 return (ent); 403 404 return (NULL); 405 } 406 407 /* 408 * Find a font. 409 */ 410 int 411 wsfont_find(const char *name, int width, int height, int stride) 412 { 413 struct font *ent; 414 int s; 415 416 s = splhigh(); 417 418 TAILQ_FOREACH(ent, &fontlist, chain) { 419 if (height != 0 && ent->font->fontheight != height) 420 continue; 421 422 if (width != 0 && ent->font->fontwidth != width) 423 continue; 424 425 if (stride != 0 && ent->font->stride != stride) 426 continue; 427 428 if (name != NULL && strcmp(ent->font->name, name) != 0) 429 continue; 430 431 splx(s); 432 return (ent->cookie); 433 } 434 435 splx(s); 436 return (-1); 437 } 438 439 /* 440 * Add a font to the list. 441 */ 442 int 443 wsfont_add(struct wsdisplay_font *font, int copy) 444 { 445 static int cookiegen = 666; 446 struct font *ent; 447 int s; 448 449 s = splhigh(); 450 451 /* Don't allow exact duplicates */ 452 if (wsfont_find(font->name, font->fontwidth, font->fontheight, 453 font->stride) >= 0) { 454 splx(s); 455 return (-1); 456 } 457 458 ent = (struct font *)malloc(sizeof *ent, M_DEVBUF, M_WAITOK); 459 460 ent->lockcount = 0; 461 ent->flg = 0; 462 ent->cookie = cookiegen++; 463 464 /* 465 * If we are coming from a WSDISPLAYIO_LDFONT ioctl, we need to 466 * make a copy of the wsdisplay_font struct, but not of font->bits. 467 */ 468 if (copy) { 469 ent->font = (struct wsdisplay_font *)malloc(sizeof *ent->font, 470 M_DEVBUF, M_WAITOK); 471 memcpy(ent->font, font, sizeof(*ent->font)); 472 ent->flg = 0; 473 } else { 474 ent->font = font; 475 ent->flg = WSFONT_STATIC; 476 } 477 478 /* Now link into the list and return */ 479 TAILQ_INSERT_TAIL(&fontlist, ent, chain); 480 splx(s); 481 return (0); 482 } 483 484 /* 485 * Remove a font. 486 */ 487 #ifdef notyet 488 int 489 wsfont_remove(int cookie) 490 { 491 struct font *ent; 492 int s; 493 494 s = splhigh(); 495 496 if ((ent = wsfont_find0(cookie)) == NULL) { 497 splx(s); 498 return (-1); 499 } 500 501 if ((ent->flg & WSFONT_BUILTIN) != 0 || ent->lockcount != 0) { 502 splx(s); 503 return (-1); 504 } 505 506 /* Don't free statically allocated font data */ 507 if ((ent->flg & WSFONT_STATIC) != 0) { 508 free(ent->font->data, M_DEVBUF, 0); 509 free(ent->font, M_DEVBUF, 0); 510 } 511 512 /* Remove from list, free entry */ 513 TAILQ_REMOVE(&list, ent, chain); 514 free(ent, M_DEVBUF, 0); 515 splx(s); 516 return (0); 517 } 518 #endif 519 520 /* 521 * Lock a given font and return new lockcount. This fails if the cookie 522 * is invalid, or if the font is already locked and the bit/byte order 523 * requested by the caller differs. 524 */ 525 int 526 wsfont_lock(int cookie, struct wsdisplay_font **ptr, int bitorder, 527 int byteorder) 528 { 529 struct font *ent; 530 int s, lc; 531 532 s = splhigh(); 533 534 if ((ent = wsfont_find0(cookie)) != NULL) { 535 if (bitorder && bitorder != ent->font->bitorder) { 536 #if !defined(SMALL_KERNEL) || defined(__alpha__) 537 if (ent->lockcount) { 538 splx(s); 539 return (-1); 540 } 541 wsfont_revbit(ent->font); 542 ent->font->bitorder = bitorder; 543 #else 544 splx(s); 545 return (-1); 546 #endif 547 } 548 549 if (byteorder && byteorder != ent->font->byteorder) { 550 #if !defined(SMALL_KERNEL) 551 if (ent->lockcount) { 552 splx(s); 553 return (-1); 554 } 555 wsfont_revbyte(ent->font); 556 ent->font->byteorder = byteorder; 557 #else 558 splx(s); 559 return (-1); 560 #endif 561 } 562 563 lc = ++ent->lockcount; 564 *ptr = ent->font; 565 } else 566 lc = -1; 567 568 splx(s); 569 return (lc); 570 } 571 572 /* 573 * Unlock a given font and return new lockcount. 574 */ 575 int 576 wsfont_unlock(int cookie) 577 { 578 struct font *ent; 579 int s, lc; 580 581 s = splhigh(); 582 583 if ((ent = wsfont_find0(cookie)) != NULL) { 584 if (ent->lockcount == 0) 585 panic("wsfont_unlock: font not locked"); 586 lc = --ent->lockcount; 587 } else 588 lc = -1; 589 590 splx(s); 591 return (lc); 592 } 593 594 #if !defined(SMALL_KERNEL) 595 596 /* 597 * Unicode to font encoding mappings 598 */ 599 600 /* 601 * To save memory, font encoding tables use a two level lookup. 602 * First the high byte of the Unicode is used to lookup the level 2 603 * table, then the low byte indexes that table. Level 2 tables that are 604 * not needed are omitted (NULL), and both level 1 and level 2 tables 605 * have base and size attributes to keep their size down. 606 */ 607 608 struct wsfont_level1_glyphmap { 609 struct wsfont_level2_glyphmap **level2; 610 int base; /* High byte for first level2 entry */ 611 int size; /* Number of level2 entries */ 612 }; 613 614 struct wsfont_level2_glyphmap { 615 int base; /* Low byte for first character */ 616 int size; /* Number of characters */ 617 void *chars; /* Pointer to character number entries */ 618 int width; /* Size of each entry in bytes (1,2,4) */ 619 }; 620 621 /* 622 * IBM 437 maps 623 */ 624 625 static u_int8_t 626 ibm437_chars_0[] = { 627 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 628 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 629 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 630 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 631 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 632 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 633 96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111, 634 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, 635 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 636 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 637 255,173,155,156, 0, 157, 0, 0, 0, 0, 166,174,170, 0, 0, 0, 638 0, 241,253, 0, 0, 0, 0, 249, 0, 0, 167,175,172,171, 0, 168, 639 0, 0, 0, 0, 142,143,146,128, 0, 144, 0, 0, 0, 0, 0, 0, 640 0, 165, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 154, 0, 0, 0, 641 133,160,131, 0, 132,134,145,135,138,130,136,137,141,161,140,139, 642 0, 164,149,162,147, 0, 148,246, 0, 151,163,150,129, 0, 0, 152 643 }, 644 ibm437_chars_1[] = { 645 159 646 }, 647 ibm437_chars_3[] = { 648 226, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 649 228, 0, 0, 232, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 224,225, 650 0, 235,238, 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0, 651 229,231 652 }, 653 ibm437_chars_32[] = { 654 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 655 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 656 0, 0, 0, 0, 0, 0, 0, 0, 158 657 }, 658 ibm437_chars_34[] = { 659 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 660 0, 0, 0, 248,250,251, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 661 0, 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 662 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 663 0, 0, 0, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 664 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 0, 0,243, 665 242 666 }, 667 ibm437_chars_35[] = { 668 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 669 244,245 670 }, 671 ibm437_chars_37[] = { 672 196,205,179,186, 0, 0, 0, 0, 0, 0, 0, 0, 218,213,214,201, 673 191,184,183,187,192,212,211,200,217,190,189,188,195,198, 0, 0, 674 199, 0, 0, 204,180,181, 0, 0, 182, 0, 0, 185,194, 0, 0, 209, 675 210, 0, 0, 203,193, 0, 0, 207,208, 0, 0, 202,197, 0, 0, 216, 676 0, 0, 215, 0, 0, 0, 0, 0, 0, 0, 0, 206, 0, 0, 0, 0, 677 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 678 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 679 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 680 223, 0, 0, 0, 220, 0, 0, 0, 219, 0, 0, 0, 221, 0, 0, 0, 681 222,176,177,178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 682 254 683 }; 684 685 static struct wsfont_level2_glyphmap 686 ibm437_level2_0 = { 0, 256, ibm437_chars_0, 1 }, 687 ibm437_level2_1 = { 146, 1, ibm437_chars_1, 1 }, 688 ibm437_level2_3 = { 147, 50, ibm437_chars_3, 1 }, 689 ibm437_level2_32 = { 127, 41, ibm437_chars_32, 1 }, 690 ibm437_level2_34 = { 5, 97, ibm437_chars_34, 1 }, 691 ibm437_level2_35 = { 16, 18, ibm437_chars_35, 1 }, 692 ibm437_level2_37 = { 0, 161, ibm437_chars_37, 1 }; 693 694 static struct wsfont_level2_glyphmap *ibm437_level1[] = { 695 &ibm437_level2_0, &ibm437_level2_1, NULL, &ibm437_level2_3, 696 NULL, NULL, NULL, NULL, 697 NULL, NULL, NULL, NULL, 698 NULL, NULL, NULL, NULL, 699 NULL, NULL, NULL, NULL, 700 NULL, NULL, NULL, NULL, 701 NULL, NULL, NULL, NULL, 702 NULL, NULL, NULL, NULL, 703 &ibm437_level2_32, NULL, &ibm437_level2_34, &ibm437_level2_35, 704 NULL, &ibm437_level2_37 705 }; 706 707 static struct wsfont_level1_glyphmap encodings[] = { 708 /* WSDISPLAY_FONTENC_ISO */ 709 { NULL, 0, 0 }, 710 /* WSDISPLAY_FONTENC_IBM */ 711 { ibm437_level1, 0, nitems(ibm437_level1) } 712 }; 713 714 #endif /* !SMALL_KERNEL */ 715 716 /* 717 * Remap Unicode character to glyph 718 */ 719 int 720 wsfont_map_unichar(struct wsdisplay_font *font, int c) 721 { 722 if (font->encoding == WSDISPLAY_FONTENC_ISO) 723 return (c); 724 725 #if !defined(SMALL_KERNEL) 726 if (font->encoding >= 0 && font->encoding < nitems(encodings)) { 727 int hi = (c >> 8), lo = c & 255; 728 struct wsfont_level1_glyphmap *map1 = 729 &encodings[font->encoding]; 730 struct wsfont_level2_glyphmap *map2; 731 732 hi -= map1->base; 733 734 if (hi >= 0 && hi < map1->size && 735 (map2 = map1->level2[hi]) != NULL) { 736 lo -= map2->base; 737 738 if (lo >= 0 && lo < map2->size) { 739 switch (map2->width) { 740 case 1: 741 c = (((u_int8_t *)map2->chars)[lo]); 742 break; 743 case 2: 744 c = (((u_int16_t *)map2->chars)[lo]); 745 break; 746 case 4: 747 c = (((u_int32_t *)map2->chars)[lo]); 748 break; 749 } 750 751 if (c != 0 || lo == 0) 752 return (c); 753 } 754 } 755 } 756 #endif /* !SMALL_KERNEL */ 757 758 return (-1); 759 } 760