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