wsfont.c revision 1.14 1 /* $NetBSD: wsfont.c,v 1.14 2000/11/21 11:44:45 tsutsui 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.14 2000/11/21 11:44:45 tsutsui 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 /* Make sure we always have at least one font. */
92 #ifndef HAVE_FONT
93 #define HAVE_FONT 1
94 #define FONT_BOLD8x16 1
95 #endif
96
97 #ifdef FONT_BOLD8x16
98 #include <dev/wsfont/bold8x16.h>
99 #endif
100
101 /* Placeholder struct used for linked list */
102 struct font {
103 struct font *next;
104 struct font *prev;
105 struct wsdisplay_font *font;
106 u_short lockcount;
107 u_short cookie;
108 u_short flg;
109 };
110
111 /* Our list of built-in fonts */
112 static struct font *list, builtin_fonts[] = {
113 #ifdef FONT_BOLD8x16
114 { NULL, NULL, &bold8x16, 0, 1, WSFONT_STATIC | WSFONT_BUILTIN },
115 #endif
116 #ifdef FONT_ISO8x16
117 { NULL, NULL, &iso8x16, 0, 2, WSFONT_STATIC | WSFONT_BUILTIN },
118 #endif
119 #ifdef FONT_COURIER11x18
120 { NULL, NULL, &courier11x18, 0, 3, WSFONT_STATIC | WSFONT_BUILTIN },
121 #endif
122 #ifdef FONT_GALLANT12x22
123 { NULL, NULL, &gallant12x22, 0, 4, WSFONT_STATIC | WSFONT_BUILTIN },
124 #endif
125 #ifdef FONT_LUCIDA16x29
126 { NULL, NULL, &lucida16x29, 0, 5, WSFONT_STATIC | WSFONT_BUILTIN },
127 #endif
128 #ifdef FONT_QVSS8x15
129 { NULL, NULL, &qvss8x15, 0, 6, WSFONT_STATIC | WSFONT_BUILTIN },
130 #endif
131 #ifdef FONT_VT220L8x8
132 { NULL, NULL, &vt220l8x8, 0, 7, WSFONT_STATIC | WSFONT_BUILTIN },
133 #endif
134 #ifdef FONT_VT220L8x10
135 { NULL, NULL, &vt220l8x10, 0, 8, WSFONT_STATIC | WSFONT_BUILTIN },
136 #endif
137 #ifdef FONT_SONY8x16
138 { NULL, NULL, &sony8x16, 0, 9, WSFONT_STATIC | WSFONT_BUILTIN },
139 #endif
140 #ifdef FONT_SONY12x24
141 { NULL, NULL, &sony12x24, 0, 10, WSFONT_STATIC | WSFONT_BUILTIN },
142 #endif
143 { NULL, NULL, NULL, 0 },
144 };
145
146 /* Reverse the bit order in a byte */
147 static const u_char reverse[256] = {
148 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
149 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
150 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
151 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
152 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
153 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
154 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
155 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
156 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
157 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
158 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
159 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
160 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
161 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
162 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
163 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
164 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
165 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
166 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
167 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
168 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
169 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
170 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
171 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
172 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
173 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
174 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
175 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
176 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
177 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
178 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
179 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
180 };
181
182 static struct font *wsfont_find0 __P((int));
183 static void wsfont_revbit __P((struct wsdisplay_font *));
184 static void wsfont_revbyte __P((struct wsdisplay_font *));
185
186 /*
187 * Reverse the bit order of a font
188 */
189 static void
190 wsfont_revbit(font)
191 struct wsdisplay_font *font;
192 {
193 u_char *p, *m;
194
195 p = (u_char *)font->data;
196 m = p + font->stride * font->numchars * font->fontheight;
197
198 while (p < m)
199 *p++ = reverse[*p];
200 }
201
202 /*
203 * Reverse the byte order of a font
204 */
205 static void
206 wsfont_revbyte(font)
207 struct wsdisplay_font *font;
208 {
209 int x, l, r, nr;
210 u_char *rp;
211
212 if (font->stride == 1)
213 return;
214
215 rp = (u_char *)font->data;
216 nr = font->numchars * font->fontheight;
217
218 while (nr--) {
219 l = 0;
220 r = font->stride - 1;
221
222 while (l < r) {
223 x = rp[l];
224 rp[l] = rp[r];
225 rp[r] = x;
226 l++, r--;
227 }
228
229 rp += font->stride;
230 }
231 }
232
233 /*
234 * Enumarate the list of fonts
235 */
236 void
237 wsfont_enum(cb)
238 void (*cb) __P((char *, int, int, int));
239 {
240 struct wsdisplay_font *f;
241 struct font *ent;
242 int s;
243
244 s = splhigh();
245
246 for (ent = list; ent; ent = ent->next) {
247 f = ent->font;
248 cb(f->name, f->fontwidth, f->fontheight, f->stride);
249 }
250
251 splx(s);
252 }
253
254 /*
255 * Initialize list with WSFONT_BUILTIN fonts
256 */
257 void
258 wsfont_init(void)
259 {
260 static int again;
261 int i;
262
263 if (again != 0)
264 return;
265 again = 1;
266
267 for (i = 0; builtin_fonts[i].font != NULL; i++) {
268 builtin_fonts[i].next = list;
269 list = &builtin_fonts[i];
270 }
271 }
272
273 /*
274 * Find a font by cookie. Called at splhigh.
275 */
276 static struct font *
277 wsfont_find0(cookie)
278 int cookie;
279 {
280 struct font *ent;
281
282 for (ent = list; ent != NULL; ent = ent->next)
283 if (ent->cookie == cookie)
284 return (ent);
285
286 return (NULL);
287 }
288
289 /*
290 * Find a font.
291 */
292 int
293 wsfont_find(name, width, height, stride)
294 char *name;
295 int width, height, stride;
296 {
297 struct font *ent;
298 int s;
299
300 s = splhigh();
301
302 for (ent = list; ent != NULL; ent = ent->next) {
303 if (height != 0 && ent->font->fontheight != height)
304 continue;
305
306 if (width != 0 && ent->font->fontwidth != width)
307 continue;
308
309 if (stride != 0 && ent->font->stride != stride)
310 continue;
311
312 if (name != NULL && strcmp(ent->font->name, name) != 0)
313 continue;
314
315 splx(s);
316 return (ent->cookie);
317 }
318
319 splx(s);
320 return (-1);
321 }
322
323 /*
324 * Add a font to the list.
325 */
326 #ifdef notyet
327 int
328 wsfont_add(font, copy)
329 struct wsdisplay_font *font;
330 int copy;
331 {
332 static int cookiegen = 666;
333 struct font *ent;
334 size_t size;
335 int s;
336
337 s = splhigh();
338
339 /* Don't allow exact duplicates */
340 if (wsfont_find(font->name, font->fontwidth, font->fontheight,
341 font->stride) >= 0) {
342 splx(s);
343 return (-1);
344 }
345
346 MALLOC(ent, struct font *, sizeof *ent, M_DEVBUF, M_WAITOK);
347
348 ent->lockcount = 0;
349 ent->flg = 0;
350 ent->cookie = cookiegen++;
351 ent->next = list;
352 ent->prev = NULL;
353
354 /* Is this font statically allocated? */
355 if (!copy) {
356 ent->font = font;
357 ent->flg = WSFONT_STATIC;
358 } else {
359 MALLOC(ent->font, struct wsdisplay_font *, sizeof *ent->font,
360 M_DEVBUF, M_WAITOK);
361 memcpy(ent->font, font, sizeof(*ent->font));
362
363 size = font->fontheight * font->numchars * font->stride;
364 MALLOC(ent->font->data, void *, size, M_DEVBUF, M_WAITOK);
365 memcpy(ent->font->data, font->data, size);
366 ent->flg = 0;
367 }
368
369 /* Now link into the list and return */
370 list = ent;
371 splx(s);
372 return (0);
373 }
374 #endif
375
376 /*
377 * Remove a font.
378 */
379 #ifdef notyet
380 int
381 wsfont_remove(cookie)
382 int cookie;
383 {
384 struct font *ent;
385 int s;
386
387 s = splhigh();
388
389 if ((ent = wsfont_find0(cookie)) == NULL) {
390 splx(s);
391 return (-1);
392 }
393
394 if ((ent->flg & WSFONT_BUILTIN) != 0 || ent->lockcount != 0) {
395 splx(s);
396 return (-1);
397 }
398
399 /* Don't free statically allocated font data */
400 if ((ent->flg & WSFONT_STATIC) != 0) {
401 FREE(ent->font->data, M_DEVBUF);
402 FREE(ent->font, M_DEVBUF);
403 }
404
405 /* Remove from list, free entry */
406 if (ent->prev)
407 ent->prev->next = ent->next;
408 else
409 list = ent->next;
410
411 if (ent->next)
412 ent->next->prev = ent->prev;
413
414 FREE(ent, M_DEVBUF);
415 splx(s);
416 return (0);
417 }
418 #endif
419
420 /*
421 * Lock a given font and return new lockcount. This fails if the cookie
422 * is invalid, or if the font is already locked and the bit/byte order
423 * requested by the caller differs.
424 */
425 int
426 wsfont_lock(cookie, ptr, bitorder, byteorder)
427 int cookie;
428 struct wsdisplay_font **ptr;
429 int bitorder, byteorder;
430 {
431 struct font *ent;
432 int s, lc;
433
434 s = splhigh();
435
436 if ((ent = wsfont_find0(cookie)) != NULL) {
437 if (bitorder && bitorder != ent->font->bitorder) {
438 if (ent->lockcount) {
439 splx(s);
440 return (-1);
441 }
442 wsfont_revbit(ent->font);
443 ent->font->bitorder = bitorder;
444 }
445
446 if (byteorder && byteorder != ent->font->byteorder) {
447 if (ent->lockcount) {
448 splx(s);
449 return (-1);
450 }
451 wsfont_revbyte(ent->font);
452 ent->font->byteorder = byteorder;
453 }
454
455 lc = ++ent->lockcount;
456 *ptr = ent->font;
457 } else
458 lc = -1;
459
460 splx(s);
461 return (lc);
462 }
463
464 /*
465 * Get font flags and lockcount.
466 */
467 int
468 wsfont_getflg(cookie, flg, lc)
469 int cookie, *flg, *lc;
470 {
471 struct font *ent;
472 int s;
473
474 s = splhigh();
475
476 if ((ent = wsfont_find0(cookie)) != NULL) {
477 *flg = ent->flg;
478 *lc = ent->lockcount;
479 }
480
481 splx(s);
482 return (ent != NULL ? 0 : -1);
483 }
484
485 /*
486 * Unlock a given font and return new lockcount.
487 */
488 int
489 wsfont_unlock(cookie)
490 int cookie;
491 {
492 struct font *ent;
493 int s, lc;
494
495 s = splhigh();
496
497 if ((ent = wsfont_find0(cookie)) != NULL) {
498 if (ent->lockcount == 0)
499 panic("wsfont_unlock: font not locked\n");
500 lc = --ent->lockcount;
501 } else
502 lc = -1;
503
504 splx(s);
505 return (lc);
506 }
507