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