X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=gfx%2Ftext.c;h=c37e871e508acb3c03c57a0d11e751d4646cadc4;hb=3fc75747c81395f9027b6b27cd03037e2a8eec08;hp=9c96c983c3613c0254e7ef1bba54eb04e6fa7598;hpb=c66da8dee53d20f2bc02267d798530f5fb1bf37f;p=bertos.git diff --git a/gfx/text.c b/gfx/text.c old mode 100755 new mode 100644 index 9c96c983..c37e871e --- a/gfx/text.c +++ b/gfx/text.c @@ -1,9 +1,34 @@ -/*! +/** * \file * * * \brief Text graphic routines @@ -15,6 +40,30 @@ /*#* *#* $Log$ + *#* Revision 1.13 2006/07/19 12:56:26 bernie + *#* Convert to new Doxygen style. + *#* + *#* Revision 1.12 2006/05/25 23:35:22 bernie + *#* Implement correct and faster clipping for algo text. + *#* + *#* Revision 1.11 2006/05/15 07:21:06 bernie + *#* Doxygen fix. + *#* + *#* Revision 1.10 2006/04/27 05:39:23 bernie + *#* Enhance text rendering to arbitrary x,y coords. + *#* + *#* Revision 1.9 2006/04/11 00:08:24 bernie + *#* text_offset(): New function, but I'm not quite confident with the design. + *#* + *#* Revision 1.8 2006/03/22 09:50:37 bernie + *#* Use the same format for fonts and rasters. + *#* + *#* Revision 1.7 2006/03/20 17:51:55 bernie + *#* Cleanups. + *#* + *#* Revision 1.6 2006/03/13 02:05:54 bernie + *#* Mark slow paths as UNLIKELY. + *#* *#* Revision 1.5 2006/03/07 22:18:04 bernie *#* Correctly compute text width for prop fonts; Make styles a per-bitmap attribute. *#* @@ -95,37 +144,39 @@ #include -/*! ANSI escape sequences flag: true for ESC state on */ +/** + * ANSI escape sequences flag: true for ESC state on. + * + * \todo Move to Bitmap.flags. + */ static bool ansi_mode = false; +/** + * Move (imaginary) cursor to coordinates specified. + */ +void text_setCoord(struct Bitmap *bm, int x, int y) +{ + bm->penX = x; + bm->penY = y; +} + -/*! +/** * Move (imaginary) cursor to column and row specified. * Next text write will start a that row and col. */ -void text_moveto(struct Bitmap *bm, int row, int col) +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); - bm->penX = col * bm->font->width; - bm->penY = row * bm->font->height; -} - - -/*! - * Move (imaginary) cursor to coordinates specified. - */ -void text_setcoord(struct Bitmap *bm, int x, int y) -{ - bm->penX = x; - bm->penY = y; + text_setCoord(bm, col * bm->font->width, row * bm->font->height); } -/*! +/** * Render char \a c on Bitmap \a bm. */ static int text_putglyph(char c, struct Bitmap *bm) @@ -135,10 +186,10 @@ static int text_putglyph(char c, struct Bitmap *bm) unsigned char index = (unsigned char)c; /* Check for out of range char and replace with '?' or first char in font. */ - if (index < bm->font->first || index > bm->font->last) + if (UNLIKELY(!FONT_HAS_GLYPH(bm->font, index))) { kprintf("Illegal char '%c' (0x%02x)\n", index, index); - if ('?' >= bm->font->first && '?' <= bm->font->last) + if (FONT_HAS_GLYPH(bm->font, '?')) index = '?'; else index = bm->font->first; @@ -172,11 +223,24 @@ static int text_putglyph(char c, struct Bitmap *bm) } /* Slow path for styled glyphs */ - if (bm->styles) + if (UNLIKELY(bm->styles)) { + uint8_t styles = bm->styles; uint8_t prev_dots = 0, italic_prev_dots = 0; uint8_t dots; - uint8_t row, col; + uint8_t row, col, row_bit; + + /* + * To avoid repeating clipping and other expensive computations, + * we cluster calls to gfx_blitRaster() using a small buffer. + */ + #define CONFIG_TEXT_RENDER_OPTIMIZE 1 + #if CONFIG_TEXT_RENDER_OPTIMIZE + #define RENDER_BUF_WIDTH 12 + #define RENDER_BUF_HEIGHT 8 + uint8_t render_buf[RAST_SIZE(RENDER_BUF_WIDTH, RENDER_BUF_HEIGHT)]; + uint8_t render_xpos = 0; + #endif /* This style alone could be handled by the fast path too */ if (bm->styles & STYLEF_CONDENSED) @@ -185,31 +249,22 @@ static int text_putglyph(char c, struct Bitmap *bm) 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)) - { - kprintf("bad coords x=%d y=%d\n", bm->penX, bm->penY); - return 0; - } - - for (row = 0; row < glyph_height_bytes; ++row) + for (row = 0, row_bit = 0; row < glyph_height_bytes; ++row, row_bit += 8) { /* For each dot column in the glyph... */ for (col = 0; col < glyph_width; ++col) { uint8_t src_col = col; - uint8_t i; /* Expanded style: advances only once every two columns. */ - if (bm->styles & STYLEF_EXPANDED) + if (styles & STYLEF_EXPANDED) src_col /= 2; /* Fetch a column of dots from glyph. */ - dots = PGM_READ_CHAR(glyph + src_col * glyph_height_bytes + row); + dots = PGM_READ_CHAR(RAST_ADDR(glyph, src_col, row_bit, glyph_width)); /* Italic: get lower 4 dots from previous column */ - if (bm->styles & STYLEF_ITALIC) + if (styles & STYLEF_ITALIC) { uint8_t new_dots = dots; dots = (dots & 0xF0) | italic_prev_dots; @@ -217,7 +272,7 @@ static int text_putglyph(char c, struct Bitmap *bm) } /* Bold: "or" pixels with the previous column */ - if (bm->styles & STYLEF_BOLD) + if (styles & STYLEF_BOLD) { uint8_t new_dots = dots; dots |= prev_dots; @@ -225,23 +280,48 @@ static int text_putglyph(char c, struct Bitmap *bm) } /* Underlined: turn on base pixel */ - if (bm->styles & STYLEF_UNDERLINE) - dots |= 0x80; + if ((styles & STYLEF_UNDERLINE) + && (row == glyph_height_bytes - 1)) + dots |= (1 << (glyph_height - row_bit - 1)); /* Inverted: invert pixels */ - if (bm->styles & STYLEF_INVERT) + if (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 + col - render_xpos + 1, bm->penY + row_bit, + render_buf, render_xpos, + MIN((uint8_t)RENDER_BUF_HEIGHT, (uint8_t)(glyph_height - row_bit)), + RENDER_BUF_WIDTH); + render_xpos = 0; + } + #else + gfx_blitRaster(bm, bm->penX + col, bm->penY + row_bit, + &dots, 1, MIN((uint8_t)8, glyph_height - row_bit), 1); + #endif } + + #if CONFIG_TEXT_RENDER_OPTIMIZE + /* Flush out rest of render buffer */ + if (render_xpos != 0) + { + gfx_blitRaster(bm, bm->penX + col - render_xpos, bm->penY + row_bit, + render_buf, render_xpos, + MIN((uint8_t)RENDER_BUF_HEIGHT, (uint8_t)(glyph_height - row_bit)), + RENDER_BUF_WIDTH); + render_xpos = 0; + } + #endif } } else { /* No style: fast vanilla copy of glyph to bitmap */ - gfx_blitRaster(bm, bm->penX, bm->penY, glyph, glyph_width, glyph_height, glyph_height_bytes); + gfx_blitRaster(bm, bm->penX, bm->penY, glyph, glyph_width, glyph_height, glyph_width); } /* Update current pen position */ @@ -251,14 +331,14 @@ static int text_putglyph(char c, struct Bitmap *bm) } -/*! +/** * Render char \c c, with (currently) limited ANSI escapes * emulation support and '\n' for newline. */ int text_putchar(char c, struct Bitmap *bm) { /* Handle ANSI escape sequences */ - if (ansi_mode) + if (UNLIKELY(ansi_mode)) { switch (c) { @@ -293,7 +373,7 @@ int text_putchar(char c, struct Bitmap *bm) } -/*! +/** * Clear the screen and reset cursor position */ void text_clear(struct Bitmap *bmp) @@ -309,9 +389,10 @@ void text_clearLine(struct Bitmap *bm, int line) } -/*! +/** * Set/clear algorithmic font style bits. * + * \param bm Pointer to Bitmap to affect. * \param flags Style flags to set * \param mask Mask of flags to modify * \return Old style flags