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