1 /* $NetBSD: wsfont.c,v 1.46 2010/04/17 13:36:22 nonaka 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 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: wsfont.c,v 1.46 2010/04/17 13:36:22 nonaka Exp $"); 34 35 #include "opt_wsfont.h" 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/time.h> 40 #include <sys/malloc.h> 41 #include <sys/queue.h> 42 43 #include <dev/wscons/wsdisplayvar.h> 44 #include <dev/wscons/wsconsio.h> 45 #include <dev/wsfont/wsfont.h> 46 47 #include "wsfont_glue.h" /* NRASOPS_ROTATION */ 48 49 #undef HAVE_FONT 50 51 #ifdef FONT_QVSS8x15 52 #define HAVE_FONT 1 53 #include <dev/wsfont/qvss8x15.h> 54 #endif 55 56 #ifdef FONT_GALLANT12x22 57 #define HAVE_FONT 1 58 #include <dev/wsfont/gallant12x22.h> 59 #endif 60 61 #ifdef FONT_LUCIDA16x29 62 #define HAVE_FONT 1 63 #include <dev/wsfont/lucida16x29.h> 64 #endif 65 66 #ifdef FONT_VT220L8x8 67 #define HAVE_FONT 1 68 #include <dev/wsfont/vt220l8x8.h> 69 #endif 70 71 #ifdef FONT_VT220L8x10 72 #define HAVE_FONT 1 73 #include <dev/wsfont/vt220l8x10.h> 74 #endif 75 76 #ifdef FONT_VT220L8x16 77 #define HAVE_FONT 1 78 #include <dev/wsfont/vt220l8x16.h> 79 #endif 80 81 #ifdef FONT_VT220ISO8x16 82 #define HAVE_FONT 1 83 #include <dev/wsfont/vt220iso8x16.h> 84 #endif 85 86 #ifdef FONT_VT220KOI8x10_KOI8_R 87 #define HAVE_FONT 1 88 #include <dev/wsfont/vt220koi8x10.h> 89 #endif 90 91 #ifdef FONT_VT220KOI8x10_KOI8_U 92 #define HAVE_FONT 1 93 #define KOI8_U 94 #include <dev/wsfont/vt220koi8x10.h> 95 #undef KOI8_U 96 #endif 97 98 #ifdef FONT_SONY8x16 99 #define HAVE_FONT 1 100 #include <dev/wsfont/sony8x16.h> 101 #endif 102 103 #ifdef FONT_SONY12x24 104 #define HAVE_FONT 1 105 #include <dev/wsfont/sony12x24.h> 106 #endif 107 108 #ifdef FONT_OMRON12x20 109 #define HAVE_FONT 1 110 #include <dev/wsfont/omron12x20.h> 111 #endif 112 113 /* Make sure we always have at least one font. */ 114 #ifndef HAVE_FONT 115 #define HAVE_FONT 1 116 #define FONT_BOLD8x16 1 117 #endif 118 119 #ifdef FONT_BOLD8x16 120 #include <dev/wsfont/bold8x16.h> 121 #endif 122 123 #define WSFONT_IDENT_MASK 0xffffff00 124 #define WSFONT_IDENT_SHIFT 8 125 #define WSFONT_BITO_MASK 0x000000f0 126 #define WSFONT_BITO_SHIFT 4 127 #define WSFONT_BYTEO_MASK 0x0000000f 128 #define WSFONT_BYTEO_SHIFT 0 129 130 #define WSFONT_BUILTIN 0x01 /* In wsfont.c */ 131 #define WSFONT_STATIC 0x02 /* Font structures not malloc()ed */ 132 #define WSFONT_COPY 0x04 /* Copy of existing font in table */ 133 134 /* Placeholder struct used for linked list */ 135 struct font { 136 TAILQ_ENTRY(font) chain; 137 struct wsdisplay_font *font; 138 u_int lockcount; 139 u_int cookie; 140 u_int flags; 141 }; 142 143 /* Our list of built-in fonts */ 144 static struct font builtin_fonts[] = { 145 #ifdef FONT_BOLD8x16 146 { { NULL, NULL }, &bold8x16, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN }, 147 #endif 148 #ifdef FONT_ISO8x16 149 { { NULL, NULL }, &iso8x16, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN }, 150 #endif 151 #ifdef FONT_COURIER11x18 152 { { NULL, NULL }, &courier11x18, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN }, 153 #endif 154 #ifdef FONT_GALLANT12x22 155 { { NULL, NULL }, &gallant12x22, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN }, 156 #endif 157 #ifdef FONT_LUCIDA16x29 158 { { NULL, NULL }, &lucida16x29, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN }, 159 #endif 160 #ifdef FONT_QVSS8x15 161 { { NULL, NULL }, &qvss8x15, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN }, 162 #endif 163 #ifdef FONT_VT220L8x8 164 { { NULL, NULL }, &vt220l8x8, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN }, 165 #endif 166 #ifdef FONT_VT220L8x10 167 { { NULL, NULL }, &vt220l8x10, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN }, 168 #endif 169 #ifdef FONT_VT220L8x16 170 { { NULL, NULL }, &vt220l8x16, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN }, 171 #endif 172 #ifdef FONT_VT220ISO8x16 173 { { NULL, NULL }, &vt220iso8x16, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN }, 174 #endif 175 #ifdef FONT_VT220KOI8x10_KOI8_R 176 { { NULL, NULL }, &vt220kr8x10, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN }, 177 #endif 178 #ifdef FONT_VT220KOI8x10_KOI8_U 179 { { NULL, NULL }, &vt220ku8x10, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN }, 180 #endif 181 #ifdef FONT_SONY8x16 182 { { NULL, NULL }, &sony8x16, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN }, 183 #endif 184 #ifdef FONT_SONY12x24 185 { { NULL, NULL }, &sony12x24, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN }, 186 #endif 187 #ifdef FONT_OMRON12x20 188 { { NULL, NULL }, &omron12x20, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN }, 189 #endif 190 { { NULL, NULL }, NULL, 0, 0, 0 }, 191 }; 192 193 static TAILQ_HEAD(,font) list; 194 static int ident; 195 196 /* Reverse the bit order in a byte */ 197 static const u_char reverse[256] = { 198 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 199 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 200 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 201 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 202 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 203 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 204 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 205 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 206 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 207 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 208 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 209 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 210 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 211 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 212 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 213 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 214 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 215 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 216 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 217 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 218 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 219 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 220 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 221 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 222 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 223 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 224 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 225 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 226 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 227 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 228 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 229 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, 230 }; 231 232 static struct font *wsfont_find0(int, int); 233 static struct font *wsfont_add0(struct wsdisplay_font *, int); 234 static void wsfont_revbit(struct wsdisplay_font *); 235 static void wsfont_revbyte(struct wsdisplay_font *); 236 static inline int wsfont_make_cookie(int, int, int); 237 238 static inline int 239 wsfont_make_cookie(int cident, int bito, int byteo) 240 { 241 242 return ((cident & WSFONT_IDENT_MASK) | 243 (bito << WSFONT_BITO_SHIFT) | 244 (byteo << WSFONT_BYTEO_SHIFT)); 245 } 246 247 static void 248 wsfont_revbit(struct wsdisplay_font *font) 249 { 250 u_char *p, *m; 251 252 p = (u_char *)font->data; 253 m = p + font->stride * font->numchars * font->fontheight; 254 255 for (; p < m; p++) 256 *p = reverse[*p]; 257 } 258 259 static void 260 wsfont_revbyte(struct wsdisplay_font *font) 261 { 262 int x, l, r, nr; 263 u_char *rp; 264 265 if (font->stride == 1) 266 return; 267 268 rp = (u_char *)font->data; 269 nr = font->numchars * font->fontheight; 270 271 while (nr--) { 272 l = 0; 273 r = font->stride - 1; 274 275 while (l < r) { 276 x = rp[l]; 277 rp[l] = rp[r]; 278 rp[r] = x; 279 l++, r--; 280 } 281 282 rp += font->stride; 283 } 284 } 285 286 void 287 wsfont_enum(void (*cb)(const char *, int, int, int)) 288 { 289 struct wsdisplay_font *f; 290 struct font *ent; 291 292 TAILQ_FOREACH(ent, &list, chain) { 293 f = ent->font; 294 cb(f->name, f->fontwidth, f->fontheight, f->stride); 295 } 296 } 297 298 #if NRASOPS_ROTATION > 0 299 300 struct wsdisplay_font *wsfont_rotate_cw_internal(struct wsdisplay_font *); 301 struct wsdisplay_font *wsfont_rotate_ccw_internal(struct wsdisplay_font *); 302 303 struct wsdisplay_font * 304 wsfont_rotate_cw_internal(struct wsdisplay_font *font) 305 { 306 int b, n, r, newstride; 307 struct wsdisplay_font *newfont; 308 char *newbits; 309 310 /* Duplicate the existing font... */ 311 newfont = malloc(sizeof(*font), M_DEVBUF, M_WAITOK); 312 if (newfont == NULL) 313 return (NULL); 314 315 *newfont = *font; 316 317 /* Allocate a buffer big enough for the rotated font. */ 318 newstride = (font->fontheight + 7) / 8; 319 newbits = malloc(newstride * font->fontwidth * font->numchars, 320 M_DEVBUF, M_WAITOK|M_ZERO); 321 if (newbits == NULL) { 322 free(newfont, M_DEVBUF); 323 return (NULL); 324 } 325 326 /* Rotate the font a bit at a time. */ 327 for (n = 0; n < font->numchars; n++) { 328 unsigned char *ch = (unsigned char *)font->data + 329 (n * font->stride * font->fontheight); 330 331 for (r = 0; r < font->fontheight; r++) { 332 for (b = 0; b < font->fontwidth; b++) { 333 unsigned char *rb; 334 335 rb = ch + (font->stride * r) + (b / 8); 336 if (*rb & (0x80 >> (b % 8))) { 337 unsigned char *rrb; 338 339 rrb = newbits + newstride - 1 - (r / 8) 340 + (n * newstride * font->fontwidth) 341 + (newstride * b); 342 *rrb |= (1 << (r % 8)); 343 } 344 } 345 } 346 } 347 348 newfont->data = newbits; 349 350 /* Update font sizes. */ 351 newfont->stride = newstride; 352 newfont->fontwidth = font->fontheight; 353 newfont->fontheight = font->fontwidth; 354 355 if (wsfont_add(newfont, 0) != 0) { 356 /* 357 * If we seem to have rotated this font already, drop the 358 * new one... 359 */ 360 free(newbits, M_DEVBUF); 361 free(newfont, M_DEVBUF); 362 newfont = NULL; 363 } 364 365 return (newfont); 366 } 367 368 struct wsdisplay_font * 369 wsfont_rotate_ccw_internal(struct wsdisplay_font *font) 370 { 371 int b, n, r, newstride; 372 struct wsdisplay_font *newfont; 373 char *newbits; 374 375 /* Duplicate the existing font... */ 376 newfont = malloc(sizeof(*font), M_DEVBUF, M_WAITOK); 377 if (newfont == NULL) 378 return (NULL); 379 380 *newfont = *font; 381 382 /* Allocate a buffer big enough for the rotated font. */ 383 newstride = (font->fontheight + 7) / 8; 384 newbits = malloc(newstride * font->fontwidth * font->numchars, 385 M_DEVBUF, M_WAITOK|M_ZERO); 386 if (newbits == NULL) { 387 free(newfont, M_DEVBUF); 388 return (NULL); 389 } 390 391 /* Rotate the font a bit at a time. */ 392 for (n = 0; n < font->numchars; n++) { 393 unsigned char *ch = (unsigned char *)font->data + 394 (n * font->stride * font->fontheight); 395 396 for (r = 0; r < font->fontheight; r++) { 397 for (b = 0; b < font->fontwidth; b++) { 398 unsigned char *rb; 399 400 rb = ch + (font->stride * r) + (b / 8); 401 if (*rb & (0x80 >> (b % 8))) { 402 unsigned char *rrb; 403 int w = font->fontwidth; 404 405 rrb = newbits + (r / 8) 406 + (n * newstride * w) 407 + (newstride * (w - 1 - b)); 408 *rrb |= (0x80 >> (r % 8)); 409 } 410 } 411 } 412 } 413 414 newfont->data = newbits; 415 416 /* Update font sizes. */ 417 newfont->stride = newstride; 418 newfont->fontwidth = font->fontheight; 419 newfont->fontheight = font->fontwidth; 420 421 if (wsfont_add(newfont, 0) != 0) { 422 /* 423 * If we seem to have rotated this font already, drop the 424 * new one... 425 */ 426 free(newbits, M_DEVBUF); 427 free(newfont, M_DEVBUF); 428 newfont = NULL; 429 } 430 431 return (newfont); 432 } 433 434 int 435 wsfont_rotate(int cookie, int rotate) 436 { 437 int s, ncookie; 438 struct wsdisplay_font *font; 439 struct font *origfont; 440 441 s = splhigh(); 442 origfont = wsfont_find0(cookie, 0xffffffff); 443 splx(s); 444 445 switch (rotate) { 446 case WSFONT_ROTATE_CW: 447 font = wsfont_rotate_cw_internal(origfont->font); 448 if (font == NULL) 449 return (-1); 450 break; 451 452 case WSFONT_ROTATE_CCW: 453 font = wsfont_rotate_ccw_internal(origfont->font); 454 if (font == NULL) 455 return (-1); 456 break; 457 458 case WSFONT_ROTATE_UD: 459 default: 460 return (-1); 461 } 462 463 ncookie = wsfont_find(font->name, font->fontwidth, font->fontheight, 464 font->stride, 0, 0); 465 466 return (ncookie); 467 } 468 469 #endif /* NRASOPS_ROTATION */ 470 471 void 472 wsfont_init(void) 473 { 474 struct font *ent; 475 static int again; 476 int i; 477 478 if (again != 0) 479 return; 480 again = 1; 481 482 TAILQ_INIT(&list); 483 ent = builtin_fonts; 484 485 for (i = 0; builtin_fonts[i].font != NULL; i++, ent++) { 486 ident += (1 << WSFONT_IDENT_SHIFT); 487 ent->cookie = wsfont_make_cookie(ident, 488 ent->font->bitorder, ent->font->byteorder); 489 TAILQ_INSERT_TAIL(&list, ent, chain); 490 } 491 } 492 493 static struct font * 494 wsfont_find0(int cookie, int mask) 495 { 496 struct font *ent; 497 498 TAILQ_FOREACH(ent, &list, chain) { 499 if ((ent->cookie & mask) == (cookie & mask)) 500 return (ent); 501 } 502 503 return (NULL); 504 } 505 506 int 507 wsfont_matches(struct wsdisplay_font *font, const char *name, 508 int width, int height, int stride) 509 { 510 511 if (height != 0 && font->fontheight != height) 512 return (0); 513 514 if (width != 0 && font->fontwidth != width) 515 return (0); 516 517 if (stride != 0 && font->stride != stride) 518 return (0); 519 520 if (name != NULL && strcmp(font->name, name) != 0) 521 return (0); 522 523 return (1); 524 } 525 526 int 527 wsfont_find(const char *name, int width, int height, int stride, int bito, int byteo) 528 { 529 struct font *ent; 530 531 TAILQ_FOREACH(ent, &list, chain) { 532 if (wsfont_matches(ent->font, name, width, height, stride)) 533 return (wsfont_make_cookie(ent->cookie, bito, byteo)); 534 } 535 536 return (-1); 537 } 538 539 static struct font * 540 wsfont_add0(struct wsdisplay_font *font, int copy) 541 { 542 struct font *ent; 543 size_t size; 544 545 ent = malloc(sizeof(struct font), M_DEVBUF, M_WAITOK | M_ZERO); 546 547 /* Is this font statically allocated? */ 548 if (!copy) { 549 ent->font = font; 550 ent->flags = WSFONT_STATIC; 551 } else { 552 void *data; 553 char *name; 554 555 ent->font = malloc(sizeof(struct wsdisplay_font), M_DEVBUF, 556 M_WAITOK); 557 memcpy(ent->font, font, sizeof(*ent->font)); 558 559 size = font->fontheight * font->numchars * font->stride; 560 data = malloc(size, M_DEVBUF, M_WAITOK); 561 memcpy(data, font->data, size); 562 ent->font->data = data; 563 564 name = malloc(strlen(font->name) + 1, M_DEVBUF, M_WAITOK); 565 strlcpy(name, font->name, strlen(font->name) + 1); 566 ent->font->name = name; 567 } 568 569 TAILQ_INSERT_TAIL(&list, ent, chain); 570 return (ent); 571 } 572 573 int 574 wsfont_add(struct wsdisplay_font *font, int copy) 575 { 576 struct font *ent; 577 578 /* Don't allow exact duplicates */ 579 if (wsfont_find(font->name, font->fontwidth, font->fontheight, 580 font->stride, 0, 0) >= 0) 581 return (EEXIST); 582 583 ent = wsfont_add0(font, copy); 584 585 ident += (1 << WSFONT_IDENT_SHIFT); 586 ent->cookie = wsfont_make_cookie(ident, font->bitorder, 587 font->byteorder); 588 589 return (0); 590 } 591 592 int 593 wsfont_remove(int cookie) 594 { 595 struct font *ent; 596 597 if ((ent = wsfont_find0(cookie, 0xffffffff)) == NULL) 598 return (ENOENT); 599 600 if ((ent->flags & WSFONT_BUILTIN) != 0 || ent->lockcount != 0) 601 return (EBUSY); 602 603 if ((ent->flags & WSFONT_STATIC) == 0) { 604 free(ent->font->data, M_DEVBUF); 605 free(__UNCONST(ent->font->name), M_DEVBUF); /*XXXUNCONST*/ 606 free(ent->font, M_DEVBUF); 607 } 608 609 TAILQ_REMOVE(&list, ent, chain); 610 free(ent, M_DEVBUF); 611 612 return (0); 613 } 614 615 int 616 wsfont_lock(int cookie, struct wsdisplay_font **ptr) 617 { 618 struct font *ent, *neu; 619 int bito, byteo; 620 621 if ((ent = wsfont_find0(cookie, 0xffffffff)) == NULL) { 622 if ((ent = wsfont_find0(cookie, WSFONT_IDENT_MASK)) == NULL) 623 return (ENOENT); 624 625 bito = (cookie & WSFONT_BITO_MASK) >> WSFONT_BITO_SHIFT; 626 byteo = (cookie & WSFONT_BYTEO_MASK) >> WSFONT_BYTEO_SHIFT; 627 628 if (ent->lockcount != 0) { 629 neu = wsfont_add0(ent->font, 1); 630 neu->flags |= WSFONT_COPY; 631 632 aprint_debug("wsfont: font '%s' bito %d byteo %d " 633 "copied to bito %d byteo %d\n", 634 ent->font->name, 635 ent->font->bitorder, ent->font->byteorder, 636 bito, byteo); 637 638 ent = neu; 639 } 640 641 if (bito && bito != ent->font->bitorder) { 642 wsfont_revbit(ent->font); 643 ent->font->bitorder = bito; 644 } 645 646 if (byteo && byteo != ent->font->byteorder) { 647 wsfont_revbyte(ent->font); 648 ent->font->byteorder = byteo; 649 } 650 651 ent->cookie = cookie; 652 } 653 654 ent->lockcount++; 655 *ptr = ent->font; 656 return (0); 657 } 658 659 int 660 wsfont_unlock(int cookie) 661 { 662 struct font *ent; 663 664 if ((ent = wsfont_find0(cookie, 0xffffffff)) == NULL) 665 return (ENOENT); 666 667 if (ent->lockcount == 0) 668 panic("wsfont_unlock: font not locked"); 669 670 if (--ent->lockcount == 0 && (ent->flags & WSFONT_COPY) != 0) 671 wsfont_remove(cookie); 672 673 return (0); 674 } 675 676 /* 677 * Unicode to font encoding mappings 678 */ 679 680 /* 681 * To save memory, font encoding tables use a two level lookup. First the 682 * high byte of the Unicode is used to lookup the level 2 table, then the 683 * low byte indexes that table. Level 2 tables that are not needed are 684 * omitted (NULL), and both level 1 and level 2 tables have base and size 685 * attributes to keep their size down. 686 */ 687 688 struct wsfont_level1_glyphmap { 689 const struct wsfont_level2_glyphmap **level2; 690 int base; /* High byte for first level2 entry */ 691 int size; /* Number of level2 entries */ 692 }; 693 694 struct wsfont_level2_glyphmap { 695 int base; /* Low byte for first character */ 696 int size; /* Number of characters */ 697 const void *chars; /* Pointer to character number entries */ 698 int width; /* Size of each entry in bytes (1,2,4) */ 699 }; 700 701 #define null16 \ 702 NULL, NULL, NULL, NULL, \ 703 NULL, NULL, NULL, NULL, \ 704 NULL, NULL, NULL, NULL, \ 705 NULL, NULL, NULL, NULL 706 707 /* 708 * IBM 437 maps 709 */ 710 711 static const u_int8_t ibm437_chars_0[] = { 712 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 713 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 714 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 715 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 716 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 717 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 718 96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111, 719 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, 720 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 721 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 722 255,173,155,156, 0, 157, 0, 0, 0, 0, 166,174,170, 0, 0, 0, 723 0, 241,253, 0, 0, 0, 0, 249, 0, 0, 167,175,172,171, 0, 168, 724 0, 0, 0, 0, 142,143,146,128, 0, 144, 0, 0, 0, 0, 0, 0, 725 0, 165, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 154, 0, 0, 0, 726 133,160,131, 0, 132,134,145,135,138,130,136,137,141,161,140,139, 727 0, 164,149,162,147, 0, 148,246, 0, 151,163,150,129, 0, 0, 152 728 }; 729 730 static const u_int8_t ibm437_chars_1[] = { 731 159 732 }; 733 734 static const u_int8_t ibm437_chars_3[] = { 735 226, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 736 228, 0, 0, 232, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 224,225, 737 0, 235,238, 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0, 738 229,231 739 }; 740 741 static const u_int8_t ibm437_chars_32[] = { 742 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 743 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 744 0, 0, 0, 0, 0, 0, 0, 0, 158 745 }; 746 747 static const u_int8_t ibm437_chars_34[] = { 748 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 749 0, 0, 0, 248,250,251, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 750 0, 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 751 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 752 0, 0, 0, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 753 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 0, 0,243, 754 242 755 }; 756 757 static const u_int8_t ibm437_chars_35[] = { 758 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 759 244,245 760 }; 761 762 static const u_int8_t ibm437_chars_37[] = { 763 196,205,179,186, 0, 0, 0, 0, 0, 0, 0, 0, 218,213,214,201, 764 191,184,183,187,192,212,211,200,217,190,189,188,195,198, 0, 0, 765 199, 0, 0, 204,180,181, 0, 0, 182, 0, 0, 185,194, 0, 0, 209, 766 210, 0, 0, 203,193, 0, 0, 207,208, 0, 0, 202,197, 0, 0, 216, 767 0, 0, 215, 0, 0, 0, 0, 0, 0, 0, 0, 206, 0, 0, 0, 0, 768 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 769 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 770 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 771 223, 0, 0, 0, 220, 0, 0, 0, 219, 0, 0, 0, 221, 0, 0, 0, 772 222,176,177,178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 773 254 774 }; 775 776 static const struct wsfont_level2_glyphmap ibm437_level2_0 = 777 { 0, 256, ibm437_chars_0, 1 }; 778 779 static const struct wsfont_level2_glyphmap ibm437_level2_1 = 780 { 146, 1, ibm437_chars_1, 1 }; 781 782 static const struct wsfont_level2_glyphmap ibm437_level2_3 = 783 { 147, 50, ibm437_chars_3, 1 }; 784 785 static const struct wsfont_level2_glyphmap ibm437_level2_32 = 786 { 127, 41, ibm437_chars_32, 1 }; 787 788 static const struct wsfont_level2_glyphmap ibm437_level2_34 = 789 { 5, 97, ibm437_chars_34, 1 }; 790 791 static const struct wsfont_level2_glyphmap ibm437_level2_35 = 792 { 16, 18, ibm437_chars_35, 1 }; 793 794 static const struct wsfont_level2_glyphmap ibm437_level2_37 = 795 { 0, 161, ibm437_chars_37, 1 }; 796 797 static const struct wsfont_level2_glyphmap *ibm437_level1[] = { 798 &ibm437_level2_0, &ibm437_level2_1, NULL, &ibm437_level2_3, 799 NULL, NULL, NULL, NULL, 800 NULL, NULL, NULL, NULL, 801 NULL, NULL, NULL, NULL, 802 NULL, NULL, NULL, NULL, 803 NULL, NULL, NULL, NULL, 804 NULL, NULL, NULL, NULL, 805 NULL, NULL, NULL, NULL, 806 &ibm437_level2_32, NULL, &ibm437_level2_34, &ibm437_level2_35, 807 NULL, &ibm437_level2_37 808 }; 809 810 /* 811 * ISO-8859-7 maps 812 */ 813 static const u_int8_t iso7_chars_0[] = { 814 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 815 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 816 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 817 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 818 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 819 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 820 96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111, 821 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, 822 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, 823 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, 824 160, 0, 0, 163, 0, 0, 166,167,168,169, 0, 171,172,173, 0, 0, 825 176,177,178,179,180, 0, 0, 183, 0, 0, 0, 187, 0, 189 826 }; 827 828 static const u_int8_t iso7_chars_3[] = { 829 182, 0, 184,185,186, 0, 188, 0, 190,191,192,193,194,195,196,197, 830 198,199,200,201,202,203,204,205,206,207,208,209, 0, 211,212,213, 831 214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229, 832 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245, 833 246,247,248,249,250,251,252,253,254, 0, 0, 0, 0, 0, 0, 0, 834 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 835 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181 836 }; 837 838 static const u_int8_t iso7_chars_32[] = { 839 175, 0, 0, 0, 0, 162, 0, 161 840 }; 841 842 static const struct wsfont_level2_glyphmap iso7_level2_0 = 843 { 0, 190, iso7_chars_0, 1 }; 844 845 static const struct wsfont_level2_glyphmap iso7_level2_3 = 846 { 134, 111, iso7_chars_3, 1 }; 847 848 static const struct wsfont_level2_glyphmap iso7_level2_32 = 849 { 20, 8, iso7_chars_32, 1 }; 850 851 static const struct wsfont_level2_glyphmap *iso7_level1[] = { 852 &iso7_level2_0, NULL, NULL, &iso7_level2_3, 853 NULL, NULL, NULL, NULL, 854 NULL, NULL, NULL, NULL, 855 NULL, NULL, NULL, NULL, 856 NULL, NULL, NULL, NULL, 857 NULL, NULL, NULL, NULL, 858 NULL, NULL, NULL, NULL, 859 NULL, NULL, NULL, NULL, 860 &iso7_level2_32 861 }; 862 863 static const struct wsfont_level1_glyphmap encodings[] = { 864 { NULL, 0, 0 }, /* WSDISPLAY_FONTENC_ISO */ 865 { ibm437_level1, 0, 38 }, /* WSDISPLAY_FONTENC_IBM */ 866 { NULL, 0, 0 }, /* WSDISPLAY_FONTENC_PCVT */ 867 { iso7_level1, 0, 33 }, /* WSDISPLAY_FONTENC_ISO7 */ 868 }; 869 870 #define MAX_ENCODING (sizeof(encodings) / sizeof(encodings[0])) 871 872 /* 873 * Remap Unicode character to glyph 874 */ 875 int 876 wsfont_map_unichar(struct wsdisplay_font *font, int c) 877 { 878 const struct wsfont_level1_glyphmap *map1; 879 const struct wsfont_level2_glyphmap *map2; 880 int hi, lo; 881 882 if (font->encoding == WSDISPLAY_FONTENC_ISO) 883 return (c); 884 885 if (font->encoding < 0 || font->encoding >= MAX_ENCODING) 886 return (-1); 887 888 hi = (c >> 8); 889 lo = c & 255; 890 map1 = &encodings[font->encoding]; 891 892 if (hi < map1->base || hi >= map1->base + map1->size) 893 return (-1); 894 895 map2 = map1->level2[hi - map1->base]; 896 897 if (map2 == NULL || lo < map2->base || lo >= map2->base + map2->size) 898 return (-1); 899 900 lo -= map2->base; 901 902 switch(map2->width) { 903 case 1: 904 c = (((const u_int8_t *)map2->chars)[lo]); 905 break; 906 case 2: 907 c = (((const u_int16_t *)map2->chars)[lo]); 908 break; 909 case 4: 910 c = (((const u_int32_t *)map2->chars)[lo]); 911 break; 912 } 913 914 if (c == 0 && lo != 0) 915 return (-1); 916 917 return (c); 918 } 919