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