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 /**
344  * Initialize a style
345  * @param style pointer to a style to initialize
346  * @note Do not call `lv_style_init` on styles that already have some properties
347  *       because this function won't free the used memory, just sets a default state for the style.
348  *       In other words be sure to initialize styles only once!
349  */
350 void lv_style_init(lv_style_t * style);
351 
352 /**
353  * Clear all properties from a style and free all allocated memories.
354  * @param style pointer to a style
355  */
356 void lv_style_reset(lv_style_t * style);
357 
358 /**
359  * Register a new style property for custom usage
360  * @return a new property ID, or LV_STYLE_PROP_INV if there are no more available.
361  * @example
362  * lv_style_prop_t MY_PROP;
363  * static inline void lv_style_set_my_prop(lv_style_t * style, lv_color_t value) {
364  * lv_style_value_t v = {.color = value}; lv_style_set_prop(style, MY_PROP, v); }
365  *
366  * ...
367  * MY_PROP = lv_style_register_prop();
368  * ...
369  * lv_style_set_my_prop(&style1, lv_palette_main(LV_PALETTE_RED));
370  */
371 lv_style_prop_t lv_style_register_prop(uint8_t flag);
372 
373 /**
374  * Get the number of custom properties that have been registered thus far.
375  */
376 lv_style_prop_t lv_style_get_num_custom_props(void);
377 
378 /**
379  * Remove a property from a style
380  * @param style pointer to a style
381  * @param prop  a style property ORed with a state.
382  * @return true: the property was found and removed; false: the property wasn't found
383  */
384 bool lv_style_remove_prop(lv_style_t * style, lv_style_prop_t prop);
385 
386 /**
387  * Set the value of property in a style.
388  * This function shouldn't be used directly by the user.
389  * Instead use `lv_style_set_<prop_name>()`. E.g. `lv_style_set_bg_color()`
390  * @param style pointer to style
391  * @param prop the ID of a property (e.g. `LV_STYLE_BG_COLOR`)
392  * @param value `lv_style_value_t` variable in which a field is set according to the type of `prop`
393  */
394 void lv_style_set_prop(lv_style_t * style, lv_style_prop_t prop, lv_style_value_t value);
395 
396 /**
397  * Set a special meta state for a property in a style.
398  * This function shouldn't be used directly by the user.
399  * @param style pointer to style
400  * @param prop the ID of a property (e.g. `LV_STYLE_BG_COLOR`)
401  * @param meta the meta value to attach to the property in the style
402  */
403 void lv_style_set_prop_meta(lv_style_t * style, lv_style_prop_t prop, uint16_t meta);
404 
405 /**
406  * Get the value of a property
407  * @param style pointer to a style
408  * @param prop  the ID of a property
409  * @param value pointer to a `lv_style_value_t` variable to store the value
410  * @return LV_RES_INV: the property wasn't found in the style (`value` is unchanged)
411  *         LV_RES_OK: the property was fond, and `value` is set accordingly
412  * @note For performance reasons there are no sanity check on `style`
413  */
414 lv_style_res_t lv_style_get_prop(const lv_style_t * style, lv_style_prop_t prop, lv_style_value_t * value);
415 
416 /**
417  * Initialize a transition descriptor.
418  * @param tr        pointer to a transition descriptor to initialize
419  * @param props     an array with the properties to transition. The last element must be zero.
420  * @param path_cb   an animation path (ease) callback. If `NULL` liner path will be used.
421  * @param time      duration of the transition in [ms]
422  * @param delay     delay before the transition in [ms]
423  * @param user_data any custom data that will be saved in the transition animation and will be available when `path_cb` is called
424  * @example
425  * const static lv_style_prop_t trans_props[] = { LV_STYLE_BG_OPA, LV_STYLE_BG_COLOR, 0 };
426  *  static lv_style_transition_dsc_t trans1;
427  *  lv_style_transition_dsc_init(&trans1, trans_props, NULL, 300, 0, NULL);
428  */
429 void lv_style_transition_dsc_init(lv_style_transition_dsc_t * tr, const lv_style_prop_t props[],
430                                   lv_anim_path_cb_t path_cb, uint32_t time, uint32_t delay, void * user_data);
431 
432 /**
433  * Get the default value of a property
434  * @param prop the ID of a property
435  * @return the default value
436  */
437 lv_style_value_t lv_style_prop_get_default(lv_style_prop_t prop);
438 
439 /**
440  * Get the value of a property
441  * @param style pointer to a style
442  * @param prop  the ID of a property
443  * @param value pointer to a `lv_style_value_t` variable to store the value
444  * @return LV_RES_INV: the property wasn't found in the style (`value` is unchanged)
445  *         LV_RES_OK: the property was fond, and `value` is set accordingly
446  * @note For performance reasons there are no sanity check on `style`
447  * @note This function is the same as ::lv_style_get_prop but inlined. Use it only on performance critical places
448  */
lv_style_get_prop_inlined(const lv_style_t * style,lv_style_prop_t prop,lv_style_value_t * value)449 static inline lv_style_res_t lv_style_get_prop_inlined(const lv_style_t * style, lv_style_prop_t prop,
450                                                        lv_style_value_t * value)
451 {
452     if(style->prop1 == LV_STYLE_PROP_ANY) {
453         const lv_style_const_prop_t * const_prop;
454         uint32_t i;
455         for(i = 0; i < style->prop_cnt; i++) {
456             const_prop = style->v_p.const_props + i;
457             lv_style_prop_t prop_id = LV_STYLE_PROP_ID_MASK(const_prop->prop);
458             if(prop_id == prop) {
459                 if(const_prop->prop & LV_STYLE_PROP_META_INHERIT)
460                     return LV_STYLE_RES_INHERIT;
461                 *value = (const_prop->prop & LV_STYLE_PROP_META_INITIAL) ? lv_style_prop_get_default(prop_id) : const_prop->value;
462                 return LV_STYLE_RES_FOUND;
463             }
464         }
465         return LV_STYLE_RES_NOT_FOUND;
466     }
467 
468     if(style->prop_cnt == 0) return LV_STYLE_RES_NOT_FOUND;
469 
470     if(style->prop_cnt > 1) {
471         uint8_t * tmp = style->v_p.values_and_props + style->prop_cnt * sizeof(lv_style_value_t);
472         uint16_t * props = (uint16_t *)tmp;
473         uint32_t i;
474         for(i = 0; i < style->prop_cnt; i++) {
475             lv_style_prop_t prop_id = LV_STYLE_PROP_ID_MASK(props[i]);
476             if(prop_id == prop) {
477                 if(props[i] & LV_STYLE_PROP_META_INHERIT)
478                     return LV_STYLE_RES_INHERIT;
479                 if(props[i] & LV_STYLE_PROP_META_INITIAL)
480                     *value = lv_style_prop_get_default(prop_id);
481                 else {
482                     lv_style_value_t * values = (lv_style_value_t *)style->v_p.values_and_props;
483                     *value = values[i];
484                 }
485                 return LV_STYLE_RES_FOUND;
486             }
487         }
488     }
489     else if(LV_STYLE_PROP_ID_MASK(style->prop1) == prop) {
490         if(style->prop1 & LV_STYLE_PROP_META_INHERIT)
491             return LV_STYLE_RES_INHERIT;
492         *value = (style->prop1 & LV_STYLE_PROP_META_INITIAL) ? lv_style_prop_get_default(LV_STYLE_PROP_ID_MASK(
493                                                                                              style->prop1)) : style->v_p.value1;
494         return LV_STYLE_RES_FOUND;
495     }
496     return LV_STYLE_RES_NOT_FOUND;
497 }
498 
499 /**
500  * Checks if a style is empty (has no properties)
501  * @param style pointer to a style
502  * @return true if the style is empty
503  */
504 bool lv_style_is_empty(const lv_style_t * style);
505 
506 /**
507  * 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.
508  * It allows early skipping the style if the property is not exists in the style at all.
509  * @param prop a style property
510  * @return the group [0..7] 7 means all the custom properties with index > 112
511  */
512 uint8_t _lv_style_get_prop_group(lv_style_prop_t prop);
513 
514 /**
515  * Get the flags of a built-in or custom property.
516  *
517  * @param prop a style property
518  * @return the flags of the property
519  */
520 uint8_t _lv_style_prop_lookup_flags(lv_style_prop_t prop);
521 
522 #include "lv_style_gen.h"
523 
lv_style_set_size(lv_style_t * style,lv_coord_t value)524 static inline void lv_style_set_size(lv_style_t * style, lv_coord_t value)
525 {
526     lv_style_set_width(style, value);
527     lv_style_set_height(style, value);
528 }
529 
lv_style_set_pad_all(lv_style_t * style,lv_coord_t value)530 static inline void lv_style_set_pad_all(lv_style_t * style, lv_coord_t value)
531 {
532     lv_style_set_pad_left(style, value);
533     lv_style_set_pad_right(style, value);
534     lv_style_set_pad_top(style, value);
535     lv_style_set_pad_bottom(style, value);
536 }
537 
lv_style_set_pad_hor(lv_style_t * style,lv_coord_t value)538 static inline void lv_style_set_pad_hor(lv_style_t * style, lv_coord_t value)
539 {
540     lv_style_set_pad_left(style, value);
541     lv_style_set_pad_right(style, value);
542 }
543 
lv_style_set_pad_ver(lv_style_t * style,lv_coord_t value)544 static inline void lv_style_set_pad_ver(lv_style_t * style, lv_coord_t value)
545 {
546     lv_style_set_pad_top(style, value);
547     lv_style_set_pad_bottom(style, value);
548 }
549 
lv_style_set_pad_gap(lv_style_t * style,lv_coord_t value)550 static inline void lv_style_set_pad_gap(lv_style_t * style, lv_coord_t value)
551 {
552     lv_style_set_pad_row(style, value);
553     lv_style_set_pad_column(style, value);
554 }
555 
556 /**
557  * @brief Check if the style property has a specified behavioral flag.
558  *
559  * Do not pass multiple flags to this function as backwards-compatibility is not guaranteed
560  * for that.
561  *
562  * @param prop Property ID
563  * @param flag Flag
564  * @return true if the flag is set for this property
565  */
lv_style_prop_has_flag(lv_style_prop_t prop,uint8_t flag)566 static inline bool lv_style_prop_has_flag(lv_style_prop_t prop, uint8_t flag)
567 {
568     return _lv_style_prop_lookup_flags(prop) & flag;
569 }
570 
571 /*************************
572  *    GLOBAL VARIABLES
573  *************************/
574 
575 /**********************
576  *      MACROS
577  **********************/
578 
579 #if LV_USE_ASSERT_STYLE
580 #  define LV_ASSERT_STYLE(style_p)                                                                            \
581     do {                                                                                                      \
582         LV_ASSERT_MSG(style_p != NULL, "The style is NULL");                                                  \
583         LV_ASSERT_MSG(style_p->sentinel == LV_STYLE_SENTINEL_VALUE, "Style is not initialized or corrupted"); \
584     } while(0)
585 #else
586 #  define LV_ASSERT_STYLE(p) do{}while(0)
587 #endif
588 
589 #ifdef __cplusplus
590 } /*extern "C"*/
591 #endif
592 
593 #endif /*LV_STYLE_H*/
594