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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -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;
|
||||
|
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 |