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