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