Module Name:    src
Committed By:   macallan
Date:           Wed Jan 11 15:52:32 UTC 2012

Modified Files:
        src/sys/dev/rasops: files.rasops rasops.c rasops.h
        src/sys/dev/wsfont: wsfont.c wsfont.h

Log Message:
make rasops_init()'s font selection code a bit less boneheaded by:
- actually trying to pick a font which gets as close as possible to the
  requested terminal size
- accepting 0,0 as 'use system default' which can be changed by
   options RASOPS_DEFAULT_WIDTH=100
   options RASOPS_DEFAULT_HEIGHT=30
  default is 80x25
- putting alpha and bitmap fonts in the same list and making wsfont_find()
  aware of wether we support alpha fonts or not
- if supported, prefer alpha fonts over otherwise equally suitable bitmap
  fonts


To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 src/sys/dev/rasops/files.rasops
cvs rdiff -u -r1.69 -r1.70 src/sys/dev/rasops/rasops.c
cvs rdiff -u -r1.29 -r1.30 src/sys/dev/rasops/rasops.h
cvs rdiff -u -r1.52 -r1.53 src/sys/dev/wsfont/wsfont.c
cvs rdiff -u -r1.23 -r1.24 src/sys/dev/wsfont/wsfont.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/rasops/files.rasops
diff -u src/sys/dev/rasops/files.rasops:1.12 src/sys/dev/rasops/files.rasops:1.13
--- src/sys/dev/rasops/files.rasops:1.12	Fri Feb  2 02:10:24 2007
+++ src/sys/dev/rasops/files.rasops	Wed Jan 11 15:52:32 2012
@@ -1,4 +1,4 @@
-# 	$NetBSD: files.rasops,v 1.12 2007/02/02 02:10:24 ober Exp $
+# 	$NetBSD: files.rasops,v 1.13 2012/01/11 15:52:32 macallan Exp $
 
 # Note: `rasops_glue' is only here to force the header file's name
 #       hence it must be mentioned first  (shudder...)
