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