Home | History | Annotate | Line # | Download | only in wsfont
wsfont.c revision 1.18.2.6
      1  1.18.2.6   nathanw /* 	$NetBSD: wsfont.c,v 1.18.2.6 2002/04/01 07:47:47 nathanw Exp $	*/
      2       1.1        ad 
      3       1.7        ad /*-
      4  1.18.2.6   nathanw  * Copyright (c) 1999, 2000, 2001, 2002 The NetBSD Foundation, Inc.
      5       1.1        ad  * All rights reserved.
      6       1.1        ad  *
      7       1.7        ad  * This code is derived from software contributed to The NetBSD Foundation
      8      1.13        ad  * by Andrew Doran.
      9       1.7        ad  *
     10       1.1        ad  * Redistribution and use in source and binary forms, with or without
     11       1.1        ad  * modification, are permitted provided that the following conditions
     12       1.1        ad  * are met:
     13       1.1        ad  * 1. Redistributions of source code must retain the above copyright
     14       1.1        ad  *    notice, this list of conditions and the following disclaimer.
     15       1.1        ad  * 2. Redistributions in binary form must reproduce the above copyright
     16       1.1        ad  *    notice, this list of conditions and the following disclaimer in the
     17       1.1        ad  *    documentation and/or other materials provided with the distribution.
     18       1.7        ad  * 3. All advertising materials mentioning features or use of this software
     19       1.7        ad  *    must display the following acknowledgement:
     20       1.7        ad  *	This product includes software developed by the NetBSD
     21       1.7        ad  *	Foundation, Inc. and its contributors.
     22       1.7        ad  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23       1.7        ad  *    contributors may be used to endorse or promote products derived
     24       1.7        ad  *    from this software without specific prior written permission.
     25       1.1        ad  *
     26       1.7        ad  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27       1.7        ad  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28       1.7        ad  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29       1.7        ad  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30       1.7        ad  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31       1.7        ad  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32       1.7        ad  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33       1.7        ad  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34       1.7        ad  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35       1.7        ad  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36       1.7        ad  * POSSIBILITY OF SUCH DAMAGE.
     37       1.1        ad  */
     38       1.2        ad 
     39       1.1        ad #include <sys/cdefs.h>
     40  1.18.2.6   nathanw __KERNEL_RCSID(0, "$NetBSD: wsfont.c,v 1.18.2.6 2002/04/01 07:47:47 nathanw Exp $");
     41       1.1        ad 
     42       1.1        ad #include "opt_wsfont.h"
     43       1.1        ad 
     44       1.1        ad #include <sys/param.h>
     45       1.1        ad #include <sys/systm.h>
     46       1.1        ad #include <sys/time.h>
     47       1.1        ad #include <sys/malloc.h>
     48  1.18.2.6   nathanw #include <sys/queue.h>
     49       1.1        ad 
     50       1.1        ad #include <dev/wscons/wsdisplayvar.h>
     51       1.1        ad #include <dev/wscons/wsconsio.h>
     52       1.1        ad #include <dev/wsfont/wsfont.h>
     53       1.1        ad 
     54       1.1        ad #undef HAVE_FONT
     55       1.1        ad 
     56       1.4        ad #ifdef FONT_QVSS8x15
     57       1.1        ad #define HAVE_FONT 1
     58       1.4        ad #include <dev/wsfont/qvss8x15.h>
     59       1.1        ad #endif
     60       1.1        ad 
     61       1.1        ad #ifdef FONT_GALLANT12x22
     62       1.1        ad #define HAVE_FONT 1
     63       1.1        ad #include <dev/wsfont/gallant12x22.h>
     64       1.1        ad #endif
     65       1.1        ad 
     66       1.1        ad #ifdef FONT_LUCIDA16x29
     67       1.1        ad #define HAVE_FONT 1
     68       1.1        ad #include <dev/wsfont/lucida16x29.h>
     69       1.1        ad #endif
     70       1.1        ad 
     71       1.8  takemura #ifdef FONT_VT220L8x8
     72       1.8  takemura #define HAVE_FONT 1
     73       1.8  takemura #include <dev/wsfont/vt220l8x8.h>
     74       1.8  takemura #endif
     75       1.8  takemura 
     76       1.8  takemura #ifdef FONT_VT220L8x10
     77       1.8  takemura #define HAVE_FONT 1
     78       1.8  takemura #include <dev/wsfont/vt220l8x10.h>
     79       1.8  takemura #endif
     80       1.8  takemura 
     81      1.14   tsutsui #ifdef FONT_SONY8x16
     82      1.14   tsutsui #define HAVE_FONT 1
     83      1.14   tsutsui #include <dev/wsfont/sony8x16.h>
     84      1.14   tsutsui #endif
     85      1.14   tsutsui 
     86      1.14   tsutsui #ifdef FONT_SONY12x24
     87      1.14   tsutsui #define HAVE_FONT 1
     88      1.14   tsutsui #include <dev/wsfont/sony12x24.h>
     89      1.14   tsutsui #endif
     90      1.14   tsutsui 
     91      1.15   tsutsui #ifdef FONT_OMRON12x20
     92      1.15   tsutsui #define HAVE_FONT 1
     93      1.15   tsutsui #include <dev/wsfont/omron12x20.h>
     94      1.15   tsutsui #endif
     95      1.15   tsutsui 
     96       1.4        ad /* Make sure we always have at least one font. */
     97       1.1        ad #ifndef HAVE_FONT
     98       1.1        ad #define HAVE_FONT 1
     99       1.4        ad #define FONT_BOLD8x16 1
    100       1.1        ad #endif
    101       1.1        ad 
    102       1.4        ad #ifdef FONT_BOLD8x16
    103       1.4        ad #include <dev/wsfont/bold8x16.h>
    104       1.1        ad #endif
    105       1.1        ad 
    106  1.18.2.6   nathanw #define	WSFONT_IDENT_MASK	0xffffff00
    107  1.18.2.6   nathanw #define	WSFONT_IDENT_SHIFT	8
    108  1.18.2.6   nathanw #define	WSFONT_BITO_MASK	0x000000f0
    109  1.18.2.6   nathanw #define	WSFONT_BITO_SHIFT	4
    110  1.18.2.6   nathanw #define	WSFONT_BYTEO_MASK	0x0000000f
    111  1.18.2.6   nathanw #define	WSFONT_BYTEO_SHIFT	0
    112  1.18.2.6   nathanw 
    113  1.18.2.6   nathanw #define WSFONT_BUILTIN	0x01	/* In wsfont.c */
    114  1.18.2.6   nathanw #define WSFONT_STATIC	0x02	/* Font structures not malloc()ed */
    115  1.18.2.6   nathanw #define WSFONT_COPY	0x04	/* Copy of existing font in table */
    116  1.18.2.6   nathanw 
    117       1.1        ad /* Placeholder struct used for linked list */
    118       1.1        ad struct font {
    119  1.18.2.6   nathanw 	TAILQ_ENTRY(font) chain;
    120       1.1        ad 	struct	wsdisplay_font *font;
    121  1.18.2.6   nathanw 	u_int	lockcount;
    122  1.18.2.6   nathanw 	u_int	cookie;
    123  1.18.2.6   nathanw 	u_int	flags;
    124  1.18.2.6   nathanw };
    125       1.1        ad 
    126       1.1        ad /* Our list of built-in fonts */
    127  1.18.2.6   nathanw static struct font builtin_fonts[] = {
    128       1.1        ad #ifdef FONT_BOLD8x16
    129  1.18.2.6   nathanw 	{ { NULL }, &bold8x16, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN  },
    130       1.1        ad #endif
    131       1.1        ad #ifdef FONT_ISO8x16
    132  1.18.2.6   nathanw 	{ { NULL }, &iso8x16, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
    133       1.1        ad #endif
    134       1.1        ad #ifdef FONT_COURIER11x18
    135  1.18.2.6   nathanw 	{ { NULL }, &courier11x18, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
    136       1.1        ad #endif
    137       1.1        ad #ifdef FONT_GALLANT12x22
    138  1.18.2.6   nathanw 	{ { NULL }, &gallant12x22, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
    139       1.1        ad #endif
    140       1.1        ad #ifdef FONT_LUCIDA16x29
    141  1.18.2.6   nathanw 	{ { NULL }, &lucida16x29, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
    142       1.1        ad #endif
    143       1.1        ad #ifdef FONT_QVSS8x15
    144  1.18.2.6   nathanw 	{ { NULL }, &qvss8x15, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
    145       1.8  takemura #endif
    146       1.8  takemura #ifdef FONT_VT220L8x8
    147  1.18.2.6   nathanw 	{ { NULL }, &vt220l8x8, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
    148       1.8  takemura #endif
    149       1.8  takemura #ifdef FONT_VT220L8x10
    150  1.18.2.6   nathanw 	{ { NULL }, &vt220l8x10, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
    151      1.14   tsutsui #endif
    152      1.14   tsutsui #ifdef FONT_SONY8x16
    153  1.18.2.6   nathanw 	{ { NULL }, &sony8x16, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
    154      1.14   tsutsui #endif
    155      1.14   tsutsui #ifdef FONT_SONY12x24
    156  1.18.2.6   nathanw 	{ { NULL }, &sony12x24, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
    157      1.15   tsutsui #endif
    158      1.15   tsutsui #ifdef FONT_OMRON12x20
    159  1.18.2.6   nathanw 	{ { NULL }, &omron12x20, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
    160       1.1        ad #endif
    161  1.18.2.6   nathanw 	{ { NULL }, NULL, 0, 0, 0 },
    162       1.1        ad };
    163       1.1        ad 
    164  1.18.2.6   nathanw static TAILQ_HEAD(,font)	list;
    165  1.18.2.6   nathanw static int	ident;
    166  1.18.2.6   nathanw 
    167       1.1        ad /* Reverse the bit order in a byte */
    168       1.1        ad static const u_char reverse[256] = {
    169       1.1        ad 	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
    170       1.1        ad 	0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
    171       1.1        ad 	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
    172       1.1        ad 	0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
    173       1.1        ad 	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
    174       1.1        ad 	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
    175       1.1        ad 	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
    176       1.1        ad 	0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
    177       1.1        ad 	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
    178       1.1        ad 	0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
    179       1.1        ad 	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
    180       1.1        ad 	0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
    181       1.1        ad 	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
    182       1.1        ad 	0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
    183       1.1        ad 	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
    184       1.1        ad 	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
    185       1.1        ad 	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
    186       1.1        ad 	0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
    187       1.1        ad 	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
    188       1.1        ad 	0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
    189       1.1        ad 	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
    190       1.1        ad 	0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
    191       1.1        ad 	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
    192       1.1        ad 	0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
    193       1.1        ad 	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
    194       1.1        ad 	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
    195       1.1        ad 	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
    196       1.1        ad 	0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
    197       1.1        ad 	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
    198       1.1        ad 	0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
    199       1.1        ad 	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
    200       1.1        ad 	0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
    201       1.1        ad };
    202       1.1        ad 
    203  1.18.2.6   nathanw static struct	font *wsfont_find0(int, int);
    204  1.18.2.6   nathanw static struct	font *wsfont_add0(struct wsdisplay_font *, int);
    205  1.18.2.4   nathanw static void	wsfont_revbit(struct wsdisplay_font *);
    206  1.18.2.4   nathanw static void	wsfont_revbyte(struct wsdisplay_font *);
    207  1.18.2.6   nathanw static int __inline__ wsfont_make_cookie(int, int, int);
    208  1.18.2.6   nathanw 
    209  1.18.2.6   nathanw static int __inline__
    210  1.18.2.6   nathanw wsfont_make_cookie(int ident, int bito, int byteo)
    211  1.18.2.6   nathanw {
    212  1.18.2.6   nathanw 
    213  1.18.2.6   nathanw 	return ((ident & WSFONT_IDENT_MASK) |
    214  1.18.2.6   nathanw 	    (bito << WSFONT_BITO_SHIFT) |
    215  1.18.2.6   nathanw 	    (byteo << WSFONT_BYTEO_SHIFT));
    216  1.18.2.6   nathanw }
    217       1.1        ad 
    218       1.1        ad static void
    219  1.18.2.4   nathanw wsfont_revbit(struct wsdisplay_font *font)
    220       1.1        ad {
    221       1.1        ad 	u_char *p, *m;
    222  1.18.2.6   nathanw 
    223       1.1        ad 	p = (u_char *)font->data;
    224       1.1        ad 	m = p + font->stride * font->numchars * font->fontheight;
    225      1.18       cgd 
    226      1.18       cgd 	for (; p < m; p++)
    227      1.18       cgd 		*p = reverse[*p];
    228       1.1        ad }
    229       1.1        ad 
    230       1.1        ad static void
    231  1.18.2.4   nathanw wsfont_revbyte(struct wsdisplay_font *font)
    232       1.1        ad {
    233       1.1        ad 	int x, l, r, nr;
    234       1.1        ad 	u_char *rp;
    235  1.18.2.6   nathanw 
    236       1.1        ad 	if (font->stride == 1)
    237       1.1        ad 		return;
    238       1.1        ad 
    239       1.1        ad 	rp = (u_char *)font->data;
    240       1.1        ad 	nr = font->numchars * font->fontheight;
    241  1.18.2.6   nathanw 
    242       1.1        ad 	while (nr--) {
    243       1.1        ad 		l = 0;
    244       1.1        ad 		r = font->stride - 1;
    245  1.18.2.6   nathanw 
    246       1.1        ad 		while (l < r) {
    247       1.1        ad 			x = rp[l];
    248       1.1        ad 			rp[l] = rp[r];
    249       1.1        ad 			rp[r] = x;
    250       1.1        ad 			l++, r--;
    251       1.1        ad 		}
    252  1.18.2.6   nathanw 
    253       1.1        ad 		rp += font->stride;
    254       1.1        ad 	}
    255       1.1        ad }
    256       1.1        ad 
    257       1.1        ad void
    258  1.18.2.4   nathanw wsfont_enum(void (*cb)(char *, int, int, int))
    259       1.1        ad {
    260       1.9        ad 	struct wsdisplay_font *f;
    261       1.1        ad 	struct font *ent;
    262  1.18.2.6   nathanw 
    263  1.18.2.6   nathanw 	TAILQ_FOREACH(ent, &list, chain) {
    264       1.9        ad 		f = ent->font;
    265       1.9        ad 		cb(f->name, f->fontwidth, f->fontheight, f->stride);
    266       1.1        ad 	}
    267       1.1        ad }
    268       1.1        ad 
    269       1.1        ad void
    270       1.1        ad wsfont_init(void)
    271       1.1        ad {
    272  1.18.2.6   nathanw 	struct font *ent;
    273       1.1        ad 	static int again;
    274       1.1        ad 	int i;
    275  1.18.2.6   nathanw 
    276       1.9        ad 	if (again != 0)
    277       1.1        ad 		return;
    278       1.1        ad 	again = 1;
    279  1.18.2.6   nathanw 
    280  1.18.2.6   nathanw 	TAILQ_INIT(&list);
    281  1.18.2.6   nathanw 	ent = builtin_fonts;
    282  1.18.2.6   nathanw 
    283  1.18.2.6   nathanw 	for (i = 0; builtin_fonts[i].font != NULL; i++, ent++) {
    284  1.18.2.6   nathanw 		ident += (1 << WSFONT_IDENT_SHIFT);
    285  1.18.2.6   nathanw 		ent->cookie = wsfont_make_cookie(ident,
    286  1.18.2.6   nathanw 		    ent->font->bitorder, ent->font->byteorder);
    287  1.18.2.6   nathanw 		TAILQ_INSERT_TAIL(&list, ent, chain);
    288       1.1        ad 	}
    289       1.1        ad }
    290       1.1        ad 
    291       1.1        ad static struct font *
    292  1.18.2.6   nathanw wsfont_find0(int cookie, int mask)
    293       1.1        ad {
    294       1.1        ad 	struct font *ent;
    295  1.18.2.6   nathanw 
    296  1.18.2.6   nathanw 	TAILQ_FOREACH(ent, &list, chain) {
    297  1.18.2.6   nathanw 		if ((ent->cookie & mask) == (cookie & mask))
    298       1.1        ad 			return (ent);
    299  1.18.2.6   nathanw 	}
    300  1.18.2.6   nathanw 
    301       1.1        ad 	return (NULL);
    302       1.1        ad }
    303       1.1        ad 
    304  1.18.2.3   nathanw int
    305  1.18.2.4   nathanw wsfont_matches(struct wsdisplay_font *font, char *name,
    306  1.18.2.4   nathanw 	       int width, int height, int stride)
    307  1.18.2.3   nathanw {
    308  1.18.2.3   nathanw 
    309  1.18.2.3   nathanw 	if (height != 0 && font->fontheight != height)
    310  1.18.2.3   nathanw 		return (0);
    311  1.18.2.3   nathanw 
    312  1.18.2.3   nathanw 	if (width != 0 && font->fontwidth != width)
    313  1.18.2.3   nathanw 		return (0);
    314  1.18.2.3   nathanw 
    315  1.18.2.3   nathanw 	if (stride != 0 && font->stride != stride)
    316  1.18.2.3   nathanw 		return (0);
    317  1.18.2.6   nathanw 
    318  1.18.2.3   nathanw 	if (name != NULL && strcmp(font->name, name) != 0)
    319  1.18.2.3   nathanw 		return (0);
    320  1.18.2.3   nathanw 
    321  1.18.2.3   nathanw 	return (1);
    322  1.18.2.3   nathanw }
    323  1.18.2.3   nathanw 
    324       1.1        ad int
    325  1.18.2.6   nathanw wsfont_find(char *name, int width, int height, int stride, int bito, int byteo)
    326       1.1        ad {
    327       1.1        ad 	struct font *ent;
    328  1.18.2.6   nathanw 
    329  1.18.2.6   nathanw 	TAILQ_FOREACH(ent, &list, chain) {
    330  1.18.2.6   nathanw 		if (wsfont_matches(ent->font, name, width, height, stride))
    331  1.18.2.6   nathanw 			return (wsfont_make_cookie(ent->cookie, bito, byteo));
    332       1.1        ad 	}
    333       1.1        ad 
    334       1.1        ad 	return (-1);
    335       1.1        ad }
    336       1.1        ad 
    337  1.18.2.6   nathanw static struct font *
    338  1.18.2.6   nathanw wsfont_add0(struct wsdisplay_font *font, int copy)
    339       1.1        ad {
    340       1.1        ad 	struct font *ent;
    341       1.9        ad 	size_t size;
    342  1.18.2.6   nathanw 
    343  1.18.2.6   nathanw 	ent = malloc(sizeof(struct font), M_DEVBUF, M_WAITOK | M_ZERO);
    344  1.18.2.6   nathanw 
    345       1.1        ad 	/* Is this font statically allocated? */
    346       1.1        ad 	if (!copy) {
    347       1.1        ad 		ent->font = font;
    348  1.18.2.6   nathanw 		ent->flags = WSFONT_STATIC;
    349       1.1        ad 	} else {
    350  1.18.2.6   nathanw 		ent->font = malloc(sizeof(struct wsdisplay_font), M_DEVBUF,
    351  1.18.2.6   nathanw 		    M_WAITOK);
    352       1.1        ad 		memcpy(ent->font, font, sizeof(*ent->font));
    353  1.18.2.6   nathanw 
    354       1.1        ad 		size = font->fontheight * font->numchars * font->stride;
    355  1.18.2.6   nathanw 		ent->font->data = malloc(size, M_DEVBUF, M_WAITOK);
    356       1.1        ad 		memcpy(ent->font->data, font->data, size);
    357  1.18.2.6   nathanw 
    358  1.18.2.6   nathanw 		ent->font->name = malloc(strlen(font->name) + 1, M_DEVBUF,
    359  1.18.2.6   nathanw 		    M_WAITOK);
    360  1.18.2.3   nathanw 		strcpy(ent->font->name, font->name);
    361       1.1        ad 	}
    362  1.18.2.6   nathanw 
    363  1.18.2.6   nathanw 	TAILQ_INSERT_TAIL(&list, ent, chain);
    364  1.18.2.6   nathanw 	return (ent);
    365  1.18.2.6   nathanw }
    366  1.18.2.6   nathanw 
    367  1.18.2.6   nathanw int
    368  1.18.2.6   nathanw wsfont_add(struct wsdisplay_font *font, int copy)
    369  1.18.2.6   nathanw {
    370  1.18.2.6   nathanw 	struct font *ent;
    371  1.18.2.6   nathanw 
    372  1.18.2.6   nathanw 	/* Don't allow exact duplicates */
    373  1.18.2.6   nathanw 	if (wsfont_find(font->name, font->fontwidth, font->fontheight,
    374  1.18.2.6   nathanw 	    font->stride, 0, 0) >= 0)
    375  1.18.2.6   nathanw 		return (EEXIST);
    376  1.18.2.6   nathanw 
    377  1.18.2.6   nathanw 	ent = wsfont_add0(font, copy);
    378  1.18.2.6   nathanw 
    379  1.18.2.6   nathanw 	ident += (1 << WSFONT_IDENT_SHIFT);
    380  1.18.2.6   nathanw 	ent->cookie = wsfont_make_cookie(ident, font->bitorder,
    381  1.18.2.6   nathanw 	    font->byteorder);
    382  1.18.2.6   nathanw 
    383       1.1        ad 	return (0);
    384       1.1        ad }
    385  1.18.2.6   nathanw 
    386       1.1        ad int
    387  1.18.2.4   nathanw wsfont_remove(int cookie)
    388       1.1        ad {
    389       1.1        ad 	struct font *ent;
    390       1.1        ad 
    391  1.18.2.6   nathanw 	if ((ent = wsfont_find0(cookie, 0xffffffff)) == NULL)
    392  1.18.2.3   nathanw 		return (ENOENT);
    393  1.18.2.6   nathanw 
    394  1.18.2.6   nathanw 	if ((ent->flags & WSFONT_BUILTIN) != 0 || ent->lockcount != 0)
    395  1.18.2.3   nathanw 		return (EBUSY);
    396  1.18.2.6   nathanw 
    397  1.18.2.6   nathanw 	if ((ent->flags & WSFONT_STATIC) == 0) {
    398  1.18.2.6   nathanw 		free(ent->font->data, M_DEVBUF);
    399  1.18.2.6   nathanw 		free(ent->font->name, M_DEVBUF);
    400  1.18.2.6   nathanw 		free(ent->font, M_DEVBUF);
    401       1.1        ad 	}
    402  1.18.2.6   nathanw 
    403  1.18.2.6   nathanw 	TAILQ_REMOVE(&list, ent, chain);
    404  1.18.2.6   nathanw 	free(ent, M_DEVBUF);
    405  1.18.2.6   nathanw 
    406       1.9        ad 	return (0);
    407       1.1        ad }
    408       1.1        ad 
    409       1.1        ad int
    410  1.18.2.6   nathanw wsfont_lock(int cookie, struct wsdisplay_font **ptr)
    411       1.1        ad {
    412  1.18.2.6   nathanw 	struct font *ent, *neu;
    413  1.18.2.6   nathanw 	int bito, byteo;
    414  1.18.2.6   nathanw 
    415  1.18.2.6   nathanw 	if ((ent = wsfont_find0(cookie, 0xffffffff)) == NULL) {
    416  1.18.2.6   nathanw 		if ((ent = wsfont_find0(cookie, WSFONT_IDENT_MASK)) == NULL)
    417  1.18.2.6   nathanw 			return (ENOENT);
    418  1.18.2.6   nathanw 
    419  1.18.2.6   nathanw 		if (ent->lockcount != 0) {
    420  1.18.2.6   nathanw 			neu = wsfont_add0(ent->font, 1);
    421  1.18.2.6   nathanw 			neu->flags |= WSFONT_COPY;
    422  1.18.2.6   nathanw 			ent = neu;
    423  1.18.2.6   nathanw 		}
    424  1.18.2.6   nathanw 
    425  1.18.2.6   nathanw 		bito = (cookie & WSFONT_BITO_MASK) >> WSFONT_BITO_SHIFT;
    426  1.18.2.6   nathanw 		byteo = (cookie & WSFONT_BYTEO_MASK) >> WSFONT_BYTEO_SHIFT;
    427  1.18.2.6   nathanw 
    428  1.18.2.6   nathanw 		if (bito && bito != ent->font->bitorder) {
    429       1.1        ad 			wsfont_revbit(ent->font);
    430  1.18.2.6   nathanw 			ent->font->bitorder = bito;
    431       1.1        ad 		}
    432       1.1        ad 
    433  1.18.2.6   nathanw 		if (byteo && byteo != ent->font->byteorder) {
    434       1.1        ad 			wsfont_revbyte(ent->font);
    435  1.18.2.6   nathanw 			ent->font->byteorder = byteo;
    436       1.1        ad 		}
    437       1.1        ad 
    438  1.18.2.6   nathanw 		ent->cookie = cookie;
    439       1.1        ad 	}
    440  1.18.2.6   nathanw 
    441  1.18.2.6   nathanw 	ent->lockcount++;
    442  1.18.2.6   nathanw 	*ptr = ent->font;
    443  1.18.2.6   nathanw 	return (0);
    444       1.1        ad }
    445       1.1        ad 
    446       1.1        ad int
    447  1.18.2.4   nathanw wsfont_unlock(int cookie)
    448       1.1        ad {
    449       1.1        ad 	struct font *ent;
    450      1.16    marcus 
    451  1.18.2.6   nathanw 	if ((ent = wsfont_find0(cookie, 0xffffffff)) == NULL)
    452  1.18.2.6   nathanw 		return (ENOENT);
    453  1.18.2.6   nathanw 
    454  1.18.2.6   nathanw 	if (ent->lockcount == 0)
    455  1.18.2.6   nathanw 		panic("wsfont_unlock: font not locked\n");
    456  1.18.2.6   nathanw 
    457  1.18.2.6   nathanw 	if (--ent->lockcount == 0 && (ent->flags & WSFONT_COPY) != 0)
    458  1.18.2.6   nathanw 		wsfont_remove(cookie);
    459  1.18.2.6   nathanw 
    460  1.18.2.6   nathanw 	return (0);
    461  1.18.2.6   nathanw }
    462      1.16    marcus 
    463      1.16    marcus /*
    464      1.16    marcus  * Unicode to font encoding mappings
    465      1.16    marcus  */
    466      1.16    marcus 
    467      1.16    marcus /*
    468  1.18.2.6   nathanw  * To save memory, font encoding tables use a two level lookup.  First the
    469  1.18.2.6   nathanw  * high byte of the Unicode is used to lookup the level 2 table, then the
    470  1.18.2.6   nathanw  * low byte indexes that table.  Level 2 tables that are not needed are
    471  1.18.2.6   nathanw  * omitted (NULL), and both level 1 and level 2 tables have base and size
    472  1.18.2.6   nathanw  * attributes to keep their size down.
    473      1.16    marcus  */
    474      1.16    marcus 
    475      1.16    marcus struct wsfont_level1_glyphmap {
    476  1.18.2.6   nathanw 	const struct	wsfont_level2_glyphmap **level2;
    477  1.18.2.6   nathanw 	int	base;	/* High byte for first level2 entry	*/
    478  1.18.2.6   nathanw 	int	size;	/* Number of level2 entries		*/
    479      1.16    marcus };
    480      1.16    marcus 
    481      1.16    marcus struct wsfont_level2_glyphmap {
    482  1.18.2.6   nathanw 	int	base;	/* Low byte for first character		*/
    483  1.18.2.6   nathanw 	int	size;	/* Number of characters			*/
    484  1.18.2.6   nathanw 	const void	*chars;	/* Pointer to character number entries  */
    485  1.18.2.6   nathanw 	int	width;	/* Size of each entry in bytes (1,2,4)  */
    486      1.16    marcus };
    487      1.16    marcus 
    488      1.16    marcus #define null16			\
    489      1.16    marcus 	NULL, NULL, NULL, NULL,	\
    490      1.16    marcus 	NULL, NULL, NULL, NULL,	\
    491      1.16    marcus 	NULL, NULL, NULL, NULL,	\
    492      1.16    marcus 	NULL, NULL, NULL, NULL
    493      1.16    marcus 
    494      1.16    marcus /*
    495      1.16    marcus  * IBM 437 maps
    496      1.16    marcus  */
    497      1.16    marcus 
    498  1.18.2.6   nathanw static const u_int8_t ibm437_chars_0[] = {
    499      1.16    marcus 	 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
    500      1.16    marcus 	16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
    501      1.16    marcus 	32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
    502      1.16    marcus 	48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
    503      1.16    marcus 	64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
    504      1.16    marcus 	80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
    505      1.16    marcus 	96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,
    506      1.16    marcus 	112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
    507      1.16    marcus 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    508      1.16    marcus 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    509      1.16    marcus 	255,173,155,156, 0, 157, 0,  0,  0,  0, 166,174,170, 0,  0,  0,
    510      1.16    marcus 	 0, 241,253, 0,  0,  0,  0, 249, 0,  0, 167,175,172,171, 0, 168,
    511      1.16    marcus 	 0,  0,  0,  0, 142,143,146,128, 0, 144, 0,  0,  0,  0,  0,  0,
    512      1.16    marcus 	 0, 165, 0,  0,  0,  0, 153, 0,  0,  0,  0,  0, 154, 0,  0,  0,
    513      1.16    marcus 	133,160,131, 0, 132,134,145,135,138,130,136,137,141,161,140,139,
    514      1.16    marcus 	 0, 164,149,162,147, 0, 148,246, 0, 151,163,150,129, 0,  0, 152
    515  1.18.2.6   nathanw };
    516  1.18.2.6   nathanw 
    517  1.18.2.6   nathanw static const u_int8_t ibm437_chars_1[] = {
    518      1.16    marcus 	159
    519  1.18.2.6   nathanw };
    520  1.18.2.6   nathanw 
    521  1.18.2.6   nathanw static const u_int8_t ibm437_chars_3[] = {
    522      1.16    marcus 	226, 0,  0,  0,  0, 233, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    523      1.16    marcus 	228, 0,  0, 232, 0,  0, 234, 0,  0,  0,  0,  0,  0,  0, 224,225,
    524      1.16    marcus 	 0, 235,238, 0,  0,  0,  0,  0,  0, 230, 0,  0,  0, 227, 0,  0,
    525      1.16    marcus 	229,231
    526  1.18.2.6   nathanw };
    527  1.18.2.6   nathanw 
    528  1.18.2.6   nathanw static const u_int8_t ibm437_chars_32[] = {
    529      1.16    marcus 	252, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    530      1.16    marcus 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    531      1.16    marcus 	 0,  0,  0,  0,  0,  0,  0,  0, 158
    532  1.18.2.6   nathanw };
    533  1.18.2.6   nathanw 
    534  1.18.2.6   nathanw static const u_int8_t ibm437_chars_34[] = {
    535      1.16    marcus 	237, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    536      1.16    marcus 	 0,  0,  0, 248,250,251, 0,  0,  0, 236, 0,  0,  0,  0,  0,  0,
    537      1.16    marcus 	 0,  0,  0,  0, 239, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    538      1.16    marcus 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    539      1.16    marcus 	 0,  0,  0, 247, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    540      1.16    marcus 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,240,  0,  0,243,
    541      1.16    marcus 	242
    542  1.18.2.6   nathanw };
    543  1.18.2.6   nathanw 
    544  1.18.2.6   nathanw static const u_int8_t ibm437_chars_35[] = {
    545      1.16    marcus 	169, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    546      1.16    marcus 	244,245
    547  1.18.2.6   nathanw };
    548  1.18.2.6   nathanw 
    549  1.18.2.6   nathanw static const u_int8_t ibm437_chars_37[] = {
    550      1.16    marcus 	196,205,179,186, 0,  0,  0,  0,  0,  0,  0,  0, 218,213,214,201,
    551      1.16    marcus 	191,184,183,187,192,212,211,200,217,190,189,188,195,198, 0,  0,
    552      1.16    marcus 	199, 0,  0, 204,180,181, 0,  0, 182, 0,  0, 185,194, 0,  0, 209,
    553      1.16    marcus 	210, 0,  0, 203,193, 0,  0, 207,208, 0,  0, 202,197, 0,  0, 216,
    554      1.16    marcus 	 0,  0, 215, 0,  0,  0,  0,  0,  0,  0,  0, 206, 0,  0,  0,  0,
    555      1.16    marcus 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    556      1.16    marcus 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    557      1.16    marcus 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    558      1.16    marcus 	223, 0,  0,  0, 220, 0,  0,  0, 219, 0,  0,  0, 221, 0,  0,  0,
    559      1.16    marcus 	222,176,177,178, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    560      1.16    marcus 	254
    561      1.16    marcus };
    562      1.16    marcus 
    563  1.18.2.6   nathanw static const struct wsfont_level2_glyphmap ibm437_level2_0 =
    564  1.18.2.6   nathanw     { 0, 256, ibm437_chars_0, 1 };
    565  1.18.2.6   nathanw 
    566  1.18.2.6   nathanw static const struct wsfont_level2_glyphmap ibm437_level2_1 =
    567  1.18.2.6   nathanw     { 146, 1, ibm437_chars_1, 1 };
    568  1.18.2.6   nathanw 
    569  1.18.2.6   nathanw static const struct wsfont_level2_glyphmap ibm437_level2_3 =
    570  1.18.2.6   nathanw     { 147, 50, ibm437_chars_3, 1 };
    571  1.18.2.6   nathanw 
    572  1.18.2.6   nathanw static const struct wsfont_level2_glyphmap ibm437_level2_32 =
    573  1.18.2.6   nathanw     { 127, 41, ibm437_chars_32, 1 };
    574  1.18.2.6   nathanw 
    575  1.18.2.6   nathanw static const struct wsfont_level2_glyphmap ibm437_level2_34 =
    576  1.18.2.6   nathanw     { 5, 97, ibm437_chars_34, 1 };
    577  1.18.2.6   nathanw 
    578  1.18.2.6   nathanw static const struct wsfont_level2_glyphmap ibm437_level2_35 =
    579  1.18.2.6   nathanw     { 16, 18, ibm437_chars_35, 1 };
    580  1.18.2.6   nathanw 
    581  1.18.2.6   nathanw static const struct wsfont_level2_glyphmap ibm437_level2_37 =
    582  1.18.2.6   nathanw     { 0, 161, ibm437_chars_37, 1 };
    583      1.16    marcus 
    584  1.18.2.6   nathanw static const struct wsfont_level2_glyphmap *ibm437_level1[] = {
    585      1.16    marcus 	&ibm437_level2_0, &ibm437_level2_1, NULL, &ibm437_level2_3,
    586      1.16    marcus 	NULL, NULL, NULL, NULL,
    587      1.16    marcus 	NULL, NULL, NULL, NULL,
    588      1.16    marcus 	NULL, NULL, NULL, NULL,
    589      1.16    marcus 	NULL, NULL, NULL, NULL,
    590      1.16    marcus 	NULL, NULL, NULL, NULL,
    591      1.16    marcus 	NULL, NULL, NULL, NULL,
    592      1.16    marcus 	NULL, NULL, NULL, NULL,
    593      1.16    marcus 	&ibm437_level2_32, NULL, &ibm437_level2_34, &ibm437_level2_35,
    594      1.16    marcus 	NULL, &ibm437_level2_37
    595      1.16    marcus };
    596      1.16    marcus 
    597      1.16    marcus /*
    598      1.16    marcus  * ISO-8859-7 maps
    599      1.16    marcus  */
    600  1.18.2.6   nathanw static const u_int8_t iso7_chars_0[] = {
    601      1.16    marcus 	 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
    602      1.16    marcus 	16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
    603      1.16    marcus 	32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
    604      1.16    marcus 	48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
    605      1.16    marcus 	64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
    606      1.16    marcus 	80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
    607      1.16    marcus 	96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,
    608      1.16    marcus 	112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
    609      1.16    marcus 	128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
    610      1.16    marcus 	144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
    611      1.16    marcus 	160, 0,  0, 163, 0,  0, 166,167,168,169, 0, 171,172,173, 0,  0,
    612      1.16    marcus 	176,177,178,179,180, 0,  0, 183, 0,  0,  0, 187, 0, 189
    613  1.18.2.6   nathanw };
    614  1.18.2.6   nathanw 
    615  1.18.2.6   nathanw static const u_int8_t iso7_chars_3[] = {
    616      1.16    marcus 	182, 0, 184,185,186, 0, 188, 0, 190,191,192,193,194,195,196,197,
    617      1.16    marcus 	198,199,200,201,202,203,204,205,206,207,208,209, 0, 211,212,213,
    618      1.16    marcus 	214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,
    619      1.16    marcus 	230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,
    620      1.16    marcus 	246,247,248,249,250,251,252,253,254, 0,  0,  0,  0,  0,  0,  0,
    621      1.16    marcus 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    622      1.16    marcus 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 181
    623  1.18.2.6   nathanw };
    624  1.18.2.6   nathanw 
    625  1.18.2.6   nathanw static const u_int8_t iso7_chars_32[] = {
    626      1.16    marcus 	175, 0,  0,  0,  0, 162, 0, 161
    627      1.16    marcus };
    628      1.16    marcus 
    629  1.18.2.6   nathanw static const struct wsfont_level2_glyphmap iso7_level2_0 =
    630  1.18.2.6   nathanw     { 0, 190, iso7_chars_0, 1 };
    631  1.18.2.6   nathanw 
    632  1.18.2.6   nathanw static const struct wsfont_level2_glyphmap iso7_level2_3 =
    633  1.18.2.6   nathanw     { 134, 111, iso7_chars_3, 1 };
    634  1.18.2.6   nathanw 
    635  1.18.2.6   nathanw static const struct wsfont_level2_glyphmap iso7_level2_32 =
    636  1.18.2.6   nathanw     { 20, 8, iso7_chars_32, 1 };
    637      1.16    marcus 
    638  1.18.2.6   nathanw static const struct wsfont_level2_glyphmap *iso7_level1[] = {
    639      1.16    marcus 	&iso7_level2_0, NULL, NULL, &iso7_level2_3,
    640      1.16    marcus 	NULL, NULL, NULL, NULL,
    641      1.16    marcus 	NULL, NULL, NULL, NULL,
    642      1.16    marcus 	NULL, NULL, NULL, NULL,
    643      1.16    marcus 	NULL, NULL, NULL, NULL,
    644      1.16    marcus 	NULL, NULL, NULL, NULL,
    645      1.16    marcus 	NULL, NULL, NULL, NULL,
    646      1.16    marcus 	NULL, NULL, NULL, NULL,
    647      1.16    marcus 	&iso7_level2_32
    648      1.16    marcus };
    649      1.16    marcus 
    650  1.18.2.6   nathanw static const struct wsfont_level1_glyphmap encodings[] = {
    651      1.16    marcus 	{ NULL, 0, 0 },			/* WSDISPLAY_FONTENC_ISO */
    652      1.16    marcus 	{ ibm437_level1, 0, 38 },	/* WSDISPLAY_FONTENC_IBM */
    653      1.16    marcus 	{ NULL, 0, 0 },			/* WSDISPLAY_FONTENC_PCVT */
    654      1.16    marcus 	{ iso7_level1, 0, 33 },		/* WSDISPLAY_FONTENC_ISO7 */
    655      1.16    marcus };
    656      1.16    marcus 
    657  1.18.2.1   nathanw #define MAX_ENCODING (sizeof(encodings) / sizeof(encodings[0]))
    658      1.16    marcus 
    659      1.16    marcus /*
    660      1.16    marcus  * Remap Unicode character to glyph
    661      1.16    marcus  */
    662      1.16    marcus int
    663  1.18.2.4   nathanw wsfont_map_unichar(struct wsdisplay_font *font, int c)
    664      1.16    marcus {
    665  1.18.2.6   nathanw 	const struct wsfont_level1_glyphmap *map1;
    666  1.18.2.6   nathanw 	const struct wsfont_level2_glyphmap *map2;
    667  1.18.2.6   nathanw 	int hi, lo;
    668      1.16    marcus 
    669  1.18.2.6   nathanw 	if (font->encoding == WSDISPLAY_FONTENC_ISO)
    670  1.18.2.6   nathanw 		return (c);
    671      1.16    marcus 
    672  1.18.2.6   nathanw 	if (font->encoding < 0 || font->encoding > MAX_ENCODING)
    673  1.18.2.6   nathanw 		return (-1);
    674  1.18.2.6   nathanw 
    675  1.18.2.6   nathanw 	hi = (c >> 8);
    676  1.18.2.6   nathanw 	lo = c & 255;
    677  1.18.2.6   nathanw 	map1 = &encodings[font->encoding];
    678      1.16    marcus 
    679  1.18.2.6   nathanw 	if (hi < map1->base || hi >= map1->base + map1->size)
    680      1.16    marcus 		return (-1);
    681      1.16    marcus 
    682  1.18.2.6   nathanw 	map2 = map1->level2[hi - map1->base];
    683      1.16    marcus 
    684  1.18.2.6   nathanw 	if (map2 == NULL || lo < map2->base || lo >= map2->base + map2->size)
    685  1.18.2.6   nathanw 		return (-1);
    686      1.16    marcus 
    687  1.18.2.6   nathanw 	lo -= map2->base;
    688      1.16    marcus 
    689  1.18.2.6   nathanw 	switch(map2->width) {
    690  1.18.2.6   nathanw 	case 1:
    691  1.18.2.6   nathanw 		c = (((const u_int8_t *)map2->chars)[lo]);
    692  1.18.2.6   nathanw 		break;
    693  1.18.2.6   nathanw 	case 2:
    694  1.18.2.6   nathanw 		c = (((const u_int16_t *)map2->chars)[lo]);
    695  1.18.2.6   nathanw 		break;
    696  1.18.2.6   nathanw 	case 4:
    697  1.18.2.6   nathanw 		c = (((const u_int32_t *)map2->chars)[lo]);
    698  1.18.2.6   nathanw 		break;
    699      1.16    marcus 	}
    700      1.16    marcus 
    701  1.18.2.6   nathanw 	if (c == 0 && lo != 0)
    702  1.18.2.6   nathanw 		return (-1);
    703  1.18.2.6   nathanw 
    704  1.18.2.6   nathanw 	return (c);
    705       1.1        ad }
    706