nanogui: using freetype2 with fblin4


Previous by date: 31 May 2005 16:08:06 +0100 using freetype2 with fblin4, Markus Wekenmann
Next by date: 31 May 2005 16:08:06 +0100 Re: using freetype2 with fblin4, Steven Scholz
Previous in thread: 31 May 2005 16:08:06 +0100 using freetype2 with fblin4, Markus Wekenmann
Next in thread: 31 May 2005 16:08:06 +0100 Re: using freetype2 with fblin4, Steven Scholz

Subject: Re: [nanogui] using freetype2 with fblin4
From: Steven Scholz ####@####.####
Date: 31 May 2005 16:08:06 +0100
Message-Id: <429C7DC1.20903@imc-berlin.de>

Markus Wekenmann wrote:

> Hi,
> 
> is there a patch for using freetype2 with the fblin4 driver?
> I tried to implement the drawarea function but it do not work correct in my
> application.

Quick and Dirty. Not optimized but broking!

--
Steven

--- microwindows-0.90.prestine/src/drivers/fblin4.c	2003-02-25 20:52:25.000000000 +0100
+++ microwindows-0.90/src/drivers/fblin4.c	2004-09-09 12:55:30.000000000 +0200
@@ -16,6 +16,10 @@
 #include "device.h"
 #include "fb.h"
 
+
+#include <stdio.h>
+
+
 #if INVERT4BPP
 #define INVERT(c)	((c) = (~c & 0x0f))
 #else
@@ -35,6 +39,14 @@
 }
 
 /* Set pixel at x, y, to pixelval c*/
+#define linear4_drawpixelfast(psd, x, y, c) \
+{\
+	ADDR8	addr = psd->addr;\
+	addr += ((x)>>1) + (y) * psd->linelen;\
+	*addr = (*addr & notmask[(x)&1]) | ((c) << ((1-((x)&1))<<2));\
+}
+
+/* Set pixel at x, y, to pixelval c*/
 static void
 linear4_drawpixel(PSD psd, MWCOORD x, MWCOORD y, MWPIXELVAL c)
 {
@@ -187,6 +199,272 @@
 	DRAWOFF;
 }
 
