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