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);
|
_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 */
|
/* path functions */
|
||||||
lv_vector_path_t * lv_vector_path_create(lv_vector_path_quality_t quality)
|
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);
|
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)
|
void lv_vector_path_append_rect(lv_vector_path_t * path, const lv_area_t * rect, float rx, float ry)
|
||||||
{
|
{
|
||||||
float x = rect->x1;
|
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));
|
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.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);
|
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);
|
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
|
* Create a vector graphic path object
|
||||||
* @param quality the quality hint of path
|
* @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);
|
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
|
* Add a rectangle to the path
|
||||||
* @param path pointer to a 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);
|
_lv_area_to_tvg(&rc, &dsc->scissor_area);
|
||||||
|
|
||||||
_tvg_color c;
|
_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 = {
|
Tvg_Matrix mtx = {
|
||||||
1.0f, 0.0f, 0.0f,
|
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);
|
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)
|
void test_draw_lines(void)
|
||||||
{
|
{
|
||||||
canvas_draw("draw_lines", draw_lines);
|
canvas_draw("draw_lines", draw_lines);
|
||||||
|
|||||||
Reference in New Issue
Block a user