/*#*
*#* $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.
*#*
#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() */
}
-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;
/*
* 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;
/* 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));
}
/*#*
*#* $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.
*#*
* 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 */
/*#*
*#* $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.
*#*
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
/*!
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);
#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;
}
/*#*
*#* $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 */
#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 */
/*#*
*#* $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.
*#*
#include <gfx/text.h>
#include <gfx/text.h>
+#include <gfx/gfx_p.h> // FIXME: BM_DRAWPIXEL
+
#include <cfg/debug.h>
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;
/*!
- * 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;