text_format.c

Go to the documentation of this file.
00001 
00041 /*#*
00042  *#* $Log$
00043  *#* Revision 1.10  2006/07/19 12:56:26  bernie
00044  *#* Convert to new Doxygen style.
00045  *#*
00046  *#* Revision 1.9  2006/04/27 05:39:24  bernie
00047  *#* Enhance text rendering to arbitrary x,y coords.
00048  *#*
00049  *#* Revision 1.8  2006/03/22 09:50:11  bernie
00050  *#* Don't use C99 stuff.
00051  *#*
00052  *#* Revision 1.7  2006/03/20 17:51:55  bernie
00053  *#* Cleanups.
00054  *#*
00055  *#* Revision 1.6  2006/03/13 02:05:54  bernie
00056  *#* Mark slow paths as UNLIKELY.
00057  *#*
00058  *#* Revision 1.5  2006/03/07 22:18:04  bernie
00059  *#* Correctly compute text width for prop fonts; Make styles a per-bitmap attribute.
00060  *#*
00061  *#* Revision 1.4  2006/02/10 12:31:33  bernie
00062  *#* Add multiple font support in bitmaps.
00063  *#*
00064  *#* Revision 1.3  2005/11/27 23:31:58  bernie
00065  *#* Reorder includes.
00066  *#*
00067  *#* Revision 1.2  2005/11/04 18:17:45  bernie
00068  *#* Fix header guards and includes for new location of gfx module.
00069  *#*
00070  *#* Revision 1.1  2005/11/04 18:11:35  bernie
00071  *#* Move graphics stuff from mware/ to gfx/.
00072  *#*
00073  *#* Revision 1.10  2005/11/04 16:20:02  bernie
00074  *#* Fix reference to README.devlib in header.
00075  *#*
00076  *#* Revision 1.9  2004/12/31 17:47:45  bernie
00077  *#* Rename UNUSED() to UNUSED_ARG().
00078  *#*
00079  *#* Revision 1.8  2004/11/16 21:16:56  bernie
00080  *#* Update to new naming scheme in mware/gfx.c.
00081  *#*
00082  *#* Revision 1.7  2004/10/03 19:05:04  bernie
00083  *#* text_widthf(), text_vwidthf(): New functions.
00084  *#*
00085  *#* Revision 1.6  2004/09/14 20:59:04  bernie
00086  *#* text_xprintf(): Support all styles; Pixel-wise text centering.
00087  *#*
00088  *#* Revision 1.5  2004/08/25 14:12:09  rasky
00089  *#* Aggiornato il comment block dei log RCS
00090  *#*
00091  *#* Revision 1.4  2004/08/05 18:46:44  bernie
00092  *#* Documentation improvements.
00093  *#*
00094  *#* Revision 1.3  2004/08/03 15:57:18  aleph
00095  *#* Add include to fix warning for vsprintf()
00096  *#*
00097  *#* Revision 1.2  2004/06/03 11:27:09  bernie
00098  *#* Add dual-license information.
00099  *#*
00100  *#* Revision 1.1  2004/05/23 15:43:16  bernie
00101  *#* Import mware modules.
00102  *#*
00103  *#* Revision 1.2  2004/03/26 18:50:50  bernie
00104  *#* Move _PROGMEM stuff to compiler.h
00105  *#*
00106  *#* Revision 1.1  2004/03/19 16:52:28  bernie
00107  *#* Move printf() like functions from text.c to text_format.c and add PROGMEM versions.
00108  *#*
00109  *#*/
00110 
00111 #include "text.h"
00112 
00113 #include <mware/formatwr.h> /* _formatted_write() */
00114 #include <gfx/font.h>
00115 #include <gfx/gfx.h>
00116 
00117 #include <stdio.h> /* vsprintf() */
00118 #include <stdarg.h>
00119 #include <string.h> /* strlen() */
00120 
00131 int PGM_FUNC(text_puts)(const char * PGM_ATTR str, struct Bitmap *bm)
00132 {
00133     char c;
00134 
00135     while ((c = PGM_READ_CHAR(str++)))
00136         text_putchar(c, bm);
00137 
00138     return 0;
00139 }
00140 
00141 
00152 int PGM_FUNC(text_vprintf)(struct Bitmap *bm, const char * PGM_ATTR fmt, va_list ap)
00153 {
00154     return PGM_FUNC(_formatted_write)(fmt, (void (*)(char, void *))text_putchar, bm, ap);
00155 }
00156 
00166 int PGM_FUNC(text_printf)(struct Bitmap *bm, const char * PGM_ATTR fmt, ...)
00167 {
00168     int len;
00169 
00170     va_list ap;
00171     va_start(ap, fmt);
00172     len = PGM_FUNC(text_vprintf)(bm, fmt, ap);
00173     va_end(ap);
00174 
00175     return len;
00176 }
00177 
00183 int PGM_FUNC(text_xyvprintf)(struct Bitmap *bm,
00184         coord_t x, coord_t y, uint16_t style, const char * PGM_ATTR fmt, va_list ap)
00185 {
00186     int len;
00187     uint8_t oldstyle = 0;
00188 
00189     text_setCoord(bm, x, y);
00190 
00191     if (style & STYLEF_MASK)
00192         oldstyle = text_style(bm, style, STYLEF_MASK);
00193 
00194     if (style & (TEXT_CENTER | TEXT_RIGHT))
00195     {
00196         uint8_t pad = bm->width - PGM_FUNC(text_vwidthf)(bm, fmt, ap);
00197 
00198         if (style & TEXT_CENTER)
00199             pad /= 2;
00200 
00201         if (style & TEXT_FILL)
00202             gfx_rectFillC(bm, 0, y, pad, y + bm->font->height,
00203                 (style & STYLEF_INVERT) ? 0xFF : 0x00);
00204 
00205         text_setCoord(bm, pad, y);
00206     }
00207 
00208     len = PGM_FUNC(text_vprintf)(bm, fmt, ap);
00209 
00210     if (style & TEXT_FILL)
00211         gfx_rectFillC(bm, bm->penX, y, bm->width, y + bm->font->height,
00212             (style & STYLEF_INVERT) ? 0xFF : 0x00);
00213 
00214     /* Restore old style */
00215     if (style & STYLEF_MASK)
00216         text_style(bm, oldstyle, STYLEF_MASK);
00217 
00218     return len;
00219 }
00220 
00221 
00236 int PGM_FUNC(text_xyprintf)(struct Bitmap *bm,
00237         coord_t x, coord_t y, uint16_t style, const char * PGM_ATTR fmt, ...)
00238 {
00239     int len;
00240     va_list ap;
00241 
00242     va_start(ap, fmt);
00243     len = PGM_FUNC(text_xyvprintf)(bm, x, y, style, fmt, ap);
00244     va_end(ap);
00245 
00246     return len;
00247 }
00248 
00249 
00255 int PGM_FUNC(text_xprintf)(struct Bitmap *bm,
00256         uint8_t row, uint8_t col, uint16_t style, const char * PGM_ATTR fmt, ...)
00257 {
00258     int len;
00259     va_list ap;
00260 
00261     va_start(ap, fmt);
00262     len = PGM_FUNC(text_xyvprintf)(
00263             bm, col * bm->font->width, row * bm->font->height,
00264             style, fmt, ap);
00265     va_end(ap);
00266 
00267     return len;
00268 }
00269 
00270 
00271 struct TextWidthData
00272 {
00273     Bitmap *bitmap;
00274     coord_t width;
00275 };
00276 
00289 static int text_charWidth(int c, struct TextWidthData *twd)
00290 {
00291     unsigned char index = (unsigned char)c;
00292     Bitmap *bm = twd->bitmap;
00293     coord_t glyph_width;
00294 
00295 
00296     if (UNLIKELY(!FONT_HAS_GLYPH(bm->font, index)))
00297     {
00298         if (!FONT_HAS_GLYPH(bm->font, '?'))
00299             index = '?';
00300         else
00301             index = bm->font->first;
00302     }
00303 
00304     /* Make character relative to font start */
00305     index -= bm->font->first;
00306 
00307     if (bm->font->offset)
00308         /* Proportional font */
00309         glyph_width = bm->font->widths[index]; /* TODO: optimize away */
00310     else
00311         /* Fixed width font */
00312         glyph_width = bm->font->width;
00313 
00314     if (bm->styles & STYLEF_CONDENSED)
00315         --glyph_width;
00316 
00317     if (bm->styles & STYLEF_EXPANDED)
00318         glyph_width *= 2;
00319 
00320     twd->width += glyph_width;
00321 
00322     return c;
00323 }
00324 
00328 int PGM_FUNC(text_vwidthf)(
00329     UNUSED_ARG(struct Bitmap *, bm),
00330     const char * PGM_ATTR fmt,
00331     va_list ap)
00332 {
00333     /* Fixed font with no styles affecting the width? */
00334     if (!bm->font->offset && !(bm->styles & (STYLEF_CONDENSED | STYLEF_EXPANDED)))
00335         return PGM_FUNC(vsprintf)(NULL, fmt, ap) * bm->font->width;
00336     else
00337     {
00338         struct TextWidthData twd;
00339         twd.bitmap = bm;
00340         twd.width = 0;
00341         _formatted_write(fmt, (void (*)(char, void *))text_charWidth, &twd, ap);
00342         return twd.width;
00343     }
00344 }
00345 
00346 
00350 int PGM_FUNC(text_widthf)(struct Bitmap *bm, const char * PGM_ATTR fmt, ...)
00351 {
00352     int width;
00353 
00354     va_list ap;
00355     va_start(ap, fmt);
00356     width = PGM_FUNC(text_vwidthf)(bm, fmt, ap);
00357     va_end(ap);
00358 
00359     return width;
00360 }