+
+#if 1 /*MW_FEATURE_PSDOP_BITMAP_BYTES_MSB_FIRST*/
+/* psd->DrawArea operation PSDOP_BITMAP_BYTES_MSB_FIRST which
+ * takes a pixmap, each line is byte aligned, and copies it
+ * to the screen using fg_color and bg_color to replace a 1
+ * and 0 in the pixmap.
+ *
+ * The bitmap is ordered how you'd expect, with the MSB used
+ * for the leftmost of the 8 pixels controlled by each byte.
+ *
+ * Variables used in the gc:
+ *       dstx, dsty, dsth, dstw   Destination rectangle
+ *       srcx, srcy               Source rectangle
+ *       src_linelen              Linesize in bytes of source
+ *       pixels                   Pixmap data
+ *       fg_color                 Color of a '1' bit
+ *       bg_color                 Color of a '0' bit
+ *       gr_usebg                 If set, bg_color is used.  If zero,
+ *                                then '0' bits are transparent.
+ */
+static void
+linear4_drawarea_bitmap_bytes_msb_first(PSD psd, driver_gc_t * gc)
+{
+/*
+ * The difference between the MSB_FIRST and LSB_FIRST variants of
+ * this function is simply the definition of these three #defines.
+ *
+ * MWI_IS_BIT_BEFORE_OR_EQUAL(A,B) returns true if bit A is before
+ *     (i.e. to the left of) bit B.
+ * MWI_ADVANCE_BIT(X) advances X on to the next bit to the right,
+ *     and stores the result back in X.
+ * MWI_BIT_NO(N), where 0<=n<=7, gives the Nth bit, where 0 is the
+ *     leftmost bit and 7 is the rightmost bit.  This is a constant
+ *     iff N is a constant.
+ */
+#define MWI_IS_BIT_BEFORE_OR_EQUAL(a,b) ((a) >= (b))
+#define MWI_ADVANCE_BIT(target) ((target) >>= 1)
+#define MWI_BIT_NO(n) (0x80 >> (n))
+
+/*
+ * Two convenience defines - these are the same for MSB_FIRST and
+ * LSB_FIRST.
+ */
+#define MWI_FIRST_BIT MWI_BIT_NO(0)
+#define MWI_LAST_BIT  MWI_BIT_NO(7)
+
+	unsigned char prefix_first_bit;
+	unsigned char postfix_first_bit = MWI_FIRST_BIT;
+	unsigned char postfix_last_bit;
+	unsigned char bitmap_byte;
+	unsigned char mask;
+	unsigned char fg, bg;
+	int first_byte, last_byte;
+	int size_main;
+	int t, y;
+	unsigned int advance_src, advance_dst;
+	ADDR8 src;
+	ADDR8 dst;
+
+	/* The bit in the first byte, which corresponds to the leftmost pixel. */
+	prefix_first_bit = MWI_BIT_NO(gc->srcx & 7);
+
+	/* The bit in the last byte, which corresponds to the rightmost pixel. */
+	postfix_last_bit = MWI_BIT_NO((gc->srcx + gc->dstw - 1) & 7);
+
+	/* The index into each scanline of the first byte to use. */
+	first_byte = gc->srcx >> 3;
+
+	/* The index into each scanline of the last byte to use. */
+	last_byte = (gc->srcx + gc->dstw - 1) >> 3;
+
+	src = ((ADDR8) gc->pixels) + gc->src_linelen * gc->srcy + first_byte;
+	dst = ((ADDR8) psd->addr) + ((psd->linelen * gc->dsty + gc->dstx) / 2);	/* 4bpp = 2 ppb */
+
+	fg = gc->fg_color;
+	bg = gc->bg_color;
+
+	advance_src = gc->src_linelen - last_byte + first_byte - 1;
+	advance_dst = psd->linelen - (gc->dstw / 2);				/* 4bpp = 2 ppb */
+
+#if 0
+	printf("\n\n--------------------------------\n%s(%d): \n", __FUNCTION__, __LINE__);
+//	printf(" fg_color=%x, bg_color=%x\n", fg, bg);
+//	printf(" src=%08lx, dst=%08lx\n", (unsigned long) src, (unsigned long) dst);
+	printf(" first_byte=%d, last_byte=%d\n", first_byte, last_byte);
+//	printf(" gc->srcx=%d, gc->srcy=%d\n", gc->srcx, gc->srcy);
+	printf(" gc->src_linelen=%d\n", gc->src_linelen);
+	printf(" gc->dstx=%d, gc->dsty=%d\n", gc->dstx, gc->dsty);
+	printf(" gc->dstw=%d, gc->dsth=%d\n", gc->dstw, gc->dsth);
+//	printf(" gc->dst_linelen=%d\n", gc->dst_linelen);
+	printf(" advance_src=%08x, advance_dst=%08x\n", advance_src, advance_dst);
+	printf(" gc->gr_usebg=%d\n", gc->gr_usebg);
+#endif
+
+	if (first_byte != last_byte) {
+		/* The total number of bytes to use, less the two special-cased
+		 * bytes (first and last).
+		 */
+		size_main = last_byte - first_byte + 1 - 2;
+
+		if (prefix_first_bit == MWI_FIRST_BIT) {
+			/* No need to special case. */
+			prefix_first_bit = 0;
+			size_main++;
+		}
+		if (postfix_last_bit == MWI_LAST_BIT) {
+			/* No need to special case. */
+			postfix_last_bit = 0;
+			size_main++;
+		}
+	} else if ((prefix_first_bit == MWI_FIRST_BIT)
+		   && (postfix_last_bit == MWI_LAST_BIT)) {
+		/* Exactly one byte wide. */
+		prefix_first_bit = 0;
+		postfix_last_bit = 0;
+		size_main = 1;
+	} else {
+		/* Very narrow pixmap, fits in single first byte. */
+		/* Do everything in 'postfix' loop. */
+		postfix_first_bit = prefix_first_bit;
+		prefix_first_bit = 0;
+		size_main = 0;
+	}
+
+	DRAWON;
+
+#if 0
+	printf(" prefix_first_bit=%d\n", prefix_first_bit);
+	printf(" postfix_first_bit=%d\n", postfix_first_bit);
+	printf(" size_main=%d\n", size_main);
+
+#endif
+
+	if (gc->gr_usebg) {
+		for (y = 0; y < gc->dsth; y++) {
+			int x = 0;
+
+			/* Do pixels of partial first byte */
+			if (prefix_first_bit) {
+				bitmap_byte = *src++;
+				for (mask = prefix_first_bit; mask;
+				     MWI_ADVANCE_BIT(mask)) {
+				linear4_drawpixel(psd,gc->dstx+(x++),gc->dsty+y,(mask & bitmap_byte) ? fg : bg);
+				}
+			}
+
+			/* Do all pixels of main part one byte at a time */
+			for (t = size_main; t != 0; t--) {
+				bitmap_byte = *src++;
+				linear4_drawpixelfast(psd, gc->dstx+(x++), gc->dsty+y, (MWI_BIT_NO(0) & bitmap_byte) ? fg : bg);
+				linear4_drawpixelfast(psd, gc->dstx+(x++), gc->dsty+y, (MWI_BIT_NO(1) & bitmap_byte) ? fg : bg);
+				linear4_drawpixelfast(psd, gc->dstx+(x++), gc->dsty+y, (MWI_BIT_NO(2) & bitmap_byte) ? fg : bg);
+				linear4_drawpixelfast(psd, gc->dstx+(x++), gc->dsty+y, (MWI_BIT_NO(3) & bitmap_byte) ? fg : bg);
+				linear4_drawpixelfast(psd, gc->dstx+(x++), gc->dsty+y, (MWI_BIT_NO(4) & bitmap_byte) ? fg : bg);
+				linear4_drawpixelfast(psd, gc->dstx+(x++), gc->dsty+y, (MWI_BIT_NO(5) & bitmap_byte) ? fg : bg);
+				linear4_drawpixelfast(psd, gc->dstx+(x++), gc->dsty+y, (MWI_BIT_NO(6) & bitmap_byte) ? fg : bg);
+				linear4_drawpixelfast(psd, gc->dstx+(x++), gc->dsty+y, (MWI_BIT_NO(7) & bitmap_byte) ? fg : bg);
+			}
+
+			/* Do last few bits of line */
+			if (postfix_last_bit) {
+				bitmap_byte = *src++;
+				for (mask = postfix_first_bit;
+				     MWI_IS_BIT_BEFORE_OR_EQUAL(mask,
+								postfix_last_bit);
+				     MWI_ADVANCE_BIT(mask)) {
+					linear4_drawpixel(psd,gc->dstx+(x++),gc->dsty+y,(mask & bitmap_byte) ? fg : bg);
+				}
+			}
+			src += advance_src;
+			dst += advance_dst;
+		}
+	} else {	/* don't use background */
+		for (y = 0; y < gc->dsth; y++) {
+			int x = 0;
+
+			/* Do pixels of partial first byte */
+			if (prefix_first_bit) {
+				bitmap_byte = *src++;
+				for (mask = prefix_first_bit; mask;
+				     MWI_ADVANCE_BIT(mask)) {
+					if (mask & bitmap_byte)
+						linear4_drawpixel(psd,gc->dstx+(x),gc->dsty+y, fg);
+					x++;
+					dst++;
+				}
+			}
+
+			/* Do all pixels of main part one byte at a time */
+			for (t = size_main; t != 0; t--) {
+				bitmap_byte = *src++;
+
+				if (MWI_BIT_NO(0) & bitmap_byte)
+					linear4_drawpixelfast(psd,gc->dstx+(x),gc->dsty+y, fg);
+				x++;
+				if (MWI_BIT_NO(1) & bitmap_byte)
+					linear4_drawpixelfast(psd,gc->dstx+(x),gc->dsty+y, fg);
+				x++;
+				if (MWI_BIT_NO(2) & bitmap_byte)
+					linear4_drawpixelfast(psd,gc->dstx+(x),gc->dsty+y, fg);
+				x++;
+				if (MWI_BIT_NO(3) & bitmap_byte)
+					linear4_drawpixelfast(psd,gc->dstx+(x),gc->dsty+y, fg);
+				x++;
+				if (MWI_BIT_NO(4) & bitmap_byte)
+					linear4_drawpixelfast(psd,gc->dstx+(x),gc->dsty+y, fg);
+				x++;
+				if (MWI_BIT_NO(5) & bitmap_byte)
+					linear4_drawpixelfast(psd,gc->dstx+(x),gc->dsty+y, fg);
+				x++;
+				if (MWI_BIT_NO(6) & bitmap_byte)
+					linear4_drawpixelfast(psd,gc->dstx+(x),gc->dsty+y, fg);
+				x++;
+				if (MWI_BIT_NO(7) & bitmap_byte)
+					linear4_drawpixelfast(psd,gc->dstx+(x),gc->dsty+y, fg);
+				x++;
+
+				dst += 8;
+			}
+
+			/* Do last few bits of line */
+			if (postfix_last_bit) {
+				bitmap_byte = *src++;
+				for (mask = postfix_first_bit;
+				     MWI_IS_BIT_BEFORE_OR_EQUAL(mask,
+								postfix_last_bit);
+				     MWI_ADVANCE_BIT(mask)) {
+					if (mask & bitmap_byte)
+						linear4_drawpixel(psd,gc->dstx+(x),gc->dsty+y, fg);
+					x++;
+					dst++;
+				}
+			}
+			src += advance_src;
+			dst += advance_dst;
+		}
+	}
+
+	DRAWOFF;
+
+#undef MWI_IS_BIT_BEFORE_OR_EQUAL
+#undef MWI_ADVANCE_BIT
+#undef MWI_BIT_NO
+#undef MWI_FIRST_BIT
+#undef MWI_LAST_BIT
+}
+#endif /* MW_FEATURE_PSDOP_BITMAP_BYTES_MSB_FIRST */
+
+
+
+static void
+linear4_drawarea(PSD psd, driver_gc_t * gc, int op)
+{
+	assert(psd->addr != 0);
+	/*assert(gc->dstw <= gc->srcw); */
+	assert(gc->dstx >= 0 && gc->dstx + gc->dstw <= psd->xres);
+	/*assert(gc->dsty >= 0 && gc->dsty+gc->dsth <= psd->yres); */
+	/*assert(gc->srcx >= 0 && gc->srcx+gc->dstw <= gc->srcw); */
+	assert(gc->srcy >= 0);
+
+//	printf("linear4_drawarea op=%d dstx=%d dsty=%d\n", op, gc->dstx, gc->dsty);
+
+	linear4_drawarea_bitmap_bytes_msb_first(psd, gc);
+}
+
+
 SUBDRIVER fblinear4 = {
 	linear4_init,
 	linear4_drawpixel,
@@ -194,5 +472,64 @@
 	linear4_drawhorzline,
 	linear4_drawvertline,
 	gen_fillrect,
-	linear4_blit
+	linear4_blit,
+	linear4_drawarea
 };
