Implement prop fonts; Fix algo styles.
authorbernie <bernie@38d2e660-2303-0410-9eaa-f027e97ec537>
Wed, 15 Feb 2006 09:10:15 +0000 (09:10 +0000)
committerbernie <bernie@38d2e660-2303-0410-9eaa-f027e97ec537>
Wed, 15 Feb 2006 09:10:15 +0000 (09:10 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@510 38d2e660-2303-0410-9eaa-f027e97ec537

gfx/bitmap.c
gfx/font.h
gfx/gfx.h
gfx/gfx_p.h
gfx/text.c

index 0cb67d4739d085a779c82d90ab909511769e5466..01ae977a105d4782e14910d989c3e22abc1c71c9 100755 (executable)
@@ -16,6 +16,9 @@
 
 /*#*
  *#* $Log$
+ *#* Revision 1.5  2006/02/15 09:10:15  bernie
+ *#* Implement prop fonts; Fix algo styles.
+ *#*
  *#* Revision 1.4  2006/02/10 12:32:33  bernie
  *#* Add multiple font support in bitmaps; gfx_blitRaster(): New function.
  *#*
@@ -36,6 +39,7 @@
 #include <cfg/debug.h>  /* ASSERT() */
 #include <cfg/cpu.h>    /* CPU_HARVARD */
 #include <cfg/macros.h> /* MIN() */
+#include <appconfig.h>  /* CONFIG_GFX_CLIPPING */
 
 #include <string.h>     /* memset() */
 
@@ -146,7 +150,7 @@ void gfx_blit(Bitmap *dst, const Rect *rect, const Bitmap *src, coord_t srcx, co
 }
 
 
-void gfx_blitRaster(Bitmap *dst, coord_t dxmin, coord_t dymin, const uint8_t *raster, coord_t w, coord_t h)
+void gfx_blitRaster(Bitmap *dst, coord_t dxmin, coord_t dymin, const uint8_t *raster, coord_t w, coord_t h, coord_t stride)
 {
        coord_t dxmax, dymax;
        coord_t sxmin = 0, symin = 0;
@@ -155,12 +159,12 @@ void gfx_blitRaster(Bitmap *dst, coord_t dxmin, coord_t dymin, const uint8_t *ra
        /*
         * Clip coordinates inside dst->cr.
         */
-       if (dx < dst->cr.xmin)
+       if (dxmin < dst->cr.xmin)
        {
                sxmin += dst->cr.xmin - dxmin;
                dxmin = dst->cr.xmin;
        }
-       if (dy < dst->cr.ymin)
+       if (dymin < dst->cr.ymin)
        {
                symin += dst->cr.ymin - dymin;
                dymin = dst->cr.ymin;
@@ -171,9 +175,7 @@ void gfx_blitRaster(Bitmap *dst, coord_t dxmin, coord_t dymin, const uint8_t *ra
        /* TODO: make it not as dog slow as this */
        for (dx = dxmin, sx = sxmin; dx < dxmax; ++dx, ++sx)
                for (dy = dymin, sy = symin; dy < dymax; ++dy, ++sy)
-                       BM_DRAWPIXEL(dst, dx, dy,
-                               (raster[sy * ((w + 7) / 8) + sx / 8] & (1 << (7 - sx % 8))) ? 1 : 0
-                       );
+                       BM_DRAWPIXEL(dst, dx, dy, RAST_READPIXEL(raster, sx, sy, stride));
 }
 
 
index 1701b1fc94acd9c15780b8c7e8e61e861305ceb4..d3b241e2913b57af918b9d2366dcc65b00aab332 100755 (executable)
@@ -14,6 +14,9 @@
 
 /*#*
  *#* $Log$
+ *#* Revision 1.4  2006/02/15 09:10:15  bernie
+ *#* Implement prop fonts; Fix algo styles.
+ *#*
  *#* Revision 1.3  2006/02/10 12:29:05  bernie
  *#* Add multiple font support in bitmaps.
  *#*
@@ -62,14 +65,22 @@ typedef struct Font
         * Data is an array of at most 256 glyphs packed together.
         * Raster format must be the same of the bitmap.
         */
-       const PROGMEM uint8_t * const glyph;
+       const PROGMEM uint8_t *glyph;
+
+       uint8_t width;     /**< Pixel width of character cell. */
+       uint8_t height;    /**< Pixel height of character cell. */
+
+       uint8_t first;     /**< First encoded character in glyph array. */
+       uint8_t last;      /**< Last encoded character in glyph array (inclusive). */
 
-       uint8_t width;    /**< Pixel width of character cell. */
-       uint8_t height;   /**< Pixel height of character cell. */
+       /** Array of glyph offsets in bytes. NULL for fixed-width fonts. */
+       const PROGMEM uint16_t *offset;
+       const PROGMEM uint8_t *widths;
 
 } Font;
 
-/**< The default font. */
-extern struct Font default_font;
+/** The default font. */
+#define default_font font_ncenB18
+extern const struct Font default_font;
 
 #endif /* GFX_FONT_H */
index 7159cdb306b78df72f56fae19d8344a2776e54ca..fb7e615f7b4be737c3ca17b2b64a3698a07899a1 100755 (executable)
--- a/gfx/gfx.h
+++ b/gfx/gfx.h
@@ -14,6 +14,9 @@
 
 /*#*
  *#* $Log$
+ *#* Revision 1.9  2006/02/15 09:10:15  bernie
+ *#* Implement prop fonts; Fix algo styles.
+ *#*
  *#* Revision 1.8  2006/02/10 12:28:33  bernie
  *#* Add font support in bitmaps; Make bitmap formats public.
  *#*
@@ -118,7 +121,7 @@ typedef struct Bitmap
        Rect cr;                /*!< Clip drawing inside this rectangle */
 
 #if CONFIG_GFX_TEXT
-       struct Font *font;      /**< Current font for text rendering. */
+       const struct Font *font;/**< Current font for text rendering. */
 #endif
 #if CONFIG_GFX_VCOORDS
        /*!
@@ -154,7 +157,7 @@ typedef struct Bitmap
 void gfx_bitmapInit (Bitmap *bm, uint8_t *raster, coord_t w, coord_t h);
 void gfx_bitmapClear(Bitmap *bm);
 void gfx_blit       (Bitmap *dst, const Rect *rect, const Bitmap *src, coord_t srcx, coord_t srcy);
-void gfx_blitRaster (Bitmap *dst, coord_t dx, coord_t dy, const uint8_t *raster, coord_t w, coord_t h);
+void gfx_blitRaster (Bitmap *dst, coord_t dx, coord_t dy, const uint8_t *raster, coord_t w, coord_t h, coord_t stride);
 void gfx_line       (Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2);
 void gfx_rectDraw   (Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2);
 void gfx_rectFillC  (Bitmap *bm, coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint8_t color);
@@ -170,7 +173,7 @@ void gfx_setClipRect(Bitmap *bm, coord_t xmin, coord_t ymin, coord_t xmax, coord
 #endif
 
 #if CONFIG_GFX_TEXT
-INLINE void gfx_setFont(Bitmap *bm, Font *font)
+INLINE void gfx_setFont(Bitmap *bm, const struct Font *font)
 {
        bm->font = font;
 }
index 8482d8e6bd91baa333af0c5a91bf4e923eb8e6fb..101eb12c89ae85cc39f84498c183e6c7fc8ff0d1 100755 (executable)
@@ -15,6 +15,9 @@
 
 /*#*
  *#* $Log$
+ *#* Revision 1.3  2006/02/15 09:10:15  bernie
+ *#* Implement prop fonts; Fix algo styles.
+ *#*
  *#* Revision 1.2  2006/02/10 12:28:33  bernie
  *#* Add font support in bitmaps; Make bitmap formats public.
  *#*
 
 #if CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_H_MSB
 
+       //TODO: Collapse with RAST_* macros
        #define BM_ADDR(bm, x, y)  ((bm)->raster + (y) * (bm)->stride + ((x) / 8))
        #define BM_MASK(bm, x, y)  (1 << (7 - (x) % 8))
 
+       #define RAST_ADDR(raster, x, y, stride)  ((raster) + (y) * (stride) + (x) / 8)
+       #define RAST_MASK(raster, x, y)          (1 << (7 - (x) % 8))
+
 #elif CONFIG_BITMAP_FMT == BITMAP_FMT_PLANAR_V_LSB
 
        #define BM_ADDR(bm, x, y)  ((bm)->raster + ((y) / 8) * (bm)->stride + (x))
        #define BM_MASK(bm, x, y)  (1 << ((y) % 8))
 
+       // FIXME: not the same format of bitmaps!
+       #define RAST_ADDR(raster, x, y, stride)  ((raster) + (y) / 8 + (x) * (stride))
+       #define RAST_MASK(raster, x, y)          (1 << ((y) % 8))
 #else
        #error Unknown value of CONFIG_BITMAP_FMT
 #endif /* CONFIG_BITMAP_FMT */
@@ -84,5 +94,7 @@
 #define BM_READPIXEL(bm, x, y) \
        ( *BM_ADDR(bm, x, y) & BM_MASK(bm, x, y) ? 1 : 0 )
 
+#define RAST_READPIXEL(raster, x, y, stride) \
+               ( *RAST_ADDR(raster, x, y, stride) & RAST_MASK(raster, x, y) ? 1 : 0 )
 
 #endif /* GFX_GFX_P_H */
index 75d5dc3fc3b0dbd93ed8e7013d94365f0427d64c..0fa994cd55189e41abbd9a8ba44b9ad9a7d6392b 100755 (executable)
@@ -15,6 +15,9 @@
 
 /*#*
  *#* $Log$
+ *#* Revision 1.4  2006/02/15 09:10:15  bernie
+ *#* Implement prop fonts; Fix algo styles.
+ *#*
  *#* Revision 1.3  2006/02/10 12:31:55  bernie
  *#* Add multiple font support in bitmaps.
  *#*
@@ -84,6 +87,8 @@
 #include <gfx/text.h>
 #include <gfx/text.h>
 
+#include <gfx/gfx_p.h> // FIXME: BM_DRAWPIXEL
+
 #include <cfg/debug.h>
 
 
@@ -110,7 +115,7 @@ void text_moveto(struct Bitmap *bm, int row, int col)
        ASSERT(col >= 0);
        ASSERT(col < bm->width / bm->font->width);
        ASSERT(row >= 0);
-//     ASSERT(row < bm->height / bm->font->height);
+       ASSERT(row < bm->height / bm->font->height);
 
        bm->penX = col * bm->font->width;
        bm->penY = row * bm->font->height;
@@ -128,97 +133,124 @@ void text_setcoord(struct Bitmap *bm, int x, int y)
 
 
 /*!
- * Render char \a c on Bitmap \a bm
+ * Render char \a c on Bitmap \a bm.
  */
 static int text_putglyph(char c, struct Bitmap *bm)
 {
        const uint8_t * PROGMEM glyph;  /* font is in progmem */
-       uint8_t glyph_width;
-       uint8_t i;
-       uint8_t *buf;
+       uint8_t glyph_width, glyph_height, glyph_height_bytes;
+       unsigned char index = (unsigned char)c;
 
-       /*
-        * Compute the first column of pixels of the selected glyph,
-        * using the character code to index the glyph array.
-        */
-       glyph_width = bm->font->width;
-       glyph = &bm->font->glyph[(unsigned char)c * (((glyph_width + 7) / 8) * bm->font->height) ];
+       /* Check for out of range char and replace with '?' or first char in font. */
+       if (index < bm->font->first || index > bm->font->last)
+       {
+               kprintf("Illegal char '%c' (0x%02x)\n", index, index);
+               if ('?' >= bm->font->first && '?' <= bm->font->last)
+                       index = '?';
+               else
+                       index = bm->font->first;
+       }
 
-       if (text_styles & STYLEF_CONDENSED)
-               --glyph_width;
+       /* Make character relative to font start */
+       index -= bm->font->first;
 
-       if (text_styles & STYLEF_EXPANDED)
-               glyph_width *= 2;
-
-       /* The y coord is rounded at multiples of 8 for simplicity */
-//     bm->penY &= ~((coord_t)7);
+       glyph_height = bm->font->height;
+       // FIXME: for vertical fonts only
+       glyph_height_bytes = (glyph_height + 7) / 8;
 
-       /* Check if glyph to write fits in the bitmap */
-       if ((bm->penX < 0) || (bm->penX + glyph_width > bm->width)
-               || (bm->penY < 0) || (bm->penY + bm->font->height > bm->height))
+       if (bm->font->offset)
+       {
+               /* Proportional font */
+               glyph_width = bm->font->widths[index]; /* TODO: optimize away */
+               glyph = bm->font->glyph + bm->font->offset[index];
+       }
+       else
        {
-               kprintf("w=%d, h=%d\n", glyph_width, bm->font->height);
-               DB(kprintf("bad coords x=%d y=%d\n", bm->penX, bm->penY);)
-               return 0;
+               /*
+                * Fixed-width font: compute the first column of pixels
+                * of the selected glyph using the character code to index
+                * the glyph array.
+                */
+               glyph_width = bm->font->width;
+
+               //For horizontal fonts
+               //glyph = bm->font->glyph + index * (((glyph_width + 7) / 8) * glyph_height);
+               glyph = bm->font->glyph + index * glyph_height_bytes * glyph_width;
        }
 
-       /* Locate position where to write in the raster */
-       buf = bm->raster + bm->penY / 8 * bm->width + bm->penX;
+       if (text_styles & STYLEF_CONDENSED)
+               --glyph_width;
 
-//     bm->penX += glyph_width;
+       if (text_styles & STYLEF_EXPANDED)
+               glyph_width *= 2;
 
-       /* If some styles are set */
+       /* Slow path for styled glyphs */
        if (text_styles)
        {
-               uint8_t prev_dots = 0, italic_prev_dots = 0, new_dots;
+               uint8_t prev_dots = 0, italic_prev_dots = 0;
                uint8_t dots;
+               uint8_t row, col;
 
-               /* Per ogni colonna di dot del glyph... */
-               for (i = 0; i < glyph_width; ++i)
+               /* Check if glyph fits in the bitmap. */
+               if ((bm->penX < 0) || (bm->penX + glyph_width > bm->width)
+                       || (bm->penY < 0) || (bm->penY + glyph_height > bm->height))
                {
-                       dots = PGM_READ_CHAR(glyph);
-
-                       /* Advance to next column in glyph.
-                        * Expand: advances only once every two columns
-                        */
-                       if (!(text_styles & STYLEF_EXPANDED) || (i & 1))
-                               glyph++;
-
-                       /* Italic: get lower 4 dots from previous column */
-                       if (text_styles & STYLEF_ITALIC)
-                       {
-                               new_dots = dots;
-                               dots = (dots & 0xF0) | italic_prev_dots;
-                               italic_prev_dots = new_dots & 0x0F;
-                       }
+                       kprintf("bad coords x=%d y=%d\n", bm->penX, bm->penY);
+                       return 0;
+               }
 
-                       /* Bold: "or" pixels with the previous column */
-                       if (text_styles & STYLEF_BOLD)
+               for (row = 0; row < glyph_height_bytes; ++row)
+               {
+                       /* For each dot column in the glyph... */
+                       for (col = 0; col < glyph_width; ++col)
                        {
-                               new_dots = dots;
-                               dots |= prev_dots;
-                               prev_dots = new_dots;
+                               uint8_t src_col = col;
+                               uint8_t i;
+
+                               /* Expanded style: advances only once every two columns. */
+                               if (text_styles & STYLEF_EXPANDED)
+                                       src_col /= 2;
+
+                               /* Fetch a column of dots from glyph. */
+                               dots = PGM_READ_CHAR(glyph + src_col * glyph_height_bytes + row);
+
+                               /* Italic: get lower 4 dots from previous column */
+                               if (text_styles & STYLEF_ITALIC)
+                               {
+                                       uint8_t new_dots = dots;
+                                       dots = (dots & 0xF0) | italic_prev_dots;
+                                       italic_prev_dots = new_dots & 0x0F;
+                               }
+
+                               /* Bold: "or" pixels with the previous column */
+                               if (text_styles & STYLEF_BOLD)
+                               {
+                                       uint8_t new_dots = dots;
+                                       dots |= prev_dots;
+                                       prev_dots = new_dots;
+                               }
+
+                               /* Underlined: turn on base pixel */
+                               if (text_styles & STYLEF_UNDERLINE)
+                                       dots |= 0x80;
+
+                               /* Inverted: invert pixels */
+                               if (text_styles & STYLEF_INVERT)
+                                       dots = ~dots;
+
+                               /* Output dots */
+                               for (i = 0; i < 8 && (row * 8) + i < glyph_height; ++i)
+                                       BM_DRAWPIXEL(bm, bm->penX + col, bm->penY + row * 8 + i, dots & (1<<i));
                        }
-
-                       /* Underlined: turn on base pixel */
-                       if (text_styles & STYLEF_UNDERLINE)
-                               dots |= 0x80;
-
-                       /* Inverted: invert pixels */
-                       if (text_styles & STYLEF_INVERT)
-                               dots = ~dots;
-
-                       /* Output dots */
-                       *buf++ = dots;
                }
        }
        else
        {
-               /* No style: fast vanilla copy of glyph to line buffer */
-               gfx_blitRaster(bm, bm->penX, bm->penY, glyph, glyph_width, bm->font->height);
-//             while (glyph_width--)
-//                     *buf++ = PGM_READ_CHAR(glyph++);
+               /* No style: fast vanilla copy of glyph to bitmap */
+               gfx_blitRaster(bm, bm->penX, bm->penY, glyph, glyph_width, glyph_height, glyph_height_bytes);
        }
+
+       /* Update current pen position */
        bm->penX += glyph_width;
 
        return c;