Module Name:    src
Committed By:   macallan
Date:           Thu Dec 22 04:52:45 UTC 2011

Modified Files:
        src/sys/dev/rasops: rasops.c rasops.h rasops32.c

Log Message:
support anti-aliased fonts ( as in, pre-rendered alpha maps ), for now only
in rasops32 although adding support in 15, 16 and 24 would be trivial.
Enabled only if the driver explicitly requests it by setting the
RI_ENABLE_ALPHA flag.


To generate a diff of this commit:
cvs rdiff -u -r1.66 -r1.67 src/sys/dev/rasops/rasops.c
cvs rdiff -u -r1.26 -r1.27 src/sys/dev/rasops/rasops.h
cvs rdiff -u -r1.19 -r1.20 src/sys/dev/rasops/rasops32.c

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/rasops.c
diff -u src/sys/dev/rasops/rasops.c:1.66 src/sys/dev/rasops/rasops.c:1.67
--- src/sys/dev/rasops/rasops.c:1.66	Wed Jul 21 12:12:58 2010
+++ src/sys/dev/rasops/rasops.c	Thu Dec 22 04:52:45 2011
@@ -1,4 +1,4 @@
-/*	 $NetBSD: rasops.c,v 1.66 2010/07/21 12:12:58 tsutsui Exp $	*/
+/*	 $NetBSD: rasops.c,v 1.67 2011/12/22 04:52:45 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.66 2010/07/21 12:12:58 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rasops.c,v 1.67 2011/12/22 04:52:45 macallan Exp $");
 
 #include "opt_rasops.h"
 #include "rasops_glue.h"
@@ -162,6 +162,7 @@ struct rotatedfont {
 void	rasops_make_box_chars_8(struct rasops_info *);
 void	rasops_make_box_chars_16(struct rasops_info *);
 void	rasops_make_box_chars_32(struct rasops_info *);
+void	rasops_make_box_chars_alpha(struct rasops_info *);
 
 extern int cold;
 
@@ -176,13 +177,20 @@ rasops_init(struct rasops_info *ri, int 
 #ifdef _KERNEL
 	/* Select a font if the caller doesn't care */
 	if (ri->ri_font == NULL) {
-		int cookie;
+		int cookie = -1;
 
 		wsfont_init();
 
-		/* Want 8 pixel wide, don't care about aesthetics */
-		cookie = wsfont_find(NULL, 8, 0, 0, WSDISPLAY_FONTORDER_L2R,
-		    WSDISPLAY_FONTORDER_L2R);
+		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);
@@ -263,17 +271,20 @@ rasops_reconfig(struct rasops_info *ri, 
 	if (((ri->ri_flg & RI_NO_AUTO) == 0) && 
 	  ((ri->ri_optfont.data = kmem_zalloc(len, KM_SLEEP)) != NULL)) {
 
-	
-		switch (ri->ri_optfont.stride) {
-		case 1:
-			rasops_make_box_chars_8(ri);
-			break;
-		case 2:
-			rasops_make_box_chars_16(ri);
-			break;
-		case 4:
-			rasops_make_box_chars_32(ri);
-			break;
+		if (ri->ri_optfont.stride < ri->ri_optfont.fontwidth) {
+			switch (ri->ri_optfont.stride) {
+			case 1:
+				rasops_make_box_chars_8(ri);
+				break;
+			case 2:
+				rasops_make_box_chars_16(ri);
+				break;
+			case 4:
+				rasops_make_box_chars_32(ri);
+				break;
+			}
+		} else {
+			rasops_make_box_chars_alpha(ri);
 		}
 	} else
 		memset(&ri->ri_optfont, 0, sizeof(ri->ri_optfont));
@@ -1622,3 +1633,54 @@ rasops_make_box_chars_32(struct rasops_i
 		}
 	}
 }
+
+void
+rasops_make_box_chars_alpha(struct rasops_info *ri)
+{
+	uint8_t *data = (uint8_t *)ri->ri_optfont.data;
+	uint8_t *ddata;
+	int c, i, hmid, vmid, wi, he;
+
+	wi = ri->ri_font->fontwidth;
+	he = ri->ri_font->fontheight;
+	
+	vmid = (he + 1) >> 1;
+	hmid = (wi + 1) >> 1;
+
+	/* 0x00 would be empty anyway so don't bother */
+	for (c = 1; c < 16; c++) {
+		data += ri->ri_fontscale;
+		if (c & 1) {
+			/* upper segment */
+			ddata = data + hmid;
+			for (i = 0; i <= vmid; i++) {
+				*ddata = 0xff;
+				ddata += wi;
+			}
+		}
+		if (c & 4) {
+			/* lower segment */
+			ddata = data + wi * vmid + hmid;
+			for (i = vmid; i < he; i++) {
+				*ddata = 0xff;
+				ddata += wi;
+			}
+		}
+		if (c & 2) {
+			/* right segment */
+			ddata = data + wi * vmid + hmid;
+			for (i = hmid; i < wi; i++) {
+				*ddata = 0xff;
+				ddata++;
+			}
+		}
+		if (c & 8) {
+			/* left segment */
+			ddata = data + wi * vmid;
+			for (i = 0; i <= hmid; i++) {
+				*ddata = 0xff;
+				ddata++;
+			}
+		}
+	}
+}

