From c1010bc0250b1e8dd6172faa884c61fb7ade3432 Mon Sep 17 00:00:00 2001 From: Vitalii Vorobiov Date: Mon, 13 Jun 2016 15:31:48 +0300 Subject: [PATCH] edje_calc: fix interpolate calculation of map colors There were a problem when while swithcing between states (because of program running in transition), there is SIGSEV appearing when first state has only one point color, and next state more than one. Basically it looks like this: .... part { name: "rectangle"; type: RECT; description { state: "default" 0.0; map { on: 1; color: 3 255 90 0 255; } } description { state: "moved" 0.0; map { on: 1; color: 0 0 0 255 255; color: 1 255 0 0 255; color: 2 255 90 0 255; color: 3 41 68 59 255; } } } .... @fix Change-Id: I078f692cf1e8f959fed68dbf79b38357f6882764 Signed-off-by: Vitalii Vorobiov --- src/lib/edje/edje_calc.c | 87 ++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 47 deletions(-) diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c index cc5677d..d9eb09d 100644 --- a/src/lib/edje/edje_calc.c +++ b/src/lib/edje/edje_calc.c @@ -3860,9 +3860,11 @@ static Eina_Bool _map_colors_interp(Edje_Calc_Params *p1, Edje_Calc_Params *p2, Edje_Calc_Params_Map *pmap, FLOAT_T pos) { - Edje_Map_Color *col, *col2, *col3; - int i, j, idx = 0; - Eina_Bool matched = EINA_FALSE; + Edje_Map_Color *col = NULL, *col2 = NULL, *col3; + int i, j; + + unsigned char col1_r = 255, col1_g = 255, col1_b = 255, col1_a = 255; + unsigned char col2_r = 255, col2_g = 255, col2_b = 255, col2_a = 255; if ((p1->map->colors_count > 0) || (p2->map->colors_count > 0)) { @@ -3870,59 +3872,50 @@ _map_colors_interp(Edje_Calc_Params *p1, Edje_Calc_Params *p2, pmap->colors = (Edje_Map_Color **)malloc(sizeof(Edje_Map_Color *) * (int)pmap->colors_count); - for (i = 0; i < (int)p1->map->colors_count; i++) + /* create all Map Color structs at first + to make sure we won't get SIGSEV later on cleanup. */ + for (i = 0; i < (int)pmap->colors_count; i++) { - col = p1->map->colors[i]; col3 = malloc(sizeof(Edje_Map_Color)); - col3->idx = col->idx; - - for (j = 0; j < (int)p2->map->colors_count; j++) - { - col2 = p2->map->colors[j]; - if (col->idx != col2->idx) continue; - col3->r = INTP(col->r, col2->r, pos); - col3->g = INTP(col->g, col2->g, pos); - col3->b = INTP(col->b, col2->b, pos); - col3->a = INTP(col->a, col2->a, pos); - pmap->colors[idx] = col3; - matched = EINA_TRUE; - break; - } - if (!matched) - { - col3->r = INTP(col->r, 255, pos); - col3->g = INTP(col->g, 255, pos); - col3->b = INTP(col->b, 255, pos); - col3->a = INTP(col->a, 255, pos); - pmap->colors[idx] = col3; - } - idx++; - matched = EINA_FALSE; - } - for (i = 0; i < (int)p2->map->colors_count; i++) - { - col = p2->map->colors[i]; + col3->idx = i; /* we don't care about index position anyway */ + /* find color with idx from first */ for (j = 0; j < (int)p1->map->colors_count; j++) { - col2 = p1->map->colors[j]; - if (col->idx != col2->idx) continue; - matched = EINA_TRUE; - break; + col = p1->map->colors[j]; + if (col3->idx == col->idx) + { + col1_r = col->r; + col1_g = col->g; + col1_b = col->b; + col1_a = col->a; + break; + } } - if (!matched) + /* find color from idx from second */ + for (j = 0; j < (int)p2->map->colors_count; j++) { - col3 = malloc(sizeof(Edje_Map_Color)); - col3->idx = col->idx; - col3->r = INTP(255, col->r, pos); - col3->g = INTP(255, col->g, pos); - col3->b = INTP(255, col->b, pos); - col3->a = INTP(255, col->a, pos); - pmap->colors[idx] = col3; + col2 = p2->map->colors[j]; + if (col3->idx == col2->idx) + { + col2_r = col2->r; + col2_g = col2->g; + col2_b = col2->b; + col2_a = col2->a; + break; + } } - idx++; - matched = EINA_FALSE; + + /* interpolate! + if color didn't existed, then there are default 255 values */ + col3->r = INTP(col1_r, col2_r, pos); + col3->g = INTP(col1_g, col2_g, pos); + col3->b = INTP(col1_b, col2_b, pos); + col3->a = INTP(col1_a, col2_a, pos); + + pmap->colors[i] = col3; } + return EINA_TRUE; } -- 2.7.4