static bool skin_render_line(struct skin_element* line, struct skin_draw_info *info)
{
bool needs_update = false;
int last_value, value;
bool in_changed_alternator = false;
struct skin_element *child;
struct conditional *conditional;
int old_refresh_mode = info->refresh_type;
if (line->type == LINE_ALTERNATOR)
{
line = line->children[alternator_change_line(line, info,
&in_changed_alternator)];
if (line->children_count == 0)
return in_changed_alternator;
if (in_changed_alternator)
{
info->refresh_type = SKIN_REFRESH_ALL;
info->force_redraw = true;
}
}
if (line->children_count == 0)
return false; /* empty line, do nothing */
child = line->children[0];
while (child)
{
switch (child->type)
{
case CONDITIONAL:
conditional = (struct conditional*)child->data;
last_value = conditional->last_value;
value = evaluate_conditional(info->gwps, info->offset,
conditional, child->children_count);
conditional->last_value = value;
if (child->children_count == 1)
{
/* special handling so
* %?aa<true> and %?<true|false> need special handlng here */
if (value == -1) /* tag is false */
{
/* we are in a false branch of a %?aa<true> conditional */
if (last_value == 0)
do_tags_in_hidden_conditional(child->children[0], info);
break;
}
}
else
{
if (last_value >= 0 && value != last_value && last_value < child->children_count)
do_tags_in_hidden_conditional(child->children[last_value], info);
}
if (value != last_value)
{
info->refresh_type = SKIN_REFRESH_ALL;
info->force_redraw = true;
}
if (skin_render_line(child->children[value], info))
needs_update = true;
else
needs_update = needs_update || (last_value != value);
info->refresh_type = old_refresh_mode;
break;
case TAG:
if (child->tag->flags & NOBREAK)
info->no_line_break = true;
if (child->tag->type == SKIN_TOKEN_SUBLINE_SCROLL)
info->line_scrolls = true;
fix_line_alignment(info, child);
if (!child->data)
{
break;
}
if (!do_non_text_tags(info->gwps, info, child, &info->skin_vp->vp))
{
static char tempbuf[128];
const char *value = get_token_value(info->gwps, child->data,
info->offset, tempbuf,
sizeof(tempbuf), NULL);
if (value)
{
#if CONFIG_RTC
if (child->tag->flags&SKIN_RTC_REFRESH)
needs_update = needs_update || info->refresh_type&SKIN_REFRESH_DYNAMIC;
#endif
needs_update = needs_update ||
((child->tag->flags&info->refresh_type)!=0);
strlcat(info->cur_align_start, value,
info->buf_size - (info->cur_align_start-info->buf));
}
}
break;
case TEXT:
strlcat(info->cur_align_start, child->data,
info->buf_size - (info->cur_align_start-info->buf));
needs_update = needs_update ||
(info->refresh_type&SKIN_REFRESH_STATIC) != 0;
break;
case COMMENT:
default:
break;
}
child = child->next;
}
if (in_changed_alternator)
{
info->refresh_type = old_refresh_mode;
info->force_redraw = false;
needs_update = true;
}
return needs_update;
}