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