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>
@ -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);
|
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)
|
static void draw_execute(lv_draw_vg_lite_unit_t * u)
|
||||||
{
|
{
|
||||||
lv_draw_task_t * t = u->task_act;
|
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
|
#endif
|
||||||
case LV_DRAW_TASK_TYPE_LAYER:
|
case LV_DRAW_TASK_TYPE_LAYER:
|
||||||
case LV_DRAW_TASK_TYPE_LINE:
|
case LV_DRAW_TASK_TYPE_LINE:
|
||||||
case LV_DRAW_TASK_TYPE_ARC:
|
|
||||||
case LV_DRAW_TASK_TYPE_TRIANGLE:
|
case LV_DRAW_TASK_TYPE_TRIANGLE:
|
||||||
case LV_DRAW_TASK_TYPE_MASK_RECTANGLE:
|
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
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LV_DRAW_TASK_TYPE_ARC: {
|
||||||
|
if(!check_arc_is_supported(task->draw_dsc)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case LV_DRAW_TASK_TYPE_IMAGE: {
|
case LV_DRAW_TASK_TYPE_IMAGE: {
|
||||||
if(!check_image_is_supported(task->draw_dsc)) {
|
if(!check_image_is_supported(task->draw_dsc)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -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_out = dsc->radius;
|
||||||
float radius_in = dsc->radius - dsc->width;
|
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 cx = dsc->center.x;
|
||||||
float cy = dsc->center.y;
|
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)) {
|
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_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;
|
fill = VG_LITE_FILL_EVEN_ODD;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* radius_out start point */
|
|
||||||
float start_angle_rad = MATH_RADIANS(start_angle);
|
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_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 */
|
/* radius_in start point */
|
||||||
lv_vg_lite_path_append_arc(path,
|
float end_x = radius_in * MATH_COSF(end_angle_rad) + cx;
|
||||||
cx, cy,
|
float end_y = radius_in * MATH_SINF(end_angle_rad) + cy;
|
||||||
radius_out,
|
|
||||||
start_angle,
|
|
||||||
sweep_angle,
|
|
||||||
false);
|
|
||||||
|
|
||||||
/* line to radius_in */
|
lv_vg_lite_path_move_to(path, start_x, start_y);
|
||||||
lv_vg_lite_path_line_to(path, end_x, end_y);
|
|
||||||
|
|
||||||
/* radius_in arc */
|
/* radius_out arc */
|
||||||
lv_vg_lite_path_append_arc(path,
|
lv_vg_lite_path_append_arc(path,
|
||||||
cx, cy,
|
cx, cy,
|
||||||
radius_in,
|
radius_out,
|
||||||
end_angle,
|
start_angle,
|
||||||
-sweep_angle,
|
sweep_angle,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
/* close arc */
|
/* line to radius_in */
|
||||||
lv_vg_lite_path_close(path);
|
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 */
|
/* draw round */
|
||||||
if(dsc->rounded && half_width > 0) {
|
if(dsc->rounded && dsc->width > 0) {
|
||||||
float rcx1 = cx + radius_center * MATH_COSF(end_angle_rad);
|
float round_radius = radius_out > dsc->width ? dsc->width / 2.0f : radius_out / 2.0f;
|
||||||
float rcy1 = cy + radius_center * MATH_SINF(end_angle_rad);
|
float round_center = radius_out - round_radius;
|
||||||
lv_vg_lite_path_append_circle(path, rcx1, rcy1, half_width, half_width);
|
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 rcx2 = cx + round_center * MATH_COSF(start_angle_rad);
|
||||||
float rcy2 = cy + radius_center * MATH_SINF(start_angle_rad);
|
float rcy2 = cy + round_center * MATH_SINF(start_angle_rad);
|
||||||
lv_vg_lite_path_append_circle(path, rcx2, rcy2, half_width, half_width);
|
lv_vg_lite_path_append_circle(path, rcx2, rcy2, round_radius, round_radius);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_vg_lite_path_end(path);
|
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_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_DEST_BUFFER(&u->target_buffer);
|
||||||
LV_VG_LITE_ASSERT_PATH(vg_lite_path);
|
LV_VG_LITE_ASSERT_PATH(vg_lite_path);
|
||||||
LV_VG_LITE_ASSERT_MATRIX(&matrix);
|
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) {
|
if(dsc->img_src) {
|
||||||
vg_lite_buffer_t src_buf;
|
vg_lite_buffer_t src_buf;
|
||||||
lv_image_decoder_dsc_t decoder_dsc;
|
lv_image_decoder_dsc_t decoder_dsc;
|
||||||
if(lv_vg_lite_buffer_open_image(&src_buf, &decoder_dsc, dsc->img_src, false, true)) {
|
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;
|
vg_lite_matrix_t path_matrix = u->global_matrix;
|
||||||
|
|
||||||
/* move image to center */
|
/* 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_MATRIX(&path_matrix);
|
||||||
|
LV_VG_LITE_ASSERT_SRC_BUFFER(&src_buf);
|
||||||
|
|
||||||
LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_draw_pattern");
|
LV_PROFILER_DRAW_BEGIN_TAG("vg_lite_draw_pattern");
|
||||||
LV_VG_LITE_CHECK_ERROR(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_BLEND_SRC_OVER,
|
||||||
VG_LITE_PATTERN_COLOR,
|
VG_LITE_PATTERN_COLOR,
|
||||||
0,
|
0,
|
||||||
color,
|
img_color,
|
||||||
VG_LITE_FILTER_BI_LINEAR));
|
VG_LITE_FILTER_BI_LINEAR));
|
||||||
LV_PROFILER_DRAW_END_TAG("vg_lite_draw_pattern");
|
LV_PROFILER_DRAW_END_TAG("vg_lite_draw_pattern");
|
||||||
lv_vg_lite_pending_add(u->image_dsc_pending, &decoder_dsc);
|
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_vg_lite_path_drop(u, path);
|
||||||
LV_PROFILER_DRAW_END;
|
LV_PROFILER_DRAW_END;
|
||||||
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 9.4 KiB |