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