1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

fix(vg_lite): fix arc drawing boundary case drawing error (#7107)

Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com>
Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
VIFEX 2024-10-19 16:59:42 +08:00 committed by GitHub
parent 07854b1d0b
commit aa3a85222b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 97 additions and 53 deletions

View File

@ -95,6 +95,22 @@ static bool check_image_is_supported(const lv_draw_image_dsc_t * dsc)
return lv_vg_lite_is_src_cf_supported(dsc->header.cf);
}
static bool check_arc_is_supported(const lv_draw_arc_dsc_t * dsc)
{
if(dsc->img_src == NULL) {
return true;
}
lv_image_header_t header;
lv_result_t res = lv_image_decoder_get_info(dsc->img_src, &header);
if(res != LV_RESULT_OK) {
LV_LOG_TRACE("get image info failed");
return false;
}
return lv_vg_lite_is_src_cf_supported(header.cf);
}
static void draw_execute(lv_draw_vg_lite_unit_t * u)
{
lv_draw_task_t * t = u->task_act;
@ -231,7 +247,6 @@ static int32_t draw_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task)
#endif
case LV_DRAW_TASK_TYPE_LAYER:
case LV_DRAW_TASK_TYPE_LINE:
case LV_DRAW_TASK_TYPE_ARC:
case LV_DRAW_TASK_TYPE_TRIANGLE:
case LV_DRAW_TASK_TYPE_MASK_RECTANGLE:
@ -240,6 +255,13 @@ static int32_t draw_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task)
#endif
break;
case LV_DRAW_TASK_TYPE_ARC: {
if(!check_arc_is_supported(task->draw_dsc)) {
return 0;
}
}
break;
case LV_DRAW_TASK_TYPE_IMAGE: {
if(!check_image_is_supported(task->draw_dsc)) {
return 0;

View File

@ -88,8 +88,6 @@ void lv_draw_vg_lite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * d
float radius_out = dsc->radius;
float radius_in = dsc->radius - dsc->width;
float half_width = dsc->width * 0.5f;
float radius_center = radius_out - half_width;
float cx = dsc->center.x;
float cy = dsc->center.y;
@ -97,88 +95,100 @@ void lv_draw_vg_lite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * d
if(math_equal(sweep_angle, 360)) {
lv_vg_lite_path_append_circle(path, cx, cy, radius_out, radius_out);
lv_vg_lite_path_append_circle(path, cx, cy, radius_in, radius_in);
/* radius_in <= 0, normal fill circle */
if(radius_in > 0) {
lv_vg_lite_path_append_circle(path, cx, cy, radius_in, radius_in);
}
fill = VG_LITE_FILL_EVEN_ODD;
}
else {
/* radius_out start point */
float start_angle_rad = MATH_RADIANS(start_angle);
float start_x = radius_out * MATH_COSF(start_angle_rad) + cx;
float start_y = radius_out * MATH_SINF(start_angle_rad) + cy;
/* radius_in start point */
float end_angle_rad = MATH_RADIANS(end_angle);
float end_x = radius_in * MATH_COSF(end_angle_rad) + cx;
float end_y = radius_in * MATH_SINF(end_angle_rad) + cy;
lv_vg_lite_path_move_to(path, start_x, start_y);
if(radius_in > 0) {
/* radius_out start point */
float start_x = radius_out * MATH_COSF(start_angle_rad) + cx;
float start_y = radius_out * MATH_SINF(start_angle_rad) + cy;
/* radius_out arc */
lv_vg_lite_path_append_arc(path,
cx, cy,
radius_out,
start_angle,
sweep_angle,
false);
/* radius_in start point */
float end_x = radius_in * MATH_COSF(end_angle_rad) + cx;
float end_y = radius_in * MATH_SINF(end_angle_rad) + cy;
/* line to radius_in */
lv_vg_lite_path_line_to(path, end_x, end_y);
lv_vg_lite_path_move_to(path, start_x, start_y);
/* radius_in arc */
lv_vg_lite_path_append_arc(path,
cx, cy,
radius_in,
end_angle,
-sweep_angle,
false);
/* radius_out arc */
lv_vg_lite_path_append_arc(path,
cx, cy,
radius_out,
start_angle,
sweep_angle,
false);
/* close arc */
lv_vg_lite_path_close(path);
/* line to radius_in */
lv_vg_lite_path_line_to(path, end_x, end_y);
/* radius_in arc */
lv_vg_lite_path_append_arc(path,
cx, cy,
radius_in,
end_angle,
-sweep_angle,
false);
/* close arc */
lv_vg_lite_path_close(path);
}
else {
/* draw a normal arc pie shape */
lv_vg_lite_path_append_arc(path, cx, cy, radius_out, start_angle, sweep_angle, true);
}
/* draw round */
if(dsc->rounded && half_width > 0) {
float rcx1 = cx + radius_center * MATH_COSF(end_angle_rad);
float rcy1 = cy + radius_center * MATH_SINF(end_angle_rad);
lv_vg_lite_path_append_circle(path, rcx1, rcy1, half_width, half_width);
if(dsc->rounded && dsc->width > 0) {
float round_radius = radius_out > dsc->width ? dsc->width / 2.0f : radius_out / 2.0f;
float round_center = radius_out - round_radius;
float rcx1 = cx + round_center * MATH_COSF(end_angle_rad);
float rcy1 = cy + round_center * MATH_SINF(end_angle_rad);
lv_vg_lite_path_append_circle(path, rcx1, rcy1, round_radius, round_radius);
float rcx2 = cx + radius_center * MATH_COSF(start_angle_rad);
float rcy2 = cy + radius_center * MATH_SINF(start_angle_rad);
lv_vg_lite_path_append_circle(path, rcx2, rcy2, half_width, half_width);
float rcx2 = cx + round_center * MATH_COSF(start_angle_rad);
float rcy2 = cy + round_center * MATH_SINF(start_angle_rad);
lv_vg_lite_path_append_circle(path, rcx2, rcy2, round_radius, round_radius);
}
}
lv_vg_lite_path_end(path);
vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path);
vg_lite_matrix_t matrix = u->global_matrix;
vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true);
vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path);
LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer);
LV_VG_LITE_ASSERT_PATH(vg_lite_path);
LV_VG_LITE_ASSERT_MATRIX(&matrix);
LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_draw");
LV_VG_LITE_CHECK_ERROR(vg_lite_draw(
&u->target_buffer,
vg_lite_path,
fill,
&matrix,
VG_LITE_BLEND_SRC_OVER,
color));
LV_PROFILER_DRAW_END_TAG("vg_lite_draw");
if(dsc->img_src) {
vg_lite_buffer_t src_buf;
lv_image_decoder_dsc_t decoder_dsc;
if(lv_vg_lite_buffer_open_image(&src_buf, &decoder_dsc, dsc->img_src, false, true)) {
vg_lite_color_t img_color = 0;
if(dsc->opa < LV_OPA_COVER) {
/* normal image opa */
src_buf.image_mode = VG_LITE_MULTIPLY_IMAGE_MODE;
lv_memset(&img_color, dsc->opa, sizeof(img_color));
}
vg_lite_matrix_t path_matrix = u->global_matrix;
/* move image to center */
vg_lite_translate(cx - radius_out, cy - radius_out, &matrix);
float img_half_w = decoder_dsc.decoded->header.w / 2.0f;
float img_half_h = decoder_dsc.decoded->header.h / 2.0f;
vg_lite_translate(cx - img_half_w, cy - img_half_h, &matrix);
LV_VG_LITE_ASSERT_MATRIX(&matrix);
LV_VG_LITE_ASSERT_MATRIX(&path_matrix);
LV_VG_LITE_ASSERT_SRC_BUFFER(&src_buf);
LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_draw_pattern");
LV_VG_LITE_CHECK_ERROR(vg_lite_draw_pattern(
@ -191,12 +201,24 @@ void lv_draw_vg_lite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * d
VG_LITE_BLEND_SRC_OVER,
VG_LITE_PATTERN_COLOR,
0,
color,
img_color,
VG_LITE_FILTER_BI_LINEAR));
LV_PROFILER_DRAW_END_TAG("vg_lite_draw_pattern");
lv_vg_lite_pending_add(u->image_dsc_pending, &decoder_dsc);
}
}
else {
/* normal color fill */
LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_draw");
LV_VG_LITE_CHECK_ERROR(vg_lite_draw(
&u->target_buffer,
vg_lite_path,
fill,
&matrix,
VG_LITE_BLEND_SRC_OVER,
lv_vg_lite_color(dsc->color, dsc->opa, true)));
LV_PROFILER_DRAW_END_TAG("vg_lite_draw");
}
lv_vg_lite_path_drop(u, path);
LV_PROFILER_DRAW_END;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB