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