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