Home | History | Annotate | Line # | Download | only in wsfont
wsfont.c revision 1.20.2.1
      1 /* 	$NetBSD: wsfont.c,v 1.20.2.1 2001/09/13 01:16:15 thorpej 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.20.2.1 2001/09/13 01:16:15 thorpej 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 	for (; p < m; p++)
    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 int
    298 wsfont_matches(font, name, width, height, stride)
    299 	struct wsdisplay_font *font;
    300 	char *name;
    301 	int width, height, stride;
    302 {
    303 
    304 	if (height != 0 && font->fontheight != height)
    305 		return (0);
    306 
    307 	if (width != 0 && font->fontwidth != width)
    308 		return (0);
    309 
    310 	if (stride != 0 && font->stride != stride)
    311 		return (0);
    312 
    313 	if (name != NULL && strcmp(font->name, name) != 0)
    314 		return (0);
    315 
    316 	return (1);
    317 }
    318 
    319 /*
    320  * Find a font.
    321  */
    322 int
    323 wsfont_find(name, width, height, stride)
    324 	char *name;
    325 	int width, height, stride;
    326 {
    327 	struct font *ent;
    328 	int s;
    329 
    330 	s = splhigh();
    331 
    332 	for (ent = list; ent != NULL; ent = ent->next) {
    333 		if (wsfont_matches(ent->font, name, width, height, stride)) {
    334 			splx(s);
    335 			return (ent->cookie);
    336 		}
    337 	}
    338 
    339 	splx(s);
    340 	return (-1);
    341 }
    342 
    343 /*
    344  * Add a font to the list.
    345  */
    346 int
    347 wsfont_add(font, copy)
    348 	struct wsdisplay_font *font;
    349 	int copy;
    350 {
    351 	static int cookiegen = 666;
    352 	struct font *ent;
    353 	size_t size;
    354 	int s;
    355 
    356 	s = splhigh();
    357 
    358 	/* Don't allow exact duplicates */
    359 	if (wsfont_find(font->name, font->fontwidth, font->fontheight,
    360 	    font->stride) >= 0) {
    361 		splx(s);
    362 		return (EEXIST);
    363 	}
    364 
    365 	MALLOC(ent, struct font *, sizeof *ent, M_DEVBUF, M_WAITOK);
    366 
    367 	ent->lockcount = 0;
    368 	ent->flg = 0;
    369 	ent->cookie = cookiegen++;
    370 	ent->next = list;
    371 	ent->prev = NULL;
    372 
    373 	/* Is this font statically allocated? */
    374 	if (!copy) {
    375 		ent->font = font;
    376 		ent->flg = WSFONT_STATIC;
    377 	} else {
    378 		MALLOC(ent->font, struct wsdisplay_font *, sizeof *ent->font,
    379 		    M_DEVBUF, M_WAITOK);
    380 		memcpy(ent->font, font, sizeof(*ent->font));
    381 
    382 		size = font->fontheight * font->numchars * font->stride;
    383 		MALLOC(ent->font->data, void *, size, M_DEVBUF, M_WAITOK);
    384 		memcpy(ent->font->data, font->data, size);
    385 		MALLOC(ent->font->name, char *, strlen(font->name) + 1,
    386 		       M_DEVBUF, M_WAITOK);
    387 		strcpy(ent->font->name, font->name);
    388 		ent->flg = 0;
    389 	}
    390 
    391 	/* Now link into the list and return */
    392 	list = ent;
    393 	splx(s);
    394 	return (0);
    395 }
    396 
    397 /*
    398  * Remove a font.
    399  */
    400 int
    401 wsfont_remove(cookie)
    402 	int cookie;
    403 {
    404 	struct font *ent;
    405 	int s;
    406 
    407 	s = splhigh();
    408 
    409 	if ((ent = wsfont_find0(cookie)) == NULL) {
    410 		splx(s);
    411 		return (ENOENT);
    412 	}
    413 
    414 	if ((ent->flg & WSFONT_BUILTIN) != 0 || ent->lockcount != 0) {
    415 		splx(s);
    416 		return (EBUSY);
    417 	}
    418 
    419 	/* Don't free statically allocated font data */
    420 	if ((ent->flg & WSFONT_STATIC) != 0) {
    421 		FREE(ent->font->data, M_DEVBUF);
    422 		FREE(ent->font->name, M_DEVBUF);
    423 		FREE(ent->font, M_DEVBUF);
    424 	}
    425 
    426 	/* Remove from list, free entry */
    427 	if (ent->prev)
    428 		ent->prev->next = ent->next;
    429 	else
    430 		list = ent->next;
    431 
    432 	if (ent->next)
    433 		ent->next->prev = ent->prev;
    434 
    435 	FREE(ent, M_DEVBUF);
    436 	splx(s);
    437 	return (0);
    438 }
    439 
    440 /*
    441  * Lock a given font and return new lockcount. This fails if the cookie
    442  * is invalid, or if the font is already locked and the bit/byte order
    443  * requested by the caller differs.
    444  */
    445 int
    446 wsfont_lock(cookie, ptr, bitorder, byteorder)
    447 	int cookie;
    448 	struct wsdisplay_font **ptr;
    449 	int bitorder, byteorder;
    450 {
    451 	struct font *ent;
    452 	int s, lc;
    453 
    454 	s = splhigh();
    455 
    456 	if ((ent = wsfont_find0(cookie)) != NULL) {
    457 		if (bitorder && bitorder != ent->font->bitorder) {
    458 			if (ent->lockcount) {
    459 				splx(s);
    460 				return (-1);
    461 			}
    462 			wsfont_revbit(ent->font);
    463 			ent->font->bitorder = bitorder;
    464 		}
    465 
    466 		if (byteorder && byteorder != ent->font->byteorder) {
    467 			if (ent->lockcount) {
    468 				splx(s);
    469 				return (-1);
    470 			}
    471 			wsfont_revbyte(ent->font);
    472 			ent->font->byteorder = byteorder;
    473 		}
    474 
    475 		lc = ++ent->lockcount;
    476 		*ptr = ent->font;
    477 	} else
    478 		lc = -1;
    479 
    480 	splx(s);
    481 	return (lc);
    482 }
    483 
    484 /*
    485  * Get font flags and lockcount.
    486  */
    487 int
    488 wsfont_getflg(cookie, flg, lc)
    489 	int cookie, *flg, *lc;
    490 {
    491 	struct font *ent;
    492 	int s;
    493 
    494 	s = splhigh();
    495 
    496 	if ((ent = wsfont_find0(cookie)) != NULL) {
    497 		*flg = ent->flg;
    498 		*lc = ent->lockcount;
    499 	}
    500 
    501 	splx(s);
    502 	return (ent != NULL ? 0 : -1);
    503 }
    504 
    505 /*
    506  * Unlock a given font and return new lockcount.
    507  */
    508 int
    509 wsfont_unlock(cookie)
    510 	int cookie;
    511 {
    512 	struct font *ent;
    513 	int s, lc;
    514 
    515 	s = splhigh();
    516 
    517 	if ((ent = wsfont_find0(cookie)) != NULL) {
    518 		if (ent->lockcount == 0)
    519 			panic("wsfont_unlock: font not locked\n");
    520 		lc = --ent->lockcount;
    521 	} else
    522 		lc = -1;
    523 
    524 	splx(s);
    525 	return (lc);
    526 }
    527 
    528 
    529 /*
    530  * Unicode to font encoding mappings
    531  */
    532 
    533 /*
    534  * To save memory, font encoding tables use a two level lookup.
    535  * First the high byte of the Unicode is used to lookup the level 2
    536  * table, then the low byte indexes that table.  Level 2 tables that are
    537  * not needed are omitted (NULL), and both level 1 and level 2 tables
    538  * have base and size attributes to keep their size down.
    539  */
    540 
    541 struct wsfont_level1_glyphmap {
    542 	struct wsfont_level2_glyphmap **level2;
    543 	int base;	/* High byte for first level2 entry	*/
    544 	int size;	/* Number of level2 entries		*/
    545 };
    546 
    547 struct wsfont_level2_glyphmap {
    548 	int base;	/* Low byte for first character		*/
    549 	int size;	/* Number of characters			*/
    550 	void *chars;	/* Pointer to character number entries  */
    551 	int width;	/* Size of each entry in bytes (1,2,4)  */
    552 };
    553 
    554 #define null16			\
    555 	NULL, NULL, NULL, NULL,	\
    556 	NULL, NULL, NULL, NULL,	\
    557 	NULL, NULL, NULL, NULL,	\
    558 	NULL, NULL, NULL, NULL
    559 
    560 /*
    561  * IBM 437 maps
    562  */
    563 
    564 static u_int8_t
    565 ibm437_chars_0[] = {
    566 	 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
    567 	16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
    568 	32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
    569 	48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
    570 	64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
    571 	80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
    572 	96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,
    573 	112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
    574 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    575 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    576 	255,173,155,156, 0, 157, 0,  0,  0,  0, 166,174,170, 0,  0,  0,
    577 	 0, 241,253, 0,  0,  0,  0, 249, 0,  0, 167,175,172,171, 0, 168,
    578 	 0,  0,  0,  0, 142,143,146,128, 0, 144, 0,  0,  0,  0,  0,  0,
    579 	 0, 165, 0,  0,  0,  0, 153, 0,  0,  0,  0,  0, 154, 0,  0,  0,
    580 	133,160,131, 0, 132,134,145,135,138,130,136,137,141,161,140,139,
    581 	 0, 164,149,162,147, 0, 148,246, 0, 151,163,150,129, 0,  0, 152
    582 },
    583 ibm437_chars_1[] = {
    584 	159
    585 },
    586 ibm437_chars_3[] = {
    587 	226, 0,  0,  0,  0, 233, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    588 	228, 0,  0, 232, 0,  0, 234, 0,  0,  0,  0,  0,  0,  0, 224,225,
    589 	 0, 235,238, 0,  0,  0,  0,  0,  0, 230, 0,  0,  0, 227, 0,  0,
    590 	229,231
    591 },
    592 ibm437_chars_32[] = {
    593 	252, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    594 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    595 	 0,  0,  0,  0,  0,  0,  0,  0, 158
    596 },
    597 ibm437_chars_34[] = {
    598 	237, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    599 	 0,  0,  0, 248,250,251, 0,  0,  0, 236, 0,  0,  0,  0,  0,  0,
    600 	 0,  0,  0,  0, 239, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    601 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    602 	 0,  0,  0, 247, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    603 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,240,  0,  0,243,
    604 	242
    605 },
    606 ibm437_chars_35[] = {
    607 	169, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    608 	244,245
    609 },
    610 ibm437_chars_37[] = {
    611 	196,205,179,186, 0,  0,  0,  0,  0,  0,  0,  0, 218,213,214,201,
    612 	191,184,183,187,192,212,211,200,217,190,189,188,195,198, 0,  0,
    613 	199, 0,  0, 204,180,181, 0,  0, 182, 0,  0, 185,194, 0,  0, 209,
    614 	210, 0,  0, 203,193, 0,  0, 207,208, 0,  0, 202,197, 0,  0, 216,
    615 	 0,  0, 215, 0,  0,  0,  0,  0,  0,  0,  0, 206, 0,  0,  0,  0,
    616 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    617 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    618 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    619 	223, 0,  0,  0, 220, 0,  0,  0, 219, 0,  0,  0, 221, 0,  0,  0,
    620 	222,176,177,178, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    621 	254
    622 };
    623 
    624 static struct wsfont_level2_glyphmap
    625 ibm437_level2_0 = { 0, 256, ibm437_chars_0, 1 },
    626 ibm437_level2_1 = { 146, 1, ibm437_chars_1, 1 },
    627 ibm437_level2_3 = { 147, 50, ibm437_chars_3, 1 },
    628 ibm437_level2_32 = { 127, 41, ibm437_chars_32, 1 },
    629 ibm437_level2_34 = { 5, 97, ibm437_chars_34, 1 },
    630 ibm437_level2_35 = { 16, 18, ibm437_chars_35, 1 },
    631 ibm437_level2_37 = { 0, 161, ibm437_chars_37, 1 };
    632 
    633 static struct wsfont_level2_glyphmap *ibm437_level1[] = {
    634 	&ibm437_level2_0, &ibm437_level2_1, NULL, &ibm437_level2_3,
    635 	NULL, NULL, NULL, NULL,
    636 	NULL, NULL, NULL, NULL,
    637 	NULL, NULL, NULL, NULL,
    638 	NULL, NULL, NULL, NULL,
    639 	NULL, NULL, NULL, NULL,
    640 	NULL, NULL, NULL, NULL,
    641 	NULL, NULL, NULL, NULL,
    642 	&ibm437_level2_32, NULL, &ibm437_level2_34, &ibm437_level2_35,
    643 	NULL, &ibm437_level2_37
    644 };
    645 
    646 
    647 /*
    648  * ISO-8859-7 maps
    649  */
    650 
    651 static u_int8_t
    652 iso7_chars_0[] = {
    653 	 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
    654 	16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
    655 	32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
    656 	48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
    657 	64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
    658 	80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
    659 	96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,
    660 	112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
    661 	128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
    662 	144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
    663 	160, 0,  0, 163, 0,  0, 166,167,168,169, 0, 171,172,173, 0,  0,
    664 	176,177,178,179,180, 0,  0, 183, 0,  0,  0, 187, 0, 189
    665 },
    666 iso7_chars_3[] = {
    667 	182, 0, 184,185,186, 0, 188, 0, 190,191,192,193,194,195,196,197,
    668 	198,199,200,201,202,203,204,205,206,207,208,209, 0, 211,212,213,
    669 	214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,
    670 	230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,
    671 	246,247,248,249,250,251,252,253,254, 0,  0,  0,  0,  0,  0,  0,
    672 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    673 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 181
    674 },
    675 iso7_chars_32[] = {
    676 	175, 0,  0,  0,  0, 162, 0, 161
    677 };
    678 
    679 static struct wsfont_level2_glyphmap
    680 iso7_level2_0 = { 0, 190, iso7_chars_0, 1 },
    681 iso7_level2_3 = { 134, 111, iso7_chars_3, 1 },
    682 iso7_level2_32 = { 20, 8, iso7_chars_32, 1 };
    683 
    684 static struct wsfont_level2_glyphmap *iso7_level1[] = {
    685 	&iso7_level2_0, NULL, NULL, &iso7_level2_3,
    686 	NULL, NULL, NULL, NULL,
    687 	NULL, NULL, NULL, NULL,
    688 	NULL, NULL, NULL, NULL,
    689 	NULL, NULL, NULL, NULL,
    690 	NULL, NULL, NULL, NULL,
    691 	NULL, NULL, NULL, NULL,
    692 	NULL, NULL, NULL, NULL,
    693 	&iso7_level2_32
    694 };
    695 
    696 static struct wsfont_level1_glyphmap encodings[] = {
    697 	{ NULL, 0, 0 },			/* WSDISPLAY_FONTENC_ISO */
    698 	{ ibm437_level1, 0, 38 },	/* WSDISPLAY_FONTENC_IBM */
    699 	{ NULL, 0, 0 },			/* WSDISPLAY_FONTENC_PCVT */
    700 	{ iso7_level1, 0, 33 },		/* WSDISPLAY_FONTENC_ISO7 */
    701 };
    702 
    703 #define MAX_ENCODING (sizeof(encodings) / sizeof(encodings[0]))
    704 
    705 /*
    706  * Remap Unicode character to glyph
    707  */
    708 int
    709 wsfont_map_unichar(font, c)
    710 	struct wsdisplay_font *font;
    711 	int c;
    712 {
    713 	if (font->encoding == WSDISPLAY_FONTENC_ISO) {
    714 
    715 		return c;
    716 
    717 	} else if (font->encoding < 0 || font->encoding > MAX_ENCODING) {
    718 
    719 		return (-1);
    720 
    721 	} else {
    722 
    723 		int hi = (c >> 8), lo = c & 255;
    724 		struct wsfont_level1_glyphmap *map1 =
    725 			&encodings[font->encoding];
    726 
    727 		if (hi >= map1->base && hi < map1->base + map1->size) {
    728 			struct wsfont_level2_glyphmap *map2 =
    729 			  map1->level2[hi - map1->base];
    730 
    731 			if (map2 != NULL &&
    732 			    lo >= map2->base && lo < map2->base + map2->size) {
    733 
    734 			  	lo -= map2->base;
    735 
    736 				switch(map2->width) {
    737 				 case 1:
    738 				   c = (((u_int8_t *)map2->chars)[lo]);
    739 				   break;
    740 				 case 2:
    741 				   c = (((u_int16_t *)map2->chars)[lo]);
    742 				   break;
    743 				 case 4:
    744 				   c = (((u_int32_t *)map2->chars)[lo]);
    745 				   break;
    746 				}
    747 
    748 				if (c == 0 && lo != 0)
    749 					return (-1);
    750 				else
    751 					return (c);
    752 
    753 			} else {
    754 				return (-1);
    755 			}
    756 
    757 		} else {
    758 			return (-1);
    759 		}
    760 
    761 	}
    762 
    763 }
    764