From 7c303eb72efe8a61383c4914fb940024236b2bdb Mon Sep 17 00:00:00 2001 From: inmarket Date: Mon, 29 Jul 2013 16:29:25 +1000 Subject: [PATCH] Vastly simplify GDISP mcufont interface code. Fix boundary cases. Prevent overwriting of defined display area. Improve performance. Remove hardware acceleration for fonts (unlikely anyway unles the hardware understood our software font structures) --- include/gdisp/gdisp.h | 64 +++--- include/gdisp/lld/emulation.c | 137 ------------- include/gdisp/lld/gdisp_lld.h | 36 ---- include/gdisp/lld/gdisp_lld_msgs.h | 21 -- include/gdisp/options.h | 4 + src/gdisp/gdisp.c | 309 ++++++++++++----------------- 6 files changed, 156 insertions(+), 415 deletions(-) diff --git a/include/gdisp/gdisp.h b/include/gdisp/gdisp.h index 25194c4f..aa418cdb 100644 --- a/include/gdisp/gdisp.h +++ b/include/gdisp/gdisp.h @@ -36,12 +36,6 @@ typedef int16_t coord_t; #if GFX_USE_GDISP || defined(__DOXYGEN__) -/*===========================================================================*/ -/* Include the low level driver configuration information */ -/*===========================================================================*/ - -#include "gdisp_lld_config.h" - /*===========================================================================*/ /* Type definitions */ /*===========================================================================*/ @@ -480,35 +474,6 @@ extern "C" { void gdispFillArc(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color); #endif - /* Basic Text Rendering Functions */ - - #if GDISP_NEED_TEXT || defined(__DOXYGEN__) - /** - * @brief Draw a text character. - * - * @param[in] x,y The position for the text - * @param[in] c The character to draw - * @param[in] font The font to use - * @param[in] color The color to use - * - * @api - */ - void gdispDrawChar(coord_t x, coord_t y, uint16_t c, font_t font, color_t color); - - /** - * @brief Draw a text character with a filled background. - * - * @param[in] x,y The position for the text - * @param[in] c The character to draw - * @param[in] font The font to use - * @param[in] color The color to use - * @param[in] bgcolor The background color to use - * - * @api - */ - void gdispFillChar(coord_t x, coord_t y, uint16_t c, font_t font, color_t color, color_t bgcolor); - #endif - /* Read a pixel Function */ #if GDISP_NEED_PIXELREAD || defined(__DOXYGEN__) @@ -591,8 +556,6 @@ extern "C" { #define gdispFillArc(x, y, radius, sangle, eangle, color) gdisp_lld_fill_arc(x, y, radius, sangle, eangle, color) #define gdispDrawEllipse(x, y, a, b, color) gdisp_lld_draw_ellipse(x, y, a, b, color) #define gdispFillEllipse(x, y, a, b, color) gdisp_lld_fill_ellipse(x, y, a, b, color) - #define gdispDrawChar(x, y, c, font, color) gdisp_lld_draw_char(x, y, c, font, color) - #define gdispFillChar(x, y, c, font, color, bgcolor) gdisp_lld_fill_char(x, y, c, font, color, bgcolor) #define gdispGetPixelColor(x, y) gdisp_lld_get_pixel_color(x, y) #define gdispVerticalScroll(x, y, cx, cy, lines, bgcolor) gdisp_lld_vertical_scroll(x, y, cx, cy, lines, bgcolor) #define gdispControl(what, value) gdisp_lld_control(what, value) @@ -652,9 +615,34 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color); void gdispFillConvexPoly(coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color); #endif -/* Extra Text Functions */ +/* Text Functions */ #if GDISP_NEED_TEXT || defined(__DOXYGEN__) + /** + * @brief Draw a text character. + * + * @param[in] x,y The position for the text + * @param[in] c The character to draw + * @param[in] font The font to use + * @param[in] color The color to use + * + * @api + */ + void gdispDrawChar(coord_t x, coord_t y, uint16_t c, font_t font, color_t color); + + /** + * @brief Draw a text character with a filled background. + * + * @param[in] x,y The position for the text + * @param[in] c The character to draw + * @param[in] font The font to use + * @param[in] color The color to use + * @param[in] bgcolor The background color to use + * + * @api + */ + void gdispFillChar(coord_t x, coord_t y, uint16_t c, font_t font, color_t color, color_t bgcolor); + /** * @brief Draw a text string. * diff --git a/include/gdisp/lld/emulation.c b/include/gdisp/lld/emulation.c index 716a3988..cb0c9c4b 100644 --- a/include/gdisp/lld/emulation.c +++ b/include/gdisp/lld/emulation.c @@ -461,135 +461,6 @@ GDISPDriver GDISP; } #endif -#if GDISP_NEED_TEXT && !GDISP_HARDWARE_TEXT - #include "mcufont.h" -#endif - -#if GDISP_NEED_TEXT && !GDISP_HARDWARE_TEXT - static void gdisp_lld_draw_char_callback(int16_t x, int16_t y, uint8_t count, uint8_t alpha, void *state) { - color_t color = *(color_t*)state; - if (alpha == 255) - { - if (count == 1) - gdisp_lld_draw_pixel(x, y, color); - else - gdisp_lld_fill_area(x, y, count, 1, color); - } -#if GDISP_NEED_ANTIALIAS - else - { - while (count--) - { - color_t oldColor; - - oldColor = gdisp_lld_get_pixel_color(x, y); - oldColor = gdispBlendColor(color, oldColor, alpha); - gdisp_lld_draw_pixel(x, y, oldColor); - - x++; - } - } -#endif - } - - void gdisp_lld_draw_char(coord_t x, coord_t y, uint16_t c, font_t font, color_t color) { - mf_render_character(font, x, y, c, gdisp_lld_draw_char_callback, &color); - } -#endif - -#if GDISP_NEED_TEXT && !GDISP_HARDWARE_TEXTFILLS - typedef struct { - int16_t x0; - int16_t y0; - int16_t x1; - int16_t y1; - int16_t x; - int16_t y; - color_t fg; - color_t bg; - } gdisp_lld_fill_char_state_t; - - static void gdisp_lld_fill_char_callback(int16_t x, int16_t y, uint8_t count, uint8_t alpha, void *state) { - gdisp_lld_fill_char_state_t *s = state; - - if (y > s->y && s->x != s->x0) - { - /* Fill background to the end of current line */ - gdisp_lld_fill_area(s->x, s->y, s->x1 - s->x, 1, s->bg); - s->y++; - s->x = s->x0; - } - - if (y > s->y) - { - /* Fill background for given number of full lines */ - gdisp_lld_fill_area(s->x0, s->y, s->x1 - s->x0, y - s->y, s->bg); - s->y = y; - } - - if (x > s->x) - { - /* Fill background from previous X position */ - gdisp_lld_fill_area(s->x, s->y, x - s->x, 1, s->bg); - s->x = x; - } - - if (!count) - return; - - if (y == s->y) - { - s->x += count; - - if (s->x == s->x1) - { - s->x = s->x0; - s->y++; - } - } - - /* Draw the foreground */ - if (alpha == 255 || alpha == 0) - { - if (count == 1) - gdisp_lld_draw_pixel(x, y, alpha ? s->fg : s->bg); - else - gdisp_lld_fill_area(x, y, count, 1, alpha ? s->fg : s->bg); - } -#if GDISP_NEED_ANTIALIAS - else - { - while (count--) - { - color_t color; - color = gdispBlendColor(s->fg, s->bg, alpha); - gdisp_lld_draw_pixel(x, y, color); - - x++; - } - } -#endif - } - - void gdisp_lld_fill_char(coord_t x, coord_t y, uint16_t c, font_t font, color_t color, color_t bgcolor) { - gdisp_lld_fill_char_state_t state; - - state.x0 = x; - state.y0 = y; - state.x1 = x + mf_character_width(font, c) + font->baseline_x; - state.y1 = y + font->height; - state.x = x; - state.y = y; - state.fg = color; - state.bg = bgcolor; - - mf_render_character(font, x, y, c, gdisp_lld_fill_char_callback, &state); - - gdisp_lld_fill_char_callback(state.x0, state.y1, 0, 0, &state); - } -#endif - - #if GDISP_NEED_CONTROL && !GDISP_HARDWARE_CONTROL void gdisp_lld_control(unsigned what, void *value) { (void)what; @@ -657,14 +528,6 @@ void *gdisp_lld_query(unsigned what) { gdisp_lld_fill_circle(msg->fillarc.x, msg->fillarc.y, msg->fillarc.radius, msg->fillarc.startangle, msg->fillarc.endangle, msg->fillarc.color); break; #endif - #if GDISP_NEED_TEXT - case GDISP_LLD_MSG_DRAWCHAR: - gdisp_lld_draw_char(msg->drawchar.x, msg->drawchar.y, msg->drawchar.c, msg->drawchar.font, msg->drawchar.color); - break; - case GDISP_LLD_MSG_FILLCHAR: - gdisp_lld_fill_char(msg->fillchar.x, msg->fillchar.y, msg->fillchar.c, msg->fillchar.font, msg->fillchar.color, msg->fillchar.bgcolor); - break; - #endif #if GDISP_NEED_PIXELREAD case GDISP_LLD_MSG_GETPIXELCOLOR: msg->getpixelcolor.result = gdisp_lld_get_pixel_color(msg->getpixelcolor.x, msg->getpixelcolor.y); diff --git a/include/gdisp/lld/gdisp_lld.h b/include/gdisp/lld/gdisp_lld.h index 9c4b3947..98c7569c 100644 --- a/include/gdisp/lld/gdisp_lld.h +++ b/include/gdisp/lld/gdisp_lld.h @@ -106,22 +106,6 @@ #define GDISP_HARDWARE_ARCFILLS FALSE #endif - /** - * @brief Hardware accelerated text drawing. - * @details If set to @p FALSE software emulation is used. - */ - #ifndef GDISP_HARDWARE_TEXT - #define GDISP_HARDWARE_TEXT FALSE - #endif - - /** - * @brief Hardware accelerated text drawing with a filled background. - * @details If set to @p FALSE software emulation is used. - */ - #ifndef GDISP_HARDWARE_TEXTFILLS - #define GDISP_HARDWARE_TEXTFILLS FALSE - #endif - /** * @brief Hardware accelerated scrolling. * @details If set to @p FALSE there is no support for scrolling. @@ -167,26 +151,6 @@ * @name GDISP software algorithm choices * @{ */ - /** - * @brief For filled text drawing, use a background fill and then draw - * the text instead of using a blit or direct pixel drawing. - * @details If set to @p TRUE background fill and then text draw is used. - * @note This is ignored if hardware accelerated text is supported. - */ - #ifndef GDISP_SOFTWARE_TEXTFILLDRAW - #define GDISP_SOFTWARE_TEXTFILLDRAW FALSE - #endif - - /** - * @brief For filled text drawing, when using a bitmap blit - * use a column by column buffer rather than a full character - * buffer to save memory at a small performance cost. - * @details If set to @p TRUE background fill one character column at a time. - * @note This is ignored if software text using blit is not being used. - */ - #ifndef GDISP_SOFTWARE_TEXTBLITCOLUMN - #define GDISP_SOFTWARE_TEXTBLITCOLUMN FALSE - #endif /** @} */ /** diff --git a/include/gdisp/lld/gdisp_lld_msgs.h b/include/gdisp/lld/gdisp_lld_msgs.h index 5f4bed9a..2c199cbe 100644 --- a/include/gdisp/lld/gdisp_lld_msgs.h +++ b/include/gdisp/lld/gdisp_lld_msgs.h @@ -42,10 +42,6 @@ typedef enum gdisp_msgaction { GDISP_LLD_MSG_DRAWARC, GDISP_LLD_MSG_FILLARC, #endif - #if GDISP_NEED_TEXT - GDISP_LLD_MSG_DRAWCHAR, - GDISP_LLD_MSG_FILLCHAR, - #endif #if GDISP_NEED_PIXELREAD GDISP_LLD_MSG_GETPIXELCOLOR, #endif @@ -151,23 +147,6 @@ typedef union gdisp_lld_msg { coord_t startangle, endangle; color_t color; } fillarc; - struct gdisp_lld_msg_drawchar { - gfxQueueItem qi; - gdisp_msgaction_t action; // GDISP_LLD_MSG_DRAWCHAR - coord_t x, y; - uint16_t c; - font_t font; - color_t color; - } drawchar; - struct gdisp_lld_msg_fillchar { - gfxQueueItem qi; - gdisp_msgaction_t action; // GDISP_LLD_MSG_FILLCHAR - coord_t x, y; - uint16_t c; - font_t font; - color_t color; - color_t bgcolor; - } fillchar; struct gdisp_lld_msg_getpixelcolor { gfxQueueItem qi; gdisp_msgaction_t action; // GDISP_LLD_MSG_GETPIXELCOLOR diff --git a/include/gdisp/options.h b/include/gdisp/options.h index 918c7aea..d5818284 100644 --- a/include/gdisp/options.h +++ b/include/gdisp/options.h @@ -296,6 +296,10 @@ /* #define GDISP_USE_GPIO */ /** @} */ +#if GFX_USE_GDISP + #include "gdisp_lld_config.h" +#endif + #endif /* _GDISP_OPTIONS_H */ /** @} */ diff --git a/src/gdisp/gdisp.c b/src/gdisp/gdisp.c index f7a94a60..5ad06f96 100644 --- a/src/gdisp/gdisp.c +++ b/src/gdisp/gdisp.c @@ -16,10 +16,6 @@ #if GFX_USE_GDISP -#ifdef GDISP_NEED_TEXT - #include "mcufont.h" -#endif - /* Include the low level driver information */ #include "gdisp/lld/gdisp_lld.h" @@ -399,43 +395,6 @@ void gdispFillRoundedBox(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t r } #endif -#if (GDISP_NEED_TEXT && GDISP_NEED_MULTITHREAD) - void gdispDrawChar(coord_t x, coord_t y, uint16_t c, font_t font, color_t color) { - gfxMutexEnter(&gdispMutex); - gdisp_lld_draw_char(x, y, c, font, color); - gfxMutexExit(&gdispMutex); - } -#elif GDISP_NEED_TEXT && GDISP_NEED_ASYNC - void gdispDrawChar(coord_t x, coord_t y, uint16_t c, font_t font, color_t color) { - gdisp_lld_msg_t *p = gdispAllocMsg(GDISP_LLD_MSG_DRAWCHAR); - p->drawchar.x = x; - p->drawchar.y = y; - p->drawchar.c = c; - p->drawchar.font = font; - p->drawchar.color = color; - gfxQueuePut(&gdispQueue, &p->qi, TIME_IMMEDIATE); - } -#endif - -#if (GDISP_NEED_TEXT && GDISP_NEED_MULTITHREAD) - void gdispFillChar(coord_t x, coord_t y, uint16_t c, font_t font, color_t color, color_t bgcolor) { - gfxMutexEnter(&gdispMutex); - gdisp_lld_fill_char(x, y, c, font, color, bgcolor); - gfxMutexExit(&gdispMutex); - } -#elif GDISP_NEED_TEXT && GDISP_NEED_ASYNC - void gdispFillChar(coord_t x, coord_t y, uint16_t c, font_t font, color_t color, color_t bgcolor) { - gdisp_lld_msg_t *p = gdispAllocMsg(GDISP_LLD_MSG_FILLCHAR); - p->fillchar.x = x; - p->fillchar.y = y; - p->fillchar.c = c; - p->fillchar.font = font; - p->fillchar.color = color; - p->fillchar.bgcolor = bgcolor; - gfxQueuePut(&gdispQueue, &p->qi, TIME_IMMEDIATE); - } -#endif - #if (GDISP_NEED_PIXELREAD && (GDISP_NEED_MULTITHREAD || GDISP_NEED_ASYNC)) color_t gdispGetPixelColor(coord_t x, coord_t y) { color_t c; @@ -620,21 +579,84 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { #endif #if GDISP_NEED_TEXT + #include "mcufont.h" + + #if GDISP_NEED_ANTIALIAS && GDISP_NEED_PIXELREAD + static void text_draw_char_callback(int16_t x, int16_t y, uint8_t count, uint8_t alpha, void *state) { + if (alpha == 255) { + if (count == 1) + gdispDrawPixel(x, y, ((color_t *)state)[0]); + else + gdispFillArea(x, y, count, 1, ((color_t *)state)[0]); + } else { + while (count--) { + gdispDrawPixel(x, y, gdispBlendColor(((color_t *)state)[0], gdispGetPixelColor(x, y), alpha)); + x++; + } + } + } + #else + static void text_draw_char_callback(int16_t x, int16_t y, uint8_t count, uint8_t alpha, void *state) { + if (alpha > 0x80) { // A best approximation when using anti-aliased fonts but we can't actually draw them anti-aliased + if (count == 1) + gdispDrawPixel(x, y, ((color_t *)state)[0]); + else + gdispFillArea(x, y, count, 1, ((color_t *)state)[0]); + } + } + #endif + + void gdispDrawChar(coord_t x, coord_t y, uint16_t c, font_t font, color_t color) { + /* No mutex required as we only call high level functions which have their own mutex */ + mf_render_character(font, x, y, c, text_draw_char_callback, &color); + } + + #if GDISP_NEED_ANTIALIAS + static void text_fill_char_callback(int16_t x, int16_t y, uint8_t count, uint8_t alpha, void *state) { + if (alpha == 255) { + if (count == 1) + gdispDrawPixel(x, y, ((color_t *)state)[0]); + else + gdispFillArea(x, y, count, 1, ((color_t *)state)[0]); + } else { + while (count--) { + gdispDrawPixel(x, y, gdispBlendColor(((color_t *)state)[0], ((color_t *)state)[1], alpha)); + x++; + } + } + } + #else + #define text_fill_char_callback text_draw_char_callback + #endif + + void gdispFillChar(coord_t x, coord_t y, uint16_t c, font_t font, color_t color, color_t bgcolor) { + /* No mutex required as we only call high level functions which have their own mutex */ + color_t state[2]; + + state[0] = color; + state[1] = bgcolor; + + gdispFillArea(x, y, mf_character_width(font, c) + font->baseline_x, font->height, bgcolor); + mf_render_character(font, x, y, c, text_fill_char_callback, state); + } + typedef struct { font_t font; color_t color; + coord_t x, y; + coord_t cx, cy; } gdispDrawString_state_t; /* Callback to render characters. */ - static uint8_t gdispDrawString_callback(int16_t x, int16_t y, - mf_char character, void *state) + static uint8_t gdispDrawString_callback(int16_t x, int16_t y, mf_char character, void *state) { gdispDrawString_state_t *s = state; uint8_t w; - gdispDrawChar(x, y, character, s->font, s->color); w = mf_character_width(s->font, character); + if (x >= s->x && x+w < s->x + s->cx && y >= s->y && y+s->font->height <= s->y + s->cy) + mf_render_character(s->font, x, y, character, text_draw_char_callback, &s->color); return w; } @@ -644,80 +666,31 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { state.font = font; state.color = color; + state.x = x; + state.y = y; + state.cx = GDISP.Width - x; + state.cy = GDISP.Height - y; - mf_render_aligned(font, x, y, MF_ALIGN_LEFT, str, 0, - gdispDrawString_callback, &state); + mf_render_aligned(font, x, y, MF_ALIGN_LEFT, str, 0, gdispDrawString_callback, &state); } -#endif - -#if GDISP_NEED_TEXT + typedef struct { - coord_t y0; - coord_t prev_x; font_t font; - color_t color; - color_t bgcolor; - bool_t rightalign; + color_t color[2]; + coord_t x, y; + coord_t cx, cy; } gdispFillString_state_t; /* Callback to render characters. */ - static uint8_t gdispFillString_callback(int16_t x, int16_t y, - mf_char character, void *state) + static uint8_t gdispFillString_callback(int16_t x, int16_t y, mf_char character, void *state) { gdispFillString_state_t *s = state; uint8_t w; - int16_t right_edge; - w = mf_character_width(s->font, character); - right_edge = x + w + s->font->baseline_x; - - if (!s->rightalign) - { - if (s->prev_x < x) - { - /* Fill any space between characters */ - gdispFillArea(s->prev_x, s->y0, x - s->prev_x, s->font->height, - s->bgcolor); - } - else if (s->prev_x > x) - { - /* Uh, looks like there is some kerning going on. If we would - * just call gdispFillChar() here, it would overwrite part of - * the previous character. Instead, fill background separately. - */ - gdispFillArea(s->prev_x, s->y0, right_edge - s->prev_x, - s->font->height, s->bgcolor); - gdispDrawChar(x, y, character, s->font, s->color); - s->prev_x = right_edge; - return w; - } - - s->prev_x = right_edge; - } - else - { - /* When rendering right-aligned text, the characters are drawn - * from right to left. */ - if (s->prev_x > right_edge) - { - /* Fill any space between characters */ - gdispFillArea(right_edge, s->y0, s->prev_x - right_edge, - s->font->height, s->bgcolor); - } - else if (s->prev_x < right_edge) - { - gdispFillArea(x, s->y0, s->prev_x - x, - s->font->height, s->bgcolor); - gdispDrawChar(x, y, character, s->font, s->color); - s->prev_x = x; - return w; - } - - s->prev_x = x; - } - gdispFillChar(x, y, character, s->font, s->color, s->bgcolor); - + w = mf_character_width(s->font, character); + if (x >= s->x && x+w < s->x + s->cx && y >= s->y && y+s->font->height <= s->y + s->cy) + mf_render_character(s->font, x, y, character, text_fill_char_callback, s->color); return w; } @@ -725,104 +698,78 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { /* No mutex required as we only call high level functions which have their own mutex */ gdispFillString_state_t state; - state.y0 = y; - state.prev_x = x; state.font = font; - state.color = color; - state.bgcolor = bgcolor; - state.rightalign = false; + state.color[0] = color; + state.color[1] = bgcolor; + state.x = x; + state.y = y; + state.cx = mf_get_string_width(font, str, 0, 0); + state.cy = font->height; - x += font->baseline_x; - mf_render_aligned(font, x, y, MF_ALIGN_LEFT, str, 0, - gdispFillString_callback, &state); + gdispFillArea(x, y, state.cx, state.cy, bgcolor); + mf_render_aligned(font, x+font->baseline_x, y, MF_ALIGN_LEFT, str, 0, gdispFillString_callback, &state); } -#endif - -#if GDISP_NEED_TEXT + void gdispDrawStringBox(coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, justify_t justify) { /* No mutex required as we only call high level functions which have their own mutex */ gdispDrawString_state_t state; state.font = font; state.color = color; + state.x = x; + state.y = y; + state.cx = cx; + state.cy = cy; /* Select the anchor position */ - if (justify == justifyLeft) - x += font->baseline_x; - else if (justify == justifyCenter) + switch(justify) { + case justifyCenter: x += (cx + 1) / 2; - else if (justify == justifyRight) + break; + case justifyRight: x += cx; + break; + default: // justifyLeft + x += font->baseline_x; + break; + } + y += (cy+1 - font->height)/2; - mf_render_aligned(font, x, y, justify, str, 0, - gdispDrawString_callback, &state); + mf_render_aligned(font, x, y, justify, str, 0, gdispDrawString_callback, &state); } -#endif - -#if GDISP_NEED_TEXT + void gdispFillStringBox(coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, color_t bgcolor, justify_t justify) { /* No mutex required as we only call high level functions which have their own mutex */ gdispFillString_state_t state; - int16_t min_x, max_x; - - min_x = x; - max_x = x + cx; - - state.y0 = y + (cy - font->height + 1) / 2; - state.prev_x = x; + state.font = font; - state.color = color; - state.bgcolor = bgcolor; - state.rightalign = false; - - /* Fill above the text */ - if (state.y0 > y) - { - gdispFillArea(x, y, cx, state.y0 - y, bgcolor); - } - - /* Fill below the text */ - if (state.y0 + font->height < y + cy) - { - gdispFillArea(x, state.y0 + font->height, cx, - (y + cy) - (state.y0 + font->height), bgcolor); - } + state.color[0] = color; + state.color[1] = bgcolor; + state.x = x; + state.y = y; + state.cx = cx; + state.cy = cy; + + gdispFillArea(x, y, cx, cy, bgcolor); /* Select the anchor position */ - if (justify == justifyLeft) - { - x += font->baseline_x; - } - else if (justify == justifyCenter) - { + switch(justify) { + case justifyCenter: x += (cx + 1) / 2; - } - else if (justify == justifyRight) - { - state.rightalign = true; - state.prev_x = x + cx; + break; + case justifyRight: x += cx; + break; + default: // justifyLeft + x += font->baseline_x; + break; } + y += (cy+1 - font->height)/2; /* Render */ - mf_render_aligned(font, x, state.y0, justify, str, 0, - gdispFillString_callback, &state); - - /* Fill any space left */ - if (!state.rightalign && state.prev_x < max_x) - { - gdispFillArea(state.prev_x, state.y0, max_x - state.prev_x, - state.font->height, bgcolor); - } - else if (state.rightalign && state.prev_x > min_x) - { - gdispFillArea(min_x, state.y0, state.prev_x - min_x, - state.font->height, bgcolor); - } + mf_render_aligned(font, x, y, justify, str, 0, gdispFillString_callback, &state); } -#endif - -#if GDISP_NEED_TEXT + coord_t gdispGetFontMetric(font_t font, fontmetric_t metric) { /* No mutex required as we only read static data */ switch(metric) { @@ -835,16 +782,12 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { } return 0; } -#endif - -#if GDISP_NEED_TEXT + coord_t gdispGetCharWidth(char c, font_t font) { /* No mutex required as we only read static data */ return mf_character_width(font, c); } -#endif - -#if GDISP_NEED_TEXT + coord_t gdispGetStringWidth(const char* str, font_t font) { /* No mutex required as we only read static data */ return mf_get_string_width(font, str, 0, 0);