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