1 /* $OpenBSD: wsfont.c,v 1.42 2015/09/13 16:44:30 miod 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(__sparc__) || 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; 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 ent = (struct font *)malloc(sizeof *ent, M_DEVBUF, M_WAITOK); 465 466 ent->lockcount = 0; 467 ent->flg = 0; 468 ent->cookie = cookiegen++; 469 470 /* 471 * If we are coming from a WSDISPLAYIO_LDFONT ioctl, we need to 472 * make a copy of the wsdisplay_font struct, but not of font->bits. 473 */ 474 if (copy) { 475 ent->font = (struct wsdisplay_font *)malloc(sizeof *ent->font, 476 M_DEVBUF, M_WAITOK); 477 memcpy(ent->font, font, sizeof(*ent->font)); 478 ent->flg = 0; 479 } else { 480 ent->font = font; 481 ent->flg = WSFONT_STATIC; 482 } 483 484 /* Now link into the list and return */ 485 TAILQ_INSERT_TAIL(&fontlist, ent, chain); 486 splx(s); 487 return (0); 488 } 489 490 /* 491 * Remove a font. 492 */ 493 #ifdef notyet 494 int 495 wsfont_remove(int cookie) 496 { 497 struct font *ent; 498 int s; 499 500 s = splhigh(); 501 502 if ((ent = wsfont_find0(cookie)) == NULL) { 503 splx(s); 504 return (-1); 505 } 506 507 if ((ent->flg & WSFONT_BUILTIN) != 0 || ent->lockcount != 0) { 508 splx(s); 509 return (-1); 510 } 511 512 /* Don't free statically allocated font data */ 513 if ((ent->flg & WSFONT_STATIC) != 0) { 514 free(ent->font->data, M_DEVBUF, 0); 515 free(ent->font, M_DEVBUF, 0); 516 } 517 518 /* Remove from list, free entry */ 519 TAILQ_REMOVE(&list, ent, chain); 520 free(ent, M_DEVBUF, 0); 521 splx(s); 522 return (0); 523 } 524 #endif 525 526 /* 527 * Lock a given font and return new lockcount. This fails if the cookie 528 * is invalid, or if the font is already locked and the bit/byte order 529 * requested by the caller differs. 530 */ 531 int 532 wsfont_lock(int cookie, struct wsdisplay_font **ptr, int bitorder, 533 int byteorder) 534 { 535 struct font *ent; 536 int s, lc; 537 538 s = splhigh(); 539 540 if ((ent = wsfont_find0(cookie)) != NULL) { 541 if (bitorder && bitorder != ent->font->bitorder) { 542 #ifdef INCLUDE_FONT_BIT_ENDIANNESS_SWAP_CODE 543 if (ent->lockcount) { 544 splx(s); 545 return (-1); 546 } 547 wsfont_revbit(ent->font); 548 ent->font->bitorder = bitorder; 549 #else 550 splx(s); 551 return (-1); 552 #endif 553 } 554 555 if (byteorder && byteorder != ent->font->byteorder) { 556 #if !defined(SMALL_KERNEL) 557 if (ent->lockcount) { 558 splx(s); 559 return (-1); 560 } 561 wsfont_revbyte(ent->font); 562 ent->font->byteorder = byteorder; 563 #else 564 splx(s); 565 return (-1); 566 #endif 567 } 568 569 lc = ++ent->lockcount; 570 *ptr = ent->font; 571 } else 572 lc = -1; 573 574 splx(s); 575 return (lc); 576 } 577 578 /* 579 * Unlock a given font and return new lockcount. 580 */ 581 int 582 wsfont_unlock(int cookie) 583 { 584 struct font *ent; 585 int s, lc; 586 587 s = splhigh(); 588 589 if ((ent = wsfont_find0(cookie)) != NULL) { 590 if (ent->lockcount == 0) 591 panic("wsfont_unlock: font not locked"); 592 lc = --ent->lockcount; 593 } else 594 lc = -1; 595 596 splx(s); 597 return (lc); 598 } 599 600 #if !defined(SMALL_KERNEL) 601 602 /* 603 * Unicode to font encoding mappings 604 */ 605 606 /* 607 * To save memory, font encoding tables use a two level lookup. 608 * First the high byte of the Unicode is used to lookup the level 2 609 * table, then the low byte indexes that table. Level 2 tables that are 610 * not needed are omitted (NULL), and both level 1 and level 2 tables 611 * have base and size attributes to keep their size down. 612 */ 613 614 struct wsfont_level1_glyphmap { 615 struct wsfont_level2_glyphmap **level2; 616 int base; /* High byte for first level2 entry */ 617 int size; /* Number of level2 entries */ 618 }; 619 620 struct wsfont_level2_glyphmap { 621 int base; /* Low byte for first character */ 622 int size; /* Number of characters */ 623 void *chars; /* Pointer to character number entries */ 624 int width; /* Size of each entry in bytes (1,2,4) */ 625 }; 626 627 /* 628 * IBM 437 maps 629 */ 630 631 static u_int8_t 632 ibm437_chars_0[] = { 633 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 634 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 635 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 636 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 637 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 638 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 639 96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111, 640 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, 641 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 642 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 643 255,173,155,156, 0, 157, 0, 0, 0, 0, 166,174,170, 0, 0, 0, 644 0, 241,253, 0, 0, 0, 0, 249, 0, 0, 167,175,172,171, 0, 168, 645 0, 0, 0, 0, 142,143,146,128, 0, 144, 0, 0, 0, 0, 0, 0, 646 0, 165, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 154, 0, 0, 0, 647 133,160,131, 0, 132,134,145,135,138,130,136,137,141,161,140,139, 648 0, 164,149,162,147, 0, 148,246, 0, 151,163,150,129, 0, 0, 152 649 }, 650 ibm437_chars_1[] = { 651 159 652 }, 653 ibm437_chars_3[] = { 654 226, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 655 228, 0, 0, 232, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 224,225, 656 0, 235,238, 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0, 657 229,231 658 }, 659 ibm437_chars_32[] = { 660 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 661 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 662 0, 0, 0, 0, 0, 0, 0, 0, 158 663 }, 664 ibm437_chars_34[] = { 665 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 666 0, 0, 0, 248,250,251, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 667 0, 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 668 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 669 0, 0, 0, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 670 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 0, 0,243, 671 242 672 }, 673 ibm437_chars_35[] = { 674 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 675 244,245 676 }, 677 ibm437_chars_37[] = { 678 196,205,179,186, 0, 0, 0, 0, 0, 0, 0, 0, 218,213,214,201, 679 191,184,183,187,192,212,211,200,217,190,189,188,195,198, 0, 0, 680 199, 0, 0, 204,180,181, 0, 0, 182, 0, 0, 185,194, 0, 0, 209, 681 210, 0, 0, 203,193, 0, 0, 207,208, 0, 0, 202,197, 0, 0, 216, 682 0, 0, 215, 0, 0, 0, 0, 0, 0, 0, 0, 206, 0, 0, 0, 0, 683 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 684 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 685 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 686 223, 0, 0, 0, 220, 0, 0, 0, 219, 0, 0, 0, 221, 0, 0, 0, 687 222,176,177,178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 688 254 689 }; 690 691 static struct wsfont_level2_glyphmap 692 ibm437_level2_0 = { 0, 256, ibm437_chars_0, 1 }, 693 ibm437_level2_1 = { 146, 1, ibm437_chars_1, 1 }, 694 ibm437_level2_3 = { 147, 50, ibm437_chars_3, 1 }, 695 ibm437_level2_32 = { 127, 41, ibm437_chars_32, 1 }, 696 ibm437_level2_34 = { 5, 97, ibm437_chars_34, 1 }, 697 ibm437_level2_35 = { 16, 18, ibm437_chars_35, 1 }, 698 ibm437_level2_37 = { 0, 161, ibm437_chars_37, 1 }; 699 700 static struct wsfont_level2_glyphmap *ibm437_level1[] = { 701 &ibm437_level2_0, &ibm437_level2_1, NULL, &ibm437_level2_3, 702 NULL, NULL, NULL, NULL, 703 NULL, NULL, NULL, NULL, 704 NULL, NULL, NULL, NULL, 705 NULL, NULL, NULL, NULL, 706 NULL, NULL, NULL, NULL, 707 NULL, NULL, NULL, NULL, 708 NULL, NULL, NULL, NULL, 709 &ibm437_level2_32, NULL, &ibm437_level2_34, &ibm437_level2_35, 710 NULL, &ibm437_level2_37 711 }; 712 713 static struct wsfont_level1_glyphmap encodings[] = { 714 /* WSDISPLAY_FONTENC_ISO */ 715 { NULL, 0, 0 }, 716 /* WSDISPLAY_FONTENC_IBM */ 717 { ibm437_level1, 0, nitems(ibm437_level1) } 718 }; 719 720 #endif /* !SMALL_KERNEL */ 721 722 /* 723 * Remap Unicode character to glyph 724 */ 725 int 726 wsfont_map_unichar(struct wsdisplay_font *font, int c) 727 { 728 if (font->encoding == WSDISPLAY_FONTENC_ISO) 729 return (c); 730 731 #if !defined(SMALL_KERNEL) 732 if (font->encoding >= 0 && font->encoding < nitems(encodings)) { 733 int hi = (c >> 8), lo = c & 255; 734 struct wsfont_level1_glyphmap *map1 = 735 &encodings[font->encoding]; 736 struct wsfont_level2_glyphmap *map2; 737 738 hi -= map1->base; 739 740 if (hi >= 0 && hi < map1->size && 741 (map2 = map1->level2[hi]) != NULL) { 742 lo -= map2->base; 743 744 if (lo >= 0 && lo < map2->size) { 745 switch (map2->width) { 746 case 1: 747 c = (((u_int8_t *)map2->chars)[lo]); 748 break; 749 case 2: 750 c = (((u_int16_t *)map2->chars)[lo]); 751 break; 752 case 4: 753 c = (((u_int32_t *)map2->chars)[lo]); 754 break; 755 } 756 757 if (c != 0 || lo == 0) 758 return (c); 759 } 760 } 761 } 762 #endif /* !SMALL_KERNEL */ 763 764 return (-1); 765 } 766