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