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