wsfont.c revision 1.25
1/* $OpenBSD: wsfont.c,v 1.25 2010/05/23 15:04:19 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 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 */ 120struct 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 */ 130static 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 */ 170static 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 207static struct font *wsfont_find0(int); 208 209#if !defined(SMALL_KERNEL) || defined(__alpha__) 210 211/* 212 * Reverse the bit order of a font 213 */ 214static void wsfont_revbit(struct wsdisplay_font *); 215static void 216wsfont_revbit(font) 217 struct wsdisplay_font *font; 218{ 219 u_char *p, *m; 220 221 p = (u_char *)font->data; 222 m = p + font->stride * font->numchars * font->fontheight; 223 224 for (; p < m; p++) 225 *p = reverse[*p]; 226} 227 228#endif 229 230#if !defined(SMALL_KERNEL) 231 232/* 233 * Reverse the byte order of a font 234 */ 235static void wsfont_revbyte(struct wsdisplay_font *); 236static void 237wsfont_revbyte(font) 238 struct wsdisplay_font *font; 239{ 240 int x, l, r, nr; 241 u_char *rp; 242 243 if (font->stride == 1) 244 return; 245 246 rp = (u_char *)font->data; 247 nr = font->numchars * font->fontheight; 248 249 while (nr--) { 250 l = 0; 251 r = font->stride - 1; 252 253 while (l < r) { 254 x = rp[l]; 255 rp[l] = rp[r]; 256 rp[r] = x; 257 l++, r--; 258 } 259 260 rp += font->stride; 261 } 262} 263 264#endif 265 266/* 267 * Enumerate the list of fonts 268 */ 269void 270wsfont_enum(cb) 271 void (*cb)(char *, int, int, int); 272{ 273 struct wsdisplay_font *f; 274 struct font *ent; 275 int s; 276 277 s = splhigh(); 278 279 for (ent = list; ent; ent = ent->next) { 280 f = ent->font; 281 cb(f->name, f->fontwidth, f->fontheight, f->stride); 282 } 283 284 splx(s); 285} 286 287#if NRASOPS_ROTATION > 0 288 289struct wsdisplay_font *wsfont_rotate_internal(struct wsdisplay_font *); 290 291struct wsdisplay_font * 292wsfont_rotate_internal(struct wsdisplay_font *font) 293{ 294 int b, n, r, newstride; 295 struct wsdisplay_font *newfont; 296 char *newbits; 297 298 /* Duplicate the existing font... */ 299 newfont = malloc(sizeof *font, M_DEVBUF, M_WAITOK); 300 301 bcopy(font, newfont, sizeof *font); 302 newfont->cookie = NULL; 303 304 /* Allocate a buffer big enough for the rotated font. */ 305 newstride = (font->fontheight + 7) / 8; 306 newbits = malloc(newstride * font->fontwidth * font->numchars, 307 M_DEVBUF, M_WAITOK | M_ZERO); 308 309 /* Rotate the font a bit at a time. */ 310 for (n = 0; n < font->numchars; n++) { 311 char *ch = font->data + (n * font->stride * font->fontheight); 312 313 for (r = 0; r < font->fontheight; r++) { 314 for (b = 0; b < font->fontwidth; b++) { 315 unsigned char *rb; 316 317 rb = ch + (font->stride * r) + (b / 8); 318 if (*rb & (0x80 >> (b % 8))) { 319 unsigned char *rrb; 320 321 rrb = newbits + newstride - 1 - (r / 8) 322 + (n * newstride * font->fontwidth) 323 + (newstride * b); 324 *rrb |= (1 << (r % 8)); 325 } 326 } 327 } 328 } 329 330 newfont->data = newbits; 331 332 /* Update font sizes. */ 333 newfont->stride = newstride; 334 newfont->fontwidth = font->fontheight; 335 newfont->fontheight = font->fontwidth; 336 337 if (wsfont_add(newfont, 0) != 0) { 338 /* 339 * If we seem to have rotated this font already, drop the 340 * new one... 341 */ 342 free(newbits, M_DEVBUF); 343 free(newfont, M_DEVBUF); 344 newfont = NULL; 345 } 346 347 return (newfont); 348} 349 350int 351wsfont_rotate(int cookie) 352{ 353 int s, ncookie; 354 struct wsdisplay_font *font; 355 struct font *origfont; 356 357 s = splhigh(); 358 origfont = wsfont_find0(cookie); 359 splx(s); 360 361 font = wsfont_rotate_internal(origfont->font); 362 if (font == NULL) 363 return (-1); 364 365 ncookie = wsfont_find(font->name, font->fontwidth, font->fontheight, 366 font->stride); 367 368 return (ncookie); 369} 370 371#endif /* NRASOPS_ROTATION */ 372 373/* 374 * Initialize list with WSFONT_BUILTIN fonts 375 */ 376void 377wsfont_init(void) 378{ 379 static int again; 380 int i; 381 382 if (again != 0) 383 return; 384 again = 1; 385 386 for (i = 0; builtin_fonts[i].font != NULL; i++) { 387 builtin_fonts[i].next = list; 388 list = &builtin_fonts[i]; 389 } 390} 391 392/* 393 * Find a font by cookie. Called at splhigh. 394 */ 395static struct font * 396wsfont_find0(cookie) 397 int cookie; 398{ 399 struct font *ent; 400 401 for (ent = list; ent != NULL; ent = ent->next) 402 if (ent->cookie == cookie) 403 return (ent); 404 405 return (NULL); 406} 407 408/* 409 * Find a font. 410 */ 411int 412wsfont_find(name, width, height, stride) 413 char *name; 414 int width, height, stride; 415{ 416 struct font *ent; 417 int s; 418 419 s = splhigh(); 420 421 for (ent = list; ent != NULL; ent = ent->next) { 422 if (height != 0 && ent->font->fontheight != height) 423 continue; 424 425 if (width != 0 && ent->font->fontwidth != width) 426 continue; 427 428 if (stride != 0 && ent->font->stride != stride) 429 continue; 430 431 if (name != NULL && strcmp(ent->font->name, name) != 0) 432 continue; 433 434 splx(s); 435 return (ent->cookie); 436 } 437 438 splx(s); 439 return (-1); 440} 441 442/* 443 * Add a font to the list. 444 */ 445int 446wsfont_add(font, copy) 447 struct wsdisplay_font *font; 448 int copy; 449{ 450 static int cookiegen = 666; 451 struct font *ent; 452 size_t size; 453 int s; 454 455 s = splhigh(); 456 457 /* Don't allow exact duplicates */ 458 if (wsfont_find(font->name, font->fontwidth, font->fontheight, 459 font->stride) >= 0) { 460 splx(s); 461 return (-1); 462 } 463 464 ent = (struct font *)malloc(sizeof *ent, M_DEVBUF, M_WAITOK); 465 466 ent->lockcount = 0; 467 ent->flg = 0; 468 ent->cookie = cookiegen++; 469 ent->next = list; 470 ent->prev = NULL; 471 472 /* Is this font statically allocated? */ 473 if (!copy) { 474 ent->font = font; 475 ent->flg = WSFONT_STATIC; 476 } else { 477 ent->font = (struct wsdisplay_font *)malloc(sizeof *ent->font, 478 M_DEVBUF, M_WAITOK); 479 480 memcpy(ent->font, font, sizeof(*ent->font)); 481 482 size = font->fontheight * font->numchars * font->stride; 483 ent->font->data = (void *)malloc(size, M_DEVBUF, M_WAITOK); 484 memcpy(ent->font->data, font->data, size); 485 ent->flg = 0; 486 } 487 488 /* Now link into the list and return */ 489 list = ent; 490 splx(s); 491 return (0); 492} 493 494/* 495 * Remove a font. 496 */ 497#ifdef notyet 498int 499wsfont_remove(cookie) 500 int cookie; 501{ 502 struct font *ent; 503 int s; 504 505 s = splhigh(); 506 507 if ((ent = wsfont_find0(cookie)) == NULL) { 508 splx(s); 509 return (-1); 510 } 511 512 if ((ent->flg & WSFONT_BUILTIN) != 0 || ent->lockcount != 0) { 513 splx(s); 514 return (-1); 515 } 516 517 /* Don't free statically allocated font data */ 518 if ((ent->flg & WSFONT_STATIC) != 0) { 519 free(ent->font->data, M_DEVBUF); 520 free(ent->font, M_DEVBUF); 521 } 522 523 /* Remove from list, free entry */ 524 if (ent->prev) 525 ent->prev->next = ent->next; 526 else 527 list = ent->next; 528 529 if (ent->next) 530 ent->next->prev = ent->prev; 531 532 free(ent, M_DEVBUF); 533 splx(s); 534 return (0); 535} 536#endif 537 538/* 539 * Lock a given font and return new lockcount. This fails if the cookie 540 * is invalid, or if the font is already locked and the bit/byte order 541 * requested by the caller differs. 542 */ 543int 544wsfont_lock(cookie, ptr, bitorder, byteorder) 545 int cookie; 546 struct wsdisplay_font **ptr; 547 int bitorder, byteorder; 548{ 549 struct font *ent; 550 int s, lc; 551 552 s = splhigh(); 553 554 if ((ent = wsfont_find0(cookie)) != NULL) { 555 if (bitorder && bitorder != ent->font->bitorder) { 556#if !defined(SMALL_KERNEL) || defined(__alpha__) 557 if (ent->lockcount) { 558 splx(s); 559 return (-1); 560 } 561 wsfont_revbit(ent->font); 562 ent->font->bitorder = bitorder; 563#else 564 splx(s); 565 return (-1); 566#endif 567 } 568 569 if (byteorder && byteorder != ent->font->byteorder) { 570#if !defined(SMALL_KERNEL) 571 if (ent->lockcount) { 572 splx(s); 573 return (-1); 574 } 575 wsfont_revbyte(ent->font); 576 ent->font->byteorder = byteorder; 577#else 578 splx(s); 579 return (-1); 580#endif 581 } 582 583 lc = ++ent->lockcount; 584 *ptr = ent->font; 585 } else 586 lc = -1; 587 588 splx(s); 589 return (lc); 590} 591 592/* 593 * Get font flags and lockcount. 594 */ 595int 596wsfont_getflg(cookie, flg, lc) 597 int cookie, *flg, *lc; 598{ 599 struct font *ent; 600 int s; 601 602 s = splhigh(); 603 604 if ((ent = wsfont_find0(cookie)) != NULL) { 605 *flg = ent->flg; 606 *lc = ent->lockcount; 607 } 608 609 splx(s); 610 return (ent != NULL ? 0 : -1); 611} 612 613/* 614 * Unlock a given font and return new lockcount. 615 */ 616int 617wsfont_unlock(cookie) 618 int cookie; 619{ 620 struct font *ent; 621 int s, lc; 622 623 s = splhigh(); 624 625 if ((ent = wsfont_find0(cookie)) != NULL) { 626 if (ent->lockcount == 0) 627 panic("wsfont_unlock: font not locked"); 628 lc = --ent->lockcount; 629 } else 630 lc = -1; 631 632 splx(s); 633 return (lc); 634} 635 636#if !defined(SMALL_KERNEL) 637 638/* 639 * Unicode to font encoding mappings 640 */ 641 642/* 643 * To save memory, font encoding tables use a two level lookup. 644 * First the high byte of the Unicode is used to lookup the level 2 645 * table, then the low byte indexes that table. Level 2 tables that are 646 * not needed are omitted (NULL), and both level 1 and level 2 tables 647 * have base and size attributes to keep their size down. 648 */ 649 650struct wsfont_level1_glyphmap { 651 struct wsfont_level2_glyphmap **level2; 652 int base; /* High byte for first level2 entry */ 653 int size; /* Number of level2 entries */ 654}; 655 656struct wsfont_level2_glyphmap { 657 int base; /* Low byte for first character */ 658 int size; /* Number of characters */ 659 void *chars; /* Pointer to character number entries */ 660 int width; /* Size of each entry in bytes (1,2,4) */ 661}; 662 663#define null16 \ 664 NULL, NULL, NULL, NULL, \ 665 NULL, NULL, NULL, NULL, \ 666 NULL, NULL, NULL, NULL, \ 667 NULL, NULL, NULL, NULL 668 669/* 670 * IBM 437 maps 671 */ 672 673static u_int8_t 674ibm437_chars_0[] = { 675 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 676 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 677 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 678 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 679 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 680 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 681 96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111, 682 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, 683 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 684 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 685 255,173,155,156, 0, 157, 0, 0, 0, 0, 166,174,170, 0, 0, 0, 686 0, 241,253, 0, 0, 0, 0, 249, 0, 0, 167,175,172,171, 0, 168, 687 0, 0, 0, 0, 142,143,146,128, 0, 144, 0, 0, 0, 0, 0, 0, 688 0, 165, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 154, 0, 0, 0, 689 133,160,131, 0, 132,134,145,135,138,130,136,137,141,161,140,139, 690 0, 164,149,162,147, 0, 148,246, 0, 151,163,150,129, 0, 0, 152 691}, 692ibm437_chars_1[] = { 693 159 694}, 695ibm437_chars_3[] = { 696 226, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 697 228, 0, 0, 232, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 224,225, 698 0, 235,238, 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0, 699 229,231 700}, 701ibm437_chars_32[] = { 702 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 703 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 704 0, 0, 0, 0, 0, 0, 0, 0, 158 705}, 706ibm437_chars_34[] = { 707 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 708 0, 0, 0, 248,250,251, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 709 0, 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 710 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 711 0, 0, 0, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 712 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 0, 0,243, 713 242 714}, 715ibm437_chars_35[] = { 716 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 717 244,245 718}, 719ibm437_chars_37[] = { 720 196,205,179,186, 0, 0, 0, 0, 0, 0, 0, 0, 218,213,214,201, 721 191,184,183,187,192,212,211,200,217,190,189,188,195,198, 0, 0, 722 199, 0, 0, 204,180,181, 0, 0, 182, 0, 0, 185,194, 0, 0, 209, 723 210, 0, 0, 203,193, 0, 0, 207,208, 0, 0, 202,197, 0, 0, 216, 724 0, 0, 215, 0, 0, 0, 0, 0, 0, 0, 0, 206, 0, 0, 0, 0, 725 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 726 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 727 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 728 223, 0, 0, 0, 220, 0, 0, 0, 219, 0, 0, 0, 221, 0, 0, 0, 729 222,176,177,178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 730 254 731}; 732 733static struct wsfont_level2_glyphmap 734ibm437_level2_0 = { 0, 256, ibm437_chars_0, 1 }, 735ibm437_level2_1 = { 146, 1, ibm437_chars_1, 1 }, 736ibm437_level2_3 = { 147, 50, ibm437_chars_3, 1 }, 737ibm437_level2_32 = { 127, 41, ibm437_chars_32, 1 }, 738ibm437_level2_34 = { 5, 97, ibm437_chars_34, 1 }, 739ibm437_level2_35 = { 16, 18, ibm437_chars_35, 1 }, 740ibm437_level2_37 = { 0, 161, ibm437_chars_37, 1 }; 741 742static struct wsfont_level2_glyphmap *ibm437_level1[] = { 743 &ibm437_level2_0, &ibm437_level2_1, NULL, &ibm437_level2_3, 744 NULL, NULL, NULL, NULL, 745 NULL, NULL, NULL, NULL, 746 NULL, NULL, NULL, NULL, 747 NULL, NULL, NULL, NULL, 748 NULL, NULL, NULL, NULL, 749 NULL, NULL, NULL, NULL, 750 NULL, NULL, NULL, NULL, 751 &ibm437_level2_32, NULL, &ibm437_level2_34, &ibm437_level2_35, 752 NULL, &ibm437_level2_37 753}; 754 755 756/* 757 * ISO-8859-7 maps 758 */ 759 760static u_int8_t 761iso7_chars_0[] = { 762 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 763 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 764 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 765 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 766 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 767 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 768 96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111, 769 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, 770 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, 771 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, 772 160, 0, 0, 163, 0, 0, 166,167,168,169, 0, 171,172,173, 0, 0, 773 176,177,178,179,180, 0, 0, 183, 0, 0, 0, 187, 0, 189 774}, 775iso7_chars_3[] = { 776 182, 0, 184,185,186, 0, 188, 0, 190,191,192,193,194,195,196,197, 777 198,199,200,201,202,203,204,205,206,207,208,209, 0, 211,212,213, 778 214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229, 779 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245, 780 246,247,248,249,250,251,252,253,254, 0, 0, 0, 0, 0, 0, 0, 781 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 782 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181 783}, 784iso7_chars_32[] = { 785 175, 0, 0, 0, 0, 162, 0, 161 786}; 787 788static struct wsfont_level2_glyphmap 789iso7_level2_0 = { 0, 190, iso7_chars_0, 1 }, 790iso7_level2_3 = { 134, 111, iso7_chars_3, 1 }, 791iso7_level2_32 = { 20, 8, iso7_chars_32, 1 }; 792 793static struct wsfont_level2_glyphmap *iso7_level1[] = { 794 &iso7_level2_0, NULL, NULL, &iso7_level2_3, 795 NULL, NULL, NULL, NULL, 796 NULL, NULL, NULL, NULL, 797 NULL, NULL, NULL, NULL, 798 NULL, NULL, NULL, NULL, 799 NULL, NULL, NULL, NULL, 800 NULL, NULL, NULL, NULL, 801 NULL, NULL, NULL, NULL, 802 &iso7_level2_32 803}; 804 805 806static struct wsfont_level1_glyphmap encodings[] = { 807 { NULL, 0, 0 }, /* WSDISPLAY_FONTENC_ISO */ 808 { ibm437_level1, 0, 38 }, /* WSDISPLAY_FONTENC_IBM */ 809 { NULL, 0, 0 }, /* WSDISPLAY_FONTENC_PCVT */ 810 { iso7_level1, 0, 33 }, /* WSDISPLAY_FONTENC_ISO7 */ 811}; 812 813#define MAX_ENCODING (sizeof(encodings) / sizeof(encodings[0])) 814 815#endif /* !SMALL_KERNEL */ 816 817/* 818 * Remap Unicode character to glyph 819 */ 820int 821wsfont_map_unichar(font, c) 822 struct wsdisplay_font *font; 823 int c; 824{ 825 if (font->encoding == WSDISPLAY_FONTENC_ISO) 826 return c; 827 else 828#if !defined(SMALL_KERNEL) 829 if (font->encoding < 0 || font->encoding > MAX_ENCODING) 830 return (-1); 831 else { 832 int hi = (c >> 8), lo = c & 255; 833 struct wsfont_level1_glyphmap *map1 = 834 &encodings[font->encoding]; 835 836 if (hi >= map1->base && hi < map1->base + map1->size) { 837 struct wsfont_level2_glyphmap *map2 = 838 map1->level2[hi - map1->base]; 839 840 if (map2 != NULL && 841 lo >= map2->base && lo < map2->base + map2->size) { 842 843 lo -= map2->base; 844 845 switch(map2->width) { 846 case 1: 847 c = (((u_int8_t *)map2->chars)[lo]); 848 break; 849 case 2: 850 c = (((u_int16_t *)map2->chars)[lo]); 851 break; 852 case 4: 853 c = (((u_int32_t *)map2->chars)[lo]); 854 break; 855 } 856 857 if (c == 0 && lo != 0) 858 return (-1); 859 else 860 return (c); 861 862 } else { 863 return (-1); 864 } 865 866 } else { 867 return (-1); 868 } 869 870 } 871#else 872 return (-1); 873#endif /* SMALL_KERNEL */ 874} 875