diff --git a/demos/render/lv_demo_render.c b/demos/render/lv_demo_render.c index ea52b6263..a827fe036 100644 --- a/demos/render/lv_demo_render.c +++ b/demos/render/lv_demo_render.c @@ -871,7 +871,7 @@ static lv_obj_t * create_linear_gradient_obj(lv_obj_t * parent, int32_t col, int }; /*init gradient color map*/ - lv_gradient_init_stops(grad, grad_color, use_opa_map ? grad_opa : NULL, NULL, sizeof(grad_color) / sizeof(lv_color_t)); + lv_grad_init_stops(grad, grad_color, use_opa_map ? grad_opa : NULL, NULL, sizeof(grad_color) / sizeof(lv_color_t)); /*init gradient parameters*/ grad->dir = LV_GRAD_DIR_LINEAR; @@ -947,7 +947,7 @@ static lv_obj_t * create_radial_gradient_obj(lv_obj_t * parent, int32_t col, int }; /*init gradient color map*/ - lv_gradient_init_stops(grad, grad_color, use_opa_map ? grad_opa : NULL, NULL, sizeof(grad_color) / sizeof(lv_color_t)); + lv_grad_init_stops(grad, grad_color, use_opa_map ? grad_opa : NULL, NULL, sizeof(grad_color) / sizeof(lv_color_t)); /*init gradient parameters*/ grad->dir = LV_GRAD_DIR_RADIAL; @@ -1025,7 +1025,7 @@ static lv_obj_t * create_conical_gradient_obj(lv_obj_t * parent, int32_t col, in }; /*init gradient color map*/ - lv_gradient_init_stops(grad, grad_color, use_opa_map ? grad_opa : NULL, NULL, sizeof(grad_color) / sizeof(lv_color_t)); + lv_grad_init_stops(grad, grad_color, use_opa_map ? grad_opa : NULL, NULL, sizeof(grad_color) / sizeof(lv_color_t)); /*init gradient parameters*/ grad->dir = LV_GRAD_DIR_CONICAL; diff --git a/demos/vector_graphic/lv_demo_vector_graphic.c b/demos/vector_graphic/lv_demo_vector_graphic.c index 38729da05..24958b4db 100644 --- a/demos/vector_graphic/lv_demo_vector_graphic.c +++ b/demos/vector_graphic/lv_demo_vector_graphic.c @@ -58,7 +58,7 @@ static void draw_gradient(lv_vector_dsc_t * ctx, lv_vector_path_t * path) lv_vector_path_quad_to(path, &pts[1], &pts[2]); lv_vector_path_close(path); - lv_gradient_stop_t stops[2]; + lv_grad_stop_t stops[2]; lv_memzero(stops, sizeof(stops)); stops[0].color = lv_color_hex(0xff0000); stops[0].opa = LV_OPA_COVER; @@ -90,7 +90,7 @@ static void draw_radial_gradient(lv_vector_dsc_t * ctx, lv_vector_path_t * path) lv_vector_path_line_to(path, &pts[3]); lv_vector_path_close(path); - lv_gradient_stop_t stops[2]; + lv_grad_stop_t stops[2]; lv_memzero(stops, sizeof(stops)); stops[0].color = lv_color_hex(0xff0000); stops[0].opa = LV_OPA_COVER; diff --git a/examples/grad/index.rst b/examples/grad/index.rst new file mode 100644 index 000000000..a8a4fc415 --- /dev/null +++ b/examples/grad/index.rst @@ -0,0 +1,25 @@ + + +Play with a simple horizontal gradient +-------------------------------------- + +.. lv_example:: get_started/lv_example_grad_1 + :language: c + +Play with a linear (skew) gradient +---------------------------------- + +.. lv_example:: get_started/lv_example_grad_2 + :language: c + +Play with a radial gradient +--------------------------- + +.. lv_example:: get_started/lv_example_grad_3 + :language: c + +Play with a conical gradient +---------------------------- + +.. lv_example:: get_started/lv_example_grad_4 + :language: c diff --git a/src/draw/sw/lv_draw_sw_gradient_private.h b/examples/grad/lv_example_grad.h similarity index 55% rename from src/draw/sw/lv_draw_sw_gradient_private.h rename to examples/grad/lv_example_grad.h index a1e14932c..330013c7c 100644 --- a/src/draw/sw/lv_draw_sw_gradient_private.h +++ b/examples/grad/lv_example_grad.h @@ -1,10 +1,10 @@ /** - * @file lv_draw_sw_gradient_private.h + * @file lv_example_grad.h * */ -#ifndef LV_DRAW_SW_GRADIENT_PRIVATE_H -#define LV_DRAW_SW_GRADIENT_PRIVATE_H +#ifndef LV_EXAMPLE_GRAD_H +#define LV_EXAMPLE_GRAD_H #ifdef __cplusplus extern "C" { @@ -14,10 +14,6 @@ extern "C" { * INCLUDES *********************/ -#include "lv_draw_sw_gradient.h" - -#if LV_USE_DRAW_SW - /********************* * DEFINES *********************/ @@ -26,25 +22,20 @@ extern "C" { * TYPEDEFS **********************/ -struct _lv_grad_t { - lv_color_t * color_map; - lv_opa_t * opa_map; - uint32_t size; -}; - - /********************** * GLOBAL PROTOTYPES **********************/ +void lv_example_grad_1(void); +void lv_example_grad_2(void); +void lv_example_grad_3(void); +void lv_example_grad_4(void); /********************** * MACROS **********************/ -#endif /* LV_USE_DRAW_SW */ - #ifdef __cplusplus } /*extern "C"*/ #endif -#endif /*LV_DRAW_SW_GRADIENT_PRIVATE_H*/ +#endif /*LV_EXAMPLE_GRAD_H*/ diff --git a/examples/grad/lv_example_grad_1.c b/examples/grad/lv_example_grad_1.c new file mode 100644 index 000000000..7b1abf6d8 --- /dev/null +++ b/examples/grad/lv_example_grad_1.c @@ -0,0 +1,109 @@ +#include "../lv_examples.h" +#if LV_BUILD_EXAMPLES && LV_USE_LABEL + +static void position_bullet(lv_event_t * e, lv_point_t * p) +{ + lv_indev_t * indev = lv_event_get_param(e); + lv_indev_get_point(indev, p); + + lv_obj_t * bullet = lv_event_get_target(e); + lv_obj_t * parent = lv_obj_get_parent(bullet); + + p->x -= lv_obj_get_x(parent); + p->y -= lv_obj_get_y(parent); + + int32_t w = lv_obj_get_width(parent); + int32_t h = lv_obj_get_height(parent); + lv_obj_set_pos(bullet, LV_CLAMP(5, p->x, w - 20), LV_CLAMP(5, p->y, h - 20)); +} + +static void frac_1_event_cb(lv_event_t * e) +{ + lv_style_t * style = lv_event_get_user_data(e); + lv_style_value_t v; + lv_style_get_prop(style, LV_STYLE_BG_GRAD, &v); + lv_grad_dsc_t * dsc = (lv_grad_dsc_t *)v.ptr; + + lv_point_t p; + position_bullet(e, &p); + + lv_obj_t * bullet = lv_event_get_target(e); + lv_obj_t * parent = lv_obj_get_parent(bullet); + dsc->stops[0].frac = LV_CLAMP(0, p.x * 255 / lv_obj_get_width(parent), 255); + + lv_obj_invalidate(parent); +} + +static void frac_2_event_cb(lv_event_t * e) +{ + lv_style_t * style = lv_event_get_user_data(e); + lv_style_value_t v; + lv_style_get_prop(style, LV_STYLE_BG_GRAD, &v); + lv_grad_dsc_t * dsc = (lv_grad_dsc_t *)v.ptr; + + lv_point_t p; + position_bullet(e, &p); + + lv_obj_t * bullet = lv_event_get_target(e); + lv_obj_t * parent = lv_obj_get_parent(bullet); + + dsc->stops[1].frac = LV_CLAMP(0, p.x * 255 / lv_obj_get_width(parent), 255); + lv_obj_invalidate(parent); +} + +/** + * Play with a simple horizontal gradient. + * Adjust the stop positions of the gradient. + */ +void lv_example_grad_1(void) +{ + static const lv_color_t grad_colors[2] = { + LV_COLOR_MAKE(0xff, 0x00, 0x00), + LV_COLOR_MAKE(0x00, 0xff, 0x00), + }; + + static const lv_opa_t grad_opa[2] = { + LV_OPA_100, + LV_OPA_0, + }; + + static const uint8_t frac[2] = { + 20 * 255 / 100, /*20%*/ + 80 * 255 / 100, /*80%*/ + }; + + static lv_style_t style; + lv_style_init(&style); + + static lv_grad_dsc_t grad_dsc; + lv_grad_init_stops(&grad_dsc, grad_colors, grad_opa, frac, sizeof(grad_colors) / sizeof(lv_color_t)); + lv_grad_horizontal_init(&grad_dsc); + + /*Set gradient as background*/ + lv_style_set_bg_grad(&style, &grad_dsc); + lv_style_set_border_width(&style, 2); + lv_style_set_pad_all(&style, 0); + lv_style_set_radius(&style, 12); + + /*Create an object with the new style*/ + lv_obj_t * obj = lv_obj_create(lv_screen_active()); + lv_obj_add_style(obj, &style, 0); + lv_obj_set_size(obj, lv_pct(80), lv_pct(80)); + lv_obj_center(obj); + + lv_obj_t * frac_1 = lv_button_create(obj); + lv_obj_set_size(frac_1, 15, 15); + lv_obj_set_style_bg_color(frac_1, lv_color_hex(0xff00ff), 0); + lv_obj_add_event_cb(frac_1, frac_1_event_cb, LV_EVENT_PRESSING, &style); + lv_obj_set_ext_click_area(frac_1, 5); + lv_obj_set_pos(frac_1, lv_pct(20), lv_pct(50)); + + lv_obj_t * frac_2 = lv_button_create(obj); + lv_obj_set_size(frac_2, 15, 15); + lv_obj_set_style_bg_color(frac_2, lv_color_hex(0xffff00), 0); + lv_obj_add_event_cb(frac_2, frac_2_event_cb, LV_EVENT_PRESSING, &style); + lv_obj_set_ext_click_area(frac_2, 5); + lv_obj_set_pos(frac_2, lv_pct(80), lv_pct(50)); +} + +#endif diff --git a/examples/grad/lv_example_grad_2.c b/examples/grad/lv_example_grad_2.c new file mode 100644 index 000000000..2de98181c --- /dev/null +++ b/examples/grad/lv_example_grad_2.c @@ -0,0 +1,122 @@ +#include "../lv_examples.h" +#if LV_BUILD_EXAMPLES && LV_USE_LABEL + +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS +static void position_bullet(lv_event_t * e, lv_point_t * p) +{ + lv_indev_t * indev = lv_event_get_param(e); + lv_indev_get_point(indev, p); + + lv_obj_t * bullet = lv_event_get_target(e); + lv_obj_t * parent = lv_obj_get_parent(bullet); + + p->x -= lv_obj_get_x(parent); + p->y -= lv_obj_get_y(parent); + + int32_t w = lv_obj_get_width(parent); + int32_t h = lv_obj_get_height(parent); + lv_obj_set_pos(bullet, LV_CLAMP(5, p->x, w - 20), LV_CLAMP(5, p->y, h - 20)); +} + +static void start_event_cb(lv_event_t * e) +{ + lv_style_t * style = lv_event_get_user_data(e); + lv_style_value_t v; + lv_style_get_prop(style, LV_STYLE_BG_GRAD, &v); + lv_grad_dsc_t * dsc = (lv_grad_dsc_t *)v.ptr; + + lv_point_t p; + position_bullet(e, &p); + + dsc->params.linear.start.x = p.x; + dsc->params.linear.start.y = p.y; + + lv_obj_t * bullet = lv_event_get_target(e); + lv_obj_t * parent = lv_obj_get_parent(bullet); + lv_obj_invalidate(parent); +} + +static void end_event_cb(lv_event_t * e) +{ + lv_style_t * style = lv_event_get_user_data(e); + lv_style_value_t v; + lv_style_get_prop(style, LV_STYLE_BG_GRAD, &v); + lv_grad_dsc_t * dsc = (lv_grad_dsc_t *)v.ptr; + + lv_point_t p; + position_bullet(e, &p); + + dsc->params.linear.end.x = p.x; + dsc->params.linear.end.y = p.y; + + lv_obj_t * bullet = lv_event_get_target(e); + lv_obj_t * parent = lv_obj_get_parent(bullet); + lv_obj_invalidate(parent); +} + +/** + * Play with the linear gradient. + * Adjust the 2 point in between the a linear gradient can be drawn (can be skew as well) + */ +void lv_example_grad_2(void) +{ + static const lv_color_t grad_colors[2] = { + LV_COLOR_MAKE(0xff, 0x00, 0x00), + LV_COLOR_MAKE(0x00, 0xff, 0x00), + }; + + static const lv_opa_t grad_opa[2] = { + LV_OPA_100, + LV_OPA_0, + }; + + + static lv_style_t style; + lv_style_init(&style); + + /*First define a color gradient. In this example we use a purple to black color map.*/ + static lv_grad_dsc_t grad; + + lv_grad_init_stops(&grad, grad_colors, grad_opa, NULL, sizeof(grad_colors) / sizeof(lv_color_t)); + + lv_grad_linear_init(&grad, 100, 100, 200, 150, LV_GRAD_EXTEND_PAD); + + /*Set gradient as background*/ + lv_style_set_bg_grad(&style, &grad); + lv_style_set_border_width(&style, 2); + lv_style_set_pad_all(&style, 0); + lv_style_set_radius(&style, 12); + + /*Create an object with the new style*/ + lv_obj_t * obj = lv_obj_create(lv_screen_active()); + lv_obj_add_style(obj, &style, 0); + lv_obj_set_size(obj, lv_pct(80), lv_pct(80)); + lv_obj_center(obj); + + lv_obj_t * start = lv_button_create(obj); + lv_obj_set_size(start, 15, 15); + lv_obj_set_style_bg_color(start, lv_color_hex(0x0000ff), 0); + lv_obj_add_event_cb(start, start_event_cb, LV_EVENT_PRESSING, &style); + lv_obj_set_ext_click_area(start, 5); + lv_obj_set_pos(start, 100, 100); + + lv_obj_t * end = lv_button_create(obj); + lv_obj_set_size(end, 15, 15); + lv_obj_set_style_bg_color(end, lv_color_hex(0x00ffff), 0); + lv_obj_add_event_cb(end, end_event_cb, LV_EVENT_PRESSING, &style); + lv_obj_set_ext_click_area(end, 5); + lv_obj_set_pos(end, 200, 150); +} + +#else + +void lv_example_grad_2(void) +{ + lv_obj_t * label = lv_label_create(lv_screen_active()); + lv_label_set_text(label, "LV_USE_DRAW_SW_COMPLEX_GRADIENTS needs to be enabled"); + lv_obj_center(label); +} + +#endif /*LV_USE_DRAW_SW_COMPLEX_GRADIENTS*/ + +#endif diff --git a/examples/grad/lv_example_grad_3.c b/examples/grad/lv_example_grad_3.c new file mode 100644 index 000000000..bb2ec83fe --- /dev/null +++ b/examples/grad/lv_example_grad_3.c @@ -0,0 +1,135 @@ +#include "../lv_examples.h" +#if LV_BUILD_EXAMPLES && LV_USE_LABEL + +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + +static void position_bullet(lv_event_t * e, lv_point_t * p) +{ + lv_indev_t * indev = lv_event_get_param(e); + lv_indev_get_point(indev, p); + + lv_obj_t * bullet = lv_event_get_target(e); + lv_obj_t * parent = lv_obj_get_parent(bullet); + + p->x -= lv_obj_get_x(parent); + p->y -= lv_obj_get_y(parent); + + int32_t w = lv_obj_get_width(parent); + int32_t h = lv_obj_get_height(parent); + lv_obj_set_pos(bullet, LV_CLAMP(5, p->x, w - 20), LV_CLAMP(5, p->y, h - 20)); +} + +static void focal_event_cb(lv_event_t * e) +{ + lv_style_t * style = lv_event_get_user_data(e); + lv_style_value_t v; + lv_style_get_prop(style, LV_STYLE_BG_GRAD, &v); + lv_grad_dsc_t * dsc = (lv_grad_dsc_t *)v.ptr; + + lv_point_t p; + position_bullet(e, &p); + + dsc->params.radial.focal.x = p.x; + dsc->params.radial.focal.y = p.y; + dsc->params.radial.focal_extent.x = p.x + 10; + dsc->params.radial.focal_extent.y = p.y; + + lv_obj_t * bullet = lv_event_get_target(e); + lv_obj_t * parent = lv_obj_get_parent(bullet); + lv_obj_invalidate(parent); +} + +static void end_event_cb(lv_event_t * e) +{ + lv_style_t * style = lv_event_get_user_data(e); + lv_style_value_t v; + lv_style_get_prop(style, LV_STYLE_BG_GRAD, &v); + lv_grad_dsc_t * dsc = (lv_grad_dsc_t *)v.ptr; + + lv_point_t p; + position_bullet(e, &p); + + dsc->params.radial.end.x = p.x; + dsc->params.radial.end.y = p.y; + dsc->params.radial.end_extent.x = p.x + 100; + dsc->params.radial.end_extent.y = p.y; + lv_obj_t * bullet = lv_event_get_target(e); + lv_obj_t * parent = lv_obj_get_parent(bullet); + lv_obj_invalidate(parent); +} + +/** + * Play with the radial gradient + * Adjust the end circle and focal point position. + * The radius of the end circle and an focal point are hardcoded in the example. + */ +void lv_example_grad_3(void) +{ + static const lv_color_t grad_colors[2] = { + LV_COLOR_MAKE(0xff, 0x00, 0x00), + LV_COLOR_MAKE(0x00, 0xff, 0x00), + }; + + static const lv_opa_t grad_opa[2] = { + LV_OPA_100, + LV_OPA_0, + }; + + static lv_style_t style; + lv_style_init(&style); + + /*First define a color gradient. In this example we use a purple to black color map.*/ + static lv_grad_dsc_t grad; + + lv_grad_init_stops(&grad, grad_colors, grad_opa, NULL, sizeof(grad_colors) / sizeof(lv_color_t)); + + /*Init a radial gradient where the center is at 100;100 + *and the edge of the circle is at 200;100. + *Try LV_GRAD_EXTEND_REFLECT and LV_GRAD_EXTEND_REPEAT too. */ + lv_grad_radial_init(&grad, 100, 100, 200, 100, LV_GRAD_EXTEND_PAD); + + /*The gradient will be calculated between the focal point's circle and the + *edge of the circle. If the center of the focal point and the + *center of the main circle is the same, the gradient will spread + *evenly in all directions. The focal point should be inside the + *main circle.*/ + lv_grad_radial_set_focal(&grad, 50, 50, 10); + + /*Set the widget containing the gradient*/ + lv_style_set_bg_grad(&style, &grad); + lv_style_set_border_width(&style, 2); + lv_style_set_pad_all(&style, 0); + lv_style_set_radius(&style, 12); + + /*Create an object with the new style*/ + lv_obj_t * obj = lv_obj_create(lv_screen_active()); + lv_obj_add_style(obj, &style, 0); + lv_obj_set_size(obj, lv_pct(80), lv_pct(80)); + lv_obj_center(obj); + + lv_obj_t * focal = lv_button_create(obj); + lv_obj_set_size(focal, 15, 15); + lv_obj_set_style_bg_color(focal, lv_color_hex(0x0000ff), 0); + lv_obj_add_event_cb(focal, focal_event_cb, LV_EVENT_PRESSING, &style); + lv_obj_set_ext_click_area(focal, 5); + lv_obj_set_pos(focal, 50, 50); + + lv_obj_t * end = lv_button_create(obj); + lv_obj_set_size(end, 15, 15); + lv_obj_set_style_bg_color(end, lv_color_hex(0x00ffff), 0); + lv_obj_add_event_cb(end, end_event_cb, LV_EVENT_PRESSING, &style); + lv_obj_set_ext_click_area(end, 5); + lv_obj_set_pos(end, 100, 100); +} +#else + +void lv_example_grad_3(void) +{ + lv_obj_t * label = lv_label_create(lv_screen_active()); + lv_label_set_text(label, "LV_USE_DRAW_SW_COMPLEX_GRADIENTS needs to be enabled"); + lv_obj_center(label); +} + +#endif /*LV_USE_DRAW_SW_COMPLEX_GRADIENTS*/ + +#endif diff --git a/examples/grad/lv_example_grad_4.c b/examples/grad/lv_example_grad_4.c new file mode 100644 index 000000000..303108d7c --- /dev/null +++ b/examples/grad/lv_example_grad_4.c @@ -0,0 +1,123 @@ +#include "../lv_examples.h" +#if LV_BUILD_EXAMPLES && LV_USE_LABEL + +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + +static void position_bullet(lv_event_t * e, lv_point_t * p) +{ + lv_indev_t * indev = lv_event_get_param(e); + lv_indev_get_point(indev, p); + + lv_obj_t * bullet = lv_event_get_target(e); + lv_obj_t * parent = lv_obj_get_parent(bullet); + + p->x -= lv_obj_get_x(parent); + p->y -= lv_obj_get_y(parent); + + int32_t w = lv_obj_get_width(parent); + int32_t h = lv_obj_get_height(parent); + lv_obj_set_pos(bullet, LV_CLAMP(5, p->x, w - 20), LV_CLAMP(5, p->y, h - 20)); +} + +static void start_event_cb(lv_event_t * e) +{ + lv_style_t * style = lv_event_get_user_data(e); + lv_style_value_t v; + lv_style_get_prop(style, LV_STYLE_BG_GRAD, &v); + lv_grad_dsc_t * dsc = (lv_grad_dsc_t *)v.ptr; + + lv_point_t p; + position_bullet(e, &p); + + lv_obj_t * bullet = lv_event_get_target(e); + lv_obj_t * parent = lv_obj_get_parent(bullet); + p.x -= lv_obj_get_width(parent) / 2; + p.y -= lv_obj_get_height(parent) / 2; + + dsc->params.conical.start_angle = lv_atan2(p.y, p.x); + lv_obj_invalidate(parent); +} + +static void end_event_cb(lv_event_t * e) +{ + lv_style_t * style = lv_event_get_user_data(e); + lv_style_value_t v; + lv_style_get_prop(style, LV_STYLE_BG_GRAD, &v); + lv_grad_dsc_t * dsc = (lv_grad_dsc_t *)v.ptr; + + lv_point_t p; + position_bullet(e, &p); + + lv_obj_t * bullet = lv_event_get_target(e); + lv_obj_t * parent = lv_obj_get_parent(bullet); + p.x -= lv_obj_get_width(parent) / 2; + p.y -= lv_obj_get_height(parent) / 2; + + dsc->params.conical.end_angle = lv_atan2(p.y, p.x); + lv_obj_invalidate(parent); +} + +/** + * Play with the conical gradient + */ +void lv_example_grad_4(void) +{ + static const lv_color_t grad_colors[2] = { + LV_COLOR_MAKE(0xff, 0x00, 0x00), + LV_COLOR_MAKE(0x00, 0xff, 0x00), + }; + + static const lv_opa_t grad_opa[2] = { + LV_OPA_100, + LV_OPA_0, + }; + + static lv_style_t style; + lv_style_init(&style); + + /*First define a color gradient. In this example we use a purple to black color map.*/ + static lv_grad_dsc_t grad; + + lv_grad_init_stops(&grad, grad_colors, grad_opa, NULL, sizeof(grad_colors) / sizeof(lv_color_t)); + + lv_grad_conical_init(&grad, lv_pct(50), lv_pct(50), 0, 180, LV_GRAD_EXTEND_PAD); + + /*Set gradient as background*/ + lv_style_set_bg_grad(&style, &grad); + lv_style_set_border_width(&style, 2); + lv_style_set_pad_all(&style, 0); + lv_style_set_radius(&style, 12); + + /*Create an object with the new style*/ + lv_obj_t * obj = lv_obj_create(lv_screen_active()); + lv_obj_add_style(obj, &style, 0); + lv_obj_set_size(obj, lv_pct(80), lv_pct(80)); + lv_obj_center(obj); + + lv_obj_t * start = lv_button_create(obj); + lv_obj_set_size(start, 15, 15); + lv_obj_set_style_bg_color(start, lv_color_hex(0x0000ff), 0); + lv_obj_add_event_cb(start, start_event_cb, LV_EVENT_PRESSING, &style); + lv_obj_set_ext_click_area(start, 5); + lv_obj_set_pos(start, lv_pct(80), lv_pct(50)); + + lv_obj_t * end = lv_button_create(obj); + lv_obj_set_size(end, 15, 15); + lv_obj_set_style_bg_color(end, lv_color_hex(0x00ffff), 0); + lv_obj_add_event_cb(end, end_event_cb, LV_EVENT_PRESSING, &style); + lv_obj_set_ext_click_area(end, 5); + lv_obj_set_pos(end, lv_pct(20), lv_pct(50)); +} + +#else + +void lv_example_grad_4(void) +{ + lv_obj_t * label = lv_label_create(lv_screen_active()); + lv_label_set_text(label, "LV_USE_DRAW_SW_COMPLEX_GRADIENTS needs to be enabled"); + lv_obj_center(label); +} + +#endif /*LV_USE_DRAW_SW_COMPLEX_GRADIENTS*/ + +#endif diff --git a/examples/lv_examples.h b/examples/lv_examples.h index b4f6c91b5..d28ad13c1 100644 --- a/examples/lv_examples.h +++ b/examples/lv_examples.h @@ -25,6 +25,7 @@ extern "C" { #include "scroll/lv_example_scroll.h" #include "styles/lv_example_style.h" #include "widgets/lv_example_widgets.h" +#include "grad/lv_example_grad.h" /********************* * DEFINES diff --git a/examples/styles/lv_example_style_16.c b/examples/styles/lv_example_style_16.c index 3650974ad..48c8aa840 100644 --- a/examples/styles/lv_example_style_16.c +++ b/examples/styles/lv_example_style_16.c @@ -47,7 +47,7 @@ void lv_example_style_16(void) /*First define a color gradient. In this example we use a gray color map with random values.*/ static lv_grad_dsc_t grad; - lv_gradient_init_stops(&grad, grad_colors, NULL, NULL, sizeof(grad_colors) / sizeof(lv_color_t)); + lv_grad_init_stops(&grad, grad_colors, NULL, NULL, sizeof(grad_colors) / sizeof(lv_color_t)); /*Make a conical gradient with the center in the middle of the object*/ #if LV_GRADIENT_MAX_STOPS >= 8 diff --git a/examples/styles/lv_example_style_17.c b/examples/styles/lv_example_style_17.c index d7703d02e..ffecf666c 100644 --- a/examples/styles/lv_example_style_17.c +++ b/examples/styles/lv_example_style_17.c @@ -22,7 +22,7 @@ void lv_example_style_17(void) /*First define a color gradient. In this example we use a purple to black color map.*/ static lv_grad_dsc_t grad; - lv_gradient_init_stops(&grad, grad_colors, NULL, NULL, sizeof(grad_colors) / sizeof(lv_color_t)); + lv_grad_init_stops(&grad, grad_colors, NULL, NULL, sizeof(grad_colors) / sizeof(lv_color_t)); /*Make a radial gradient with the center in the middle of the object, extending to the farthest corner*/ lv_grad_radial_init(&grad, LV_GRAD_CENTER, LV_GRAD_CENTER, LV_GRAD_RIGHT, LV_GRAD_BOTTOM, LV_GRAD_EXTEND_PAD); diff --git a/examples/styles/lv_example_style_18.c b/examples/styles/lv_example_style_18.c index ce98c4cf2..fe6681d9b 100644 --- a/examples/styles/lv_example_style_18.c +++ b/examples/styles/lv_example_style_18.c @@ -18,7 +18,7 @@ void lv_example_style_18(void) static lv_grad_dsc_t linear_gradient_dsc; /*NOTE: the gradient descriptor must be static or global variable!*/ lv_style_init(&style_with_linear_gradient_bg); - lv_gradient_init_stops(&linear_gradient_dsc, grad_colors, NULL, NULL, sizeof(grad_colors) / sizeof(lv_color_t)); + lv_grad_init_stops(&linear_gradient_dsc, grad_colors, NULL, NULL, sizeof(grad_colors) / sizeof(lv_color_t)); lv_grad_linear_init(&linear_gradient_dsc, lv_pct(0), lv_pct(0), lv_pct(20), lv_pct(100), LV_GRAD_EXTEND_REFLECT); lv_style_set_bg_grad(&style_with_linear_gradient_bg, &linear_gradient_dsc); lv_style_set_bg_opa(&style_with_linear_gradient_bg, LV_OPA_COVER); @@ -28,7 +28,7 @@ void lv_example_style_18(void) static lv_grad_dsc_t radial_gradient_dsc; /*NOTE: the gradient descriptor must be static or global variable!*/ lv_style_init(&style_with_radial_gradient_bg); - lv_gradient_init_stops(&radial_gradient_dsc, grad_colors, NULL, NULL, sizeof(grad_colors) / sizeof(lv_color_t)); + lv_grad_init_stops(&radial_gradient_dsc, grad_colors, NULL, NULL, sizeof(grad_colors) / sizeof(lv_color_t)); lv_grad_radial_init(&radial_gradient_dsc, lv_pct(30), lv_pct(30), lv_pct(100), lv_pct(100), LV_GRAD_EXTEND_REFLECT); lv_style_set_bg_grad(&style_with_radial_gradient_bg, &radial_gradient_dsc); lv_style_set_bg_opa(&style_with_radial_gradient_bg, LV_OPA_COVER); diff --git a/lvgl_private.h b/lvgl_private.h index 415d3f6d1..cb8f9ba22 100644 --- a/lvgl_private.h +++ b/lvgl_private.h @@ -41,7 +41,6 @@ extern "C" { #include "src/draw/lv_draw_vector_private.h" #include "src/draw/lv_draw_buf_private.h" #include "src/draw/lv_draw_mask_private.h" -#include "src/draw/sw/lv_draw_sw_gradient_private.h" #include "src/draw/sw/lv_draw_sw_private.h" #include "src/draw/sw/lv_draw_sw_mask_private.h" #include "src/draw/sw/blend/lv_draw_sw_blend_private.h" diff --git a/src/draw/lv_draw_rect.h b/src/draw/lv_draw_rect.h index 6fe3a82e7..a6b61300c 100644 --- a/src/draw/lv_draw_rect.h +++ b/src/draw/lv_draw_rect.h @@ -17,7 +17,6 @@ extern "C" { #include "../misc/lv_color.h" #include "../misc/lv_area.h" #include "../misc/lv_style.h" -#include "sw/lv_draw_sw_gradient.h" /********************* * DEFINES diff --git a/src/draw/lv_draw_vector.c b/src/draw/lv_draw_vector.c index 20d0e2346..3bbca3c6a 100644 --- a/src/draw/lv_draw_vector.c +++ b/src/draw/lv_draw_vector.c @@ -571,7 +571,7 @@ void lv_vector_dsc_set_fill_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gra dsc->current_dsc.fill_dsc.gradient.spread = spread; } -void lv_vector_dsc_set_fill_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_gradient_stop_t * stops, +void lv_vector_dsc_set_fill_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_grad_stop_t * stops, uint16_t count) { if(count > LV_GRADIENT_MAX_STOPS) { @@ -579,7 +579,7 @@ void lv_vector_dsc_set_fill_gradient_color_stops(lv_vector_dsc_t * dsc, const lv count = LV_GRADIENT_MAX_STOPS; } - lv_memcpy(&(dsc->current_dsc.fill_dsc.gradient.stops), stops, sizeof(lv_gradient_stop_t) * count); + lv_memcpy(&(dsc->current_dsc.fill_dsc.gradient.stops), stops, sizeof(lv_grad_stop_t) * count); dsc->current_dsc.fill_dsc.gradient.stops_count = count; } @@ -674,7 +674,7 @@ void lv_vector_dsc_set_stroke_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_g dsc->current_dsc.stroke_dsc.gradient.spread = spread; } -void lv_vector_dsc_set_stroke_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_gradient_stop_t * stops, +void lv_vector_dsc_set_stroke_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_grad_stop_t * stops, uint16_t count) { if(count > LV_GRADIENT_MAX_STOPS) { @@ -682,7 +682,7 @@ void lv_vector_dsc_set_stroke_gradient_color_stops(lv_vector_dsc_t * dsc, const count = LV_GRADIENT_MAX_STOPS; } - lv_memcpy(&(dsc->current_dsc.stroke_dsc.gradient.stops), stops, sizeof(lv_gradient_stop_t) * count); + lv_memcpy(&(dsc->current_dsc.stroke_dsc.gradient.stops), stops, sizeof(lv_grad_stop_t) * count); dsc->current_dsc.stroke_dsc.gradient.stops_count = count; } diff --git a/src/draw/lv_draw_vector.h b/src/draw/lv_draw_vector.h index 5a59e525f..02ba6cb4d 100644 --- a/src/draw/lv_draw_vector.h +++ b/src/draw/lv_draw_vector.h @@ -309,10 +309,10 @@ void lv_vector_dsc_set_fill_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gra /** * Set fill gradient color stops for descriptor * @param dsc pointer to a vector graphic descriptor - * @param stops an array of `lv_gradient_stop_t` variables + * @param stops an array of `lv_grad_stop_t` variables * @param count the number of stops in the array, range: 0..LV_GRADIENT_MAX_STOPS */ -void lv_vector_dsc_set_fill_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_gradient_stop_t * stops, +void lv_vector_dsc_set_fill_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_grad_stop_t * stops, uint16_t count); /** @@ -407,10 +407,10 @@ void lv_vector_dsc_set_stroke_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_g /** * Set stroke color stops for descriptor * @param dsc pointer to a vector graphic descriptor - * @param stops an array of `lv_gradient_stop_t` variables + * @param stops an array of `lv_grad_stop_t` variables * @param count the number of stops in the array */ -void lv_vector_dsc_set_stroke_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_gradient_stop_t * stops, +void lv_vector_dsc_set_stroke_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_grad_stop_t * stops, uint16_t count); /** diff --git a/src/draw/lv_draw_vector_private.h b/src/draw/lv_draw_vector_private.h index 9257736ac..f92b2c6e1 100644 --- a/src/draw/lv_draw_vector_private.h +++ b/src/draw/lv_draw_vector_private.h @@ -34,8 +34,8 @@ struct _lv_vector_path_t { struct _lv_vector_gradient_t { lv_vector_gradient_style_t style; - lv_gradient_stop_t stops[LV_GRADIENT_MAX_STOPS]; /**< A gradient stop array */ - uint16_t stops_count; /**< The number of used stops in the array */ + lv_grad_stop_t stops[LV_GRADIENT_MAX_STOPS]; /**< A gradient stop array */ + uint16_t stops_count; /**< The number of used stops in the array */ float x1; float y1; float x2; diff --git a/src/draw/sw/lv_draw_sw_fill.c b/src/draw/sw/lv_draw_sw_fill.c index ed63d28af..930457f67 100644 --- a/src/draw/sw/lv_draw_sw_fill.c +++ b/src/draw/sw/lv_draw_sw_fill.c @@ -13,7 +13,7 @@ #if LV_USE_DRAW_SW #include "blend/lv_draw_sw_blend_private.h" -#include "lv_draw_sw_gradient_private.h" +#include "lv_draw_sw_grad.h" #include "../../misc/lv_math.h" #include "../../misc/lv_text_ap.h" #include "../../core/lv_refr.h" @@ -104,7 +104,7 @@ void lv_draw_sw_fill(lv_draw_task_t * t, lv_draw_fill_dsc_t * dsc, const lv_area blend_dsc.opa = LV_OPA_COVER; /*Get gradient if appropriate*/ - lv_grad_t * grad = lv_gradient_get(&dsc->grad, coords_bg_w, coords_bg_h); + lv_draw_sw_grad_calc_t * grad = lv_draw_sw_grad_get(&dsc->grad, coords_bg_w, coords_bg_h); lv_opa_t * grad_opa_map = NULL; bool transp = false; if(grad && grad_dir >= LV_GRAD_DIR_HOR) { @@ -130,13 +130,13 @@ void lv_draw_sw_fill(lv_draw_task_t * t, lv_draw_fill_dsc_t * dsc, const lv_area LV_ASSERT_NULL(grad); switch(grad_dir) { case LV_GRAD_DIR_LINEAR: - lv_gradient_linear_setup(&dsc->grad, coords); + lv_draw_sw_grad_linear_setup(&dsc->grad, coords); break; case LV_GRAD_DIR_RADIAL: - lv_gradient_radial_setup(&dsc->grad, coords); + lv_draw_sw_grad_radial_setup(&dsc->grad, coords); break; case LV_GRAD_DIR_CONICAL: - lv_gradient_conical_setup(&dsc->grad, coords); + lv_draw_sw_grad_conical_setup(&dsc->grad, coords); break; default: LV_LOG_WARN("Gradient type is not supported"); @@ -180,15 +180,15 @@ void lv_draw_sw_fill(lv_draw_task_t * t, lv_draw_fill_dsc_t * dsc, const lv_area break; #if LV_USE_DRAW_SW_COMPLEX_GRADIENTS case LV_GRAD_DIR_LINEAR: - lv_gradient_linear_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, top_y - bg_coords.y1, coords_bg_w, grad); + lv_draw_sw_grad_linear_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, top_y - bg_coords.y1, coords_bg_w, grad); preblend = true; break; case LV_GRAD_DIR_RADIAL: - lv_gradient_radial_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, top_y - bg_coords.y1, coords_bg_w, grad); + lv_draw_sw_grad_radial_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, top_y - bg_coords.y1, coords_bg_w, grad); preblend = true; break; case LV_GRAD_DIR_CONICAL: - lv_gradient_conical_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, top_y - bg_coords.y1, coords_bg_w, grad); + lv_draw_sw_grad_conical_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, top_y - bg_coords.y1, coords_bg_w, grad); preblend = true; break; #endif @@ -221,15 +221,18 @@ void lv_draw_sw_fill(lv_draw_task_t * t, lv_draw_fill_dsc_t * dsc, const lv_area break; #if LV_USE_DRAW_SW_COMPLEX_GRADIENTS case LV_GRAD_DIR_LINEAR: - lv_gradient_linear_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, bottom_y - bg_coords.y1, coords_bg_w, grad); + lv_draw_sw_grad_linear_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, bottom_y - bg_coords.y1, coords_bg_w, + grad); preblend = true; break; case LV_GRAD_DIR_RADIAL: - lv_gradient_radial_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, bottom_y - bg_coords.y1, coords_bg_w, grad); + lv_draw_sw_grad_radial_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, bottom_y - bg_coords.y1, coords_bg_w, + grad); preblend = true; break; case LV_GRAD_DIR_CONICAL: - lv_gradient_conical_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, bottom_y - bg_coords.y1, coords_bg_w, grad); + lv_draw_sw_grad_conical_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, bottom_y - bg_coords.y1, coords_bg_w, + grad); preblend = true; break; #endif @@ -300,13 +303,13 @@ void lv_draw_sw_fill(lv_draw_task_t * t, lv_draw_fill_dsc_t * dsc, const lv_area break; #if LV_USE_DRAW_SW_COMPLEX_GRADIENTS case LV_GRAD_DIR_LINEAR: - lv_gradient_linear_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, h - bg_coords.y1, coords_bg_w, grad); + lv_draw_sw_grad_linear_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, h - bg_coords.y1, coords_bg_w, grad); break; case LV_GRAD_DIR_RADIAL: - lv_gradient_radial_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, h - bg_coords.y1, coords_bg_w, grad); + lv_draw_sw_grad_radial_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, h - bg_coords.y1, coords_bg_w, grad); break; case LV_GRAD_DIR_CONICAL: - lv_gradient_conical_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, h - bg_coords.y1, coords_bg_w, grad); + lv_draw_sw_grad_conical_get_line(&dsc->grad, clipped_coords.x1 - bg_coords.x1, h - bg_coords.y1, coords_bg_w, grad); break; #endif default: @@ -321,19 +324,19 @@ void lv_draw_sw_fill(lv_draw_task_t * t, lv_draw_fill_dsc_t * dsc, const lv_area lv_draw_sw_mask_free_param(&mask_rout_param); } if(grad) { - lv_gradient_cleanup(grad); + lv_draw_sw_grad_cleanup(grad); } #if LV_USE_DRAW_SW_COMPLEX_GRADIENTS if(grad_dir >= LV_GRAD_DIR_LINEAR) { switch(grad_dir) { case LV_GRAD_DIR_LINEAR: - lv_gradient_linear_cleanup(&dsc->grad); + lv_draw_sw_grad_linear_cleanup(&dsc->grad); break; case LV_GRAD_DIR_RADIAL: - lv_gradient_radial_cleanup(&dsc->grad); + lv_draw_sw_grad_radial_cleanup(&dsc->grad); break; case LV_GRAD_DIR_CONICAL: - lv_gradient_conical_cleanup(&dsc->grad); + lv_draw_sw_grad_conical_cleanup(&dsc->grad); break; default: break; diff --git a/src/draw/sw/lv_draw_sw_gradient.c b/src/draw/sw/lv_draw_sw_grad.c similarity index 78% rename from src/draw/sw/lv_draw_sw_gradient.c rename to src/draw/sw/lv_draw_sw_grad.c index d00a1ea2a..4550a6c95 100644 --- a/src/draw/sw/lv_draw_sw_gradient.c +++ b/src/draw/sw/lv_draw_sw_grad.c @@ -1,12 +1,12 @@ /** - * @file lv_draw_sw_gradient.c + * @file lv_draw_sw_grad.c * */ /********************* * INCLUDES *********************/ -#include "lv_draw_sw_gradient_private.h" +#include "lv_draw_sw_grad.h" #if LV_USE_DRAW_SW #include "../../misc/lv_types.h" @@ -46,7 +46,7 @@ typedef struct { int32_t bpy; int32_t bc; lv_area_t clip_area; - lv_grad_t * cgrad; /*256 element cache buffer containing the gradient color map*/ + lv_draw_sw_grad_calc_t * cgrad; /*256 element cache buffer containing the gradient color map*/ } lv_grad_radial_state_t; typedef struct { @@ -54,7 +54,7 @@ typedef struct { int32_t a; int32_t b; int32_t c; - lv_grad_t * cgrad; /*256 element cache buffer containing the gradient color map*/ + lv_draw_sw_grad_calc_t * cgrad; /*256 element cache buffer containing the gradient color map*/ } lv_grad_linear_state_t; typedef struct { @@ -64,7 +64,7 @@ typedef struct { int32_t a; int32_t da; int32_t inv_da; - lv_grad_t * cgrad; /*256 element cache buffer containing the gradient color map*/ + lv_draw_sw_grad_calc_t * cgrad; /*256 element cache buffer containing the gradient color map*/ } lv_grad_conical_state_t; #endif @@ -72,8 +72,8 @@ typedef struct { /********************** * STATIC PROTOTYPES **********************/ -typedef lv_result_t (*op_cache_t)(lv_grad_t * c, void * ctx); -static lv_grad_t * allocate_item(const lv_grad_dsc_t * g, int32_t w, int32_t h); +typedef lv_result_t (*op_cache_t)(lv_draw_sw_grad_calc_t * c, void * ctx); +static lv_draw_sw_grad_calc_t * allocate_item(const lv_grad_dsc_t * g, int32_t w, int32_t h); #if LV_USE_DRAW_SW_COMPLEX_GRADIENTS @@ -89,7 +89,7 @@ static lv_grad_t * allocate_item(const lv_grad_dsc_t * g, int32_t w, int32_t h); * STATIC FUNCTIONS **********************/ -static lv_grad_t * allocate_item(const lv_grad_dsc_t * g, int32_t w, int32_t h) +static lv_draw_sw_grad_calc_t * allocate_item(const lv_grad_dsc_t * g, int32_t w, int32_t h) { int32_t size; switch(g->dir) { @@ -106,8 +106,9 @@ static lv_grad_t * allocate_item(const lv_grad_dsc_t * g, int32_t w, int32_t h) size = 64; } - size_t req_size = ALIGN(sizeof(lv_grad_t)) + ALIGN(size * sizeof(lv_color_t)) + ALIGN(size * sizeof(lv_opa_t)); - lv_grad_t * item = lv_malloc(req_size); + size_t req_size = ALIGN(sizeof(lv_draw_sw_grad_calc_t)) + ALIGN(size * sizeof(lv_color_t)) + ALIGN(size * sizeof( + lv_opa_t)); + lv_draw_sw_grad_calc_t * item = lv_malloc(req_size); LV_ASSERT_MALLOC(item); if(item == NULL) return NULL; @@ -141,13 +142,13 @@ static inline int32_t extend_w(int32_t w, lv_grad_extend_t extend) * FUNCTIONS **********************/ -lv_grad_t * lv_gradient_get(const lv_grad_dsc_t * g, int32_t w, int32_t h) +lv_draw_sw_grad_calc_t * lv_draw_sw_grad_get(const lv_grad_dsc_t * g, int32_t w, int32_t h) { /* No gradient, no cache */ if(g->dir == LV_GRAD_DIR_NONE) return NULL; /* Step 1: Search cache for the given key */ - lv_grad_t * item = allocate_item(g, w, h); + lv_draw_sw_grad_calc_t * item = allocate_item(g, w, h); if(item == NULL) { LV_LOG_WARN("Failed to allocate item for the gradient"); return item; @@ -156,15 +157,15 @@ lv_grad_t * lv_gradient_get(const lv_grad_dsc_t * g, int32_t w, int32_t h) /* Step 3: Fill it with the gradient, as expected */ uint32_t i; for(i = 0; i < item->size; i++) { - lv_gradient_color_calculate(g, item->size, i, &item->color_map[i], &item->opa_map[i]); + lv_draw_sw_grad_color_calculate(g, item->size, i, &item->color_map[i], &item->opa_map[i]); } return item; } -void LV_ATTRIBUTE_FAST_MEM lv_gradient_color_calculate(const lv_grad_dsc_t * dsc, int32_t range, - int32_t frac, lv_grad_color_t * color_out, lv_opa_t * opa_out) +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_grad_color_calculate(const lv_grad_dsc_t * dsc, int32_t range, + int32_t frac, lv_color_t * color_out, lv_opa_t * opa_out) { - lv_grad_color_t tmp; + lv_color_t tmp; /*Clip out-of-bounds first*/ int32_t min = (dsc->stops[0].frac * range) >> 8; if(frac <= min) { @@ -214,22 +215,11 @@ void LV_ATTRIBUTE_FAST_MEM lv_gradient_color_calculate(const lv_grad_dsc_t * dsc *opa_out = LV_UDIV255(dsc->stops[found_i].opa * mix + dsc->stops[found_i - 1].opa * imix); } -void lv_gradient_cleanup(lv_grad_t * grad) +void lv_draw_sw_grad_cleanup(lv_draw_sw_grad_calc_t * grad) { lv_free(grad); } -void lv_gradient_init_stops(lv_grad_dsc_t * grad, const lv_color_t colors[], const lv_opa_t opa[], - const uint8_t fracs[], int num_stops) -{ - LV_ASSERT(num_stops <= LV_GRADIENT_MAX_STOPS); - grad->stops_count = num_stops; - for(int i = 0; i < num_stops; i++) { - grad->stops[i].color = colors[i]; - grad->stops[i].opa = opa != NULL ? opa[i] : LV_OPA_COVER; - grad->stops[i].frac = fracs != NULL ? fracs[i] : 255 * i / (num_stops - 1); - } -} #if LV_USE_DRAW_SW_COMPLEX_GRADIENTS @@ -277,7 +267,7 @@ void lv_gradient_init_stops(lv_grad_dsc_t * grad, const lv_color_t colors[], con */ -void lv_gradient_radial_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) +void lv_draw_sw_grad_radial_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) { lv_point_t start = dsc->params.radial.focal; lv_point_t end = dsc->params.radial.end; @@ -305,7 +295,7 @@ void lv_gradient_radial_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) LV_ASSERT(r_end != 0); /* Create gradient color map */ - state->cgrad = lv_gradient_get(dsc, 256, 0); + state->cgrad = lv_draw_sw_grad_get(dsc, 256, 0); state->x0 = start.x; state->y0 = start.y; @@ -347,23 +337,23 @@ void lv_gradient_radial_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) } } -void lv_gradient_radial_cleanup(lv_grad_dsc_t * dsc) +void lv_draw_sw_grad_radial_cleanup(lv_grad_dsc_t * dsc) { lv_grad_radial_state_t * state = dsc->state; if(state == NULL) return; if(state->cgrad) - lv_gradient_cleanup(state->cgrad); + lv_draw_sw_grad_cleanup(state->cgrad); lv_free(state); } -void LV_ATTRIBUTE_FAST_MEM lv_gradient_radial_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, - int32_t width, lv_grad_t * result) +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_grad_radial_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, + int32_t width, lv_draw_sw_grad_calc_t * result) { lv_grad_radial_state_t * state = (lv_grad_radial_state_t *)dsc->state; lv_color_t * buf = result->color_map; lv_opa_t * opa = result->opa_map; - lv_grad_t * grad = state->cgrad; + lv_draw_sw_grad_calc_t * grad = state->cgrad; int32_t w; /* the result: this is an offset into the 256 element gradient color table */ int32_t b, db, c, dc; @@ -466,7 +456,7 @@ void LV_ATTRIBUTE_FAST_MEM lv_gradient_radial_get_line(lv_grad_dsc_t * dsc, int3 */ -void lv_gradient_linear_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) +void lv_draw_sw_grad_linear_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) { lv_point_t start = dsc->params.linear.start; lv_point_t end = dsc->params.linear.end; @@ -474,7 +464,7 @@ void lv_gradient_linear_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) dsc->state = state; /* Create gradient color map */ - state->cgrad = lv_gradient_get(dsc, 256, 0); + state->cgrad = lv_draw_sw_grad_get(dsc, 256, 0); /* Convert from percentage coordinates */ int32_t wdt = lv_area_get_width(coords); @@ -490,12 +480,13 @@ void lv_gradient_linear_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) int32_t dy = end.y - start.y; int32_t l2 = lv_sqr(dx) + lv_sqr(dy); + if(l2 == 0) l2 = 1; state->a = (dx << 16) / l2; state->b = (dy << 16) / l2; state->c = ((start.x * dx + start.y * dy) << 16) / l2; } -void lv_gradient_linear_cleanup(lv_grad_dsc_t * dsc) +void lv_draw_sw_grad_linear_cleanup(lv_grad_dsc_t * dsc) { lv_grad_linear_state_t * state = dsc->state; if(state == NULL) @@ -505,13 +496,13 @@ void lv_gradient_linear_cleanup(lv_grad_dsc_t * dsc) lv_free(state); } -void LV_ATTRIBUTE_FAST_MEM lv_gradient_linear_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, - int32_t width, lv_grad_t * result) +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_grad_linear_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, + int32_t width, lv_draw_sw_grad_calc_t * result) { lv_grad_linear_state_t * state = (lv_grad_linear_state_t *)dsc->state; lv_color_t * buf = result->color_map; lv_opa_t * opa = result->opa_map; - lv_grad_t * grad = state->cgrad; + lv_draw_sw_grad_calc_t * grad = state->cgrad; int32_t w; /* the result: this is an offset into the 256 element gradient color table */ int32_t x, d; @@ -539,7 +530,7 @@ void LV_ATTRIBUTE_FAST_MEM lv_gradient_linear_get_line(lv_grad_dsc_t * dsc, int3 w is the unknown variable */ -void lv_gradient_conical_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) +void lv_draw_sw_grad_conical_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) { lv_point_t c0 = dsc->params.conical.center; int32_t alpha = dsc->params.conical.start_angle % 360; @@ -548,7 +539,7 @@ void lv_gradient_conical_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) dsc->state = state; /* Create gradient color map */ - state->cgrad = lv_gradient_get(dsc, 256, 0); + state->cgrad = lv_draw_sw_grad_get(dsc, 256, 0); /* Convert from percentage coordinates */ int32_t wdt = lv_area_get_width(coords); @@ -567,7 +558,7 @@ void lv_gradient_conical_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords) state->inv_da = (1 << 16) / (beta - alpha); } -void lv_gradient_conical_cleanup(lv_grad_dsc_t * dsc) +void lv_draw_sw_grad_conical_cleanup(lv_grad_dsc_t * dsc) { lv_grad_conical_state_t * state = dsc->state; if(state == NULL) @@ -577,13 +568,13 @@ void lv_gradient_conical_cleanup(lv_grad_dsc_t * dsc) lv_free(state); } -void LV_ATTRIBUTE_FAST_MEM lv_gradient_conical_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, - int32_t width, lv_grad_t * result) +void LV_ATTRIBUTE_FAST_MEM lv_draw_sw_grad_conical_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, + int32_t width, lv_draw_sw_grad_calc_t * result) { lv_grad_conical_state_t * state = (lv_grad_conical_state_t *)dsc->state; lv_color_t * buf = result->color_map; lv_opa_t * opa = result->opa_map; - lv_grad_t * grad = state->cgrad; + lv_draw_sw_grad_calc_t * grad = state->cgrad; int32_t w; /* the result: this is an offset into the 256 element gradient color table */ int32_t dx = xp - state->x0; @@ -618,51 +609,6 @@ void LV_ATTRIBUTE_FAST_MEM lv_gradient_conical_get_line(lv_grad_dsc_t * dsc, int } } -void lv_grad_linear_init(lv_grad_dsc_t * dsc, int32_t from_x, int32_t from_y, int32_t to_x, int32_t to_y, - lv_grad_extend_t extend) -{ - dsc->dir = LV_GRAD_DIR_LINEAR; - dsc->params.linear.start.x = from_x; - dsc->params.linear.start.y = from_y; - dsc->params.linear.end.x = to_x; - dsc->params.linear.end.y = to_y; - dsc->extend = extend; -} - -void lv_grad_radial_init(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t to_x, int32_t to_y, - lv_grad_extend_t extend) -{ - dsc->dir = LV_GRAD_DIR_RADIAL; - dsc->params.radial.focal.x = center_x; - dsc->params.radial.focal.y = center_y; - dsc->params.radial.focal_extent.x = center_x; - dsc->params.radial.focal_extent.y = center_y; - dsc->params.radial.end.x = center_x; - dsc->params.radial.end.y = center_y; - dsc->params.radial.end_extent.x = to_x; - dsc->params.radial.end_extent.y = to_y; - dsc->extend = extend; -} - -void lv_grad_conical_init(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t start_angle, - int32_t end_angle, lv_grad_extend_t extend) -{ - dsc->dir = LV_GRAD_DIR_CONICAL; - dsc->params.conical.center.x = center_x; - dsc->params.conical.center.y = center_y; - dsc->params.conical.start_angle = start_angle; - dsc->params.conical.end_angle = end_angle; - dsc->extend = extend; -} - -void lv_grad_radial_set_focal(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t radius) -{ - dsc->params.radial.focal.x = center_x; - dsc->params.radial.focal.y = center_y; - dsc->params.radial.focal_extent.x = center_x + radius; - dsc->params.radial.focal_extent.y = center_y; -} - #endif /* LV_USE_DRAW_SW_COMPLEX_GRADIENTS */ #endif /*LV_USE_DRAW_SW*/ diff --git a/src/draw/sw/lv_draw_sw_grad.h b/src/draw/sw/lv_draw_sw_grad.h new file mode 100644 index 000000000..42b36c211 --- /dev/null +++ b/src/draw/sw/lv_draw_sw_grad.h @@ -0,0 +1,147 @@ +/** + * @file lv_draw_sw_grad.h + * + */ + +#ifndef LV_DRAW_SW_GRAD_H +#define LV_DRAW_SW_GRAD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../../misc/lv_color.h" +#include "../../misc/lv_style.h" + +#if LV_USE_DRAW_SW + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +typedef struct { + lv_color_t * color_map; + lv_opa_t * opa_map; + uint32_t size; +} lv_draw_sw_grad_calc_t; + + +/********************** + * PROTOTYPES + **********************/ + +/** Compute the color in the given gradient and fraction + * Gradient are specified in a virtual [0-255] range, so this function scales the virtual range to the given range + * @param dsc The gradient descriptor to use + * @param range The range to use in computation. + * @param frac The current part used in the range. frac is in [0; range] + * @param color_out Calculated gradient color + * @param opa_out Calculated opacity + */ + +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_grad_color_calculate(const lv_grad_dsc_t * dsc, int32_t range, + int32_t frac, lv_color_t * color_out, lv_opa_t * opa_out); + +/** Get a gradient cache from the given parameters */ +lv_draw_sw_grad_calc_t * lv_draw_sw_grad_get(const lv_grad_dsc_t * gradient, int32_t w, int32_t h); + +/** + * Clean up the gradient item after it was get with `lv_grad_get_from_cache`. + * @param grad pointer to a gradient + */ +void lv_draw_sw_grad_cleanup(lv_draw_sw_grad_calc_t * grad); + +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + + +/** + * Calculate constants from the given parameters that are used during rendering + * @param dsc gradient descriptor + * @param coords the area where to draw the gradient + */ +void lv_draw_sw_grad_linear_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords); + +/** + * Free up the allocated memory for the gradient calculation + * @param dsc gradient descriptor + */ +void lv_draw_sw_grad_linear_cleanup(lv_grad_dsc_t * dsc); + +/** + * Calculate a line segment of a linear gradient + * @param dsc gradient descriptor + * @param xp starting point x coordinate in gradient space + * @param yp starting point y coordinate in gradient space + * @param width width of the line segment in pixels + * @param result color buffer for the resulting line segment + */ +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_grad_linear_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, + int32_t width, + lv_draw_sw_grad_calc_t * result); + +/** + * Calculate constants from the given parameters that are used during rendering + * @param dsc gradient descriptor + * @param coords the area where to draw the gradient + */ +void lv_draw_sw_grad_radial_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords); + +/** + * Free up the allocated memory for the gradient calculation + * @param dsc gradient descriptor + */ +void lv_draw_sw_grad_radial_cleanup(lv_grad_dsc_t * dsc); + +/** + * Calculate a line segment of a radial gradient + * @param dsc gradient descriptor + * @param xp starting point x coordinate in gradient space + * @param yp starting point y coordinate in gradient space + * @param width width of the line segment in pixels + * @param result color buffer for the resulting line segment + */ +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_grad_radial_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, + int32_t width, + lv_draw_sw_grad_calc_t * result); + +/** + * Calculate constants from the given parameters that are used during rendering + * @param dsc gradient descriptor + * @param coords the area where to draw the gradient + */ +void lv_draw_sw_grad_conical_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords); + +/** + * Free up the allocated memory for the gradient calculation + * @param dsc gradient descriptor + */ +void lv_draw_sw_grad_conical_cleanup(lv_grad_dsc_t * dsc); + +/** + * Calculate a line segment of a conical gradient + * @param dsc gradient descriptor + * @param xp starting point x coordinate in gradient space + * @param yp starting point y coordinate in gradient space + * @param width width of the line segment in pixels + * @param result color buffer for the resulting line segment + */ +void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_sw_grad_conical_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, + int32_t width, + lv_draw_sw_grad_calc_t * result); + +#endif /*LV_USE_DRAW_SW_COMPLEX_GRADIENTS*/ + +#endif /*LV_USE_DRAW_SW*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_DRAW_GRADIENT_H*/ diff --git a/src/draw/sw/lv_draw_sw_gradient.h b/src/draw/sw/lv_draw_sw_gradient.h deleted file mode 100644 index e68301bd5..000000000 --- a/src/draw/sw/lv_draw_sw_gradient.h +++ /dev/null @@ -1,203 +0,0 @@ -/** - * @file lv_draw_sw_gradient.h - * - */ - -#ifndef LV_DRAW_SW_GRADIENT_H -#define LV_DRAW_SW_GRADIENT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ -#include "../../misc/lv_color.h" -#include "../../misc/lv_style.h" - -#if LV_USE_DRAW_SW - -/********************* - * DEFINES - *********************/ -#if LV_GRADIENT_MAX_STOPS < 2 -#error LVGL needs at least 2 stops for gradients. Please increase the LV_GRADIENT_MAX_STOPS -#endif - -#define LV_GRAD_LEFT LV_PCT(0) -#define LV_GRAD_RIGHT LV_PCT(100) -#define LV_GRAD_TOP LV_PCT(0) -#define LV_GRAD_BOTTOM LV_PCT(100) -#define LV_GRAD_CENTER LV_PCT(50) - -/********************** - * TYPEDEFS - **********************/ -typedef lv_color_t lv_grad_color_t; - -/********************** - * PROTOTYPES - **********************/ -/** Compute the color in the given gradient and fraction - * Gradient are specified in a virtual [0-255] range, so this function scales the virtual range to the given range - * @param dsc The gradient descriptor to use - * @param range The range to use in computation. - * @param frac The current part used in the range. frac is in [0; range] - * @param color_out Calculated gradient color - * @param opa_out Calculated opacity - */ - -void /* LV_ATTRIBUTE_FAST_MEM */ lv_gradient_color_calculate(const lv_grad_dsc_t * dsc, int32_t range, - int32_t frac, lv_grad_color_t * color_out, lv_opa_t * opa_out); - -/** Get a gradient cache from the given parameters */ -lv_grad_t * lv_gradient_get(const lv_grad_dsc_t * gradient, int32_t w, int32_t h); - -/** - * Clean up the gradient item after it was get with `lv_grad_get_from_cache`. - * @param grad pointer to a gradient - */ -void lv_gradient_cleanup(lv_grad_t * grad); - -/** - * Initialize gradient color map from a table - * @param grad pointer to a gradient descriptor - * @param colors color array - * @param fracs position array (0..255): if NULL, then colors are distributed evenly - * @param opa opacity array: if NULL, then LV_OPA_COVER is assumed - * @param num_stops number of gradient stops (1..LV_GRADIENT_MAX_STOPS) - */ -void lv_gradient_init_stops(lv_grad_dsc_t * grad, const lv_color_t colors[], const lv_opa_t opa[], - const uint8_t fracs[], int num_stops); - -#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS - -/** - * Helper function to initialize linear gradient - * @param dsc gradient descriptor - * @param from_x start x position: can be a coordinate or an lv_pct() value - * predefined constants LV_GRAD_LEFT, LV_GRAD_RIGHT, LV_GRAD_TOP, LV_GRAD_BOTTOM, LV_GRAD_CENTER can be used as well - * @param from_y start y position - * @param to_x end x position - * @param to_y end y position - * @param extend one of LV_GRAD_EXTEND_PAD, LV_GRAD_EXTEND_REPEAT or LV_GRAD_EXTEND_REFLECT - */ -void lv_grad_linear_init(lv_grad_dsc_t * dsc, int32_t from_x, int32_t from_y, int32_t to_x, int32_t to_y, - lv_grad_extend_t extend); - -/** - * Helper function to initialize radial gradient - * @param dsc gradient descriptor - * @param center_x center x position: can be a coordinate or an lv_pct() value - * predefined constants LV_GRAD_LEFT, LV_GRAD_RIGHT, LV_GRAD_TOP, LV_GRAD_BOTTOM, LV_GRAD_CENTER can be used as well - * @param center_y center y position - * @param to_x point on the end circle x position - * @param to_y point on the end circle y position - * @param extend one of LV_GRAD_EXTEND_PAD, LV_GRAD_EXTEND_REPEAT or LV_GRAD_EXTEND_REFLECT - */ -void lv_grad_radial_init(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t to_x, int32_t to_y, - lv_grad_extend_t extend); - -/** - * Set focal (starting) circle of a radial gradient - * @param dsc gradient descriptor - * @param center_x center x position: can be a coordinate or an lv_pct() value - * predefined constants LV_GRAD_LEFT, LV_GRAD_RIGHT, LV_GRAD_TOP, LV_GRAD_BOTTOM, LV_GRAD_CENTER can be used as well - * @param center_y center y position - * @param radius radius of the starting circle (NOTE: this must be a scalar number, not percentage) - */ -void lv_grad_radial_set_focal(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t radius); - -/** - * Helper function to initialize conical gradient - * @param dsc gradient descriptor - * @param center_x center x position: can be a coordinate or an lv_pct() value - * predefined constants LV_GRAD_LEFT, LV_GRAD_RIGHT, LV_GRAD_TOP, LV_GRAD_BOTTOM, LV_GRAD_CENTER can be used as well - * @param center_y center y position - * @param start_angle start angle in degrees - * @param end_angle end angle in degrees - * @param extend one of LV_GRAD_EXTEND_PAD, LV_GRAD_EXTEND_REPEAT or LV_GRAD_EXTEND_REFLECT - */ -void lv_grad_conical_init(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t start_angle, - int32_t end_angle, lv_grad_extend_t extend); - -/** - * Calculate constants from the given parameters that are used during rendering - * @param dsc gradient descriptor - */ -void lv_gradient_linear_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords); - -/** - * Free up the allocated memory for the gradient calculation - * @param dsc gradient descriptor - */ -void lv_gradient_linear_cleanup(lv_grad_dsc_t * dsc); - -/** - * Calculate a line segment of a linear gradient - * @param dsc gradient descriptor - * @param xp starting point x coordinate in gradient space - * @param yp starting point y coordinate in gradient space - * @param width width of the line segment in pixels - * @param result color buffer for the resulting line segment - */ -void /* LV_ATTRIBUTE_FAST_MEM */ lv_gradient_linear_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, int32_t width, - lv_grad_t * result); - -/** - * Calculate constants from the given parameters that are used during rendering - * @param dsc gradient descriptor - */ -void lv_gradient_radial_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords); - -/** - * Free up the allocated memory for the gradient calculation - * @param dsc gradient descriptor - */ -void lv_gradient_radial_cleanup(lv_grad_dsc_t * dsc); - -/** - * Calculate a line segment of a radial gradient - * @param dsc gradient descriptor - * @param xp starting point x coordinate in gradient space - * @param yp starting point y coordinate in gradient space - * @param width width of the line segment in pixels - * @param result color buffer for the resulting line segment - */ -void /* LV_ATTRIBUTE_FAST_MEM */ lv_gradient_radial_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, int32_t width, - lv_grad_t * result); - -/** - * Calculate constants from the given parameters that are used during rendering - * @param dsc gradient descriptor - */ -void lv_gradient_conical_setup(lv_grad_dsc_t * dsc, const lv_area_t * coords); - -/** - * Free up the allocated memory for the gradient calculation - * @param dsc gradient descriptor - */ -void lv_gradient_conical_cleanup(lv_grad_dsc_t * dsc); - -/** - * Calculate a line segment of a conical gradient - * @param dsc gradient descriptor - * @param xp starting point x coordinate in gradient space - * @param yp starting point y coordinate in gradient space - * @param width width of the line segment in pixels - * @param result color buffer for the resulting line segment - */ -void /* LV_ATTRIBUTE_FAST_MEM */ lv_gradient_conical_get_line(lv_grad_dsc_t * dsc, int32_t xp, int32_t yp, - int32_t width, - lv_grad_t * result); - -#endif /*LV_USE_DRAW_SW_COMPLEX_GRADIENTS*/ - -#endif /*LV_USE_DRAW_SW*/ - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*LV_DRAW_GRADIENT_H*/ diff --git a/src/draw/sw/lv_draw_sw_triangle.c b/src/draw/sw/lv_draw_sw_triangle.c index 9e868a57b..f935e19c3 100644 --- a/src/draw/sw/lv_draw_sw_triangle.c +++ b/src/draw/sw/lv_draw_sw_triangle.c @@ -18,7 +18,7 @@ #include "../../misc/lv_color.h" #include "../../stdlib/lv_string.h" #include "../lv_draw_triangle_private.h" -#include "lv_draw_sw_gradient_private.h" +#include "lv_draw_sw_grad.h" /********************* * DEFINES @@ -136,7 +136,8 @@ void lv_draw_sw_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * dsc) lv_grad_dir_t grad_dir = dsc->bg_grad.dir; - lv_grad_t * grad = lv_gradient_get(&dsc->bg_grad, lv_area_get_width(&tri_area), lv_area_get_height(&tri_area)); + lv_draw_sw_grad_calc_t * grad = lv_draw_sw_grad_get(&dsc->bg_grad, lv_area_get_width(&tri_area), + lv_area_get_height(&tri_area)); lv_opa_t * grad_opa_map = NULL; if(grad && grad_dir == LV_GRAD_DIR_HOR) { blend_dsc.src_area = &blend_area; @@ -184,7 +185,7 @@ void lv_draw_sw_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * dsc) lv_draw_sw_mask_free_param(&mask_right); if(grad) { - lv_gradient_cleanup(grad); + lv_draw_sw_grad_cleanup(grad); } #else diff --git a/src/draw/sw/lv_draw_sw_vector.c b/src/draw/sw/lv_draw_sw_vector.c index 23dd4632b..3825530d0 100644 --- a/src/draw/sw/lv_draw_sw_vector.c +++ b/src/draw/sw/lv_draw_sw_vector.c @@ -186,7 +186,7 @@ static void _setup_gradient(Tvg_Gradient * gradient, const lv_vector_gradient_t Tvg_Color_Stop * stops = (Tvg_Color_Stop *)lv_malloc(sizeof(Tvg_Color_Stop) * grad->stops_count); LV_ASSERT_MALLOC(stops); for(uint16_t i = 0; i < grad->stops_count; i++) { - const lv_gradient_stop_t * s = &(grad->stops[i]); + const lv_grad_stop_t * s = &(grad->stops[i]); stops[i].offset = s->frac / 255.0f; stops[i].r = s->color.red; diff --git a/src/draw/vg_lite/lv_vg_lite_grad.c b/src/draw/vg_lite/lv_vg_lite_grad.c index 83f039357..e652f4387 100644 --- a/src/draw/vg_lite/lv_vg_lite_grad.c +++ b/src/draw/vg_lite/lv_vg_lite_grad.c @@ -271,7 +271,7 @@ bool lv_vg_lite_draw_grad_helper( grad.style = LV_VECTOR_GRADIENT_STYLE_LINEAR; grad.stops_count = grad_dsc->stops_count; - lv_memcpy(grad.stops, grad_dsc->stops, sizeof(lv_gradient_stop_t) * grad_dsc->stops_count); + lv_memcpy(grad.stops, grad_dsc->stops, sizeof(lv_grad_stop_t) * grad_dsc->stops_count); /*convert to spread mode*/ #if LV_USE_DRAW_SW_COMPLEX_GRADIENTS @@ -725,7 +725,7 @@ static lv_cache_compare_res_t grad_compare_cb(const grad_item_t * lhs, const gra } int cmp_res = lv_memcmp(lhs->lv.stops, rhs->lv.stops, - sizeof(lv_gradient_stop_t) * lhs->lv.stops_count); + sizeof(lv_grad_stop_t) * lhs->lv.stops_count); if(cmp_res != 0) { return cmp_res > 0 ? 1 : -1; } diff --git a/src/lv_api_map_v9_1.h b/src/lv_api_map_v9_1.h index a573d3767..7cceafad9 100644 --- a/src/lv_api_map_v9_1.h +++ b/src/lv_api_map_v9_1.h @@ -104,10 +104,13 @@ extern "C" { #define LV_LABEL_LONG_SCROLL_CIRCULAR LV_LABEL_LONG_MODE_SCROLL_CIRCULAR #define LV_LABEL_LONG_CLIP LV_LABEL_LONG_MODE_CLIP -#define lv_anim_set_playback_delay lv_anim_set_reverse_delay -#define lv_anim_set_playback_duration lv_anim_set_reverse_duration -#define lv_anim_set_time lv_anim_set_duration -#define lv_anim_set_playback_time lv_anim_set_reverse_duration +#define lv_anim_set_time lv_anim_set_duration +#define lv_anim_set_playback_time lv_anim_set_reverse_duration +#define lv_anim_set_playback_delay lv_anim_set_reverse_delay +#define lv_anim_set_playback_duration lv_anim_set_reverse_duration + +#define lv_gradient_init_stops lv_grad_init_stops +#define lv_gradient_stop_t lv_grad_stop_t #define lv_spangroup_new_span lv_spangroup_add_span #define lv_spangroup_refr_mode lv_spangroup_refresh diff --git a/src/misc/lv_grad.c b/src/misc/lv_grad.c new file mode 100644 index 000000000..f3a73613d --- /dev/null +++ b/src/misc/lv_grad.c @@ -0,0 +1,120 @@ +/** + * @file lv_grad.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_grad.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ +void lv_grad_init_stops(lv_grad_dsc_t * dsc, const lv_color_t colors[], const lv_opa_t opa[], + const uint8_t fracs[], int num_stops) +{ + LV_ASSERT(num_stops <= LV_GRADIENT_MAX_STOPS); + LV_ASSERT(num_stops > 1); + LV_ASSERT_NULL(dsc); + LV_ASSERT_NULL(colors); + + dsc->stops_count = num_stops; + for(int i = 0; i < num_stops; i++) { + dsc->stops[i].color = colors[i]; + dsc->stops[i].opa = opa != NULL ? opa[i] : LV_OPA_COVER; + dsc->stops[i].frac = fracs != NULL ? fracs[i] : 255 * i / (num_stops - 1); + } +} + +void lv_grad_horizontal_init(lv_grad_dsc_t * dsc) +{ + LV_ASSERT_NULL(dsc); + + dsc->dir = LV_GRAD_DIR_HOR; +} + +void lv_grad_vertical_init(lv_grad_dsc_t * dsc) +{ + LV_ASSERT_NULL(dsc); + + dsc->dir = LV_GRAD_DIR_VER; +} + + +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + +void lv_grad_linear_init(lv_grad_dsc_t * dsc, int32_t from_x, int32_t from_y, int32_t to_x, int32_t to_y, + lv_grad_extend_t extend) +{ + LV_ASSERT_NULL(dsc); + dsc->dir = LV_GRAD_DIR_LINEAR; + dsc->params.linear.start.x = from_x; + dsc->params.linear.start.y = from_y; + dsc->params.linear.end.x = to_x; + dsc->params.linear.end.y = to_y; + dsc->extend = extend; +} + +void lv_grad_radial_init(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t to_x, int32_t to_y, + lv_grad_extend_t extend) +{ + LV_ASSERT_NULL(dsc); + dsc->dir = LV_GRAD_DIR_RADIAL; + dsc->params.radial.focal.x = center_x; + dsc->params.radial.focal.y = center_y; + dsc->params.radial.focal_extent.x = center_x; + dsc->params.radial.focal_extent.y = center_y; + dsc->params.radial.end.x = center_x; + dsc->params.radial.end.y = center_y; + dsc->params.radial.end_extent.x = to_x; + dsc->params.radial.end_extent.y = to_y; + dsc->extend = extend; +} + +void lv_grad_conical_init(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t start_angle, + int32_t end_angle, lv_grad_extend_t extend) +{ + LV_ASSERT_NULL(dsc); + dsc->dir = LV_GRAD_DIR_CONICAL; + dsc->params.conical.center.x = center_x; + dsc->params.conical.center.y = center_y; + dsc->params.conical.start_angle = start_angle; + dsc->params.conical.end_angle = end_angle; + dsc->extend = extend; +} + +void lv_grad_radial_set_focal(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t radius) +{ + LV_ASSERT_NULL(dsc); + dsc->params.radial.focal.x = center_x; + dsc->params.radial.focal.y = center_y; + dsc->params.radial.focal_extent.x = center_x + radius; + dsc->params.radial.focal_extent.y = center_y; +} + +#endif /* LV_USE_DRAW_SW_COMPLEX_GRADIENTS */ + +/********************** + * STATIC FUNCTIONS + **********************/ diff --git a/src/misc/lv_grad.h b/src/misc/lv_grad.h new file mode 100644 index 000000000..3ddeb724d --- /dev/null +++ b/src/misc/lv_grad.h @@ -0,0 +1,182 @@ +/** + * @file lv_grad.h + * + */ + +#ifndef LV_GRAD_H +#define LV_GRAD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" +#include "lv_color.h" +#include "lv_area.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/** + * The direction of the gradient. + */ +typedef enum { + LV_GRAD_DIR_NONE, /**< No gradient (the `grad_color` property is ignored)*/ + LV_GRAD_DIR_VER, /**< Simple vertical (top to bottom) gradient*/ + LV_GRAD_DIR_HOR, /**< Simple horizontal (left to right) gradient*/ + LV_GRAD_DIR_LINEAR, /**< Linear gradient defined by start and end points. Can be at any angle.*/ + LV_GRAD_DIR_RADIAL, /**< Radial gradient defined by start and end circles*/ + LV_GRAD_DIR_CONICAL, /**< Conical gradient defined by center point, start and end angles*/ +} lv_grad_dir_t; + +/** + * Gradient behavior outside the defined range. + */ +typedef enum { + LV_GRAD_EXTEND_PAD, /**< Repeat the same color*/ + LV_GRAD_EXTEND_REPEAT, /**< Repeat the pattern*/ + LV_GRAD_EXTEND_REFLECT, /**< Repeat the pattern mirrored*/ +} lv_grad_extend_t; + +/** A gradient stop definition. + * This matches a color and a position in a virtual 0-255 scale. + */ +typedef struct { + lv_color_t color; /**< The stop color */ + lv_opa_t opa; /**< The opacity of the color*/ + uint8_t frac; /**< The stop position in 1/255 unit */ +} lv_grad_stop_t; + +/** A descriptor of a gradient. */ +typedef struct { + lv_grad_stop_t stops[LV_GRADIENT_MAX_STOPS]; /**< A gradient stop array */ + uint8_t stops_count; /**< The number of used stops in the array */ + lv_grad_dir_t dir : 4; /**< The gradient direction. + * Any of LV_GRAD_DIR_NONE, LV_GRAD_DIR_VER, LV_GRAD_DIR_HOR, + * LV_GRAD_TYPE_LINEAR, LV_GRAD_TYPE_RADIAL, LV_GRAD_TYPE_CONICAL */ + lv_grad_extend_t extend : 3; /**< Behaviour outside the defined range. + * LV_GRAD_EXTEND_NONE, LV_GRAD_EXTEND_PAD, LV_GRAD_EXTEND_REPEAT, LV_GRAD_EXTEND_REFLECT */ +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + union { + /*Linear gradient parameters*/ + struct { + lv_point_t start; /**< Linear gradient vector start point */ + lv_point_t end; /**< Linear gradient vector end point */ + } linear; + /*Radial gradient parameters*/ + struct { + lv_point_t focal; /**< Center of the focal (starting) circle in local coordinates */ + /* (can be the same as the ending circle to create concentric circles) */ + lv_point_t focal_extent; /**< Point on the circle (can be the same as the center) */ + lv_point_t end; /**< Center of the ending circle in local coordinates */ + lv_point_t end_extent; /**< Point on the circle determining the radius of the gradient */ + } radial; + /*Conical gradient parameters*/ + struct { + lv_point_t center; /**< Conical gradient center point */ + int16_t start_angle; /**< Start angle 0..3600 */ + int16_t end_angle; /**< End angle 0..3600 */ + } conical; + } params; + void * state; +#endif +} lv_grad_dsc_t; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Initialize gradient color map from a table + * @param grad pointer to a gradient descriptor + * @param colors color array + * @param fracs position array (0..255): if NULL, then colors are distributed evenly + * @param opa opacity array: if NULL, then LV_OPA_COVER is assumed + * @param num_stops number of gradient stops (1..LV_GRADIENT_MAX_STOPS) + */ +void lv_grad_init_stops(lv_grad_dsc_t * grad, const lv_color_t colors[], const lv_opa_t opa[], + const uint8_t fracs[], int num_stops); + +/** + * Helper function to initialize a horizontal gradient. + * @param dsc gradient descriptor + */ +void lv_grad_horizontal_init(lv_grad_dsc_t * dsc); + +/** + * Helper function to initialize a vertical gradient. + * @param dsc gradient descriptor + */ +void lv_grad_vertical_init(lv_grad_dsc_t * dsc); + +#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS + +/** + * Helper function to initialize linear gradient + * @param dsc gradient descriptor + * @param from_x start x position: can be a coordinate or an lv_pct() value + * predefined constants LV_GRAD_LEFT, LV_GRAD_RIGHT, LV_GRAD_TOP, LV_GRAD_BOTTOM, LV_GRAD_CENTER can be used as well + * @param from_y start y position + * @param to_x end x position + * @param to_y end y position + * @param extend one of LV_GRAD_EXTEND_PAD, LV_GRAD_EXTEND_REPEAT or LV_GRAD_EXTEND_REFLECT + */ +void lv_grad_linear_init(lv_grad_dsc_t * dsc, int32_t from_x, int32_t from_y, int32_t to_x, int32_t to_y, + lv_grad_extend_t extend); + +/** + * Helper function to initialize radial gradient + * @param dsc gradient descriptor + * @param center_x center x position: can be a coordinate or an lv_pct() value + * predefined constants LV_GRAD_LEFT, LV_GRAD_RIGHT, LV_GRAD_TOP, LV_GRAD_BOTTOM, LV_GRAD_CENTER can be used as well + * @param center_y center y position + * @param to_x point on the end circle x position + * @param to_y point on the end circle y position + * @param extend one of LV_GRAD_EXTEND_PAD, LV_GRAD_EXTEND_REPEAT or LV_GRAD_EXTEND_REFLECT + */ +void lv_grad_radial_init(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t to_x, int32_t to_y, + lv_grad_extend_t extend); + +/** + * Set focal (starting) circle of a radial gradient + * @param dsc gradient descriptor + * @param center_x center x position: can be a coordinate or an lv_pct() value + * predefined constants LV_GRAD_LEFT, LV_GRAD_RIGHT, LV_GRAD_TOP, LV_GRAD_BOTTOM, LV_GRAD_CENTER can be used as well + * @param center_y center y position + * @param radius radius of the starting circle (NOTE: this must be a scalar number, not percentage) + */ +void lv_grad_radial_set_focal(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t radius); + +/** + * Helper function to initialize conical gradient + * @param dsc gradient descriptor + * @param center_x center x position: can be a coordinate or an lv_pct() value + * predefined constants LV_GRAD_LEFT, LV_GRAD_RIGHT, LV_GRAD_TOP, LV_GRAD_BOTTOM, LV_GRAD_CENTER can be used as well + * @param center_y center y position + * @param start_angle start angle in degrees + * @param end_angle end angle in degrees + * @param extend one of LV_GRAD_EXTEND_PAD, LV_GRAD_EXTEND_REPEAT or LV_GRAD_EXTEND_REFLECT + */ +void lv_grad_conical_init(lv_grad_dsc_t * dsc, int32_t center_x, int32_t center_y, int32_t start_angle, + int32_t end_angle, lv_grad_extend_t extend); + +#endif /*LV_USE_DRAW_SW_COMPLEX_GRADIENTS*/ + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_GRAD_H*/ diff --git a/src/misc/lv_style.h b/src/misc/lv_style.h index 8abb78695..f417bbeac 100644 --- a/src/misc/lv_style.h +++ b/src/misc/lv_style.h @@ -21,6 +21,7 @@ extern "C" { #include "lv_types.h" #include "lv_assert.h" #include "lv_bidi.h" +#include "lv_grad.h" #include "../layouts/lv_layout.h" /********************* @@ -68,6 +69,16 @@ LV_EXPORT_CONST_INT(LV_SCALE_NONE); #define LV_STYLE_CONST_PROPS_END { .prop = LV_STYLE_PROP_INV, .value = { .num = 0 } } +#if LV_GRADIENT_MAX_STOPS < 2 +#error LVGL needs at least 2 stops for gradients. Please increase the LV_GRADIENT_MAX_STOPS +#endif + +#define LV_GRAD_LEFT LV_PCT(0) +#define LV_GRAD_RIGHT LV_PCT(100) +#define LV_GRAD_TOP LV_PCT(0) +#define LV_GRAD_BOTTOM LV_PCT(100) +#define LV_GRAD_CENTER LV_PCT(50) + /********************** * TYPEDEFS **********************/ @@ -106,71 +117,6 @@ typedef enum { LV_BORDER_SIDE_INTERNAL = 0x10, /**< FOR matrix-like objects (e.g. Button matrix)*/ } lv_border_side_t; -/** - * The direction of the gradient. - */ -typedef enum { - LV_GRAD_DIR_NONE, /**< No gradient (the `grad_color` property is ignored)*/ - LV_GRAD_DIR_VER, /**< Simple vertical (top to bottom) gradient*/ - LV_GRAD_DIR_HOR, /**< Simple horizontal (left to right) gradient*/ - LV_GRAD_DIR_LINEAR, /**< Linear gradient defined by start and end points. Can be at any angle.*/ - LV_GRAD_DIR_RADIAL, /**< Radial gradient defined by start and end circles*/ - LV_GRAD_DIR_CONICAL, /**< Conical gradient defined by center point, start and end angles*/ -} lv_grad_dir_t; - -/** - * Gradient behavior outside the defined range. -*/ -typedef enum { - LV_GRAD_EXTEND_PAD, /**< Repeat the same color*/ - LV_GRAD_EXTEND_REPEAT, /**< Repeat the pattern*/ - LV_GRAD_EXTEND_REFLECT, /**< Repeat the pattern mirrored*/ -} lv_grad_extend_t; - -/** A gradient stop definition. - * This matches a color and a position in a virtual 0-255 scale. - */ -typedef struct { - lv_color_t color; /**< The stop color */ - lv_opa_t opa; /**< The opacity of the color*/ - uint8_t frac; /**< The stop position in 1/255 unit */ -} lv_gradient_stop_t; - -/** A descriptor of a gradient. */ -typedef struct { - lv_gradient_stop_t stops[LV_GRADIENT_MAX_STOPS]; /**< A gradient stop array */ - uint8_t stops_count; /**< The number of used stops in the array */ - lv_grad_dir_t dir : 4; /**< The gradient direction. - * Any of LV_GRAD_DIR_NONE, LV_GRAD_DIR_VER, LV_GRAD_DIR_HOR, - * LV_GRAD_TYPE_LINEAR, LV_GRAD_TYPE_RADIAL, LV_GRAD_TYPE_CONICAL */ - lv_grad_extend_t extend : 3; /**< Behaviour outside the defined range. - * LV_GRAD_EXTEND_NONE, LV_GRAD_EXTEND_PAD, LV_GRAD_EXTEND_REPEAT, LV_GRAD_EXTEND_REFLECT */ -#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS - union { - /*Linear gradient parameters*/ - struct { - lv_point_t start; /**< Linear gradient vector start point */ - lv_point_t end; /**< Linear gradient vector end point */ - } linear; - /*Radial gradient parameters*/ - struct { - lv_point_t focal; /**< Center of the focal (starting) circle in local coordinates */ - /* (can be the same as the ending circle to create concentric circles) */ - lv_point_t focal_extent; /**< Point on the circle (can be the same as the center) */ - lv_point_t end; /**< Center of the ending circle in local coordinates */ - lv_point_t end_extent; /**< Point on the circle determining the radius of the gradient */ - } radial; - /*Conical gradient parameters*/ - struct { - lv_point_t center; /**< Conical gradient center point */ - int16_t start_angle; /**< Start angle 0..3600 */ - int16_t end_angle; /**< End angle 0..3600 */ - } conical; - } params; - void * state; -#endif -} lv_grad_dsc_t; - /** * A common type to handle all the property types in the same way. */ diff --git a/src/misc/lv_types.h b/src/misc/lv_types.h index da804d5a7..a9d9ab67e 100644 --- a/src/misc/lv_types.h +++ b/src/misc/lv_types.h @@ -151,8 +151,6 @@ typedef struct _lv_image_header_cache_data_t lv_image_header_cache_data_t; typedef struct _lv_draw_mask_t lv_draw_mask_t; -typedef struct _lv_grad_t lv_grad_t; - typedef struct _lv_draw_label_hint_t lv_draw_label_hint_t; typedef struct _lv_draw_glyph_dsc_t lv_draw_glyph_dsc_t; diff --git a/tests/src/test_cases/draw/test_draw_vector.c b/tests/src/test_cases/draw/test_draw_vector.c index 914e03ba9..ea2fc7a90 100644 --- a/tests/src/test_cases/draw/test_draw_vector.c +++ b/tests/src/test_cases/draw/test_draw_vector.c @@ -48,7 +48,7 @@ static void draw_shapes(lv_layer_t * layer) lv_vector_dsc_identity(ctx); lv_vector_dsc_translate(ctx, 0, 150); - lv_gradient_stop_t stops[2]; + lv_grad_stop_t stops[2]; lv_memzero(stops, sizeof(stops)); stops[0].color = lv_color_hex(0xffffff); stops[0].opa = LV_OPA_COVER; @@ -210,7 +210,7 @@ static void draw_lines(lv_layer_t * layer) lv_vector_path_clear(path); lv_vector_path_append_rect(path, &rect1, 0, 0); - lv_gradient_stop_t stops[2]; + lv_grad_stop_t stops[2]; lv_memzero(stops, sizeof(stops)); stops[0].color = lv_color_hex(0xff0000); stops[0].opa = LV_OPA_COVER;