xref: /openbsd-src/sys/dev/wsfont/wsfont.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: wsfont.c,v 1.1 2001/03/18 04:30:24 nate Exp $ */
2 /* 	$NetBSD: wsfont.c,v 1.17 2001/02/07 13:59:24 ad Exp $	*/
3 
4 /*-
5  * Copyright (c) 1999 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Andrew Doran.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *	This product includes software developed by the NetBSD
22  *	Foundation, Inc. and its contributors.
23  * 4. Neither the name of The NetBSD Foundation nor the names of its
24  *    contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  */
39 
40 #include <sys/cdefs.h>
41 //__KERNEL_RCSID(0, "$NetBSD: wsfont.c,v 1.17 2001/02/07 13:59:24 ad Exp $");
42 
43 #include <sys/types.h>
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/time.h>
47 #include <sys/malloc.h>
48 
49 #include <dev/wscons/wsdisplayvar.h>
50 #include <dev/wscons/wsconsio.h>
51 #include <dev/wsfont/wsfont.h>
52 
53 #undef HAVE_FONT
54 
55 #ifdef FONT_QVSS8x15
56 #define HAVE_FONT 1
57 #include <dev/wsfont/qvss8x15.h>
58 #endif
59 
60 #ifdef FONT_GALLANT12x22
61 #define HAVE_FONT 1
62 #include <dev/wsfont/gallant12x22.h>
63 #endif
64 
65 #ifdef FONT_LUCIDA16x29
66 #define HAVE_FONT 1
67 #include <dev/wsfont/lucida16x29.h>
68 #endif
69 
70 #ifdef FONT_VT220L8x8
71 #define HAVE_FONT 1
72 #include <dev/wsfont/vt220l8x8.h>
73 #endif
74 
75 #ifdef FONT_VT220L8x10
76 #define HAVE_FONT 1
77 #include <dev/wsfont/vt220l8x10.h>
78 #endif
79 
80 #ifdef FONT_SONY8x16
81 #define HAVE_FONT 1
82 #include <dev/wsfont/sony8x16.h>
83 #endif
84 
85 #ifdef FONT_SONY12x24
86 #define HAVE_FONT 1
87 #include <dev/wsfont/sony12x24.h>
88 #endif
89 
90 #ifdef FONT_OMRON12x20
91 #define HAVE_FONT 1
92 #include <dev/wsfont/omron12x20.h>
93 #endif
94 
95 /* Make sure we always have at least one font. */
96 #ifndef HAVE_FONT
97 #define HAVE_FONT 1
98 #define FONT_BOLD8x16 1
99 #endif
100 
101 #ifdef FONT_BOLD8x16
102 #include <dev/wsfont/bold8x16.h>
103 #endif
104 
105 /* Placeholder struct used for linked list */
106 struct font {
107 	struct	font *next;
108 	struct	font *prev;
109 	struct	wsdisplay_font *font;
110 	u_short	lockcount;
111 	u_short	cookie;
112 	u_short	flg;
113 };
114 
115 /* Our list of built-in fonts */
116 static struct font *list, builtin_fonts[] = {
117 #ifdef FONT_BOLD8x16
118 	{ NULL, NULL, &bold8x16, 0, 1, WSFONT_STATIC | WSFONT_BUILTIN  },
119 #endif
120 #ifdef FONT_ISO8x16
121 	{ NULL, NULL, &iso8x16, 0, 2, WSFONT_STATIC | WSFONT_BUILTIN },
122 #endif
123 #ifdef FONT_COURIER11x18
124 	{ NULL, NULL, &courier11x18, 0, 3, WSFONT_STATIC | WSFONT_BUILTIN },
125 #endif
126 #ifdef FONT_GALLANT12x22
127 	{ NULL, NULL, &gallant12x22, 0, 4, WSFONT_STATIC | WSFONT_BUILTIN },
128 #endif
129 #ifdef FONT_LUCIDA16x29
130 	{ NULL, NULL, &lucida16x29, 0, 5, WSFONT_STATIC | WSFONT_BUILTIN },
131 #endif
132 #ifdef FONT_QVSS8x15
133 	{ NULL, NULL, &qvss8x15, 0, 6, WSFONT_STATIC | WSFONT_BUILTIN },
134 #endif
135 #ifdef FONT_VT220L8x8
136 	{ NULL, NULL, &vt220l8x8, 0, 7, WSFONT_STATIC | WSFONT_BUILTIN },
137 #endif
138 #ifdef FONT_VT220L8x10
139 	{ NULL, NULL, &vt220l8x10, 0, 8, WSFONT_STATIC | WSFONT_BUILTIN },
140 #endif
141 #ifdef FONT_SONY8x16
142 	{ NULL, NULL, &sony8x16, 0, 9, WSFONT_STATIC | WSFONT_BUILTIN },
143 #endif
144 #ifdef FONT_SONY12x24
145 	{ NULL, NULL, &sony12x24, 0, 10, WSFONT_STATIC | WSFONT_BUILTIN },
146 #endif
147 #ifdef FONT_OMRON12x20
148 	{ NULL, NULL, &omron12x20, 0, 11, WSFONT_STATIC | WSFONT_BUILTIN },
149 #endif
150 	{ NULL, NULL, NULL, 0 },
151 };
152 
153 /* Reverse the bit order in a byte */
154 static const u_char reverse[256] = {
155 	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
156 	0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
157 	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
158 	0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
159 	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
160 	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
161 	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
162 	0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
163 	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
164 	0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
165 	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
166 	0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
167 	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
168 	0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
169 	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
170 	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
171 	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
172 	0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
173 	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
174 	0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
175 	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
176 	0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
177 	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
178 	0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
179 	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
180 	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
181 	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
182 	0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
183 	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
184 	0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
185 	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
186 	0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
187 };
188 
189 static struct	font *wsfont_find0 __P((int));
190 static void	wsfont_revbit __P((struct wsdisplay_font *));
191 static void	wsfont_revbyte __P((struct wsdisplay_font *));
192 
193 /*
194  * Reverse the bit order of a font
195  */
196 static void
197 wsfont_revbit(font)
198 	struct wsdisplay_font *font;
199 {
200 	u_char *p, *m;
201 
202 	p = (u_char *)font->data;
203 	m = p + font->stride * font->numchars * font->fontheight;
204 
205 	for (; p < m; p++)
206 		*p = reverse[*p];
207 }
208 
209 /*
210  * Reverse the byte order of a font
211  */
212 static void
213 wsfont_revbyte(font)
214 	struct wsdisplay_font *font;
215 {
216 	int x, l, r, nr;
217 	u_char *rp;
218 
219 	if (font->stride == 1)
220 		return;
221 
222 	rp = (u_char *)font->data;
223 	nr = font->numchars * font->fontheight;
224 
225 	while (nr--) {
226 		l = 0;
227 		r = font->stride - 1;
228 
229 		while (l < r) {
230 			x = rp[l];
231 			rp[l] = rp[r];
232 			rp[r] = x;
233 			l++, r--;
234 		}
235 
236 		rp += font->stride;
237 	}
238 }
239 
240 /*
241  * Enumarate the list of fonts
242  */
243 void
244 wsfont_enum(cb)
245 	void (*cb) __P((char *, int, int, int));
246 {
247 	struct wsdisplay_font *f;
248 	struct font *ent;
249 	int s;
250 
251 	s = splhigh();
252 
253 	for (ent = list; ent; ent = ent->next) {
254 		f = ent->font;
255 		cb(f->name, f->fontwidth, f->fontheight, f->stride);
256 	}
257 
258 	splx(s);
259 }
260 
261 /*
262  * Initialize list with WSFONT_BUILTIN fonts
263  */
264 void
265 wsfont_init(void)
266 {
267 	static int again;
268 	int i;
269 
270 	if (again != 0)
271 		return;
272 	again = 1;
273 
274 	for (i = 0; builtin_fonts[i].font != NULL; i++) {
275 		builtin_fonts[i].next = list;
276 		list = &builtin_fonts[i];
277 	}
278 }
279 
280 /*
281  * Find a font by cookie. Called at splhigh.
282  */
283 static struct font *
284 wsfont_find0(cookie)
285 	int cookie;
286 {
287 	struct font *ent;
288 
289 	for (ent = list; ent != NULL; ent = ent->next)
290 		if (ent->cookie == cookie)
291 			return (ent);
292 
293 	return (NULL);
294 }
295 
296 /*
297  * Find a font.
298  */
299 int
300 wsfont_find(name, width, height, stride)
301 	char *name;
302 	int width, height, stride;
303 {
304 	struct font *ent;
305 	int s;
306 
307 	s = splhigh();
308 
309 	for (ent = list; ent != NULL; ent = ent->next) {
310 		if (height != 0 && ent->font->fontheight != height)
311 			continue;
312 
313 		if (width != 0 && ent->font->fontwidth != width)
314 			continue;
315 
316 		if (stride != 0 && ent->font->stride != stride)
317 			continue;
318 
319 		if (name != NULL && strcmp(ent->font->name, name) != 0)
320 			continue;
321 
322 		splx(s);
323 		return (ent->cookie);
324 	}
325 
326 	splx(s);
327 	return (-1);
328 }
329 
330 /*
331  * Add a font to the list.
332  */
333 #ifdef notyet
334 int
335 wsfont_add(font, copy)
336 	struct wsdisplay_font *font;
337 	int copy;
338 {
339 	static int cookiegen = 666;
340 	struct font *ent;
341 	size_t size;
342 	int s;
343 
344 	s = splhigh();
345 
346 	/* Don't allow exact duplicates */
347 	if (wsfont_find(font->name, font->fontwidth, font->fontheight,
348 	    font->stride) >= 0) {
349 		splx(s);
350 		return (-1);
351 	}
352 
353 	MALLOC(ent, struct font *, sizeof *ent, M_DEVBUF, M_WAITOK);
354 
355 	ent->lockcount = 0;
356 	ent->flg = 0;
357 	ent->cookie = cookiegen++;
358 	ent->next = list;
359 	ent->prev = NULL;
360 
361 	/* Is this font statically allocated? */
362 	if (!copy) {
363 		ent->font = font;
364 		ent->flg = WSFONT_STATIC;
365 	} else {
366 		MALLOC(ent->font, struct wsdisplay_font *, sizeof *ent->font,
367 		    M_DEVBUF, M_WAITOK);
368 		memcpy(ent->font, font, sizeof(*ent->font));
369 
370 		size = font->fontheight * font->numchars * font->stride;
371 		MALLOC(ent->font->data, void *, size, M_DEVBUF, M_WAITOK);
372 		memcpy(ent->font->data, font->data, size);
373 		ent->flg = 0;
374 	}
375 
376 	/* Now link into the list and return */
377 	list = ent;
378 	splx(s);
379 	return (0);
380 }
381 #endif
382 
383 /*
384  * Remove a font.
385  */
386 #ifdef notyet
387 int
388 wsfont_remove(cookie)
389 	int cookie;
390 {
391 	struct font *ent;
392 	int s;
393 
394 	s = splhigh();
395 
396 	if ((ent = wsfont_find0(cookie)) == NULL) {
397 		splx(s);
398 		return (-1);
399 	}
400 
401 	if ((ent->flg & WSFONT_BUILTIN) != 0 || ent->lockcount != 0) {
402 		splx(s);
403 		return (-1);
404 	}
405 
406 	/* Don't free statically allocated font data */
407 	if ((ent->flg & WSFONT_STATIC) != 0) {
408 		FREE(ent->font->data, M_DEVBUF);
409 		FREE(ent->font, M_DEVBUF);
410 	}
411 
412 	/* Remove from list, free entry */
413 	if (ent->prev)
414 		ent->prev->next = ent->next;
415 	else
416 		list = ent->next;
417 
418 	if (ent->next)
419 		ent->next->prev = ent->prev;
420 
421 	FREE(ent, M_DEVBUF);
422 	splx(s);
423 	return (0);
424 }
425 #endif
426 
427 /*
428  * Lock a given font and return new lockcount. This fails if the cookie
429  * is invalid, or if the font is already locked and the bit/byte order
430  * requested by the caller differs.
431  */
432 int
433 wsfont_lock(cookie, ptr, bitorder, byteorder)
434 	int cookie;
435 	struct wsdisplay_font **ptr;
436 	int bitorder, byteorder;
437 {
438 	struct font *ent;
439 	int s, lc;
440 
441 	s = splhigh();
442 
443 	if ((ent = wsfont_find0(cookie)) != NULL) {
444 		if (bitorder && bitorder != ent->font->bitorder) {
445 			if (ent->lockcount) {
446 				splx(s);
447 				return (-1);
448 			}
449 			wsfont_revbit(ent->font);
450 			ent->font->bitorder = bitorder;
451 		}
452 
453 		if (byteorder && byteorder != ent->font->byteorder) {
454 			if (ent->lockcount) {
455 				splx(s);
456 				return (-1);
457 			}
458 			wsfont_revbyte(ent->font);
459 			ent->font->byteorder = byteorder;
460 		}
461 
462 		lc = ++ent->lockcount;
463 		*ptr = ent->font;
464 	} else
465 		lc = -1;
466 
467 	splx(s);
468 	return (lc);
469 }
470 
471 /*
472  * Get font flags and lockcount.
473  */
474 int
475 wsfont_getflg(cookie, flg, lc)
476 	int cookie, *flg, *lc;
477 {
478 	struct font *ent;
479 	int s;
480 
481 	s = splhigh();
482 
483 	if ((ent = wsfont_find0(cookie)) != NULL) {
484 		*flg = ent->flg;
485 		*lc = ent->lockcount;
486 	}
487 
488 	splx(s);
489 	return (ent != NULL ? 0 : -1);
490 }
491 
492 /*
493  * Unlock a given font and return new lockcount.
494  */
495 int
496 wsfont_unlock(cookie)
497 	int cookie;
498 {
499 	struct font *ent;
500 	int s, lc;
501 
502 	s = splhigh();
503 
504 	if ((ent = wsfont_find0(cookie)) != NULL) {
505 		if (ent->lockcount == 0)
506 			panic("wsfont_unlock: font not locked\n");
507 		lc = --ent->lockcount;
508 	} else
509 		lc = -1;
510 
511 	splx(s);
512 	return (lc);
513 }
514 
515 
516 /*
517  * Unicode to font encoding mappings
518  */
519 
520 /*
521  * To save memory, font encoding tables use a two level lookup.
522  * First the high byte of the Unicode is used to lookup the level 2
523  * table, then the low byte indexes that table.  Level 2 tables that are
524  * not needed are omitted (NULL), and both level 1 and level 2 tables
525  * have base and size attributes to keep their size down.
526  */
527 
528 struct wsfont_level1_glyphmap {
529 	struct wsfont_level2_glyphmap **level2;
530 	int base;	/* High byte for first level2 entry	*/
531 	int size;	/* Number of level2 entries		*/
532 };
533 
534 struct wsfont_level2_glyphmap {
535 	int base;	/* Low byte for first character		*/
536 	int size;	/* Number of characters			*/
537 	void *chars;	/* Pointer to character number entries  */
538 	int width;	/* Size of each entry in bytes (1,2,4)  */
539 };
540 
541 #define null16			\
542 	NULL, NULL, NULL, NULL,	\
543 	NULL, NULL, NULL, NULL,	\
544 	NULL, NULL, NULL, NULL,	\
545 	NULL, NULL, NULL, NULL
546 
547 /*
548  * IBM 437 maps
549  */
550 
551 static u_int8_t
552 ibm437_chars_0[] = {
553 	 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
554 	16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
555 	32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
556 	48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
557 	64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
558 	80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
559 	96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,
560 	112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
561 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
562 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
563 	255,173,155,156, 0, 157, 0,  0,  0,  0, 166,174,170, 0,  0,  0,
564 	 0, 241,253, 0,  0,  0,  0, 249, 0,  0, 167,175,172,171, 0, 168,
565 	 0,  0,  0,  0, 142,143,146,128, 0, 144, 0,  0,  0,  0,  0,  0,
566 	 0, 165, 0,  0,  0,  0, 153, 0,  0,  0,  0,  0, 154, 0,  0,  0,
567 	133,160,131, 0, 132,134,145,135,138,130,136,137,141,161,140,139,
568 	 0, 164,149,162,147, 0, 148,246, 0, 151,163,150,129, 0,  0, 152
569 },
570 ibm437_chars_1[] = {
571 	159
572 },
573 ibm437_chars_3[] = {
574 	226, 0,  0,  0,  0, 233, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
575 	228, 0,  0, 232, 0,  0, 234, 0,  0,  0,  0,  0,  0,  0, 224,225,
576 	 0, 235,238, 0,  0,  0,  0,  0,  0, 230, 0,  0,  0, 227, 0,  0,
577 	229,231
578 },
579 ibm437_chars_32[] = {
580 	252, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  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, 158
583 },
584 ibm437_chars_34[] = {
585 	237, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
586 	 0,  0,  0, 248,250,251, 0,  0,  0, 236, 0,  0,  0,  0,  0,  0,
587 	 0,  0,  0,  0, 239, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
588 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
589 	 0,  0,  0, 247, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
590 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,240,  0,  0,243,
591 	242
592 },
593 ibm437_chars_35[] = {
594 	169, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
595 	244,245
596 },
597 ibm437_chars_37[] = {
598 	196,205,179,186, 0,  0,  0,  0,  0,  0,  0,  0, 218,213,214,201,
599 	191,184,183,187,192,212,211,200,217,190,189,188,195,198, 0,  0,
600 	199, 0,  0, 204,180,181, 0,  0, 182, 0,  0, 185,194, 0,  0, 209,
601 	210, 0,  0, 203,193, 0,  0, 207,208, 0,  0, 202,197, 0,  0, 216,
602 	 0,  0, 215, 0,  0,  0,  0,  0,  0,  0,  0, 206, 0,  0,  0,  0,
603 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
604 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
605 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
606 	223, 0,  0,  0, 220, 0,  0,  0, 219, 0,  0,  0, 221, 0,  0,  0,
607 	222,176,177,178, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
608 	254
609 };
610 
611 static struct wsfont_level2_glyphmap
612 ibm437_level2_0 = { 0, 256, ibm437_chars_0, 1 },
613 ibm437_level2_1 = { 146, 1, ibm437_chars_1, 1 },
614 ibm437_level2_3 = { 147, 50, ibm437_chars_3, 1 },
615 ibm437_level2_32 = { 127, 41, ibm437_chars_32, 1 },
616 ibm437_level2_34 = { 5, 97, ibm437_chars_34, 1 },
617 ibm437_level2_35 = { 16, 18, ibm437_chars_35, 1 },
618 ibm437_level2_37 = { 0, 161, ibm437_chars_37, 1 };
619 
620 static struct wsfont_level2_glyphmap *ibm437_level1[] = {
621 	&ibm437_level2_0, &ibm437_level2_1, NULL, &ibm437_level2_3,
622 	NULL, NULL, NULL, NULL,
623 	NULL, NULL, NULL, NULL,
624 	NULL, NULL, NULL, NULL,
625 	NULL, NULL, NULL, NULL,
626 	NULL, NULL, NULL, NULL,
627 	NULL, NULL, NULL, NULL,
628 	NULL, NULL, NULL, NULL,
629 	&ibm437_level2_32, NULL, &ibm437_level2_34, &ibm437_level2_35,
630 	NULL, &ibm437_level2_37
631 };
632 
633 
634 /*
635  * ISO-8859-7 maps
636  */
637 
638 static u_int8_t
639 iso7_chars_0[] = {
640 	 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
641 	16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
642 	32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
643 	48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
644 	64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
645 	80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
646 	96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,
647 	112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
648 	128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
649 	144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
650 	160, 0,  0, 163, 0,  0, 166,167,168,169, 0, 171,172,173, 0,  0,
651 	176,177,178,179,180, 0,  0, 183, 0,  0,  0, 187, 0, 189
652 },
653 iso7_chars_3[] = {
654 	182, 0, 184,185,186, 0, 188, 0, 190,191,192,193,194,195,196,197,
655 	198,199,200,201,202,203,204,205,206,207,208,209, 0, 211,212,213,
656 	214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,
657 	230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,
658 	246,247,248,249,250,251,252,253,254, 0,  0,  0,  0,  0,  0,  0,
659 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
660 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 181
661 },
662 iso7_chars_32[] = {
663 	175, 0,  0,  0,  0, 162, 0, 161
664 };
665 
666 static struct wsfont_level2_glyphmap
667 iso7_level2_0 = { 0, 190, iso7_chars_0, 1 },
668 iso7_level2_3 = { 134, 111, iso7_chars_3, 1 },
669 iso7_level2_32 = { 20, 8, iso7_chars_32, 1 };
670 
671 static struct wsfont_level2_glyphmap *iso7_level1[] = {
672 	&iso7_level2_0, NULL, NULL, &iso7_level2_3,
673 	NULL, NULL, NULL, NULL,
674 	NULL, NULL, NULL, NULL,
675 	NULL, NULL, NULL, NULL,
676 	NULL, NULL, NULL, NULL,
677 	NULL, NULL, NULL, NULL,
678 	NULL, NULL, NULL, NULL,
679 	NULL, NULL, NULL, NULL,
680 	&iso7_level2_32
681 };
682 
683 
684 /*
685  * SONY maps
686  */
687 
688 static u_int8_t
689 sony_chars_0[] = {
690 	 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
691 	16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
692 	32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
693 	48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
694 	64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
695 	80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
696 	96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,
697 	112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
698 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
699 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
700 	128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
701 	144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
702 	160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
703 	176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
704 	192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
705 	208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223
706 };
707 static u_int16_t
708 sony_chars_255[] = {
709 	225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,
710 	241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,
711 	257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,
712 	273,274,275,276,277,278,279,280,281,282,283,284,285,286,287
713 };
714 
715 static struct wsfont_level2_glyphmap
716 sony_level2_0 = { 0, 256, sony_chars_0, 1 },
717 sony_level2_255 = { 97, 63, sony_chars_255, 2 };
718 
719 static struct wsfont_level2_glyphmap *sony_level1[] = {
720 	&sony_level2_0, NULL, NULL, NULL,
721 	NULL, NULL, NULL, NULL,
722 	NULL, NULL, NULL, NULL,
723 	NULL, NULL, NULL, NULL,
724 	null16, null16, null16, null16,
725 	null16, null16, null16, null16,
726 	null16, null16, null16, null16,
727 	null16, null16,
728 	NULL, NULL, NULL, NULL,
729 	NULL, NULL, NULL, NULL,
730 	NULL, NULL, NULL, NULL,
731 	NULL, NULL, NULL, &sony_level2_255
732 };
733 
734 static struct wsfont_level1_glyphmap encodings[] = {
735 	{ NULL, 0, 0 },			/* WSDISPLAY_FONTENC_ISO */
736 	{ ibm437_level1, 0, 38 },	/* WSDISPLAY_FONTENC_IBM */
737 	{ NULL, 0, 0 },			/* WSDISPLAY_FONTENC_PCVT */
738 	{ iso7_level1, 0, 33 },		/* WSDISPLAY_FONTENC_ISO7 */
739 	{ sony_level1, 0, 256 },	/* WSDISPLAY_FONTENC_SONY */
740 };
741 
742 #define MAX_ENCODING WSDISPLAY_FONTENC_SONY
743 
744 /*
745  * Remap Unicode character to glyph
746  */
747 int
748 wsfont_map_unichar(font, c)
749 	struct wsdisplay_font *font;
750 	int c;
751 {
752 	if (font->encoding == WSDISPLAY_FONTENC_ISO) {
753 
754 		return c;
755 
756 	} else if (font->encoding < 0 || font->encoding > MAX_ENCODING) {
757 
758 		return (-1);
759 
760 	} else {
761 
762 		int hi = (c >> 8), lo = c & 255;
763 		struct wsfont_level1_glyphmap *map1 =
764 			&encodings[font->encoding];
765 
766 		if (hi >= map1->base && hi < map1->base + map1->size) {
767 			struct wsfont_level2_glyphmap *map2 =
768 			  map1->level2[hi - map1->base];
769 
770 			if (map2 != NULL &&
771 			    lo >= map2->base && hi < map2->base + map2->size) {
772 
773 			  	lo -= map2->base;
774 
775 				switch(map2->width) {
776 				 case 1:
777 				   c = (((u_int8_t *)map2->chars)[lo]);
778 				   break;
779 				 case 2:
780 				   c = (((u_int16_t *)map2->chars)[lo]);
781 				   break;
782 				 case 4:
783 				   c = (((u_int32_t *)map2->chars)[lo]);
784 				   break;
785 				}
786 
787 				if (c == 0 && lo != 0)
788 					return (-1);
789 				else
790 					return (c);
791 
792 			} else {
793 				return (-1);
794 			}
795 
796 		} else {
797 			return (-1);
798 		}
799 
800 	}
801 
802 }
803