@@ -18,3 +18,5 @@ file dev/rasops/rasops24.c ((rasterconso
 file dev/rasops/rasops32.c ((rasterconsole | wsdisplay) & rasops32)
 
 defflag	opt_rasops.h 	RASOPS_CLIPPING RASOPS_SMALL
+defparam opt_rasops.h	RASOPS_DEFAULT_WIDTH = 80
+defparam opt_rasops.h	RASOPS_DEFAULT_HEIGHT = 25

Index: src/sys/dev/rasops/rasops.c
diff -u src/sys/dev/rasops/rasops.c:1.69 src/sys/dev/rasops/rasops.c:1.70
--- src/sys/dev/rasops/rasops.c:1.69	Wed Jan  4 20:17:05 2012
+++ src/sys/dev/rasops/rasops.c	Wed Jan 11 15:52:32 2012
@@ -1,4 +1,4 @@
-/*	 $NetBSD: rasops.c,v 1.69 2012/01/04 20:17:05 macallan Exp $	*/
+/*	 $NetBSD: rasops.c,v 1.70 2012/01/11 15:52:32 macallan Exp $	*/
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rasops.c,v 1.69 2012/01/04 20:17:05 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rasops.c,v 1.70 2012/01/11 15:52:32 macallan Exp $");
 
 #include "opt_rasops.h"
 #include "rasops_glue.h"
@@ -53,6 +53,20 @@ __KERNEL_RCSID(0, "$NetBSD: rasops.c,v 1
 #include <errno.h>
 #endif
 
+#ifdef RASOPS_DEBUG
+#define DPRINTF aprint_error
+#else
+#define DPRINTF while (0) printf
+#endif
+
+struct rasops_matchdata {
+	struct rasops_info *ri;
+	int wantcols, wantrows;
+	int bestscore;
+	struct wsdisplay_font *pick;
+	int ident;
+};	
+
 /* ANSI colormap (R,G,B). Upper 8 are high-intensity */
 const u_char rasops_cmap[256*3] = {
 	0x00, 0x00, 0x00, /* black */
@@ -167,6 +181,57 @@ void	rasops_make_box_chars_alpha(struct 
 extern int cold;
 
 /*
+ * Rate a font based on how many character cells we would get out of it in the
+ * current video mode. Lower is better.
+ */
+static void
+rasops_matches(struct wsdisplay_font *font, void *cookie, int ident)
+{
+	struct rasops_matchdata *md = cookie;
+	struct rasops_info *ri = md->ri;
+	int cols, score = 1;
+
+	/* first weed out fonts the caller doesn't claim support for */
+	if (FONT_IS_ALPHA(font)) {
+		/*
+		 * If we end up with a bitmap font and an alpha font with
+		 * otherwise identical scores, prefer alpha
+		 */
+		score = 0;
+		if ((ri->ri_flg & RI_ENABLE_ALPHA) == 0)
+			return;
+	}
+	cols = ri->ri_width / font->fontwidth;
+	/*
+	 * if the font is too small to allow 80 columns give those closer to
+	 * 80 a better score but with a huge penalty compared to fonts that
+	 * give us 80 columns or more
+	 */ 
+	if (cols < md->wantcols) {
+		score += 100000 + 2 * (md->wantcols - cols);
+	} else 
+		score += 2 * cols;
+	DPRINTF("%s: %d\n", font->name, score);
+	if (score < md->bestscore) {
+		md->bestscore = score;
+		md->pick = font;
+		md->ident = ident;
+	}
+}
+
+static int
+rasops_find(struct rasops_info *ri, int wantrows, int wantcols)
+{
+	struct rasops_matchdata md =
+	    { ri, wantcols, wantrows, 1000000, NULL, 0};
+
+	wsfont_walk(rasops_matches, &md);
+	if (md.pick == NULL)
+		return -1;
+	return (wsfont_make_cookie(md.ident, WSDISPLAY_FONTORDER_L2R,
+			    WSDISPLAY_FONTORDER_L2R));
+}
+/*
  * Initialize a 'rasops_info' descriptor.
  */
 int
@@ -181,22 +246,21 @@ rasops_init(struct rasops_info *ri, int 
 
 		wsfont_init();
 
-		if (ri->ri_flg & RI_ENABLE_ALPHA) {
-			/* try finding an AA font first */
-			cookie = wsfont_find_aa(NULL, 0, 0, 0, WSDISPLAY_FONTORDER_L2R,
-			    WSDISPLAY_FONTORDER_L2R);
-		}
-		if (cookie == -1) {
-			/* Want 8 pixel wide, don't care about aesthetics */
-			cookie = wsfont_find(NULL, 8, 0, 0, WSDISPLAY_FONTORDER_L2R,
-			    WSDISPLAY_FONTORDER_L2R);
-		}
-		if (cookie <= 0)
-			cookie = wsfont_find(NULL, 0, 0, 0,
-			    WSDISPLAY_FONTORDER_L2R, WSDISPLAY_FONTORDER_L2R);
+		/*
+		 * first, try to find something that's as close as possible
+		 * to the caller's requested terminal size
+		 */ 
+		if (wantrows == 0)
+			wantrows = RASOPS_DEFAULT_HEIGHT;
+		if (wantcols == 0)
+			wantcols = RASOPS_DEFAULT_WIDTH;
+		cookie = rasops_find(ri, wantrows, wantcols);
 
+		/*
+		 * this means there is no supported font in the list
+		 */
 		if (cookie <= 0) {
-			printf("rasops_init: font table is empty\n");
+			aprint_error("rasops_init: font table is empty\n");
 			return (-1);
 		}
 
@@ -214,7 +278,7 @@ rasops_init(struct rasops_info *ri, int 
 #endif
 
 		if (wsfont_lock(cookie, &ri->ri_font)) {
-			printf("rasops_init: couldn't lock font\n");
+			aprint_error("rasops_init: couldn't lock font\n");
 			return (-1);
 		}
 
@@ -225,12 +289,12 @@ rasops_init(struct rasops_info *ri, int 
 	/* This should never happen in reality... */
 #ifdef DEBUG
 	if ((long)ri->ri_bits & 3) {
-		printf("rasops_init: bits not aligned on 32-bit boundary\n");
+		aprint_error("rasops_init: bits not aligned on 32-bit boundary\n");
 		return (-1);
 	}
 
 	if ((int)ri->ri_stride & 3) {
-		printf("rasops_init: stride not aligned on 32-bit boundary\n");
+		aprint_error("rasops_init: stride not aligned on 32-bit boundary\n");
 		return (-1);
 	}
 #endif
@@ -252,6 +316,11 @@ rasops_reconfig(struct rasops_info *ri, 
 
 	s = splhigh();
 
+	if (wantrows == 0)
+		wantrows = RASOPS_DEFAULT_HEIGHT;
+	if (wantcols == 0)
+		wantcols = RASOPS_DEFAULT_WIDTH;
+
 	/* throw away old line drawing character bitmaps, if we have any */
 	if (ri->ri_optfont.data != NULL) {
 		kmem_free(ri->ri_optfont.data, ri->ri_optfont.stride * 

Index: src/sys/dev/rasops/rasops.h
diff -u src/sys/dev/rasops/rasops.h:1.29 src/sys/dev/rasops/rasops.h:1.30
--- src/sys/dev/rasops/rasops.h:1.29	Tue Jan  3 23:13:59 2012
+++ src/sys/dev/rasops/rasops.h	Wed Jan 11 15:52:32 2012
@@ -1,4 +1,4 @@
-/* 	$NetBSD: rasops.h,v 1.29 2012/01/03 23:13:59 macallan Exp $ */
+/* 	$NetBSD: rasops.h,v 1.30 2012/01/11 15:52:32 macallan Exp $ */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -143,7 +143,6 @@ struct rasops_info {
 			  (ri->ri_optfont.data != NULL)) ? \
 			 &ri->ri_optfont : ri->ri_font
 
-#define FONT_IS_ALPHA(f) ((f)->fontwidth <= (f)->stride)
 /*
  * rasops_init().
  *

Index: src/sys/dev/wsfont/wsfont.c
diff -u src/sys/dev/wsfont/wsfont.c:1.52 src/sys/dev/wsfont/wsfont.c:1.53
--- src/sys/dev/wsfont/wsfont.c:1.52	Wed Dec 28 18:29:48 2011
+++ src/sys/dev/wsfont/wsfont.c	Wed Jan 11 15:52:32 2012
@@ -1,4 +1,4 @@
-/* 	$NetBSD: wsfont.c,v 1.52 2011/12/28 18:29:48 macallan Exp $	*/
+/* 	$NetBSD: wsfont.c,v 1.53 2012/01/11 15:52:32 macallan Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2002 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wsfont.c,v 1.52 2011/12/28 18:29:48 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wsfont.c,v 1.53 2012/01/11 15:52:32 macallan Exp $");
 
 #include "opt_wsfont.h"
 
@@ -131,7 +131,7 @@ __KERNEL_RCSID(0, "$NetBSD: wsfont.c,v 1
 #include <dev/wsfont/FreeMono_12x22.h>
 #endif
 
-/* Make sure we always have at least one font. */
+/* Make sure we always have at least one bitmap font. */
 #ifndef HAVE_FONT
 #define HAVE_FONT 1
 #define FONT_BOLD8x16 1
@@ -211,9 +211,6 @@ static struct font builtin_fonts[] = {
 #ifdef FONT_OMRON12x20
 	{ { NULL, NULL }, &omron12x20, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
 #endif
-	{ { NULL, NULL }, NULL, 0, 0, 0 },
-};
-static struct font builtin_aa_fonts[] = {
 #ifdef FONT_DEJAVU_SANS_MONO12x22
 	{ { NULL, NULL }, &DejaVu_Sans_Mono_12x22, 0, 0, WSFONT_STATIC | WSFONT_BUILTIN },
 #endif
@@ -230,7 +227,6 @@ static struct font builtin_aa_fonts[] = 
 };
 
 static TAILQ_HEAD(,font)	list;
-static TAILQ_HEAD(,font)	aa_list;
 static int	ident;
 
 /* Reverse the bit order in a byte */
@@ -273,9 +269,8 @@ static struct	font *wsfont_find0(int, in
 static struct	font *wsfont_add0(struct wsdisplay_font *, int);
 static void	wsfont_revbit(struct wsdisplay_font *);
 static void	wsfont_revbyte(struct wsdisplay_font *);
-static inline int wsfont_make_cookie(int, int, int);
 
-static inline int
+int
 wsfont_make_cookie(int cident, int bito, int byteo)
 {
 
@@ -540,16 +535,6 @@ wsfont_init(void)
 		    ent->font->bitorder, ent->font->byteorder);
 		TAILQ_INSERT_TAIL(&list, ent, chain);
 	}
-
-	TAILQ_INIT(&aa_list);
-	ent = builtin_aa_fonts;
-
-	for (i = 0; builtin_aa_fonts[i].font != NULL; i++, ent++) {
-		ident += (1 << WSFONT_IDENT_SHIFT);
-		ent->cookie = wsfont_make_cookie(ident,
-		    ent->font->bitorder, ent->font->byteorder);
-		TAILQ_INSERT_TAIL(&aa_list, ent, chain);
-	}
 }
 
 static struct font *
@@ -562,19 +547,23 @@ wsfont_find0(int cookie, int mask)
 			return (ent);
 	}
 
-	TAILQ_FOREACH(ent, &aa_list, chain) {
-		if ((ent->cookie & mask) == (cookie & mask))
-			return (ent);
-	}
-
 	return (NULL);
 }
 
 int
 wsfont_matches(struct wsdisplay_font *font, const char *name,
-	       int width, int height, int stride)
+	       int width, int height, int stride, int flags)
 {
 
+	/* first weed out fonts the caller doesn't claim support for */
+	if (FONT_IS_ALPHA(font)) {
+		if ((flags & WSFONT_FIND_ALPHA) == 0)
+			return 0;
+	} else {
+		if ((flags & WSFONT_FIND_BITMAP) == 0)
+			return 0;
+	}
+
 	if (height != 0 && font->fontheight != height)
 		return (0);
 
@@ -591,29 +580,26 @@ wsfont_matches(struct wsdisplay_font *fo
 }
 
 int
-wsfont_find(const char *name, int width, int height, int stride, int bito, int byteo)
+wsfont_find(const char *name, int width, int height, int stride, int bito, int byteo, int flags)
 {
 	struct font *ent;
 
 	TAILQ_FOREACH(ent, &list, chain) {
-		if (wsfont_matches(ent->font, name, width, height, stride))
+		if (wsfont_matches(ent->font, name, width, height, stride, flags))
 			return (wsfont_make_cookie(ent->cookie, bito, byteo));
 	}
 
 	return (-1);
 }
 
-int
-wsfont_find_aa(const char *name, int width, int height, int stride, int bito, int byteo)
+void
+wsfont_walk(void (*matchfunc)(struct wsdisplay_font *, void *, int), void *cookie)
 {
 	struct font *ent;
 
-	TAILQ_FOREACH(ent, &aa_list, chain) {
-		if (wsfont_matches(ent->font, name, width, height, stride))
-			return (wsfont_make_cookie(ent->cookie, bito, byteo));
+	TAILQ_FOREACH(ent, &list, chain) {
+		matchfunc(ent->font, cookie, ent->cookie);
 	}
-
-	return (-1);
 }
 
 static struct font *
@@ -657,7 +643,7 @@ wsfont_add(struct wsdisplay_font *font, 
 
 	/* Don't allow exact duplicates */
 	if (wsfont_find(font->name, font->fontwidth, font->fontheight,
-	    font->stride, 0, 0) >= 0)
+	    font->stride, 0, 0, WSFONT_FIND_ALL) >= 0)
 		return (EEXIST);
 
 	ent = wsfont_add0(font, copy);

Index: src/sys/dev/wsfont/wsfont.h
diff -u src/sys/dev/wsfont/wsfont.h:1.23 src/sys/dev/wsfont/wsfont.h:1.24
--- src/sys/dev/wsfont/wsfont.h:1.23	Wed Jan  4 15:53:49 2012
+++ src/sys/dev/wsfont/wsfont.h	Wed Jan 11 15:52:32 2012
@@ -1,4 +1,4 @@
-/* 	$NetBSD: wsfont.h,v 1.23 2012/01/04 15:53:49 macallan Exp $	*/
+/* 	$NetBSD: wsfont.h,v 1.24 2012/01/11 15:52:32 macallan Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2002 The NetBSD Foundation, Inc.
@@ -36,6 +36,8 @@
 #define WSFONT_FLAG_OPT		0x01000000	/* use alternate font */
 #define WSFONT_GLYPH(c, font)	((uint8_t *)font->data + \
 		((c) - font->firstchar) * font->stride * font->fontheight)
+#define FONT_IS_ALPHA(f) ((f)->fontwidth <= (f)->stride)
+
 /*
  * Example:
  *
@@ -58,9 +60,13 @@
 struct wsdisplay_font;
 
 void	wsfont_init(void);
-int	wsfont_matches(struct wsdisplay_font *, const char *, int, int, int);
-int	wsfont_find(const char *, int, int, int, int, int);
-int	wsfont_find_aa(const char *, int, int, int, int, int);
+int	wsfont_matches(struct wsdisplay_font *, const char *, int, int, int, int);
+int	wsfont_find(const char *, int, int, int, int, int, int);
+#define WSFONT_FIND_BITMAP	1
+#define WSFONT_FIND_ALPHA	2
+#define WSFONT_FIND_ALL		0xff
+void	wsfont_walk(void (*)(struct wsdisplay_font *, void *, int), void *);
+
 int	wsfont_add(struct wsdisplay_font *, int);
 int	wsfont_remove(int);
 void	wsfont_enum(void (*)(const char *, int, int, int));
@@ -75,4 +81,6 @@ enum {
 	WSFONT_ROTATE_UD
 };
 
+int	wsfont_make_cookie(int, int, int);
+
 #endif	/* !_WSFONT_H_ */

Reply via email to