Module Name:    src
Committed By:   macallan
Date:           Wed Dec 28 09:29:04 UTC 2011

Modified Files:
        src/sys/dev/pci: r128fb.c

Log Message:
support anti-aliased fonts in 8 bit r3g3b2 colour


To generate a diff of this commit:
cvs rdiff -u -r1.22 -r1.23 src/sys/dev/pci/r128fb.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/pci/r128fb.c
diff -u src/sys/dev/pci/r128fb.c:1.22 src/sys/dev/pci/r128fb.c:1.23
--- src/sys/dev/pci/r128fb.c:1.22	Wed Jun 29 03:14:36 2011
+++ src/sys/dev/pci/r128fb.c	Wed Dec 28 09:29:03 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: r128fb.c,v 1.22 2011/06/29 03:14:36 macallan Exp $	*/
+/*	$NetBSD: r128fb.c,v 1.23 2011/12/28 09:29:03 macallan Exp $	*/
 
 /*
  * Copyright (c) 2007 Michael Lorenz
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: r128fb.c,v 1.22 2011/06/29 03:14:36 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: r128fb.c,v 1.23 2011/12/28 09:29:03 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -274,14 +274,26 @@ r128fb_attach(device_t parent, device_t 
 	ri = &sc->sc_console_screen.scr_ri;
 
 	j = 0;
-	for (i = 0; i < (1 << sc->sc_depth); i++) {
-
-		sc->sc_cmap_red[i] = rasops_cmap[j];
-		sc->sc_cmap_green[i] = rasops_cmap[j + 1];
-		sc->sc_cmap_blue[i] = rasops_cmap[j + 2];
-		r128fb_putpalreg(sc, i, rasops_cmap[j], rasops_cmap[j + 1],
-		    rasops_cmap[j + 2]);
-		j += 3;
+	if (sc->sc_depth == 8) {
+		/* generate an r3g3b2 colour map */
+		for (i = 0; i < 256; i++) {
+			sc->sc_cmap_red[i] = i & 0xe0;
+			sc->sc_cmap_green[i] = (i & 0x1c) << 3;
+			sc->sc_cmap_blue[i] = (i & 0x03) << 6;
+			r128fb_putpalreg(sc, i, sc->sc_cmap_red[i],
+				       sc->sc_cmap_green[i],
+				       sc->sc_cmap_blue[i]);
+		}
+	} else {
+		/* steal rasops' ANSI cmap */
+		for (i = 0; i < 256; i++) {
+			sc->sc_cmap_red[i] = rasops_cmap[j];
+			sc->sc_cmap_green[i] = rasops_cmap[j + 1];
+			sc->sc_cmap_blue[i] = rasops_cmap[j + 2];
+			r128fb_putpalreg(sc, i, rasops_cmap[j], rasops_cmap[j + 1],
+			    rasops_cmap[j + 2]);
+			j += 3;
+		}
 	}
 
 	if (is_console) {
@@ -504,6 +516,8 @@ r128fb_init_screen(void *cookie, struct 
 	ri->ri_height = sc->sc_height;
 	ri->ri_stride = sc->sc_stride;
 	ri->ri_flg = RI_CENTER;
+	if (sc->sc_depth == 8)
+		ri->ri_flg |= RI_8BIT_IS_RGB | RI_ENABLE_ALPHA;
 
 	rasops_init(ri, sc->sc_height / 8, sc->sc_width / 8);
 	ri->ri_caps = WSSCREEN_WSCOLORS;
@@ -779,72 +793,77 @@ r128fb_putchar(void *cookie, int row, in
 	struct wsdisplay_font *font = PICK_FONT(ri, c);
 	struct vcons_screen *scr = ri->ri_hw;
 	struct r128fb_softc *sc = scr->scr_cookie;
+	void *data;
+	uint32_t fg, bg;
+	int uc, i;
+	int x, y, wi, he, offset;
 
-	if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
-		void *data;
-		uint32_t fg, bg;
-		int uc, i;
-		int x, y, wi, he, offset;
+	if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) 
+		return;
 
-		wi = font->fontwidth;
-		he = font->fontheight;
+	if (!CHAR_IN_FONT(c, font))
+		return;
 
-		if (!CHAR_IN_FONT(c, font))
-			return;
-		bg = ri->ri_devcmap[(attr >> 16) & 0xf];
-		fg = ri->ri_devcmap[(attr >> 24) & 0xf];
-		x = ri->ri_xorigin + col * wi;
-		y = ri->ri_yorigin + row * he;
-		if (c == 0x20) {
-			r128fb_rectfill(sc, x, y, wi, he, bg);
-		} else {
-			uc = c - font->firstchar;
-			data = (uint8_t *)font->data + uc * ri->ri_fontscale;
-
-			r128fb_wait(sc, 8);
-
-			bus_space_write_4(sc->sc_memt, sc->sc_regh, 
-			    R128_DP_GUI_MASTER_CNTL,
-			    R128_GMC_BRUSH_SOLID_COLOR |
-			    R128_GMC_SRC_DATATYPE_MONO_FG_BG |
-			    R128_ROP3_S |
-			    R128_DP_SRC_SOURCE_HOST_DATA |
-			    R128_GMC_DST_CLIPPING |
-			    sc->sc_master_cntl);
-
-			bus_space_write_4(sc->sc_memt, sc->sc_regh, 
-			    R128_DP_CNTL, 
-			    R128_DST_Y_TOP_TO_BOTTOM | 
-			    R128_DST_X_LEFT_TO_RIGHT);
-
-			bus_space_write_4(sc->sc_memt, sc->sc_regh, 
-			    R128_DP_SRC_FRGD_CLR, fg);
-			bus_space_write_4(sc->sc_memt, sc->sc_regh, 
-			    R128_DP_SRC_BKGD_CLR, bg);
-
-			/*
-			 * The Rage 128 doesn't have anything to skip pixels
-			 * when colour expanding but all coordinates
-			 * are signed so we just clip the leading bytes and 
-			 * trailing bits away
-			 */
-			bus_space_write_4(sc->sc_memt, sc->sc_regh, 
-			    R128_SC_RIGHT, x + wi - 1);
-			bus_space_write_4(sc->sc_memt, sc->sc_regh, 
-			    R128_SC_LEFT, x);
-
-			/* needed? */
-			bus_space_write_4(sc->sc_memt, sc->sc_regh, 
-			    R128_SRC_X_Y, 0);
-
-			offset = 32 - (ri->ri_font->stride << 3);
-			bus_space_write_4(sc->sc_memt, sc->sc_regh, 
-			    R128_DST_X_Y, ((x - offset) << 16) | y);
-			bus_space_write_4(sc->sc_memt, sc->sc_regh, 
-			    R128_DST_WIDTH_HEIGHT, (32 << 16) | he);
+	wi = font->fontwidth;
+	he = font->fontheight;
+
+	bg = ri->ri_devcmap[(attr >> 16) & 0xf];
+	fg = ri->ri_devcmap[(attr >> 24) & 0xf];
+	x = ri->ri_xorigin + col * wi;
+	y = ri->ri_yorigin + row * he;
+	if (c == 0x20) {
+		r128fb_rectfill(sc, x, y, wi, he, bg);
+		return;
+	}
+
+	uc = c - font->firstchar;
+	data = (uint8_t *)font->data + uc * ri->ri_fontscale;
+	if (font->stride < wi) {
+		/* this is a mono bitmap font */
+
+		r128fb_wait(sc, 8);
+
+		bus_space_write_4(sc->sc_memt, sc->sc_regh, 
+		    R128_DP_GUI_MASTER_CNTL,
+		    R128_GMC_BRUSH_SOLID_COLOR |
+		    R128_GMC_SRC_DATATYPE_MONO_FG_BG |
+		    R128_ROP3_S |
+		    R128_DP_SRC_SOURCE_HOST_DATA |
+		    R128_GMC_DST_CLIPPING |
+		    sc->sc_master_cntl);
+
+		bus_space_write_4(sc->sc_memt, sc->sc_regh, 
+		    R128_DP_CNTL, 
+		    R128_DST_Y_TOP_TO_BOTTOM | 
+		    R128_DST_X_LEFT_TO_RIGHT);
+
+		bus_space_write_4(sc->sc_memt, sc->sc_regh, 
+		    R128_DP_SRC_FRGD_CLR, fg);
+		bus_space_write_4(sc->sc_memt, sc->sc_regh, 
+		    R128_DP_SRC_BKGD_CLR, bg);
+
+		/*
+		 * The Rage 128 doesn't have anything to skip pixels
+		 * when colour expanding but all coordinates
+		 * are signed so we just clip the leading bytes and 
+		 * trailing bits away
+		 */
+		bus_space_write_4(sc->sc_memt, sc->sc_regh, 
+		    R128_SC_RIGHT, x + wi - 1);
+		bus_space_write_4(sc->sc_memt, sc->sc_regh, 
+		    R128_SC_LEFT, x);
+
+		/* needed? */
+		bus_space_write_4(sc->sc_memt, sc->sc_regh, R128_SRC_X_Y, 0);
+
+		offset = 32 - (ri->ri_font->stride << 3);
+		bus_space_write_4(sc->sc_memt, sc->sc_regh, R128_DST_X_Y,
+		    ((x - offset) << 16) | y);
+		bus_space_write_4(sc->sc_memt, sc->sc_regh,
+		    R128_DST_WIDTH_HEIGHT, (32 << 16) | he);
 
-			r128fb_wait(sc, he);
-			switch (ri->ri_font->stride) {
+		r128fb_wait(sc, he);
+		switch (ri->ri_font->stride) {
 			case 1: {
 				uint8_t *data8 = data;
 				uint32_t reg;
@@ -855,7 +874,7 @@ r128fb_putchar(void *cookie, int row, in
 					    R128_HOST_DATA0, reg);
 					data8++;
 				}
-			break;
+				break;
 			}
 			case 2: {
 				uint16_t *data16 = data;
@@ -869,7 +888,87 @@ r128fb_putchar(void *cookie, int row, in
 				}
 				break;
 			}
+		}
+	} else {
+		/*
+		 * this is an alpha font
+		 * for now we only support this in 8 bit r3g3b2 colour
+		 */
+		uint32_t latch = 0, bg8, fg8, pixel;
+		int r, g, b, aval;
+		int r1, g1, b1, r0, g0, b0, fgo, bgo;
+		uint8_t *data8 = data;
+
+		r128fb_wait(sc, 5);
+		bus_space_write_4(sc->sc_memt, sc->sc_regh, 
+		    R128_DP_GUI_MASTER_CNTL,
+		    R128_GMC_BRUSH_SOLID_COLOR |
+		    R128_GMC_SRC_DATATYPE_COLOR |
+		    R128_ROP3_S |
+		    R128_DP_SRC_SOURCE_HOST_DATA |
+		    sc->sc_master_cntl);
+
+		bus_space_write_4(sc->sc_memt, sc->sc_regh, 
+		    R128_DP_CNTL, 
+		    R128_DST_Y_TOP_TO_BOTTOM | 
+		    R128_DST_X_LEFT_TO_RIGHT);
+
+		/* needed? */
+		bus_space_write_4(sc->sc_memt, sc->sc_regh, 
+		    R128_SRC_X_Y, 0);
+		bus_space_write_4(sc->sc_memt, sc->sc_regh, 
+		    R128_DST_X_Y, (x << 16) | y);
+		bus_space_write_4(sc->sc_memt, sc->sc_regh, 
+		    R128_DST_WIDTH_HEIGHT, (wi << 16) | he);
+
+		/*
+		 * we need the RGB colours here, so get offsets into
+		 * rasops_cmap
+		 */
+		fgo = ((attr >> 24) & 0xf) * 3;
+		bgo = ((attr >> 16) & 0xf) * 3;
+
+		r0 = rasops_cmap[bgo];
+		r1 = rasops_cmap[fgo];
+		g0 = rasops_cmap[bgo + 1];
+		g1 = rasops_cmap[fgo + 1];
+		b0 = rasops_cmap[bgo + 2];
+		b1 = rasops_cmap[fgo + 2];
+#define R3G3B2(r, g, b) ((r & 0xe0) | ((g >> 3) & 0x1c) | (b >> 6))
+		bg8 = R3G3B2(r0, g0, b0);
+		fg8 = R3G3B2(r1, g1, b1);
+		for (i = 0; i < ri->ri_fontscale; i++) {
+			aval = *data8;
+			if (aval == 0) {
+				pixel = bg8;
+			} else if (aval == 255) {
+				pixel = fg8;
+			} else {
+				r = aval * r1 + (255 - aval) * r0;
+				g = aval * g1 + (255 - aval) * g0;
+				b = aval * b1 + (255 - aval) * b0;
+				pixel = ((r & 0xe000) >> 8) |
+					((g & 0xe000) >> 11) |
+					((b & 0xc000) >> 14);
+			}
+			latch = (latch << 8) | pixel;
+			/* write in 32bit chunks */
+			if ((i & 3) == 3) {
+				bus_space_write_stream_4(sc->sc_memt,
+				    sc->sc_regh, R128_HOST_DATA0, latch);
+				/*
+				 * not strictly necessary, old data
+				 * should be shifted out 
+				 */
+				latch = 0;
 			}
+			data8++;
+		}
+		/* if we have pixels left in latch write them out */
+		if ((i & 3) != 0) {
+			latch = latch << ((4 - (i & 3)) << 3);	
+			bus_space_write_stream_4(sc->sc_memt, sc->sc_regh,
+					    R128_HOST_DATA0, latch);
 		}
 	}
 }

Reply via email to