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