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