acid-drop

- Hacking the planet from a LilyGo T-Deck using custom firmware
git clone git://git.acid.vegas/acid-drop.git
Log | Files | Refs | Archive | README | LICENSE

lv_style.h (18489B)

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