summaryrefslogtreecommitdiff
path: root/apps/gui/skin_engine/skin_render.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/gui/skin_engine/skin_render.c')
-rw-r--r--apps/gui/skin_engine/skin_render.c66
1 files changed, 43 insertions, 23 deletions
diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c
index ed2f783e7a..7f2dcab222 100644
--- a/apps/gui/skin_engine/skin_render.c
+++ b/apps/gui/skin_engine/skin_render.c
@@ -96,7 +96,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
96 struct skin_element *element, struct skin_viewport* skin_vp) 96 struct skin_element *element, struct skin_viewport* skin_vp)
97{ 97{
98 struct wps_token *token = (struct wps_token *)SKINOFFSETTOPTR(skin_buffer, element->data); 98 struct wps_token *token = (struct wps_token *)SKINOFFSETTOPTR(skin_buffer, element->data);
99 99 if (!token) return false;
100 struct viewport *vp = &skin_vp->vp; 100 struct viewport *vp = &skin_vp->vp;
101 struct wps_data *data = gwps->data; 101 struct wps_data *data = gwps->data;
102 bool do_refresh = (element->tag->flags & info->refresh_type) > 0; 102 bool do_refresh = (element->tag->flags & info->refresh_type) > 0;
@@ -107,7 +107,9 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
107 case SKIN_TOKEN_VIEWPORT_FGCOLOUR: 107 case SKIN_TOKEN_VIEWPORT_FGCOLOUR:
108 { 108 {
109 struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data); 109 struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data);
110 if (!col) return false;
110 struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp); 111 struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp);
112 if (!vp) return false;
111 vp->fg_pattern = col->colour; 113 vp->fg_pattern = col->colour;
112 skin_vp->fgbg_changed = true; 114 skin_vp->fgbg_changed = true;
113 } 115 }
@@ -115,7 +117,9 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
115 case SKIN_TOKEN_VIEWPORT_BGCOLOUR: 117 case SKIN_TOKEN_VIEWPORT_BGCOLOUR:
116 { 118 {
117 struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data); 119 struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data);
120 if (!col) return false;
118 struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp); 121 struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp);
122 if (!vp) return false;
119 vp->bg_pattern = col->colour; 123 vp->bg_pattern = col->colour;
120 skin_vp->fgbg_changed = true; 124 skin_vp->fgbg_changed = true;
121 } 125 }
@@ -124,6 +128,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
124 { 128 {
125 struct line_desc *data = SKINOFFSETTOPTR(skin_buffer, token->value.data); 129 struct line_desc *data = SKINOFFSETTOPTR(skin_buffer, token->value.data);
126 struct line_desc *linedes = &info->line_desc; 130 struct line_desc *linedes = &info->line_desc;
131 if (!data || !linedes) return false;
127 /* gradient colors are handled with a separate tag 132 /* gradient colors are handled with a separate tag
128 * (SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP, see below). since it may 133 * (SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP, see below). since it may
129 * come before the text style tag color fields need to be preserved */ 134 * come before the text style tag color fields need to be preserved */
@@ -147,6 +152,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
147 { 152 {
148 struct gradient_config *cfg = SKINOFFSETTOPTR(skin_buffer, token->value.data); 153 struct gradient_config *cfg = SKINOFFSETTOPTR(skin_buffer, token->value.data);
149 struct line_desc *linedes = &info->line_desc; 154 struct line_desc *linedes = &info->line_desc;
155 if (!cfg || !linedes) return false;
150 linedes->text_color = cfg->text; 156 linedes->text_color = cfg->text;
151 linedes->line_color = cfg->start; 157 linedes->line_color = cfg->start;
152 linedes->line_end_color = cfg->end; 158 linedes->line_end_color = cfg->end;
@@ -162,17 +168,19 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
162 { 168 {
163 struct skin_viewport *skinvp = SKINOFFSETTOPTR(skin_buffer, viewport->data); 169 struct skin_viewport *skinvp = SKINOFFSETTOPTR(skin_buffer, viewport->data);
164 170
165 char *vplabel = SKINOFFSETTOPTR(skin_buffer, skinvp->label); 171 if (skinvp) {
166 if (skinvp->label == VP_DEFAULT_LABEL) 172 char *vplabel = SKINOFFSETTOPTR(skin_buffer, skinvp->label);
167 vplabel = VP_DEFAULT_LABEL_STRING; 173 if (skinvp->label == VP_DEFAULT_LABEL)
168 if (vplabel && !skinvp->is_infovp && 174 vplabel = VP_DEFAULT_LABEL_STRING;
169 !strcmp(vplabel, label)) 175 if (vplabel && !skinvp->is_infovp &&
170 { 176 !strcmp(vplabel, label))
171 if (skinvp->hidden_flags&VP_DRAW_HIDDEN)
172 { 177 {
173 temp |= VP_DRAW_WASHIDDEN; 178 if (skinvp->hidden_flags&VP_DRAW_HIDDEN)
179 {
180 temp |= VP_DRAW_WASHIDDEN;
181 }
182 skinvp->hidden_flags = temp;
174 } 183 }
175 skinvp->hidden_flags = temp;
176 } 184 }
177 viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next); 185 viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next);
178 } 186 }
@@ -195,12 +203,13 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
195 { 203 {
196 struct draw_rectangle *rect = 204 struct draw_rectangle *rect =
197 SKINOFFSETTOPTR(skin_buffer, token->value.data); 205 SKINOFFSETTOPTR(skin_buffer, token->value.data);
206 if (!rect) break;
198#ifdef HAVE_LCD_COLOR 207#ifdef HAVE_LCD_COLOR
199 if (rect->start_colour != rect->end_colour && 208 if (rect->start_colour != rect->end_colour &&
200 gwps->display->screen_type == SCREEN_MAIN) 209 gwps->display->screen_type == SCREEN_MAIN)
201 { 210 {
202 gwps->display->gradient_fillrect(rect->x, rect->y, rect->width, 211 gwps->display->gradient_fillrect(rect->x, rect->y, rect->width,
203 rect->height, rect->start_colour, rect->end_colour); 212 rect->height, rect->start_colour, rect->end_colour);
204 } 213 }
205 else 214 else
206#endif 215#endif
@@ -210,7 +219,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
210 vp->fg_pattern = rect->start_colour; 219 vp->fg_pattern = rect->start_colour;
211#endif 220#endif
212 gwps->display->fillrect(rect->x, rect->y, rect->width, 221 gwps->display->fillrect(rect->x, rect->y, rect->width,
213 rect->height); 222 rect->height);
214#if LCD_DEPTH > 1 223#if LCD_DEPTH > 1
215 vp->fg_pattern = backup; 224 vp->fg_pattern = backup;
216#endif 225#endif
@@ -245,6 +254,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
245 case SKIN_TOKEN_IMAGE_DISPLAY_9SEGMENT: 254 case SKIN_TOKEN_IMAGE_DISPLAY_9SEGMENT:
246 { 255 {
247 struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data); 256 struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data);
257 if (!id) break;
248 const char* label = SKINOFFSETTOPTR(skin_buffer, id->label); 258 const char* label = SKINOFFSETTOPTR(skin_buffer, id->label);
249 struct gui_img *img = skin_find_item(label,SKIN_FIND_IMAGE, data); 259 struct gui_img *img = skin_find_item(label,SKIN_FIND_IMAGE, data);
250 if (img && img->loaded) 260 if (img && img->loaded)
@@ -313,7 +323,6 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
313 skin_render_playlistviewer(SKINOFFSETTOPTR(skin_buffer, token->value.data), gwps, 323 skin_render_playlistviewer(SKINOFFSETTOPTR(skin_buffer, token->value.data), gwps,
314 info->skin_vp, info->refresh_type); 324 info->skin_vp, info->refresh_type);
315 break; 325 break;
316
317#ifdef HAVE_SKIN_VARIABLES 326#ifdef HAVE_SKIN_VARIABLES
318 case SKIN_TOKEN_VAR_SET: 327 case SKIN_TOKEN_VAR_SET:
319 { 328 {
@@ -374,19 +383,21 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
374 { 383 {
375 do_tags_in_hidden_conditional(get_child(child->children, i), info); 384 do_tags_in_hidden_conditional(get_child(child->children, i), info);
376 } 385 }
377 child = SKINOFFSETTOPTR(skin_buffer, child->next); 386 goto skip;
378 continue;
379 } 387 }
380 else if (child->type != TAG || !SKINOFFSETTOPTR(skin_buffer, child->data)) 388 else if (child->type != TAG || !SKINOFFSETTOPTR(skin_buffer, child->data))
381 { 389 {
382 child = SKINOFFSETTOPTR(skin_buffer, child->next); 390 goto skip;
383 continue;
384 } 391 }
392
385 token = (struct wps_token *)SKINOFFSETTOPTR(skin_buffer, child->data); 393 token = (struct wps_token *)SKINOFFSETTOPTR(skin_buffer, child->data);
394
386 /* clear all pictures in the conditional and nested ones */ 395 /* clear all pictures in the conditional and nested ones */
387 if (token->type == SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY) 396 if (token->type == SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY)
388 { 397 {
389 struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data); 398 struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data);
399 if (!id) goto skip;
400
390 struct gui_img *img = skin_find_item(SKINOFFSETTOPTR(skin_buffer, id->label), 401 struct gui_img *img = skin_find_item(SKINOFFSETTOPTR(skin_buffer, id->label),
391 SKIN_FIND_IMAGE, data); 402 SKIN_FIND_IMAGE, data);
392 clear_image_pos(gwps, img); 403 clear_image_pos(gwps, img);
@@ -404,6 +415,7 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
404 viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next)) 415 viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next))
405 { 416 {
406 struct skin_viewport *skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data); 417 struct skin_viewport *skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data);
418 if (!skin_viewport) continue;
407 char *vplabel = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label); 419 char *vplabel = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label);
408 if (skin_viewport->label == VP_DEFAULT_LABEL) 420 if (skin_viewport->label == VP_DEFAULT_LABEL)
409 vplabel = VP_DEFAULT_LABEL_STRING; 421 vplabel = VP_DEFAULT_LABEL_STRING;
@@ -451,6 +463,7 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
451 playback_current_aa_hid(data->playback_aa_slot), true); 463 playback_current_aa_hid(data->playback_aa_slot), true);
452 } 464 }
453#endif 465#endif
466 skip:
454 child = SKINOFFSETTOPTR(skin_buffer, child->next); 467 child = SKINOFFSETTOPTR(skin_buffer, child->next);
455 } 468 }
456 } 469 }
@@ -517,6 +530,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
517 { 530 {
518 case CONDITIONAL: 531 case CONDITIONAL:
519 conditional = SKINOFFSETTOPTR(skin_buffer, child->data); 532 conditional = SKINOFFSETTOPTR(skin_buffer, child->data);
533 if (!conditional) break;
520 last_value = conditional->last_value; 534 last_value = conditional->last_value;
521 value = evaluate_conditional(info->gwps, info->offset, 535 value = evaluate_conditional(info->gwps, info->offset,
522 conditional, child->children_count); 536 conditional, child->children_count);
@@ -623,7 +637,8 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line)
623 element->tag->type == SKIN_TOKEN_SUBLINE_TIMEOUT ) 637 element->tag->type == SKIN_TOKEN_SUBLINE_TIMEOUT )
624 { 638 {
625 token = SKINOFFSETTOPTR(skin_buffer, element->data); 639 token = SKINOFFSETTOPTR(skin_buffer, element->data);
626 return token->value.i; 640 if (token)
641 return token->value.i;
627 } 642 }
628 else if (element->type == CONDITIONAL) 643 else if (element->type == CONDITIONAL)
629 { 644 {
@@ -726,8 +741,11 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps,
726 while (imglist) 741 while (imglist)
727 { 742 {
728 struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, imglist->token); 743 struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, imglist->token);
729 struct gui_img *img = (struct gui_img *)SKINOFFSETTOPTR(skin_buffer, token->value.data); 744 if (token) {
730 img->display = -1; 745 struct gui_img *img = (struct gui_img *)SKINOFFSETTOPTR(skin_buffer, token->value.data);
746 if (img)
747 img->display = -1;
748 }
731 imglist = SKINOFFSETTOPTR(skin_buffer, imglist->next); 749 imglist = SKINOFFSETTOPTR(skin_buffer, imglist->next);
732 } 750 }
733 751
@@ -756,7 +774,6 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps,
756 align->center = NULL; 774 align->center = NULL;
757 align->right = NULL; 775 align->right = NULL;
758 776
759
760 if (line->type == LINE_ALTERNATOR) 777 if (line->type == LINE_ALTERNATOR)
761 func = skin_render_alternator; 778 func = skin_render_alternator;
762 else if (line->type == LINE) 779 else if (line->type == LINE)
@@ -819,9 +836,10 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
819 display->clear_viewport(); 836 display->clear_viewport();
820 } 837 }
821 } 838 }
822
823 viewport = SKINOFFSETTOPTR(skin_buffer, data->tree); 839 viewport = SKINOFFSETTOPTR(skin_buffer, data->tree);
840 if (!viewport) return;
824 skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data); 841 skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data);
842 if (!skin_viewport) return;
825 label = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label); 843 label = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label);
826 if (skin_viewport->label == VP_DEFAULT_LABEL) 844 if (skin_viewport->label == VP_DEFAULT_LABEL)
827 label = VP_DEFAULT_LABEL_STRING; 845 label = VP_DEFAULT_LABEL_STRING;
@@ -833,8 +851,10 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
833 viewport; 851 viewport;
834 viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next)) 852 viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next))
835 { 853 {
854
836 /* SETUP */ 855 /* SETUP */
837 skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data); 856 skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data);
857 if (!skin_viewport) continue;
838 unsigned vp_refresh_mode = refresh_mode; 858 unsigned vp_refresh_mode = refresh_mode;
839#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1) 859#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
840 if (skin_viewport->output_to_backdrop_buffer) 860 if (skin_viewport->output_to_backdrop_buffer)