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