diff options
-rw-r--r-- | apps/gui/skin_engine/skin_parser.c | 48 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_render.c | 23 | ||||
-rw-r--r-- | apps/gui/skin_engine/wps_internals.h | 9 | ||||
-rw-r--r-- | apps/screen_access.c | 3 | ||||
-rw-r--r-- | apps/screen_access.h | 4 | ||||
-rw-r--r-- | firmware/drivers/lcd-bitmap-common.c | 14 | ||||
-rw-r--r-- | lib/skin_parser/tag_table.c | 1 | ||||
-rw-r--r-- | lib/skin_parser/tag_table.h | 2 | ||||
-rw-r--r-- | manual/appendix/wps_tags.tex | 7 |
9 files changed, 105 insertions, 6 deletions
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index 2d9d7cd807..49373eca32 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c @@ -638,6 +638,51 @@ static int parse_viewporttextstyle(struct skin_element *element, return 0; } +static int parse_drawrectangle( struct skin_element *element, + struct wps_token *token, + struct wps_data *wps_data) +{ + (void)wps_data; + struct draw_rectangle *rect = + (struct draw_rectangle *)skin_buffer_alloc(sizeof(struct draw_rectangle)); + + if (!rect) + return -1; + + rect->x = get_param(element, 0)->data.number; + rect->y = get_param(element, 1)->data.number; + + if (isdefault(get_param(element, 2))) + rect->width = curr_vp->vp.width - rect->x; + else + rect->width = get_param(element, 2)->data.number; + + if (isdefault(get_param(element, 3))) + rect->height = curr_vp->vp.height - rect->y; + else + rect->height = get_param(element, 3)->data.number; + + rect->start_colour = curr_vp->vp.fg_pattern; + rect->end_colour = curr_vp->vp.fg_pattern; + + if (element->params_count > 4) + { + if (!parse_color(curr_screen, get_param_text(element, 4), + &rect->start_colour)) + return -1; + rect->end_colour = rect->start_colour; + } + if (element->params_count > 5) + { + if (!parse_color(curr_screen, get_param_text(element, 5), + &rect->end_colour)) + return -1; + } + token->value.data = PTRTOSKINOFFSET(skin_buffer, rect); + + return 0; +} + static int parse_viewportcolour(struct skin_element *element, struct wps_token *token, struct wps_data *wps_data) @@ -2013,6 +2058,9 @@ static int skin_element_callback(struct skin_element* element, void* data) sb_skin_has_title(curr_screen); #endif break; + case SKIN_TOKEN_DRAWRECTANGLE: + function = parse_drawrectangle; + break; #endif case SKIN_TOKEN_FILE_DIRECTORY: token->value.i = get_param(element, 0)->data.number; diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c index 80d8c83d27..7ceb0bce17 100644 --- a/apps/gui/skin_engine/skin_render.c +++ b/apps/gui/skin_engine/skin_render.c @@ -176,8 +176,29 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, if (do_refresh) draw_peakmeters(gwps, info->line_number, vp); break; + case SKIN_TOKEN_DRAWRECTANGLE: + if (do_refresh) + { + struct draw_rectangle *rect = + SKINOFFSETTOPTR(skin_buffer, token->value.data); +#ifdef HAVE_LCD_COLOR + if (rect->start_colour != rect->end_colour && + gwps->display->screen_type == SCREEN_MAIN) + { + gwps->display->gradient_fillrect(rect->x, rect->y, rect->width, + rect->height, rect->start_colour, rect->end_colour); + } + else #endif -#ifdef HAVE_LCD_BITMAP + { + unsigned backup = vp->fg_pattern; + vp->fg_pattern = rect->start_colour; + gwps->display->fillrect(rect->x, rect->y, rect->width, + rect->height); + vp->fg_pattern = backup; + } + } + break; case SKIN_TOKEN_PEAKMETER_LEFTBAR: case SKIN_TOKEN_PEAKMETER_RIGHTBAR: data->peak_meter_enabled = true; diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h index 3b1d7cf054..3788712c9d 100644 --- a/apps/gui/skin_engine/wps_internals.h +++ b/apps/gui/skin_engine/wps_internals.h @@ -113,6 +113,15 @@ struct progressbar { bool horizontal; OFFSETTYPE(struct gui_img *) backdrop; }; + +struct draw_rectangle { + int x; + int y; + int width; + int height; + unsigned start_colour; + unsigned end_colour; +}; #endif diff --git a/apps/screen_access.c b/apps/screen_access.c index 43000e1360..fc92210981 100644 --- a/apps/screen_access.c +++ b/apps/screen_access.c @@ -264,6 +264,9 @@ struct screen screens[NB_SCREENS] = #endif #if defined(HAVE_LCD_BITMAP) .set_framebuffer = (void*)lcd_set_framebuffer, +#if defined(HAVE_LCD_COLOR) + .gradient_fillrect = lcd_gradient_fillrect, +#endif #endif }, #if NB_SCREENS == 2 diff --git a/apps/screen_access.h b/apps/screen_access.h index 343829b915..ab2ef4f14d 100644 --- a/apps/screen_access.h +++ b/apps/screen_access.h @@ -162,6 +162,10 @@ struct screen #endif #if defined(HAVE_LCD_BITMAP) void (*set_framebuffer)(void *framebuffer); +#if defined(HAVE_LCD_COLOR) + void (*gradient_fillrect)(int x, int y, int width, int height, + unsigned start, unsigned end); +#endif #endif }; diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c index 80796b392b..0bae790e58 100644 --- a/firmware/drivers/lcd-bitmap-common.c +++ b/firmware/drivers/lcd-bitmap-common.c @@ -41,14 +41,18 @@ #endif #if defined(MAIN_LCD) && defined(HAVE_LCD_COLOR) -void lcd_gradient_fillrect(int x1, int x2, int y1, int y2, +void lcd_gradient_fillrect(int x, int y, int width, int height, unsigned start_rgb, unsigned end_rgb) { int old_pattern = current_vp->fg_pattern; int step_mul, i; - if (y2 - y1 == 0) return; + int x1, x2; + x1 = x; + x2 = x + width; + + if (height == 0) return; - step_mul = (1 << 16) / (y2 - y1); + step_mul = (1 << 16) / height; int h_r = RGB_UNPACK_RED(start_rgb); int h_g = RGB_UNPACK_GREEN(start_rgb); int h_b = RGB_UNPACK_BLUE(start_rgb); @@ -59,7 +63,7 @@ void lcd_gradient_fillrect(int x1, int x2, int y1, int y2, h_g = (h_g << 16) + (1 << 15); h_b = (h_b << 16) + (1 << 15); - for(i = y1; i < y2; i++) { + for(i = y; i < y + height; i++) { current_vp->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); lcd_hline(x1, x2, i); h_r -= rstep; @@ -108,7 +112,7 @@ static void lcd_do_gradient_line(int x1, int x2, int y, unsigned h, h_g -= h * gstep; h_b -= h * bstep; end_rgb = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); - lcd_gradient_fillrect(x1, x2, y, y + h, start_rgb, end_rgb); + lcd_gradient_fillrect(x1, y, x2 - x1, h, start_rgb, end_rgb); } #endif diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c index fb61da501b..1842cb9f70 100644 --- a/lib/skin_parser/tag_table.c +++ b/lib/skin_parser/tag_table.c @@ -244,6 +244,7 @@ static const struct tag_info legal_tags[] = { SKIN_TOKEN_VAR_TIMEOUT, "vl", "S|D", SKIN_REFRESH_DYNAMIC }, { SKIN_TOKEN_SUBSTRING, "ss", "IiT|s", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_DRAWRECTANGLE, "dr", "IIii|ss", SKIN_REFRESH_STATIC }, { SKIN_TOKEN_UNKNOWN, "" , "", 0 } /* Keep this here to mark the end of the table */ }; diff --git a/lib/skin_parser/tag_table.h b/lib/skin_parser/tag_table.h index cf0096f28d..932f4a5ffd 100644 --- a/lib/skin_parser/tag_table.h +++ b/lib/skin_parser/tag_table.h @@ -288,6 +288,8 @@ enum skin_token_type { SKIN_TOKEN_VAR_TIMEOUT, SKIN_TOKEN_SUBSTRING, + + SKIN_TOKEN_DRAWRECTANGLE, }; /* diff --git a/manual/appendix/wps_tags.tex b/manual/appendix/wps_tags.tex index f1a661c2da..4aa9472e74 100644 --- a/manual/appendix/wps_tags.tex +++ b/manual/appendix/wps_tags.tex @@ -100,6 +100,13 @@ show the information for the next song to be played. \config{\%Fl('id',filename)} & See section \ref{ref:multifont}.\\ \end{tagmap} + \section{Misc Coloring Tags} + \begin{tagmap} + \config{\%dr(x,y,width,height,[color1,color2])} & Color a rectangle. \\ + \end{tagmap} + width and height can be - to fill the viewport. If no color is + specified the viewports foreground color will be used. If two + colors are specified it will do a gradient fill. } \section{Power Related Information} |