+
+
+
+#if 0
+			/* Do pixels of partial first byte */
+			if (prefix_first_bit) {
+				bitmap_byte = *src++;
+				for (mask = prefix_first_bit; mask;
+				     MWI_ADVANCE_BIT(mask)) {
+					*dst++ = (mask & bitmap_byte) ? fg :
+						bg;
+				}
+			}
+
+			for (t = size_main; t != 0; t--) {
+				bitmap_byte = *src++;
+
+				*dst++ = (MWI_BIT_NO(0) & bitmap_byte) ? fg :
+					bg;
+				*dst++ = (MWI_BIT_NO(1) & bitmap_byte) ? fg :
+					bg;
+				*dst++ = (MWI_BIT_NO(2) & bitmap_byte) ? fg :
+					bg;
+				*dst++ = (MWI_BIT_NO(3) & bitmap_byte) ? fg :
+					bg;
+				*dst++ = (MWI_BIT_NO(4) & bitmap_byte) ? fg :
+					bg;
+				*dst++ = (MWI_BIT_NO(5) & bitmap_byte) ? fg :
+					bg;
+				*dst++ = (MWI_BIT_NO(6) & bitmap_byte) ? fg :
+					bg;
+				*dst++ = (MWI_BIT_NO(7) & bitmap_byte) ? fg :
+					bg;
+			}
+
+			/* Do last few bits of line */
+			if (postfix_last_bit) {
+				bitmap_byte = *src++;
+				for (mask = postfix_first_bit;
+				     MWI_IS_BIT_BEFORE_OR_EQUAL(mask,
+								postfix_last_bit);
+				     MWI_ADVANCE_BIT(mask)) {
+					*dst++ = (mask & bitmap_byte) ? fg :
+						bg;
+				}
+			}
+#endif
+#if 0
+printf("%c", (MWI_BIT_NO(0) & bitmap_byte) ? '.' : ' ');
+printf("%c", (MWI_BIT_NO(1) & bitmap_byte) ? '.' : ' ');
+printf("%c", (MWI_BIT_NO(2) & bitmap_byte) ? '.' : ' ');
+printf("%c", (MWI_BIT_NO(3) & bitmap_byte) ? '.' : ' ');
+printf("%c", (MWI_BIT_NO(4) & bitmap_byte) ? '.' : ' ');
+printf("%c", (MWI_BIT_NO(5) & bitmap_byte) ? '.' : ' ');
+printf("%c", (MWI_BIT_NO(6) & bitmap_byte) ? '.' : ' ');
+printf("%c", (MWI_BIT_NO(7) & bitmap_byte) ? '.' : ' ');
+#endif
+//printf("\n");

Previous by date: 31 May 2005 16:08:06 +0100 using freetype2 with fblin4, Markus Wekenmann
Next by date: 31 May 2005 16:08:06 +0100 Re: using freetype2 with fblin4, Steven Scholz
Previous in thread: 31 May 2005 16:08:06 +0100 using freetype2 with fblin4, Markus Wekenmann
Next in thread: 31 May 2005 16:08:06 +0100 Re: using freetype2 with fblin4, Steven Scholz


Powered by ezmlm-browse 0.20.