summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/gui/skin_engine/skin_parser.c48
-rw-r--r--apps/gui/skin_engine/skin_render.c23
-rw-r--r--apps/gui/skin_engine/wps_internals.h9
-rw-r--r--apps/screen_access.c3
-rw-r--r--apps/screen_access.h4
-rw-r--r--firmware/drivers/lcd-bitmap-common.c14
-rw-r--r--lib/skin_parser/tag_table.c1
-rw-r--r--lib/skin_parser/tag_table.h2
-rw-r--r--manual/appendix/wps_tags.tex7
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,
638 return 0; 638 return 0;
639} 639}
640 640
641static int parse_drawrectangle( struct skin_element *element,
642 struct wps_token *token,
643 struct wps_data *wps_data)
644{
645 (void)wps_data;
646 struct draw_rectangle *rect =
647 (struct draw_rectangle *)skin_buffer_alloc(sizeof(struct draw_rectangle));
648
649 if (!rect)
650 return -1;
651
652 rect->x = get_param(element, 0)->data.number;
653 rect->y = get_param(element, 1)->data.number;
654
655 if (isdefault(get_param(element, 2)))
656 rect->width = curr_vp->vp.width - rect->x;
657 else
658 rect->width = get_param(element, 2)->data.number;
659
660 if (isdefault(get_param(element, 3)))
661 rect->height = curr_vp->vp.height - rect->y;
662 else
663 rect->height = get_param(element, 3)->data.number;
664
665 rect->start_colour = curr_vp->vp.fg_pattern;
666 rect->end_colour = curr_vp->vp.fg_pattern;
667
668 if (element->params_count > 4)
669 {
670 if (!parse_color(curr_screen, get_param_text(element, 4),
671 &rect->start_colour))
672 return -1;
673 rect->end_colour = rect->start_colour;
674 }
675 if (element->params_count > 5)
676 {
677 if (!parse_color(curr_screen, get_param_text(element, 5),
678 &rect->end_colour))
679 return -1;
680 }
681 token->value.data = PTRTOSKINOFFSET(skin_buffer, rect);
682
683 return 0;
684}
685
641static int parse_viewportcolour(struct skin_element *element, 686static int parse_viewportcolour(struct skin_element *element,
642 struct wps_token *token, 687 struct wps_token *token,
643 struct wps_data *wps_data) 688 struct wps_data *wps_data)
@@ -2013,6 +2058,9 @@ static int skin_element_callback(struct skin_element* element, void* data)
2013 sb_skin_has_title(curr_screen); 2058 sb_skin_has_title(curr_screen);
2014#endif 2059#endif
2015 break; 2060 break;
2061 case SKIN_TOKEN_DRAWRECTANGLE:
2062 function = parse_drawrectangle;
2063 break;
2016#endif 2064#endif
2017 case SKIN_TOKEN_FILE_DIRECTORY: 2065 case SKIN_TOKEN_FILE_DIRECTORY:
2018 token->value.i = get_param(element, 0)->data.number; 2066 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,
176 if (do_refresh) 176 if (do_refresh)
177 draw_peakmeters(gwps, info->line_number, vp); 177 draw_peakmeters(gwps, info->line_number, vp);
178 break; 178 break;
179 case SKIN_TOKEN_DRAWRECTANGLE:
180 if (do_refresh)
181 {
182 struct draw_rectangle *rect =
183 SKINOFFSETTOPTR(skin_buffer, token->value.data);
184#ifdef HAVE_LCD_COLOR
185 if (rect->start_colour != rect->end_colour &&
186 gwps->display->screen_type == SCREEN_MAIN)
187 {
188 gwps->display->gradient_fillrect(rect->x, rect->y, rect->width,
189 rect->height, rect->start_colour, rect->end_colour);
190 }
191 else
179#endif 192#endif
180#ifdef HAVE_LCD_BITMAP 193 {
194 unsigned backup = vp->fg_pattern;
195 vp->fg_pattern = rect->start_colour;
196 gwps->display->fillrect(rect->x, rect->y, rect->width,
197 rect->height);
198 vp->fg_pattern = backup;
199 }
200 }
201 break;
181 case SKIN_TOKEN_PEAKMETER_LEFTBAR: 202 case SKIN_TOKEN_PEAKMETER_LEFTBAR:
182 case SKIN_TOKEN_PEAKMETER_RIGHTBAR: 203 case SKIN_TOKEN_PEAKMETER_RIGHTBAR:
183 data->peak_meter_enabled = true; 204 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 {
113 bool horizontal; 113 bool horizontal;
114 OFFSETTYPE(struct gui_img *) backdrop; 114 OFFSETTYPE(struct gui_img *) backdrop;
115}; 115};
116
117struct draw_rectangle {
118 int x;
119 int y;
120 int width;
121 int height;
122 unsigned start_colour;
123 unsigned end_colour;
124};
116#endif 125#endif
117 126
118 127
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] =
264#endif 264#endif
265#if defined(HAVE_LCD_BITMAP) 265#if defined(HAVE_LCD_BITMAP)
266 .set_framebuffer = (void*)lcd_set_framebuffer, 266 .set_framebuffer = (void*)lcd_set_framebuffer,
267#if defined(HAVE_LCD_COLOR)
268 .gradient_fillrect = lcd_gradient_fillrect,
269#endif
267#endif 270#endif
268 }, 271 },
269#if NB_SCREENS == 2 272#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
162#endif 162#endif
163#if defined(HAVE_LCD_BITMAP) 163#if defined(HAVE_LCD_BITMAP)
164 void (*set_framebuffer)(void *framebuffer); 164 void (*set_framebuffer)(void *framebuffer);
165#if defined(HAVE_LCD_COLOR)
166 void (*gradient_fillrect)(int x, int y, int width, int height,
167 unsigned start, unsigned end);
168#endif
165#endif 169#endif
166}; 170};
167 171
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 @@
41#endif 41#endif
42 42
43#if defined(MAIN_LCD) && defined(HAVE_LCD_COLOR) 43#if defined(MAIN_LCD) && defined(HAVE_LCD_COLOR)
44void lcd_gradient_fillrect(int x1, int x2, int y1, int y2, 44void lcd_gradient_fillrect(int x, int y, int width, int height,
45 unsigned start_rgb, unsigned end_rgb) 45 unsigned start_rgb, unsigned end_rgb)
46{ 46{
47 int old_pattern = current_vp->fg_pattern; 47 int old_pattern = current_vp->fg_pattern;
48 int step_mul, i; 48 int step_mul, i;
49 if (y2 - y1 == 0) return; 49 int x1, x2;
50 x1 = x;
51 x2 = x + width;
52
53 if (height == 0) return;
50 54
51 step_mul = (1 << 16) / (y2 - y1); 55 step_mul = (1 << 16) / height;
52 int h_r = RGB_UNPACK_RED(start_rgb); 56 int h_r = RGB_UNPACK_RED(start_rgb);
53 int h_g = RGB_UNPACK_GREEN(start_rgb); 57 int h_g = RGB_UNPACK_GREEN(start_rgb);
54 int h_b = RGB_UNPACK_BLUE(start_rgb); 58 int h_b = RGB_UNPACK_BLUE(start_rgb);
@@ -59,7 +63,7 @@ void lcd_gradient_fillrect(int x1, int x2, int y1, int y2,
59 h_g = (h_g << 16) + (1 << 15); 63 h_g = (h_g << 16) + (1 << 15);
60 h_b = (h_b << 16) + (1 << 15); 64 h_b = (h_b << 16) + (1 << 15);
61 65
62 for(i = y1; i < y2; i++) { 66 for(i = y; i < y + height; i++) {
63 current_vp->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); 67 current_vp->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16);
64 lcd_hline(x1, x2, i); 68 lcd_hline(x1, x2, i);
65 h_r -= rstep; 69 h_r -= rstep;
@@ -108,7 +112,7 @@ static void lcd_do_gradient_line(int x1, int x2, int y, unsigned h,
108 h_g -= h * gstep; 112 h_g -= h * gstep;
109 h_b -= h * bstep; 113 h_b -= h * bstep;
110 end_rgb = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); 114 end_rgb = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16);
111 lcd_gradient_fillrect(x1, x2, y, y + h, start_rgb, end_rgb); 115 lcd_gradient_fillrect(x1, y, x2 - x1, h, start_rgb, end_rgb);
112} 116}
113 117
114#endif 118#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[] =
244 { SKIN_TOKEN_VAR_TIMEOUT, "vl", "S|D", SKIN_REFRESH_DYNAMIC }, 244 { SKIN_TOKEN_VAR_TIMEOUT, "vl", "S|D", SKIN_REFRESH_DYNAMIC },
245 245
246 { SKIN_TOKEN_SUBSTRING, "ss", "IiT|s", SKIN_REFRESH_DYNAMIC }, 246 { SKIN_TOKEN_SUBSTRING, "ss", "IiT|s", SKIN_REFRESH_DYNAMIC },
247 { SKIN_TOKEN_DRAWRECTANGLE, "dr", "IIii|ss", SKIN_REFRESH_STATIC },
247 { SKIN_TOKEN_UNKNOWN, "" , "", 0 } 248 { SKIN_TOKEN_UNKNOWN, "" , "", 0 }
248 /* Keep this here to mark the end of the table */ 249 /* Keep this here to mark the end of the table */
249}; 250};
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 {
288 SKIN_TOKEN_VAR_TIMEOUT, 288 SKIN_TOKEN_VAR_TIMEOUT,
289 289
290 SKIN_TOKEN_SUBSTRING, 290 SKIN_TOKEN_SUBSTRING,
291
292 SKIN_TOKEN_DRAWRECTANGLE,
291}; 293};
292 294
293/* 295/*
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.
100 \config{\%Fl('id',filename)} & See section \ref{ref:multifont}.\\ 100 \config{\%Fl('id',filename)} & See section \ref{ref:multifont}.\\
101 \end{tagmap} 101 \end{tagmap}
102 102
103 \section{Misc Coloring Tags}
104 \begin{tagmap}
105 \config{\%dr(x,y,width,height,[color1,color2])} & Color a rectangle. \\
106 \end{tagmap}
107 width and height can be - to fill the viewport. If no color is
108 specified the viewports foreground color will be used. If two
109 colors are specified it will do a gradient fill.
103} 110}
104 111
105\section{Power Related Information} 112\section{Power Related Information}