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