wsfont.c revision 1.8
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 */
131struct 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 */
141static 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 */
179static 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
214static struct	font *wsfont_find0(int);
215static void	wsfont_revbit(struct wsdisplay_font *);
216static void	wsfont_revbyte(struct wsdisplay_font *);
217
218/*
219 * Reverse the bit order of a font
220 */
221static void
222wsfont_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 */
237static void
238wsfont_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 */
268void
269wsfont_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 */
289void
290wsfont_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 */
308static struct font *
309wsfont_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 */
324int
325wsfont_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
359int
360wsfont_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
412int
413wsfont_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 */
457int
458wsfont_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 */
499int
500wsfont_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 */
520int
521wsfont_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
553struct 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
559struct 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
576static u_int8_t
577ibm437_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},
595ibm437_chars_1[] = {
596	159
597},
598ibm437_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},
604ibm437_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},
609ibm437_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},
618ibm437_chars_35[] = {
619	169, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
620	244,245
621},
622ibm437_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
636static struct wsfont_level2_glyphmap
637ibm437_level2_0 = { 0, 256, ibm437_chars_0, 1 },
638ibm437_level2_1 = { 146, 1, ibm437_chars_1, 1 },
639ibm437_level2_3 = { 147, 50, ibm437_chars_3, 1 },
640ibm437_level2_32 = { 127, 41, ibm437_chars_32, 1 },
641ibm437_level2_34 = { 5, 97, ibm437_chars_34, 1 },
642ibm437_level2_35 = { 16, 18, ibm437_chars_35, 1 },
643ibm437_level2_37 = { 0, 161, ibm437_chars_37, 1 };
644
645static 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
663static u_int8_t
664iso7_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},
678iso7_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},
687iso7_chars_32[] = {
688	175, 0,  0,  0,  0, 162, 0, 161
689};
690
691static struct wsfont_level2_glyphmap
692iso7_level2_0 = { 0, 190, iso7_chars_0, 1 },
693iso7_level2_3 = { 134, 111, iso7_chars_3, 1 },
694iso7_level2_32 = { 20, 8, iso7_chars_32, 1 };
695
696static 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
713static u_int8_t
714sony_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};
732static u_int16_t
733sony_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
740static struct wsfont_level2_glyphmap
741sony_level2_0 = { 0, 256, sony_chars_0, 1 },
742sony_level2_255 = { 97, 63, sony_chars_255, 2 };
743
744static 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
759static 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 */
772int
773wsfont_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