Home | History | Annotate | Line # | Download | only in wsfont
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