1 /**
2 * @file lv_style.h
3 *
4 */
5
6 #ifndef LV_STYLE_H
7 #define LV_STYLE_H
8
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12
13 /*********************
14 * INCLUDES
15 *********************/
16 #include <stdbool.h>
17 #include <stdint.h>
18 #include "../font/lv_font.h"
19 #include "lv_color.h"
20 #include "lv_area.h"
21 #include "lv_anim.h"
22 #include "lv_txt.h"
23 #include "lv_types.h"
24 #include "lv_assert.h"
25 #include "lv_bidi.h"
26
27 /*********************
28 * DEFINES
29 *********************/
30
31 #define LV_STYLE_SENTINEL_VALUE 0xAABBCCDD
32
33 /**
34 * Flags for style behavior
35 *
36 * The rest of the flags will have _FLAG added to their name in v9.
37 */
38 #define LV_STYLE_PROP_FLAG_NONE (0)
39 #define LV_STYLE_PROP_INHERIT (1 << 0) /*Inherited*/
40 #define LV_STYLE_PROP_EXT_DRAW (1 << 1) /*Requires ext. draw size update when changed*/
41 #define LV_STYLE_PROP_LAYOUT_REFR (1 << 2) /*Requires layout update when changed*/
42 #define LV_STYLE_PROP_PARENT_LAYOUT_REFR (1 << 3) /*Requires layout update on parent when changed*/
43 #define LV_STYLE_PROP_LAYER_REFR (1 << 4) /*Affects layer handling*/
44 #define LV_STYLE_PROP_ALL (0x1F) /*Indicating all flags*/
45
46 /**
47 * Other constants
48 */
49 #define LV_IMG_ZOOM_NONE 256 /*Value for not zooming the image*/
50 LV_EXPORT_CONST_INT(LV_IMG_ZOOM_NONE);
51
52 // *INDENT-OFF*
53 #if LV_USE_ASSERT_STYLE
54 #define LV_STYLE_CONST_INIT(var_name, prop_array) \
55 const lv_style_t var_name = { \
56 .sentinel = LV_STYLE_SENTINEL_VALUE, \
57 .v_p = { .const_props = prop_array }, \
58 .has_group = 0xFF, \
59 .prop1 = LV_STYLE_PROP_ANY, \
60 .prop_cnt = (sizeof(prop_array) / sizeof((prop_array)[0])), \
61 }
62 #else
63 #define LV_STYLE_CONST_INIT(var_name, prop_array) \
64 const lv_style_t var_name = { \
65 .v_p = { .const_props = prop_array }, \
66 .has_group = 0xFF, \
67 .prop1 = LV_STYLE_PROP_ANY, \
68 .prop_cnt = (sizeof(prop_array) / sizeof((prop_array)[0])), \
69 }
70 #endif
71 // *INDENT-ON*
72
73 #define LV_STYLE_PROP_META_INHERIT 0x8000
74 #define LV_STYLE_PROP_META_INITIAL 0x4000
75 #define LV_STYLE_PROP_META_MASK (LV_STYLE_PROP_META_INHERIT | LV_STYLE_PROP_META_INITIAL)
76
77 #define LV_STYLE_PROP_ID_MASK(prop) ((lv_style_prop_t)((prop) & ~LV_STYLE_PROP_META_MASK))
78
79 /**********************
80 * TYPEDEFS
81 **********************/
82
83 /**
84 * Possible options how to blend opaque drawings
85 */
86 enum {
87 LV_BLEND_MODE_NORMAL, /**< Simply mix according to the opacity value*/
88 LV_BLEND_MODE_ADDITIVE, /**< Add the respective color channels*/
89 LV_BLEND_MODE_SUBTRACTIVE,/**< Subtract the foreground from the background*/
90 LV_BLEND_MODE_MULTIPLY, /**< Multiply the foreground and background*/
91 LV_BLEND_MODE_REPLACE, /**< Replace background with foreground in the area*/
92 };
93
94 typedef uint8_t lv_blend_mode_t;
95
96 /**
97 * Some options to apply decorations on texts.
98 * 'OR'ed values can be used.
99 */
100 enum {
101 LV_TEXT_DECOR_NONE = 0x00,
102 LV_TEXT_DECOR_UNDERLINE = 0x01,
103 LV_TEXT_DECOR_STRIKETHROUGH = 0x02,
104 };
105
106 typedef uint8_t lv_text_decor_t;
107
108 /**
109 * Selects on which sides border should be drawn
110 * 'OR'ed values can be used.
111 */
112 enum {
113 LV_BORDER_SIDE_NONE = 0x00,
114 LV_BORDER_SIDE_BOTTOM = 0x01,
115 LV_BORDER_SIDE_TOP = 0x02,
116 LV_BORDER_SIDE_LEFT = 0x04,
117 LV_BORDER_SIDE_RIGHT = 0x08,
118 LV_BORDER_SIDE_FULL = 0x0F,
119 LV_BORDER_SIDE_INTERNAL = 0x10, /**< FOR matrix-like objects (e.g. Button matrix)*/
120 };
121 typedef uint8_t lv_border_side_t;
122
123 /**
124 * The direction of the gradient.
125 */
126 enum {
127 LV_GRAD_DIR_NONE, /**< No gradient (the `grad_color` property is ignored)*/
128 LV_GRAD_DIR_VER, /**< Vertical (top to bottom) gradient*/
129 LV_GRAD_DIR_HOR, /**< Horizontal (left to right) gradient*/
130 };
131
132 typedef uint8_t lv_grad_dir_t;
133
134 /**
135 * The dithering algorithm for the gradient
136 * Depends on LV_DITHER_GRADIENT
137 */
138 enum {
139 LV_DITHER_NONE, /**< No dithering, colors are just quantized to the output resolution*/
140 LV_DITHER_ORDERED, /**< Ordered dithering. Faster to compute and use less memory but lower quality*/
141 LV_DITHER_ERR_DIFF, /**< Error diffusion mode. Slower to compute and use more memory but give highest dither quality*/
142 };
143
144 typedef uint8_t lv_dither_mode_t;
145
146 /** A gradient stop definition.
147 * This matches a color and a position in a virtual 0-255 scale.
148 */
149 typedef struct {
150 lv_color_t color; /**< The stop color */
151 uint8_t frac; /**< The stop position in 1/255 unit */
152 } lv_gradient_stop_t;
153
154 /** A descriptor of a gradient. */
155 typedef struct {
156 lv_gradient_stop_t stops[LV_GRADIENT_MAX_STOPS]; /**< A gradient stop array */
157 uint8_t stops_count; /**< The number of used stops in the array */
158 lv_grad_dir_t dir : 3; /**< The gradient direction.
159 * Any of LV_GRAD_DIR_HOR, LV_GRAD_DIR_VER, LV_GRAD_DIR_NONE */
160 lv_dither_mode_t dither : 3; /**< Whether to dither the gradient or not.
161 * Any of LV_DITHER_NONE, LV_DITHER_ORDERED, LV_DITHER_ERR_DIFF */
162 } lv_grad_dsc_t;
163
164 /**
165 * A common type to handle all the property types in the same way.
166 */
167 typedef union {
168 int32_t num; /**< Number integer number (opacity, enums, booleans or "normal" numbers)*/
169 const void * ptr; /**< Constant pointers (font, cone text, etc)*/
170 lv_color_t color; /**< Colors*/
171 } lv_style_value_t;
172
173 /**
174 * Enumeration of all built in style properties
175 *
176 * Props are split into groups of 16. When adding a new prop to a group, ensure it does not overflow into the next one.
177 */
178 typedef enum {
179 LV_STYLE_PROP_INV = 0,
180
181 /*Group 0*/
182 LV_STYLE_WIDTH = 1,
183 LV_STYLE_MIN_WIDTH = 2,
184 LV_STYLE_MAX_WIDTH = 3,
185 LV_STYLE_HEIGHT = 4,
186 LV_STYLE_MIN_HEIGHT = 5,
187 LV_STYLE_MAX_HEIGHT = 6,
188 LV_STYLE_X = 7,
189 LV_STYLE_Y = 8,
190 LV_STYLE_ALIGN = 9,
191 LV_STYLE_LAYOUT = 10,
192 LV_STYLE_RADIUS = 11,
193
194 /*Group 1*/
195 LV_STYLE_PAD_TOP = 16,
196 LV_STYLE_PAD_BOTTOM = 17,
197 LV_STYLE_PAD_LEFT = 18,
198 LV_STYLE_PAD_RIGHT = 19,
199 LV_STYLE_PAD_ROW = 20,
200 LV_STYLE_PAD_COLUMN = 21,
201 LV_STYLE_BASE_DIR = 22,
202 LV_STYLE_CLIP_CORNER = 23,
203
204 /*Group 2*/
205 LV_STYLE_BG_COLOR = 32,
206 LV_STYLE_BG_OPA = 33,
207 LV_STYLE_BG_GRAD_COLOR = 34,
208 LV_STYLE_BG_GRAD_DIR = 35,
209 LV_STYLE_BG_MAIN_STOP = 36,
210 LV_STYLE_BG_GRAD_STOP = 37,
211 LV_STYLE_BG_GRAD = 38,
212 LV_STYLE_BG_DITHER_MODE = 39,
213 LV_STYLE_BG_IMG_SRC = 40,
214 LV_STYLE_BG_IMG_OPA = 41,
215 LV_STYLE_BG_IMG_RECOLOR = 42,
216 LV_STYLE_BG_IMG_RECOLOR_OPA = 43,
217 LV_STYLE_BG_IMG_TILED = 44,
218
219 /*Group 3*/
220 LV_STYLE_BORDER_COLOR = 48,
221 LV_STYLE_BORDER_OPA = 49,
222 LV_STYLE_BORDER_WIDTH = 50,
223 LV_STYLE_BORDER_SIDE = 51,
224 LV_STYLE_BORDER_POST = 52,
225 LV_STYLE_OUTLINE_WIDTH = 53,
226 LV_STYLE_OUTLINE_COLOR = 54,
227 LV_STYLE_OUTLINE_OPA = 55,
228 LV_STYLE_OUTLINE_PAD = 56,
229
230 /*Group 4*/
231 LV_STYLE_SHADOW_WIDTH = 64,
232 LV_STYLE_SHADOW_OFS_X = 65,
233 LV_STYLE_SHADOW_OFS_Y = 66,
234 LV_STYLE_SHADOW_SPREAD = 67,
235 LV_STYLE_SHADOW_COLOR = 68,
236 LV_STYLE_SHADOW_OPA = 69,
237 LV_STYLE_IMG_OPA = 70,
238 LV_STYLE_IMG_RECOLOR = 71,
239 LV_STYLE_IMG_RECOLOR_OPA = 72,
240 LV_STYLE_LINE_WIDTH = 73,
241 LV_STYLE_LINE_DASH_WIDTH = 74,
242 LV_STYLE_LINE_DASH_GAP = 75,
243 LV_STYLE_LINE_ROUNDED = 76,
244 LV_STYLE_LINE_COLOR = 77,
245 LV_STYLE_LINE_OPA = 78,
246
247 /*Group 5*/
248 LV_STYLE_ARC_WIDTH = 80,
249 LV_STYLE_ARC_ROUNDED = 81,
250 LV_STYLE_ARC_COLOR = 82,
251 LV_STYLE_ARC_OPA = 83,
252 LV_STYLE_ARC_IMG_SRC = 84,
253 LV_STYLE_TEXT_COLOR = 85,
254 LV_STYLE_TEXT_OPA = 86,
255 LV_STYLE_TEXT_FONT = 87,
256 LV_STYLE_TEXT_LETTER_SPACE = 88,
257 LV_STYLE_TEXT_LINE_SPACE = 89,
258 LV_STYLE_TEXT_DECOR = 90,
259 LV_STYLE_TEXT_ALIGN = 91,
260
261 /*Group 6*/
262 LV_STYLE_OPA = 96,
263 LV_STYLE_OPA_LAYERED = 97,
264 LV_STYLE_COLOR_FILTER_DSC = 98,
265 LV_STYLE_COLOR_FILTER_OPA = 99,
266 LV_STYLE_ANIM = 100,
267 LV_STYLE_ANIM_TIME = 101,
268 LV_STYLE_ANIM_SPEED = 102,
269 LV_STYLE_TRANSITION = 103,
270 LV_STYLE_BLEND_MODE = 104,
271 LV_STYLE_TRANSFORM_WIDTH = 105,
272 LV_STYLE_TRANSFORM_HEIGHT = 106,
273 LV_STYLE_TRANSLATE_X = 107,
274 LV_STYLE_TRANSLATE_Y = 108,
275 LV_STYLE_TRANSFORM_ZOOM = 109,
276 LV_STYLE_TRANSFORM_ANGLE = 110,
277 LV_STYLE_TRANSFORM_PIVOT_X = 111,
278 LV_STYLE_TRANSFORM_PIVOT_Y = 112,
279
280 _LV_STYLE_LAST_BUILT_IN_PROP = 112,
281 _LV_STYLE_NUM_BUILT_IN_PROPS = _LV_STYLE_LAST_BUILT_IN_PROP + 1,
282
283 LV_STYLE_PROP_ANY = 0xFFFF,
284 _LV_STYLE_PROP_CONST = 0xFFFF /* magic value for const styles */
285 } lv_style_prop_t;
286
287 enum {
288 LV_STYLE_RES_NOT_FOUND,
289 LV_STYLE_RES_FOUND,
290 LV_STYLE_RES_INHERIT
291 };
292
293 typedef uint8_t lv_style_res_t;
294
295 /**
296 * Descriptor for style transitions
297 */
298 typedef struct {
299 const lv_style_prop_t * props; /**< An array with the properties to animate.*/
300 #if LV_USE_USER_DATA
301 void * user_data; /**< A custom user data that will be passed to the animation's user_data */
302 #endif
303 lv_anim_path_cb_t path_xcb; /**< A path for the animation.*/
304 uint32_t time; /**< Duration of the transition in [ms]*/
305 uint32_t delay; /**< Delay before the transition in [ms]*/
306 } lv_style_transition_dsc_t;
307
308 /**
309 * Descriptor of a constant style property.
310 */
311 typedef struct {
312 lv_style_prop_t prop;
313 lv_style_value_t value;
314 } lv_style_const_prop_t;
315
316 /**
317 * Descriptor of a style (a collection of properties and values).
318 */
319 typedef struct {
320
321 #if LV_USE_ASSERT_STYLE
322 uint32_t sentinel;
323 #endif
324
325 /*If there is only one property store it directly.
326 *For more properties allocate an array*/
327 union {
328 lv_style_value_t value1;
329 uint8_t * values_and_props;
330 const lv_style_const_prop_t * const_props;
331 } v_p;
332
333 uint16_t prop1;
334 uint8_t has_group;
335 uint8_t prop_cnt;
336 } lv_style_t;
337
338 /**********************
339 * GLOBAL PROTOTYPES
340 **********************/
341
342 /**
343 * Initialize a style
344 * @param style pointer to a style to initialize
345 * @note Do not call `lv_style_init` on styles that already have some properties
346 * because this function won't free the used memory, just sets a default state for the style.
347 * In other words be sure to initialize styles only once!
348 */
349 void lv_style_init(lv_style_t * style);
350
351 /**
352 * Clear all properties from a style and free all allocated memories.
353 * @param style pointer to a style
354 */
355 void lv_style_reset(lv_style_t * style);
356
357 /**
358 * Register a new style property for custom usage
359 * @return a new property ID, or LV_STYLE_PROP_INV if there are no more available.
360 * @example
361 * lv_style_prop_t MY_PROP;
362 * static inline void lv_style_set_my_prop(lv_style_t * style, lv_color_t value) {
363 * lv_style_value_t v = {.color = value}; lv_style_set_prop(style, MY_PROP, v); }
364 *
365 * ...
366 * MY_PROP = lv_style_register_prop();
367 * ...
368 * lv_style_set_my_prop(&style1, lv_palette_main(LV_PALETTE_RED));
369 */
370 lv_style_prop_t lv_style_register_prop(uint8_t flag);
371
372 /**
373 * Get the number of custom properties that have been registered thus far.
374 */
375 lv_style_prop_t lv_style_get_num_custom_props(void);
376
377 /**
378 * Remove a property from a style
379 * @param style pointer to a style
380 * @param prop a style property ORed with a state.
381 * @return true: the property was found and removed; false: the property wasn't found
382 */
383 bool lv_style_remove_prop(lv_style_t * style, lv_style_prop_t prop);
384
385 /**
386 * Set the value of property in a style.
387 * This function shouldn't be used directly by the user.
388 * Instead use `lv_style_set_<prop_name>()`. E.g. `lv_style_set_bg_color()`
389 * @param style pointer to style
390 * @param prop the ID of a property (e.g. `LV_STYLE_BG_COLOR`)
391 * @param value `lv_style_value_t` variable in which a field is set according to the type of `prop`
392 */
393 void lv_style_set_prop(lv_style_t * style, lv_style_prop_t prop, lv_style_value_t value);
394
395 /**
396 * Set a special meta state for a property in a style.
397 * This function shouldn't be used directly by the user.
398 * @param style pointer to style
399 * @param prop the ID of a property (e.g. `LV_STYLE_BG_COLOR`)
400 * @param meta the meta value to attach to the property in the style
401 */
402 void lv_style_set_prop_meta(lv_style_t * style, lv_style_prop_t prop, uint16_t meta);
403
404 /**
405 * Get the value of a property
406 * @param style pointer to a style
407 * @param prop the ID of a property
408 * @param value pointer to a `lv_style_value_t` variable to store the value
409 * @return LV_RES_INV: the property wasn't found in the style (`value` is unchanged)
410 * LV_RES_OK: the property was fond, and `value` is set accordingly
411 * @note For performance reasons there are no sanity check on `style`
412 */
413 lv_style_res_t lv_style_get_prop(const lv_style_t * style, lv_style_prop_t prop, lv_style_value_t * value);
414
415 /**
416 * Initialize a transition descriptor.
417 * @param tr pointer to a transition descriptor to initialize
418 * @param props an array with the properties to transition. The last element must be zero.
419 * @param path_cb an animation path (ease) callback. If `NULL` liner path will be used.
420 * @param time duration of the transition in [ms]
421 * @param delay delay before the transition in [ms]
422 * @param user_data any custom data that will be saved in the transition animation and will be available when `path_cb` is called
423 * @example
424 * const static lv_style_prop_t trans_props[] = { LV_STYLE_BG_OPA, LV_STYLE_BG_COLOR, 0 };
425 * static lv_style_transition_dsc_t trans1;
426 * lv_style_transition_dsc_init(&trans1, trans_props, NULL, 300, 0, NULL);
427 */
428 void lv_style_transition_dsc_init(lv_style_transition_dsc_t * tr, const lv_style_prop_t props[],
429 lv_anim_path_cb_t path_cb, uint32_t time, uint32_t delay, void * user_data);
430
431 /**
432 * Get the default value of a property
433 * @param prop the ID of a property
434 * @return the default value
435 */
436 lv_style_value_t lv_style_prop_get_default(lv_style_prop_t prop);
437
438 /**
439 * Get the value of a property
440 * @param style pointer to a style
441 * @param prop the ID of a property
442 * @param value pointer to a `lv_style_value_t` variable to store the value
443 * @return LV_RES_INV: the property wasn't found in the style (`value` is unchanged)
444 * LV_RES_OK: the property was fond, and `value` is set accordingly
445 * @note For performance reasons there are no sanity check on `style`
446 * @note This function is the same as ::lv_style_get_prop but inlined. Use it only on performance critical places
447 */
lv_style_get_prop_inlined(const lv_style_t * style,lv_style_prop_t prop,lv_style_value_t * value)448 static inline lv_style_res_t lv_style_get_prop_inlined(const lv_style_t * style, lv_style_prop_t prop,
449 lv_style_value_t * value)
450 {
451 if(style->prop1 == LV_STYLE_PROP_ANY) {
452 const lv_style_const_prop_t * const_prop;
453 uint32_t i;
454 for(i = 0; i < style->prop_cnt; i++) {
455 const_prop = style->v_p.const_props + i;
456 lv_style_prop_t prop_id = LV_STYLE_PROP_ID_MASK(const_prop->prop);
457 if(prop_id == prop) {
458 if(const_prop->prop & LV_STYLE_PROP_META_INHERIT)
459 return LV_STYLE_RES_INHERIT;
460 *value = (const_prop->prop & LV_STYLE_PROP_META_INITIAL) ? lv_style_prop_get_default(prop_id) : const_prop->value;
461 return LV_STYLE_RES_FOUND;
462 }
463 }
464 return LV_STYLE_RES_NOT_FOUND;
465 }
466
467 if(style->prop_cnt == 0) return LV_STYLE_RES_NOT_FOUND;
468
469 if(style->prop_cnt > 1) {
470 uint8_t * tmp = style->v_p.values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
471 uint16_t * props = (uint16_t *)tmp;
472 uint32_t i;
473 for(i = 0; i < style->prop_cnt; i++) {
474 lv_style_prop_t prop_id = LV_STYLE_PROP_ID_MASK(props[i]);
475 if(prop_id == prop) {
476 if(props[i] & LV_STYLE_PROP_META_INHERIT)
477 return LV_STYLE_RES_INHERIT;
478 if(props[i] & LV_STYLE_PROP_META_INITIAL)
479 *value = lv_style_prop_get_default(prop_id);
480 else {
481 lv_style_value_t * values = (lv_style_value_t *)style->v_p.values_and_props;
482 *value = values[i];
483 }
484 return LV_STYLE_RES_FOUND;
485 }
486 }
487 }
488 else if(LV_STYLE_PROP_ID_MASK(style->prop1) == prop) {
489 if(style->prop1 & LV_STYLE_PROP_META_INHERIT)
490 return LV_STYLE_RES_INHERIT;
491 *value = (style->prop1 & LV_STYLE_PROP_META_INITIAL) ? lv_style_prop_get_default(LV_STYLE_PROP_ID_MASK(
492 style->prop1)) : style->v_p.value1;
493 return LV_STYLE_RES_FOUND;
494 }
495 return LV_STYLE_RES_NOT_FOUND;
496 }
497
498 /**
499 * Checks if a style is empty (has no properties)
500 * @param style pointer to a style
501 * @return true if the style is empty
502 */
503 bool lv_style_is_empty(const lv_style_t * style);
504
505 /**
506 * Tell the group of a property. If the a property from a group is set in a style the (1 << group) bit of style->has_group is set.
507 * It allows early skipping the style if the property is not exists in the style at all.
508 * @param prop a style property
509 * @return the group [0..7] 7 means all the custom properties with index > 112
510 */
511 uint8_t _lv_style_get_prop_group(lv_style_prop_t prop);
512
513 /**
514 * Get the flags of a built-in or custom property.
515 *
516 * @param prop a style property
517 * @return the flags of the property
518 */
519 uint8_t _lv_style_prop_lookup_flags(lv_style_prop_t prop);
520
521 #include "lv_style_gen.h"
522
lv_style_set_size(lv_style_t * style,lv_coord_t value)523 static inline void lv_style_set_size(lv_style_t * style, lv_coord_t value)
524 {
525 lv_style_set_width(style, value);
526 lv_style_set_height(style, value);
527 }
528
lv_style_set_pad_all(lv_style_t * style,lv_coord_t value)529 static inline void lv_style_set_pad_all(lv_style_t * style, lv_coord_t value)
530 {
531 lv_style_set_pad_left(style, value);
532 lv_style_set_pad_right(style, value);
533 lv_style_set_pad_top(style, value);
534 lv_style_set_pad_bottom(style, value);
535 }
536
lv_style_set_pad_hor(lv_style_t * style,lv_coord_t value)537 static inline void lv_style_set_pad_hor(lv_style_t * style, lv_coord_t value)
538 {
539 lv_style_set_pad_left(style, value);
540 lv_style_set_pad_right(style, value);
541 }
542
lv_style_set_pad_ver(lv_style_t * style,lv_coord_t value)543 static inline void lv_style_set_pad_ver(lv_style_t * style, lv_coord_t value)
544 {
545 lv_style_set_pad_top(style, value);
546 lv_style_set_pad_bottom(style, value);
547 }
548
lv_style_set_pad_gap(lv_style_t * style,lv_coord_t value)549 static inline void lv_style_set_pad_gap(lv_style_t * style, lv_coord_t value)
550 {
551 lv_style_set_pad_row(style, value);
552 lv_style_set_pad_column(style, value);
553 }
554
555 /**
556 * @brief Check if the style property has a specified behavioral flag.
557 *
558 * Do not pass multiple flags to this function as backwards-compatibility is not guaranteed
559 * for that.
560 *
561 * @param prop Property ID
562 * @param flag Flag
563 * @return true if the flag is set for this property
564 */
lv_style_prop_has_flag(lv_style_prop_t prop,uint8_t flag)565 static inline bool lv_style_prop_has_flag(lv_style_prop_t prop, uint8_t flag)
566 {
567 return _lv_style_prop_lookup_flags(prop) & flag;
568 }
569
570 /*************************
571 * GLOBAL VARIABLES
572 *************************/
573
574 /**********************
575 * MACROS
576 **********************/
577
578 #if LV_USE_ASSERT_STYLE
579 # define LV_ASSERT_STYLE(style_p) \
580 do { \
581 LV_ASSERT_MSG(style_p != NULL, "The style is NULL"); \
582 LV_ASSERT_MSG(style_p->sentinel == LV_STYLE_SENTINEL_VALUE, "Style is not initialized or corrupted"); \
583 } while(0)
584 #else
585 # define LV_ASSERT_STYLE(p) do{}while(0)
586 #endif
587
588 #ifdef __cplusplus
589 } /*extern "C"*/
590 #endif
591
592 #endif /*LV_STYLE_H*/
593