1 /* $NetBSD: wsfont.c,v 1.35 2003/12/15 15:13:55 tsutsui 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.35 2003/12/15 15:13:55 tsutsui 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_debug("wsfont: font '%s' bito %d byteo %d "
465 "copied to bito %d byteo %d\n",
466 ent->font->name,
467 ent->font->bitorder, ent->font->byteorder,
468 bito, byteo);
469
470 ent = neu;
471 }
472
473 if (bito && bito != ent->font->bitorder) {
474 wsfont_revbit(ent->font);
475 ent->font->bitorder = bito;
476 }
477
478 if (byteo && byteo != ent->font->byteorder) {
479 wsfont_revbyte(ent->font);
480 ent->font->byteorder = byteo;
481 }
482
483 ent->cookie = cookie;
484 }
485
486 ent->lockcount++;
487 *ptr = ent->font;
488 return (0);
489 }
490
491 int
492 wsfont_unlock(int cookie)
493 {
494 struct font *ent;
495
496 if ((ent = wsfont_find0(cookie, 0xffffffff)) == NULL)
497 return (ENOENT);
498
499 if (ent->lockcount == 0)
500 panic("wsfont_unlock: font not locked");
501
502 if (--ent->lockcount == 0 && (ent->flags & WSFONT_COPY) != 0)
503 wsfont_remove(cookie);
504
505 return (0);
506 }
507
508 /*
509 * Unicode to font encoding mappings
510 */
511
512 /*
513 * To save memory, font encoding tables use a two level lookup. First the
514 * high byte of the Unicode is used to lookup the level 2 table, then the
515 * low byte indexes that table. Level 2 tables that are not needed are
516 * omitted (NULL), and both level 1 and level 2 tables have base and size
517 * attributes to keep their size down.
518 */
519
520 struct wsfont_level1_glyphmap {
521 const struct wsfont_level2_glyphmap **level2;
522 int base; /* High byte for first level2 entry */
523 int size; /* Number of level2 entries */
524 };
525
526 struct wsfont_level2_glyphmap {
527 int base; /* Low byte for first character */
528 int size; /* Number of characters */
529 const void *chars; /* Pointer to character number entries */
530 int width; /* Size of each entry in bytes (1,2,4) */
531 };
532
533 #define null16 \
534 NULL, NULL, NULL, NULL, \
535 NULL, NULL, NULL, NULL, \
536 NULL, NULL, NULL, NULL, \
537 NULL, NULL, NULL, NULL
538
539 /*
540 * IBM 437 maps
541 */
542
543 static const u_int8_t ibm437_chars_0[] = {
544 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
545 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
546 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
547 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
548 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
549 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
550 96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,
551 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
552 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
553 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
554 255,173,155,156, 0, 157, 0, 0, 0, 0, 166,174,170, 0, 0, 0,
555 0, 241,253, 0, 0, 0, 0, 249, 0, 0, 167,175,172,171, 0, 168,
556 0, 0, 0, 0, 142,143,146,128, 0, 144, 0, 0, 0, 0, 0, 0,
557 0, 165, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 154, 0, 0, 0,
558 133,160,131, 0, 132,134,145,135,138,130,136,137,141,161,140,139,
559 0, 164,149,162,147, 0, 148,246, 0, 151,163,150,129, 0, 0, 152
560 };
561
562 static const u_int8_t ibm437_chars_1[] = {
563 159
564 };
565
566 static const u_int8_t ibm437_chars_3[] = {
567 226, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
568 228, 0, 0, 232, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 224,225,
569 0, 235,238, 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0,
570 229,231
571 };
572
573 static const u_int8_t ibm437_chars_32[] = {
574 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 158
577 };
578
579 static const u_int8_t ibm437_chars_34[] = {
580 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
581 0, 0, 0, 248,250,251, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0,
582 0, 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
583 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
584 0, 0, 0, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
585 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 0, 0,243,
586 242
587 };
588
589 static const u_int8_t ibm437_chars_35[] = {
590 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
591 244,245
592 };
593
594 static const u_int8_t ibm437_chars_37[] = {
595 196,205,179,186, 0, 0, 0, 0, 0, 0, 0, 0, 218,213,214,201,
596 191,184,183,187,192,212,211,200,217,190,189,188,195,198, 0, 0,
597 199, 0, 0, 204,180,181, 0, 0, 182, 0, 0, 185,194, 0, 0, 209,
598 210, 0, 0, 203,193, 0, 0, 207,208, 0, 0, 202,197, 0, 0, 216,
599 0, 0, 215, 0, 0, 0, 0, 0, 0, 0, 0, 206, 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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
603 223, 0, 0, 0, 220, 0, 0, 0, 219, 0, 0, 0, 221, 0, 0, 0,
604 222,176,177,178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
605 254
606 };
607
608 static const struct wsfont_level2_glyphmap ibm437_level2_0 =
609 { 0, 256, ibm437_chars_0, 1 };
610
611 static const struct wsfont_level2_glyphmap ibm437_level2_1 =
612 { 146, 1, ibm437_chars_1, 1 };
613
614 static const struct wsfont_level2_glyphmap ibm437_level2_3 =
615 { 147, 50, ibm437_chars_3, 1 };
616
617 static const struct wsfont_level2_glyphmap ibm437_level2_32 =
618 { 127, 41, ibm437_chars_32, 1 };
619
620 static const struct wsfont_level2_glyphmap ibm437_level2_34 =
621 { 5, 97, ibm437_chars_34, 1 };
622
623 static const struct wsfont_level2_glyphmap ibm437_level2_35 =
624 { 16, 18, ibm437_chars_35, 1 };
625
626 static const struct wsfont_level2_glyphmap ibm437_level2_37 =
627 { 0, 161, ibm437_chars_37, 1 };
628
629 static const struct wsfont_level2_glyphmap *ibm437_level1[] = {
630 &ibm437_level2_0, &ibm437_level2_1, NULL, &ibm437_level2_3,
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 NULL, NULL, NULL, NULL,
638 &ibm437_level2_32, NULL, &ibm437_level2_34, &ibm437_level2_35,
639 NULL, &ibm437_level2_37
640 };
641
642 /*
643 * ISO-8859-7 maps
644 */
645 static const u_int8_t iso7_chars_0[] = {
646 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
647 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
648 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
649 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
650 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
651 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
652 96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,
653 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
654 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
655 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
656 160, 0, 0, 163, 0, 0, 166,167,168,169, 0, 171,172,173, 0, 0,
657 176,177,178,179,180, 0, 0, 183, 0, 0, 0, 187, 0, 189
658 };
659
660 static const u_int8_t iso7_chars_3[] = {
661 182, 0, 184,185,186, 0, 188, 0, 190,191,192,193,194,195,196,197,
662 198,199,200,201,202,203,204,205,206,207,208,209, 0, 211,212,213,
663 214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,
664 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,
665 246,247,248,249,250,251,252,253,254, 0, 0, 0, 0, 0, 0, 0,
666 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
667 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181
668 };
669
670 static const u_int8_t iso7_chars_32[] = {
671 175, 0, 0, 0, 0, 162, 0, 161
672 };
673
674 static const struct wsfont_level2_glyphmap iso7_level2_0 =
675 { 0, 190, iso7_chars_0, 1 };
676
677 static const struct wsfont_level2_glyphmap iso7_level2_3 =
678 { 134, 111, iso7_chars_3, 1 };
679
680 static const struct wsfont_level2_glyphmap iso7_level2_32 =
681 { 20, 8, iso7_chars_32, 1 };
682
683 static const struct wsfont_level2_glyphmap *iso7_level1[] = {
684 &iso7_level2_0, NULL, NULL, &iso7_level2_3,
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 NULL, NULL, NULL, NULL,
692 &iso7_level2_32
693 };
694
695 static const struct wsfont_level1_glyphmap encodings[] = {
696 { NULL, 0, 0 }, /* WSDISPLAY_FONTENC_ISO */
697 { ibm437_level1, 0, 38 }, /* WSDISPLAY_FONTENC_IBM */
698 { NULL, 0, 0 }, /* WSDISPLAY_FONTENC_PCVT */
699 { iso7_level1, 0, 33 }, /* WSDISPLAY_FONTENC_ISO7 */
700 };
701
702 #define MAX_ENCODING (sizeof(encodings) / sizeof(encodings[0]))
703
704 /*
705 * Remap Unicode character to glyph
706 */
707 int
708 wsfont_map_unichar(struct wsdisplay_font *font, int c)
709 {
710 const struct wsfont_level1_glyphmap *map1;
711 const struct wsfont_level2_glyphmap *map2;
712 int hi, lo;
713
714 if (font->encoding == WSDISPLAY_FONTENC_ISO)
715 return (c);
716
717 if (font->encoding < 0 || font->encoding > MAX_ENCODING)
718 return (-1);
719
720 hi = (c >> 8);
721 lo = c & 255;
722 map1 = &encodings[font->encoding];
723
724 if (hi < map1->base || hi >= map1->base + map1->size)
725 return (-1);
726
727 map2 = map1->level2[hi - map1->base];
728
729 if (map2 == NULL || lo < map2->base || lo >= map2->base + map2->size)
730 return (-1);
731
732 lo -= map2->base;
733
734 switch(map2->width) {
735 case 1:
736 c = (((const u_int8_t *)map2->chars)[lo]);
737 break;
738 case 2:
739 c = (((const u_int16_t *)map2->chars)[lo]);
740 break;
741 case 4:
742 c = (((const u_int32_t *)map2->chars)[lo]);
743 break;
744 }
745
746 if (c == 0 && lo != 0)
747 return (-1);
748
749 return (c);
750 }
Cache object: 5cc842a59a50153823f1a2b508f47cdc
|