Annotation of src/sys/dev/wsfont/wsfont.c, Revision 1.74
1.74 ! rin 1: /* $NetBSD: wsfont.c,v 1.73 2021/11/19 23:55:16 rin Exp $ */
1.1 ad 2:
1.7 ad 3: /*-
1.24 ad 4: * Copyright (c) 1999, 2000, 2001, 2002 The NetBSD Foundation, Inc.
1.1 ad 5: * All rights reserved.
6: *
1.7 ad 7: * This code is derived from software contributed to The NetBSD Foundation
1.13 ad 8: * by Andrew Doran.
1.7 ad 9: *
1.1 ad 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: *
1.7 ad 19: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29: * POSSIBILITY OF SUCH DAMAGE.
1.1 ad 30: */
1.2 ad 31:
1.1 ad 32: #include <sys/cdefs.h>
1.74 ! rin 33: __KERNEL_RCSID(0, "$NetBSD: wsfont.c,v 1.73 2021/11/19 23:55:16 rin Exp $");
1.1 ad 34:
35: #include "opt_wsfont.h"
36:
37: #include <sys/param.h>
38: #include <sys/systm.h>
39: #include <sys/time.h>
40: #include <sys/malloc.h>
1.26 uch 41: #include <sys/queue.h>
1.1 ad 42:
43: #include <dev/wscons/wsdisplayvar.h>
44: #include <dev/wscons/wsconsio.h>
45: #include <dev/wsfont/wsfont.h>
46:
1.44 ober 47: #include "wsfont_glue.h" /* NRASOPS_ROTATION */
48:
1.1 ad 49: #undef HAVE_FONT
50:
1.4 ad 51: #ifdef FONT_QVSS8x15
1.1 ad 52: #define HAVE_FONT 1
1.4 ad 53: #include <dev/wsfont/qvss8x15.h>
1.1 ad 54: #endif
55:
56: #ifdef FONT_GALLANT12x22
57: #define HAVE_FONT 1
58: #include <dev/wsfont/gallant12x22.h>
59: #endif
60:
61: #ifdef FONT_LUCIDA16x29
62: #define HAVE_FONT 1
63: #include <dev/wsfont/lucida16x29.h>
64: #endif
65:
1.8 takemura 66: #ifdef FONT_VT220L8x8
67: #define HAVE_FONT 1
68: #include <dev/wsfont/vt220l8x8.h>
69: #endif
70:
71: #ifdef FONT_VT220L8x10
72: #define HAVE_FONT 1
73: #include <dev/wsfont/vt220l8x10.h>
74: #endif
75:
1.30 tsutsui 76: #ifdef FONT_VT220L8x16
77: #define HAVE_FONT 1
78: #include <dev/wsfont/vt220l8x16.h>
79: #endif
80:
1.48 tsutsui 81: #ifdef FONT_VT220ISO8x8
82: #define HAVE_FONT 1
83: #include <dev/wsfont/vt220iso8x8.h>
84: #endif
85:
1.30 tsutsui 86: #ifdef FONT_VT220ISO8x16
87: #define HAVE_FONT 1
88: #include <dev/wsfont/vt220iso8x16.h>
89: #endif
90:
1.34 uwe 91: #ifdef FONT_VT220KOI8x10_KOI8_R
92: #define HAVE_FONT 1
93: #include <dev/wsfont/vt220koi8x10.h>
94: #endif
95:
96: #ifdef FONT_VT220KOI8x10_KOI8_U
97: #define HAVE_FONT 1
98: #define KOI8_U
99: #include <dev/wsfont/vt220koi8x10.h>
100: #undef KOI8_U
101: #endif
102:
1.14 tsutsui 103: #ifdef FONT_SONY8x16
104: #define HAVE_FONT 1
105: #include <dev/wsfont/sony8x16.h>
106: #endif
107:
108: #ifdef FONT_SONY12x24
109: #define HAVE_FONT 1
110: #include <dev/wsfont/sony12x24.h>
111: #endif
112:
1.15 tsutsui 113: #ifdef FONT_OMRON12x20
114: #define HAVE_FONT 1
115: #include <dev/wsfont/omron12x20.h>
116: #endif
117:
1.57 christos 118: #ifdef FONT_GLASS10x19
119: #define HAVE_FONT 1
120: #include <dev/wsfont/glass10x19.h>
121: #endif
122:
123: #ifdef FONT_GLASS10x25
124: #define HAVE_FONT 1
125: #include <dev/wsfont/glass10x25.h>
126: #endif
127:
1.51 macallan 128: #ifdef FONT_DEJAVU_SANS_MONO12x22
1.65 rin 129: #define HAVE_FONT 1
1.51 macallan 130: #include <dev/wsfont/DejaVu_Sans_Mono_12x22.h>
131: #endif
132:
1.74 ! rin 133: #ifdef FONT_DROID_SANS_MONO9x18
1.65 rin 134: #define HAVE_FONT 1
1.74 ! rin 135: #include <dev/wsfont/Droid_Sans_Mono_9x18.h>
1.51 macallan 136: #endif
137:
1.74 ! rin 138: #ifdef FONT_DROID_SANS_MONO12x22
1.65 rin 139: #define HAVE_FONT 1
1.74 ! rin 140: #include <dev/wsfont/Droid_Sans_Mono_12x22.h>
1.52 macallan 141: #endif
142:
1.56 macallan 143: #ifdef FONT_DROID_SANS_MONO19x36
1.65 rin 144: #define HAVE_FONT 1
1.56 macallan 145: #include <dev/wsfont/Droid_Sans_Mono_19x36.h>
146: #endif
147:
1.61 macallan 148: #ifdef FONT_GO_MONO12x23
1.65 rin 149: #define HAVE_FONT 1
1.61 macallan 150: #include <dev/wsfont/Go_Mono_12x23.h>
151: #endif
152:
1.70 rin 153: #ifdef FONT_SPLEEN5x8
1.65 rin 154: #define HAVE_FONT 1
1.70 rin 155: #include <dev/wsfont/spleen5x8.h>
1.64 tnn 156: #endif
157:
1.70 rin 158: #ifdef FONT_SPLEEN6x12
1.65 rin 159: #define HAVE_FONT 1
1.70 rin 160: #include <dev/wsfont/spleen6x12.h>
1.64 tnn 161: #endif
162:
1.70 rin 163: #ifdef FONT_SPLEEN8x16
1.65 rin 164: #define HAVE_FONT 1
1.70 rin 165: #include <dev/wsfont/spleen8x16.h>
1.64 tnn 166: #endif
167:
1.70 rin 168: #ifdef FONT_SPLEEN12x24
1.65 rin 169: #define HAVE_FONT 1
1.70 rin 170: #include <dev/wsfont/spleen12x24.h>
1.64 tnn 171: #endif
172:
1.70 rin 173: #ifdef FONT_SPLEEN16x32
1.68 fcambus 174: #define HAVE_FONT 1
1.70 rin 175: #include <dev/wsfont/spleen16x32.h>
1.68 fcambus 176: #endif
177:
1.70 rin 178: #ifdef FONT_SPLEEN32x64
1.65 rin 179: #define HAVE_FONT 1
1.70 rin 180: #include <dev/wsfont/spleen32x64.h>
1.64 tnn 181: #endif
182:
1.69 macallan 183: #ifdef FONT_LIBERATION_MONO12x21
184: #define HAVE_FONT 1
185: #include <dev/wsfont/Liberation_Mono_12x21.h>
186: #endif
187:
1.66 jmcneill 188: #ifdef FONT_BOLD16x32
189: #define HAVE_FONT 1
190: #include <dev/wsfont/bold16x32.h>
191: #endif
192:
1.53 macallan 193: /* Make sure we always have at least one bitmap font. */
1.1 ad 194: #ifndef HAVE_FONT
195: #define HAVE_FONT 1
1.4 ad 196: #define FONT_BOLD8x16 1
1.1 ad 197: #endif
198:
1.4 ad 199: #ifdef FONT_BOLD8x16
200: #include <dev/wsfont/bold8x16.h>
1.1 ad 201: #endif
202:
1.25 ad 203: #define WSFONT_IDENT_MASK 0xffffff00
204: #define WSFONT_IDENT_SHIFT 8
205: #define WSFONT_BITO_MASK 0x000000f0
206: #define WSFONT_BITO_SHIFT 4
207: #define WSFONT_BYTEO_MASK 0x0000000f
208: #define WSFONT_BYTEO_SHIFT 0
209:
210: #define WSFONT_BUILTIN 0x01 /* In wsfont.c */
211: #define WSFONT_STATIC 0x02 /* Font structures not malloc()ed */
212: #define WSFONT_COPY 0x04 /* Copy of existing font in table */
213:
1.1 ad 214: /* Placeholder struct used for linked list */
215: struct font {
1.25 ad 216: TAILQ_ENTRY(font) chain;
1.1 ad 217: struct wsdisplay_font *font;
1.25 ad 218: u_int lockcount;
219: u_int cookie;
220: u_int flags;
221: };
1.1 ad 222:
223: /* Our list of built-in fonts */
1.25 ad 224: static struct font builtin_fonts[] = {
1.1 ad 225: #ifdef FONT_BOLD8x16
1.43 christos 226: { { NULL, NULL }, &bold8x16, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
1.1 ad 227: #endif
1.66 jmcneill 228: #ifdef FONT_BOLD16x32
229: { { NULL, NULL }, &bold16x32, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
230: #endif
1.1 ad 231: #ifdef FONT_GALLANT12x22
1.43 christos 232: { { NULL, NULL }, &gallant12x22, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
1.1 ad 233: #endif
234: #ifdef FONT_LUCIDA16x29
1.43 christos 235: { { NULL, NULL }, &lucida16x29, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
1.1 ad 236: #endif
237: #ifdef FONT_QVSS8x15
1.43 christos 238: { { NULL, NULL }, &qvss8x15, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
1.8 takemura 239: #endif
240: #ifdef FONT_VT220L8x8
1.43 christos 241: { { NULL, NULL }, &vt220l8x8, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
1.8 takemura 242: #endif
243: #ifdef FONT_VT220L8x10
1.43 christos 244: { { NULL, NULL }, &vt220l8x10, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
1.30 tsutsui 245: #endif
246: #ifdef FONT_VT220L8x16
1.43 christos 247: { { NULL, NULL }, &vt220l8x16, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
1.30 tsutsui 248: #endif
1.48 tsutsui 249: #ifdef FONT_VT220ISO8x8
250: { { NULL, NULL }, &vt220iso8x8, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
251: #endif
1.30 tsutsui 252: #ifdef FONT_VT220ISO8x16
1.43 christos 253: { { NULL, NULL }, &vt220iso8x16, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
1.34 uwe 254: #endif
255: #ifdef FONT_VT220KOI8x10_KOI8_R
1.43 christos 256: { { NULL, NULL }, &vt220kr8x10, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
1.34 uwe 257: #endif
258: #ifdef FONT_VT220KOI8x10_KOI8_U
1.43 christos 259: { { NULL, NULL }, &vt220ku8x10, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
1.14 tsutsui 260: #endif
261: #ifdef FONT_SONY8x16
1.43 christos 262: { { NULL, NULL }, &sony8x16, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
1.14 tsutsui 263: #endif
264: #ifdef FONT_SONY12x24
1.43 christos 265: { { NULL, NULL }, &sony12x24, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
1.15 tsutsui 266: #endif
267: #ifdef FONT_OMRON12x20
1.43 christos 268: { { NULL, NULL }, &omron12x20, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
1.1 ad 269: #endif
1.57 christos 270: #ifdef FONT_GLASS10x19
271: { { NULL, NULL }, &Glass_TTY_VT220_10x19, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
272: #endif
273: #ifdef FONT_GLASS10x25
274: { { NULL, NULL }, &Glass_TTY_VT220_10x25, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
275: #endif
1.51 macallan 276: #ifdef FONT_DEJAVU_SANS_MONO12x22
277: { { NULL, NULL }, &DejaVu_Sans_Mono_12x22, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
278: #endif
279: #ifdef FONT_DROID_SANS_MONO12x22
280: { { NULL, NULL }, &Droid_Sans_Mono_12x22, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
281: #endif
1.52 macallan 282: #ifdef FONT_DROID_SANS_MONO9x18
283: { { NULL, NULL }, &Droid_Sans_Mono_9x18, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
284: #endif
1.56 macallan 285: #ifdef FONT_DROID_SANS_MONO19x36
286: { { NULL, NULL }, &Droid_Sans_Mono_19x36, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
287: #endif
1.61 macallan 288: #ifdef FONT_GO_MONO12x23
289: { { NULL, NULL }, &Go_Mono_12x23, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
290: #endif
1.71 rin 291: #ifdef FONT_SPLEEN5x8
292: { { NULL, NULL }, &spleen5x8, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
293: #endif
294: #ifdef FONT_SPLEEN6x12
295: { { NULL, NULL }, &spleen6x12, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
296: #endif
297: #ifdef FONT_SPLEEN8x16
298: { { NULL, NULL }, &spleen8x16, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
299: #endif
1.64 tnn 300: #ifdef FONT_SPLEEN12x24
301: { { NULL, NULL }, &spleen12x24, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
302: #endif
303: #ifdef FONT_SPLEEN16x32
304: { { NULL, NULL }, &spleen16x32, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
305: #endif
306: #ifdef FONT_SPLEEN32x64
307: { { NULL, NULL }, &spleen32x64, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
308: #endif
1.69 macallan 309: #ifdef FONT_LIBERATION_MONO12x21
310: { { NULL, NULL }, &Liberation_Mono_12x21, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
311: #endif
1.43 christos 312: { { NULL, NULL }, NULL, 0, 0, 0 },
1.1 ad 313: };
314:
1.25 ad 315: static TAILQ_HEAD(,font) list;
316: static int ident;
317:
1.1 ad 318: /* Reverse the bit order in a byte */
319: static const u_char reverse[256] = {
1.37 perry 320: 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
321: 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
322: 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
323: 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
324: 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
325: 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
326: 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
327: 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
328: 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
329: 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
330: 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
331: 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
332: 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
333: 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
334: 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
335: 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
336: 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
337: 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
338: 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
339: 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
340: 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
341: 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
342: 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
343: 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
344: 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
345: 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
346: 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
347: 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
348: 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
349: 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
350: 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
351: 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
1.1 ad 352: };
353:
1.25 ad 354: static struct font *wsfont_find0(int, int);
355: static struct font *wsfont_add0(struct wsdisplay_font *, int);
1.22 augustss 356: static void wsfont_revbit(struct wsdisplay_font *);
357: static void wsfont_revbyte(struct wsdisplay_font *);
1.25 ad 358:
1.53 macallan 359: int
1.38 christos 360: wsfont_make_cookie(int cident, int bito, int byteo)
1.25 ad 361: {
362:
1.38 christos 363: return ((cident & WSFONT_IDENT_MASK) |
1.25 ad 364: (bito << WSFONT_BITO_SHIFT) |
365: (byteo << WSFONT_BYTEO_SHIFT));
366: }
1.1 ad 367:
368: static void
1.22 augustss 369: wsfont_revbit(struct wsdisplay_font *font)
1.1 ad 370: {
371: u_char *p, *m;
1.24 ad 372:
1.1 ad 373: p = (u_char *)font->data;
374: m = p + font->stride * font->numchars * font->fontheight;
1.18 cgd 375:
1.37 perry 376: for (; p < m; p++)
1.18 cgd 377: *p = reverse[*p];
1.1 ad 378: }
379:
380: static void
1.22 augustss 381: wsfont_revbyte(struct wsdisplay_font *font)
1.1 ad 382: {
383: int x, l, r, nr;
384: u_char *rp;
1.24 ad 385:
1.1 ad 386: if (font->stride == 1)
387: return;
388:
389: rp = (u_char *)font->data;
390: nr = font->numchars * font->fontheight;
1.24 ad 391:
1.1 ad 392: while (nr--) {
393: l = 0;
394: r = font->stride - 1;
1.24 ad 395:
1.1 ad 396: while (l < r) {
397: x = rp[l];
398: rp[l] = rp[r];
399: rp[r] = x;
400: l++, r--;
401: }
1.24 ad 402:
1.1 ad 403: rp += font->stride;
404: }
405: }
406:
407: void
1.31 jdolecek 408: wsfont_enum(void (*cb)(const char *, int, int, int))
1.1 ad 409: {
1.9 ad 410: struct wsdisplay_font *f;
1.1 ad 411: struct font *ent;
1.24 ad 412:
1.25 ad 413: TAILQ_FOREACH(ent, &list, chain) {
1.37 perry 414: f = ent->font;
1.9 ad 415: cb(f->name, f->fontwidth, f->fontheight, f->stride);
1.1 ad 416: }
417: }
418:
1.44 ober 419: #if NRASOPS_ROTATION > 0
420:
1.73 rin 421: static struct wsdisplay_font *
422: wsfont_rotate_internal(struct wsdisplay_font *font, int rotate)
1.44 ober 423: {
424: struct wsdisplay_font *newfont;
1.73 rin 425: char *newname, *newdata;
426: u_char *ch, *newch, *p, *newp;
427: int namelen, newstride, n, h, w;
428: u_char bit;
429: bool alpha = FONT_IS_ALPHA(font), cw = (rotate == WSFONT_ROTATE_CW);
1.44 ober 430:
431: /* Duplicate the existing font... */
432: newfont = malloc(sizeof(*font), M_DEVBUF, M_WAITOK);
433:
434: *newfont = *font;
435:
1.50 tsutsui 436: namelen = strlen(font->name) + 4;
437: newname = malloc(namelen, M_DEVBUF, M_WAITOK);
438: strlcpy(newname, font->name, namelen);
1.73 rin 439: strlcat(newname, cw ? "cw" : "ccw", namelen);
1.50 tsutsui 440: newfont->name = newname;
441:
1.44 ober 442: /* Allocate a buffer big enough for the rotated font. */
1.73 rin 443: newstride = alpha ? font->fontheight : howmany(font->fontheight, 8);
444: newdata = malloc(newstride * font->fontwidth * font->numchars,
1.44 ober 445: M_DEVBUF, M_WAITOK|M_ZERO);
446:
1.73 rin 447: #define BYTE_OFFSET(x, alpha) ((alpha) ? (x) : (x) / 8)
448: #define BIT_FROM_LEFT(x) __BIT(7 - ((x) % 8))
449: #define BIT_FROM_RIGHT(x) __BIT((x) % 8)
450:
451: /* Rotate the font a pixel at a time. */
1.44 ober 452: for (n = 0; n < font->numchars; n++) {
1.73 rin 453: ch = (u_char *)font->data +
1.44 ober 454: (n * font->stride * font->fontheight);
1.73 rin 455: newch = newdata +
456: (n * newstride * font->fontwidth);
457: for (h = 0; h < font->fontheight; h++) {
458: for (w = 0; w < font->fontwidth; w++) {
459: p = ch + (h * font->stride) +
460: BYTE_OFFSET(w, alpha);
461: if (cw) {
462: /* Rotate clockwise. */
463: newp = newch +
464: (w * newstride) +
465: (newstride - 1 -
466: BYTE_OFFSET(h, alpha));
467: bit = BIT_FROM_RIGHT(h);
468: } else {
469: /* Rotate counter-clockwise. */
470: newp = newch +
471: ((font->fontwidth - 1 - w) *
472: newstride) +
473: BYTE_OFFSET(h, alpha);
474: bit = BIT_FROM_LEFT(h);
475: }
476: if (alpha) {
477: *newp = *p;
478: } else {
479: if (*p & BIT_FROM_LEFT(w))
480: *newp |= bit;
1.44 ober 481: }
482: }
483: }
484: }
485:
1.73 rin 486: #undef BYTE_OFFSET
487: #undef BIT_FROM_LEFT
488: #undef BIT_FROM_RIGHT
1.46 nonaka 489:
1.73 rin 490: newfont->data = newdata;
1.46 nonaka 491:
492: /* Update font sizes. */
493: newfont->stride = newstride;
494: newfont->fontwidth = font->fontheight;
495: newfont->fontheight = font->fontwidth;
496:
497: if (wsfont_add(newfont, 0) != 0) {
498: /*
499: * If we seem to have rotated this font already, drop the
500: * new one...
501: */
1.73 rin 502: free(newdata, M_DEVBUF);
1.46 nonaka 503: free(newfont, M_DEVBUF);
504: newfont = NULL;
505: }
506:
507: return (newfont);
508: }
509:
1.44 ober 510: int
1.46 nonaka 511: wsfont_rotate(int cookie, int rotate)
1.44 ober 512: {
513: int s, ncookie;
514: struct wsdisplay_font *font;
515: struct font *origfont;
516:
517: s = splhigh();
518: origfont = wsfont_find0(cookie, 0xffffffff);
519: splx(s);
520:
1.72 rin 521: if (origfont == NULL)
522: return (-1);
523:
1.46 nonaka 524: switch (rotate) {
525: case WSFONT_ROTATE_CW:
526: case WSFONT_ROTATE_CCW:
1.73 rin 527: font = wsfont_rotate_internal(origfont->font, rotate);
1.46 nonaka 528: if (font == NULL)
529: return (-1);
530: break;
531:
532: case WSFONT_ROTATE_UD:
533: default:
1.44 ober 534: return (-1);
1.46 nonaka 535: }
1.73 rin 536:
1.44 ober 537: ncookie = wsfont_find(font->name, font->fontwidth, font->fontheight,
1.73 rin 538: font->stride, 0, 0, WSFONT_FIND_ALL);
1.44 ober 539:
540: return (ncookie);
541: }
542:
543: #endif /* NRASOPS_ROTATION */
544:
1.1 ad 545: void
546: wsfont_init(void)
547: {
1.25 ad 548: struct font *ent;
1.1 ad 549: static int again;
550: int i;
1.25 ad 551:
1.9 ad 552: if (again != 0)
1.1 ad 553: return;
554: again = 1;
1.25 ad 555:
556: TAILQ_INIT(&list);
557: ent = builtin_fonts;
558:
559: for (i = 0; builtin_fonts[i].font != NULL; i++, ent++) {
560: ident += (1 << WSFONT_IDENT_SHIFT);
561: ent->cookie = wsfont_make_cookie(ident,
562: ent->font->bitorder, ent->font->byteorder);
563: TAILQ_INSERT_TAIL(&list, ent, chain);
1.1 ad 564: }
565: }
566:
567: static struct font *
1.25 ad 568: wsfont_find0(int cookie, int mask)
1.1 ad 569: {
570: struct font *ent;
1.24 ad 571:
1.25 ad 572: TAILQ_FOREACH(ent, &list, chain) {
573: if ((ent->cookie & mask) == (cookie & mask))
1.1 ad 574: return (ent);
1.25 ad 575: }
1.24 ad 576:
1.1 ad 577: return (NULL);
578: }
579:
1.21 drochner 580: int
1.31 jdolecek 581: wsfont_matches(struct wsdisplay_font *font, const char *name,
1.53 macallan 582: int width, int height, int stride, int flags)
1.21 drochner 583: {
1.59 mlelstv 584: int score = 20000;
1.21 drochner 585:
1.53 macallan 586: /* first weed out fonts the caller doesn't claim support for */
587: if (FONT_IS_ALPHA(font)) {
1.60 macallan 588: if (flags & WSFONT_PREFER_ALPHA)
589: score++;
1.53 macallan 590: if ((flags & WSFONT_FIND_ALPHA) == 0)
591: return 0;
592: } else {
593: if ((flags & WSFONT_FIND_BITMAP) == 0)
594: return 0;
595: }
596:
1.21 drochner 597: if (height != 0 && font->fontheight != height)
598: return (0);
599:
1.58 mlelstv 600: if (width != 0) {
601: if ((flags & WSFONT_FIND_BESTWIDTH) == 0) {
602: if (font->fontwidth != width)
603: return (0);
604: } else {
605: if (font->fontwidth > width)
1.63 riastrad 606: score -= 10000 + uimin(font->fontwidth - width, 9999);
1.59 mlelstv 607: else
1.63 riastrad 608: score -= uimin(width - font->fontwidth, 9999);
1.58 mlelstv 609: }
610: }
1.21 drochner 611:
612: if (stride != 0 && font->stride != stride)
613: return (0);
1.24 ad 614:
1.21 drochner 615: if (name != NULL && strcmp(font->name, name) != 0)
616: return (0);
617:
1.58 mlelstv 618: return (score);
1.21 drochner 619: }
620:
1.1 ad 621: int
1.53 macallan 622: wsfont_find(const char *name, int width, int height, int stride, int bito, int byteo, int flags)
1.1 ad 623: {
1.58 mlelstv 624: struct font *ent, *bestent = NULL;
625: int score, bestscore = 0;
1.24 ad 626:
1.25 ad 627: TAILQ_FOREACH(ent, &list, chain) {
1.58 mlelstv 628: score = wsfont_matches(ent->font, name,
629: width, height, stride, flags);
630: if (score > bestscore) {
631: bestscore = score;
632: bestent = ent;
633: }
1.1 ad 634: }
635:
1.58 mlelstv 636: if (bestent != NULL)
637: return (wsfont_make_cookie(bestent->cookie, bito, byteo));
638:
1.1 ad 639: return (-1);
640: }
641:
1.53 macallan 642: void
643: wsfont_walk(void (*matchfunc)(struct wsdisplay_font *, void *, int), void *cookie)
1.51 macallan 644: {
645: struct font *ent;
646:
1.53 macallan 647: TAILQ_FOREACH(ent, &list, chain) {
648: matchfunc(ent->font, cookie, ent->cookie);
1.51 macallan 649: }
650: }
651:
1.25 ad 652: static struct font *
653: wsfont_add0(struct wsdisplay_font *font, int copy)
1.1 ad 654: {
655: struct font *ent;
1.9 ad 656: size_t size;
1.24 ad 657:
1.28 enami 658: ent = malloc(sizeof(struct font), M_DEVBUF, M_WAITOK | M_ZERO);
1.24 ad 659:
1.1 ad 660: /* Is this font statically allocated? */
661: if (!copy) {
662: ent->font = font;
1.25 ad 663: ent->flags = WSFONT_STATIC;
1.1 ad 664: } else {
1.31 jdolecek 665: void *data;
666: char *name;
667:
1.25 ad 668: ent->font = malloc(sizeof(struct wsdisplay_font), M_DEVBUF,
1.28 enami 669: M_WAITOK);
1.27 ad 670: memcpy(ent->font, font, sizeof(*ent->font));
1.25 ad 671:
1.1 ad 672: size = font->fontheight * font->numchars * font->stride;
1.31 jdolecek 673: data = malloc(size, M_DEVBUF, M_WAITOK);
674: memcpy(data, font->data, size);
675: ent->font->data = data;
676:
677: name = malloc(strlen(font->name) + 1, M_DEVBUF, M_WAITOK);
1.36 itojun 678: strlcpy(name, font->name, strlen(font->name) + 1);
1.31 jdolecek 679: ent->font->name = name;
1.1 ad 680: }
1.24 ad 681:
1.25 ad 682: TAILQ_INSERT_TAIL(&list, ent, chain);
683: return (ent);
684: }
685:
686: int
687: wsfont_add(struct wsdisplay_font *font, int copy)
688: {
689: struct font *ent;
690:
691: /* Don't allow exact duplicates */
692: if (wsfont_find(font->name, font->fontwidth, font->fontheight,
1.53 macallan 693: font->stride, 0, 0, WSFONT_FIND_ALL) >= 0)
1.25 ad 694: return (EEXIST);
695:
696: ent = wsfont_add0(font, copy);
697:
698: ident += (1 << WSFONT_IDENT_SHIFT);
699: ent->cookie = wsfont_make_cookie(ident, font->bitorder,
700: font->byteorder);
701:
1.1 ad 702: return (0);
703: }
1.24 ad 704:
1.1 ad 705: int
1.22 augustss 706: wsfont_remove(int cookie)
1.1 ad 707: {
708: struct font *ent;
709:
1.25 ad 710: if ((ent = wsfont_find0(cookie, 0xffffffff)) == NULL)
1.21 drochner 711: return (ENOENT);
1.24 ad 712:
1.25 ad 713: if ((ent->flags & WSFONT_BUILTIN) != 0 || ent->lockcount != 0)
1.21 drochner 714: return (EBUSY);
1.24 ad 715:
1.25 ad 716: if ((ent->flags & WSFONT_STATIC) == 0) {
1.38 christos 717: free(ent->font->data, M_DEVBUF);
718: free(__UNCONST(ent->font->name), M_DEVBUF); /*XXXUNCONST*/
1.25 ad 719: free(ent->font, M_DEVBUF);
1.1 ad 720: }
1.24 ad 721:
1.25 ad 722: TAILQ_REMOVE(&list, ent, chain);
723: free(ent, M_DEVBUF);
1.24 ad 724:
1.9 ad 725: return (0);
1.1 ad 726: }
727:
728: int
1.25 ad 729: wsfont_lock(int cookie, struct wsdisplay_font **ptr)
1.1 ad 730: {
1.25 ad 731: struct font *ent, *neu;
732: int bito, byteo;
733:
734: if ((ent = wsfont_find0(cookie, 0xffffffff)) == NULL) {
735: if ((ent = wsfont_find0(cookie, WSFONT_IDENT_MASK)) == NULL)
736: return (ENOENT);
737:
1.32 jdolecek 738: bito = (cookie & WSFONT_BITO_MASK) >> WSFONT_BITO_SHIFT;
739: byteo = (cookie & WSFONT_BYTEO_MASK) >> WSFONT_BYTEO_SHIFT;
740:
1.33 jdolecek 741: if (ent->lockcount != 0) {
1.25 ad 742: neu = wsfont_add0(ent->font, 1);
743: neu->flags |= WSFONT_COPY;
1.32 jdolecek 744:
1.35 tsutsui 745: aprint_debug("wsfont: font '%s' bito %d byteo %d "
746: "copied to bito %d byteo %d\n",
747: ent->font->name,
748: ent->font->bitorder, ent->font->byteorder,
749: bito, byteo);
1.32 jdolecek 750:
1.25 ad 751: ent = neu;
752: }
1.24 ad 753:
1.25 ad 754: if (bito && bito != ent->font->bitorder) {
1.1 ad 755: wsfont_revbit(ent->font);
1.25 ad 756: ent->font->bitorder = bito;
1.1 ad 757: }
758:
1.25 ad 759: if (byteo && byteo != ent->font->byteorder) {
1.1 ad 760: wsfont_revbyte(ent->font);
1.25 ad 761: ent->font->byteorder = byteo;
1.1 ad 762: }
1.24 ad 763:
1.25 ad 764: ent->cookie = cookie;
1.1 ad 765: }
1.24 ad 766:
1.25 ad 767: ent->lockcount++;
768: *ptr = ent->font;
769: return (0);
1.1 ad 770: }
771:
772: int
1.22 augustss 773: wsfont_unlock(int cookie)
1.1 ad 774: {
775: struct font *ent;
1.24 ad 776:
1.25 ad 777: if ((ent = wsfont_find0(cookie, 0xffffffff)) == NULL)
778: return (ENOENT);
779:
780: if (ent->lockcount == 0)
1.29 provos 781: panic("wsfont_unlock: font not locked");
1.24 ad 782:
1.25 ad 783: if (--ent->lockcount == 0 && (ent->flags & WSFONT_COPY) != 0)
784: wsfont_remove(cookie);
1.24 ad 785:
1.25 ad 786: return (0);
1.16 marcus 787: }
788:
789: /*
790: * Unicode to font encoding mappings
791: */
792:
793: /*
1.24 ad 794: * To save memory, font encoding tables use a two level lookup. First the
795: * high byte of the Unicode is used to lookup the level 2 table, then the
796: * low byte indexes that table. Level 2 tables that are not needed are
797: * omitted (NULL), and both level 1 and level 2 tables have base and size
798: * attributes to keep their size down.
1.16 marcus 799: */
800:
801: struct wsfont_level1_glyphmap {
1.24 ad 802: const struct wsfont_level2_glyphmap **level2;
803: int base; /* High byte for first level2 entry */
804: int size; /* Number of level2 entries */
1.16 marcus 805: };
806:
807: struct wsfont_level2_glyphmap {
1.24 ad 808: int base; /* Low byte for first character */
809: int size; /* Number of characters */
810: const void *chars; /* Pointer to character number entries */
811: int width; /* Size of each entry in bytes (1,2,4) */
1.16 marcus 812: };
813:
814: #define null16 \
815: NULL, NULL, NULL, NULL, \
816: NULL, NULL, NULL, NULL, \
817: NULL, NULL, NULL, NULL, \
818: NULL, NULL, NULL, NULL
819:
820: /*
821: * IBM 437 maps
822: */
823:
1.24 ad 824: static const u_int8_t ibm437_chars_0[] = {
1.16 marcus 825: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
826: 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
827: 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
828: 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
829: 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
830: 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
831: 96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,
832: 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
833: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
834: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
835: 255,173,155,156, 0, 157, 0, 0, 0, 0, 166,174,170, 0, 0, 0,
836: 0, 241,253, 0, 0, 0, 0, 249, 0, 0, 167,175,172,171, 0, 168,
837: 0, 0, 0, 0, 142,143,146,128, 0, 144, 0, 0, 0, 0, 0, 0,
838: 0, 165, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 154, 0, 0, 0,
839: 133,160,131, 0, 132,134,145,135,138,130,136,137,141,161,140,139,
840: 0, 164,149,162,147, 0, 148,246, 0, 151,163,150,129, 0, 0, 152
1.24 ad 841: };
842:
843: static const u_int8_t ibm437_chars_1[] = {
1.16 marcus 844: 159
1.24 ad 845: };
846:
847: static const u_int8_t ibm437_chars_3[] = {
1.16 marcus 848: 226, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
849: 228, 0, 0, 232, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 224,225,
850: 0, 235,238, 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0,
851: 229,231
1.24 ad 852: };
853:
854: static const u_int8_t ibm437_chars_32[] = {
1.16 marcus 855: 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
856: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
857: 0, 0, 0, 0, 0, 0, 0, 0, 158
1.24 ad 858: };
859:
860: static const u_int8_t ibm437_chars_34[] = {
1.16 marcus 861: 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
862: 0, 0, 0, 248,250,251, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0,
863: 0, 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
864: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
865: 0, 0, 0, 247, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
866: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,240, 0, 0,243,
867: 242
1.24 ad 868: };
869:
870: static const u_int8_t ibm437_chars_35[] = {
1.16 marcus 871: 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
872: 244,245
1.24 ad 873: };
874:
875: static const u_int8_t ibm437_chars_37[] = {
1.16 marcus 876: 196,205,179,186, 0, 0, 0, 0, 0, 0, 0, 0, 218,213,214,201,
877: 191,184,183,187,192,212,211,200,217,190,189,188,195,198, 0, 0,
878: 199, 0, 0, 204,180,181, 0, 0, 182, 0, 0, 185,194, 0, 0, 209,
879: 210, 0, 0, 203,193, 0, 0, 207,208, 0, 0, 202,197, 0, 0, 216,
880: 0, 0, 215, 0, 0, 0, 0, 0, 0, 0, 0, 206, 0, 0, 0, 0,
881: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
882: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
883: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
884: 223, 0, 0, 0, 220, 0, 0, 0, 219, 0, 0, 0, 221, 0, 0, 0,
885: 222,176,177,178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
886: 254
887: };
888:
1.24 ad 889: static const struct wsfont_level2_glyphmap ibm437_level2_0 =
890: { 0, 256, ibm437_chars_0, 1 };
891:
892: static const struct wsfont_level2_glyphmap ibm437_level2_1 =
893: { 146, 1, ibm437_chars_1, 1 };
894:
895: static const struct wsfont_level2_glyphmap ibm437_level2_3 =
896: { 147, 50, ibm437_chars_3, 1 };
897:
898: static const struct wsfont_level2_glyphmap ibm437_level2_32 =
899: { 127, 41, ibm437_chars_32, 1 };
900:
901: static const struct wsfont_level2_glyphmap ibm437_level2_34 =
902: { 5, 97, ibm437_chars_34, 1 };
903:
904: static const struct wsfont_level2_glyphmap ibm437_level2_35 =
905: { 16, 18, ibm437_chars_35, 1 };
1.16 marcus 906:
1.24 ad 907: static const struct wsfont_level2_glyphmap ibm437_level2_37 =
908: { 0, 161, ibm437_chars_37, 1 };
909:
910: static const struct wsfont_level2_glyphmap *ibm437_level1[] = {
1.16 marcus 911: &ibm437_level2_0, &ibm437_level2_1, NULL, &ibm437_level2_3,
912: NULL, NULL, NULL, NULL,
913: NULL, NULL, NULL, NULL,
914: NULL, NULL, NULL, NULL,
915: NULL, NULL, NULL, NULL,
916: NULL, NULL, NULL, NULL,
917: NULL, NULL, NULL, NULL,
918: NULL, NULL, NULL, NULL,
919: &ibm437_level2_32, NULL, &ibm437_level2_34, &ibm437_level2_35,
920: NULL, &ibm437_level2_37
921: };
922:
923: /*
924: * ISO-8859-7 maps
925: */
1.24 ad 926: static const u_int8_t iso7_chars_0[] = {
1.16 marcus 927: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
928: 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
929: 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
930: 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
931: 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
932: 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
933: 96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,
934: 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
935: 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
936: 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
937: 160, 0, 0, 163, 0, 0, 166,167,168,169, 0, 171,172,173, 0, 0,
938: 176,177,178,179,180, 0, 0, 183, 0, 0, 0, 187, 0, 189
1.24 ad 939: };
940:
941: static const u_int8_t iso7_chars_3[] = {
1.16 marcus 942: 182, 0, 184,185,186, 0, 188, 0, 190,191,192,193,194,195,196,197,
943: 198,199,200,201,202,203,204,205,206,207,208,209, 0, 211,212,213,
944: 214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,
945: 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,
946: 246,247,248,249,250,251,252,253,254, 0, 0, 0, 0, 0, 0, 0,
947: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
948: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181
1.24 ad 949: };
950:
1.47 macallan 951: /*
952: * map all variants of the box drawing characters to the same basic shapes for
953: * now, encoded like this:
954: *
955: * 1
956: * 1
957: * 888 222
958: * 4
959: * 4
960: *
961: * so an upright line would be 0x05
962: */
963: #define FL |WSFONT_FLAG_OPT
964: static const u_int32_t netbsd_boxes[] = {
965: /*00*/ 0x0a FL, 0x0a FL, 0x05 FL, 0x05 FL, 0x0a FL, 0x0a FL, 0x05 FL, 0x05 FL,
966: /*08*/ 0x0a FL, 0x0a FL, 0x05 FL, 0x05 FL, 0x06 FL, 0x06 FL, 0x06 FL, 0x06 FL,
967: /*10*/ 0x0c FL, 0x0c FL, 0x0c FL, 0x0c FL, 0x03 FL, 0x03 FL, 0x03 FL, 0x03 FL,
968: /*18*/ 0x09 FL, 0x09 FL, 0x09 FL, 0x09 FL, 0x07 FL, 0x07 FL, 0x07 FL, 0x07 FL,
969: /*20*/ 0x07 FL, 0x07 FL, 0x07 FL, 0x07 FL, 0x0d FL, 0x0d FL, 0x0d FL, 0x0d FL,
970: /*28*/ 0x0d FL, 0x0d FL, 0x0d FL, 0x0d FL, 0x0e FL, 0x0e FL, 0x0e FL, 0x0e FL,
971: /*30*/ 0x0e FL, 0x0e FL, 0x0e FL, 0x0e FL, 0x0b FL, 0x0b FL, 0x0b FL, 0x0b FL,
972: /*38*/ 0x0b FL, 0x0b FL, 0x0b FL, 0x0b FL, 0x0f FL, 0x0f FL, 0x0f FL, 0x0f FL,
973: /*40*/ 0x0f FL, 0x0f FL, 0x0f FL, 0x0f FL, 0x0f FL, 0x0f FL, 0x0f FL, 0x0f FL,
974: /*48*/ 0x0f FL, 0x0f FL, 0x0f FL, 0x0f FL, 0x0a FL, 0x0a FL, 0x05 FL, 0x05 FL,
975: /*50*/ 0x0a FL, 0x05 FL, 0x06 FL, 0x06 FL, 0x06 FL, 0x0c FL, 0x0c FL, 0x0c FL,
976: /*58*/ 0x03 FL, 0x03 FL, 0x03 FL, 0x09 FL, 0x09 FL, 0x09 FL, 0x07 FL, 0x07 FL,
977: /*60*/ 0x07 FL, 0x0d FL, 0x0d FL, 0x0d FL, 0x0e FL, 0x0e FL, 0x0e FL, 0x0b FL,
978: /*68*/ 0x0b FL, 0x0b FL, 0x0f FL, 0x0f FL, 0x0f FL, 0x06 FL, 0x0c FL, 0x09 FL,
979: /*70*/ 0x03 FL, 0 FL, 0 FL, 0 FL, 0x08 FL, 0x01 FL, 0x02 FL, 0x04 FL,
980: /*78*/ 0x08 FL, 0x01 FL, 0x02 FL, 0x04 FL, 0x0a FL, 0x05 FL, 0x0a FL, 0x05 FL
981: };
982: #undef FL
983:
1.24 ad 984: static const u_int8_t iso7_chars_32[] = {
1.16 marcus 985: 175, 0, 0, 0, 0, 162, 0, 161
986: };
987:
1.24 ad 988: static const struct wsfont_level2_glyphmap iso7_level2_0 =
989: { 0, 190, iso7_chars_0, 1 };
990:
991: static const struct wsfont_level2_glyphmap iso7_level2_3 =
992: { 134, 111, iso7_chars_3, 1 };
1.16 marcus 993:
1.24 ad 994: static const struct wsfont_level2_glyphmap iso7_level2_32 =
995: { 20, 8, iso7_chars_32, 1 };
996:
1.47 macallan 997: static const struct wsfont_level2_glyphmap netbsd_box_drawing =
998: { 0, 128, netbsd_boxes, 4 };
999:
1.24 ad 1000: static const struct wsfont_level2_glyphmap *iso7_level1[] = {
1.16 marcus 1001: &iso7_level2_0, NULL, NULL, &iso7_level2_3,
1002: NULL, NULL, NULL, NULL,
1003: NULL, NULL, NULL, NULL,
1004: NULL, NULL, NULL, NULL,
1005: NULL, NULL, NULL, NULL,
1006: NULL, NULL, NULL, NULL,
1007: NULL, NULL, NULL, NULL,
1008: NULL, NULL, NULL, NULL,
1.47 macallan 1009: &iso7_level2_32, NULL, NULL, NULL,
1010: NULL, &netbsd_box_drawing
1011: };
1012:
1013: static const struct wsfont_level2_glyphmap *iso_level1[] = {
1014: NULL, NULL, NULL, NULL,
1015: NULL, NULL, NULL, NULL,
1016: NULL, NULL, NULL, NULL,
1017: NULL, NULL, NULL, NULL,
1018: NULL, NULL, NULL, NULL,
1019: NULL, NULL, NULL, NULL,
1020: NULL, NULL, NULL, NULL,
1021: NULL, NULL, NULL, NULL,
1022: NULL, NULL, NULL, NULL,
1023: NULL, &netbsd_box_drawing
1.16 marcus 1024: };
1025:
1.24 ad 1026: static const struct wsfont_level1_glyphmap encodings[] = {
1.47 macallan 1027: { iso_level1, 0, 0x26 }, /* WSDISPLAY_FONTENC_ISO */
1.16 marcus 1028: { ibm437_level1, 0, 38 }, /* WSDISPLAY_FONTENC_IBM */
1029: { NULL, 0, 0 }, /* WSDISPLAY_FONTENC_PCVT */
1.47 macallan 1030: { iso7_level1, 0, 0x26 }, /* WSDISPLAY_FONTENC_ISO7 */
1.16 marcus 1031: };
1032:
1.19 enami 1033: #define MAX_ENCODING (sizeof(encodings) / sizeof(encodings[0]))
1.16 marcus 1034:
1035: /*
1036: * Remap Unicode character to glyph
1037: */
1038: int
1.22 augustss 1039: wsfont_map_unichar(struct wsdisplay_font *font, int c)
1.16 marcus 1040: {
1.24 ad 1041: const struct wsfont_level1_glyphmap *map1;
1042: const struct wsfont_level2_glyphmap *map2;
1043: int hi, lo;
1.16 marcus 1044:
1.41 chris 1045: if (font->encoding < 0 || font->encoding >= MAX_ENCODING)
1.24 ad 1046: return (-1);
1.16 marcus 1047:
1.24 ad 1048: hi = (c >> 8);
1049: lo = c & 255;
1050: map1 = &encodings[font->encoding];
1051:
1052: if (hi < map1->base || hi >= map1->base + map1->size)
1.16 marcus 1053: return (-1);
1054:
1.24 ad 1055: map2 = map1->level2[hi - map1->base];
1.16 marcus 1056:
1.47 macallan 1057: /* so we don't need an identical level 2 table for hi == 0 */
1058: if (hi == 0 && font->encoding == WSDISPLAY_FONTENC_ISO)
1059: return lo;
1060:
1.24 ad 1061: if (map2 == NULL || lo < map2->base || lo >= map2->base + map2->size)
1062: return (-1);
1.16 marcus 1063:
1.24 ad 1064: lo -= map2->base;
1.16 marcus 1065:
1.24 ad 1066: switch(map2->width) {
1067: case 1:
1068: c = (((const u_int8_t *)map2->chars)[lo]);
1069: break;
1070: case 2:
1071: c = (((const u_int16_t *)map2->chars)[lo]);
1072: break;
1073: case 4:
1074: c = (((const u_int32_t *)map2->chars)[lo]);
1075: break;
1076: }
1.16 marcus 1077:
1.24 ad 1078: if (c == 0 && lo != 0)
1079: return (-1);
1.16 marcus 1080:
1.24 ad 1081: return (c);
1.1 ad 1082: }
CVSweb <webmaster@jp.NetBSD.org>