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