Index: src/sys/dev/rasops/rasops.h
diff -u src/sys/dev/rasops/rasops.h:1.26 src/sys/dev/rasops/rasops.h:1.27
--- src/sys/dev/rasops/rasops.h:1.26	Thu May  6 04:30:18 2010
+++ src/sys/dev/rasops/rasops.h	Thu Dec 22 04:52:45 2011
@@ -1,4 +1,4 @@
-/* 	$NetBSD: rasops.h,v 1.26 2010/05/06 04:30:18 macallan Exp $ */
+/* 	$NetBSD: rasops.h,v 1.27 2011/12/22 04:52:45 macallan Exp $ */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -55,6 +55,12 @@
  * box drawing characters
  */
 #define	RI_NO_AUTO	0x800	/* do not generate box drawing characters */
+/*
+ * Set this if your driver's putchar() method supports anti-aliased fonts in
+ * the given video mode. Without this flag rasops_init() will only ever pick
+ * monochrome bitmap fonts. 
+ */
+#define RI_ENABLE_ALPHA	0x1000
 
 struct rasops_info {
 	/* These must be filled in by the caller */

Index: src/sys/dev/rasops/rasops32.c
diff -u src/sys/dev/rasops/rasops32.c:1.19 src/sys/dev/rasops/rasops32.c:1.20
--- src/sys/dev/rasops/rasops32.c:1.19	Tue May  4 04:57:34 2010
+++ src/sys/dev/rasops/rasops32.c	Thu Dec 22 04:52:45 2011
@@ -1,4 +1,4 @@
-/*	 $NetBSD: rasops32.c,v 1.19 2010/05/04 04:57:34 macallan Exp $	*/
+/*	 $NetBSD: rasops32.c,v 1.20 2011/12/22 04:52:45 macallan Exp $	*/
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rasops32.c,v 1.19 2010/05/04 04:57:34 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rasops32.c,v 1.20 2011/12/22 04:52:45 macallan Exp $");
 
 #include "opt_rasops.h"
 
@@ -122,22 +122,51 @@ rasops32_putchar(void *cookie, int row, 
 		fr = (u_char *)font->data + uc * ri->ri_fontscale;
 		fs = font->stride;
 
-		while (height--) {
-			dp = rp;
-			fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) |
-			    (fr[0] << 24);
-			fr += fs;
-			DELTA(rp, ri->ri_stride, int32_t *);
-			if (ri->ri_hwbits) {
-				hp = hrp;
-				DELTA(hrp, ri->ri_stride, int32_t *);
+		if (font->stride < width) {
+			/* this is a mono font */
+			while (height--) {
+				dp = rp;
+				fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) |
+				    (fr[0] << 24);
+				fr += fs;
+				DELTA(rp, ri->ri_stride, int32_t *);
+				if (ri->ri_hwbits) {
+					hp = hrp;
+					DELTA(hrp, ri->ri_stride, int32_t *);
+				}
+
+				for (cnt = width; cnt; cnt--) {
+					*dp++ = clr[(fb >> 31) & 1];
+					if (ri->ri_hwbits)
+						*hp++ = clr[(fb >> 31) & 1];
+					fb <<= 1;
+				}
 			}
-
-			for (cnt = width; cnt; cnt--) {
-				*dp++ = clr[(fb >> 31) & 1];
-				if (ri->ri_hwbits)
-					*hp++ = clr[(fb >> 31) & 1];
-				fb <<= 1;
+		} else {
+			/* this is an alpha map */
+			int x, y, r, g, b, alpha;
+			int r1, g1, b1, r0, g0, b0;
+
+			r0 = (clr[0] >> 16) & 0xff;
+			r1 = (clr[1] >> 16) & 0xff;
+			g0 = (clr[0] >> 8) & 0xff;
+			g1 = (clr[1] >> 8) & 0xff;
+			b0 =  clr[0] & 0xff;
+			b1 =  clr[1] & 0xff;
+
+			for (y = 0; y < height; y++) {
+				dp = rp + ri->ri_width * y;
+				for (x = 0; x < width; x++) {
+					alpha = *fr;
+					r = alpha * r1 + (255 - alpha) * r0;
+					g = alpha * g1 + (255 - alpha) * g0;
+					b = alpha * b1 + (255 - alpha) * b0;
+					*dp = (r & 0xff00) << 8 | 
+					      (g & 0xff00) | 
+					      (b & 0xff00) >> 8;
+					dp++;
+					fr++;
+				}
 			}
 		}
 	}

Reply via email to