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