1 /* $NetBSD: wsfont.c,v 1.22 2001/10/13 16:05:42 augustss 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.22 2001/10/13 16:05:42 augustss 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(int); 191 static void wsfont_revbit(struct wsdisplay_font *); 192 static void wsfont_revbyte(struct wsdisplay_font *); 193 194 /* 195 * Reverse the bit order of a font 196 */ 197 static void 198 wsfont_revbit(struct wsdisplay_font *font) 199 { 200 u_char *p, *m; 201 202 p = (u_char *)font->data; 203 m = p + font->stride * font->numchars * font->fontheight; 204 205 for (; p < m; p++) 206 *p = reverse[*p]; 207 } 208 209 /* 210 * Reverse the byte order of a font 211 */ 212 static void 213 wsfont_revbyte(struct wsdisplay_font *font) 214 { 215 int x, l, r, nr; 216 u_char *rp; 217 218 if (font->stride == 1) 219 return; 220 221 rp = (u_char *)font->data; 222 nr = font->numchars * font->fontheight; 223 224 while (nr--) { 225 l = 0; 226 r = font->stride - 1; 227 228 while (l < r) { 229 x = rp[l]; 230 rp[l] = rp[r]; 231 rp[r] = x; 232 l++, r--; 233 } 234 235 rp += font->stride; 236 } 237 } 238 239 /* 240 * Enumarate the list of fonts 241 */ 242 void 243 wsfont_enum(void (*cb)(char *, int, int, int)) 244 { 245 struct wsdisplay_font *f; 246 struct font *ent; 247 int s; 248 249 s = splhigh(); 250 251 for (ent = list; ent; ent = ent->next) { 252 f = ent->font; 253 cb(f->name, f->fontwidth, f->fontheight, f->stride); 254 } 255 256 splx(s); 257 } 258 259 /* 260 * Initialize list with WSFONT_BUILTIN fonts 261 */ 262 void 263 wsfont_init(void) 264 { 265 static int again; 266 int i; 267 268 if (again != 0) 269 return; 270 again = 1; 271 272 for (i = 0; builtin_fonts[i].font != NULL; i++) { 273 builtin_fonts[i].next = list; 274 list = &builtin_fonts[i]; 275 } 276 } 277 278 /* 279 * Find a font by cookie. Called at splhigh. 280 */ 281 static struct font * 282 wsfont_find0(int cookie) 283 { 284 struct font *ent; 285 286 for (ent = list; ent != NULL; ent = ent->next) 287 if (ent->cookie == cookie) 288 return (ent); 289 290 return (NULL); 291 } 292 293 int 294 wsfont_matches(struct wsdisplay_font *font, char *name, 295 int width, int height, int stride) 296 { 297 298 if (height != 0 && font->fontheight != height) 299 return (0); 300 301 if (width != 0 && font->fontwidth != width) 302 return (0); 303 304 if (stride != 0 && font->stride != stride) 305 return (0); 306 307 if (name != NULL && strcmp(font->name, name) != 0) 308 return (0); 309 310 return (1); 311 } 312 313 /* 314 * Find a font. 315 */ 316 int 317 wsfont_find(char *name, int width, int height, int stride) 318 { 319 struct font *ent; 320 int s; 321 322 s = splhigh(); 323 324 for (ent = list; ent != NULL; ent = ent->next) { 325 if (wsfont_matches(ent->font, name, width, height, stride)) { 326 splx(s); 327 return (ent->cookie); 328 } 329 } 330 331 splx(s); 332 return (-1); 333 } 334 335 /* 336 * Add a font to the list. 337 */ 338 int 339 wsfont_add(struct wsdisplay_font *font, int copy) 340 { 341 static int cookiegen = 666; 342 struct font *ent; 343 size_t size; 344 int s; 345 346 s = splhigh(); 347 348 /* Don't allow exact duplicates */ 349 if (wsfont_find(font->name, font->fontwidth, font->fontheight, 350 font->stride) >= 0) { 351 splx(s); 352 return (EEXIST); 353 } 354 355 MALLOC(ent, struct font *, sizeof *ent, M_DEVBUF, M_WAITOK); 356 357 ent->lockcount = 0; 358 ent->flg = 0; 359 ent->cookie = cookiegen++; 360 ent->next = list; 361 ent->prev = NULL; 362 363 /* Is this font statically allocated? */ 364 if (!copy) { 365 ent->font = font; 366 ent->flg = WSFONT_STATIC; 367 } else { 368 MALLOC(ent->font, struct wsdisplay_font *, sizeof *ent->font, 369 M_DEVBUF, M_WAITOK); 370 memcpy(ent->font, font, sizeof(*ent->font)); 371 372 size = font->fontheight * font->numchars * font->stride; 373 MALLOC(ent->font->data, void *, size, M_DEVBUF, M_WAITOK); 374 memcpy(ent->font->data, font->data, size); 375 MALLOC(ent->font->name, char *, strlen(font->name) + 1, 376 M_DEVBUF, M_WAITOK); 377 strcpy(ent->font->name, font->name); 378 ent->flg = 0; 379 } 380 381 /* Now link into the list and return */ 382 list = ent; 383 splx(s); 384 return (0); 385 } 386 387 /* 388 * Remove a font. 389 */ 390 int 391 wsfont_remove(int cookie) 392 { 393 struct font *ent; 394 int s; 395 396 s = splhigh(); 397 398 if ((ent = wsfont_find0(cookie)) == NULL) { 399 splx(s); 400 return (ENOENT); 401 } 402 403 if ((ent->flg & WSFONT_BUILTIN) != 0 || ent->lockcount != 0) { 404 splx(s); 405 return (EBUSY); 406 } 407 408 /* Don't free statically allocated font data */ 409 if ((ent->flg & WSFONT_STATIC) != 0) { 410 FREE(ent->font->data, M_DEVBUF); 411 FREE(ent->font->name, M_DEVBUF); 412 FREE(ent->font, M_DEVBUF); 413 } 414 415 /* Remove from list, free entry */ 416 if (ent->prev) 417 ent->prev->next = ent->next; 418 else 419 list = ent->next; 420 421 if (ent->next) 422 ent->next->prev = ent->prev; 423 424 FREE(ent, M_DEVBUF); 425 splx(s); 426 return (0); 427 } 428 429 /* 430 * Lock a given font and return new lockcount. This fails if the cookie 431 * is invalid, or if the font is already locked and the bit/byte order 432 * requested by the caller differs. 433 */ 434 int 435 wsfont_lock(int cookie, struct wsdisplay_font **ptr, 436 int bitorder, int byteorder) 437 { 438 struct font *ent; 439 int s, lc; 440 441 s = splhigh(); 442 443 if ((ent = wsfont_find0(cookie)) != NULL) { 444 if (bitorder && bitorder != ent->font->bitorder) { 445 if (ent->lockcount) { 446 splx(s); 447 return (-1); 448 } 449 wsfont_revbit(ent->font); 450 ent->font->bitorder = bitorder; 451 } 452 453 if (byteorder && byteorder != ent->font->byteorder) { 454 if (ent->lockcount) { 455 splx(s); 456 return (-1); 457 } 458 wsfont_revbyte(ent->font); 459 ent->font->byteorder = byteorder; 460 } 461 462 lc = ++ent->lockcount; 463 *ptr = ent->font; 464 } else 465 lc = -1; 466 467 splx(s); 468 return (lc); 469 } 470 471 /* 472 * Get font flags and lockcount. 473 */ 474 int 475 wsfont_getflg(int cookie, int *flg, int *lc) 476 { 477 struct font *ent; 478 int s; 479 480 s = splhigh(); 481 482 if ((ent = wsfont_find0(cookie)) != NULL) { 483 *flg = ent->flg; 484 *lc = ent->lockcount; 485 } 486 487 splx(s); 488 return (ent != NULL ? 0 : -1); 489 } 490 491 /* 492 * Unlock a given font and return new lockcount. 493 */ 494 int 495 wsfont_unlock(int cookie) 496 { 497 struct font *ent; 498 int s, lc; 499 500 s = splhigh(); 501 502 if ((ent = wsfont_find0(cookie)) != NULL) { 503 if (ent->lockcount == 0) 504 panic("wsfont_unlock: font not locked\n"); 505 lc = --ent->lockcount; 506 } else 507 lc = -1; 508 509 splx(s); 510 return (lc); 511 } 512 513 514 /* 515 * Unicode to font encoding mappings 516 */ 517 518 /* 519 * To save memory, font encoding tables use a two level lookup. 520 * First the high byte of the Unicode is used to lookup the level 2 521 * table, then the low byte indexes that table. Level 2 tables that are 522 * not needed are omitted (NULL), and both level 1 and level 2 tables 523 * have base and size attributes to keep their size down. 524 */ 525 526 struct wsfont_level1_glyphmap { 527 struct wsfont_level2_glyphmap **level2; 528 int base; /* High byte for first level2 entry */ 529 int size; /* Number of level2 entries */ 530 }; 531 532 struct wsfont_level2_glyphmap { 533 int base; /* Low byte for first character */ 534 int size; /* Number of characters */ 535 void *chars; /* Pointer to character number entries */ 536 int width; /* Size of each entry in bytes (1,2,4) */ 537 }; 538 539 #define null16 \ 540 NULL, NULL, NULL, NULL, \ 541 NULL, NULL, NULL, NULL, \ 542 NULL, NULL, NULL, NULL, \ 543 NULL, NULL, NULL, NULL 544 545 /* 546 * IBM 437 maps 547 */ 548 549 static u_int8_t 550 ibm437_chars_0[] = { 551 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 552 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 553 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 554 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 555 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 556 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 557 96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111, 558 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, 559 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 560 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 561 255,173,155,156, 0, 157, 0, 0, 0, 0, 166,174,170, 0, 0, 0, 562 0, 241,253, 0, 0, 0, 0, 249, 0, 0, 167,175,172,171, 0, 168, 563 0, 0, 0, 0, 142,143,146,128, 0, 144, 0, 0, 0, 0, 0, 0, 564 0, 165, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 154, 0, 0, 0, 565 133,160,131, 0, 132,134,145,135,138,130,136,137,141,161,140,139, 566 0, 164,149,162,147, 0, 148,246, 0, 151,163,150,129, 0, 0, 152 567 }, 568 ibm437_chars_1[] = { 569 159 570 }, 571 ibm437_chars_3[] = { 572 226, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 573 228, 0, 0, 232, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 224,225, 574 0, 235,238, 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0, 575 229,231 576 }, 577 ibm437_chars_32[] = { 578 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 579 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 580 0, 0, 0, 0, 0, 0, 0, 0, 158 581 }, 582 ibm437_chars_34[] = { 583 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 584 0, 0, 0, 248,250,251, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 585 0, 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 586 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 587 0, 0, 0, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 588 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 0, 0,243, 589 242 590 }, 591 ibm437_chars_35[] = { 592 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 593 244,245 594 }, 595 ibm437_chars_37[] = { 596 196,205,179,186, 0, 0, 0, 0, 0, 0, 0, 0, 218,213,214,201, 597 191,184,183,187,192,212,211,200,217,190,189,188,195,198, 0, 0, 598 199, 0, 0, 204,180,181, 0, 0, 182, 0, 0, 185,194, 0, 0, 209, 599 210, 0, 0, 203,193, 0, 0, 207,208, 0, 0, 202,197, 0, 0, 216, 600 0, 0, 215, 0, 0, 0, 0, 0, 0, 0, 0, 206, 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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 604 223, 0, 0, 0, 220, 0, 0, 0, 219, 0, 0, 0, 221, 0, 0, 0, 605 222,176,177,178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 606 254 607 }; 608 609 static struct wsfont_level2_glyphmap 610 ibm437_level2_0 = { 0, 256, ibm437_chars_0, 1 }, 611 ibm437_level2_1 = { 146, 1, ibm437_chars_1, 1 }, 612 ibm437_level2_3 = { 147, 50, ibm437_chars_3, 1 }, 613 ibm437_level2_32 = { 127, 41, ibm437_chars_32, 1 }, 614 ibm437_level2_34 = { 5, 97, ibm437_chars_34, 1 }, 615 ibm437_level2_35 = { 16, 18, ibm437_chars_35, 1 }, 616 ibm437_level2_37 = { 0, 161, ibm437_chars_37, 1 }; 617 618 static struct wsfont_level2_glyphmap *ibm437_level1[] = { 619 &ibm437_level2_0, &ibm437_level2_1, NULL, &ibm437_level2_3, 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 NULL, NULL, NULL, NULL, 627 &ibm437_level2_32, NULL, &ibm437_level2_34, &ibm437_level2_35, 628 NULL, &ibm437_level2_37 629 }; 630 631 632 /* 633 * ISO-8859-7 maps 634 */ 635 636 static u_int8_t 637 iso7_chars_0[] = { 638 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 639 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 640 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 641 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 642 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 643 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 644 96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111, 645 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, 646 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, 647 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, 648 160, 0, 0, 163, 0, 0, 166,167,168,169, 0, 171,172,173, 0, 0, 649 176,177,178,179,180, 0, 0, 183, 0, 0, 0, 187, 0, 189 650 }, 651 iso7_chars_3[] = { 652 182, 0, 184,185,186, 0, 188, 0, 190,191,192,193,194,195,196,197, 653 198,199,200,201,202,203,204,205,206,207,208,209, 0, 211,212,213, 654 214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229, 655 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245, 656 246,247,248,249,250,251,252,253,254, 0, 0, 0, 0, 0, 0, 0, 657 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 658 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181 659 }, 660 iso7_chars_32[] = { 661 175, 0, 0, 0, 0, 162, 0, 161 662 }; 663 664 static struct wsfont_level2_glyphmap 665 iso7_level2_0 = { 0, 190, iso7_chars_0, 1 }, 666 iso7_level2_3 = { 134, 111, iso7_chars_3, 1 }, 667 iso7_level2_32 = { 20, 8, iso7_chars_32, 1 }; 668 669 static struct wsfont_level2_glyphmap *iso7_level1[] = { 670 &iso7_level2_0, NULL, NULL, &iso7_level2_3, 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 NULL, NULL, NULL, NULL, 678 &iso7_level2_32 679 }; 680 681 static struct wsfont_level1_glyphmap encodings[] = { 682 { NULL, 0, 0 }, /* WSDISPLAY_FONTENC_ISO */ 683 { ibm437_level1, 0, 38 }, /* WSDISPLAY_FONTENC_IBM */ 684 { NULL, 0, 0 }, /* WSDISPLAY_FONTENC_PCVT */ 685 { iso7_level1, 0, 33 }, /* WSDISPLAY_FONTENC_ISO7 */ 686 }; 687 688 #define MAX_ENCODING (sizeof(encodings) / sizeof(encodings[0])) 689 690 /* 691 * Remap Unicode character to glyph 692 */ 693 int 694 wsfont_map_unichar(struct wsdisplay_font *font, int c) 695 { 696 if (font->encoding == WSDISPLAY_FONTENC_ISO) { 697 698 return c; 699 700 } else if (font->encoding < 0 || font->encoding > MAX_ENCODING) { 701 702 return (-1); 703 704 } else { 705 706 int hi = (c >> 8), lo = c & 255; 707 struct wsfont_level1_glyphmap *map1 = 708 &encodings[font->encoding]; 709 710 if (hi >= map1->base && hi < map1->base + map1->size) { 711 struct wsfont_level2_glyphmap *map2 = 712 map1->level2[hi - map1->base]; 713 714 if (map2 != NULL && 715 lo >= map2->base && lo < map2->base + map2->size) { 716 717 lo -= map2->base; 718 719 switch(map2->width) { 720 case 1: 721 c = (((u_int8_t *)map2->chars)[lo]); 722 break; 723 case 2: 724 c = (((u_int16_t *)map2->chars)[lo]); 725 break; 726 case 4: 727 c = (((u_int32_t *)map2->chars)[lo]); 728 break; 729 } 730 731 if (c == 0 && lo != 0) 732 return (-1); 733 else 734 return (c); 735 736 } else { 737 return (-1); 738 } 739 740 } else { 741 return (-1); 742 } 743 744 } 745 746 } 747