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