diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index 237e4033e2..01fedba99b 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c @@ -1995,6 +1995,8 @@ static int convert_viewport(struct wps_data *data, struct skin_element* element) skin_vp->vp.x = param->data.number; if (param->data.number < 0) skin_vp->vp.x += display->lcdwidth; + else if (param->type == PERCENT) + skin_vp->vp.x = param->data.number * display->lcdwidth / 1000; } param++; /* y */ @@ -2003,6 +2005,8 @@ static int convert_viewport(struct wps_data *data, struct skin_element* element) skin_vp->vp.y = param->data.number; if (param->data.number < 0) skin_vp->vp.y += display->lcdheight; + else if (param->type == PERCENT) + skin_vp->vp.y = param->data.number * display->lcdheight / 1000; } param++; /* width */ @@ -2011,6 +2015,8 @@ static int convert_viewport(struct wps_data *data, struct skin_element* element) skin_vp->vp.width = param->data.number; if (param->data.number < 0) skin_vp->vp.width = (skin_vp->vp.width + display->lcdwidth) - skin_vp->vp.x; + else if (param->type == PERCENT) + skin_vp->vp.width = param->data.number * display->lcdwidth / 1000; } else { @@ -2023,6 +2029,8 @@ static int convert_viewport(struct wps_data *data, struct skin_element* element) skin_vp->vp.height = param->data.number; if (param->data.number < 0) skin_vp->vp.height = (skin_vp->vp.height + display->lcdheight) - skin_vp->vp.y; + else if (param->type == PERCENT) + skin_vp->vp.height = param->data.number * display->lcdheight / 1000; } else { diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c index b550a90073..e58393e19c 100644 --- a/apps/gui/skin_engine/skin_tokens.c +++ b/apps/gui/skin_engine/skin_tokens.c @@ -761,6 +761,7 @@ static const char* NOINLINE get_lif_token_value(struct gui_wps *gwps, if (!number_set && out_text && *out_text >= '0' && *out_text <= '9') a = atoi(out_text); /* fall through */ + case PERCENT: case DECIMAL: b = lif->operand.data.number; break; diff --git a/lib/skin_parser/skin_parser.c b/lib/skin_parser/skin_parser.c index 748ea5da22..1f4b87a328 100644 --- a/lib/skin_parser/skin_parser.c +++ b/lib/skin_parser/skin_parser.c @@ -568,7 +568,7 @@ static int skin_parse_tag(struct skin_element* element, const char** document) while(*cursor != '\n' && *cursor != '\0' && *cursor != ARGLISTCLOSESYM) { /* Skipping over escaped characters */ - if(*cursor == TAGSYM) + if(*cursor == TAGSYM && *(cursor+1) != ARGLISTSEPARATESYM) { skip_tag(&cursor); } @@ -625,7 +625,7 @@ static int skin_parse_tag(struct skin_element* element, const char** document) * default > decimal/integer > single tag/code > string */ int j=0; - bool canbedefault = false; + bool canbedefault = false, last_char_is_percent = false; bool haspercent = false, number = true, hasdecimal = false; char temp_params[8]; open_square_bracket = tag_args; @@ -644,9 +644,11 @@ static int skin_parse_tag(struct skin_element* element, const char** document) hasdecimal = hasdecimal || (cursor[j] == '.'); number = number && (isdigit(cursor[j]) || (cursor[j] == '.') || - (cursor[j] == '-')); + (cursor[j] == '-') || + (cursor[j] == '%')); j++; } + last_char_is_percent = cursor[j-1] == '%'; type_code = '?'; if (canbedefault && *cursor == DEFAULTSYM && !isdigit(cursor[1])) { @@ -656,6 +658,10 @@ static int skin_parse_tag(struct skin_element* element, const char** document) { type_code = 'd'; } + else if (number && last_char_is_percent && strchr(temp_params, 'p')) + { + type_code = 'p'; + } else if (number && (strchr(temp_params, 'i') || strchr(temp_params, 'd'))) { @@ -707,7 +713,7 @@ static int skin_parse_tag(struct skin_element* element, const char** document) params[i].type = INTEGER; params[i].data.number = scan_int(&cursor); } - else if(tolower(type_code) == 'd') + else if(tolower(type_code) == 'd' || tolower(type_code) == 'p') { int val = 0; bool have_point = false; @@ -731,7 +737,13 @@ static int skin_parse_tag(struct skin_element* element, const char** document) } if (have_tenth == false) val *= 10; - params[i].type = DECIMAL; + if (tolower(type_code) == 'd') + params[i].type = DECIMAL; + else + { + params[i].type = PERCENT; + cursor++; /* skip trailing % sign */ + } params[i].data.number = val; } else if(tolower(type_code) == 's' || tolower(type_code) == 'f') diff --git a/lib/skin_parser/skin_parser.h b/lib/skin_parser/skin_parser.h index 120112d995..ec51b64c8b 100644 --- a/lib/skin_parser/skin_parser.h +++ b/lib/skin_parser/skin_parser.h @@ -89,6 +89,7 @@ struct skin_tag_parameter { INTEGER, DECIMAL, /* stored in data.number as (whole*10)+part */ + PERCENT, /* stored in data.number as (whole*10)+part */ STRING, CODE, DEFAULT diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c index 76139df04e..ec1476fb80 100644 --- a/lib/skin_parser/tag_table.c +++ b/lib/skin_parser/tag_table.c @@ -206,9 +206,9 @@ static const struct tag_info legal_tags[] = { SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP, "Vg" , "SS|s", SKIN_REFRESH_STATIC|NOBREAK }, { SKIN_TOKEN_VIEWPORT_DRAWONBG, "VB" , "", SKIN_REFRESH_STATIC|NOBREAK }, - { SKIN_TOKEN_VIEWPORT_CONDITIONAL, "Vl" , "SIIiii", 0 }, - { SKIN_TOKEN_UIVIEWPORT_LOAD, "Vi" , "sIIiii", 0 }, - { SKIN_TOKEN_VIEWPORT_LOAD, "V" , "IIiii", 0 }, + { SKIN_TOKEN_VIEWPORT_CONDITIONAL, "Vl" , "S[IP][IP][ip][ip]i", 0 }, + { SKIN_TOKEN_UIVIEWPORT_LOAD, "Vi" , "s[IP][IP][ip][ip]i", 0 }, + { SKIN_TOKEN_VIEWPORT_LOAD, "V" , "[IP][IP][ip][ip]i", 0 }, { SKIN_TOKEN_IMAGE_BACKDROP, "X" , "f", SKIN_REFRESH_STATIC|NOBREAK }, /* This uses the bar tag params also but the first item can be a string diff --git a/lib/skin_parser/tag_table.h b/lib/skin_parser/tag_table.h index b29c6d79d8..41f7d7dd86 100644 --- a/lib/skin_parser/tag_table.h +++ b/lib/skin_parser/tag_table.h @@ -304,6 +304,9 @@ enum skin_token_type { * D - Required decimal * d - Nullable decimal * Decimals are stored as (whole*10)+part + * P - Required percentage + * p - Nullable percentage + * Percentages pestored as permilles (percent*10 + part) * S - Required string * s - Nullable string * F - Required file name