wsfont.c revision 1.28 1 /* $NetBSD: wsfont.c,v 1.28 2002/03/21 03:26:55 enami 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.28 2002/03/21 03:26:55 enami 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);
352 memcpy(ent->font, font, sizeof(*ent->font));
353
354 size = font->fontheight * font->numchars * font->stride;
355 ent->font->data = malloc(size, M_DEVBUF, M_WAITOK);
356 memcpy(ent->font->data, font->data, size);
357
358 ent->font->name = malloc(strlen(font->name) + 1, M_DEVBUF,
359 M_WAITOK);
360 strcpy(ent->font->name, font->name);
361 }
362
363 TAILQ_INSERT_TAIL(&list, ent, chain);
364 return (ent);
365 }
366
367 int
368 wsfont_add(struct wsdisplay_font *font, int copy)
369 {
370 struct font *ent;
371
372 /* Don't allow exact duplicates */
373 if (wsfont_find(font->name, font->fontwidth, font->fontheight,
374 font->stride, 0, 0) >= 0)
375 return (EEXIST);
376
377 ent = wsfont_add0(font, copy);
378
379 ident += (1 << WSFONT_IDENT_SHIFT);
380 ent->cookie = wsfont_make_cookie(ident, font->bitorder,
381 font->byteorder);
382
383 return (0);
384 }
385
386 int
387 wsfont_remove(int cookie)
388 {
389 struct font *ent;
390
391 if ((ent = wsfont_find0(cookie, 0xffffffff)) == NULL)
392 return (ENOENT);
393
394 if ((ent->flags & WSFONT_BUILTIN) != 0 || ent->lockcount != 0)
395 return (EBUSY);
396
397 if ((ent->flags & WSFONT_STATIC) == 0) {
398 free(ent->font->data, M_DEVBUF);
399 free(ent->font->name, M_DEVBUF);
400 free(ent->font, M_DEVBUF);
401 }
402
403 TAILQ_REMOVE(&list, ent, chain);
404 free(ent, M_DEVBUF);
405
406 return (0);
407 }
408
409 int
410 wsfont_lock(int cookie, struct wsdisplay_font **ptr)
411 {
412 struct font *ent, *neu;
413 int bito, byteo;
414
415 if ((ent = wsfont_find0(cookie, 0xffffffff)) == NULL) {
416 if ((ent = wsfont_find0(cookie, WSFONT_IDENT_MASK)) == NULL)
417 return (ENOENT);
418
419 if (ent->lockcount != 0) {
420 neu = wsfont_add0(ent->font, 1);
421 neu->flags |= WSFONT_COPY;
422 ent = neu;
423 }
424
425 bito = (cookie & WSFONT_BITO_MASK) >> WSFONT_BITO_SHIFT;
426 byteo = (cookie & WSFONT_BYTEO_MASK) >> WSFONT_BYTEO_SHIFT;
427
428 if (bito && bito != ent->font->bitorder) {
429 wsfont_revbit(ent->font);
430 ent->font->bitorder = bito;
431 }
432
433 if (byteo && byteo != ent->font->byteorder) {
434 wsfont_revbyte(ent->font);
435 ent->font->byteorder = byteo;
436 }
437
438 ent->cookie = cookie;
439 }
440
441 ent->lockcount++;
442 *ptr = ent->font;
443 return (0);
444 }
445
446 int
447 wsfont_unlock(int cookie)
448 {
449 struct font *ent;
450
451 if ((ent = wsfont_find0(cookie, 0xffffffff)) == NULL)
452 return (ENOENT);
453
454 if (ent->lockcount == 0)
455 panic("wsfont_unlock: font not locked\n");
456
457 if (--ent->lockcount == 0 && (ent->flags & WSFONT_COPY) != 0)
458 wsfont_remove(cookie);
459
460 return (0);
461 }
462
463 /*
464 * Unicode to font encoding mappings
465 */
466
467 /*
468 * To save memory, font encoding tables use a two level lookup. First the
469 * high byte of the Unicode is used to lookup the level 2 table, then the
470 * low byte indexes that table. Level 2 tables that are not needed are
471 * omitted (NULL), and both level 1 and level 2 tables have base and size
472 * attributes to keep their size down.
473 */
474
475 struct wsfont_level1_glyphmap {
476 const struct wsfont_level2_glyphmap **level2;
477 int base; /* High byte for first level2 entry */
478 int size; /* Number of level2 entries */
479 };
480
481 struct wsfont_level2_glyphmap {
482 int base; /* Low byte for first character */
483 int size; /* Number of characters */
484 const void *chars; /* Pointer to character number entries */
485 int width; /* Size of each entry in bytes (1,2,4) */
486 };
487
488 #define null16 \
489 NULL, NULL, NULL, NULL, \
490 NULL, NULL, NULL, NULL, \
491 NULL, NULL, NULL, NULL, \
492 NULL, NULL, NULL, NULL
493
494 /*
495 * IBM 437 maps
496 */
497
498 static const u_int8_t ibm437_chars_0[] = {
499 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
500 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
501 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
502 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
503 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
504 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
505 96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,
506 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
507 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
508 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
509 255,173,155,156, 0, 157, 0, 0, 0, 0, 166,174,170, 0, 0, 0,
510 0, 241,253, 0, 0, 0, 0, 249, 0, 0, 167,175,172,171, 0, 168,
511 0, 0, 0, 0, 142,143,146,128, 0, 144, 0, 0, 0, 0, 0, 0,
512 0, 165, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 154, 0, 0, 0,
513 133,160,131, 0, 132,134,145,135,138,130,136,137,141,161,140,139,
514 0, 164,149,162,147, 0, 148,246, 0, 151,163,150,129, 0, 0, 152
515 };
516
517 static const u_int8_t ibm437_chars_1[] = {
518 159
519 };
520
521 static const u_int8_t ibm437_chars_3[] = {
522 226, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
523 228, 0, 0, 232, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 224,225,
524 0, 235,238, 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0,
525 229,231
526 };
527
528 static const u_int8_t ibm437_chars_32[] = {
529 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
530 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
531 0, 0, 0, 0, 0, 0, 0, 0, 158
532 };
533
534 static const u_int8_t ibm437_chars_34[] = {
535 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
536 0, 0, 0, 248,250,251, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0,
537 0, 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
538 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
539 0, 0, 0, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
540 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 0, 0,243,
541 242
542 };
543
544 static const u_int8_t ibm437_chars_35[] = {
545 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
546 244,245
547 };
548
549 static const u_int8_t ibm437_chars_37[] = {
550 196,205,179,186, 0, 0, 0, 0, 0, 0, 0, 0, 218,213,214,201,
551 191,184,183,187,192,212,211,200,217,190,189,188,195,198, 0, 0,
552 199, 0, 0, 204,180,181, 0, 0, 182, 0, 0, 185,194, 0, 0, 209,
553 210, 0, 0, 203,193, 0, 0, 207,208, 0, 0, 202,197, 0, 0, 216,
554 0, 0, 215, 0, 0, 0, 0, 0, 0, 0, 0, 206, 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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
558 223, 0, 0, 0, 220, 0, 0, 0, 219, 0, 0, 0, 221, 0, 0, 0,
559 222,176,177,178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
560 254
561 };
562
563 static const struct wsfont_level2_glyphmap ibm437_level2_0 =
564 { 0, 256, ibm437_chars_0, 1 };
565
566 static const struct wsfont_level2_glyphmap ibm437_level2_1 =
567 { 146, 1, ibm437_chars_1, 1 };
568
569 static const struct wsfont_level2_glyphmap ibm437_level2_3 =
570 { 147, 50, ibm437_chars_3, 1 };
571
572 static const struct wsfont_level2_glyphmap ibm437_level2_32 =
573 { 127, 41, ibm437_chars_32, 1 };
574
575 static const struct wsfont_level2_glyphmap ibm437_level2_34 =
576 { 5, 97, ibm437_chars_34, 1 };
577
578 static const struct wsfont_level2_glyphmap ibm437_level2_35 =
579 { 16, 18, ibm437_chars_35, 1 };
580
581 static const struct wsfont_level2_glyphmap ibm437_level2_37 =
582 { 0, 161, ibm437_chars_37, 1 };
583
584 static const struct wsfont_level2_glyphmap *ibm437_level1[] = {
585 &ibm437_level2_0, &ibm437_level2_1, NULL, &ibm437_level2_3,
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 NULL, NULL, NULL, NULL,
593 &ibm437_level2_32, NULL, &ibm437_level2_34, &ibm437_level2_35,
594 NULL, &ibm437_level2_37
595 };
596
597 /*
598 * ISO-8859-7 maps
599 */
600 static const u_int8_t iso7_chars_0[] = {
601 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
602 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
603 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
604 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
605 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
606 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
607 96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,
608 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
609 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
610 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
611 160, 0, 0, 163, 0, 0, 166,167,168,169, 0, 171,172,173, 0, 0,
612 176,177,178,179,180, 0, 0, 183, 0, 0, 0, 187, 0, 189
613 };
614
615 static const u_int8_t iso7_chars_3[] = {
616 182, 0, 184,185,186, 0, 188, 0, 190,191,192,193,194,195,196,197,
617 198,199,200,201,202,203,204,205,206,207,208,209, 0, 211,212,213,
618 214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,
619 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,
620 246,247,248,249,250,251,252,253,254, 0, 0, 0, 0, 0, 0, 0,
621 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
622 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181
623 };
624
625 static const u_int8_t iso7_chars_32[] = {
626 175, 0, 0, 0, 0, 162, 0, 161
627 };
628
629 static const struct wsfont_level2_glyphmap iso7_level2_0 =
630 { 0, 190, iso7_chars_0, 1 };
631
632 static const struct wsfont_level2_glyphmap iso7_level2_3 =
633 { 134, 111, iso7_chars_3, 1 };
634
635 static const struct wsfont_level2_glyphmap iso7_level2_32 =
636 { 20, 8, iso7_chars_32, 1 };
637
638 static const struct wsfont_level2_glyphmap *iso7_level1[] = {
639 &iso7_level2_0, NULL, NULL, &iso7_level2_3,
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 NULL, NULL, NULL, NULL,
647 &iso7_level2_32
648 };
649
650 static const struct wsfont_level1_glyphmap encodings[] = {
651 { NULL, 0, 0 }, /* WSDISPLAY_FONTENC_ISO */
652 { ibm437_level1, 0, 38 }, /* WSDISPLAY_FONTENC_IBM */
653 { NULL, 0, 0 }, /* WSDISPLAY_FONTENC_PCVT */
654 { iso7_level1, 0, 33 }, /* WSDISPLAY_FONTENC_ISO7 */
655 };
656
657 #define MAX_ENCODING (sizeof(encodings) / sizeof(encodings[0]))
658
659 /*
660 * Remap Unicode character to glyph
661 */
662 int
663 wsfont_map_unichar(struct wsdisplay_font *font, int c)
664 {
665 const struct wsfont_level1_glyphmap *map1;
666 const struct wsfont_level2_glyphmap *map2;
667 int hi, lo;
668
669 if (font->encoding == WSDISPLAY_FONTENC_ISO)
670 return (c);
671
672 if (font->encoding < 0 || font->encoding > MAX_ENCODING)
673 return (-1);
674
675 hi = (c >> 8);
676 lo = c & 255;
677 map1 = &encodings[font->encoding];
678
679 if (hi < map1->base || hi >= map1->base + map1->size)
680 return (-1);
681
682 map2 = map1->level2[hi - map1->base];
683
684 if (map2 == NULL || lo < map2->base || lo >= map2->base + map2->size)
685 return (-1);
686
687 lo -= map2->base;
688
689 switch(map2->width) {
690 case 1:
691 c = (((const u_int8_t *)map2->chars)[lo]);
692 break;
693 case 2:
694 c = (((const u_int16_t *)map2->chars)[lo]);
695 break;
696 case 4:
697 c = (((const u_int32_t *)map2->chars)[lo]);
698 break;
699 }
700
701 if (c == 0 && lo != 0)
702 return (-1);
703
704 return (c);
705 }
706