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