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