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