wsfont.c revision 1.18.2.3 1 /* $NetBSD: wsfont.c,v 1.18.2.3 2001/09/21 22:36:21 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.3 2001/09/21 22:36:21 nathanw 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 __P((int));
191 static void wsfont_revbit __P((struct wsdisplay_font *));
192 static void wsfont_revbyte __P((struct wsdisplay_font *));
193
194 /*
195 * Reverse the bit order of a font
196 */
197 static void
198 wsfont_revbit(font)
199 struct wsdisplay_font *font;
200 {
201 u_char *p, *m;
202
203 p = (u_char *)font->data;
204 m = p + font->stride * font->numchars * font->fontheight;
205
206 for (; p < m; p++)
207 *p = reverse[*p];
208 }
209
210 /*
211 * Reverse the byte order of a font
212 */
213 static void
214 wsfont_revbyte(font)
215 struct wsdisplay_font *font;
216 {
217 int x, l, r, nr;
218 u_char *rp;
219
220 if (font->stride == 1)
221 return;
222
223 rp = (u_char *)font->data;
224 nr = font->numchars * font->fontheight;
225
226 while (nr--) {
227 l = 0;
228 r = font->stride - 1;
229
230 while (l < r) {
231 x = rp[l];
232 rp[l] = rp[r];
233 rp[r] = x;
234 l++, r--;
235 }
236
237 rp += font->stride;
238 }
239 }
240
241 /*
242 * Enumarate the list of fonts
243 */
244 void
245 wsfont_enum(cb)
246 void (*cb) __P((char *, int, int, int));
247 {
248 struct wsdisplay_font *f;
249 struct font *ent;
250 int s;
251
252 s = splhigh();
253
254 for (ent = list; ent; ent = ent->next) {
255 f = ent->font;
256 cb(f->name, f->fontwidth, f->fontheight, f->stride);
257 }
258
259 splx(s);
260 }
261
262 /*
263 * Initialize list with WSFONT_BUILTIN fonts
264 */
265 void
266 wsfont_init(void)
267 {
268 static int again;
269 int i;
270
271 if (again != 0)
272 return;
273 again = 1;
274
275 for (i = 0; builtin_fonts[i].font != NULL; i++) {
276 builtin_fonts[i].next = list;
277 list = &builtin_fonts[i];
278 }
279 }
280
281 /*
282 * Find a font by cookie. Called at splhigh.
283 */
284 static struct font *
285 wsfont_find0(cookie)
286 int cookie;
287 {
288 struct font *ent;
289
290 for (ent = list; ent != NULL; ent = ent->next)
291 if (ent->cookie == cookie)
292 return (ent);
293
294 return (NULL);
295 }
296
297 int
298 wsfont_matches(font, name, width, height, stride)
299 struct wsdisplay_font *font;
300 char *name;
301 int width, height, stride;
302 {
303
304 if (height != 0 && font->fontheight != height)
305 return (0);
306
307 if (width != 0 && font->fontwidth != width)
308 return (0);
309
310 if (stride != 0 && font->stride != stride)
311 return (0);
312
313 if (name != NULL && strcmp(font->name, name) != 0)
314 return (0);
315
316 return (1);
317 }
318
319 /*
320 * Find a font.
321 */
322 int
323 wsfont_find(name, width, height, stride)
324 char *name;
325 int width, height, stride;
326 {
327 struct font *ent;
328 int s;
329
330 s = splhigh();
331
332 for (ent = list; ent != NULL; ent = ent->next) {
333 if (wsfont_matches(ent->font, name, width, height, stride)) {
334 splx(s);
335 return (ent->cookie);
336 }
337 }
338
339 splx(s);
340 return (-1);
341 }
342
343 /*
344 * Add a font to the list.
345 */
346 int
347 wsfont_add(font, copy)
348 struct wsdisplay_font *font;
349 int copy;
350 {
351 static int cookiegen = 666;
352 struct font *ent;
353 size_t size;
354 int s;
355
356 s = splhigh();
357
358 /* Don't allow exact duplicates */
359 if (wsfont_find(font->name, font->fontwidth, font->fontheight,
360 font->stride) >= 0) {
361 splx(s);
362 return (EEXIST);
363 }
364
365 MALLOC(ent, struct font *, sizeof *ent, M_DEVBUF, M_WAITOK);
366
367 ent->lockcount = 0;
368 ent->flg = 0;
369 ent->cookie = cookiegen++;
370 ent->next = list;
371 ent->prev = NULL;
372
373 /* Is this font statically allocated? */
374 if (!copy) {
375 ent->font = font;
376 ent->flg = WSFONT_STATIC;
377 } else {
378 MALLOC(ent->font, struct wsdisplay_font *, sizeof *ent->font,
379 M_DEVBUF, M_WAITOK);
380 memcpy(ent->font, font, sizeof(*ent->font));
381
382 size = font->fontheight * font->numchars * font->stride;
383 MALLOC(ent->font->data, void *, size, M_DEVBUF, M_WAITOK);
384 memcpy(ent->font->data, font->data, size);
385 MALLOC(ent->font->name, char *, strlen(font->name) + 1,
386 M_DEVBUF, M_WAITOK);
387 strcpy(ent->font->name, font->name);
388 ent->flg = 0;
389 }
390
391 /* Now link into the list and return */
392 list = ent;
393 splx(s);
394 return (0);
395 }
396
397 /*
398 * Remove a font.
399 */
400 int
401 wsfont_remove(cookie)
402 int cookie;
403 {
404 struct font *ent;
405 int s;
406
407 s = splhigh();
408
409 if ((ent = wsfont_find0(cookie)) == NULL) {
410 splx(s);
411 return (ENOENT);
412 }
413
414 if ((ent->flg & WSFONT_BUILTIN) != 0 || ent->lockcount != 0) {
415 splx(s);
416 return (EBUSY);
417 }
418
419 /* Don't free statically allocated font data */
420 if ((ent->flg & WSFONT_STATIC) != 0) {
421 FREE(ent->font->data, M_DEVBUF);
422 FREE(ent->font->name, M_DEVBUF);
423 FREE(ent->font, M_DEVBUF);
424 }
425
426 /* Remove from list, free entry */
427 if (ent->prev)
428 ent->prev->next = ent->next;
429 else
430 list = ent->next;
431
432 if (ent->next)
433 ent->next->prev = ent->prev;
434
435 FREE(ent, M_DEVBUF);
436 splx(s);
437 return (0);
438 }
439
440 /*
441 * Lock a given font and return new lockcount. This fails if the cookie
442 * is invalid, or if the font is already locked and the bit/byte order
443 * requested by the caller differs.
444 */
445 int
446 wsfont_lock(cookie, ptr, bitorder, byteorder)
447 int cookie;
448 struct wsdisplay_font **ptr;
449 int bitorder, byteorder;
450 {
451 struct font *ent;
452 int s, lc;
453
454 s = splhigh();
455
456 if ((ent = wsfont_find0(cookie)) != NULL) {
457 if (bitorder && bitorder != ent->font->bitorder) {
458 if (ent->lockcount) {
459 splx(s);
460 return (-1);
461 }
462 wsfont_revbit(ent->font);
463 ent->font->bitorder = bitorder;
464 }
465
466 if (byteorder && byteorder != ent->font->byteorder) {
467 if (ent->lockcount) {
468 splx(s);
469 return (-1);
470 }
471 wsfont_revbyte(ent->font);
472 ent->font->byteorder = byteorder;
473 }
474
475 lc = ++ent->lockcount;
476 *ptr = ent->font;
477 } else
478 lc = -1;
479
480 splx(s);
481 return (lc);
482 }
483
484 /*
485 * Get font flags and lockcount.
486 */
487 int
488 wsfont_getflg(cookie, flg, lc)
489 int cookie, *flg, *lc;
490 {
491 struct font *ent;
492 int s;
493
494 s = splhigh();
495
496 if ((ent = wsfont_find0(cookie)) != NULL) {
497 *flg = ent->flg;
498 *lc = ent->lockcount;
499 }
500
501 splx(s);
502 return (ent != NULL ? 0 : -1);
503 }
504
505 /*
506 * Unlock a given font and return new lockcount.
507 */
508 int
509 wsfont_unlock(cookie)
510 int cookie;
511 {
512 struct font *ent;
513 int s, lc;
514
515 s = splhigh();
516
517 if ((ent = wsfont_find0(cookie)) != NULL) {
518 if (ent->lockcount == 0)
519 panic("wsfont_unlock: font not locked\n");
520 lc = --ent->lockcount;
521 } else
522 lc = -1;
523
524 splx(s);
525 return (lc);
526 }
527
528
529 /*
530 * Unicode to font encoding mappings
531 */
532
533 /*
534 * To save memory, font encoding tables use a two level lookup.
535 * First the high byte of the Unicode is used to lookup the level 2
536 * table, then the low byte indexes that table. Level 2 tables that are
537 * not needed are omitted (NULL), and both level 1 and level 2 tables
538 * have base and size attributes to keep their size down.
539 */
540
541 struct wsfont_level1_glyphmap {
542 struct wsfont_level2_glyphmap **level2;
543 int base; /* High byte for first level2 entry */
544 int size; /* Number of level2 entries */
545 };
546
547 struct wsfont_level2_glyphmap {
548 int base; /* Low byte for first character */
549 int size; /* Number of characters */
550 void *chars; /* Pointer to character number entries */
551 int width; /* Size of each entry in bytes (1,2,4) */
552 };
553
554 #define null16 \
555 NULL, NULL, NULL, NULL, \
556 NULL, NULL, NULL, NULL, \
557 NULL, NULL, NULL, NULL, \
558 NULL, NULL, NULL, NULL
559
560 /*
561 * IBM 437 maps
562 */
563
564 static u_int8_t
565 ibm437_chars_0[] = {
566 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
567 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
568 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
569 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
570 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
571 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
572 96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,
573 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
574 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
575 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
576 255,173,155,156, 0, 157, 0, 0, 0, 0, 166,174,170, 0, 0, 0,
577 0, 241,253, 0, 0, 0, 0, 249, 0, 0, 167,175,172,171, 0, 168,
578 0, 0, 0, 0, 142,143,146,128, 0, 144, 0, 0, 0, 0, 0, 0,
579 0, 165, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 154, 0, 0, 0,
580 133,160,131, 0, 132,134,145,135,138,130,136,137,141,161,140,139,
581 0, 164,149,162,147, 0, 148,246, 0, 151,163,150,129, 0, 0, 152
582 },
583 ibm437_chars_1[] = {
584 159
585 },
586 ibm437_chars_3[] = {
587 226, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
588 228, 0, 0, 232, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 224,225,
589 0, 235,238, 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0,
590 229,231
591 },
592 ibm437_chars_32[] = {
593 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
594 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
595 0, 0, 0, 0, 0, 0, 0, 0, 158
596 },
597 ibm437_chars_34[] = {
598 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
599 0, 0, 0, 248,250,251, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0,
600 0, 0, 0, 0, 239, 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, 247, 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,240, 0, 0,243,
604 242
605 },
606 ibm437_chars_35[] = {
607 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
608 244,245
609 },
610 ibm437_chars_37[] = {
611 196,205,179,186, 0, 0, 0, 0, 0, 0, 0, 0, 218,213,214,201,
612 191,184,183,187,192,212,211,200,217,190,189,188,195,198, 0, 0,
613 199, 0, 0, 204,180,181, 0, 0, 182, 0, 0, 185,194, 0, 0, 209,
614 210, 0, 0, 203,193, 0, 0, 207,208, 0, 0, 202,197, 0, 0, 216,
615 0, 0, 215, 0, 0, 0, 0, 0, 0, 0, 0, 206, 0, 0, 0, 0,
616 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
617 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
618 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
619 223, 0, 0, 0, 220, 0, 0, 0, 219, 0, 0, 0, 221, 0, 0, 0,
620 222,176,177,178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
621 254
622 };
623
624 static struct wsfont_level2_glyphmap
625 ibm437_level2_0 = { 0, 256, ibm437_chars_0, 1 },
626 ibm437_level2_1 = { 146, 1, ibm437_chars_1, 1 },
627 ibm437_level2_3 = { 147, 50, ibm437_chars_3, 1 },
628 ibm437_level2_32 = { 127, 41, ibm437_chars_32, 1 },
629 ibm437_level2_34 = { 5, 97, ibm437_chars_34, 1 },
630 ibm437_level2_35 = { 16, 18, ibm437_chars_35, 1 },
631 ibm437_level2_37 = { 0, 161, ibm437_chars_37, 1 };
632
633 static struct wsfont_level2_glyphmap *ibm437_level1[] = {
634 &ibm437_level2_0, &ibm437_level2_1, NULL, &ibm437_level2_3,
635 NULL, NULL, NULL, NULL,
636 NULL, NULL, NULL, NULL,
637 NULL, NULL, NULL, NULL,
638 NULL, NULL, NULL, NULL,
639 NULL, NULL, NULL, NULL,
640 NULL, NULL, NULL, NULL,
641 NULL, NULL, NULL, NULL,
642 &ibm437_level2_32, NULL, &ibm437_level2_34, &ibm437_level2_35,
643 NULL, &ibm437_level2_37
644 };
645
646
647 /*
648 * ISO-8859-7 maps
649 */
650
651 static u_int8_t
652 iso7_chars_0[] = {
653 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
654 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
655 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
656 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
657 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
658 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
659 96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,
660 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
661 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
662 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
663 160, 0, 0, 163, 0, 0, 166,167,168,169, 0, 171,172,173, 0, 0,
664 176,177,178,179,180, 0, 0, 183, 0, 0, 0, 187, 0, 189
665 },
666 iso7_chars_3[] = {
667 182, 0, 184,185,186, 0, 188, 0, 190,191,192,193,194,195,196,197,
668 198,199,200,201,202,203,204,205,206,207,208,209, 0, 211,212,213,
669 214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,
670 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,
671 246,247,248,249,250,251,252,253,254, 0, 0, 0, 0, 0, 0, 0,
672 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
673 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181
674 },
675 iso7_chars_32[] = {
676 175, 0, 0, 0, 0, 162, 0, 161
677 };
678
679 static struct wsfont_level2_glyphmap
680 iso7_level2_0 = { 0, 190, iso7_chars_0, 1 },
681 iso7_level2_3 = { 134, 111, iso7_chars_3, 1 },
682 iso7_level2_32 = { 20, 8, iso7_chars_32, 1 };
683
684 static struct wsfont_level2_glyphmap *iso7_level1[] = {
685 &iso7_level2_0, NULL, NULL, &iso7_level2_3,
686 NULL, NULL, NULL, NULL,
687 NULL, NULL, NULL, NULL,
688 NULL, NULL, NULL, NULL,
689 NULL, NULL, NULL, NULL,
690 NULL, NULL, NULL, NULL,
691 NULL, NULL, NULL, NULL,
692 NULL, NULL, NULL, NULL,
693 &iso7_level2_32
694 };
695
696 static struct wsfont_level1_glyphmap encodings[] = {
697 { NULL, 0, 0 }, /* WSDISPLAY_FONTENC_ISO */
698 { ibm437_level1, 0, 38 }, /* WSDISPLAY_FONTENC_IBM */
699 { NULL, 0, 0 }, /* WSDISPLAY_FONTENC_PCVT */
700 { iso7_level1, 0, 33 }, /* WSDISPLAY_FONTENC_ISO7 */
701 };
702
703 #define MAX_ENCODING (sizeof(encodings) / sizeof(encodings[0]))
704
705 /*
706 * Remap Unicode character to glyph
707 */
708 int
709 wsfont_map_unichar(font, c)
710 struct wsdisplay_font *font;
711 int c;
712 {
713 if (font->encoding == WSDISPLAY_FONTENC_ISO) {
714
715 return c;
716
717 } else if (font->encoding < 0 || font->encoding > MAX_ENCODING) {
718
719 return (-1);
720
721 } else {
722
723 int hi = (c >> 8), lo = c & 255;
724 struct wsfont_level1_glyphmap *map1 =
725 &encodings[font->encoding];
726
727 if (hi >= map1->base && hi < map1->base + map1->size) {
728 struct wsfont_level2_glyphmap *map2 =
729 map1->level2[hi - map1->base];
730
731 if (map2 != NULL &&
732 lo >= map2->base && lo < map2->base + map2->size) {
733
734 lo -= map2->base;
735
736 switch(map2->width) {
737 case 1:
738 c = (((u_int8_t *)map2->chars)[lo]);
739 break;
740 case 2:
741 c = (((u_int16_t *)map2->chars)[lo]);
742 break;
743 case 4:
744 c = (((u_int32_t *)map2->chars)[lo]);
745 break;
746 }
747
748 if (c == 0 && lo != 0)
749 return (-1);
750 else
751 return (c);
752
753 } else {
754 return (-1);
755 }
756
757 } else {
758 return (-1);
759 }
760
761 }
762
763 }
764