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