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