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