fix(vector) : add path bounding and matrix transform functions. (#5389)

Signed-off-by: zhangjipeng <zhangjipeng@xiaomi.com>
Co-authored-by: zhangjipeng <zhangjipeng@xiaomi.com>
This commit is contained in:
Zhang Ji Peng
2024-01-23 15:11:01 +08:00
committed by GitHub
parent b125d1baad
commit 377a99947f
4 changed files with 91 additions and 1 deletions

View File

@@ -195,6 +195,23 @@ void lv_matrix_multiply(lv_matrix_t * matrix, const lv_matrix_t * m)
_multiply_matrix(matrix, m);
}
void lv_matrix_transform_point(const lv_matrix_t * matrix, lv_fpoint_t * point)
{
float x = point->x;
float y = point->y;
point->x = x * matrix->m[0][0] + y * matrix->m[1][0] + matrix->m[0][2];
point->y = x * matrix->m[0][1] + y * matrix->m[1][1] + matrix->m[1][2];
}
void lv_matrix_transform_path(const lv_matrix_t * matrix, lv_vector_path_t * path)
{
for(uint32_t i = 0; i < path->points.size; i++) {
lv_fpoint_t * pt = lv_array_at(&path->points, i);
lv_matrix_transform_point(matrix, pt);
}
}
/* path functions */
lv_vector_path_t * lv_vector_path_create(lv_vector_path_quality_t quality)
{
@@ -295,6 +312,28 @@ void lv_vector_path_close(lv_vector_path_t * path)
lv_array_push_back(&path->ops, &op);
}
void lv_vector_path_get_bounding(const lv_vector_path_t * path, lv_area_t * area)
{
uint32_t len = lv_array_size(&path->points);
lv_fpoint_t * p = lv_array_at(&path->points, 0);
float x1 = p[0].x;
float x2 = p[0].x;
float y1 = p[0].y;
float y2 = p[0].y;
for(uint32_t i = 1; i < len; i++) {
if(p[i].x < x1) x1 = p[i].x;
if(p[i].y < y1) y1 = p[i].y;
if(p[i].x > x2) x2 = p[i].x;
if(p[i].y > y2) y2 = p[i].y;
}
area->x1 = (int32_t)x1;
area->y1 = (int32_t)y1;
area->x2 = (int32_t)x2;
area->y2 = (int32_t)y2;
}
void lv_vector_path_append_rect(lv_vector_path_t * path, const lv_area_t * rect, float rx, float ry)
{
float x = rect->x1;
@@ -682,6 +721,7 @@ void lv_vector_clear_area(lv_vector_dsc_t * dsc, const lv_area_t * rect)
lv_memset(new_task, 0, sizeof(_lv_vector_draw_task));
new_task->dsc.fill_dsc.color = dsc->current_dsc.fill_dsc.color;
new_task->dsc.fill_dsc.opa = dsc->current_dsc.fill_dsc.opa;
lv_area_copy(&(new_task->dsc.scissor_area), rect);
}

View File

@@ -205,6 +205,20 @@ void lv_matrix_skew(lv_matrix_t * matrix, float skew_x, float skew_y);
*/
void lv_matrix_multiply(lv_matrix_t * matrix, const lv_matrix_t * matrix2);
/**
* Transform the coordinates of a point using given matrix
* @param matrix pointer to a matrix
* @param point pointer to a point
*/
void lv_matrix_transform_point(const lv_matrix_t * matrix, lv_fpoint_t * point);
/**
* Transform all the coordinates of a path using given matrix
* @param matrix pointer to a matrix
* @param path pointer to a path
*/
void lv_matrix_transform_path(const lv_matrix_t * matrix, lv_vector_path_t * path);
/**
* Create a vector graphic path object
* @param quality the quality hint of path
@@ -269,6 +283,13 @@ void lv_vector_path_cubic_to(lv_vector_path_t * path, const lv_fpoint_t * p1, co
*/
void lv_vector_path_close(lv_vector_path_t * path);
/**
* Get the bounding box of a path
* @param path pointer to a path
* @param area pointer to a `lv_area_t` variable for bounding box
*/
void lv_vector_path_get_bounding(const lv_vector_path_t * path, lv_area_t * area);
/**
* Add a rectangle to the path
* @param path pointer to a path

View File

@@ -391,7 +391,7 @@ static void _task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_ve
_lv_area_to_tvg(&rc, &dsc->scissor_area);
_tvg_color c;
_lv_color_to_tvg(&c, &dsc->fill_dsc.color, LV_OPA_COVER);
_lv_color_to_tvg(&c, &dsc->fill_dsc.color, dsc->fill_dsc.opa);
Tvg_Matrix mtx = {
1.0f, 0.0f, 0.0f,

View File

@@ -225,6 +225,35 @@ static void canvas_draw(const char * name, void (*draw_cb)(lv_layer_t *))
lv_obj_del(canvas);
}
void test_transform(void)
{
lv_matrix_t matrix;
lv_matrix_identity(&matrix);
lv_matrix_translate(&matrix, 100, 100);
lv_fpoint_t p = {10, 10};
lv_matrix_transform_point(&matrix, &p);
TEST_ASSERT_EQUAL_FLOAT(110.0f, p.x);
TEST_ASSERT_EQUAL_FLOAT(110.0f, p.y);
lv_vector_path_t * path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_MEDIUM);
lv_vector_path_move_to(path, &p);
lv_fpoint_t p2 = {20, 20};
lv_vector_path_line_to(path, &p2);
lv_matrix_transform_path(&matrix, path);
lv_fpoint_t * pt = lv_array_at(&path->points, 0);
TEST_ASSERT_EQUAL_FLOAT(210.0f, pt[0].x);
TEST_ASSERT_EQUAL_FLOAT(210.0f, pt[0].y);
TEST_ASSERT_EQUAL_FLOAT(120.0f, pt[1].x);
TEST_ASSERT_EQUAL_FLOAT(120.0f, pt[1].y);
lv_vector_path_delete(path);
}
void test_draw_lines(void)
{
canvas_draw("draw_lines", draw_lines);