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