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