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