X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=gfx%2Ftext.c;fp=gfx%2Ftext.c;h=0fa994cd55189e41abbd9a8ba44b9ad9a7d6392b;hb=39108834d9c102712d6c11830ca9b9fb5b098d19;hp=75d5dc3fc3b0dbd93ed8e7013d94365f0427d64c;hpb=11325315fd4947c5a7b31ae63060cc6c8cde822e;p=bertos.git 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;