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");