-/*!
+/**
* \file
* <!--
* Copyright 2003, 2004 Develer S.r.l. (http://www.develer.com/)
/*#*
*#* $Log$
+ *#* Revision 1.10 2006/07/19 12:56:26 bernie
+ *#* Convert to new Doxygen style.
+ *#*
+ *#* Revision 1.9 2006/04/27 05:39:24 bernie
+ *#* Enhance text rendering to arbitrary x,y coords.
+ *#*
+ *#* Revision 1.8 2006/03/22 09:50:11 bernie
+ *#* Don't use C99 stuff.
+ *#*
+ *#* 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.
+ *#*
+ *#* Revision 1.4 2006/02/10 12:31:33 bernie
+ *#* Add multiple font support in bitmaps.
+ *#*
+ *#* Revision 1.3 2005/11/27 23:31:58 bernie
+ *#* Reorder includes.
+ *#*
+ *#* Revision 1.2 2005/11/04 18:17:45 bernie
+ *#* Fix header guards and includes for new location of gfx module.
+ *#*
*#* Revision 1.1 2005/11/04 18:11:35 bernie
*#* Move graphics stuff from mware/ to gfx/.
*#*
*#*/
#include "text.h"
-#include "formatwr.h" /* _formatted_write() */
-#include "font.h"
-#include "gfx.h"
+
+#include <mware/formatwr.h> /* _formatted_write() */
+#include <gfx/font.h>
+#include <gfx/gfx.h>
+
#include <stdio.h> /* vsprintf() */
#include <stdarg.h>
#include <string.h> /* strlen() */
-/*!
+/**
* Render string \a str in Bitmap \a bm at current cursor position
*
* \note Text formatting functions are also available with an _P suffix
}
-/*!
+/**
* vprintf()-like formatter to render text in a Bitmap.
*
* Perform vprintf()-like formatting on the \a fmt format string using the
return PGM_FUNC(_formatted_write)(fmt, (void (*)(char, void *))text_putchar, bm, ap);
}
-/*!
+/**
* printf()-like formatter to render text in a Bitmap.
*
* Perform printf()-like formatting on the \a fmt format string.
return len;
}
-
-/*!
- * Render the result of printf()-like formatting in a specified position
- * of a Bitmap.
- *
- * \param bm Bitmap where to render the text
- * \param row Starting row in character units (zero based)
- * \param col Starting column in character units (zero based)
- * \param style Formatting style to use. In addition to any STYLEF_
- * flag, it can be TEXT_NORMAL, TEXT_FILL, TEXT_INVERT or
- * TEXT_RIGHT, or a combination of these flags ORed together.
- * \param fmt String possibly containing printf() formatting commands.
+/**
+ * Render text with vprintf()-like formatting at a specified pixel position.
*
- * \see text_puts() text_putchar() text_printf() text_vprintf()
- * \see text_moveto() text_style()
+ * \see text_xyprintf()
*/
-int PGM_FUNC(text_xprintf)(struct Bitmap *bm,
- uint8_t row, uint8_t col, uint16_t style, const char * PGM_ATTR fmt, ...)
+int PGM_FUNC(text_xyvprintf)(struct Bitmap *bm,
+ coord_t x, coord_t y, uint16_t style, const char * PGM_ATTR fmt, va_list ap)
{
int len;
uint8_t oldstyle = 0;
- va_list ap;
-
- va_start(ap, fmt);
- text_moveto(bm, row, col);
+ text_setCoord(bm, x, y);
if (style & STYLEF_MASK)
- oldstyle = text_style(style, STYLEF_MASK);
+ oldstyle = text_style(bm, style, STYLEF_MASK);
if (style & (TEXT_CENTER | TEXT_RIGHT))
{
pad /= 2;
if (style & TEXT_FILL)
- gfx_rectFillC(bm, 0, row * FONT_HEIGHT, pad, (row + 1) * FONT_HEIGHT,
+ gfx_rectFillC(bm, 0, y, pad, y + bm->font->height,
(style & STYLEF_INVERT) ? 0xFF : 0x00);
- text_setcoord(bm, pad, row * FONT_HEIGHT);
+ text_setCoord(bm, pad, y);
}
len = PGM_FUNC(text_vprintf)(bm, fmt, ap);
- va_end(ap);
if (style & TEXT_FILL)
- gfx_rectFillC(bm, bm->penX, row * FONT_HEIGHT, bm->width, (row + 1) * FONT_HEIGHT,
+ gfx_rectFillC(bm, bm->penX, y, bm->width, y + bm->font->height,
(style & STYLEF_INVERT) ? 0xFF : 0x00);
/* Restore old style */
if (style & STYLEF_MASK)
- text_style(oldstyle, STYLEF_MASK);
+ text_style(bm, oldstyle, STYLEF_MASK);
return len;
}
-/*!
+/**
+ * Render text with printf()-like formatting at a specified pixel position.
+ *
+ * \param bm Bitmap where to render the text
+ * \param x [pixels] Initial X coordinate of text.
+ * \param y [pixels] Coordinate of top border of text.
+ * \param style Formatting style to use. In addition to any STYLEF_
+ * flag, it can be TEXT_NORMAL, TEXT_FILL, TEXT_INVERT or
+ * TEXT_RIGHT, or a combination of these flags ORed together.
+ * \param fmt String possibly containing printf() formatting commands.
+ *
+ * \see text_puts() text_putchar() text_printf() text_vprintf()
+ * \see text_moveTo() text_style()
+ */
+int PGM_FUNC(text_xyprintf)(struct Bitmap *bm,
+ coord_t x, coord_t y, uint16_t style, const char * PGM_ATTR fmt, ...)
+{
+ int len;
+ va_list ap;
+
+ va_start(ap, fmt);
+ len = PGM_FUNC(text_xyvprintf)(bm, x, y, style, fmt, ap);
+ va_end(ap);
+
+ return len;
+}
+
+
+/**
+ * Render text with printf()-like formatting at a specified row/column position.
+ *
+ * \see text_xyprintf()
+ */
+int PGM_FUNC(text_xprintf)(struct Bitmap *bm,
+ uint8_t row, uint8_t col, uint16_t style, const char * PGM_ATTR fmt, ...)
+{
+ int len;
+ va_list ap;
+
+ va_start(ap, fmt);
+ len = PGM_FUNC(text_xyvprintf)(
+ bm, col * bm->font->width, row * bm->font->height,
+ style, fmt, ap);
+ va_end(ap);
+
+ 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 (UNLIKELY(!FONT_HAS_GLYPH(bm->font, index)))
+ {
+ if (!FONT_HAS_GLYPH(bm->font, '?'))
+ 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.
*/
int PGM_FUNC(text_vwidthf)(
const char * PGM_ATTR fmt,
va_list ap)
{
- return PGM_FUNC(vsprintf)(NULL, fmt, ap) * 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;
+ twd.bitmap = bm;
+ twd.width = 0;
+ _formatted_write(fmt, (void (*)(char, void *))text_charWidth, &twd, ap);
+ return twd.width;
+ }
}
-/*!
+/**
* Return the width in pixels of a printf()-formatted string.
*/
int PGM_FUNC(text_widthf)(struct Bitmap *bm, const char * PGM_ATTR fmt, ...)