text_format.c

Go to the documentation of this file.
00001 
00045 #include "text.h"
00046 
00047 #include <mware/formatwr.h> /* _formatted_write() */
00048 #include <gfx/font.h>
00049 #include <gfx/gfx.h>
00050 
00051 #include <stdio.h> /* vsprintf() */
00052 #include <stdarg.h>
00053 #include <string.h> /* strlen() */
00054 
00065 int PGM_FUNC(text_puts)(const char * PGM_ATTR str, struct Bitmap *bm)
00066 {
00067     char c;
00068 
00069     while ((c = PGM_READ_CHAR(str++)))
00070         text_putchar(c, bm);
00071 
00072     return 0;
00073 }
00074 
00075 
00086 int PGM_FUNC(text_vprintf)(struct Bitmap *bm, const char * PGM_ATTR fmt, va_list ap)
00087 {
00088     return PGM_FUNC(_formatted_write)(fmt, (void (*)(char, void *))text_putchar, bm, ap);
00089 }
00090 
00100 int PGM_FUNC(text_printf)(struct Bitmap *bm, const char * PGM_ATTR fmt, ...)
00101 {
00102     int len;
00103 
00104     va_list ap;
00105     va_start(ap, fmt);
00106     len = PGM_FUNC(text_vprintf)(bm, fmt, ap);
00107     va_end(ap);
00108 
00109     return len;
00110 }
00111 
00117 int PGM_FUNC(text_xyvprintf)(struct Bitmap *bm,
00118         coord_t x, coord_t y, uint16_t style, const char * PGM_ATTR fmt, va_list ap)
00119 {
00120     int len;
00121     uint8_t oldstyle = 0;
00122 
00123     text_setCoord(bm, x, y);
00124 
00125     if (style & STYLEF_MASK)
00126         oldstyle = text_style(bm, style, STYLEF_MASK);
00127 
00128     if (style & (TEXT_CENTER | TEXT_RIGHT))
00129     {
00130         uint8_t pad = bm->width - PGM_FUNC(text_vwidthf)(bm, fmt, ap);
00131 
00132         if (style & TEXT_CENTER)
00133             pad /= 2;
00134 
00135         if (style & TEXT_FILL)
00136             gfx_rectFillC(bm, 0, y, pad, y + bm->font->height,
00137                 (style & STYLEF_INVERT) ? 0xFF : 0x00);
00138 
00139         text_setCoord(bm, pad, y);
00140     }
00141 
00142     len = PGM_FUNC(text_vprintf)(bm, fmt, ap);
00143 
00144     if (style & TEXT_FILL)
00145         gfx_rectFillC(bm, bm->penX, y, bm->width, y + bm->font->height,
00146             (style & STYLEF_INVERT) ? 0xFF : 0x00);
00147 
00148     /* Restore old style */
00149     if (style & STYLEF_MASK)
00150         text_style(bm, oldstyle, STYLEF_MASK);
00151 
00152     return len;
00153 }
00154 
00155 
00170 int PGM_FUNC(text_xyprintf)(struct Bitmap *bm,
00171         coord_t x, coord_t y, uint16_t style, const char * PGM_ATTR fmt, ...)
00172 {
00173     int len;
00174     va_list ap;
00175 
00176     va_start(ap, fmt);
00177     len = PGM_FUNC(text_xyvprintf)(bm, x, y, style, fmt, ap);
00178     va_end(ap);
00179 
00180     return len;
00181 }
00182 
00183 
00189 int PGM_FUNC(text_xprintf)(struct Bitmap *bm,
00190         uint8_t row, uint8_t col, uint16_t style, const char * PGM_ATTR fmt, ...)
00191 {
00192     int len;
00193     va_list ap;
00194 
00195     va_start(ap, fmt);
00196     len = PGM_FUNC(text_xyvprintf)(
00197             bm, col * bm->font->width, row * bm->font->height,
00198             style, fmt, ap);
00199     va_end(ap);
00200 
00201     return len;
00202 }
00203 
00204 
00205 struct TextWidthData
00206 {
00207     Bitmap *bitmap;
00208     coord_t width;
00209 };
00210 
00223 static int text_charWidth(int c, struct TextWidthData *twd)
00224 {
00225     unsigned char index = (unsigned char)c;
00226     Bitmap *bm = twd->bitmap;
00227     coord_t glyph_width;
00228 
00229 
00230     if (UNLIKELY(!FONT_HAS_GLYPH(bm->font, index)))
00231     {
00232         if (!FONT_HAS_GLYPH(bm->font, '?'))
00233             index = '?';
00234         else
00235             index = bm->font->first;
00236     }
00237 
00238     /* Make character relative to font start */
00239     index -= bm->font->first;
00240 
00241     if (bm->font->offset)
00242         /* Proportional font */
00243         glyph_width = bm->font->widths[index]; /* TODO: optimize away */
00244     else
00245         /* Fixed width font */
00246         glyph_width = bm->font->width;
00247 
00248     if (bm->styles & STYLEF_CONDENSED)
00249         --glyph_width;
00250 
00251     if (bm->styles & STYLEF_EXPANDED)
00252         glyph_width *= 2;
00253 
00254     twd->width += glyph_width;
00255 
00256     return c;
00257 }
00258 
00262 int PGM_FUNC(text_vwidthf)(
00263     UNUSED_ARG(struct Bitmap *, bm),
00264     const char * PGM_ATTR fmt,
00265     va_list ap)
00266 {
00267     /* Fixed font with no styles affecting the width? */
00268     if (!bm->font->offset && !(bm->styles & (STYLEF_CONDENSED | STYLEF_EXPANDED)))
00269         return PGM_FUNC(vsprintf)(NULL, fmt, ap) * bm->font->width;
00270     else
00271     {
00272         struct TextWidthData twd;
00273         twd.bitmap = bm;
00274         twd.width = 0;
00275         _formatted_write(fmt, (void (*)(char, void *))text_charWidth, &twd, ap);
00276         return twd.width;
00277     }
00278 }
00279 
00280 
00284 int PGM_FUNC(text_widthf)(struct Bitmap *bm, const char * PGM_ATTR fmt, ...)
00285 {
00286     int width;
00287 
00288     va_list ap;
00289     va_start(ap, fmt);
00290     width = PGM_FUNC(text_vwidthf)(bm, fmt, ap);
00291     va_end(ap);
00292 
00293     return width;
00294 }