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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user