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