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