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