Correctly compute text width for prop fonts; Make styles a per-bitmap attribute.
authorbernie <bernie@38d2e660-2303-0410-9eaa-f027e97ec537>
Tue, 7 Mar 2006 22:18:04 +0000 (22:18 +0000)
committerbernie <bernie@38d2e660-2303-0410-9eaa-f027e97ec537>
Tue, 7 Mar 2006 22:18:04 +0000 (22:18 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@560 38d2e660-2303-0410-9eaa-f027e97ec537

gfx/bitmap.c
gfx/gfx.h
gfx/text.c
gfx/text.h
gfx/text_format.c

index ccc6f0bece6930a6465e31726dc2890722c2885a..e99a254d0f440dca8b28ebacd5e77f4b6c7c971c 100755 (executable)
@@ -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
index 1def1e88d0fbf8db429a82e6c3b466bea0e2e8db..324c7c59b97c272ae049491eb0116e20b65e393a 100755 (executable)
--- 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
        /*!
index 0fa994cd55189e41abbd9a8ba44b9ad9a7d6392b..9c96c983c3613c0254e7ef1bba54eb04e6fa7598 100755 (executable)
@@ -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.
  *#*
 #include <cfg/debug.h>
 
 
-/*!
- * 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;
 }
index c8b1d12b98475c23d7fb5711a84bec4158586f04..1f00e7fa3aa58b7eb49453bd171fa28cf4c30c64 100755 (executable)
@@ -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);
 
index c59a3af9141cd81442d05f6773319e2ca5ac4bc4..e1452d8a0015f0f354d1f40c4b9c1b0e7b236ca9 100755 (executable)
@@ -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;
+       }
 }