wsfont.c revision 1.5 1 /* $NetBSD: wsfont.c,v 1.5 1999/04/26 04:24:22 ad Exp $ */
2
3 /*-
4 * Copyright (c) 1999 Andy Doran <ad (at) NetBSD.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 */
29
30 #include <sys/cdefs.h>
31 __KERNEL_RCSID(0, "$NetBSD: wsfont.c,v 1.5 1999/04/26 04:24:22 ad Exp $");
32
33 #include "opt_wsfont.h"
34
35 #include <sys/types.h>
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/time.h>
39 #include <sys/malloc.h>
40
41 #include <dev/wscons/wsdisplayvar.h>
42 #include <dev/wscons/wsconsio.h>
43 #include <dev/wsfont/wsfont.h>
44
45 #undef HAVE_FONT
46
47 #ifdef FONT_QVSS8x15
48 #define HAVE_FONT 1
49 #include <dev/wsfont/qvss8x15.h>
50 #endif
51
52 #ifdef FONT_GALLANT12x22
53 #define HAVE_FONT 1
54 #include <dev/wsfont/gallant12x22.h>
55 #endif
56
57 #ifdef FONT_LUCIDA16x29
58 #define HAVE_FONT 1
59 #include <dev/wsfont/lucida16x29.h>
60 #endif
61
62 /* Make sure we always have at least one font. */
63 #ifndef HAVE_FONT
64 #define HAVE_FONT 1
65 #define FONT_BOLD8x16 1
66 #endif
67
68 #ifdef FONT_BOLD8x16
69 #include <dev/wsfont/bold8x16.h>
70 #endif
71
72 /* Placeholder struct used for linked list */
73 struct font {
74 struct font *next;
75 struct font *prev;
76 struct wsdisplay_font *font;
77 u_short lockcount;
78 u_short cookie;
79 u_short flg;
80 u_char bitorder; /* XXX move to wsdisplay_font */
81 u_char byteorder; /* XXX move to wsdisplay_font */
82 };
83
84 #define WSFONT_BUILTIN (0x01)
85 #define WSFONT_STATIC (0x02)
86
87 /* Our list of built-in fonts */
88 static struct font *list, builtin_fonts[] = {
89 #ifdef FONT_BOLD8x16
90 { NULL, NULL, &bold8x16, 0, 1, WSFONT_STATIC | WSFONT_BUILTIN, 0, 0 },
91 #endif
92 #ifdef FONT_ISO8x16
93 { NULL, NULL, &iso8x16, 0, 2, WSFONT_STATIC | WSFONT_BUILTIN, 0, 0 },
94 #endif
95 #ifdef FONT_COURIER11x18
96 { NULL, NULL, &courier11x18, 0, 3, WSFONT_STATIC | WSFONT_BUILTIN, 0, 0 },
97 #endif
98 #ifdef FONT_GALLANT12x22
99 { NULL, NULL, &gallant12x22, 0, 4, WSFONT_STATIC | WSFONT_BUILTIN, 0, 0 },
100 #endif
101 #ifdef FONT_LUCIDA16x29
102 { NULL, NULL, &lucida16x29, 0, 5, WSFONT_STATIC | WSFONT_BUILTIN, 0, 0 },
103 #endif
104 #ifdef FONT_QVSS8x15
105 { NULL, NULL, &qvss8x15, 0, 6, WSFONT_STATIC | WSFONT_BUILTIN, 0, 0 },
106 #endif
107 { NULL, NULL, NULL, 0, 0, 0 },
108 };
109
110 /* Reverse the bit order in a byte */
111 static const u_char reverse[256] = {
112 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
113 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
114 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
115 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
116 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
117 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
118 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
119 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
120 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
121 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
122 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
123 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
124 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
125 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
126 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
127 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
128 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
129 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
130 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
131 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
132 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
133 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
134 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
135 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
136 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
137 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
138 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
139 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
140 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
141 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
142 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
143 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
144 };
145
146 static struct font *wsfont_find0 __P((int));
147 static void wsfont_revbit __P((struct wsdisplay_font *));
148 static void wsfont_revbyte __P((struct wsdisplay_font *));
149
150
151 /*
152 * Reverse the bit order of a font
153 */
154 static void
155 wsfont_revbit(font)
156 struct wsdisplay_font *font;
157 {
158 u_char *p, *m;
159
160 p = (u_char *)font->data;
161 m = p + font->stride * font->numchars * font->fontheight;
162
163 while (p < m)
164 *p++ = reverse[*p];
165 }
166
167
168 /*
169 * Reverse the byte order of a font
170 */
171 static void
172 wsfont_revbyte(font)
173 struct wsdisplay_font *font;
174 {
175 int x, l, r, nr;
176 u_char *rp;
177
178 if (font->stride == 1)
179 return;
180
181 rp = (u_char *)font->data;
182 nr = font->numchars * font->fontheight;
183
184 while (nr--) {
185 l = 0;
186 r = font->stride - 1;
187
188 while (l < r) {
189 x = rp[l];
190 rp[l] = rp[r];
191 rp[r] = x;
192 l++, r--;
193 }
194
195 rp += font->stride;
196 }
197 }
198
199
200 /*
201 * Enumarate the list of fonts
202 */
203 void
204 wsfont_enum(func)
205 void (*func) __P((char *, int, int, int));
206 {
207 struct font *ent;
208 struct wsdisplay_font *font;
209 int s;
210
211 s = splhigh();
212
213 for (ent = list; ent; ent = ent->next) {
214 font = ent->font;
215 func(font->name, font->fontwidth, font->fontheight,
216 font->stride);
217 }
218
219 splx(s);
220 }
221
222
223 /*
224 * Initialize list with WSFONT_BUILTIN fonts
225 */
226 void
227 wsfont_init(void)
228 {
229 static int again;
230 int i;
231
232 if (again)
233 return;
234
235 again = 1;
236
237 for (i = 0; builtin_fonts[i].font; i++) {
238 builtin_fonts[i].next = list;
239 list = &builtin_fonts[i];
240 }
241 }
242
243
244 /*
245 * Find a font by cookie. Called at splhigh.
246 */
247 static struct font *
248 wsfont_find0(cookie)
249 int cookie;
250 {
251 struct font *ent;
252
253 for (ent = list; ent; ent = ent->next)
254 if (ent->cookie == cookie)
255 return (ent);
256
257 return (NULL);
258 }
259
260
261 /*
262 * Find a font.
263 */
264 int
265 wsfont_find(name, width, height, stride)
266 char *name;
267 int width, height, stride;
268 {
269 struct font *ent;
270 int s;
271
272 s = splhigh();
273
274 for (ent = list; ent; ent = ent->next) {
275 if (height && ent->font->fontheight != height)
276 continue;
277
278 if (width && ent->font->fontwidth != width)
279 continue;
280
281 if (stride && ent->font->stride != stride)
282 continue;
283
284 if (name && strcmp(ent->font->name, name))
285 continue;
286
287 splx(s);
288 return (ent->cookie);
289 }
290
291 splx(s);
292 return (-1);
293 }
294
295
296 /*
297 * Add a font to the list.
298 */
299 #ifdef notyet
300 int
301 wsfont_add(font, copy)
302 struct wsdisplay_font *font;
303 int copy;
304 {
305 struct font *ent;
306 static int cookiegen = 666;
307 int s;
308 size_t size;
309
310 /* Don't allow exact duplicates */
311 s = splhigh();
312
313 if (wsfont_find(font->name, font->fontwidth, font->fontheight,
314 font->stride) >= 0) {
315 splx(s);
316 return (-1);
317 }
318
319 MALLOC(ent, struct font *, sizeof *ent, M_WSCONS, M_WAITOK);
320
321 ent->lockcount = 0;
322 ent->flg = 0;
323 ent->cookie = cookiegen++;
324 ent->next = list;
325 ent->prev = NULL;
326
327 /* Is this font statically allocated? */
328 if (!copy) {
329 ent->font = font;
330 ent->flg = WSFONT_STATIC;
331 } else {
332 MALLOC(ent->font, struct wsdisplay_font *, sizeof *ent->font,
333 M_WSCONS, M_WAITOK);
334 memcpy(ent->font, font, sizeof(*ent->font));
335
336 size = font->fontheight * font->numchars * font->stride;
337 MALLOC(ent->font->data, void *, size, M_WSCONS, M_WAITOK);
338 memcpy(ent->font->data, font->data, size);
339 ent->flg = 0;
340 }
341
342 /* Now link into the list and return */
343 list = ent;
344 splx(s);
345 return (0);
346 }
347 #endif
348
349
350 /*
351 * Remove a font.
352 */
353 #ifdef notyet
354 int
355 wsfont_remove(cookie)
356 int cookie;
357 {
358 struct font *ent;
359 int s;
360
361 s = splhigh();
362
363 if ((ent = wsfont_find0(cookie)) == NULL) {
364 splx(s);
365 return (-1);
366 }
367
368 if ((ent->flg & WSFONT_BUILTIN) || ent->lockcount != 0) {
369 splx(s);
370 return (-1);
371 }
372
373 /* Don't free statically allocated font data */
374 if (!(ent->flg & WSFONT_STATIC)) {
375 FREE(ent->font->data, M_WSCONS);
376 FREE(ent->font, M_WSCONS);
377 }
378
379 /* Remove from list, free entry */
380 if (ent->prev)
381 ent->prev->next = ent->next;
382 else
383 list = ent->next;
384
385 if (ent->next)
386 ent->next->prev = ent->prev;
387
388 FREE(ent, M_WSCONS);
389 splx(s);
390 return (ent ? 0 : -1);
391 }
392 #endif
393
394
395 /*
396 * Lock a given font and return new lockcount. This fails if the cookie
397 * is invalid, or if the font is already locked and the bit/byte order
398 * requested by the caller differs.
399 */
400 int
401 wsfont_lock(cookie, ptr, bitorder, byteorder)
402 int cookie;
403 struct wsdisplay_font **ptr;
404 int bitorder, byteorder;
405 {
406 struct font *ent;
407 int s, lc;
408
409 s = splhigh();
410
411 if ((ent = wsfont_find0(cookie)) != NULL) {
412 if (bitorder != ent->bitorder) {
413 if (ent->lockcount)
414 return (-1);
415
416 wsfont_revbit(ent->font);
417 ent->bitorder = bitorder;
418 }
419
420 if (byteorder != ent->byteorder) {
421 if (ent->lockcount)
422 return (-1);
423
424 wsfont_revbyte(ent->font);
425 ent->byteorder = byteorder;
426 }
427
428 lc = ++ent->lockcount;
429 *ptr = ent->font;
430 } else
431 lc = -1;
432
433
434 splx(s);
435 return (lc);
436 }
437
438
439 /*
440 * Get font flags and lockcount.
441 */
442 int
443 wsfont_getflg(cookie, flg, lc)
444 int cookie, *flg, *lc;
445 {
446 struct font *ent;
447 int s;
448
449 s = splhigh();
450
451 if ((ent = wsfont_find0(cookie)) != NULL) {
452 *flg = ent->flg;
453 *lc = ent->lockcount;
454 }
455
456 splx(s);
457 return (ent ? 0 : -1);
458 }
459
460
461 /*
462 * Unlock a given font and return new lockcount.
463 */
464 int
465 wsfont_unlock(cookie)
466 int cookie;
467 {
468 struct font *ent;
469 int s, lc;
470
471 s = splhigh();
472
473 if ((ent = wsfont_find0(cookie)) != NULL) {
474 if (ent->lockcount == 0)
475 panic("wsfont_unlock: font not locked\n");
476
477 lc = --ent->lockcount;
478 } else
479 lc = -1;
480
481 splx(s);
482 return (lc);
483 }
484