1 /**
2  * @file lv_style.c
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 #include "lv_style.h"
10 #include "../misc/lv_gc.h"
11 #include "../misc/lv_mem.h"
12 #include "lv_assert.h"
13 #include "lv_types.h"
14 
15 /*********************
16  *      DEFINES
17  *********************/
18 
19 /**********************
20  *      TYPEDEFS
21  **********************/
22 
23 /**********************
24  *  STATIC PROTOTYPES
25  **********************/
26 
27 static void lv_style_set_prop_internal(lv_style_t * style, lv_style_prop_t prop_and_meta, lv_style_value_t value,
28                                        void (*value_adjustment_helper)(lv_style_prop_t, lv_style_value_t, uint16_t *, lv_style_value_t *));
29 static void lv_style_set_prop_helper(lv_style_prop_t prop, lv_style_value_t value, uint16_t * prop_storage,
30                                      lv_style_value_t * value_storage);
31 static void lv_style_set_prop_meta_helper(lv_style_prop_t prop, lv_style_value_t value, uint16_t * prop_storage,
32                                           lv_style_value_t * value_storage);
33 
34 /**********************
35  *  GLOBAL VARIABLES
36  **********************/
37 
38 const uint8_t _lv_style_builtin_prop_flag_lookup_table[_LV_STYLE_NUM_BUILT_IN_PROPS] = {
39     [LV_STYLE_WIDTH] =                    LV_STYLE_PROP_LAYOUT_REFR,
40     [LV_STYLE_MIN_WIDTH] =                LV_STYLE_PROP_LAYOUT_REFR,
41     [LV_STYLE_MAX_WIDTH] =                LV_STYLE_PROP_LAYOUT_REFR,
42     [LV_STYLE_HEIGHT] =                   LV_STYLE_PROP_LAYOUT_REFR,
43     [LV_STYLE_MIN_HEIGHT] =               LV_STYLE_PROP_LAYOUT_REFR,
44     [LV_STYLE_MAX_HEIGHT] =               LV_STYLE_PROP_LAYOUT_REFR,
45     [LV_STYLE_X] =                        LV_STYLE_PROP_LAYOUT_REFR,
46     [LV_STYLE_Y] =                        LV_STYLE_PROP_LAYOUT_REFR,
47     [LV_STYLE_ALIGN] =                    LV_STYLE_PROP_LAYOUT_REFR,
48     [LV_STYLE_TRANSFORM_WIDTH] =           LV_STYLE_PROP_EXT_DRAW,
49     [LV_STYLE_TRANSFORM_HEIGHT] =          LV_STYLE_PROP_EXT_DRAW,
50     [LV_STYLE_TRANSLATE_X] =               LV_STYLE_PROP_LAYOUT_REFR | LV_STYLE_PROP_PARENT_LAYOUT_REFR,
51     [LV_STYLE_TRANSLATE_Y] =               LV_STYLE_PROP_LAYOUT_REFR | LV_STYLE_PROP_PARENT_LAYOUT_REFR,
52     [LV_STYLE_TRANSFORM_ZOOM] =            LV_STYLE_PROP_EXT_DRAW | LV_STYLE_PROP_LAYER_REFR,
53     [LV_STYLE_TRANSFORM_ANGLE] =           LV_STYLE_PROP_EXT_DRAW | LV_STYLE_PROP_LAYER_REFR,
54 
55     [LV_STYLE_PAD_TOP] =                   LV_STYLE_PROP_EXT_DRAW | LV_STYLE_PROP_LAYOUT_REFR,
56     [LV_STYLE_PAD_BOTTOM] =                LV_STYLE_PROP_EXT_DRAW | LV_STYLE_PROP_LAYOUT_REFR,
57     [LV_STYLE_PAD_LEFT] =                  LV_STYLE_PROP_EXT_DRAW | LV_STYLE_PROP_LAYOUT_REFR,
58     [LV_STYLE_PAD_RIGHT] =                 LV_STYLE_PROP_EXT_DRAW | LV_STYLE_PROP_LAYOUT_REFR,
59     [LV_STYLE_PAD_ROW] =                   LV_STYLE_PROP_EXT_DRAW | LV_STYLE_PROP_LAYOUT_REFR,
60     [LV_STYLE_PAD_COLUMN] =                LV_STYLE_PROP_EXT_DRAW | LV_STYLE_PROP_LAYOUT_REFR,
61 
62     [LV_STYLE_BG_COLOR] = 0,
63     [LV_STYLE_BG_OPA] = 0,
64     [LV_STYLE_BG_GRAD_COLOR] = 0,
65     [LV_STYLE_BG_GRAD_DIR] = 0,
66     [LV_STYLE_BG_MAIN_STOP] = 0,
67     [LV_STYLE_BG_GRAD_STOP] = 0,
68     [LV_STYLE_BG_GRAD] = 0,
69     [LV_STYLE_BG_DITHER_MODE] = 0,
70 
71     [LV_STYLE_BG_IMG_SRC] =                LV_STYLE_PROP_EXT_DRAW,
72     [LV_STYLE_BG_IMG_OPA] = 0,
73     [LV_STYLE_BG_IMG_RECOLOR] = 0,
74     [LV_STYLE_BG_IMG_RECOLOR_OPA] = 0,
75     [LV_STYLE_BG_IMG_TILED] = 0,
76 
77     [LV_STYLE_BORDER_COLOR] = 0,
78     [LV_STYLE_BORDER_OPA] = 0,
79     [LV_STYLE_BORDER_WIDTH] =              LV_STYLE_PROP_LAYOUT_REFR,
80     [LV_STYLE_BORDER_SIDE] = 0,
81     [LV_STYLE_BORDER_POST] = 0,
82 
83     [LV_STYLE_OUTLINE_WIDTH] =             LV_STYLE_PROP_EXT_DRAW,
84     [LV_STYLE_OUTLINE_COLOR] = 0,
85     [LV_STYLE_OUTLINE_OPA] =               LV_STYLE_PROP_EXT_DRAW,
86     [LV_STYLE_OUTLINE_PAD] =               LV_STYLE_PROP_EXT_DRAW,
87 
88     [LV_STYLE_SHADOW_WIDTH] =              LV_STYLE_PROP_EXT_DRAW,
89     [LV_STYLE_SHADOW_OFS_X] =              LV_STYLE_PROP_EXT_DRAW,
90     [LV_STYLE_SHADOW_OFS_Y] =              LV_STYLE_PROP_EXT_DRAW,
91     [LV_STYLE_SHADOW_SPREAD] =             LV_STYLE_PROP_EXT_DRAW,
92     [LV_STYLE_SHADOW_COLOR] = 0,
93     [LV_STYLE_SHADOW_OPA] =                LV_STYLE_PROP_EXT_DRAW,
94 
95     [LV_STYLE_IMG_OPA] = 0,
96     [LV_STYLE_IMG_RECOLOR] = 0,
97     [LV_STYLE_IMG_RECOLOR_OPA] = 0,
98 
99     [LV_STYLE_LINE_WIDTH] =                LV_STYLE_PROP_EXT_DRAW,
100     [LV_STYLE_LINE_DASH_WIDTH] = 0,
101     [LV_STYLE_LINE_DASH_GAP] = 0,
102     [LV_STYLE_LINE_ROUNDED] = 0,
103     [LV_STYLE_LINE_COLOR] = 0,
104     [LV_STYLE_LINE_OPA] = 0,
105 
106     [LV_STYLE_ARC_WIDTH] =                 LV_STYLE_PROP_EXT_DRAW,
107     [LV_STYLE_ARC_ROUNDED] = 0,
108     [LV_STYLE_ARC_COLOR] = 0,
109     [LV_STYLE_ARC_OPA] = 0,
110     [LV_STYLE_ARC_IMG_SRC] = 0,
111 
112     [LV_STYLE_TEXT_COLOR] =                LV_STYLE_PROP_INHERIT,
113     [LV_STYLE_TEXT_OPA] =                  LV_STYLE_PROP_INHERIT,
114     [LV_STYLE_TEXT_FONT] =                 LV_STYLE_PROP_INHERIT | LV_STYLE_PROP_LAYOUT_REFR,
115     [LV_STYLE_TEXT_LETTER_SPACE] =         LV_STYLE_PROP_INHERIT | LV_STYLE_PROP_LAYOUT_REFR,
116     [LV_STYLE_TEXT_LINE_SPACE] =           LV_STYLE_PROP_INHERIT | LV_STYLE_PROP_LAYOUT_REFR,
117     [LV_STYLE_TEXT_DECOR] =                LV_STYLE_PROP_INHERIT,
118     [LV_STYLE_TEXT_ALIGN] =                LV_STYLE_PROP_INHERIT | LV_STYLE_PROP_LAYOUT_REFR,
119 
120     [LV_STYLE_RADIUS] = 0,
121     [LV_STYLE_CLIP_CORNER] = 0,
122     [LV_STYLE_OPA] =                       0,
123     [LV_STYLE_OPA_LAYERED] =               LV_STYLE_PROP_LAYER_REFR,
124     [LV_STYLE_COLOR_FILTER_DSC] =          LV_STYLE_PROP_INHERIT,
125     [LV_STYLE_COLOR_FILTER_OPA] =          LV_STYLE_PROP_INHERIT,
126     [LV_STYLE_ANIM_TIME] = 0,
127     [LV_STYLE_ANIM_SPEED] = 0,
128     [LV_STYLE_TRANSITION] = 0,
129     [LV_STYLE_BLEND_MODE] =                LV_STYLE_PROP_LAYER_REFR,
130     [LV_STYLE_LAYOUT] =                    LV_STYLE_PROP_LAYOUT_REFR,
131     [LV_STYLE_BASE_DIR] =                  LV_STYLE_PROP_INHERIT | LV_STYLE_PROP_LAYOUT_REFR,
132 };
133 
134 uint32_t _lv_style_custom_prop_flag_lookup_table_size = 0;
135 
136 /**********************
137  *  STATIC VARIABLES
138  **********************/
139 
140 static uint16_t last_custom_prop_id = (uint16_t)_LV_STYLE_LAST_BUILT_IN_PROP;
141 static const lv_style_value_t null_style_value = { .num = 0 };
142 
143 /**********************
144  *      MACROS
145  **********************/
146 
147 /**********************
148  *   GLOBAL FUNCTIONS
149  **********************/
150 
lv_style_init(lv_style_t * style)151 void lv_style_init(lv_style_t * style)
152 {
153 #if LV_USE_ASSERT_STYLE
154     if(style->sentinel == LV_STYLE_SENTINEL_VALUE && style->prop_cnt > 1) {
155         LV_LOG_WARN("Style might be already inited. (Potential memory leak)");
156     }
157 #endif
158 
159     lv_memset_00(style, sizeof(lv_style_t));
160 #if LV_USE_ASSERT_STYLE
161     style->sentinel = LV_STYLE_SENTINEL_VALUE;
162 #endif
163 }
164 
lv_style_reset(lv_style_t * style)165 void lv_style_reset(lv_style_t * style)
166 {
167     LV_ASSERT_STYLE(style);
168 
169     if(style->prop1 == LV_STYLE_PROP_ANY) {
170         LV_LOG_ERROR("Cannot reset const style");
171         return;
172     }
173 
174     if(style->prop_cnt > 1) lv_mem_free(style->v_p.values_and_props);
175     lv_memset_00(style, sizeof(lv_style_t));
176 #if LV_USE_ASSERT_STYLE
177     style->sentinel = LV_STYLE_SENTINEL_VALUE;
178 #endif
179 }
180 
lv_style_register_prop(uint8_t flag)181 lv_style_prop_t lv_style_register_prop(uint8_t flag)
182 {
183     if(LV_GC_ROOT(_lv_style_custom_prop_flag_lookup_table) == NULL) {
184         _lv_style_custom_prop_flag_lookup_table_size = 0;
185         last_custom_prop_id = (uint16_t)_LV_STYLE_LAST_BUILT_IN_PROP;
186     }
187 
188     if(((last_custom_prop_id + 1) & LV_STYLE_PROP_META_MASK) != 0) {
189         LV_LOG_ERROR("No more custom property IDs available");
190         return LV_STYLE_PROP_INV;
191     }
192 
193     /*
194      * Allocate the lookup table if it's not yet available.
195      */
196     size_t required_size = (last_custom_prop_id + 1 - _LV_STYLE_LAST_BUILT_IN_PROP);
197     if(_lv_style_custom_prop_flag_lookup_table_size < required_size) {
198         /* Round required_size up to the nearest 32-byte value */
199         required_size = (required_size + 31) & ~31;
200         LV_ASSERT_MSG(required_size > 0, "required size has become 0?");
201         uint8_t * old_p = LV_GC_ROOT(_lv_style_custom_prop_flag_lookup_table);
202         uint8_t * new_p = lv_mem_realloc(old_p, required_size * sizeof(uint8_t));
203         if(new_p == NULL) {
204             LV_LOG_ERROR("Unable to allocate space for custom property lookup table");
205             return LV_STYLE_PROP_INV;
206         }
207         LV_GC_ROOT(_lv_style_custom_prop_flag_lookup_table) = new_p;
208         _lv_style_custom_prop_flag_lookup_table_size = required_size;
209     }
210     last_custom_prop_id++;
211     /* This should never happen - we should bail out above */
212     LV_ASSERT_NULL(LV_GC_ROOT(_lv_style_custom_prop_flag_lookup_table));
213     LV_GC_ROOT(_lv_style_custom_prop_flag_lookup_table)[last_custom_prop_id - _LV_STYLE_NUM_BUILT_IN_PROPS] = flag;
214     return last_custom_prop_id;
215 }
216 
lv_style_get_num_custom_props(void)217 lv_style_prop_t lv_style_get_num_custom_props(void)
218 {
219     return last_custom_prop_id - _LV_STYLE_LAST_BUILT_IN_PROP;
220 }
221 
lv_style_remove_prop(lv_style_t * style,lv_style_prop_t prop)222 bool lv_style_remove_prop(lv_style_t * style, lv_style_prop_t prop)
223 {
224     LV_ASSERT_STYLE(style);
225 
226     if(style->prop1 == LV_STYLE_PROP_ANY) {
227         LV_LOG_ERROR("Cannot remove prop from const style");
228         return false;
229     }
230 
231     if(style->prop_cnt == 0)  return false;
232 
233     if(style->prop_cnt == 1) {
234         if(LV_STYLE_PROP_ID_MASK(style->prop1) == prop) {
235             style->prop1 = LV_STYLE_PROP_INV;
236             style->prop_cnt = 0;
237             return true;
238         }
239         return false;
240     }
241 
242     uint8_t * tmp = style->v_p.values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
243     uint16_t * old_props = (uint16_t *)tmp;
244     uint32_t i;
245     for(i = 0; i < style->prop_cnt; i++) {
246         if(LV_STYLE_PROP_ID_MASK(old_props[i]) == prop) {
247             lv_style_value_t * old_values = (lv_style_value_t *)style->v_p.values_and_props;
248 
249             if(style->prop_cnt == 2) {
250                 style->prop_cnt = 1;
251                 style->prop1 = i == 0 ? old_props[1] : old_props[0];
252                 style->v_p.value1 = i == 0 ? old_values[1] : old_values[0];
253             }
254             else {
255                 size_t size = (style->prop_cnt - 1) * (sizeof(lv_style_value_t) + sizeof(uint16_t));
256                 uint8_t * new_values_and_props = lv_mem_alloc(size);
257                 if(new_values_and_props == NULL) return false;
258                 style->v_p.values_and_props = new_values_and_props;
259                 style->prop_cnt--;
260 
261                 tmp = new_values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
262                 uint16_t * new_props = (uint16_t *)tmp;
263                 lv_style_value_t * new_values = (lv_style_value_t *)new_values_and_props;
264 
265                 uint32_t j;
266                 for(i = j = 0; j <= style->prop_cnt;
267                     j++) { /*<=: because prop_cnt already reduced but all the old props. needs to be checked.*/
268                     if(old_props[j] != prop) {
269                         new_values[i] = old_values[j];
270                         new_props[i++] = old_props[j];
271                     }
272                 }
273             }
274 
275             lv_mem_free(old_values);
276             return true;
277         }
278     }
279 
280     return false;
281 }
282 
lv_style_set_prop(lv_style_t * style,lv_style_prop_t prop,lv_style_value_t value)283 void lv_style_set_prop(lv_style_t * style, lv_style_prop_t prop, lv_style_value_t value)
284 {
285     lv_style_set_prop_internal(style, prop, value, lv_style_set_prop_helper);
286 }
287 
lv_style_set_prop_meta(lv_style_t * style,lv_style_prop_t prop,uint16_t meta)288 void lv_style_set_prop_meta(lv_style_t * style, lv_style_prop_t prop, uint16_t meta)
289 {
290     lv_style_set_prop_internal(style, prop | meta, null_style_value, lv_style_set_prop_meta_helper);
291 }
292 
lv_style_get_prop(const lv_style_t * style,lv_style_prop_t prop,lv_style_value_t * value)293 lv_style_res_t lv_style_get_prop(const lv_style_t * style, lv_style_prop_t prop, lv_style_value_t * value)
294 {
295     return lv_style_get_prop_inlined(style, prop, value);
296 }
297 
lv_style_transition_dsc_init(lv_style_transition_dsc_t * tr,const lv_style_prop_t props[],lv_anim_path_cb_t path_cb,uint32_t time,uint32_t delay,void * user_data)298 void lv_style_transition_dsc_init(lv_style_transition_dsc_t * tr, const lv_style_prop_t props[],
299                                   lv_anim_path_cb_t path_cb, uint32_t time, uint32_t delay, void * user_data)
300 {
301     lv_memset_00(tr, sizeof(lv_style_transition_dsc_t));
302     tr->props = props;
303     tr->path_xcb = path_cb == NULL ? lv_anim_path_linear : path_cb;
304     tr->time = time;
305     tr->delay = delay;
306 #if LV_USE_USER_DATA
307     tr->user_data = user_data;
308 #else
309     LV_UNUSED(user_data);
310 #endif
311 }
312 
lv_style_prop_get_default(lv_style_prop_t prop)313 lv_style_value_t lv_style_prop_get_default(lv_style_prop_t prop)
314 {
315     lv_style_value_t value;
316     switch(prop) {
317         case LV_STYLE_TRANSFORM_ZOOM:
318             value.num = LV_IMG_ZOOM_NONE;
319             break;
320         case LV_STYLE_BG_COLOR:
321             value.color = lv_color_white();
322             break;
323         case LV_STYLE_BG_GRAD_COLOR:
324         case LV_STYLE_BORDER_COLOR:
325         case LV_STYLE_SHADOW_COLOR:
326         case LV_STYLE_OUTLINE_COLOR:
327         case LV_STYLE_ARC_COLOR:
328         case LV_STYLE_LINE_COLOR:
329         case LV_STYLE_TEXT_COLOR:
330         case LV_STYLE_IMG_RECOLOR:
331             value.color = lv_color_black();
332             break;
333         case LV_STYLE_OPA:
334         case LV_STYLE_OPA_LAYERED:
335         case LV_STYLE_BORDER_OPA:
336         case LV_STYLE_TEXT_OPA:
337         case LV_STYLE_IMG_OPA:
338         case LV_STYLE_BG_IMG_OPA:
339         case LV_STYLE_OUTLINE_OPA:
340         case LV_STYLE_SHADOW_OPA:
341         case LV_STYLE_LINE_OPA:
342         case LV_STYLE_ARC_OPA:
343             value.num = LV_OPA_COVER;
344             break;
345         case LV_STYLE_BG_GRAD_STOP:
346             value.num = 255;
347             break;
348         case LV_STYLE_BORDER_SIDE:
349             value.num = LV_BORDER_SIDE_FULL;
350             break;
351         case LV_STYLE_TEXT_FONT:
352             value.ptr = LV_FONT_DEFAULT;
353             break;
354         case LV_STYLE_MAX_WIDTH:
355         case LV_STYLE_MAX_HEIGHT:
356             value.num = LV_COORD_MAX;
357             break;
358         default:
359             value.ptr = NULL;
360             value.num = 0;
361             break;
362     }
363 
364     return value;
365 }
366 
lv_style_is_empty(const lv_style_t * style)367 bool lv_style_is_empty(const lv_style_t * style)
368 {
369     LV_ASSERT_STYLE(style);
370 
371     return style->prop_cnt == 0 ? true : false;
372 }
373 
_lv_style_get_prop_group(lv_style_prop_t prop)374 uint8_t _lv_style_get_prop_group(lv_style_prop_t prop)
375 {
376     uint16_t group = (prop & 0x1FF) >> 4;
377     if(group > 7) group = 7;    /*The MSB marks all the custom properties*/
378     return (uint8_t)group;
379 }
380 
_lv_style_prop_lookup_flags(lv_style_prop_t prop)381 uint8_t _lv_style_prop_lookup_flags(lv_style_prop_t prop)
382 {
383     extern const uint8_t _lv_style_builtin_prop_flag_lookup_table[];
384     extern uint32_t _lv_style_custom_prop_flag_lookup_table_size;
385     if(prop == LV_STYLE_PROP_ANY) return LV_STYLE_PROP_ALL; /*Any prop can have any flags*/
386     if(prop == LV_STYLE_PROP_INV) return 0;
387 
388     if(prop < _LV_STYLE_NUM_BUILT_IN_PROPS)
389         return _lv_style_builtin_prop_flag_lookup_table[prop];
390     prop -= _LV_STYLE_NUM_BUILT_IN_PROPS;
391     if(LV_GC_ROOT(_lv_style_custom_prop_flag_lookup_table) != NULL && prop < _lv_style_custom_prop_flag_lookup_table_size)
392         return LV_GC_ROOT(_lv_style_custom_prop_flag_lookup_table)[prop];
393     return 0;
394 }
395 
396 /**********************
397  *   STATIC FUNCTIONS
398  **********************/
399 
lv_style_set_prop_helper(lv_style_prop_t prop,lv_style_value_t value,uint16_t * prop_storage,lv_style_value_t * value_storage)400 static void lv_style_set_prop_helper(lv_style_prop_t prop, lv_style_value_t value, uint16_t * prop_storage,
401                                      lv_style_value_t * value_storage)
402 {
403     *prop_storage = prop;
404     *value_storage = value;
405 }
406 
lv_style_set_prop_meta_helper(lv_style_prop_t prop,lv_style_value_t value,uint16_t * prop_storage,lv_style_value_t * value_storage)407 static void lv_style_set_prop_meta_helper(lv_style_prop_t prop, lv_style_value_t value, uint16_t * prop_storage,
408                                           lv_style_value_t * value_storage)
409 {
410     LV_UNUSED(value);
411     LV_UNUSED(value_storage);
412     *prop_storage = prop; /* meta is OR-ed into the prop ID already */
413 }
414 
lv_style_set_prop_internal(lv_style_t * style,lv_style_prop_t prop_and_meta,lv_style_value_t value,void (* value_adjustment_helper)(lv_style_prop_t,lv_style_value_t,uint16_t *,lv_style_value_t *))415 static void lv_style_set_prop_internal(lv_style_t * style, lv_style_prop_t prop_and_meta, lv_style_value_t value,
416                                        void (*value_adjustment_helper)(lv_style_prop_t, lv_style_value_t, uint16_t *, lv_style_value_t *))
417 {
418     LV_ASSERT_STYLE(style);
419 
420     if(style->prop1 == LV_STYLE_PROP_ANY) {
421         LV_LOG_ERROR("Cannot set property of constant style");
422         return;
423     }
424 
425     lv_style_prop_t prop_id = LV_STYLE_PROP_ID_MASK(prop_and_meta);
426 
427     if(style->prop_cnt > 1) {
428         uint8_t * tmp = style->v_p.values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
429         uint16_t * props = (uint16_t *)tmp;
430         int32_t i;
431         for(i = style->prop_cnt - 1; i >= 0; i--) {
432             if(LV_STYLE_PROP_ID_MASK(props[i]) == prop_id) {
433                 lv_style_value_t * values = (lv_style_value_t *)style->v_p.values_and_props;
434                 value_adjustment_helper(prop_and_meta, value, &props[i], &values[i]);
435                 return;
436             }
437         }
438 
439         size_t size = (style->prop_cnt + 1) * (sizeof(lv_style_value_t) + sizeof(uint16_t));
440         uint8_t * values_and_props = lv_mem_realloc(style->v_p.values_and_props, size);
441         if(values_and_props == NULL) return;
442         style->v_p.values_and_props = values_and_props;
443 
444         tmp = values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
445         props = (uint16_t *)tmp;
446         /*Shift all props to make place for the value before them*/
447         for(i = style->prop_cnt - 1; i >= 0; i--) {
448             props[i + sizeof(lv_style_value_t) / sizeof(uint16_t)] = props[i];
449         }
450         style->prop_cnt++;
451 
452         /*Go to the new position wit the props*/
453         tmp = values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
454         props = (uint16_t *)tmp;
455         lv_style_value_t * values = (lv_style_value_t *)values_and_props;
456 
457         /*Set the new property and value*/
458         value_adjustment_helper(prop_and_meta, value, &props[style->prop_cnt - 1], &values[style->prop_cnt - 1]);
459     }
460     else if(style->prop_cnt == 1) {
461         if(LV_STYLE_PROP_ID_MASK(style->prop1) == prop_id) {
462             value_adjustment_helper(prop_and_meta, value, &style->prop1, &style->v_p.value1);
463             return;
464         }
465         size_t size = (style->prop_cnt + 1) * (sizeof(lv_style_value_t) + sizeof(uint16_t));
466         uint8_t * values_and_props = lv_mem_alloc(size);
467         if(values_and_props == NULL) return;
468         lv_style_value_t value_tmp = style->v_p.value1;
469         style->v_p.values_and_props = values_and_props;
470         style->prop_cnt++;
471 
472         uint8_t * tmp = values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
473         uint16_t * props = (uint16_t *)tmp;
474         lv_style_value_t * values = (lv_style_value_t *)values_and_props;
475         props[0] = style->prop1;
476         values[0] = value_tmp;
477         value_adjustment_helper(prop_and_meta, value, &props[1], &values[1]);
478     }
479     else {
480         style->prop_cnt = 1;
481         value_adjustment_helper(prop_and_meta, value, &style->prop1, &style->v_p.value1);
482     }
483 
484     uint8_t group = _lv_style_get_prop_group(prop_id);
485     style->has_group |= 1 << group;
486 }
487 
488