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