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