00001
00045 #include "text.h"
00046
00047 #include <mware/formatwr.h>
00048 #include <gfx/font.h>
00049 #include <gfx/gfx.h>
00050
00051 #include <stdio.h>
00052 #include <stdarg.h>
00053 #include <string.h>
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
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
00239 index -= bm->font->first;
00240
00241 if (bm->font->offset)
00242
00243 glyph_width = bm->font->widths[index];
00244 else
00245
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
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 }