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