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