1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-21 06:53:01 +08:00

initial version of new style system

This commit is contained in:
Gabor Kiss-Vamosi 2019-12-14 23:39:26 +01:00
parent 6f9d66843c
commit a101e9a3e5
18 changed files with 2676 additions and 2551 deletions

View File

@ -87,10 +87,10 @@ bool lv_debug_check_style(const lv_style_t * style)
if(style == NULL) return true; /*NULL style is still valid*/ if(style == NULL) return true; /*NULL style is still valid*/
#if LV_USE_ASSERT_STYLE #if LV_USE_ASSERT_STYLE
if(style->debug_sentinel != LV_STYLE_DEGUG_SENTINEL_VALUE) { // if(style->debug_sentinel != LV_STYLE_DEGUG_SENTINEL_VALUE) {
LV_LOG_WARN("Invalid style (local variable or not initialized?)"); // LV_LOG_WARN("Invalid style (local variable or not initialized?)");
return false; // return false;
} // }
#endif #endif
return true; return true;

View File

@ -550,24 +550,24 @@ static void style_mod_def(lv_group_t * group, lv_style_t * style)
(void)group; /*Unused*/ (void)group; /*Unused*/
#if LV_COLOR_DEPTH != 1 #if LV_COLOR_DEPTH != 1
/*Make the style to be a little bit orange*/ // /*Make the style to be a little bit orange*/
style->body.border.opa = LV_OPA_COVER; // style->body.border.opa = LV_OPA_COVER;
style->body.border.color = LV_COLOR_ORANGE; // style->body.border.color = LV_COLOR_ORANGE;
//
/*If not transparent or has border then emphasis the border*/ // /*If not transparent or has border then emphasis the border*/
if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 20; // if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 20;
//
style->body.main_color = lv_color_mix(style->body.main_color, LV_COLOR_ORANGE, LV_OPA_70); // style->body.main_color = lv_color_mix(style->body.main_color, LV_COLOR_ORANGE, LV_OPA_70);
style->body.grad_color = lv_color_mix(style->body.grad_color, LV_COLOR_ORANGE, LV_OPA_70); // style->body.grad_color = lv_color_mix(style->body.grad_color, LV_COLOR_ORANGE, LV_OPA_70);
style->body.shadow.color = lv_color_mix(style->body.shadow.color, LV_COLOR_ORANGE, LV_OPA_60); // style->body.shadow.color = lv_color_mix(style->body.shadow.color, LV_COLOR_ORANGE, LV_OPA_60);
//
style->text.color = lv_color_mix(style->text.color, LV_COLOR_ORANGE, LV_OPA_70); // style->text.color = lv_color_mix(style->text.color, LV_COLOR_ORANGE, LV_OPA_70);
//
/*Add some recolor to the images*/ // /*Add some recolor to the images*/
if(style->image.intense < LV_OPA_MIN) { // if(style->image.intense < LV_OPA_MIN) {
style->image.color = LV_COLOR_ORANGE; // style->image.color = LV_COLOR_ORANGE;
style->image.intense = LV_OPA_40; // style->image.intense = LV_OPA_40;
} // }
#else #else
style->body.border.opa = LV_OPA_COVER; style->body.border.opa = LV_OPA_COVER;
style->body.border.color = LV_COLOR_BLACK; style->body.border.color = LV_COLOR_BLACK;
@ -586,24 +586,24 @@ static void style_mod_edit_def(lv_group_t * group, lv_style_t * style)
(void)group; /*Unused*/ (void)group; /*Unused*/
#if LV_COLOR_DEPTH != 1 #if LV_COLOR_DEPTH != 1
/*Make the style to be a little bit orange*/ // /*Make the style to be a little bit orange*/
style->body.border.opa = LV_OPA_COVER; // style->body.border.opa = LV_OPA_COVER;
style->body.border.color = LV_COLOR_GREEN; // style->body.border.color = LV_COLOR_GREEN;
//
/*If not empty or has border then emphasis the border*/ // /*If not empty or has border then emphasis the border*/
if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 20; // if(style->body.opa != LV_OPA_TRANSP || style->body.border.width != 0) style->body.border.width = LV_DPI / 20;
//
style->body.main_color = lv_color_mix(style->body.main_color, LV_COLOR_GREEN, LV_OPA_70); // style->body.main_color = lv_color_mix(style->body.main_color, LV_COLOR_GREEN, LV_OPA_70);
style->body.grad_color = lv_color_mix(style->body.grad_color, LV_COLOR_GREEN, LV_OPA_70); // style->body.grad_color = lv_color_mix(style->body.grad_color, LV_COLOR_GREEN, LV_OPA_70);
style->body.shadow.color = lv_color_mix(style->body.shadow.color, LV_COLOR_GREEN, LV_OPA_60); // style->body.shadow.color = lv_color_mix(style->body.shadow.color, LV_COLOR_GREEN, LV_OPA_60);
//
style->text.color = lv_color_mix(style->text.color, LV_COLOR_GREEN, LV_OPA_70); // style->text.color = lv_color_mix(style->text.color, LV_COLOR_GREEN, LV_OPA_70);
//
/*Add some recolor to the images*/ // /*Add some recolor to the images*/
if(style->image.intense < LV_OPA_MIN) { // if(style->image.intense < LV_OPA_MIN) {
style->image.color = LV_COLOR_GREEN; // style->image.color = LV_COLOR_GREEN;
style->image.intense = LV_OPA_40; // style->image.intense = LV_OPA_40;
} // }
#else #else
style->body.border.opa = LV_OPA_COVER; style->body.border.opa = LV_OPA_COVER;

View File

