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