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