@ -105,7 +105,7 @@ void lv_init(void)
#endif #endif
/*Init. the sstyles*/ /*Init. the sstyles*/
lv_style_init(); lv_style_built_in_init();
/*Initialize the screen refresh system*/ /*Initialize the screen refresh system*/
lv_refr_init(); lv_refr_init();
@ -187,9 +187,11 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
/*Set the default styles*/ /*Set the default styles*/
lv_theme_t * th = lv_theme_get_current(); lv_theme_t * th = lv_theme_get_current();
if(th) { if(th) {
new_obj->style_p = th->style.scr; // new_obj->style_p = th->style.scr;
} else { } else {
new_obj->style_p = &lv_style_scr; lv_style_init(&new_obj->style_local);
new_obj->style_chain.style = &new_obj->style_local;
new_obj->style_chain.next = NULL;
} }
/*Init. user date*/ /*Init. user date*/
@ -279,9 +281,11 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
/*Set appearance*/ /*Set appearance*/
lv_theme_t * th = lv_theme_get_current(); lv_theme_t * th = lv_theme_get_current();
if(th) { if(th) {
new_obj->style_p = th->style.panel; // new_obj->style_p = th->style.panel;
} else { } else {
new_obj->style_p = &lv_style_plain_color; lv_style_init(&new_obj->style_local);
new_obj->style_chain.style = &new_obj->style_local;
new_obj->style_chain.next = NULL;
} }
#if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL #if LV_USE_EXT_CLICK_AREA == LV_EXT_CLICK_AREA_FULL
@ -365,8 +369,6 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy)
new_obj->protect = copy->protect; new_obj->protect = copy->protect;
new_obj->opa_scale = copy->opa_scale; new_obj->opa_scale = copy->opa_scale;
new_obj->style_p = copy->style_p;
#if LV_USE_GROUP #if LV_USE_GROUP
/*Add to the same group*/ /*Add to the same group*/
if(copy->group_p != NULL) { if(copy->group_p != NULL) {
@ -1198,20 +1200,47 @@ void lv_obj_set_ext_click_area(lv_obj_t * obj, lv_coord_t left, lv_coord_t right
* @param obj pointer to an object * @param obj pointer to an object
* @param style_p pointer to the new style * @param style_p pointer to the new style
*/ */
void lv_obj_set_style(lv_obj_t * obj, const lv_style_t * style) //void lv_obj_set_style(lv_obj_t * obj, const lv_style_t * style)
//{
// LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
// if(style) {
// LV_ASSERT_STYLE(style);
// }
//
// obj->style_p = style;
//
// /*Send a signal about style change to every children with NULL style*/
// refresh_children_style(obj);
//
// /*Notify the object about the style change too*/
// lv_obj_refresh_style(obj);
//}
void lv_obj_set_style_color(lv_obj_t * obj, lv_style_property_t prop, lv_color_t color)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); lv_style_set_color(&obj->style_local, prop, color);
if(style) { }
LV_ASSERT_STYLE(style);
}
obj->style_p = style; void lv_obj_set_style_value(lv_obj_t * obj, lv_style_property_t prop, lv_style_value_t value)
{
lv_style_set_value(&obj->style_local, prop, value);
}
/*Send a signal about style change to every children with NULL style*/ void lv_obj_set_style_opa(lv_obj_t * obj, lv_style_property_t prop, lv_opa_t opa)
refresh_children_style(obj); {
lv_style_set_opa(&obj->style_local, prop, opa);
}
/*Notify the object about the style change too*/ void lv_obj_add_style_class(lv_obj_t * obj, lv_style_t * style)
lv_obj_refresh_style(obj); {
lv_obj_style_chian_t * s = lv_mem_alloc(sizeof(lv_obj_style_chian_t));
s->style = style;
/* Insert the class after the first item.
* (The first style is the local style, and the newest class should came after it.)*/
s->next = obj->style_chain.next;
obj->style_chain.next = s;
} }
/** /**
@ -1234,22 +1263,22 @@ void lv_obj_refresh_style(lv_obj_t * obj)
*/ */
void lv_obj_report_style_mod(lv_style_t * style) void lv_obj_report_style_mod(lv_style_t * style)
{ {
LV_ASSERT_STYLE(style); // LV_ASSERT_STYLE(style);
//
lv_disp_t * d = lv_disp_get_next(NULL); // lv_disp_t * d = lv_disp_get_next(NULL);
//
while(d) { // while(d) {
lv_obj_t * i; // lv_obj_t * i;
LV_LL_READ(d->scr_ll, i) // LV_LL_READ(d->scr_ll, i)
{ // {
if(i->style_p == style || style == NULL) { // if(i->style_p == style || style == NULL) {
lv_obj_refresh_style(i); // lv_obj_refresh_style(i);
} // }
//
report_style_mod_core(style, i); // report_style_mod_core(style, i);
} // }
d = lv_disp_get_next(d); // d = lv_disp_get_next(d);
} // }
} }
/*----------------- /*-----------------
@ -1272,7 +1301,7 @@ void lv_obj_set_hidden(lv_obj_t * obj, bool en)
if(!obj->hidden) lv_obj_invalidate(obj); /*Invalidate when not hidden (hidden objects are ignored) */ if(!obj->hidden) lv_obj_invalidate(obj); /*Invalidate when not hidden (hidden objects are ignored) */
lv_obj_t * par = lv_obj_get_parent(obj); lv_obj_t * par = lv_obj_get_parent(obj);
par->signal_cb(par, LV_SIGNAL_CHILD_CHG, obj); if(par) par->signal_cb(par, LV_SIGNAL_CHILD_CHG, obj);
} }
/** /**
@ -1782,14 +1811,16 @@ void lv_obj_get_inner_coords(const lv_obj_t * obj, lv_area_t * coords_p)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
const lv_style_t * style = lv_obj_get_style(obj); lv_border_part_t part = lv_obj_get_style_value(obj, LV_STYLE_BORDER_PART);
if(style->body.border.part & LV_BORDER_PART_LEFT) coords_p->x1 += style->body.border.width; lv_coord_t w = lv_obj_get_style_value(obj, LV_STYLE_BORDER_WIDTH);
if(style->body.border.part & LV_BORDER_PART_RIGHT) coords_p->x2 -= style->body.border.width; if(part & LV_BORDER_PART_LEFT) coords_p->x1 += w;
if(style->body.border.part & LV_BORDER_PART_TOP) coords_p->y1 += style->body.border.width; if(part & LV_BORDER_PART_RIGHT) coords_p->x2 -= w;
if(style->body.border.part & LV_BORDER_PART_BOTTOM) coords_p->y2 -= style->body.border.width; if(part & LV_BORDER_PART_TOP) coords_p->y1 += w;
if(part & LV_BORDER_PART_BOTTOM) coords_p->y2 -= w;
} }
/** /**
@ -1863,9 +1894,10 @@ lv_coord_t lv_obj_get_width_fit(const lv_obj_t * obj)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
const lv_style_t * style = lv_obj_get_style(obj); lv_style_value_t left = lv_obj_get_style_value(obj, LV_STYLE_PAD_LEFT);
lv_style_value_t right = lv_obj_get_style_value(obj, LV_STYLE_PAD_RIGHT);
return lv_obj_get_width(obj) - style->body.padding.left - style->body.padding.right; return lv_obj_get_width(obj) - left - right;
} }
/** /**
@ -1877,9 +1909,10 @@ lv_coord_t lv_obj_get_height_fit(const lv_obj_t * obj)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
const lv_style_t * style = lv_obj_get_style(obj); lv_style_value_t top = lv_obj_get_style_value(obj, LV_STYLE_PAD_TOP);
lv_style_value_t bottom = lv_obj_get_style_value(obj, LV_STYLE_PAD_BOTTOM);
return lv_obj_get_height(obj) - style->body.padding.top - style->body.padding.bottom; return lv_obj_get_height(obj) - top - bottom;
} }
/** /**
@ -1991,52 +2024,137 @@ lv_coord_t lv_obj_get_ext_draw_pad(const lv_obj_t * obj)
* Appearance get * Appearance get
*---------------*/ *---------------*/
/**
* Get the style pointer of an object (if NULL get style of the parent) lv_style_value_t lv_obj_get_style_value(const lv_obj_t * obj, lv_style_property_t prop)
* @param obj pointer to an object
* @return pointer to a style
*/
const lv_style_t * lv_obj_get_style(const lv_obj_t * obj)
{ {
LV_ASSERT_OBJ(obj, LV_OBJX_NAME); lv_res_t found = LV_RES_INV;
lv_style_value_t res;
const lv_style_t * style_act = obj->style_p; lv_style_attr_t attr;
if(style_act == NULL) { attr.full= prop >> 8;
lv_obj_t * par = obj->par;
while(par) { const lv_obj_t * parent = obj;
if(par->style_p) { while(parent) {
if(par->style_p->glass == 0) { const lv_obj_style_chian_t * chain = &obj->style_chain;
#if LV_USE_GROUP == 0 while(chain) {
style_act = par->style_p; found = lv_style_get_value(chain->style, prop, &res);
#else if(found == LV_RES_OK) {
/*If a parent is focused then use then focused style*/ return res;
lv_group_t * g = lv_obj_get_group(par); }
if(lv_group_get_focused(g) == par) { chain = chain->next;
style_act = lv_group_mod_style(g, par->style_p); }
} else {
style_act = par->style_p; if(attr.bits.inherit == 0) break;
} parent = lv_obj_get_parent(parent);
#endif
break;
}
}
par = par->par;
}
} }
#if LV_USE_GROUP
if(obj->group_p) { switch(prop) {
if(lv_group_get_focused(obj->group_p) == obj) { case LV_STYLE_BORDER_PART:
style_act = lv_group_mod_style(obj->group_p, style_act); return LV_BORDER_PART_FULL;
}
} }
#endif
if(style_act == NULL) style_act = &lv_style_plain; return 0;
return style_act;
} }
lv_color_t lv_obj_get_style_color(const lv_obj_t * obj, lv_style_property_t prop)
{
lv_res_t found = LV_RES_INV;
lv_color_t res;
lv_style_attr_t attr;
attr.full= prop >> 8;
const lv_obj_t * parent = obj;
while(parent) {
const lv_obj_style_chian_t * chain = &obj->style_chain;
while(chain) {
found = lv_style_get_color(chain->style, prop, &res);
if(found == LV_RES_OK) {
return res;
}
chain = chain->next;
}
if(attr.bits.inherit == 0) break;
parent = lv_obj_get_parent(parent);
}
return LV_COLOR_WHITE;
}
lv_opa_t lv_obj_get_style_opa(const lv_obj_t * obj, lv_style_property_t prop)
{
lv_res_t found = LV_RES_INV;
lv_opa_t res;
lv_style_attr_t attr;
attr.full= prop >> 8;
const lv_obj_t * parent = obj;
while(parent) {
const lv_obj_style_chian_t * chain = &obj->style_chain;
while(chain) {
found = lv_style_get_opa(chain->style, prop, &res);
if(found == LV_RES_OK) {
return res;
}
chain = chain->next;
}
if(attr.bits.inherit == 0) break;
parent = lv_obj_get_parent(parent);
}
return LV_OPA_COVER;
}
//
///**
// * Get the style pointer of an object (if NULL get style of the parent)
// * @param obj pointer to an object
// * @return pointer to a style
// */
//const lv_style_t * lv_obj_get_style(const lv_obj_t * obj)
//{
// LV_ASSERT_OBJ(obj, LV_OBJX_NAME);
//
// const lv_style_t * style_act = obj->style_p;
// if(style_act == NULL) {
// lv_obj_t * par = obj->par;
//
// while(par) {
// if(par->style_p) {
// if(par->style_p->glass == 0) {
//#if LV_USE_GROUP == 0
// style_act = par->style_p;
//#else
// /*If a parent is focused then use then focused style*/
// lv_group_t * g = lv_obj_get_group(par);
// if(lv_group_get_focused(g) == par) {
// style_act = lv_group_mod_style(g, par->style_p);
// } else {
// style_act = par->style_p;
// }
//#endif
// break;
// }
// }
// par = par->par;
// }
// }
//#if LV_USE_GROUP
// if(obj->group_p) {
// if(lv_group_get_focused(obj->group_p) == obj) {
// style_act = lv_group_mod_style(obj->group_p, style_act);
// }
// }
//#endif
//
// if(style_act == NULL) style_act = &lv_style_plain;
//
// return style_act;
//}
/*----------------- /*-----------------
* Attribute get * Attribute get
*----------------*/ *----------------*/
@ -2397,6 +2515,31 @@ static void lv_obj_del_async_cb(void * obj)
lv_obj_del(obj); lv_obj_del(obj);
} }
/**
* Initialize a rectangle descriptor from an object's styles
* @param obj pointer to an object
* @param chain an extra style chain to evaluate before processing the object's styles
* @param dsc the descriptor the initialize
* @note Only the relevant fields will be set.
* E.g. if `border width == 0` the other border properties won't be evaluated.
*/
void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, lv_obj_style_chian_t * chain, lv_draw_rect_dsc_t * dsc)
{
lv_draw_rect_dsc_init(dsc);
dsc->radius = lv_obj_get_style_value(obj, LV_STYLE_RADIUS);
dsc->bg_color = lv_obj_get_style_color(obj, LV_STYLE_BG_COLOR);
dsc->border_width = lv_obj_get_style_value(obj, LV_STYLE_BORDER_WIDTH);
if(dsc->border_width) {
dsc->border_opa = lv_obj_get_style_opa(obj, LV_STYLE_BORDER_OPA);
if(dsc->border_opa >= LV_OPA_MIN) {
dsc->border_part = lv_obj_get_style_value(obj, LV_STYLE_BORDER_PART);
dsc->border_color = lv_obj_get_style_color(obj, LV_STYLE_BORDER_COLOR);
}
}
}
/** /**
* Handle the drawing related tasks of the base objects. * Handle the drawing related tasks of the base objects.
* @param obj pointer to an object * @param obj pointer to an object
@ -2412,15 +2555,17 @@ static lv_design_res_t lv_obj_design(lv_obj_t * obj, const lv_area_t * clip_area
/*Most trivial test. Is the mask fully IN the object? If no it surely doesn't cover it*/ /*Most trivial test. Is the mask fully IN the object? If no it surely doesn't cover it*/
if(lv_area_is_in(clip_area, &obj->coords) == false) return LV_DESIGN_RES_NOT_COVER; if(lv_area_is_in(clip_area, &obj->coords) == false) return LV_DESIGN_RES_NOT_COVER;
const lv_style_t * style = lv_obj_get_style(obj); if(lv_obj_get_style_value(obj, LV_STYLE_BG_BLEND_MODE) != LV_BLEND_MODE_NORMAL) return LV_DESIGN_RES_NOT_COVER;
if(style->body.corner_mask) return LV_DESIGN_RES_MASKED; if(lv_obj_get_style_value(obj, LV_STYLE_BORDER_BLEND_MODE) != LV_BLEND_MODE_NORMAL) return LV_DESIGN_RES_NOT_COVER;
if(lv_obj_get_style_value(obj, LV_STYLE_BG_CLIP_CORNER)) return LV_DESIGN_RES_MASKED;
/*Can cover the area only if fully solid (no opacity)*/ /*Can cover the area only if fully solid (no opacity)*/
if(style->body.opa < LV_OPA_MAX) return LV_DESIGN_RES_NOT_COVER; if(lv_obj_get_style_opa(obj, LV_STYLE_BG_OPA) < LV_OPA_MAX) return LV_DESIGN_RES_NOT_COVER;
/* Because of the radius it is not sure the area is covered /* Because of the radius it is not sure the area is covered
* Check the areas where there is no radius*/ * Check the areas where there is no radius*/
lv_coord_t r = style->body.radius; lv_coord_t r = lv_obj_get_style_value(obj, LV_STYLE_RADIUS);
if(r == LV_RADIUS_CIRCLE) return LV_DESIGN_RES_NOT_COVER; if(r == LV_RADIUS_CIRCLE) return LV_DESIGN_RES_NOT_COVER;
@ -2442,20 +2587,23 @@ static lv_design_res_t lv_obj_design(lv_obj_t * obj, const lv_area_t * clip_area
} }
else if(mode == LV_DESIGN_DRAW_MAIN) { else if(mode == LV_DESIGN_DRAW_MAIN) {
const lv_style_t * style = lv_obj_get_style(obj); lv_draw_rect_dsc_t draw_dsc;
lv_draw_rect(&obj->coords, clip_area, style, lv_obj_get_opa_scale(obj)); lv_obj_init_draw_rect_dsc(obj, NULL, &draw_dsc);
lv_draw_rect(&obj->coords, clip_area, &draw_dsc, lv_obj_get_opa_scale(obj));
if(style->body.corner_mask) { if(lv_obj_get_style_value(obj, LV_STYLE_BG_CLIP_CORNER)) {
lv_draw_mask_radius_param_t * mp = lv_mem_buf_get(sizeof(lv_draw_mask_radius_param_t)); lv_draw_mask_radius_param_t * mp = lv_mem_buf_get(sizeof(lv_draw_mask_radius_param_t));
lv_draw_mask_radius_init(mp, &obj->coords, style->body.radius, false); lv_coord_t r = lv_obj_get_style_value(obj, LV_STYLE_RADIUS);
lv_draw_mask_radius_init(mp, &obj->coords, r, false);
/*Add the mask and use `obj+8` as custom id. Don't use `obj` directly because it might be used by the user*/ /*Add the mask and use `obj+8` as custom id. Don't use `obj` directly because it might be used by the user*/
lv_draw_mask_add(mp, obj + 8); lv_draw_mask_add(mp, obj + 8);
} }
} }
else if(mode == LV_DESIGN_DRAW_POST) { else if(mode == LV_DESIGN_DRAW_POST) {
const lv_style_t * style = lv_obj_get_style(obj); // const lv_style_t * style = lv_obj_get_style(obj);
if(style->body.corner_mask) { if(lv_obj_get_style_value(obj, LV_STYLE_BG_CLIP_CORNER)) {
lv_draw_mask_radius_param_t * param = lv_draw_mask_remove_custom(obj + 8); lv_draw_mask_radius_param_t * param = lv_draw_mask_remove_custom(obj + 8);
lv_mem_buf_release(param); lv_mem_buf_release(param);
} }
@ -2481,10 +2629,9 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
/*Return 'invalid' if the child change signal is not enabled*/ /*Return 'invalid' if the child change signal is not enabled*/
if(lv_obj_is_protected(obj, LV_PROTECT_CHILD_CHG) != false) res = LV_RES_INV; if(lv_obj_is_protected(obj, LV_PROTECT_CHILD_CHG) != false) res = LV_RES_INV;
} else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) { } else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
const lv_style_t * style = lv_obj_get_style(obj); lv_coord_t shadow = (lv_obj_get_style_value(obj, LV_STYLE_SHADOW_WIDTH) >> 1) + 1;
lv_coord_t shadow = (style->body.shadow.width >> 1) + 1; shadow += lv_obj_get_style_value(obj, LV_STYLE_SHADOW_SPREAD);
shadow += style->body.shadow.spread; shadow += LV_MATH_MAX(LV_MATH_ABS(lv_obj_get_style_value(obj, LV_STYLE_SHADOW_OFFSET_X)), LV_MATH_ABS(lv_obj_get_style_value(obj, LV_STYLE_SHADOW_OFFSET_Y)));
shadow += LV_MATH_MAX(LV_MATH_ABS(style->body.shadow.offset.x), LV_MATH_ABS(style->body.shadow.offset.y));
if(shadow > obj->ext_draw_pad) obj->ext_draw_pad = shadow; if(shadow > obj->ext_draw_pad) obj->ext_draw_pad = shadow;
} else if(sign == LV_SIGNAL_STYLE_CHG) { } else if(sign == LV_SIGNAL_STYLE_CHG) {
@ -2520,16 +2667,16 @@ static void refresh_children_position(lv_obj_t * obj, lv_coord_t x_diff, lv_coor
*/ */
static void report_style_mod_core(void * style_p, lv_obj_t * obj) static void report_style_mod_core(void * style_p, lv_obj_t * obj)
{ {
lv_obj_t * i; // lv_obj_t * i;
LV_LL_READ(obj->child_ll, i) // LV_LL_READ(obj->child_ll, i)
{ // {
if(i->style_p == style_p || style_p == NULL) { // if(i->style.local == style_p || style_p == NULL) {
refresh_children_style(i); // refresh_children_style(i);
lv_obj_refresh_style(i); // lv_obj_refresh_style(i);
} // }
//
report_style_mod_core(style_p, i); // report_style_mod_core(style_p, i);
} // }
} }
/** /**
@ -2539,17 +2686,17 @@ static void report_style_mod_core(void * style_p, lv_obj_t * obj)
*/ */
static void refresh_children_style(lv_obj_t * obj) static void refresh_children_style(lv_obj_t * obj)
{ {
lv_obj_t * child = lv_obj_get_child(obj, NULL); // lv_obj_t * child = lv_obj_get_child(obj, NULL);
while(child != NULL) { // while(child != NULL) {
if(child->style_p == NULL) { // if(child->style_p == NULL) {
refresh_children_style(child); /*Check children too*/ // refresh_children_style(child); /*Check children too*/
lv_obj_refresh_style(child); /*Notify the child about the style change*/ // lv_obj_refresh_style(child); /*Notify the child about the style change*/
} else if(child->style_p->glass) { // } else if(child->style_p->glass) {
/*Children with 'glass' parent might be effected if their style == NULL*/ // /*Children with 'glass' parent might be effected if their style == NULL*/
refresh_children_style(child); // refresh_children_style(child);
} // }
child = lv_obj_get_child(obj, child); // child = lv_obj_get_child(obj, child);
} // }
} }
/** /**

View File

@ -187,6 +187,11 @@ typedef struct
} lv_reailgn_t; } lv_reailgn_t;
#endif #endif
typedef struct _lv_obj_style_chian_t {
lv_style_t * style;
struct _lv_obj_style_chian_t * next;
}lv_obj_style_chian_t;
typedef struct _lv_obj_t typedef struct _lv_obj_t
{ {
struct _lv_obj_t * par; /**< Pointer to the parent object*/ struct _lv_obj_t * par; /**< Pointer to the parent object*/
@ -199,7 +204,8 @@ typedef struct _lv_obj_t
lv_design_cb_t design_cb; /**< Object type specific design function*/ lv_design_cb_t design_cb; /**< Object type specific design function*/
void * ext_attr; /**< Object type specific extended data*/ void * ext_attr; /**< Object type specific extended data*/
const lv_style_t * style_p; /**< Pointer to the object's style*/ lv_style_t style_local;
lv_obj_style_chian_t style_chain;
#if LV_USE_GROUP != 0 #if LV_USE_GROUP != 0
void * group_p; /**< Pointer to the group of the object*/ void * group_p; /**< Pointer to the group of the object*/
@ -442,6 +448,12 @@ void lv_obj_set_ext_click_area(lv_obj_t * obj, lv_coord_t left, lv_coord_t right
*/ */
void lv_obj_set_style(lv_obj_t * obj, const lv_style_t * style); void lv_obj_set_style(lv_obj_t * obj, const lv_style_t * style);
void lv_obj_set_style_color(lv_obj_t * obj, lv_style_property_t prop, lv_color_t color);
void lv_obj_set_style_value(lv_obj_t * obj, lv_style_property_t prop, lv_style_value_t value);
void lv_obj_set_style_opa(lv_obj_t * obj, lv_style_property_t prop, lv_opa_t opa);
/** /**
* Notify an object about its style is modified * Notify an object about its style is modified
* @param obj pointer to an object * @param obj pointer to an object
@ -790,12 +802,18 @@ lv_coord_t lv_obj_get_ext_draw_pad(const lv_obj_t * obj);
* Appearance get * Appearance get
*---------------*/ *---------------*/
/** lv_style_value_t lv_obj_get_style_value(const lv_obj_t * obj, lv_style_property_t prop);
* Get the style pointer of an object (if NULL get style of the parent)
* @param obj pointer to an object lv_color_t lv_obj_get_style_color(const lv_obj_t * obj, lv_style_property_t prop);
* @return pointer to a style
*/ lv_opa_t lv_obj_get_style_opa(const lv_obj_t * obj, lv_style_property_t prop);
const lv_style_t * lv_obj_get_style(const lv_obj_t * obj);
///**
// * Get the style pointer of an object (if NULL get style of the parent)
// * @param obj pointer to an object
// * @return pointer to a style
// */
//const lv_style_t * lv_obj_get_style(const lv_obj_t * obj);
/*----------------- /*-----------------
* Attribute get * Attribute get

View File

@ -435,12 +435,8 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj)
/*If no better children check this object*/ /*If no better children check this object*/
if(found_p == NULL) { if(found_p == NULL) {
const lv_style_t * style = lv_obj_get_style(obj); if(lv_obj_get_style_value(obj, LV_STYLE_BG_OPA) == LV_OPA_COVER && design_res == LV_DESIGN_RES_COVER &&
if(style->body.opa == LV_OPA_COVER && design_res == LV_DESIGN_RES_COVER && lv_obj_get_opa_scale(obj) == LV_OPA_COVER) {
lv_obj_get_opa_scale(obj) == LV_OPA_COVER &&
style->body.blend_mode == LV_BLEND_MODE_NORMAL &&
style->body.border.blend_mode == LV_BLEND_MODE_NORMAL &&
style->image.blend_mode == LV_BLEND_MODE_NORMAL) {
found_p = obj; found_p = obj;
} }
} }

View File

@ -25,6 +25,9 @@
res->attr = start->attr; \ res->attr = start->attr; \
} }
#define LV_STYLE_PROP_TO_ID(prop) (prop & 0xFF);
#define LV_STYLE_PROP_GET_TYPE(prop) ((prop >> 8) & 0xFF);
/********************** /**********************
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
@ -32,6 +35,7 @@
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
static inline int32_t get_property_index(const lv_style_t * style, lv_style_property_t prop);
#if LV_USE_ANIMATION #if LV_USE_ANIMATION
static void style_animator(lv_style_anim_dsc_t * dsc, lv_anim_value_t val); static void style_animator(lv_style_anim_dsc_t * dsc, lv_anim_value_t val);
static void style_animation_common_end_cb(lv_anim_t * a); static void style_animation_common_end_cb(lv_anim_t * a);
@ -40,19 +44,19 @@ static void style_animation_common_end_cb(lv_anim_t * a);
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
**********************/ **********************/
lv_style_t lv_style_scr; //lv_style_t lv_style_scr;
lv_style_t lv_style_transp; //lv_style_t lv_style_transp;
lv_style_t lv_style_transp_fit; //lv_style_t lv_style_transp_fit;
lv_style_t lv_style_transp_tight; //lv_style_t lv_style_transp_tight;
lv_style_t lv_style_plain; //lv_style_t lv_style_plain;
lv_style_t lv_style_plain_color; //lv_style_t lv_style_plain_color;
lv_style_t lv_style_pretty; //lv_style_t lv_style_pretty;
lv_style_t lv_style_pretty_color; //lv_style_t lv_style_pretty_color;
lv_style_t lv_style_btn_rel; //lv_style_t lv_style_btn_rel;
lv_style_t lv_style_btn_pr; //lv_style_t lv_style_btn_pr;
lv_style_t lv_style_btn_tgl_rel; //lv_style_t lv_style_btn_tgl_rel;
lv_style_t lv_style_btn_tgl_pr; //lv_style_t lv_style_btn_tgl_pr;
lv_style_t lv_style_btn_ina; //lv_style_t lv_style_btn_ina;
/********************** /**********************
* MACROS * MACROS
@ -63,182 +67,18 @@ lv_style_t lv_style_btn_ina;
**********************/ **********************/
/** /**
* Init the basic styles * Init. the built-in styles
*/ */
void lv_style_init(void) void lv_style_built_in_init(void)
{ {
/* Not White/Black/Gray colors are created by HSV model with
* HUE = 210*/
/*Screen style*/ }
lv_style_scr.glass = 0;
lv_style_scr.body.opa = LV_OPA_COVER;
lv_style_scr.body.main_color = LV_COLOR_WHITE;
lv_style_scr.body.grad_color = LV_COLOR_WHITE;
lv_style_scr.body.main_color_stop = 0;
lv_style_scr.body.grad_color_stop = 255;
lv_style_scr.body.grad_dir = LV_GRAD_DIR_VER;
lv_style_scr.body.radius = 0;
lv_style_scr.body.blend_mode = LV_BLEND_MODE_NORMAL;
lv_style_scr.body.padding.left = 0;
lv_style_scr.body.padding.right = 0;
lv_style_scr.body.padding.top = 0;
lv_style_scr.body.padding.bottom = 0;
lv_style_scr.body.padding.inner = LV_DPI / 20;
lv_style_scr.body.border.color = LV_COLOR_BLACK; void lv_style_init(lv_style_t * style)
lv_style_scr.body.border.opa = LV_OPA_COVER; {
lv_style_scr.body.border.width = 0; style->map = NULL;
lv_style_scr.body.border.part = LV_BORDER_PART_FULL; style->size = 0;
lv_style_scr.body.border.blend_mode = LV_BLEND_MODE_NORMAL; style->used_groups = 0;
lv_style_scr.body.shadow.color = LV_COLOR_GRAY;
lv_style_scr.body.shadow.width = 0;
lv_style_scr.body.shadow.opa = LV_OPA_COVER;
lv_style_scr.body.shadow.offset.x = 0;
lv_style_scr.body.shadow.offset.y = 0;
lv_style_scr.body.shadow.spread = 0;
lv_style_scr.body.shadow.blend_mode = LV_BLEND_MODE_NORMAL;
lv_style_scr.text.opa = LV_OPA_COVER;
lv_style_scr.text.color = lv_color_make(0x30, 0x30, 0x30);
lv_style_scr.text.sel_color = lv_color_make(0x55, 0x96, 0xd8);
lv_style_scr.text.font = LV_FONT_DEFAULT;
lv_style_scr.text.letter_space = 0;
lv_style_scr.text.line_space = 2;
lv_style_scr.text.blend_mode = LV_BLEND_MODE_NORMAL;
lv_style_scr.text.underline = 0;
lv_style_scr.text.strikethrough = 0;
lv_style_scr.image.opa = LV_OPA_COVER;
lv_style_scr.image.color = lv_color_make(0x20, 0x20, 0x20);
lv_style_scr.image.intense = LV_OPA_TRANSP;
lv_style_scr.image.blend_mode = LV_BLEND_MODE_NORMAL;
lv_style_scr.line.opa = LV_OPA_COVER;
lv_style_scr.line.color = lv_color_make(0x20, 0x20, 0x20);
lv_style_scr.line.width = 2;
lv_style_scr.line.rounded = 0;
lv_style_scr.line.blend_mode = LV_BLEND_MODE_NORMAL;
#if LV_USE_DEBUG
#if LV_USE_ASSERT_STYLE
lv_style_scr.debug_sentinel = LV_STYLE_DEGUG_SENTINEL_VALUE;
#endif
#endif
/*Plain style (by default near the same as the screen style)*/
lv_style_copy(&lv_style_plain, &lv_style_scr);
lv_style_plain.body.opa = LV_OPA_COVER;
lv_style_plain.body.padding.left = LV_DPI / 20;
lv_style_plain.body.padding.right = LV_DPI / 20;
lv_style_plain.body.padding.top = LV_DPI / 20;
lv_style_plain.body.padding.bottom = LV_DPI / 20;
/*Plain color style*/
lv_style_copy(&lv_style_plain_color, &lv_style_plain);
lv_style_plain_color.text.color = lv_color_make(0xf0, 0xf0, 0xf0);
lv_style_plain_color.image.color = lv_color_make(0xf0, 0xf0, 0xf0);
lv_style_plain_color.line.color = lv_color_make(0xf0, 0xf0, 0xf0);
lv_style_plain_color.body.main_color = lv_color_make(0x55, 0x96, 0xd8);
lv_style_plain_color.body.grad_color = lv_style_plain_color.body.main_color;
/*Pretty style */
lv_style_copy(&lv_style_pretty, &lv_style_plain);
lv_style_pretty.text.color = lv_color_make(0x20, 0x20, 0x20);
lv_style_pretty.image.color = lv_color_make(0x20, 0x20, 0x20);
lv_style_pretty.line.color = lv_color_make(0x20, 0x20, 0x20);
lv_style_pretty.body.main_color = LV_COLOR_WHITE;
lv_style_pretty.body.grad_color = LV_COLOR_SILVER;
lv_style_pretty.body.radius = LV_DPI / 15;
lv_style_pretty.body.border.color = lv_color_make(0x40, 0x40, 0x40);
lv_style_pretty.body.border.width = LV_DPI / 50 >= 1 ? LV_DPI / 50 : 1;
lv_style_pretty.body.border.opa = LV_OPA_30;
/*Pretty color style*/
lv_style_copy(&lv_style_pretty_color, &lv_style_pretty);
lv_style_pretty_color.text.color = lv_color_make(0xe0, 0xe0, 0xe0);
lv_style_pretty_color.image.color = lv_color_make(0xe0, 0xe0, 0xe0);
lv_style_pretty_color.line.color = lv_color_make(0xc0, 0xc0, 0xc0);
lv_style_pretty_color.body.main_color = lv_color_make(0x6b, 0x9a, 0xc7);
lv_style_pretty_color.body.grad_color = lv_color_make(0x2b, 0x59, 0x8b);
lv_style_pretty_color.body.border.color = lv_color_make(0x15, 0x2c, 0x42);
/*Transparent style*/
lv_style_copy(&lv_style_transp, &lv_style_plain);
lv_style_transp.glass = 1;
lv_style_transp.body.border.width = 0;
lv_style_transp.body.opa = LV_OPA_TRANSP;
/*Transparent fitting size*/
lv_style_copy(&lv_style_transp_fit, &lv_style_transp);
lv_style_transp_fit.body.padding.left = 0;
lv_style_transp_fit.body.padding.right = 0;
lv_style_transp_fit.body.padding.top = 0;
lv_style_transp_fit.body.padding.bottom = 0;
/*Transparent tight style*/
lv_style_copy(&lv_style_transp_tight, &lv_style_transp_fit);
lv_style_transp_tight.body.padding.inner = 0;
/*Button released style*/
lv_style_copy(&lv_style_btn_rel, &lv_style_plain);
lv_style_btn_rel.body.main_color = lv_color_make(0x76, 0xa2, 0xd0);
lv_style_btn_rel.body.grad_color = lv_color_make(0x19, 0x3a, 0x5d);
lv_style_btn_rel.body.main_color_stop = 0x00;
lv_style_btn_rel.body.grad_color_stop = 0xff;;
lv_style_btn_rel.body.grad_dir = LV_GRAD_DIR_VER;
lv_style_btn_rel.body.radius = LV_DPI / 15;
lv_style_btn_rel.body.opa = LV_OPA_COVER;
lv_style_btn_rel.body.padding.left = LV_DPI / 4;
lv_style_btn_rel.body.padding.right = LV_DPI / 4;
lv_style_btn_rel.body.padding.top = LV_DPI / 6;
lv_style_btn_rel.body.padding.bottom = LV_DPI / 6;
lv_style_btn_rel.body.padding.inner = LV_DPI / 10;
lv_style_btn_rel.body.border.color = lv_color_make(0x0b, 0x19, 0x28);
lv_style_btn_rel.body.border.width = LV_DPI / 50 >= 1 ? LV_DPI / 50 : 1;
lv_style_btn_rel.body.border.opa = LV_OPA_70;
lv_style_btn_rel.body.shadow.color = LV_COLOR_BLACK;
lv_style_btn_rel.body.shadow.width = 0;
lv_style_btn_rel.body.shadow.opa = LV_OPA_COVER;
lv_style_btn_rel.body.shadow.offset.x = 0;
lv_style_btn_rel.body.shadow.offset.y = 0;
lv_style_btn_rel.text.color = lv_color_make(0xff, 0xff, 0xff);
lv_style_btn_rel.image.color = lv_color_make(0xff, 0xff, 0xff);
/*Button pressed style*/
lv_style_copy(&lv_style_btn_pr, &lv_style_btn_rel);
lv_style_btn_pr.body.main_color = lv_color_make(0x33, 0x62, 0x94);
lv_style_btn_pr.body.grad_color = lv_color_make(0x10, 0x26, 0x3c);
lv_style_btn_pr.text.color = lv_color_make(0xa4, 0xb5, 0xc6);
lv_style_btn_pr.image.color = lv_color_make(0xa4, 0xb5, 0xc6);
lv_style_btn_pr.line.color = lv_color_make(0xa4, 0xb5, 0xc6);
/*Button toggle released style*/
lv_style_copy(&lv_style_btn_tgl_rel, &lv_style_btn_rel);
lv_style_btn_tgl_rel.body.main_color = lv_color_make(0x0a, 0x11, 0x22);
lv_style_btn_tgl_rel.body.grad_color = lv_color_make(0x37, 0x62, 0x90);
lv_style_btn_tgl_rel.body.border.color = lv_color_make(0x01, 0x07, 0x0d);
lv_style_btn_tgl_rel.text.color = lv_color_make(0xc8, 0xdd, 0xf4);
lv_style_btn_tgl_rel.image.color = lv_color_make(0xc8, 0xdd, 0xf4);
lv_style_btn_tgl_rel.line.color = lv_color_make(0xc8, 0xdd, 0xf4);
/*Button toggle pressed style*/
lv_style_copy(&lv_style_btn_tgl_pr, &lv_style_btn_tgl_rel);
lv_style_btn_tgl_pr.body.main_color = lv_color_make(0x02, 0x14, 0x27);
lv_style_btn_tgl_pr.body.grad_color = lv_color_make(0x2b, 0x4c, 0x70);
lv_style_btn_tgl_pr.text.color = lv_color_make(0xa4, 0xb5, 0xc6);
lv_style_btn_tgl_pr.image.color = lv_color_make(0xa4, 0xb5, 0xc6);
lv_style_btn_tgl_pr.line.color = lv_color_make(0xa4, 0xb5, 0xc6);
/*Button inactive style*/
lv_style_copy(&lv_style_btn_ina, &lv_style_btn_rel);
lv_style_btn_ina.body.main_color = lv_color_make(0xd8, 0xd8, 0xd8);
lv_style_btn_ina.body.grad_color = lv_color_make(0xd8, 0xd8, 0xd8);
lv_style_btn_ina.body.border.color = lv_color_make(0x90, 0x90, 0x90);
lv_style_btn_ina.text.color = lv_color_make(0x70, 0x70, 0x70);
lv_style_btn_ina.image.color = lv_color_make(0x70, 0x70, 0x70);
lv_style_btn_ina.line.color = lv_color_make(0x70, 0x70, 0x70);
} }
/** /**
@ -251,6 +91,102 @@ void lv_style_copy(lv_style_t * dest, const lv_style_t * src)
memcpy(dest, src, sizeof(lv_style_t)); memcpy(dest, src, sizeof(lv_style_t));
} }
void lv_style_set_value(lv_style_t * style, lv_style_property_t prop, lv_style_value_t value)
{
int32_t id = get_property_index(style, prop);
/*If exists update the property*/
if(id >= 0) {
memcpy(style->map + id + sizeof(lv_style_property_t), &value, sizeof(lv_style_value_t));
}
/*Add new property if not exists yet*/
else {
style->size += sizeof(lv_style_property_t) + sizeof(lv_style_value_t);
style->map = lv_mem_realloc(style->map, style->size);
LV_ASSERT_MEM(style->map);
if(style->map == NULL) return;
memcpy(style->map + style->size - (sizeof(lv_style_property_t) + sizeof(lv_style_value_t)), &prop, sizeof(lv_style_property_t));
memcpy(style->map + style->size - sizeof(lv_style_value_t), &value, sizeof(lv_style_value_t));
}
}
void lv_style_set_color(lv_style_t * style, lv_style_property_t prop, lv_color_t color)
{
int32_t id = get_property_index(style, prop);
/*If exists update the property*/
if(id >= 0) {
memcpy(style->map + id + sizeof(lv_style_property_t), &color, sizeof(lv_color_t));
}
/*Add new property if not exists yet*/
else {
style->size += sizeof(lv_style_property_t) + sizeof(lv_color_t);
style->map = lv_mem_realloc(style->map, style->size);
LV_ASSERT_MEM(style->map);
if(style == NULL) return;
memcpy(style->map + style->size - (sizeof(lv_style_property_t) + sizeof(lv_color_t)), &prop, sizeof(lv_style_property_t));
memcpy(style->map + style->size - sizeof(lv_color_t), &color, sizeof(lv_color_t));
}
}
void lv_style_set_opa(lv_style_t * style, lv_style_property_t prop, lv_opa_t opa)
{
int32_t id = get_property_index(style, prop);
/*If exists update the property*/
if(id >= 0) {
memcpy(style->map + id + sizeof(lv_style_property_t), &opa, sizeof(lv_opa_t));
}
/*Add new property if not exists yet*/
else {
style->size += sizeof(lv_style_property_t) + sizeof(lv_opa_t);
style->map = lv_mem_realloc(style->map, style->size);
LV_ASSERT_MEM(style->map);
if(style == NULL) return;
memcpy(style->map + style->size - (sizeof(lv_style_property_t) + sizeof(lv_opa_t)), &prop, sizeof(lv_style_property_t));
memcpy(style->map + style->size - sizeof(lv_opa_t), &opa, sizeof(lv_opa_t));
}
}
lv_res_t lv_style_get_value(const lv_style_t * style, lv_style_property_t prop, lv_style_value_t * res)
{
int32_t id = get_property_index(style, prop);
if(id < 0) {
res = 0;
return LV_RES_INV;
} else {
memcpy(res, &style->map[id + sizeof(lv_style_property_t)], sizeof(lv_style_value_t));
return LV_RES_OK;
}
}
lv_res_t lv_style_get_opa(const lv_style_t * style, lv_style_property_t prop, lv_opa_t * res)
{
int32_t id = get_property_index(style, prop);
if(id < 0) {
res = 0;
return LV_RES_INV;
} else {
memcpy(res, &style->map[id + sizeof(lv_style_property_t)], sizeof(lv_opa_t));
return LV_RES_OK;
}
}
lv_res_t lv_style_get_color(const lv_style_t * style, lv_style_property_t prop, lv_color_t * res)
{
int32_t id = get_property_index(style, prop);
if(id < 0) {
res = 0;
return LV_RES_INV;
} else {
memcpy(res, &style->map[id + sizeof(lv_style_property_t)], sizeof(lv_color_t));
return LV_RES_OK;
}
}
/** /**
* Mix two styles according to a given ratio * Mix two styles according to a given ratio
* @param start start style * @param start start style
@ -260,48 +196,48 @@ void lv_style_copy(lv_style_t * dest, const lv_style_t * src)
*/ */
void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * res, uint16_t ratio) void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * res, uint16_t ratio)
{ {
STYLE_ATTR_MIX(body.opa, ratio); // STYLE_ATTR_MIX(body.opa, ratio);
STYLE_ATTR_MIX(body.radius, ratio); // STYLE_ATTR_MIX(body.radius, ratio);
STYLE_ATTR_MIX(body.border.width, ratio); // STYLE_ATTR_MIX(body.border.width, ratio);
STYLE_ATTR_MIX(body.border.opa, ratio); // STYLE_ATTR_MIX(body.border.opa, ratio);
STYLE_ATTR_MIX(body.shadow.width, ratio); // STYLE_ATTR_MIX(body.shadow.width, ratio);
STYLE_ATTR_MIX(body.shadow.offset.x, ratio); // STYLE_ATTR_MIX(body.shadow.offset.x, ratio);
STYLE_ATTR_MIX(body.shadow.offset.y, ratio); // STYLE_ATTR_MIX(body.shadow.offset.y, ratio);
STYLE_ATTR_MIX(body.shadow.spread, ratio); // STYLE_ATTR_MIX(body.shadow.spread, ratio);
STYLE_ATTR_MIX(body.padding.left, ratio); // STYLE_ATTR_MIX(body.padding.left, ratio);
STYLE_ATTR_MIX(body.padding.right, ratio); // STYLE_ATTR_MIX(body.padding.right, ratio);
STYLE_ATTR_MIX(body.padding.top, ratio); // STYLE_ATTR_MIX(body.padding.top, ratio);
STYLE_ATTR_MIX(body.padding.bottom, ratio); // STYLE_ATTR_MIX(body.padding.bottom, ratio);
STYLE_ATTR_MIX(body.padding.inner, ratio); // STYLE_ATTR_MIX(body.padding.inner, ratio);
STYLE_ATTR_MIX(text.line_space, ratio); // STYLE_ATTR_MIX(text.line_space, ratio);
STYLE_ATTR_MIX(text.letter_space, ratio); // STYLE_ATTR_MIX(text.letter_space, ratio);
STYLE_ATTR_MIX(text.opa, ratio); // STYLE_ATTR_MIX(text.opa, ratio);
STYLE_ATTR_MIX(line.width, ratio); // STYLE_ATTR_MIX(line.width, ratio);
STYLE_ATTR_MIX(line.opa, ratio); // STYLE_ATTR_MIX(line.opa, ratio);
STYLE_ATTR_MIX(image.intense, ratio); // STYLE_ATTR_MIX(image.intense, ratio);
STYLE_ATTR_MIX(image.opa, ratio); // STYLE_ATTR_MIX(image.opa, ratio);
//
lv_opa_t opa = ratio == STYLE_MIX_MAX ? LV_OPA_COVER : ratio; // lv_opa_t opa = ratio == STYLE_MIX_MAX ? LV_OPA_COVER : ratio;
//
res->body.main_color = lv_color_mix(end->body.main_color, start->body.main_color, opa); // res->body.main_color = lv_color_mix(end->body.main_color, start->body.main_color, opa);
res->body.grad_color = lv_color_mix(end->body.grad_color, start->body.grad_color, opa); // res->body.grad_color = lv_color_mix(end->body.grad_color, start->body.grad_color, opa);
res->body.border.color = lv_color_mix(end->body.border.color, start->body.border.color, opa); // res->body.border.color = lv_color_mix(end->body.border.color, start->body.border.color, opa);
res->body.shadow.color = lv_color_mix(end->body.shadow.color, start->body.shadow.color, opa); // res->body.shadow.color = lv_color_mix(end->body.shadow.color, start->body.shadow.color, opa);
res->text.color = lv_color_mix(end->text.color, start->text.color, opa); // res->text.color = lv_color_mix(end->text.color, start->text.color, opa);
res->image.color = lv_color_mix(end->image.color, start->image.color, opa); // res->image.color = lv_color_mix(end->image.color, start->image.color, opa);
res->line.color = lv_color_mix(end->line.color, start->line.color, opa); // res->line.color = lv_color_mix(end->line.color, start->line.color, opa);
//
if(ratio < (STYLE_MIX_MAX >> 1)) { // if(ratio < (STYLE_MIX_MAX >> 1)) {
res->body.border.part = start->body.border.part; // res->body.border.part = start->body.border.part;
res->glass = start->glass; // res->glass = start->glass;
res->text.font = start->text.font; // res->text.font = start->text.font;
res->line.rounded = start->line.rounded; // res->line.rounded = start->line.rounded;
} else { // } else {
res->body.border.part = end->body.border.part; // res->body.border.part = end->body.border.part;
res->glass = end->glass; // res->glass = end->glass;
res->text.font = end->text.font; // res->text.font = end->text.font;
res->line.rounded = end->line.rounded; // res->line.rounded = end->line.rounded;
} // }
} }
#if LV_USE_ANIMATION #if LV_USE_ANIMATION
@ -340,6 +276,41 @@ void lv_style_anim_set_styles(lv_anim_t * a, lv_style_t * to_anim, const lv_styl
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
static inline int32_t get_property_index(const lv_style_t * style, lv_style_property_t prop)
{
uint8_t id_to_find = prop & 0xFF;
size_t i = 0;
while(i < style->size) {
if(style->map[i] == id_to_find) {
return i;
} else {
lv_style_attr_t attr;
attr.full = style->map[i + 1];
switch(attr.bits.type) {
case LV_STYLE_ATTR_TYPE_VALUE:
i+= sizeof(lv_style_value_t);
break;
case LV_STYLE_ATTR_TYPE_OPA:
i+= sizeof(lv_opa_t);
break;
case LV_STYLE_ATTR_TYPE_COLOR:
i+= sizeof(lv_color_t);
break;
case LV_STYLE_ATTR_TYPE_PTR:
i+= sizeof(void*);
break;
}
i += sizeof(lv_style_property_t);
}
}
return -1;
}
#if LV_USE_ANIMATION #if LV_USE_ANIMATION
/** /**
* Used by the style animations to set the values of a style according to start and end style. * Used by the style animations to set the values of a style according to start and end style.

View File

@ -18,6 +18,7 @@ extern "C" {
#include "../lv_misc/lv_color.h" #include "../lv_misc/lv_color.h"
#include "../lv_misc/lv_area.h" #include "../lv_misc/lv_area.h"
#include "../lv_misc/lv_anim.h" #include "../lv_misc/lv_anim.h"
#include "../lv_misc/lv_types.h"
#include "../lv_draw/lv_draw_blend.h" #include "../lv_draw/lv_draw_blend.h"
/********************* /*********************
@ -44,8 +45,6 @@ enum {
}; };
typedef uint8_t lv_border_part_t; typedef uint8_t lv_border_part_t;
enum { enum {
LV_GRAD_DIR_NONE, LV_GRAD_DIR_NONE,
LV_GRAD_DIR_VER, LV_GRAD_DIR_VER,
@ -54,100 +53,63 @@ enum {
typedef uint8_t lv_grad_dir_t; typedef uint8_t lv_grad_dir_t;
/** #define LV_STYLE_PROP_INIT(name, id, attr) name = (id | ((attr) << 8))
* Styles can be assigned to objects - which holds information about
* how the object should be drawn.
*
* This allows for easy customization without having to modify the object's design
* function.
*/
typedef struct
{
uint8_t glass : 1; /**< 1: Do not inherit this style*/
/** Object background. */ #define LV_STYLE_ID_MASK 0x00FF
struct
{
lv_color_t main_color; /**< Object's main background color. */
lv_color_t grad_color; /**< Second color. If not equal to `main_color` a gradient will be drawn for the background. */
lv_coord_t radius; /**< Object's corner radius. You can use #LV_RADIUS_CIRCLE if you want to draw a circle. */
lv_opa_t opa; /**< Object's opacity (0-255). */
uint8_t main_color_stop; /**< 0..255 proportionally where should the gradient start (the main color stop)*/
uint8_t grad_color_stop; /**< 0..255 proportionally where should the gradient stop (the grad_color start) */
lv_blend_mode_t blend_mode :3;
lv_grad_dir_t grad_dir :2; /**< LV_GRAD_DIR_NONE/VER/HOR*/
uint8_t corner_mask :1; /**< Crop the overflowing content from the rounded corners */
struct #define LV_STYLE_ATTR_TYPE_OPA (0 << 0)
{ #define LV_STYLE_ATTR_TYPE_VALUE (1 << 0)
lv_color_t color; /**< Border color */ #define LV_STYLE_ATTR_TYPE_COLOR (2 << 0)
lv_coord_t width; /**< Border width */ #define LV_STYLE_ATTR_TYPE_PTR (3 << 0)
lv_border_part_t part; /**< Which borders to draw */ #define LV_STYLE_ATTR_INHERIT (1 << 3)
lv_opa_t opa; /**< Border opacity. */
lv_blend_mode_t blend_mode :3;
} border;
#define LV_STYLE_ATTR_FLAGS_MASK (0x7 << 5)
struct typedef union {
{ struct {
lv_color_t color; uint8_t type :3;
lv_coord_t width; uint8_t inherit :1; /*1: The property can be inherited*/
lv_coord_t spread; uint8_t cached :1; /*1: Not a real property of this style just cached from an other style*/
lv_point_t offset; uint8_t reserved :3;
lv_opa_t opa; }bits;
lv_blend_mode_t blend_mode :3; uint8_t full;
} shadow; }lv_style_attr_t;
struct enum {
{ LV_STYLE_PROP_INIT(LV_STYLE_RADIUS, 0x01, LV_STYLE_ATTR_TYPE_VALUE),
lv_coord_t top; LV_STYLE_PROP_INIT(LV_STYLE_PAD_TOP, 0x04, LV_STYLE_ATTR_TYPE_VALUE),
lv_coord_t bottom; LV_STYLE_PROP_INIT(LV_STYLE_PAD_BOTTOM, 0x05, LV_STYLE_ATTR_TYPE_VALUE),
lv_coord_t left; LV_STYLE_PROP_INIT(LV_STYLE_PAD_LEFT, 0x06, LV_STYLE_ATTR_TYPE_VALUE),
lv_coord_t right; LV_STYLE_PROP_INIT(LV_STYLE_PAD_RIGHT, 0x07, LV_STYLE_ATTR_TYPE_VALUE),
lv_coord_t inner; LV_STYLE_PROP_INIT(LV_STYLE_BG_COLOR, 0x10, LV_STYLE_ATTR_TYPE_COLOR),
} padding; LV_STYLE_PROP_INIT(LV_STYLE_BG_OPA, 0x11, LV_STYLE_ATTR_TYPE_OPA),
} body; LV_STYLE_PROP_INIT(LV_STYLE_BG_CLIP_CORNER, 0x12, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_BG_BLEND_MODE, 0x13, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_COLOR, 0x20, LV_STYLE_ATTR_TYPE_COLOR),
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_OPA, 0x21, LV_STYLE_ATTR_TYPE_OPA),
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_WIDTH, 0x22, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_PART, 0x23, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_BORDER_BLEND_MODE, 0x24, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_WIDTH, 0x30, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_COLOR, 0x31, LV_STYLE_ATTR_TYPE_COLOR),
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_OFFSET_X, 0x32, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_OFFSET_Y, 0x33, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_SPREAD, 0x34, LV_STYLE_ATTR_TYPE_VALUE),
LV_STYLE_PROP_INIT(LV_STYLE_SHADOW_OPA, 0x35, LV_STYLE_ATTR_TYPE_OPA),
LV_STYLE_PROP_INIT(LV_STYLE_TEXT_COLOR, 0x40, LV_STYLE_ATTR_TYPE_COLOR),
LV_STYLE_PROP_INIT(LV_STYLE_LINE_COLOR, 0x50, LV_STYLE_ATTR_TYPE_COLOR),
LV_STYLE_PROP_INIT(LV_STYLE_IMG_COLOR, 0x60, LV_STYLE_ATTR_TYPE_COLOR),
};
/** Style for text drawn by this object. */ typedef uint16_t lv_style_property_t;
struct
{
lv_color_t color; /**< Text color */
lv_color_t sel_color; /**< Text selection background color. */
const lv_font_t * font;
lv_coord_t letter_space; /**< Space between letters */
lv_coord_t line_space; /**< Space between lines (vertical) */
lv_opa_t opa; /**< Text opacity */
lv_blend_mode_t blend_mode :3;
uint8_t underline :1;
uint8_t strikethrough :1;
} text;
/**< Style of images. */ typedef struct {
struct uint8_t * map;
{ uint16_t used_groups;
lv_color_t color; /**< Color to recolor the image with */ uint16_t size;
lv_opa_t intense; /**< Opacity of recoloring (0 means no recoloring) */ }lv_style_t;
lv_opa_t opa; /**< Opacity of whole image */
lv_blend_mode_t blend_mode :3;
} image;
/**< Style of lines (not borders). */ typedef int16_t lv_style_value_t;
struct
{
lv_color_t color;
lv_coord_t width;
lv_opa_t opa;
uint8_t rounded : 1; /**< 1: rounded line endings*/
lv_blend_mode_t blend_mode :3;
} line;
#if LV_USE_DEBUG
#if LV_USE_ASSERT_STYLE
uint32_t debug_sentinel; /**<Should `LV_STYLE_DEGUG_SENTINEL_VALUE` to indicate that the style is valid*/
#endif
#endif
} lv_style_t;
#if LV_USE_ANIMATION #if LV_USE_ANIMATION
/** Data structure for style animations. */ /** Data structure for style animations. */
@ -165,10 +127,13 @@ typedef struct
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
**********************/ **********************/
/** /**
* Init the basic styles * Init. the built-in styles
*/ */
void lv_style_init(void); void lv_style_built_in_init(void);
void lv_style_init(lv_style_t * style);
/** /**
* Copy a style to an other * Copy a style to an other
@ -186,6 +151,14 @@ void lv_style_copy(lv_style_t * dest, const lv_style_t * src);
*/ */
void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * res, uint16_t ratio); void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * res, uint16_t ratio);
void lv_style_set_value(lv_style_t * style, lv_style_property_t prop, lv_style_value_t value);
void lv_style_set_color(lv_style_t * style, lv_style_property_t prop, lv_color_t color);
void lv_style_set_opa(lv_style_t * style, lv_style_property_t prop, lv_opa_t opa);
lv_res_t lv_style_get_value(const lv_style_t * style, lv_style_property_t prop, lv_style_value_t * res);
lv_res_t lv_style_get_opa(const lv_style_t * style, lv_style_property_t prop, lv_opa_t * res);
lv_res_t lv_style_get_color(const lv_style_t * style, lv_style_property_t prop, lv_color_t * res);
#if LV_USE_ANIMATION #if LV_USE_ANIMATION
/** /**
@ -282,19 +255,19 @@ static inline void lv_style_anim_create(lv_anim_t * a)
/************************* /*************************
* GLOBAL VARIABLES * GLOBAL VARIABLES
*************************/ *************************/
extern lv_style_t lv_style_scr; //extern lv_style_t lv_style_scr;
extern lv_style_t lv_style_transp; //extern lv_style_t lv_style_transp;
extern lv_style_t lv_style_transp_fit; //extern lv_style_t lv_style_transp_fit;
extern lv_style_t lv_style_transp_tight; //extern lv_style_t lv_style_transp_tight;
extern lv_style_t lv_style_plain; //extern lv_style_t lv_style_plain;
extern lv_style_t lv_style_plain_color; //extern lv_style_t lv_style_plain_color;
extern lv_style_t lv_style_pretty; //extern lv_style_t lv_style_pretty;
extern lv_style_t lv_style_pretty_color; //extern lv_style_t lv_style_pretty_color;
extern lv_style_t lv_style_btn_rel; //extern lv_style_t lv_style_btn_rel;
extern lv_style_t lv_style_btn_pr; //extern lv_style_t lv_style_btn_pr;
extern lv_style_t lv_style_btn_tgl_rel; //extern lv_style_t lv_style_btn_tgl_rel;
extern lv_style_t lv_style_btn_tgl_pr; //extern lv_style_t lv_style_btn_tgl_pr;
extern lv_style_t lv_style_btn_ina; //extern lv_style_t lv_style_btn_ina;
/********************** /**********************
* MACROS * MACROS

View File

@ -1,150 +1,150 @@
/** ///**
* @file lv_draw_arc.c // * @file lv_draw_arc.c
* // *
*/ // */
//
/********************* ///*********************
* INCLUDES // * INCLUDES
*********************/ // *********************/
#include "lv_draw_arc.h" //#include "lv_draw_arc.h"
#include "lv_draw_mask.h" //#include "lv_draw_mask.h"
#include "../lv_misc/lv_math.h" //#include "../lv_misc/lv_math.h"
//
/********************* ///*********************
* DEFINES // * DEFINES
*********************/ // *********************/
//
/********************** ///**********************
* TYPEDEFS // * TYPEDEFS
**********************/ // **********************/
//
/********************** ///**********************
* STATIC PROTOTYPES // * STATIC PROTOTYPES
**********************/ // **********************/
static void get_rounded_area(int16_t angle, lv_coord_t radius, uint8_t tickness, lv_area_t * res_area); //static void get_rounded_area(int16_t angle, lv_coord_t radius, uint8_t tickness, lv_area_t * res_area);
//
/********************** ///**********************
* STATIC VARIABLES // * STATIC VARIABLES
**********************/ // **********************/
//
/********************** ///**********************
* MACROS // * MACROS
**********************/ // **********************/
//
/********************** ///**********************
* GLOBAL FUNCTIONS // * GLOBAL FUNCTIONS
**********************/ // **********************/
//
/** ///**
* Draw an arc. (Can draw pie too with great thickness.) // * Draw an arc. (Can draw pie too with great thickness.)
* @param center_x the x coordinate of the center of the arc // * @param center_x the x coordinate of the center of the arc
* @param center_y the y coordinate of the center of the arc // * @param center_y the y coordinate of the center of the arc
* @param radius the radius of the arc // * @param radius the radius of the arc
* @param mask the arc will be drawn only in this mask // * @param mask the arc will be drawn only in this mask
* @param start_angle the start angle of the arc (0 deg on the bottom, 90 deg on the right) // * @param start_angle the start angle of the arc (0 deg on the bottom, 90 deg on the right)
* @param end_angle the end angle of the arc // * @param end_angle the end angle of the arc
* @param style style of the arc (`body.thickness`, `body.main_color`, `body.opa` is used) // * @param style style of the arc (`body.thickness`, `body.main_color`, `body.opa` is used)
* @param opa_scale scale down all opacities by the factor // * @param opa_scale scale down all opacities by the factor
*/ // */
void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, const lv_area_t * clip_area, //void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, const lv_area_t * clip_area,
uint16_t start_angle, uint16_t end_angle, const lv_style_t * style, lv_opa_t opa_scale) // uint16_t start_angle, uint16_t end_angle, const lv_style_t * style, lv_opa_t opa_scale)
{ //{
lv_style_t circle_style; // lv_style_t circle_style;
lv_style_copy(&circle_style, style); // lv_style_copy(&circle_style, style);
circle_style.body.radius = LV_RADIUS_CIRCLE; // circle_style.body.radius = LV_RADIUS_CIRCLE;
circle_style.body.opa = LV_OPA_TRANSP; // circle_style.body.opa = LV_OPA_TRANSP;
circle_style.body.border.width = style->line.width; // circle_style.body.border.width = style->line.width;
circle_style.body.border.color = style->line.color; // circle_style.body.border.color = style->line.color;
circle_style.body.border.opa = style->line.opa; // circle_style.body.border.opa = style->line.opa;
//
lv_draw_mask_angle_param_t mask_angle_param; // lv_draw_mask_angle_param_t mask_angle_param;
lv_draw_mask_angle_init(&mask_angle_param, center_x, center_y, start_angle, end_angle); // lv_draw_mask_angle_init(&mask_angle_param, center_x, center_y, start_angle, end_angle);
//
int16_t mask_angle_id = lv_draw_mask_add(&mask_angle_param, NULL); // int16_t mask_angle_id = lv_draw_mask_add(&mask_angle_param, NULL);
//
lv_area_t area; // lv_area_t area;
area.x1 = center_x - radius; // area.x1 = center_x - radius;
area.y1 = center_y - radius; // area.y1 = center_y - radius;
area.x2 = center_x + radius - 1; /*-1 because the center already belongs to the left/bottom part*/ // area.x2 = center_x + radius - 1; /*-1 because the center already belongs to the left/bottom part*/
area.y2 = center_y + radius - 1; // area.y2 = center_y + radius - 1;
//
lv_draw_rect(&area, clip_area, &circle_style, LV_OPA_COVER); // lv_draw_rect(&area, clip_area, &circle_style, LV_OPA_COVER);
//
lv_draw_mask_remove_id(mask_angle_id); // lv_draw_mask_remove_id(mask_angle_id);
//
if(style->line.rounded) { // if(style->line.rounded) {
circle_style.body.main_color = style->line.color; // circle_style.body.main_color = style->line.color;
circle_style.body.grad_color = style->line.color; // circle_style.body.grad_color = style->line.color;
circle_style.body.opa = LV_OPA_COVER; // circle_style.body.opa = LV_OPA_COVER;
circle_style.body.border.width = 0; // circle_style.body.border.width = 0;
//
lv_area_t round_area; // lv_area_t round_area;
get_rounded_area(start_angle, radius, style->line.width, &round_area); // get_rounded_area(start_angle, radius, style->line.width, &round_area);
round_area.x1 += center_x; // round_area.x1 += center_x;
round_area.x2 += center_x; // round_area.x2 += center_x;
round_area.y1 += center_y; // round_area.y1 += center_y;
round_area.y2 += center_y; // round_area.y2 += center_y;
//
lv_draw_rect(&round_area, clip_area, &circle_style, opa_scale); // lv_draw_rect(&round_area, clip_area, &circle_style, opa_scale);
//
get_rounded_area(end_angle, radius, style->line.width, &round_area); // get_rounded_area(end_angle, radius, style->line.width, &round_area);
round_area.x1 += center_x; // round_area.x1 += center_x;
round_area.x2 += center_x; // round_area.x2 += center_x;
round_area.y1 += center_y; // round_area.y1 += center_y;
round_area.y2 += center_y; // round_area.y2 += center_y;
//
lv_draw_rect(&round_area, clip_area, &circle_style, opa_scale); // lv_draw_rect(&round_area, clip_area, &circle_style, opa_scale);
} // }
} //}
//
//
/********************** ///**********************
* STATIC FUNCTIONS // * STATIC FUNCTIONS
**********************/ // **********************/
//
static void get_rounded_area(int16_t angle, lv_coord_t radius, uint8_t tickness, lv_area_t * res_area) //static void get_rounded_area(int16_t angle, lv_coord_t radius, uint8_t tickness, lv_area_t * res_area)
{ //{
const uint8_t ps = 8; // const uint8_t ps = 8;
const uint8_t pa = 127; // const uint8_t pa = 127;
//
lv_coord_t thick_half = tickness / 2; // lv_coord_t thick_half = tickness / 2;
lv_coord_t thick_corr = tickness & 0x01 ? 0 : 1; // lv_coord_t thick_corr = tickness & 0x01 ? 0 : 1;
//
lv_coord_t rx_corr; // lv_coord_t rx_corr;
lv_coord_t ry_corr; // lv_coord_t ry_corr;
//
if(angle > 90 && angle < 270) rx_corr = 0; // if(angle > 90 && angle < 270) rx_corr = 0;
else rx_corr = 0; // else rx_corr = 0;
//
if(angle > 0 && angle < 180) ry_corr = 0; // if(angle > 0 && angle < 180) ry_corr = 0;
else ry_corr = 0; // else ry_corr = 0;
//
lv_coord_t cir_x; // lv_coord_t cir_x;
lv_coord_t cir_y; // lv_coord_t cir_y;
//
cir_x = ((radius - rx_corr - thick_half) * lv_trigo_sin(90 - angle)) >> (LV_TRIGO_SHIFT - ps); // cir_x = ((radius - rx_corr - thick_half) * lv_trigo_sin(90 - angle)) >> (LV_TRIGO_SHIFT - ps);
cir_y = ((radius - ry_corr - thick_half) * lv_trigo_sin(angle)) >> (LV_TRIGO_SHIFT - ps); // cir_y = ((radius - ry_corr - thick_half) * lv_trigo_sin(angle)) >> (LV_TRIGO_SHIFT - ps);
//
/* Actually the center of the pixel need to be calculated so apply 1/2 px offset*/ // /* Actually the center of the pixel need to be calculated so apply 1/2 px offset*/
if(cir_x > 0) { // if(cir_x > 0) {
cir_x = (cir_x - pa) >> ps; // cir_x = (cir_x - pa) >> ps;
res_area->x1 = cir_x - thick_half + thick_corr; // res_area->x1 = cir_x - thick_half + thick_corr;
res_area->x2 = cir_x + thick_half; // res_area->x2 = cir_x + thick_half;
} // }
else { // else {
cir_x = (cir_x + pa) >> ps; // cir_x = (cir_x + pa) >> ps;
res_area->x1 = cir_x - thick_half; // res_area->x1 = cir_x - thick_half;
res_area->x2 = cir_x + thick_half - thick_corr; // res_area->x2 = cir_x + thick_half - thick_corr;
} // }
//
if(cir_y > 0) { // if(cir_y > 0) {
cir_y = (cir_y - pa) >> ps; // cir_y = (cir_y - pa) >> ps;
res_area->y1 = cir_y - thick_half + thick_corr; // res_area->y1 = cir_y - thick_half + thick_corr;
res_area->y2 = cir_y + thick_half; // res_area->y2 = cir_y + thick_half;
} // }
else { // else {
cir_y = (cir_y + pa) >> ps; // cir_y = (cir_y + pa) >> ps;
res_area->y1 = cir_y - thick_half; // res_area->y1 = cir_y - thick_half;
res_area->y2 = cir_y + thick_half - thick_corr; // res_area->y2 = cir_y + thick_half - thick_corr;
} // }
} //}

