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