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