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