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.c (15718B)

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