summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2012-03-15 22:50:17 +1100
committerJonathan Gordon <rockbox@jdgordon.info>2012-03-15 22:52:53 +1100
commit014a08cabb856b2360419aac404744029ee4748c (patch)
tree1bd05c47281446eec2568a96a0e32e16439f1262
parentdcc78cb86764e5f02bc89693f64dc38c82f776ad (diff)
downloadrockbox-014a08cabb856b2360419aac404744029ee4748c.tar.gz
rockbox-014a08cabb856b2360419aac404744029ee4748c.zip
skin_engine: New tag to draw a rectangle (optionally with a gradient)
%dr(x, y, width, height, [colour1[, colour2]]): x,y - viewport relative pixel coordinates to start the rectangle. width, height - obvious. can be '-' to fill the viewport if both colours are left out the viewports foreground colour will be used if one colour is specified it will fill the rectangle that colour. if both colours are specified it will gradient fill the rectangle. Change-Id: Iad451e99ded663bc7c5d182443659db7d909b388
-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}