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] = LV_STYLE_PROP_LAYER_REFR,
123 [LV_STYLE_COLOR_FILTER_DSC] = LV_STYLE_PROP_INHERIT,
124 [LV_STYLE_COLOR_FILTER_OPA] = LV_STYLE_PROP_INHERIT,
125 [LV_STYLE_ANIM_TIME] = 0,
126 [LV_STYLE_ANIM_SPEED] = 0,
127 [LV_STYLE_TRANSITION] = 0,
128 [LV_STYLE_BLEND_MODE] = LV_STYLE_PROP_LAYER_REFR,
129 [LV_STYLE_LAYOUT] = LV_STYLE_PROP_LAYOUT_REFR,
130 [LV_STYLE_BASE_DIR] = LV_STYLE_PROP_INHERIT | LV_STYLE_PROP_LAYOUT_REFR,
131 };
132
133 uint32_t _lv_style_custom_prop_flag_lookup_table_size = 0;
134
135 /**********************
136 * STATIC VARIABLES
137 **********************/
138
139 static uint16_t last_custom_prop_id = (uint16_t)_LV_STYLE_LAST_BUILT_IN_PROP;
140 static const lv_style_value_t null_style_value = { .num = 0 };
141
142 /**********************
143 * MACROS
144 **********************/
145
146 /**********************
147 * GLOBAL FUNCTIONS
148 **********************/
149
lv_style_init(lv_style_t * style)150 void lv_style_init(lv_style_t * style)
151 {
152 #if LV_USE_ASSERT_STYLE
153 if(style->sentinel == LV_STYLE_SENTINEL_VALUE && style->prop_cnt > 1) {
154 LV_LOG_WARN("Style might be already inited. (Potential memory leak)");
155 }
156 #endif
157
158 lv_memset_00(style, sizeof(lv_style_t));
159 #if LV_USE_ASSERT_STYLE
160 style->sentinel = LV_STYLE_SENTINEL_VALUE;
161 #endif
162 }
163
lv_style_reset(lv_style_t * style)164 void lv_style_reset(lv_style_t * style)
165 {
166 LV_ASSERT_STYLE(style);
167
168 if(style->prop1 == LV_STYLE_PROP_ANY) {
169 LV_LOG_ERROR("Cannot reset const style");
170 return;
171 }
172
173 if(style->prop_cnt > 1) lv_mem_free(style->v_p.values_and_props);
174 lv_memset_00(style, sizeof(lv_style_t));
175 #if LV_USE_ASSERT_STYLE
176 style->sentinel = LV_STYLE_SENTINEL_VALUE;
177 #endif
178 }
179
lv_style_register_prop(uint8_t flag)180 lv_style_prop_t lv_style_register_prop(uint8_t flag)
181 {
182 if(LV_GC_ROOT(_lv_style_custom_prop_flag_lookup_table) == NULL) {
183 _lv_style_custom_prop_flag_lookup_table_size = 0;
184 last_custom_prop_id = (uint16_t)_LV_STYLE_LAST_BUILT_IN_PROP;
185 }
186
187 if(((last_custom_prop_id + 1) & LV_STYLE_PROP_META_MASK) != 0) {
188 LV_LOG_ERROR("No more custom property IDs available");
189 return LV_STYLE_PROP_INV;
190 }
191
192 /*
193 * Allocate the lookup table if it's not yet available.
194 */
195 size_t required_size = (last_custom_prop_id + 1 - _LV_STYLE_LAST_BUILT_IN_PROP);
196 if(_lv_style_custom_prop_flag_lookup_table_size < required_size) {
197 /* Round required_size up to the nearest 32-byte value */
198 required_size = (required_size + 31) & ~31;
199 LV_ASSERT_MSG(required_size > 0, "required size has become 0?");
200 uint8_t * old_p = LV_GC_ROOT(_lv_style_custom_prop_flag_lookup_table);
201 uint8_t * new_p = lv_mem_realloc(old_p, required_size * sizeof(uint8_t));
202 if(new_p == NULL) {
203 LV_LOG_ERROR("Unable to allocate space for custom property lookup table");
204 return LV_STYLE_PROP_INV;
205 }
206 LV_GC_ROOT(_lv_style_custom_prop_flag_lookup_table) = new_p;
207 _lv_style_custom_prop_flag_lookup_table_size = required_size;
208 }
209 last_custom_prop_id++;
210 /* This should never happen - we should bail out above */
211 LV_ASSERT_NULL(LV_GC_ROOT(_lv_style_custom_prop_flag_lookup_table));
212 LV_GC_ROOT(_lv_style_custom_prop_flag_lookup_table)[last_custom_prop_id - _LV_STYLE_NUM_BUILT_IN_PROPS] = flag;
213 return last_custom_prop_id;
214 }
215
lv_style_get_num_custom_props(void)216 lv_style_prop_t lv_style_get_num_custom_props(void)
217 {
218 return last_custom_prop_id - _LV_STYLE_LAST_BUILT_IN_PROP;
219 }
220
lv_style_remove_prop(lv_style_t * style,lv_style_prop_t prop)221 bool lv_style_remove_prop(lv_style_t * style, lv_style_prop_t prop)
222 {
223 LV_ASSERT_STYLE(style);
224
225 if(style->prop1 == LV_STYLE_PROP_ANY) {
226 LV_LOG_ERROR("Cannot remove prop from const style");
227 return false;
228 }
229
230 if(style->prop_cnt == 0) return false;
231
232 if(style->prop_cnt == 1) {
233 if(LV_STYLE_PROP_ID_MASK(style->prop1) == prop) {
234 style->prop1 = LV_STYLE_PROP_INV;
235 style->prop_cnt = 0;
236 return true;
237 }
238 return false;
239 }
240
241 uint8_t * tmp = style->v_p.values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
242 uint16_t * old_props = (uint16_t *)tmp;
243 uint32_t i;
244 for(i = 0; i < style->prop_cnt; i++) {
245 if(LV_STYLE_PROP_ID_MASK(old_props[i]) == prop) {
246 lv_style_value_t * old_values = (lv_style_value_t *)style->v_p.values_and_props;
247
248 if(style->prop_cnt == 2) {
249 style->prop_cnt = 1;
250 style->prop1 = i == 0 ? old_props[1] : old_props[0];
251 style->v_p.value1 = i == 0 ? old_values[1] : old_values[0];
252 }
253 else {
254 size_t size = (style->prop_cnt - 1) * (sizeof(lv_style_value_t) + sizeof(uint16_t));
255 uint8_t * new_values_and_props = lv_mem_alloc(size);
256 if(new_values_and_props == NULL) return false;
257 style->v_p.values_and_props = new_values_and_props;
258 style->prop_cnt--;
259
260 tmp = new_values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
261 uint16_t * new_props = (uint16_t *)tmp;
262 lv_style_value_t * new_values = (lv_style_value_t *)new_values_and_props;
263
264 uint32_t j;
265 for(i = j = 0; j <= style->prop_cnt;
266 j++) { /*<=: because prop_cnt already reduced but all the old props. needs to be checked.*/
267 if(old_props[j] != prop) {
268 new_values[i] = old_values[j];
269 new_props[i++] = old_props[j];
270 }
271 }
272 }
273
274 lv_mem_free(old_values);
275 return true;
276 }
277 }
278
279 return false;
280 }
281
lv_style_set_prop(lv_style_t * style,lv_style_prop_t prop,lv_style_value_t value)282 void lv_style_set_prop(lv_style_t * style, lv_style_prop_t prop, lv_style_value_t value)
283 {
284 lv_style_set_prop_internal(style, prop, value, lv_style_set_prop_helper);
285 }
286
lv_style_set_prop_meta(lv_style_t * style,lv_style_prop_t prop,uint16_t meta)287 void lv_style_set_prop_meta(lv_style_t * style, lv_style_prop_t prop, uint16_t meta)
288 {
289 lv_style_set_prop_internal(style, prop | meta, null_style_value, lv_style_set_prop_meta_helper);
290 }
291
lv_style_get_prop(const lv_style_t * style,lv_style_prop_t prop,lv_style_value_t * value)292 lv_style_res_t lv_style_get_prop(const lv_style_t * style, lv_style_prop_t prop, lv_style_value_t * value)
293 {
294 return lv_style_get_prop_inlined(style, prop, value);
295 }
296
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)297 void lv_style_transition_dsc_init(lv_style_transition_dsc_t * tr, const lv_style_prop_t props[],
298 lv_anim_path_cb_t path_cb, uint32_t time, uint32_t delay, void * user_data)
299 {
300 lv_memset_00(tr, sizeof(lv_style_transition_dsc_t));
301 tr->props = props;
302 tr->path_xcb = path_cb == NULL ? lv_anim_path_linear : path_cb;
303 tr->time = time;
304 tr->delay = delay;
305 #if LV_USE_USER_DATA
306 tr->user_data = user_data;
307 #else
308 LV_UNUSED(user_data);
309 #endif
310 }
311
lv_style_prop_get_default(lv_style_prop_t prop)312 lv_style_value_t lv_style_prop_get_default(lv_style_prop_t prop)
313 {
314 lv_style_value_t value;
315 switch(prop) {
316 case LV_STYLE_TRANSFORM_ZOOM:
317 value.num = LV_IMG_ZOOM_NONE;
318 break;
319 case LV_STYLE_BG_COLOR:
320 value.color = lv_color_white();
321 break;
322 case LV_STYLE_BG_GRAD_COLOR:
323 case LV_STYLE_BORDER_COLOR:
324 case LV_STYLE_SHADOW_COLOR:
325 case LV_STYLE_OUTLINE_COLOR:
326 case LV_STYLE_ARC_COLOR:
327 case LV_STYLE_LINE_COLOR:
328 case LV_STYLE_TEXT_COLOR:
329 case LV_STYLE_IMG_RECOLOR:
330 value.color = lv_color_black();
331 break;
332 case LV_STYLE_OPA:
333 case LV_STYLE_BORDER_OPA:
334 case LV_STYLE_TEXT_OPA:
335 case LV_STYLE_IMG_OPA:
336 case LV_STYLE_BG_IMG_OPA:
337 case LV_STYLE_OUTLINE_OPA:
338 case LV_STYLE_SHADOW_OPA:
339 case LV_STYLE_LINE_OPA:
340 case LV_STYLE_ARC_OPA:
341 value.num = LV_OPA_COVER;
342 break;
343 case LV_STYLE_BG_GRAD_STOP:
344 value.num = 255;
345 break;
346 case LV_STYLE_BORDER_SIDE:
347 value.num = LV_BORDER_SIDE_FULL;
348 break;
349 case LV_STYLE_TEXT_FONT:
350 value.ptr = LV_FONT_DEFAULT;
351 break;
352 case LV_STYLE_MAX_WIDTH:
353 case LV_STYLE_MAX_HEIGHT:
354 value.num = LV_COORD_MAX;
355 break;
356 default:
357 value.ptr = NULL;
358 value.num = 0;
359 break;
360 }
361
362 return value;
363 }
364
lv_style_is_empty(const lv_style_t * style)365 bool lv_style_is_empty(const lv_style_t * style)
366 {
367 LV_ASSERT_STYLE(style);
368
369 return style->prop_cnt == 0 ? true : false;
370 }
371
_lv_style_get_prop_group(lv_style_prop_t prop)372 uint8_t _lv_style_get_prop_group(lv_style_prop_t prop)
373 {
374 uint16_t group = (prop & 0x1FF) >> 4;
375 if(group > 7) group = 7; /*The MSB marks all the custom properties*/
376 return (uint8_t)group;
377 }
378
_lv_style_prop_lookup_flags(lv_style_prop_t prop)379 uint8_t _lv_style_prop_lookup_flags(lv_style_prop_t prop)
380 {
381 extern const uint8_t _lv_style_builtin_prop_flag_lookup_table[];
382 extern uint32_t _lv_style_custom_prop_flag_lookup_table_size;
383 if(prop == LV_STYLE_PROP_ANY) return LV_STYLE_PROP_ALL; /*Any prop can have any flags*/
384 if(prop == LV_STYLE_PROP_INV) return 0;
385
386 if(prop < _LV_STYLE_NUM_BUILT_IN_PROPS)
387 return _lv_style_builtin_prop_flag_lookup_table[prop];
388 prop -= _LV_STYLE_NUM_BUILT_IN_PROPS;
389 if(LV_GC_ROOT(_lv_style_custom_prop_flag_lookup_table) != NULL && prop < _lv_style_custom_prop_flag_lookup_table_size)
390 return LV_GC_ROOT(_lv_style_custom_prop_flag_lookup_table)[prop];
391 return 0;
392 }
393
394 /**********************
395 * STATIC FUNCTIONS
396 **********************/
397
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)398 static void lv_style_set_prop_helper(lv_style_prop_t prop, lv_style_value_t value, uint16_t * prop_storage,
399 lv_style_value_t * value_storage)
400 {
401 *prop_storage = prop;
402 *value_storage = value;
403 }
404
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)405 static void lv_style_set_prop_meta_helper(lv_style_prop_t prop, lv_style_value_t value, uint16_t * prop_storage,
406 lv_style_value_t * value_storage)
407 {
408 LV_UNUSED(value);
409 LV_UNUSED(value_storage);
410 *prop_storage = prop; /* meta is OR-ed into the prop ID already */
411 }
412
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 *))413 static void lv_style_set_prop_internal(lv_style_t * style, lv_style_prop_t prop_and_meta, lv_style_value_t value,
414 void (*value_adjustment_helper)(lv_style_prop_t, lv_style_value_t, uint16_t *, lv_style_value_t *))
415 {
416 LV_ASSERT_STYLE(style);
417
418 if(style->prop1 == LV_STYLE_PROP_ANY) {
419 LV_LOG_ERROR("Cannot set property of constant style");
420 return;
421 }
422
423 lv_style_prop_t prop_id = LV_STYLE_PROP_ID_MASK(prop_and_meta);
424
425 if(style->prop_cnt > 1) {
426 uint8_t * tmp = style->v_p.values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
427 uint16_t * props = (uint16_t *)tmp;
428 int32_t i;
429 for(i = style->prop_cnt - 1; i >= 0; i--) {
430 if(LV_STYLE_PROP_ID_MASK(props[i]) == prop_id) {
431 lv_style_value_t * values = (lv_style_value_t *)style->v_p.values_and_props;
432 value_adjustment_helper(prop_and_meta, value, &props[i], &values[i]);
433 return;
434 }
435 }
436
437 size_t size = (style->prop_cnt + 1) * (sizeof(lv_style_value_t) + sizeof(uint16_t));
438 uint8_t * values_and_props = lv_mem_realloc(style->v_p.values_and_props, size);
439 if(values_and_props == NULL) return;
440 style->v_p.values_and_props = values_and_props;
441
442 tmp = values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
443 props = (uint16_t *)tmp;
444 /*Shift all props to make place for the value before them*/
445 for(i = style->prop_cnt - 1; i >= 0; i--) {
446 props[i + sizeof(lv_style_value_t) / sizeof(uint16_t)] = props[i];
447 }
448 style->prop_cnt++;
449
450 /*Go to the new position wit the props*/
451 tmp = values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
452 props = (uint16_t *)tmp;
453 lv_style_value_t * values = (lv_style_value_t *)values_and_props;
454
455 /*Set the new property and value*/
456 value_adjustment_helper(prop_and_meta, value, &props[style->prop_cnt - 1], &values[style->prop_cnt - 1]);
457 }
458 else if(style->prop_cnt == 1) {
459 if(LV_STYLE_PROP_ID_MASK(style->prop1) == prop_id) {
460 value_adjustment_helper(prop_and_meta, value, &style->prop1, &style->v_p.value1);
461 return;
462 }
463 size_t size = (style->prop_cnt + 1) * (sizeof(lv_style_value_t) + sizeof(uint16_t));
464 uint8_t * values_and_props = lv_mem_alloc(size);
465 if(values_and_props == NULL) return;
466 lv_style_value_t value_tmp = style->v_p.value1;
467 style->v_p.values_and_props = values_and_props;
468 style->prop_cnt++;
469
470 uint8_t * tmp = values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
471 uint16_t * props = (uint16_t *)tmp;
472 lv_style_value_t * values = (lv_style_value_t *)values_and_props;
473 props[0] = style->prop1;
474 values[0] = value_tmp;
475 value_adjustment_helper(prop_and_meta, value, &props[1], &values[1]);
476 }
477 else {
478 style->prop_cnt = 1;
479 value_adjustment_helper(prop_and_meta, value, &style->prop1, &style->v_p.value1);
480 }
481
482 uint8_t group = _lv_style_get_prop_group(prop_id);
483 style->has_group |= 1 << group;
484 }
485
486