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