1 /* $OpenBSD: wsfont.c,v 1.20 2006/08/06 16:00:46 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(luna88k) || !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 */
127 struct 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 */
137 static 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 */
177 static 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
214 static struct font *wsfont_find0(int);
215
216 #if !defined(SMALL_KERNEL) || defined(__alpha__)
217
218 /*
219 * Reverse the bit order of a font
220 */
221 static void wsfont_revbit(struct wsdisplay_font *);
222 static void
wsfont_revbit(font)223 wsfont_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 */
242 static void wsfont_revbyte(struct wsdisplay_font *);
243 static void
wsfont_revbyte(font)244 wsfont_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 */
276 void
277 wsfont_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
296 struct wsdisplay_font *wsfont_rotate_internal(struct wsdisplay_font *);
297
298 struct wsdisplay_font *
wsfont_rotate_internal(struct wsdisplay_font * font)299 wsfont_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
365 int
wsfont_rotate(int cookie)366 wsfont_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 */
391 void
wsfont_init(void)392 wsfont_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 */
410 static struct font *
wsfont_find0(cookie)411 wsfont_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 */
426 int
wsfont_find(name,width,height,stride)427 wsfont_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 */
460 int
wsfont_add(font,copy)461 wsfont_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
512 int
wsfont_remove(cookie)513 wsfont_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 */
557 int
wsfont_lock(cookie,ptr,bitorder,byteorder)558 wsfont_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 */
609 int
wsfont_getflg(cookie,flg,lc)610 wsfont_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 */
630 int
wsfont_unlock(cookie)631 wsfont_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
664 struct 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
670 struct 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
687 static u_int8_t
688 ibm437_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 },
706 ibm437_chars_1[] = {
707 159
708 },
709 ibm437_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 },
715 ibm437_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 },
720 ibm437_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 },
729 ibm437_chars_35[] = {
730 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
731 244,245
732 },
733 ibm437_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
747 static struct wsfont_level2_glyphmap
748 ibm437_level2_0 = { 0, 256, ibm437_chars_0, 1 },
749 ibm437_level2_1 = { 146, 1, ibm437_chars_1, 1 },
750 ibm437_level2_3 = { 147, 50, ibm437_chars_3, 1 },
751 ibm437_level2_32 = { 127, 41, ibm437_chars_32, 1 },
752 ibm437_level2_34 = { 5, 97, ibm437_chars_34, 1 },
753 ibm437_level2_35 = { 16, 18, ibm437_chars_35, 1 },
754 ibm437_level2_37 = { 0, 161, ibm437_chars_37, 1 };
755
756 static 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
774 static u_int8_t
775 iso7_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 },
789 iso7_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 },
798 iso7_chars_32[] = {
799 175, 0, 0, 0, 0, 162, 0, 161
800 };
801
802 static struct wsfont_level2_glyphmap
803 iso7_level2_0 = { 0, 190, iso7_chars_0, 1 },
804 iso7_level2_3 = { 134, 111, iso7_chars_3, 1 },
805 iso7_level2_32 = { 20, 8, iso7_chars_32, 1 };
806
807 static 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 static struct wsfont_level1_glyphmap encodings[] = {
821 { NULL, 0, 0 }, /* WSDISPLAY_FONTENC_ISO */
822 { ibm437_level1, 0, 38 }, /* WSDISPLAY_FONTENC_IBM */
823 { NULL, 0, 0 }, /* WSDISPLAY_FONTENC_PCVT */
824 { iso7_level1, 0, 33 }, /* WSDISPLAY_FONTENC_ISO7 */
825 };
826
827 #define MAX_ENCODING (sizeof(encodings) / sizeof(encodings[0]))
828
829 #endif /* !SMALL_KERNEL */
830
831 /*
832 * Remap Unicode character to glyph
833 */
834 int
wsfont_map_unichar(font,c)835 wsfont_map_unichar(font, c)
836 struct wsdisplay_font *font;
837 int c;
838 {
839 if (font->encoding == WSDISPLAY_FONTENC_ISO)
840 return c;
841 else
842 #if !defined(SMALL_KERNEL)
843 if (font->encoding < 0 || font->encoding > MAX_ENCODING)
844 return (-1);
845 else {
846 int hi = (c >> 8), lo = c & 255;
847 struct wsfont_level1_glyphmap *map1 =
848 &encodings[font->encoding];
849
850 if (hi >= map1->base && hi < map1->base + map1->size) {
851 struct wsfont_level2_glyphmap *map2 =
852 map1->level2[hi - map1->base];
853
854 if (map2 != NULL &&
855 lo >= map2->base && lo < map2->base + map2->size) {
856
857 lo -= map2->base;
858
859 switch(map2->width) {
860 case 1:
861 c = (((u_int8_t *)map2->chars)[lo]);
862 break;
863 case 2:
864 c = (((u_int16_t *)map2->chars)[lo]);
865 break;
866 case 4:
867 c = (((u_int32_t *)map2->chars)[lo]);
868 break;
869 }
870
871 if (c == 0 && lo != 0)
872 return (-1);
873 else
874 return (c);
875
876 } else {
877 return (-1);
878 }
879
880 } else {
881 return (-1);
882 }
883
884 }
885 #else
886 return (-1);
887 #endif /* SMALL_KERNEL */
888 }
889