View File

@ -57,22 +57,22 @@ static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area,
void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, const lv_style_t * style, void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, const lv_style_t * style,
uint16_t angle, lv_point_t * center, uint16_t zoom, bool antialias, lv_opa_t opa_scale) uint16_t angle, lv_point_t * center, uint16_t zoom, bool antialias, lv_opa_t opa_scale)
{ {
if(src == NULL) { // if(src == NULL) {
LV_LOG_WARN("Image draw: src is NULL"); // LV_LOG_WARN("Image draw: src is NULL");
lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER); // lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR); // lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR);
return; // return;
} // }
//
lv_res_t res; // lv_res_t res;
res = lv_img_draw_core(coords, mask, src, style, angle, center, zoom, antialias, opa_scale); // res = lv_img_draw_core(coords, mask, src, style, angle, center, zoom, antialias, opa_scale);
//
if(res == LV_RES_INV) { // if(res == LV_RES_INV) {
LV_LOG_WARN("Image draw error"); // LV_LOG_WARN("Image draw error");
lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER); // lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR); // lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR);
return; // return;
} // }
} }
/** /**
@ -194,124 +194,124 @@ lv_img_src_t lv_img_src_get_type(const void * src)
static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mask, const void * src, static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mask, const void * src,
const lv_style_t * style, uint16_t angle, lv_point_t * pivot, uint16_t zoom, bool antialias, lv_opa_t opa_scale) const lv_style_t * style, uint16_t angle, lv_point_t * pivot, uint16_t zoom, bool antialias, lv_opa_t opa_scale)
{ {
lv_opa_t opa = // lv_opa_t opa =
opa_scale == LV_OPA_COVER ? style->image.opa : (uint16_t)((uint16_t)style->image.opa * opa_scale) >> 8; // opa_scale == LV_OPA_COVER ? style->image.opa : (uint16_t)((uint16_t)style->image.opa * opa_scale) >> 8;
//
lv_img_cache_entry_t * cdsc = lv_img_cache_open(src, style); // lv_img_cache_entry_t * cdsc = lv_img_cache_open(src, style);
//
if(cdsc == NULL) return LV_RES_INV; // if(cdsc == NULL) return LV_RES_INV;
//
bool chroma_keyed = lv_img_cf_is_chroma_keyed(cdsc->dec_dsc.header.cf); // bool chroma_keyed = lv_img_cf_is_chroma_keyed(cdsc->dec_dsc.header.cf);
bool alpha_byte = lv_img_cf_has_alpha(cdsc->dec_dsc.header.cf); // bool alpha_byte = lv_img_cf_has_alpha(cdsc->dec_dsc.header.cf);
//
if(cdsc->dec_dsc.error_msg != NULL) { // if(cdsc->dec_dsc.error_msg != NULL) {
LV_LOG_WARN("Image draw error"); // LV_LOG_WARN("Image draw error");
lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER); // lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, cdsc->dec_dsc.error_msg, LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR); // lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, cdsc->dec_dsc.error_msg, LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR);
} // }
/* The decoder open could open the image and gave the entire uncompressed image. // /* The decoder open could open the image and gave the entire uncompressed image.
* Just draw it!*/ // * Just draw it!*/
else if(cdsc->dec_dsc.img_data) { // else if(cdsc->dec_dsc.img_data) {
lv_area_t map_area_rot; // lv_area_t map_area_rot;
lv_area_copy(&map_area_rot, coords); // lv_area_copy(&map_area_rot, coords);
if(angle || zoom != LV_IMG_ZOOM_NONE) { // if(angle || zoom != LV_IMG_ZOOM_NONE) {
/*Get the exact area which is required to show the rotated image*/ // /*Get the exact area which is required to show the rotated image*/
lv_coord_t pivot_x = lv_area_get_width(coords) / 2 + coords->x1; // lv_coord_t pivot_x = lv_area_get_width(coords) / 2 + coords->x1;
lv_coord_t pivot_y = lv_area_get_height(coords) / 2 + coords->y1; // lv_coord_t pivot_y = lv_area_get_height(coords) / 2 + coords->y1;
//
if (pivot){ // if (pivot){
pivot_x = pivot->x + coords->x1; // pivot_x = pivot->x + coords->x1;
pivot_y = pivot->y + coords->y1; // pivot_y = pivot->y + coords->y1;
} // }
lv_coord_t w = lv_area_get_width(coords); // lv_coord_t w = lv_area_get_width(coords);
lv_coord_t w_zoom = (((w * zoom) >> 8) - w) / 2; // lv_coord_t w_zoom = (((w * zoom) >> 8) - w) / 2;
lv_coord_t h = lv_area_get_height(coords); // lv_coord_t h = lv_area_get_height(coords);
lv_coord_t h_zoom = (((h * zoom) >> 8) - h) / 2; // lv_coord_t h_zoom = (((h * zoom) >> 8) - h) / 2;
//
lv_area_t norm; // lv_area_t norm;
norm.x1 = coords->x1 - pivot_x - w_zoom; // norm.x1 = coords->x1 - pivot_x - w_zoom;
norm.y1 = coords->y1 - pivot_y - h_zoom; // norm.y1 = coords->y1 - pivot_y - h_zoom;
norm.x2 = coords->x2 - pivot_x + w_zoom; // norm.x2 = coords->x2 - pivot_x + w_zoom;
norm.y2 = coords->y2 - pivot_y + h_zoom; // norm.y2 = coords->y2 - pivot_y + h_zoom;
//
int16_t sinma = lv_trigo_sin(angle); // int16_t sinma = lv_trigo_sin(angle);
int16_t cosma = lv_trigo_sin(angle + 90); // int16_t cosma = lv_trigo_sin(angle + 90);
//
lv_point_t lt; // lv_point_t lt;
lv_point_t rt; // lv_point_t rt;
lv_point_t lb; // lv_point_t lb;
lv_point_t rb; // lv_point_t rb;
lt.x = ((cosma * norm.x1 - sinma * norm.y1) >> (LV_TRIGO_SHIFT)) + pivot_x; // lt.x = ((cosma * norm.x1 - sinma * norm.y1) >> (LV_TRIGO_SHIFT)) + pivot_x;
lt.y = ((sinma * norm.x1 + cosma * norm.y1) >> (LV_TRIGO_SHIFT)) + pivot_y; // lt.y = ((sinma * norm.x1 + cosma * norm.y1) >> (LV_TRIGO_SHIFT)) + pivot_y;
//
rt.x = ((cosma * norm.x2 - sinma * norm.y1) >> (LV_TRIGO_SHIFT)) + pivot_x; // rt.x = ((cosma * norm.x2 - sinma * norm.y1) >> (LV_TRIGO_SHIFT)) + pivot_x;
rt.y = ((sinma * norm.x2 + cosma * norm.y1) >> (LV_TRIGO_SHIFT)) + pivot_y; // rt.y = ((sinma * norm.x2 + cosma * norm.y1) >> (LV_TRIGO_SHIFT)) + pivot_y;
//
lb.x = ((cosma * norm.x1 - sinma * norm.y2) >> (LV_TRIGO_SHIFT)) + pivot_x; // lb.x = ((cosma * norm.x1 - sinma * norm.y2) >> (LV_TRIGO_SHIFT)) + pivot_x;
lb.y = ((sinma * norm.x1 + cosma * norm.y2) >> (LV_TRIGO_SHIFT)) + pivot_y; // lb.y = ((sinma * norm.x1 + cosma * norm.y2) >> (LV_TRIGO_SHIFT)) + pivot_y;
//
rb.x = ((cosma * norm.x2 - sinma * norm.y2) >> (LV_TRIGO_SHIFT)) + pivot_x; // rb.x = ((cosma * norm.x2 - sinma * norm.y2) >> (LV_TRIGO_SHIFT)) + pivot_x;
rb.y = ((sinma * norm.x2 + cosma * norm.y2) >> (LV_TRIGO_SHIFT)) + pivot_y; // rb.y = ((sinma * norm.x2 + cosma * norm.y2) >> (LV_TRIGO_SHIFT)) + pivot_y;
//
map_area_rot.x1 = LV_MATH_MIN(LV_MATH_MIN(LV_MATH_MIN(lb.x, lt.x), rb.x), rt.x); // map_area_rot.x1 = LV_MATH_MIN(LV_MATH_MIN(LV_MATH_MIN(lb.x, lt.x), rb.x), rt.x);
map_area_rot.x2 = LV_MATH_MAX(LV_MATH_MAX(LV_MATH_MAX(lb.x, lt.x), rb.x), rt.x); // map_area_rot.x2 = LV_MATH_MAX(LV_MATH_MAX(LV_MATH_MAX(lb.x, lt.x), rb.x), rt.x);
map_area_rot.y1 = LV_MATH_MIN(LV_MATH_MIN(LV_MATH_MIN(lb.y, lt.y), rb.y), rt.y); // map_area_rot.y1 = LV_MATH_MIN(LV_MATH_MIN(LV_MATH_MIN(lb.y, lt.y), rb.y), rt.y);
map_area_rot.y2 = LV_MATH_MAX(LV_MATH_MAX(LV_MATH_MAX(lb.y, lt.y), rb.y), rt.y); // map_area_rot.y2 = LV_MATH_MAX(LV_MATH_MAX(LV_MATH_MAX(lb.y, lt.y), rb.y), rt.y);
} // }
//
lv_area_t mask_com; /*Common area of mask and coords*/ // lv_area_t mask_com; /*Common area of mask and coords*/
bool union_ok; // bool union_ok;
union_ok = lv_area_intersect(&mask_com, mask, &map_area_rot); // union_ok = lv_area_intersect(&mask_com, mask, &map_area_rot);
if(union_ok == false) { // if(union_ok == false) {
return LV_RES_OK; /*Out of mask. There is nothing to draw so the image is drawn // return LV_RES_OK; /*Out of mask. There is nothing to draw so the image is drawn
successfully.*/ // successfully.*/
} // }
//
lv_draw_map(coords, &mask_com, cdsc->dec_dsc.img_data, opa, chroma_keyed, alpha_byte, style, angle, pivot, zoom, antialias); // lv_draw_map(coords, &mask_com, cdsc->dec_dsc.img_data, opa, chroma_keyed, alpha_byte, style, angle, pivot, zoom, antialias);
} // }
/* The whole uncompressed image is not available. Try to read it line-by-line*/ // /* The whole uncompressed image is not available. Try to read it line-by-line*/
else { // else {
lv_area_t mask_com; /*Common area of mask and coords*/ // lv_area_t mask_com; /*Common area of mask and coords*/
bool union_ok; // bool union_ok;
union_ok = lv_area_intersect(&mask_com, mask, coords); // union_ok = lv_area_intersect(&mask_com, mask, coords);
if(union_ok == false) { // if(union_ok == false) {
return LV_RES_OK; /*Out of mask. There is nothing to draw so the image is drawn // return LV_RES_OK; /*Out of mask. There is nothing to draw so the image is drawn
successfully.*/ // successfully.*/
} // }
//
lv_coord_t width = lv_area_get_width(&mask_com); // lv_coord_t width = lv_area_get_width(&mask_com);
//
uint8_t * buf = lv_mem_buf_get(lv_area_get_width(&mask_com) * LV_IMG_PX_SIZE_ALPHA_BYTE); /*+1 because of the possible alpha byte*/ // uint8_t * buf = lv_mem_buf_get(lv_area_get_width(&mask_com) * LV_IMG_PX_SIZE_ALPHA_BYTE); /*+1 because of the possible alpha byte*/
//
lv_area_t line; // lv_area_t line;
lv_area_copy(&line, &mask_com); // lv_area_copy(&line, &mask_com);
lv_area_set_height(&line, 1); // lv_area_set_height(&line, 1);
lv_coord_t x = mask_com.x1 - coords->x1; // lv_coord_t x = mask_com.x1 - coords->x1;
lv_coord_t y = mask_com.y1 - coords->y1; // lv_coord_t y = mask_com.y1 - coords->y1;
lv_coord_t row; // lv_coord_t row;
lv_res_t read_res; // lv_res_t read_res;
for(row = mask_com.y1; row <= mask_com.y2; row++) { // for(row = mask_com.y1; row <= mask_com.y2; row++) {
lv_area_t mask_line; // lv_area_t mask_line;
union_ok = lv_area_intersect(&mask_line, mask, &line); // union_ok = lv_area_intersect(&mask_line, mask, &line);
if(union_ok == false) continue; // if(union_ok == false) continue;
//
read_res = lv_img_decoder_read_line(&cdsc->dec_dsc, x, y, width, buf); // read_res = lv_img_decoder_read_line(&cdsc->dec_dsc, x, y, width, buf);
if(read_res != LV_RES_OK) { // if(read_res != LV_RES_OK) {
lv_img_decoder_close(&cdsc->dec_dsc); // lv_img_decoder_close(&cdsc->dec_dsc);
LV_LOG_WARN("Image draw can't read the line"); // LV_LOG_WARN("Image draw can't read the line");
lv_mem_buf_release(buf); // lv_mem_buf_release(buf);
return LV_RES_INV; // return LV_RES_INV;
} // }
//
//
lv_draw_map(&line, &mask_line, buf, opa, chroma_keyed, alpha_byte, style, 0, NULL, LV_IMG_ZOOM_NONE, false); // lv_draw_map(&line, &mask_line, buf, opa, chroma_keyed, alpha_byte, style, 0, NULL, LV_IMG_ZOOM_NONE, false);
line.y1++; // line.y1++;
line.y2++; // line.y2++;
y++; // y++;
} // }
lv_mem_buf_release(buf); // lv_mem_buf_release(buf);
} // }
//
return LV_RES_OK; return LV_RES_OK;
} }
@ -332,187 +332,187 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas
static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area, const uint8_t * map_p, lv_opa_t opa, static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area, const uint8_t * map_p, lv_opa_t opa,
bool chroma_key, bool alpha_byte, const lv_style_t * style, uint16_t angle, lv_point_t * pivot, uint16_t zoom, bool antialaias) bool chroma_key, bool alpha_byte, const lv_style_t * style, uint16_t angle, lv_point_t * pivot, uint16_t zoom, bool antialaias)
{ {
//
if(opa < LV_OPA_MIN) return; // if(opa < LV_OPA_MIN) return;
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER; // if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
//
/* Use the clip area as draw area*/ // /* Use the clip area as draw area*/
lv_area_t draw_area; // lv_area_t draw_area;
lv_area_copy(&draw_area, clip_area); // lv_area_copy(&draw_area, clip_area);
//
lv_disp_t * disp = lv_refr_get_disp_refreshing(); // lv_disp_t * disp = lv_refr_get_disp_refreshing();
lv_disp_buf_t * vdb = lv_disp_get_buf(disp); // lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
const lv_area_t * disp_area = &vdb->area; // const lv_area_t * disp_area = &vdb->area;
//
/* Now `draw_area` has absolute coordinates. // /* Now `draw_area` has absolute coordinates.
* Make it relative to `disp_area` to simplify draw to `disp_buf`*/ // * Make it relative to `disp_area` to simplify draw to `disp_buf`*/
draw_area.x1 -= disp_area->x1; // draw_area.x1 -= disp_area->x1;
draw_area.y1 -= disp_area->y1; // draw_area.y1 -= disp_area->y1;
draw_area.x2 -= disp_area->x1; // draw_area.x2 -= disp_area->x1;
draw_area.y2 -= disp_area->y1; // draw_area.y2 -= disp_area->y1;
//
uint8_t other_mask_cnt = lv_draw_mask_get_cnt(); // uint8_t other_mask_cnt = lv_draw_mask_get_cnt();
//
/*The simplest case just copy the pixels into the VDB*/ // /*The simplest case just copy the pixels into the VDB*/
if(other_mask_cnt == 0 && angle == 0 && zoom == LV_IMG_ZOOM_NONE && // if(other_mask_cnt == 0 && angle == 0 && zoom == LV_IMG_ZOOM_NONE &&
chroma_key == false && alpha_byte == false && // chroma_key == false && alpha_byte == false &&
opa == LV_OPA_COVER && style->image.intense == LV_OPA_TRANSP) { // opa == LV_OPA_COVER && style->image.intense == LV_OPA_TRANSP) {
lv_blend_map(clip_area, map_area, (lv_color_t *)map_p, NULL, LV_DRAW_MASK_RES_FULL_COVER, LV_OPA_COVER, style->image.blend_mode); // lv_blend_map(clip_area, map_area, (lv_color_t *)map_p, NULL, LV_DRAW_MASK_RES_FULL_COVER, LV_OPA_COVER, style->image.blend_mode);
} // }
/*In the other cases every pixel need to be checked one-by-one*/ // /*In the other cases every pixel need to be checked one-by-one*/
else { // else {
/*The pixel size in byte is different if an alpha byte is added too*/ // /*The pixel size in byte is different if an alpha byte is added too*/
uint8_t px_size_byte = alpha_byte ? LV_IMG_PX_SIZE_ALPHA_BYTE : sizeof(lv_color_t); // uint8_t px_size_byte = alpha_byte ? LV_IMG_PX_SIZE_ALPHA_BYTE : sizeof(lv_color_t);
//
/*Build the image and a mask line-by-line*/ // /*Build the image and a mask line-by-line*/
uint32_t mask_buf_size = lv_area_get_size(&draw_area) > LV_HOR_RES_MAX ? LV_HOR_RES_MAX : lv_area_get_size(&draw_area); // uint32_t mask_buf_size = lv_area_get_size(&draw_area) > LV_HOR_RES_MAX ? LV_HOR_RES_MAX : lv_area_get_size(&draw_area);
lv_color_t * map2 = lv_mem_buf_get(mask_buf_size * sizeof(lv_color_t)); // lv_color_t * map2 = lv_mem_buf_get(mask_buf_size * sizeof(lv_color_t));
lv_opa_t * mask_buf = lv_mem_buf_get(mask_buf_size); // lv_opa_t * mask_buf = lv_mem_buf_get(mask_buf_size);
//
/*Go to the first displayed pixel of the map*/ // /*Go to the first displayed pixel of the map*/
lv_coord_t map_w = lv_area_get_width(map_area); // lv_coord_t map_w = lv_area_get_width(map_area);
lv_coord_t map_h = lv_area_get_height(map_area); // lv_coord_t map_h = lv_area_get_height(map_area);
const uint8_t * map_buf_tmp = map_p; // const uint8_t * map_buf_tmp = map_p;
map_buf_tmp += map_w * (draw_area.y1 - (map_area->y1 - disp_area->y1)) * px_size_byte; // map_buf_tmp += map_w * (draw_area.y1 - (map_area->y1 - disp_area->y1)) * px_size_byte;
map_buf_tmp += (draw_area.x1 - (map_area->x1 - disp_area->x1)) * px_size_byte; // map_buf_tmp += (draw_area.x1 - (map_area->x1 - disp_area->x1)) * px_size_byte;
//
lv_color_t c; // lv_color_t c;
lv_color_t chroma_keyed_color = LV_COLOR_TRANSP; // lv_color_t chroma_keyed_color = LV_COLOR_TRANSP;
uint32_t px_i = 0; // uint32_t px_i = 0;
uint32_t px_i_start; // uint32_t px_i_start;
//
const uint8_t * map_px; // const uint8_t * map_px;
//
lv_area_t blend_area; // lv_area_t blend_area;
blend_area.x1 = draw_area.x1 + disp_area->x1; // blend_area.x1 = draw_area.x1 + disp_area->x1;
blend_area.x2 = blend_area.x1 + lv_area_get_width(&draw_area) - 1; // blend_area.x2 = blend_area.x1 + lv_area_get_width(&draw_area) - 1;
blend_area.y1 = disp_area->y1 + draw_area.y1; // blend_area.y1 = disp_area->y1 + draw_area.y1;
blend_area.y2 = blend_area.y1; // blend_area.y2 = blend_area.y1;
//
/*Prepare the `mask_buf`if there are other masks*/ // /*Prepare the `mask_buf`if there are other masks*/
if(other_mask_cnt) { // if(other_mask_cnt) {
memset(mask_buf, 0xFF, mask_buf_size); // memset(mask_buf, 0xFF, mask_buf_size);
} // }
//
//
bool transform = angle != 0 || zoom != LV_IMG_ZOOM_NONE ? true : false; // bool transform = angle != 0 || zoom != LV_IMG_ZOOM_NONE ? true : false;
lv_img_transform_dsc_t trans_dsc; // lv_img_transform_dsc_t trans_dsc;
memset(&trans_dsc, 0, sizeof(lv_img_transform_dsc_t)); // memset(&trans_dsc, 0, sizeof(lv_img_transform_dsc_t));
if(transform) { // if(transform) {
lv_img_cf_t cf = LV_IMG_CF_TRUE_COLOR; // lv_img_cf_t cf = LV_IMG_CF_TRUE_COLOR;
if(alpha_byte) cf = LV_IMG_CF_TRUE_COLOR_ALPHA; // if(alpha_byte) cf = LV_IMG_CF_TRUE_COLOR_ALPHA;
else if(chroma_key) cf = LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED; // else if(chroma_key) cf = LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED;
//
//
trans_dsc.cfg.angle = angle; // trans_dsc.cfg.angle = angle;
trans_dsc.cfg.zoom = zoom; // trans_dsc.cfg.zoom = zoom;
trans_dsc.cfg.src = map_p; // trans_dsc.cfg.src = map_p;
trans_dsc.cfg.src_w = map_w; // trans_dsc.cfg.src_w = map_w;
trans_dsc.cfg.src_h = map_h; // trans_dsc.cfg.src_h = map_h;
trans_dsc.cfg.cf = cf; // trans_dsc.cfg.cf = cf;
trans_dsc.cfg.pivot_x = map_w / 2; // trans_dsc.cfg.pivot_x = map_w / 2;
trans_dsc.cfg.pivot_y = map_h / 2; // trans_dsc.cfg.pivot_y = map_h / 2;
if (pivot){ // if (pivot){
trans_dsc.cfg.pivot_x = pivot->x; // trans_dsc.cfg.pivot_x = pivot->x;
trans_dsc.cfg.pivot_y = pivot->y; // trans_dsc.cfg.pivot_y = pivot->y;
} // }
trans_dsc.cfg.color = style->image.color; // trans_dsc.cfg.color = style->image.color;
trans_dsc.cfg.antialias = antialaias; // trans_dsc.cfg.antialias = antialaias;
//
lv_img_buf_transform_init(&trans_dsc); // lv_img_buf_transform_init(&trans_dsc);
} // }
//
lv_draw_mask_res_t mask_res; // lv_draw_mask_res_t mask_res;
mask_res = (alpha_byte || chroma_key || angle) ? LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER; // mask_res = (alpha_byte || chroma_key || angle) ? LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER;
lv_coord_t x; // lv_coord_t x;
lv_coord_t y; // lv_coord_t y;
for(y = 0; y < lv_area_get_height(&draw_area); y++) { // for(y = 0; y < lv_area_get_height(&draw_area); y++) {
map_px = map_buf_tmp; // map_px = map_buf_tmp;
px_i_start = px_i; // px_i_start = px_i;
//
for(x = 0; x < lv_area_get_width(&draw_area); x++, map_px += px_size_byte, px_i++) { // for(x = 0; x < lv_area_get_width(&draw_area); x++, map_px += px_size_byte, px_i++) {
//
if(transform == false) { // if(transform == false) {
if(alpha_byte) { // if(alpha_byte) {
lv_opa_t px_opa = map_px[LV_IMG_PX_SIZE_ALPHA_BYTE - 1]; // lv_opa_t px_opa = map_px[LV_IMG_PX_SIZE_ALPHA_BYTE - 1];
mask_buf[px_i] = px_opa; // mask_buf[px_i] = px_opa;
if(px_opa < LV_OPA_MIN) continue; // if(px_opa < LV_OPA_MIN) continue;
} else { // } else {
mask_buf[px_i] = LV_OPA_COVER; // mask_buf[px_i] = LV_OPA_COVER;
} // }
//
#if LV_COLOR_DEPTH == 8 //#if LV_COLOR_DEPTH == 8
c.full = map_px[0]; // c.full = map_px[0];
#elif LV_COLOR_DEPTH == 16 //#elif LV_COLOR_DEPTH == 16
c.full = map_px[0] + (map_px[1] << 8); // c.full = map_px[0] + (map_px[1] << 8);
#elif LV_COLOR_DEPTH == 32 //#elif LV_COLOR_DEPTH == 32
c.full = *((uint32_t*)map_px); // c.full = *((uint32_t*)map_px);
#endif //#endif
if (chroma_key) { // if (chroma_key) {
if(c.full == chroma_keyed_color.full) { // if(c.full == chroma_keyed_color.full) {
mask_buf[px_i] = LV_OPA_TRANSP; // mask_buf[px_i] = LV_OPA_TRANSP;
continue; // continue;
} // }
} // }
} else { // } else {
/*Rotate*/ // /*Rotate*/
bool ret; // bool ret;
lv_coord_t rot_x = x + (disp_area->x1 + draw_area.x1) - map_area->x1; // lv_coord_t rot_x = x + (disp_area->x1 + draw_area.x1) - map_area->x1;
lv_coord_t rot_y = y + (disp_area->y1 + draw_area.y1) - map_area->y1; // lv_coord_t rot_y = y + (disp_area->y1 + draw_area.y1) - map_area->y1;
ret = lv_img_buf_transform(&trans_dsc, rot_x, rot_y); // ret = lv_img_buf_transform(&trans_dsc, rot_x, rot_y);
if(ret == false) { // if(ret == false) {
mask_buf[px_i] = LV_OPA_TRANSP; // mask_buf[px_i] = LV_OPA_TRANSP;
continue; // continue;
} else { // } else {
mask_buf[px_i] = trans_dsc.res.opa; // mask_buf[px_i] = trans_dsc.res.opa;
c.full = trans_dsc.res.color.full; // c.full = trans_dsc.res.color.full;
} // }
} // }
//
if(style->image.intense != 0) { // if(style->image.intense != 0) {
c = lv_color_mix(style->image.color, c, style->image.intense); // c = lv_color_mix(style->image.color, c, style->image.intense);
} // }
//
map2[px_i].full = c.full; // map2[px_i].full = c.full;
} // }
//
/*Apply the masks if any*/ // /*Apply the masks if any*/
if(other_mask_cnt) { // if(other_mask_cnt) {
lv_draw_mask_res_t mask_res_sub; // lv_draw_mask_res_t mask_res_sub;
mask_res_sub = lv_draw_mask_apply(mask_buf + px_i_start, draw_area.x1 + vdb->area.x1, y + draw_area.y1 + vdb->area.y1, lv_area_get_width(&draw_area)); // mask_res_sub = lv_draw_mask_apply(mask_buf + px_i_start, draw_area.x1 + vdb->area.x1, y + draw_area.y1 + vdb->area.y1, lv_area_get_width(&draw_area));
if(mask_res_sub == LV_DRAW_MASK_RES_FULL_TRANSP) { // if(mask_res_sub == LV_DRAW_MASK_RES_FULL_TRANSP) {
memset(mask_buf + px_i_start, 0x00, lv_area_get_width(&draw_area)); // memset(mask_buf + px_i_start, 0x00, lv_area_get_width(&draw_area));
mask_res = LV_DRAW_MASK_RES_CHANGED; // mask_res = LV_DRAW_MASK_RES_CHANGED;
} else if(mask_res_sub == LV_DRAW_MASK_RES_CHANGED) { // } else if(mask_res_sub == LV_DRAW_MASK_RES_CHANGED) {
mask_res = LV_DRAW_MASK_RES_CHANGED; // mask_res = LV_DRAW_MASK_RES_CHANGED;
} // }
} // }
//
map_buf_tmp += map_w * px_size_byte; // map_buf_tmp += map_w * px_size_byte;
if(px_i + lv_area_get_width(&draw_area) < mask_buf_size) { // if(px_i + lv_area_get_width(&draw_area) < mask_buf_size) {
blend_area.y2 ++; // blend_area.y2 ++;
} else { // } else {
lv_blend_map(clip_area, &blend_area, map2, mask_buf, mask_res, opa, style->image.blend_mode); // lv_blend_map(clip_area, &blend_area, map2, mask_buf, mask_res, opa, style->image.blend_mode);
//
blend_area.y1 = blend_area.y2 + 1; // blend_area.y1 = blend_area.y2 + 1;
blend_area.y2 = blend_area.y1; // blend_area.y2 = blend_area.y1;
//
px_i = 0; // px_i = 0;
mask_res = (alpha_byte || chroma_key || angle) ? LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER; // mask_res = (alpha_byte || chroma_key || angle) ? LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER;
//
/*Prepare the `mask_buf`if there are other masks*/ // /*Prepare the `mask_buf`if there are other masks*/
if(other_mask_cnt) { // if(other_mask_cnt) {
memset(mask_buf, 0xFF, mask_buf_size); // memset(mask_buf, 0xFF, mask_buf_size);
} // }
} // }
} // }
/*Flush the last part*/ // /*Flush the last part*/
if(blend_area.y1 != blend_area.y2) { // if(blend_area.y1 != blend_area.y2) {
blend_area.y2--; // blend_area.y2--;
lv_blend_map(clip_area, &blend_area, map2, mask_buf, mask_res, opa, style->image.blend_mode); // lv_blend_map(clip_area, &blend_area, map2, mask_buf, mask_res, opa, style->image.blend_mode);
} // }
//
lv_mem_buf_release(mask_buf); // lv_mem_buf_release(mask_buf);
lv_mem_buf_release(map2); // lv_mem_buf_release(map2);
} // }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,349 +1,349 @@
/**lip ///**lip
* @file lv_draw_line.c // * @file lv_draw_line.c
* // *
*/ // */
//
/********************* ///*********************
* INCLUDES // * INCLUDES
*********************/ // *********************/
#include <stdio.h> //#include <stdio.h>
#include <stdbool.h> //#include <stdbool.h>
#include "lv_draw.h" //#include "lv_draw.h"
#include "lv_draw_mask.h" //#include "lv_draw_mask.h"
#include "lv_draw_blend.h" //#include "lv_draw_blend.h"
#include "../lv_core/lv_refr.h" //#include "../lv_core/lv_refr.h"
#include "../lv_misc/lv_math.h" //#include "../lv_misc/lv_math.h"
//
/********************* ///*********************
* DEFINES // * DEFINES
*********************/ // *********************/
//
/********************** ///**********************
* TYPEDEFS // * TYPEDEFS
**********************/ // **********************/
//
/********************** ///**********************
* STATIC PROTOTYPES // * STATIC PROTOTYPES
**********************/ // **********************/
static void draw_line_skew(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, //static void draw_line_skew(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip,
const lv_style_t * style, lv_opa_t opa_scale); // const lv_style_t * style, lv_opa_t opa_scale);
static void draw_line_hor(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, //static void draw_line_hor(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip,
const lv_style_t * style, lv_opa_t opa_scale); // const lv_style_t * style, lv_opa_t opa_scale);
static void draw_line_ver(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, //static void draw_line_ver(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip,
const lv_style_t * style, lv_opa_t opa_scale); // const lv_style_t * style, lv_opa_t opa_scale);
//
//
/********************** ///**********************
* STATIC VARIABLES // * STATIC VARIABLES
**********************/ // **********************/
//
/********************** ///**********************
* MACROS // * MACROS
**********************/ // **********************/
//
/********************** ///**********************
* GLOBAL FUNCTIONS // * GLOBAL FUNCTIONS
**********************/ // **********************/
//
/** ///**
* Draw a line // * Draw a line
* @param point1 first point of the line // * @param point1 first point of the line
* @param point2 second point of the line // * @param point2 second point of the line
* @param mask the line will be drawn only on this area // * @param mask the line will be drawn only on this area
* @param style pointer to a line's style // * @param style pointer to a line's style
* @param opa_scale scale down all opacities by the factor // * @param opa_scale scale down all opacities by the factor
*/ // */
void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, //void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip,
const lv_style_t * style, lv_opa_t opa_scale) // const lv_style_t * style, lv_opa_t opa_scale)
{ //{
if(style->line.width == 0) return; // if(style->line.width == 0) return;
if(point1->x == point2->x && point1->y == point2->y) return; // if(point1->x == point2->x && point1->y == point2->y) return;
//
lv_area_t clip_line; // lv_area_t clip_line;
clip_line.x1 = LV_MATH_MIN(point1->x, point2->x) - style->line.width/2; // clip_line.x1 = LV_MATH_MIN(point1->x, point2->x) - style->line.width/2;
clip_line.x2 = LV_MATH_MAX(point1->x, point2->x) + style->line.width/2; // clip_line.x2 = LV_MATH_MAX(point1->x, point2->x) + style->line.width/2;
clip_line.y1 = LV_MATH_MIN(point1->y, point2->y) - style->line.width/2; // clip_line.y1 = LV_MATH_MIN(point1->y, point2->y) - style->line.width/2;
clip_line.y2 = LV_MATH_MAX(point1->y, point2->y) + style->line.width/2; // clip_line.y2 = LV_MATH_MAX(point1->y, point2->y) + style->line.width/2;
//
bool is_common; // bool is_common;
is_common = lv_area_intersect(&clip_line, &clip_line, clip); // is_common = lv_area_intersect(&clip_line, &clip_line, clip);
if(!is_common) return; // if(!is_common) return;
//
if(point1->y == point2->y) draw_line_hor(point1, point2, &clip_line, style, opa_scale); // if(point1->y == point2->y) draw_line_hor(point1, point2, &clip_line, style, opa_scale);
else if(point1->x == point2->x) draw_line_ver(point1, point2, &clip_line, style, opa_scale); // else if(point1->x == point2->x) draw_line_ver(point1, point2, &clip_line, style, opa_scale);
else draw_line_skew(point1, point2, &clip_line, style, opa_scale); // else draw_line_skew(point1, point2, &clip_line, style, opa_scale);
} //}
//
/********************** ///**********************
* STATIC FUNCTIONS // * STATIC FUNCTIONS
**********************/ // **********************/
//
static void draw_line_hor(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, //static void draw_line_hor(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip,
const lv_style_t * style, lv_opa_t opa_scale) // const lv_style_t * style, lv_opa_t opa_scale)
{ //{
lv_opa_t opa = style->line.opa; // lv_opa_t opa = style->line.opa;
if(opa_scale != LV_OPA_COVER) opa = (opa * opa_scale) >> 8; // if(opa_scale != LV_OPA_COVER) opa = (opa * opa_scale) >> 8;
//
lv_disp_t * disp = lv_refr_get_disp_refreshing(); // lv_disp_t * disp = lv_refr_get_disp_refreshing();
lv_disp_buf_t * vdb = lv_disp_get_buf(disp); // lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
//
const lv_area_t * disp_area = &vdb->area; // const lv_area_t * disp_area = &vdb->area;
//
lv_coord_t w = style->line.width - 1; // lv_coord_t w = style->line.width - 1;
lv_coord_t w_half0 = w >> 1; // lv_coord_t w_half0 = w >> 1;
lv_coord_t w_half1 = w_half0 + (w & 0x1); /*Compensate rounding error*/ // lv_coord_t w_half1 = w_half0 + (w & 0x1); /*Compensate rounding error*/
//
//
int16_t other_mask_cnt = lv_draw_mask_get_cnt(); // int16_t other_mask_cnt = lv_draw_mask_get_cnt();
//
lv_area_t draw_area; // lv_area_t draw_area;
draw_area.x1 = LV_MATH_MIN(point1->x, point2->x); // draw_area.x1 = LV_MATH_MIN(point1->x, point2->x);
draw_area.x2 = LV_MATH_MAX(point1->x, point2->x) - 1; // draw_area.x2 = LV_MATH_MAX(point1->x, point2->x) - 1;
draw_area.y1 = point1->y - w_half1; // draw_area.y1 = point1->y - w_half1;
draw_area.y2 = point1->y + w_half0; // draw_area.y2 = point1->y + w_half0;
//
/*If there is no mask then simply draw a rectangle*/ // /*If there is no mask then simply draw a rectangle*/
if(other_mask_cnt == 0) { // if(other_mask_cnt == 0) {
lv_blend_fill(clip, &draw_area, // lv_blend_fill(clip, &draw_area,
style->line.color, NULL, LV_DRAW_MASK_RES_FULL_COVER,opa, // style->line.color, NULL, LV_DRAW_MASK_RES_FULL_COVER,opa,
LV_BLEND_MODE_NORMAL); // LV_BLEND_MODE_NORMAL);
} // }
/*If there other mask apply it*/ // /*If there other mask apply it*/
else { // else {
/* Get clipped fill area which is the real draw area. // /* Get clipped fill area which is the real draw area.
* It is always the same or inside `fill_area` */ // * It is always the same or inside `fill_area` */
bool is_common; // bool is_common;
is_common = lv_area_intersect(&draw_area, clip, &draw_area); // is_common = lv_area_intersect(&draw_area, clip, &draw_area);
if(!is_common) return; // if(!is_common) return;
//
/* Now `draw_area` has absolute coordinates. // /* Now `draw_area` has absolute coordinates.
* Make it relative to `disp_area` to simplify draw to `disp_buf`*/ // * Make it relative to `disp_area` to simplify draw to `disp_buf`*/
draw_area.x1 -= vdb->area.x1; // draw_area.x1 -= vdb->area.x1;
draw_area.y1 -= vdb->area.y1; // draw_area.y1 -= vdb->area.y1;
draw_area.x2 -= vdb->area.x1; // draw_area.x2 -= vdb->area.x1;
draw_area.y2 -= vdb->area.y1; // draw_area.y2 -= vdb->area.y1;
//
lv_coord_t draw_area_w = lv_area_get_width(&draw_area); // lv_coord_t draw_area_w = lv_area_get_width(&draw_area);
//
lv_area_t fill_area; // lv_area_t fill_area;
fill_area.x1 = draw_area.x1 + disp_area->x1; // fill_area.x1 = draw_area.x1 + disp_area->x1;
fill_area.x2 = draw_area.x2 + disp_area->x1; // fill_area.x2 = draw_area.x2 + disp_area->x1;
fill_area.y1 = draw_area.y1 + disp_area->y1; // fill_area.y1 = draw_area.y1 + disp_area->y1;
fill_area.y2 = fill_area.y1; // fill_area.y2 = fill_area.y1;
//
lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w); // lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w);
lv_coord_t h; // lv_coord_t h;
lv_draw_mask_res_t mask_res; // lv_draw_mask_res_t mask_res;
for(h = draw_area.y1; h <= draw_area.y2; h++) { // for(h = draw_area.y1; h <= draw_area.y2; h++) {
memset(mask_buf, LV_OPA_COVER, draw_area_w); // memset(mask_buf, LV_OPA_COVER, draw_area_w);
mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w); // mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
//
lv_blend_fill(clip, &fill_area, // lv_blend_fill(clip, &fill_area,
style->line.color, mask_buf, mask_res, style->line.opa, // style->line.color, mask_buf, mask_res, style->line.opa,
style->line.blend_mode); // style->line.blend_mode);
//
fill_area.y1++; // fill_area.y1++;
fill_area.y2++; // fill_area.y2++;
} // }
lv_mem_buf_release(mask_buf); // lv_mem_buf_release(mask_buf);
} // }
} //}
//
//
static void draw_line_ver(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, //static void draw_line_ver(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip,
const lv_style_t * style, lv_opa_t opa_scale) // const lv_style_t * style, lv_opa_t opa_scale)
{ //{
lv_opa_t opa = style->line.opa; // lv_opa_t opa = style->line.opa;
if(opa_scale != LV_OPA_COVER) opa = (opa * opa_scale) >> 8; // if(opa_scale != LV_OPA_COVER) opa = (opa * opa_scale) >> 8;
//
lv_disp_t * disp = lv_refr_get_disp_refreshing(); // lv_disp_t * disp = lv_refr_get_disp_refreshing();
lv_disp_buf_t * vdb = lv_disp_get_buf(disp); // lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
//
const lv_area_t * disp_area = &vdb->area; // const lv_area_t * disp_area = &vdb->area;
//
lv_coord_t w = style->line.width - 1; // lv_coord_t w = style->line.width - 1;
lv_coord_t w_half0 = w >> 1; // lv_coord_t w_half0 = w >> 1;
lv_coord_t w_half1 = w_half0 + (w & 0x1); /*Compensate rounding error*/ // lv_coord_t w_half1 = w_half0 + (w & 0x1); /*Compensate rounding error*/
//
//
int16_t other_mask_cnt = lv_draw_mask_get_cnt(); // int16_t other_mask_cnt = lv_draw_mask_get_cnt();
//
lv_area_t draw_area; // lv_area_t draw_area;
draw_area.x1 = point1->x - w_half1; // draw_area.x1 = point1->x - w_half1;
draw_area.x2 = point1->x + w_half0; // draw_area.x2 = point1->x + w_half0;
draw_area.y1 = LV_MATH_MIN(point1->y, point2->y); // draw_area.y1 = LV_MATH_MIN(point1->y, point2->y);
draw_area.y2 = LV_MATH_MAX(point1->y, point2->y) - 1; // draw_area.y2 = LV_MATH_MAX(point1->y, point2->y) - 1;
//
/*If there is no mask then simply draw a rectangle*/ // /*If there is no mask then simply draw a rectangle*/
if(other_mask_cnt == 0) { // if(other_mask_cnt == 0) {
//
lv_blend_fill(clip, &draw_area, // lv_blend_fill(clip, &draw_area,
style->line.color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, // style->line.color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa,
style->line.blend_mode); // style->line.blend_mode);
} // }
/*If there other mask apply it*/ // /*If there other mask apply it*/
else { // else {
/* Get clipped fill area which is the real draw area. // /* Get clipped fill area which is the real draw area.
* It is always the same or inside `fill_area` */ // * It is always the same or inside `fill_area` */
bool is_common; // bool is_common;
is_common = lv_area_intersect(&draw_area, clip, &draw_area); // is_common = lv_area_intersect(&draw_area, clip, &draw_area);
if(!is_common) return; // if(!is_common) return;
//
/* Now `draw_area` has absolute coordinates. // /* Now `draw_area` has absolute coordinates.
* Make it relative to `disp_area` to simplify draw to `disp_buf`*/ // * Make it relative to `disp_area` to simplify draw to `disp_buf`*/
draw_area.x1 -= vdb->area.x1; // draw_area.x1 -= vdb->area.x1;
draw_area.y1 -= vdb->area.y1; // draw_area.y1 -= vdb->area.y1;
draw_area.x2 -= vdb->area.x1; // draw_area.x2 -= vdb->area.x1;
draw_area.y2 -= vdb->area.y1; // draw_area.y2 -= vdb->area.y1;
//
lv_coord_t draw_area_w = lv_area_get_width(&draw_area); // lv_coord_t draw_area_w = lv_area_get_width(&draw_area);
//
lv_area_t fill_area; // lv_area_t fill_area;
fill_area.x1 = draw_area.x1 + disp_area->x1; // fill_area.x1 = draw_area.x1 + disp_area->x1;
fill_area.x2 = draw_area.x2 + disp_area->x1; // fill_area.x2 = draw_area.x2 + disp_area->x1;
fill_area.y1 = draw_area.y1 + disp_area->y1; // fill_area.y1 = draw_area.y1 + disp_area->y1;
fill_area.y2 = fill_area.y1; // fill_area.y2 = fill_area.y1;
//
lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w); // lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w);
lv_coord_t h; // lv_coord_t h;
lv_draw_mask_res_t mask_res; // lv_draw_mask_res_t mask_res;
for(h = draw_area.y1; h <= draw_area.y2; h++) { // for(h = draw_area.y1; h <= draw_area.y2; h++) {
memset(mask_buf, LV_OPA_COVER, draw_area_w); // memset(mask_buf, LV_OPA_COVER, draw_area_w);
mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w); // mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
//
lv_blend_fill(clip, &fill_area, // lv_blend_fill(clip, &fill_area,
style->line.color, mask_buf, mask_res, style->line.opa, // style->line.color, mask_buf, mask_res, style->line.opa,
LV_BLEND_MODE_NORMAL); // LV_BLEND_MODE_NORMAL);
//
fill_area.y1++; // fill_area.y1++;
fill_area.y2++; // fill_area.y2++;
} // }
lv_mem_buf_release(mask_buf); // lv_mem_buf_release(mask_buf);
} // }
} //}
//
//
static void draw_line_skew(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, //static void draw_line_skew(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip,
const lv_style_t * style, lv_opa_t opa_scale) // const lv_style_t * style, lv_opa_t opa_scale)
{ //{
lv_opa_t opa = style->line.opa; // lv_opa_t opa = style->line.opa;
if(opa_scale != LV_OPA_COVER) opa = (opa * opa_scale) >> 8; // if(opa_scale != LV_OPA_COVER) opa = (opa * opa_scale) >> 8;
//
/*Keep the great y in p1*/ // /*Keep the great y in p1*/
lv_point_t p1; // lv_point_t p1;
lv_point_t p2; // lv_point_t p2;
if(point1->y < point2->y) { // if(point1->y < point2->y) {
p1.y = point1->y; // p1.y = point1->y;
p2.y = point2->y; // p2.y = point2->y;
p1.x = point1->x; // p1.x = point1->x;
p2.x = point2->x; // p2.x = point2->x;
} else { // } else {
p1.y = point2->y; // p1.y = point2->y;
p2.y = point1->y; // p2.y = point1->y;
p1.x = point2->x; // p1.x = point2->x;
p2.x = point1->x; // p2.x = point1->x;
} // }
//
lv_coord_t xdiff = p2.x - p1.x; // lv_coord_t xdiff = p2.x - p1.x;
lv_coord_t ydiff = p2.y - p1.y; // lv_coord_t ydiff = p2.y - p1.y;
bool flat = LV_MATH_ABS(xdiff) > LV_MATH_ABS(ydiff) ? true : false; // bool flat = LV_MATH_ABS(xdiff) > LV_MATH_ABS(ydiff) ? true : false;
//
static const uint8_t wcorr[] = { // static const uint8_t wcorr[] = {
128, 128, 128, 129, 129, 130, 130, 131, // 128, 128, 128, 129, 129, 130, 130, 131,
132, 133, 134, 135, 137, 138, 140, 141, // 132, 133, 134, 135, 137, 138, 140, 141,
143, 145, 147, 149, 151, 153, 155, 158, // 143, 145, 147, 149, 151, 153, 155, 158,
160, 162, 165, 167, 170, 173, 175, 178, // 160, 162, 165, 167, 170, 173, 175, 178,
181, // 181,
}; // };
//
lv_coord_t w = style->line.width; // lv_coord_t w = style->line.width;
lv_coord_t wcorr_i = 0; // lv_coord_t wcorr_i = 0;
if(flat) wcorr_i = (LV_MATH_ABS(ydiff) << 5) / LV_MATH_ABS(xdiff); // if(flat) wcorr_i = (LV_MATH_ABS(ydiff) << 5) / LV_MATH_ABS(xdiff);
else wcorr_i = (LV_MATH_ABS(xdiff) << 5) / LV_MATH_ABS(ydiff); // else wcorr_i = (LV_MATH_ABS(xdiff) << 5) / LV_MATH_ABS(ydiff);
//
w = (w * wcorr[wcorr_i]) >> 7; // w = (w * wcorr[wcorr_i]) >> 7;
lv_coord_t w_half0 = w >> 1; // lv_coord_t w_half0 = w >> 1;
lv_coord_t w_half1 = w_half0 + (w & 0x1); /*Compensate rounding error*/ // lv_coord_t w_half1 = w_half0 + (w & 0x1); /*Compensate rounding error*/
//
lv_area_t draw_area; // lv_area_t draw_area;
draw_area.x1 = LV_MATH_MIN(p1.x, p2.x) - w; // draw_area.x1 = LV_MATH_MIN(p1.x, p2.x) - w;
draw_area.x2 = LV_MATH_MAX(p1.x, p2.x) + w; // draw_area.x2 = LV_MATH_MAX(p1.x, p2.x) + w;
draw_area.y1 = LV_MATH_MIN(p1.y, p2.y) - w; // draw_area.y1 = LV_MATH_MIN(p1.y, p2.y) - w;
draw_area.y2 = LV_MATH_MAX(p1.y, p2.y) + w; // draw_area.y2 = LV_MATH_MAX(p1.y, p2.y) + w;
//
/* Get the union of `coords` and `clip`*/ // /* Get the union of `coords` and `clip`*/
/* `clip` is already truncated to the `vdb` size // /* `clip` is already truncated to the `vdb` size
* in 'lv_refr_area' function */ // * in 'lv_refr_area' function */
bool is_common = lv_area_intersect(&draw_area, &draw_area, clip); // bool is_common = lv_area_intersect(&draw_area, &draw_area, clip);
if(is_common == false) return; // if(is_common == false) return;
//
lv_draw_mask_line_param_t mask_left_param; // lv_draw_mask_line_param_t mask_left_param;
lv_draw_mask_line_param_t mask_right_param; // lv_draw_mask_line_param_t mask_right_param;
lv_draw_mask_line_param_t mask_top_param; // lv_draw_mask_line_param_t mask_top_param;
lv_draw_mask_line_param_t mask_bottom_param; // lv_draw_mask_line_param_t mask_bottom_param;
//
if(flat) { // if(flat) {
if(xdiff > 0) { // if(xdiff > 0) {
lv_draw_mask_line_points_init(&mask_left_param, p1.x, p1.y - w_half0, p2.x, p2.y - w_half0, LV_DRAW_MASK_LINE_SIDE_LEFT); // lv_draw_mask_line_points_init(&mask_left_param, p1.x, p1.y - w_half0, p2.x, p2.y - w_half0, LV_DRAW_MASK_LINE_SIDE_LEFT);
lv_draw_mask_line_points_init(&mask_right_param, p1.x, p1.y + w_half1, p2.x, p2.y + w_half1, LV_DRAW_MASK_LINE_SIDE_RIGHT); // lv_draw_mask_line_points_init(&mask_right_param, p1.x, p1.y + w_half1, p2.x, p2.y + w_half1, LV_DRAW_MASK_LINE_SIDE_RIGHT);
} else { // } else {
lv_draw_mask_line_points_init(&mask_left_param, p1.x, p1.y + w_half1, p2.x, p2.y + w_half1, LV_DRAW_MASK_LINE_SIDE_LEFT); // lv_draw_mask_line_points_init(&mask_left_param, p1.x, p1.y + w_half1, p2.x, p2.y + w_half1, LV_DRAW_MASK_LINE_SIDE_LEFT);
lv_draw_mask_line_points_init(&mask_right_param, p1.x, p1.y - w_half0, p2.x, p2.y - w_half0, LV_DRAW_MASK_LINE_SIDE_RIGHT); // lv_draw_mask_line_points_init(&mask_right_param, p1.x, p1.y - w_half0, p2.x, p2.y - w_half0, LV_DRAW_MASK_LINE_SIDE_RIGHT);
} // }
} else { // } else {
lv_draw_mask_line_points_init(&mask_left_param, p1.x + w_half1, p1.y, p2.x + w_half1, p2.y, LV_DRAW_MASK_LINE_SIDE_LEFT); // lv_draw_mask_line_points_init(&mask_left_param, p1.x + w_half1, p1.y, p2.x + w_half1, p2.y, LV_DRAW_MASK_LINE_SIDE_LEFT);
lv_draw_mask_line_points_init(&mask_right_param, p1.x - w_half0, p1.y, p2.x - w_half0, p2.y, LV_DRAW_MASK_LINE_SIDE_RIGHT); // lv_draw_mask_line_points_init(&mask_right_param, p1.x - w_half0, p1.y, p2.x - w_half0, p2.y, LV_DRAW_MASK_LINE_SIDE_RIGHT);
} // }
//
/*Use the normal vector for the endings*/ // /*Use the normal vector for the endings*/
lv_draw_mask_line_points_init(&mask_top_param, p1.x, p1.y, p1.x - ydiff, p1.y + xdiff, LV_DRAW_MASK_LINE_SIDE_BOTTOM); // lv_draw_mask_line_points_init(&mask_top_param, p1.x, p1.y, p1.x - ydiff, p1.y + xdiff, LV_DRAW_MASK_LINE_SIDE_BOTTOM);
lv_draw_mask_line_points_init(&mask_bottom_param, p2.x, p2.y,p2.x - ydiff, p2.y + xdiff, LV_DRAW_MASK_LINE_SIDE_TOP); // lv_draw_mask_line_points_init(&mask_bottom_param, p2.x, p2.y,p2.x - ydiff, p2.y + xdiff, LV_DRAW_MASK_LINE_SIDE_TOP);
//
int16_t mask_left_id = lv_draw_mask_add(&mask_left_param, NULL); // int16_t mask_left_id = lv_draw_mask_add(&mask_left_param, NULL);
int16_t mask_right_id = lv_draw_mask_add(&mask_right_param, NULL); // int16_t mask_right_id = lv_draw_mask_add(&mask_right_param, NULL);
int16_t mask_top_id = lv_draw_mask_add(&mask_top_param, NULL); // int16_t mask_top_id = lv_draw_mask_add(&mask_top_param, NULL);
int16_t mask_bottom_id = lv_draw_mask_add(&mask_bottom_param, NULL); // int16_t mask_bottom_id = lv_draw_mask_add(&mask_bottom_param, NULL);
//
lv_disp_t * disp = lv_refr_get_disp_refreshing(); // lv_disp_t * disp = lv_refr_get_disp_refreshing();
lv_disp_buf_t * vdb = lv_disp_get_buf(disp); // lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
//
const lv_area_t * disp_area = &vdb->area; // const lv_area_t * disp_area = &vdb->area;
//
/*Store the coordinates of the `draw_a` relative to the VDB */ // /*Store the coordinates of the `draw_a` relative to the VDB */
draw_area.x1 -= disp_area->x1; // draw_area.x1 -= disp_area->x1;
draw_area.y1 -= disp_area->y1; // draw_area.y1 -= disp_area->y1;
draw_area.x2 -= disp_area->x1; // draw_area.x2 -= disp_area->x1;
draw_area.y2 -= disp_area->y1; // draw_area.y2 -= disp_area->y1;
//
lv_coord_t draw_area_w = lv_area_get_width(&draw_area); // lv_coord_t draw_area_w = lv_area_get_width(&draw_area);
//
/*Draw the background line by line*/ // /*Draw the background line by line*/
lv_coord_t h; // lv_coord_t h;
lv_draw_mask_res_t mask_res; // lv_draw_mask_res_t mask_res;
lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w); // lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w);
lv_area_t fill_area; // lv_area_t fill_area;
fill_area.x1 = draw_area.x1 + disp_area->x1; // fill_area.x1 = draw_area.x1 + disp_area->x1;
fill_area.x2 = draw_area.x2 + disp_area->x1; // fill_area.x2 = draw_area.x2 + disp_area->x1;
fill_area.y1 = draw_area.y1 + disp_area->y1; // fill_area.y1 = draw_area.y1 + disp_area->y1;
fill_area.y2 = fill_area.y1; // fill_area.y2 = fill_area.y1;
//
/*Fill the first row with 'color'*/ // /*Fill the first row with 'color'*/
for(h = draw_area.y1; h <= draw_area.y2; h++) { // for(h = draw_area.y1; h <= draw_area.y2; h++) {
memset(mask_buf, LV_OPA_COVER, draw_area_w); // memset(mask_buf, LV_OPA_COVER, draw_area_w);
mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w); // mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
//
lv_blend_fill(clip, &fill_area, // lv_blend_fill(clip, &fill_area,
style->line.color, mask_buf, mask_res, opa, // style->line.color, mask_buf, mask_res, opa,
style->line.blend_mode); // style->line.blend_mode);
//
fill_area.y1++; // fill_area.y1++;
fill_area.y2++; // fill_area.y2++;
} // }
//
lv_mem_buf_release(mask_buf); // lv_mem_buf_release(mask_buf);
//
lv_draw_mask_remove_id(mask_left_id); // lv_draw_mask_remove_id(mask_left_id);
lv_draw_mask_remove_id(mask_right_id); // lv_draw_mask_remove_id(mask_right_id);
lv_draw_mask_remove_id(mask_top_id); // lv_draw_mask_remove_id(mask_top_id);
lv_draw_mask_remove_id(mask_bottom_id); // lv_draw_mask_remove_id(mask_bottom_id);
} //}

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,7 @@ extern "C" {
* INCLUDES * INCLUDES
*********************/ *********************/
#include "lv_draw.h" #include "lv_draw.h"
#include "../lv_core/lv_style.h"
/********************* /*********************
* DEFINES * DEFINES
@ -23,10 +24,26 @@ extern "C" {
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
typedef struct {
lv_color_t bg_color;
lv_color_t bg_grad_color;
lv_style_value_t border_width;
lv_color_t border_color;
lv_blend_mode_t border_blend_mode;
lv_opa_t bg_opa;
lv_opa_t border_opa;
lv_style_value_t radius;
lv_style_value_t border_part;
lv_style_value_t bg_grad_dir;
lv_style_value_t bg_blend_mode;
}lv_draw_rect_dsc_t;
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
**********************/ **********************/
void lv_draw_rect_dsc_init(lv_draw_rect_dsc_t * dsc);
/** /**
* Draw a rectangle * Draw a rectangle
* @param coords the coordinates of the rectangle * @param coords the coordinates of the rectangle
@ -34,7 +51,7 @@ extern "C" {
* @param style pointer to a style * @param style pointer to a style
* @param opa_scale scale down all opacities by the factor * @param opa_scale scale down all opacities by the factor
*/ */
void lv_draw_rect(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale); void lv_draw_rect(const lv_area_t * coords, const lv_area_t * mask, lv_draw_rect_dsc_t * dsc, lv_opa_t opa_scale);
/** /**
* Draw a pixel * Draw a pixel

View File

@ -62,7 +62,7 @@ static uint16_t entry_cnt;
* @param style style of the image * @param style style of the image
* @return pointer to the cache entry or NULL if can open the image * @return pointer to the cache entry or NULL if can open the image
*/ */
lv_img_cache_entry_t * lv_img_cache_open(const void * src, const lv_style_t * style) lv_img_cache_entry_t * lv_img_cache_open(const void * src, lv_color_t color)
{ {
if(entry_cnt == 0) { if(entry_cnt == 0) {
LV_LOG_WARN("lv_img_cache_open: the cache size is 0"); LV_LOG_WARN("lv_img_cache_open: the cache size is 0");
@ -124,7 +124,7 @@ lv_img_cache_entry_t * lv_img_cache_open(const void * src, const lv_style_t * st
uint32_t t_start; uint32_t t_start;
t_start = lv_tick_get(); t_start = lv_tick_get();
cached_src->dec_dsc.time_to_open = 0; cached_src->dec_dsc.time_to_open = 0;
lv_res_t open_res = lv_img_decoder_open(&cached_src->dec_dsc, src, style); lv_res_t open_res = lv_img_decoder_open(&cached_src->dec_dsc, src, color);
if(open_res == LV_RES_INV) { if(open_res == LV_RES_INV) {
LV_LOG_WARN("Image draw cannot open the image resource"); LV_LOG_WARN("Image draw cannot open the image resource");
lv_img_decoder_close(&cached_src->dec_dsc); lv_img_decoder_close(&cached_src->dec_dsc);

View File

@ -50,7 +50,7 @@ typedef struct
* @param style style of the image * @param style style of the image
* @return pointer to the cache entry or NULL if can open the image * @return pointer to the cache entry or NULL if can open the image
*/ */
lv_img_cache_entry_t * lv_img_cache_open(const void * src, const lv_style_t * style); lv_img_cache_entry_t * lv_img_cache_open(const void * src, lv_color_t color);
/** /**
* Set the number of images to be cached. * Set the number of images to be cached.

View File

@ -117,9 +117,9 @@ lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header)
* @return LV_RES_OK: opened the image. `dsc->img_data` and `dsc->header` are set. * @return LV_RES_OK: opened the image. `dsc->img_data` and `dsc->header` are set.
* LV_RES_INV: none of the registered image decoders were able to open the image. * LV_RES_INV: none of the registered image decoders were able to open the image.
*/ */
lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, const lv_style_t * style) lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, lv_color_t color)
{ {
dsc->style = style; dsc->color = color;
dsc->src_type = lv_img_src_get_type(src); dsc->src_type = lv_img_src_get_type(src);
dsc->user_data = NULL; dsc->user_data = NULL;
@ -569,7 +569,7 @@ static lv_res_t lv_img_decoder_built_in_line_alpha(lv_img_decoder_dsc_t * dsc, l
68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255}; 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255};
/*Simply fill the buffer with the color. Later only the alpha value will be modified.*/ /*Simply fill the buffer with the color. Later only the alpha value will be modified.*/
lv_color_t bg_color = dsc->style->image.color; lv_color_t bg_color = dsc->color;
lv_coord_t i; lv_coord_t i;
for(i = 0; i < len; i++) { for(i = 0; i < len; i++) {
#if LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1 #if LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1

View File

@ -110,7 +110,7 @@ typedef struct _lv_img_decoder_dsc
const void * src; const void * src;
/**Style to draw the image.*/ /**Style to draw the image.*/
const lv_style_t * style; lv_color_t color;
/**Type of the source: file or variable. Can be set in `open` function if required*/ /**Type of the source: file or variable. Can be set in `open` function if required*/
lv_img_src_t src_type; lv_img_src_t src_type;
@ -167,7 +167,7 @@ lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header);
* @return LV_RES_OK: opened the image. `dsc->img_data` and `dsc->header` are set. * @return LV_RES_OK: opened the image. `dsc->img_data` and `dsc->header` are set.
* LV_RES_INV: none of the registered image decoders were able to open the image. * LV_RES_INV: none of the registered image decoders were able to open the image.
*/ */
lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, const lv_style_t * style); lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, lv_color_t color);
/** /**
* Read a line from an opened image * Read a line from an opened image

View File

@ -139,8 +139,10 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
disp->act_scr = lv_obj_create(NULL, NULL); /*Create a default screen on the display*/ disp->act_scr = lv_obj_create(NULL, NULL); /*Create a default screen on the display*/
disp->top_layer = lv_obj_create(NULL, NULL); /*Create top layer on the display*/ disp->top_layer = lv_obj_create(NULL, NULL); /*Create top layer on the display*/
disp->sys_layer = lv_obj_create(NULL, NULL); /*Create sys layer on the display*/ disp->sys_layer = lv_obj_create(NULL, NULL); /*Create sys layer on the display*/
lv_obj_set_style(disp->top_layer, &lv_style_transp); // lv_obj_set_style(disp->top_layer, &lv_style_transp);
lv_obj_set_style(disp->sys_layer, &lv_style_transp); // lv_obj_set_style(disp->sys_layer, &lv_style_transp);
lv_obj_set_hidden(disp->top_layer, true);
lv_obj_set_hidden(disp->sys_layer, true);
lv_obj_invalidate(disp->act_scr); lv_obj_invalidate(disp->act_scr);