BeRTOS
|
00001 00044 #include "text.h" 00045 00046 #include <mware/formatwr.h> /* _formatted_write() */ 00047 #include <gfx/font.h> 00048 #include <gfx/gfx.h> 00049 00050 #include <stdio.h> /* vsprintf() */ 00051 #include <stdarg.h> 00052 #include <string.h> /* strlen() */ 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 /* Restore old style */ 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 /* Make character relative to font start */ 00238 index -= bm->font->first; 00239 00240 if (bm->font->offset) 00241 /* Proportional font */ 00242 glyph_width = bm->font->widths[index]; /* TODO: optimize away */ 00243 else 00244 /* Fixed width font */ 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 /* Fixed font with no styles affecting the width? */ 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 }