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