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