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