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