From: bernie Date: Tue, 7 Mar 2006 22:18:04 +0000 (+0000) Subject: Correctly compute text width for prop fonts; Make styles a per-bitmap attribute. X-Git-Tag: 1.0.0~681 X-Git-Url: https://codewiz.org/gitweb?a=commitdiff_plain;h=c66da8dee53d20f2bc02267d798530f5fb1bf37f;p=bertos.git Correctly compute text width for prop fonts; Make styles a per-bitmap attribute. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@560 38d2e660-2303-0410-9eaa-f027e97ec537 --- diff --git a/gfx/bitmap.c b/gfx/bitmap.c index ccc6f0be..e99a254d 100755 --- a/gfx/bitmap.c +++ b/gfx/bitmap.c @@ -16,6 +16,9 @@ /*#* *#* $Log$ + *#* Revision 1.7 2006/03/07 22:18:04 bernie + *#* Correctly compute text width for prop fonts; Make styles a per-bitmap attribute. + *#* *#* Revision 1.6 2006/02/23 11:17:16 bernie *#* Documentation fixes. *#* @@ -73,6 +76,7 @@ void gfx_bitmapInit(Bitmap *bm, uint8_t *raster, coord_t w, coord_t h) #if CONFIG_GFX_TEXT gfx_setFont(bm, &default_font); + bm->styles = 0; #endif #if CONFIG_GFX_CLIPPING diff --git a/gfx/gfx.h b/gfx/gfx.h index 1def1e88..324c7c59 100755 --- a/gfx/gfx.h +++ b/gfx/gfx.h @@ -14,6 +14,9 @@ /*#* *#* $Log$ + *#* Revision 1.11 2006/03/07 22:18:04 bernie + *#* Correctly compute text width for prop fonts; Make styles a per-bitmap attribute. + *#* *#* Revision 1.10 2006/02/17 22:24:40 bernie *#* Fix undefined preprocessor symbol. *#* @@ -125,6 +128,15 @@ typedef struct Bitmap #if CONFIG_GFX_TEXT const struct Font *font;/**< Current font for text rendering. */ + + /** + * Algorithmic text style flags. + * + * The text rendering routine can apply a few simple transformations + * to the current font in order to generate common styles such as + * bold, italic and underline from plain glyphs. + */ + uint8_t styles; #endif #if CONFIG_GFX_VCOORDS /*! diff --git a/gfx/text.c b/gfx/text.c index 0fa994cd..9c96c983 100755 --- a/gfx/text.c +++ b/gfx/text.c @@ -15,6 +15,9 @@ /*#* *#* $Log$ + *#* Revision 1.5 2006/03/07 22:18:04 bernie + *#* Correctly compute text width for prop fonts; Make styles a per-bitmap attribute. + *#* *#* Revision 1.4 2006/02/15 09:10:15 bernie *#* Implement prop fonts; Fix algo styles. *#* @@ -92,16 +95,6 @@ #include -/*! - * Flags degli stili algoritmici - * - * La routine di rendering del testo e' in grado di applicare - * delle semplici trasformazioni al font interno per generare - * automaticamente degli stili predefiniti (bold, italic, - * underline) a partire dal set di caratteri plain. - */ -static uint8_t text_styles; - /*! ANSI escape sequences flag: true for ESC state on */ static bool ansi_mode = false; @@ -178,19 +171,20 @@ static int text_putglyph(char c, struct Bitmap *bm) glyph = bm->font->glyph + index * glyph_height_bytes * glyph_width; } - if (text_styles & STYLEF_CONDENSED) - --glyph_width; - - if (text_styles & STYLEF_EXPANDED) - glyph_width *= 2; - /* Slow path for styled glyphs */ - if (text_styles) + if (bm->styles) { uint8_t prev_dots = 0, italic_prev_dots = 0; uint8_t dots; uint8_t row, col; + /* This style alone could be handled by the fast path too */ + if (bm->styles & STYLEF_CONDENSED) + --glyph_width; + + if (bm->styles & STYLEF_EXPANDED) + glyph_width *= 2; + /* 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)) @@ -208,14 +202,14 @@ static int text_putglyph(char c, struct Bitmap *bm) uint8_t i; /* Expanded style: advances only once every two columns. */ - if (text_styles & STYLEF_EXPANDED) + if (bm->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) + if (bm->styles & STYLEF_ITALIC) { uint8_t new_dots = dots; dots = (dots & 0xF0) | italic_prev_dots; @@ -223,7 +217,7 @@ static int text_putglyph(char c, struct Bitmap *bm) } /* Bold: "or" pixels with the previous column */ - if (text_styles & STYLEF_BOLD) + if (bm->styles & STYLEF_BOLD) { uint8_t new_dots = dots; dots |= prev_dots; @@ -231,11 +225,11 @@ static int text_putglyph(char c, struct Bitmap *bm) } /* Underlined: turn on base pixel */ - if (text_styles & STYLEF_UNDERLINE) + if (bm->styles & STYLEF_UNDERLINE) dots |= 0x80; /* Inverted: invert pixels */ - if (text_styles & STYLEF_INVERT) + if (bm->styles & STYLEF_INVERT) dots = ~dots; /* Output dots */ @@ -272,7 +266,7 @@ int text_putchar(char c, struct Bitmap *bm) gfx_bitmapClear(bm); bm->penX = 0; bm->penY = 0; - text_style(0, STYLEF_MASK); + text_style(bm, 0, STYLEF_MASK); break; DB(default: kprintf("Unknown ANSI esc code: %x\n", c);) @@ -324,20 +318,20 @@ void text_clearLine(struct Bitmap *bm, int line) * * Examples: * Turn on bold, leave other styles alone - * \code prt_style(STYLEF_BOLD, STYLEF_BOLD); \endcode + * \code text_style(bm, STYLEF_BOLD, STYLEF_BOLD); \endcode * * Turn off bold and turn on italic, leave others as they are - * \code prt_style(STYLEF_ITALIC, STYLEF_BOLD | STYLEF_ITALIC); \endcode + * \code text_style(bm, STYLEF_ITALIC, STYLEF_BOLD | STYLEF_ITALIC); \endcode * * Query current style without chaning it - * \code style = prt_style(0, 0); \endcode + * \code style = text_style(bm, 0, 0); \endcode * * Reset all styles (plain text) - * \code prt_style(0, STYLE_MASK); \endcode + * \code text_style(bm, 0, STYLE_MASK); \endcode */ -uint8_t text_style(uint8_t flags, uint8_t mask) +uint8_t text_style(struct Bitmap *bm, uint8_t flags, uint8_t mask) { - uint8_t old = text_styles; - text_styles = (text_styles & ~mask) | flags; + uint8_t old = bm->styles; + bm->styles = (bm->styles & ~mask) | flags; return old; } diff --git a/gfx/text.h b/gfx/text.h index c8b1d12b..1f00e7fa 100755 --- a/gfx/text.h +++ b/gfx/text.h @@ -15,6 +15,9 @@ /*#* *#* $Log$ + *#* Revision 1.4 2006/03/07 22:18:04 bernie + *#* Correctly compute text width for prop fonts; Make styles a per-bitmap attribute. + *#* *#* Revision 1.3 2006/02/10 12:26:19 bernie *#* Add STYLEF_TALL (unimplemented). *#* @@ -107,7 +110,7 @@ struct Bitmap; void text_moveto(struct Bitmap *bm, int row, int col); void text_setcoord(struct Bitmap *bm, int x, int y); int text_putchar(char c, struct Bitmap *bm); -uint8_t text_style(uint8_t flags, uint8_t mask); +uint8_t text_style(struct Bitmap *bm, uint8_t flags, uint8_t mask); void text_clear(struct Bitmap *bm); void text_clearLine(struct Bitmap *bm, int line); diff --git a/gfx/text_format.c b/gfx/text_format.c index c59a3af9..e1452d8a 100755 --- a/gfx/text_format.c +++ b/gfx/text_format.c @@ -15,6 +15,9 @@ /*#* *#* $Log$ + *#* Revision 1.5 2006/03/07 22:18:04 bernie + *#* Correctly compute text width for prop fonts; Make styles a per-bitmap attribute. + *#* *#* Revision 1.4 2006/02/10 12:31:33 bernie *#* Add multiple font support in bitmaps. *#* @@ -160,7 +163,7 @@ int PGM_FUNC(text_xprintf)(struct Bitmap *bm, text_moveto(bm, row, col); if (style & STYLEF_MASK) - oldstyle = text_style(style, STYLEF_MASK); + oldstyle = text_style(bm, style, STYLEF_MASK); if (style & (TEXT_CENTER | TEXT_RIGHT)) { @@ -185,12 +188,66 @@ int PGM_FUNC(text_xprintf)(struct Bitmap *bm, /* Restore old style */ if (style & STYLEF_MASK) - text_style(oldstyle, STYLEF_MASK); + text_style(bm, oldstyle, STYLEF_MASK); return len; } +struct TextWidthData +{ + Bitmap *bitmap; + coord_t width; +}; + +/** + * Compute width in pixels of a character. + * + * Compute the on screen width of a character, taking the + * current style and font into account. + * + * The width is accumulated in the WidthData structure + * passed as second argument. + * + * This is a formatted_write() callback used by text_vwidthf() + * to compute the length of a formatted string. + */ +static int text_charWidth(int c, struct TextWidthData *twd) +{ + unsigned char index = (unsigned char)c; + Bitmap *bm = twd->bitmap; + coord_t glyph_width; + + + if (index < bm->font->first || index > bm->font->last) + { + if ('?' >= bm->font->first && '?' <= bm->font->last) + index = '?'; + else + index = bm->font->first; + } + + /* Make character relative to font start */ + index -= bm->font->first; + + if (bm->font->offset) + /* Proportional font */ + glyph_width = bm->font->widths[index]; /* TODO: optimize away */ + else + /* Fixed width font */ + glyph_width = bm->font->width; + + if (bm->styles & STYLEF_CONDENSED) + --glyph_width; + + if (bm->styles & STYLEF_EXPANDED) + glyph_width *= 2; + + twd->width += glyph_width; + + return c; +} + /*! * Return the width in pixels of a vprintf()-formatted string. */ @@ -199,7 +256,15 @@ int PGM_FUNC(text_vwidthf)( const char * PGM_ATTR fmt, va_list ap) { - return PGM_FUNC(vsprintf)(NULL, fmt, ap) * bm->font->width; + /* Fixed font with no styles affecting the width? */ + if (!bm->font->offset && !(bm->styles & (STYLEF_CONDENSED | STYLEF_EXPANDED))) + return PGM_FUNC(vsprintf)(NULL, fmt, ap) * bm->font->width; + else + { + struct TextWidthData twd = { bm, 0 }; + _formatted_write(fmt, (void (*)(char, void *))text_charWidth, &twd, ap); + return twd.width; + } }