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