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