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