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