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