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