From 39108834d9c102712d6c11830ca9b9fb5b098d19 Mon Sep 17 00:00:00 2001 From: bernie Date: Wed, 15 Feb 2006 09:10:15 +0000 Subject: [PATCH] Implement prop fonts; Fix algo styles. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@510 38d2e660-2303-0410-9eaa-f027e97ec537 --- gfx/bitmap.c | 14 +++-- gfx/font.h | 21 +++++-- gfx/gfx.h | 9 ++- gfx/gfx_p.h | 12 ++++ gfx/text.c | 164 ++++++++++++++++++++++++++++++--------------------- 5 files changed, 140 insertions(+), 80 deletions(-) diff --git a/gfx/bitmap.c b/gfx/bitmap.c index 0cb67d47..01ae977a 100755 --- a/gfx/bitmap.c +++ b/gfx/bitmap.c @@ -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 /* ASSERT() */ #include /* CPU_HARVARD */ #include /* MIN() */ +#include /* CONFIG_GFX_CLIPPING */ #include /* 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)); } diff --git a/gfx/font.h b/gfx/font.h index 1701b1fc..d3b241e2 100755 --- a/gfx/font.h +++ b/gfx/font.h @@ -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 */ diff --git a/gfx/gfx.h b/gfx/gfx.h index 7159cdb3..fb7e615f 100755 --- 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; } diff --git a/gfx/gfx_p.h b/gfx/gfx_p.h index 8482d8e6..101eb12c 100755 --- a/gfx/gfx_p.h +++ b/gfx/gfx_p.h @@ -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. *#* @@ -29,14 +32,21 @@ #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 */ diff --git a/gfx/text.c b/gfx/text.c index 75d5dc3f..0fa994cd 100755 --- a/gfx/text.c +++ b/gfx/text.c @@ -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 #include +#include // FIXME: BM_DRAWPIXEL + #include @@ -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<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; -- 2.25.1