diff --git a/src/draw/sw/lv_draw_sw_letter.c b/src/draw/sw/lv_draw_sw_letter.c index c57632b7ac..be7f92ae3a 100644 --- a/src/draw/sw/lv_draw_sw_letter.c +++ b/src/draw/sw/lv_draw_sw_letter.c @@ -38,12 +38,6 @@ **********************/ #if LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG -typedef struct { - lv_vector_path_t * inside_path; /*The regular glyph*/ - lv_vector_path_t * outside_path; /*A bigger glyph that goes in the background for the letter outline*/ - lv_vector_path_t * cur_path; -} lv_draw_sw_letter_outlines_t; - #endif /* LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG */ /********************** @@ -226,6 +220,7 @@ static void LV_ATTRIBUTE_FAST_MEM draw_letter_cb(lv_draw_task_t * t, lv_draw_gly #if LV_USE_FREETYPE && LV_USE_VECTOR_GRAPHIC && LV_USE_THORVG + /* * Renders the vectors paths representing a glyph with ThorVG * the result is then blended into the draw buffer @@ -233,25 +228,25 @@ static void LV_ATTRIBUTE_FAST_MEM draw_letter_cb(lv_draw_task_t * t, lv_draw_gly static void draw_letter_outline(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_dsc) { - lv_draw_sw_letter_outlines_t * glyph_paths; lv_draw_vector_dsc_t * vector_dsc; lv_draw_buf_t * draw_buf; lv_matrix_t matrix; lv_layer_t layer; - glyph_paths = (lv_draw_sw_letter_outlines_t *) glyph_dsc->glyph_data; - LV_ASSERT_NULL(glyph_paths); + lv_vector_path_t * paths = (lv_vector_path_t *) glyph_dsc->glyph_data; + LV_ASSERT_NULL(paths); - int32_t cf; int32_t w; int32_t h; uint32_t stride; - float scale; lv_area_t buf_area; - cf = LV_COLOR_FORMAT_ARGB8888; - - scale = LV_FREETYPE_F26DOT6_TO_FLOAT(lv_freetype_outline_get_scale(glyph_dsc->g->resolved_font)); + float scale = 1.0f; +#if LV_USE_FREETYPE + if(lv_freetype_is_outline_font(glyph_dsc->g->resolved_font)) { + scale = LV_FREETYPE_F26DOT6_TO_FLOAT(lv_freetype_outline_get_scale(glyph_dsc->g->resolved_font)); + } +#endif w = (int32_t)((float) glyph_dsc->g->box_w + glyph_dsc->outline_stroke_width * 2 * scale); h = (int32_t)((float) glyph_dsc->g->box_h + glyph_dsc->outline_stroke_width * 2 * scale); buf_area.x1 = 0; @@ -259,13 +254,13 @@ static void draw_letter_outline(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_ lv_area_set_width(&buf_area, w); lv_area_set_height(&buf_area, h); - stride = lv_draw_buf_width_to_stride(w, cf); - draw_buf = lv_draw_buf_create(w, h, cf, stride); + stride = lv_draw_buf_width_to_stride(w, LV_COLOR_FORMAT_ARGB8888); + draw_buf = lv_draw_buf_create(w, h, LV_COLOR_FORMAT_ARGB8888, stride); lv_draw_buf_clear(draw_buf, NULL); lv_memzero(&layer, sizeof(lv_layer_t)); layer.draw_buf = draw_buf; - layer.color_format = cf; + layer.color_format = LV_COLOR_FORMAT_ARGB8888; layer.buf_area = buf_area; layer.phy_clip_area = buf_area; layer._clip_area = buf_area; @@ -288,24 +283,21 @@ static void draw_letter_outline(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_ lv_matrix_scale(&matrix, scale, scale); lv_draw_vector_dsc_set_transform(vector_dsc, &matrix); + /*Set attributes color, line width etc*/ - if(cf == LV_COLOR_FORMAT_ARGB8888) { - - if(glyph_dsc->outline_stroke_width > 0) { - lv_draw_vector_dsc_set_fill_color(vector_dsc, glyph_dsc->outline_stroke_color); - lv_draw_vector_dsc_set_fill_opa(vector_dsc, glyph_dsc->outline_stroke_opa); - lv_draw_vector_dsc_add_path(vector_dsc, glyph_paths->outside_path); - } - - lv_draw_vector_dsc_set_fill_color(vector_dsc, glyph_dsc->color); - lv_draw_vector_dsc_set_fill_opa(vector_dsc, glyph_dsc->opa); - lv_draw_vector_dsc_add_path(vector_dsc, glyph_paths->inside_path); - - } - else { - LV_LOG_ERROR("Unsupported color format: %d", cf); + if(glyph_dsc->outline_stroke_width > 0) { + lv_draw_vector_dsc_set_stroke_color(vector_dsc, glyph_dsc->outline_stroke_color); + lv_draw_vector_dsc_set_stroke_opa(vector_dsc, glyph_dsc->outline_stroke_opa); + lv_draw_vector_dsc_set_stroke_width(vector_dsc, glyph_dsc->outline_stroke_width); + lv_draw_vector_dsc_add_path(vector_dsc, paths); + lv_draw_vector_dsc_set_stroke_opa(vector_dsc, 0); + lv_draw_vector_dsc_set_stroke_width(vector_dsc, 0); } + lv_draw_vector_dsc_set_fill_color(vector_dsc, glyph_dsc->color); + lv_draw_vector_dsc_set_fill_opa(vector_dsc, glyph_dsc->opa); + lv_draw_vector_dsc_add_path(vector_dsc, paths); + lv_area_t old_area; lv_area_t letter_coords; @@ -326,6 +318,7 @@ static void draw_letter_outline(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_ dummy_t.clip_area = vector_dsc->base.layer->_clip_area; dummy_t.target_layer = vector_dsc->base.layer; dummy_t.type = LV_DRAW_TASK_TYPE_VECTOR; + dummy_t.opa = LV_OPA_COVER; dummy_t.draw_dsc = vector_dsc; lv_draw_sw_vector(&dummy_t, dummy_t.draw_dsc); } @@ -340,10 +333,6 @@ static void draw_letter_outline(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_ lv_draw_image_dsc_t img_dsc; lv_draw_image_dsc_init(&img_dsc); - img_dsc.rotation = 0; - img_dsc.scale_x = LV_SCALE_NONE; - img_dsc.scale_y = LV_SCALE_NONE; - img_dsc.opa = LV_OPA_100; img_dsc.src = draw_buf; lv_draw_sw_image(t, &img_dsc, &letter_coords); @@ -356,86 +345,67 @@ static void draw_letter_outline(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_ * on the received outline events emitted by lv_freetype_outline.c */ static void freetype_outline_event_cb(lv_event_t * e) { + lv_freetype_outline_event_param_t * param = lv_event_get_param(e); - lv_fpoint_t pnt; - lv_fpoint_t ctrl_pnt1; - lv_fpoint_t ctrl_pnt2; - lv_draw_sw_letter_outlines_t * glyph_paths; - lv_vector_path_t * path; - lv_freetype_outline_event_param_t * outline_event; + switch(lv_event_get_code(e)) { + case LV_EVENT_CREATE: { + /*Create the inside path*/ + param->outline = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_HIGH); + break; + } - outline_event = lv_event_get_param(e); - pnt.x = LV_FREETYPE_F26DOT6_TO_FLOAT(outline_event->to.x); - pnt.y = LV_FREETYPE_F26DOT6_TO_FLOAT(outline_event->to.y); - glyph_paths = outline_event->outline; + case LV_EVENT_DELETE: { + lv_vector_path_clear(param->outline); + lv_vector_path_delete(param->outline); + break; + } - if(lv_event_get_code(e) == LV_EVENT_CREATE) { + case LV_EVENT_INSERT: { + lv_fpoint_t pnt; + lv_fpoint_t ctrl_pnt1; + lv_fpoint_t ctrl_pnt2; + lv_vector_path_t * path = param->outline; - glyph_paths = lv_malloc_zeroed(sizeof(lv_draw_sw_letter_outlines_t)); - LV_ASSERT_MALLOC(glyph_paths); + switch(param->type) { + case LV_FREETYPE_OUTLINE_MOVE_TO: + pnt.x = LV_FREETYPE_F26DOT6_TO_FLOAT(param->to.x); + pnt.y = LV_FREETYPE_F26DOT6_TO_FLOAT(param->to.y); + lv_vector_path_move_to(path, &pnt); + break; - glyph_paths->cur_path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_HIGH); - glyph_paths->inside_path = glyph_paths->cur_path; - outline_event->outline = glyph_paths; - return; + case LV_FREETYPE_OUTLINE_LINE_TO: + pnt.x = LV_FREETYPE_F26DOT6_TO_FLOAT(param->to.x); + pnt.y = LV_FREETYPE_F26DOT6_TO_FLOAT(param->to.y); + lv_vector_path_line_to(path, &pnt); + break; - } - else if(lv_event_get_code(e) == LV_EVENT_DELETE) { + case LV_FREETYPE_OUTLINE_CUBIC_TO: + pnt.x = LV_FREETYPE_F26DOT6_TO_FLOAT(param->to.x); + pnt.y = LV_FREETYPE_F26DOT6_TO_FLOAT(param->to.y); + ctrl_pnt1.x = LV_FREETYPE_F26DOT6_TO_FLOAT(param->control1.x); + ctrl_pnt1.y = LV_FREETYPE_F26DOT6_TO_FLOAT(param->control1.y); + ctrl_pnt2.x = LV_FREETYPE_F26DOT6_TO_FLOAT(param->control2.x); + ctrl_pnt2.y = LV_FREETYPE_F26DOT6_TO_FLOAT(param->control2.y); + lv_vector_path_cubic_to(path, &ctrl_pnt1, &ctrl_pnt2, &pnt); + break; - if(glyph_paths->inside_path != NULL) { - lv_vector_path_clear(glyph_paths->inside_path); - lv_vector_path_delete(glyph_paths->inside_path); - } - - if(glyph_paths->outside_path != NULL) { - lv_vector_path_clear(glyph_paths->outside_path); - lv_vector_path_delete(glyph_paths->outside_path); - } - - lv_free(glyph_paths); - return; - - } - else if(outline_event->type == LV_FREETYPE_OUTLINE_BORDER_START) { - - /* Inside path is done - create the border path */ - lv_vector_path_close(glyph_paths->cur_path); - glyph_paths->cur_path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_HIGH); - glyph_paths->outside_path = glyph_paths->cur_path; - return; - } - - path = glyph_paths->cur_path; - - switch(outline_event->type) { - - case LV_FREETYPE_OUTLINE_MOVE_TO: - lv_vector_path_move_to(path, &pnt); - break; - - case LV_FREETYPE_OUTLINE_LINE_TO: - lv_vector_path_line_to(path, &pnt); - break; - - case LV_FREETYPE_OUTLINE_CUBIC_TO: - ctrl_pnt1.x = LV_FREETYPE_F26DOT6_TO_FLOAT(outline_event->control1.x); - ctrl_pnt1.y = LV_FREETYPE_F26DOT6_TO_FLOAT(outline_event->control1.y); - ctrl_pnt2.x = LV_FREETYPE_F26DOT6_TO_FLOAT(outline_event->control2.x); - ctrl_pnt2.y = LV_FREETYPE_F26DOT6_TO_FLOAT(outline_event->control2.y); - lv_vector_path_cubic_to(path, &ctrl_pnt1, &ctrl_pnt2, &pnt); - break; - - case LV_FREETYPE_OUTLINE_CONIC_TO: - ctrl_pnt1.x = LV_FREETYPE_F26DOT6_TO_FLOAT(outline_event->control1.x); - ctrl_pnt1.y = LV_FREETYPE_F26DOT6_TO_FLOAT(outline_event->control1.y); - lv_vector_path_quad_to(path, &ctrl_pnt1, &pnt); - break; - case LV_FREETYPE_OUTLINE_END: - case LV_FREETYPE_OUTLINE_BORDER_START: - /* It's not necessary to close the path and - * border start is handled above - */ - break; + case LV_FREETYPE_OUTLINE_CONIC_TO: + pnt.x = LV_FREETYPE_F26DOT6_TO_FLOAT(param->to.x); + pnt.y = LV_FREETYPE_F26DOT6_TO_FLOAT(param->to.y); + ctrl_pnt1.x = LV_FREETYPE_F26DOT6_TO_FLOAT(param->control1.x); + ctrl_pnt1.y = LV_FREETYPE_F26DOT6_TO_FLOAT(param->control1.y); + lv_vector_path_quad_to(path, &ctrl_pnt1, &pnt); + break; + case LV_FREETYPE_OUTLINE_END: + /* It's not necessary to close the path and + * border start is handled above + */ + break; + } + break; + } + default: + LV_LOG_WARN("Invalid event code"); } } diff --git a/src/draw/vg_lite/lv_draw_vg_lite_label.c b/src/draw/vg_lite/lv_draw_vg_lite_label.c index b4b3c0471a..f2ced749ce 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite_label.c +++ b/src/draw/vg_lite/lv_draw_vg_lite_label.c @@ -35,12 +35,14 @@ #define PATH_FLUSH_COUNT_MAX 8 #endif -#define FT_F26DOT6_SHIFT 6 +#if LV_USE_FREETYPE + #define FT_F26DOT6_SHIFT 6 -/** After converting the font reference size, it is also necessary to scale the 26dot6 data - * in the path to the real physical size - */ -#define FT_F26DOT6_TO_PATH_SCALE(x) (LV_FREETYPE_F26DOT6_TO_FLOAT(x) / (1 << FT_F26DOT6_SHIFT)) + /** After converting the font reference size, it is also necessary to scale the 26dot6 data + * in the path to the real physical size + */ + #define FT_F26DOT6_TO_PATH_SCALE(x) (LV_FREETYPE_F26DOT6_TO_FLOAT(x) / (1 << FT_F26DOT6_SHIFT)) +#endif /********************** * TYPEDEFS @@ -57,10 +59,10 @@ static void draw_letter_bitmap(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * d static void bitmap_cache_release_cb(void * entry, void * user_data); +static void outline_iter_cb(void * user_data, uint8_t op_code, const float * data, uint32_t len); +static void draw_letter_outline(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * dsc); #if LV_USE_FREETYPE static void freetype_outline_event_cb(lv_event_t * e); - static void draw_letter_outline(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * dsc); - static void outline_iter_cb(void * user_data, uint8_t op_code, const float * data, uint32_t len); #endif /* LV_USE_FREETYPE */ /********************** @@ -199,18 +201,10 @@ static void draw_letter_cb(lv_draw_task_t * t, lv_draw_glyph_dsc_t * glyph_draw_ } break; -#if LV_USE_FREETYPE - case LV_FONT_GLYPH_FORMAT_VECTOR: { - if(lv_freetype_is_outline_font(glyph_draw_dsc->g->resolved_font)) { - if(!glyph_draw_dsc->glyph_data) { - return; - } + case LV_FONT_GLYPH_FORMAT_VECTOR: + draw_letter_outline(t, glyph_draw_dsc); - draw_letter_outline(t, glyph_draw_dsc); - } - } break; -#endif /* LV_USE_FREETYPE */ case LV_FONT_GLYPH_FORMAT_IMAGE: { glyph_draw_dsc->glyph_data = lv_font_get_glyph_bitmap(glyph_draw_dsc->g, glyph_draw_dsc->_draw_buf); @@ -275,7 +269,7 @@ static inline void convert_letter_matrix(vg_lite_matrix_t * matrix, const lv_dra } static bool draw_letter_clip_areas(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * dsc, lv_area_t * letter_area, - lv_area_t * cliped_area) + lv_area_t * clipped_area) { *letter_area = *dsc->letter_coords; @@ -296,7 +290,7 @@ static bool draw_letter_clip_areas(lv_draw_task_t * t, const lv_draw_glyph_dsc_t lv_area_move(letter_area, dsc->letter_coords->x1, dsc->letter_coords->y1); } - if(!lv_area_intersect(cliped_area, &t->clip_area, letter_area)) { + if(!lv_area_intersect(clipped_area, &t->clip_area, letter_area)) { return false; } @@ -400,7 +394,6 @@ static void bitmap_cache_release_cb(void * entry, void * user_data) lv_font_glyph_release_draw_data(g_dsc); } -#if LV_USE_FREETYPE static void draw_letter_outline(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * dsc) { @@ -419,21 +412,25 @@ static void draw_letter_outline(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * path_clip_area.x2++; path_clip_area.y2++; - lv_vg_lite_path_t * outline = (lv_vg_lite_path_t *)dsc->glyph_data; + lv_vg_lite_path_t * outline = (void *)dsc->glyph_data; const lv_point_t glyph_pos = { dsc->letter_coords->x1 - dsc->g->ofs_x, dsc->letter_coords->y1 + dsc->g->box_h + dsc->g->ofs_y }; /* scale size */ - const float scale = FT_F26DOT6_TO_PATH_SCALE(lv_freetype_outline_get_scale(dsc->g->resolved_font)); - - const bool has_rotation_with_cliped = dsc->rotation && !lv_area_is_in(&letter_area, &t->clip_area, false); + float scale = 1.0; +#if LV_USE_FREETYPE + if(lv_freetype_is_outline_font(dsc->g->resolved_font)) { + scale = FT_F26DOT6_TO_PATH_SCALE(lv_freetype_outline_get_scale(dsc->g->resolved_font)); + } +#endif + const bool has_rotation_with_clipped = dsc->rotation && !lv_area_is_in(&letter_area, &t->clip_area, false); /* calc convert matrix */ vg_lite_matrix_t matrix; vg_lite_identity(&matrix); - if(!has_rotation_with_cliped && dsc->rotation) { + if(!has_rotation_with_clipped && dsc->rotation) { vg_lite_translate(glyph_pos.x + dsc->pivot.x, glyph_pos.y, &matrix); vg_lite_rotate(dsc->rotation / 10.0f, &matrix); vg_lite_translate(-dsc->pivot.x, 0, &matrix); @@ -457,12 +454,13 @@ static void draw_letter_outline(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * return; } - const lv_point_precise_t p1 = { path_clip_area.x1, path_clip_area.y1 }; + const int32_t stroke_width_scaled = (int32_t)(dsc->outline_stroke_width / scale); + const lv_point_precise_t p1 = { path_clip_area.x1 - stroke_width_scaled, path_clip_area.y1 - stroke_width_scaled }; const lv_point_precise_t p1_res = lv_vg_lite_matrix_transform_point(&result, &p1); - const lv_point_precise_t p2 = { path_clip_area.x2, path_clip_area.y2 }; + const lv_point_precise_t p2 = { path_clip_area.x2 + stroke_width_scaled, path_clip_area.y2 + stroke_width_scaled }; const lv_point_precise_t p2_res = lv_vg_lite_matrix_transform_point(&result, &p2); - if(has_rotation_with_cliped) { + if(has_rotation_with_clipped) { /** * When intersecting the clipping region, * rotate the path contents without rotating the bounding box for cropping @@ -497,10 +495,10 @@ static void draw_letter_outline(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * if(dsc->rotation) { /* The bounding rectangle before scaling relative to the original coordinates of the path */ lv_area_t box_area; - box_area.x1 = dsc->g->ofs_x; - box_area.y1 = -dsc->g->box_h - dsc->g->ofs_y; - lv_area_set_width(&box_area, dsc->g->box_w); - lv_area_set_height(&box_area, dsc->g->box_h); + box_area.x1 = dsc->g->ofs_x - stroke_width_scaled; + box_area.y1 = -dsc->g->box_h - dsc->g->ofs_y - stroke_width_scaled; + lv_area_set_width(&box_area, dsc->g->box_w + stroke_width_scaled * 2); + lv_area_set_height(&box_area, dsc->g->box_h + stroke_width_scaled * 2); /* Workaround for loss of rotation precision */ lv_area_increase(&box_area, 5, 5); @@ -516,6 +514,33 @@ static void draw_letter_outline(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * lv_vg_lite_path_set_bounding_box(outline, p1_res.x, p2_res.y, p2_res.x, p1_res.y); } + + vg_lite_path_t * vg_path = lv_vg_lite_path_get_path(outline); + if(stroke_width_scaled > 0) { + /*Set the stroke and update the path type */ + LV_VG_LITE_CHECK_ERROR(vg_lite_set_stroke(vg_path, + VG_LITE_CAP_ROUND, VG_LITE_JOIN_ROUND, stroke_width_scaled, 1.0, + NULL, 0, 0, + lv_vg_lite_color(dsc->outline_stroke_color, dsc->outline_stroke_opa, true)), {}); + + LV_VG_LITE_CHECK_ERROR(vg_lite_set_path_type(vg_path, VG_LITE_DRAW_STROKE_PATH), {}); + LV_VG_LITE_CHECK_ERROR(vg_lite_update_stroke(vg_path), {}); + + /*Draw the stroke (transparent fill)*/ + lv_vg_lite_draw( + &u->target_buffer, + vg_path, + VG_LITE_FILL_NON_ZERO, + &draw_matrix, + VG_LITE_BLEND_SRC_OVER, + lv_vg_lite_color(dsc->color, 0, true)); + + /*Restore the path to fill mode, it will release the local memory allocated for the stroke op */ + LV_VG_LITE_CHECK_ERROR(vg_lite_set_draw_path_type(vg_path, VG_LITE_DRAW_FILL_PATH), {}); + + } + + LV_VG_LITE_CHECK_ERROR(vg_lite_set_path_type(lv_vg_lite_path_get_path(outline), VG_LITE_DRAW_FILL_PATH), {}); lv_vg_lite_draw( &u->target_buffer, lv_vg_lite_path_get_path(outline), @@ -524,67 +549,7 @@ static void draw_letter_outline(lv_draw_task_t * t, const lv_draw_glyph_dsc_t * VG_LITE_BLEND_SRC_OVER, lv_vg_lite_color(dsc->color, dsc->opa, true)); - LV_PROFILER_DRAW_END; -} -static void vg_lite_outline_push(const lv_freetype_outline_event_param_t * param) -{ - LV_PROFILER_DRAW_BEGIN; - lv_vg_lite_path_t * outline = param->outline; - LV_ASSERT_NULL(outline); - - lv_freetype_outline_type_t type = param->type; - switch(type) { - - /** - * Reverse the Y-axis coordinate direction to achieve - * the conversion from Cartesian coordinate system to LCD coordinate system - */ - case LV_FREETYPE_OUTLINE_END: - lv_vg_lite_path_end(outline); - break; - case LV_FREETYPE_OUTLINE_MOVE_TO: - lv_vg_lite_path_move_to(outline, param->to.x, -param->to.y); - break; - case LV_FREETYPE_OUTLINE_LINE_TO: - lv_vg_lite_path_line_to(outline, param->to.x, -param->to.y); - break; - case LV_FREETYPE_OUTLINE_CUBIC_TO: - lv_vg_lite_path_cubic_to(outline, param->control1.x, -param->control1.y, - param->control2.x, -param->control2.y, - param->to.x, -param->to.y); - break; - case LV_FREETYPE_OUTLINE_CONIC_TO: - lv_vg_lite_path_quad_to(outline, param->control1.x, -param->control1.y, - param->to.x, -param->to.y); - break; - default: - LV_LOG_ERROR("unknown point type: %d", type); - LV_ASSERT(false); - break; - } - LV_PROFILER_DRAW_END; -} - -static void freetype_outline_event_cb(lv_event_t * e) -{ - LV_PROFILER_DRAW_BEGIN; - lv_event_code_t code = lv_event_get_code(e); - lv_freetype_outline_event_param_t * param = lv_event_get_param(e); - switch(code) { - case LV_EVENT_CREATE: - param->outline = lv_vg_lite_path_create(PATH_DATA_COORD_FORMAT); - break; - case LV_EVENT_DELETE: - lv_vg_lite_path_destroy(param->outline); - break; - case LV_EVENT_INSERT: - vg_lite_outline_push(param); - break; - default: - LV_LOG_WARN("unknown event code: %d", code); - break; - } LV_PROFILER_DRAW_END; } @@ -624,6 +589,71 @@ static void outline_iter_cb(void * user_data, uint8_t op_code, const float * dat } } + +#if LV_USE_FREETYPE + +static void vg_lite_outline_push(const lv_freetype_outline_event_param_t * param) +{ + LV_PROFILER_DRAW_BEGIN; + lv_vg_lite_path_t * path = param->outline; + LV_ASSERT_NULL(path); + + lv_freetype_outline_type_t type = param->type; + switch(type) { + + /** + * Reverse the Y-axis coordinate direction to achieve + * the conversion from Cartesian coordinate system to LCD coordinate system + */ + case LV_FREETYPE_OUTLINE_END: + lv_vg_lite_path_end(path); + break; + case LV_FREETYPE_OUTLINE_MOVE_TO: + lv_vg_lite_path_move_to(path, param->to.x, -param->to.y); + break; + case LV_FREETYPE_OUTLINE_LINE_TO: + lv_vg_lite_path_line_to(path, param->to.x, -param->to.y); + break; + case LV_FREETYPE_OUTLINE_CUBIC_TO: + lv_vg_lite_path_cubic_to(path, param->control1.x, -param->control1.y, + param->control2.x, -param->control2.y, + param->to.x, -param->to.y); + break; + case LV_FREETYPE_OUTLINE_CONIC_TO: + lv_vg_lite_path_quad_to(path, param->control1.x, -param->control1.y, + param->to.x, -param->to.y); + break; + default: + LV_LOG_ERROR("unknown point type: %d", type); + LV_ASSERT(false); + break; + } + LV_PROFILER_DRAW_END; +} + +static void freetype_outline_event_cb(lv_event_t * e) +{ + LV_PROFILER_DRAW_BEGIN; + lv_event_code_t code = lv_event_get_code(e); + lv_freetype_outline_event_param_t * param = lv_event_get_param(e); + switch(code) { + case LV_EVENT_CREATE: + param->outline = lv_vg_lite_path_create(PATH_DATA_COORD_FORMAT); + break; + case LV_EVENT_DELETE: + if(param->outline) lv_vg_lite_path_destroy(param->outline); + break; + case LV_EVENT_INSERT: + vg_lite_outline_push(param); + break; + default: + LV_LOG_WARN("unknown event code: %d", code); + break; + } + LV_PROFILER_DRAW_END; +} + + #endif /* LV_USE_FREETYPE */ #endif /*LV_USE_DRAW_VG_LITE*/ diff --git a/src/libs/freetype/lv_freetype.h b/src/libs/freetype/lv_freetype.h index 98837e5eaa..ac4ab73f9c 100755 --- a/src/libs/freetype/lv_freetype.h +++ b/src/libs/freetype/lv_freetype.h @@ -58,7 +58,6 @@ typedef enum { LV_FREETYPE_OUTLINE_LINE_TO, LV_FREETYPE_OUTLINE_CUBIC_TO, LV_FREETYPE_OUTLINE_CONIC_TO, - LV_FREETYPE_OUTLINE_BORDER_START, /* When line width > 0 the border glyph is drawn after the regular glyph */ } lv_freetype_outline_type_t; /* Only path string is required */ diff --git a/src/libs/freetype/lv_freetype_outline.c b/src/libs/freetype/lv_freetype_outline.c index f7d5edbd0d..bd0fe9d3d0 100755 --- a/src/libs/freetype/lv_freetype_outline.c +++ b/src/libs/freetype/lv_freetype_outline.c @@ -33,7 +33,7 @@ typedef struct _lv_freetype_outline_node_t { **********************/ static lv_freetype_outline_t outline_create(lv_freetype_context_t * ctx, FT_Face face, FT_UInt glyph_index, - uint32_t size, uint32_t strength, uint32_t border_width); + uint32_t size, uint32_t strength); static lv_result_t outline_delete(lv_freetype_context_t * ctx, lv_freetype_outline_t outline); static const void * freetype_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf); static void freetype_release_glyph_cb(const lv_font_t * font, lv_font_glyph_dsc_t * g_dsc); @@ -103,7 +103,7 @@ bool lv_freetype_is_outline_font(const lv_font_t * font) { LV_ASSERT_NULL(font); const lv_freetype_font_dsc_t * dsc = font->dsc; - if(!LV_FREETYPE_FONT_DSC_HAS_MAGIC_NUM(dsc)) { + if(!dsc || !LV_FREETYPE_FONT_DSC_HAS_MAGIC_NUM(dsc)) { return false; } @@ -128,8 +128,7 @@ static bool freetype_glyph_outline_create_cb(lv_freetype_outline_node_t * node, dsc->cache_node->face, node->glyph_index, dsc->cache_node->ref_size, - dsc->style & LV_FREETYPE_FONT_STYLE_BOLD ? 1 : 0, - dsc->outline_stroke_width); + dsc->style & LV_FREETYPE_FONT_STYLE_BOLD ? 1 : 0); lv_mutex_unlock(&dsc->cache_node->face_lock); if(!outline) { @@ -170,8 +169,6 @@ static const void * freetype_get_glyph_bitmap_cb(lv_font_glyph_dsc_t * g_dsc, lv lv_freetype_font_dsc_t * dsc = (lv_freetype_font_dsc_t *)font->dsc; LV_ASSERT_FREETYPE_FONT_DSC(dsc); - dsc->outline_stroke_width = g_dsc->outline_stroke_width; - lv_cache_entry_t * entry = lv_freetype_outline_lookup(dsc, (FT_UInt)g_dsc->gid.index); if(entry == NULL) { @@ -305,14 +302,11 @@ static lv_freetype_outline_t outline_create( FT_Face face, FT_UInt glyph_index, uint32_t size, - uint32_t strength, - uint32_t border_width) + uint32_t strength) { LV_PROFILER_FONT_BEGIN; LV_ASSERT_NULL(ctx); FT_Error error; - FT_Glyph glyph; - FT_Stroker stroker; error = FT_Set_Pixel_Sizes(face, 0, size); if(error) { @@ -365,104 +359,62 @@ static lv_freetype_outline_t outline_create( return NULL; } - /* 1 iteration if there is no border */ - /* 2 iterations if there is a a border and the glyph itsef */ - for(int i = 0; i < (border_width > 0 ? 2 : 1); i++) { + FT_Outline glyph_outline; + /* decompose glyph */ + glyph_outline = face->glyph->outline; - FT_Outline glyph_outline; + /*Calculate Total Segments Before decompose */ + int32_t tag_size = glyph_outline.n_points; + int32_t segments = 0; + int32_t vectors = 0; - if(i == 1) { - - /* decompose the border glyph */ - FT_Stroker_New(ctx->library, &stroker); - FT_Stroker_Set(stroker, border_width * 64, - FT_STROKER_LINECAP_ROUND, - FT_STROKER_LINEJOIN_ROUND, - 0); - - FT_Get_Glyph(face->glyph, &glyph); - FT_Glyph_StrokeBorder(&glyph, stroker, 0, true); - FT_OutlineGlyph g = (FT_OutlineGlyph) glyph; - - FT_Stroker_Done(stroker); - - glyph_outline = g->outline; - - } - else { - - /* decompose glyph */ - glyph_outline = face->glyph->outline; - } - - /*Calculate Total Segments Before decompose */ - int32_t tag_size = glyph_outline.n_points; - int32_t segments = 0; - int32_t vectors = 0; - - for(int j = 0; j < tag_size; j++) { + for(int j = 0; j < tag_size; j++) { #if 0 - if(j == 0 && (glyph_outline.tags[j] & 0x1) == 0) { - /* TODO handle the case where the first point is 'off curve' */ -https://stackoverflow.com/questions/3465809/how-to-interpret-a-freetype-glyph-outline-when-the-first-point-on-the-contour-is - } + if(j == 0 && (glyph_outline.tags[j] & 0x1) == 0) { + /* TODO handle the case where the first point is 'off curve' + https://stackoverflow.com/questions/3465809/how-to-interpret-a-freetype-glyph-outline-when-the-first-point-on-the-contour-is */ + } #endif - if((glyph_outline.tags[j] & 0x1) == 0x1) { - segments++; + if((glyph_outline.tags[j] & 0x1) == 0x1) { + segments++; + vectors++; + } + else { + int jj = j + 1 < tag_size ? j + 1 : 0; + if(glyph_outline.tags[jj] & 0x1) { vectors++; } else { - int jj = j + 1 < tag_size ? j + 1 : 0; - if(glyph_outline.tags[jj] & 0x1) { - vectors++; - } - else { - segments++; - vectors += 2; - } + segments++; + vectors += 2; } } + } - /*Also for every contour we may have a line for close*/ - segments += glyph_outline.n_contours; - vectors += glyph_outline.n_contours; + /*Also for every contour we may have a line for close*/ + segments += glyph_outline.n_contours; + vectors += glyph_outline.n_contours; - param.sizes.data_size = vectors * 2; - param.sizes.segments_size = segments; + param.sizes.data_size = vectors * 2; + param.sizes.segments_size = segments; - /* Run outline decompose again to fill outline data */ - error = FT_Outline_Decompose(&glyph_outline, &outline_funcs, outline); - if(error) { - FT_ERROR_MSG("FT_Outline_Decompose", error); - outline_delete(ctx, outline); - LV_PROFILER_FONT_END; - return NULL; - } + /* Run outline decompose again to fill outline data */ + error = FT_Outline_Decompose(&glyph_outline, &outline_funcs, outline); + if(error) { + FT_ERROR_MSG("FT_Outline_Decompose", error); + outline_delete(ctx, outline); + LV_PROFILER_FONT_END; + return NULL; + } - if(i == 0 && border_width > 0) { - - /* Close the border glyph before decomposing the inside glyph */ - res = outline_push_point(outline, LV_FREETYPE_OUTLINE_BORDER_START, NULL, NULL, NULL); - if(res != LV_RESULT_OK) { - LV_LOG_ERROR("Outline object close failed"); - outline_delete(ctx, outline); - LV_PROFILER_FONT_END; - return NULL; - } - - } - else if(i == 0 || (i == 1 && border_width > 0)) { - - /* Close the border glyph or the regular glyph */ - res = outline_push_point(outline, LV_FREETYPE_OUTLINE_END, NULL, NULL, NULL); - if(res != LV_RESULT_OK) { - LV_LOG_ERROR("Outline object close failed"); - outline_delete(ctx, outline); - LV_PROFILER_FONT_END; - return NULL; - } - } + /* Close the border glyph or the regular glyph */ + res = outline_push_point(outline, LV_FREETYPE_OUTLINE_END, NULL, NULL, NULL); + if(res != LV_RESULT_OK) { + LV_LOG_ERROR("Outline object close failed"); + outline_delete(ctx, outline); + LV_PROFILER_FONT_END; + return NULL; } LV_PROFILER_FONT_END; diff --git a/src/libs/freetype/lv_freetype_private.h b/src/libs/freetype/lv_freetype_private.h index 86c314e973..b87e947d43 100755 --- a/src/libs/freetype/lv_freetype_private.h +++ b/src/libs/freetype/lv_freetype_private.h @@ -121,7 +121,6 @@ typedef struct _lv_freetype_font_dsc_t { lv_freetype_cache_node_t * cache_node; lv_cache_entry_t * cache_node_entry; FTC_FaceID face_id; - uint32_t outline_stroke_width; lv_font_kerning_t kerning; } lv_freetype_font_dsc_t; diff --git a/tests/ref_imgs/libs/freetype_render_outline.lp32.png b/tests/ref_imgs/libs/freetype_render_outline.lp32.png new file mode 100644 index 0000000000..7e6c7f3914 Binary files /dev/null and b/tests/ref_imgs/libs/freetype_render_outline.lp32.png differ diff --git a/tests/ref_imgs/libs/freetype_render_outline.lp64.png b/tests/ref_imgs/libs/freetype_render_outline.lp64.png new file mode 100644 index 0000000000..b1e0170291 Binary files /dev/null and b/tests/ref_imgs/libs/freetype_render_outline.lp64.png differ diff --git a/tests/ref_imgs_vg_lite/libs/freetype_render_outline.lp32.png b/tests/ref_imgs_vg_lite/libs/freetype_render_outline.lp32.png new file mode 100644 index 0000000000..80ff389c74 Binary files /dev/null and b/tests/ref_imgs_vg_lite/libs/freetype_render_outline.lp32.png differ diff --git a/tests/ref_imgs_vg_lite/libs/freetype_render_outline.lp64.png b/tests/ref_imgs_vg_lite/libs/freetype_render_outline.lp64.png new file mode 100644 index 0000000000..e7041a7930 Binary files /dev/null and b/tests/ref_imgs_vg_lite/libs/freetype_render_outline.lp64.png differ diff --git a/tests/ref_imgs_vg_lite/libs/freetype_render_outline.png b/tests/ref_imgs_vg_lite/libs/freetype_render_outline.png deleted file mode 100644 index 176265da58..0000000000 Binary files a/tests/ref_imgs_vg_lite/libs/freetype_render_outline.png and /dev/null differ diff --git a/tests/src/test_cases/libs/test_freetype.c b/tests/src/test_cases/libs/test_freetype.c index 9d47e3bcf7..84767e190f 100644 --- a/tests/src/test_cases/libs/test_freetype.c +++ b/tests/src/test_cases/libs/test_freetype.c @@ -27,365 +27,6 @@ static const char * UNIVERSAL_DECLARATION_OF_HUMAN_RIGHTS_EN = static const char * UNIVERSAL_DECLARATION_OF_HUMAN_RIGHTS_JP = "人間の家族のすべての構成員の固有の尊厳と平等で譲渡不能な権利とを承認することは、自由と正義と平和の基礎である..."; -// Outline data for unicode '龘' (U+9F98) -static const lv_freetype_outline_event_param_t outline_data_U9F98[] = { - {NULL, 1, {5888, 6889}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6445, 6889}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6238, 5915}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5681, 5915}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5888, 6889}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {2069, 5145}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4576, 5145}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4508, 4825}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2525, 4825}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2178, 3195}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {1654, 3195}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2069, 5145}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {5714, 6070}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {8573, 6070}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {8401, 5259}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5542, 5259}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5606, 5562}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {7916, 5562}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {7962, 5775}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5652, 5775}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5714, 6070}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {5580, 5439}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6137, 5439}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5786, 3785}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {5832, 3600}, {5756, 3645}, {0, 0}, {0, 0}}, - {NULL, 4, {6195, 3555}, {5909, 3555}, {0, 0}, {0, 0}}, - {NULL, 4, {6461, 3555}, {6261, 3555}, {0, 0}, {0, 0}}, - {NULL, 4, {6904, 3555}, {6662, 3555}, {0, 0}, {0, 0}}, - {NULL, 4, {7359, 3555}, {7146, 3555}, {0, 0}, {0, 0}}, - {NULL, 4, {7670, 3555}, {7572, 3555}, {0, 0}, {0, 0}}, - {NULL, 4, {7880, 3579}, {7801, 3555}, {0, 0}, {0, 0}}, - {NULL, 4, {8010, 3690}, {7959, 3604}, {0, 0}, {0, 0}}, - {NULL, 4, {8107, 3957}, {8061, 3777}, {0, 0}, {0, 0}}, - {NULL, 4, {8305, 3887}, {8188, 3916}, {0, 0}, {0, 0}}, - {NULL, 4, {8526, 3842}, {8422, 3858}, {0, 0}, {0, 0}}, - {NULL, 4, {8238, 3359}, {8416, 3482}, {0, 0}, {0, 0}}, - {NULL, 4, {7668, 3236}, {8061, 3236}, {0, 0}, {0, 0}}, - {NULL, 4, {7446, 3236}, {7610, 3236}, {0, 0}, {0, 0}}, - {NULL, 4, {7074, 3236}, {7283, 3236}, {0, 0}, {0, 0}}, - {NULL, 4, {6656, 3236}, {6865, 3236}, {0, 0}, {0, 0}}, - {NULL, 4, {6287, 3236}, {6447, 3236}, {0, 0}, {0, 0}}, - {NULL, 4, {6078, 3236}, {6127, 3236}, {0, 0}, {0, 0}}, - {NULL, 4, {5345, 3334}, {5538, 3236}, {0, 0}, {0, 0}}, - {NULL, 4, {5230, 3793}, {5153, 3432}, {0, 0}, {0, 0}}, - {NULL, 2, {5580, 5439}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {4305, 6185}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4756, 6038}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {4494, 5726}, {4616, 5874}, {0, 0}, {0, 0}}, - {NULL, 4, {4258, 5464}, {4373, 5579}, {0, 0}, {0, 0}}, - {NULL, 2, {3901, 5595}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {4120, 5894}, {4002, 5726}, {0, 0}, {0, 0}}, - {NULL, 4, {4305, 6185}, {4238, 6062}, {0, 0}, {0, 0}}, - {NULL, 1, {2506, 6046}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2941, 6169}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {3051, 5894}, {3014, 6046}, {0, 0}, {0, 0}}, - {NULL, 4, {3088, 5628}, {3089, 5743}, {0, 0}, {0, 0}}, - {NULL, 2, {2610, 5497}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {2584, 5763}, {2616, 5603}, {0, 0}, {0, 0}}, - {NULL, 4, {2506, 6046}, {2553, 5923}, {0, 0}, {0, 0}}, - {NULL, 1, {4322, 5145}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4846, 5145}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4515, 3588}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {4421, 3362}, {4481, 3432}, {0, 0}, {0, 0}}, - {NULL, 4, {4238, 3252}, {4362, 3293}, {0, 0}, {0, 0}}, - {NULL, 4, {3912, 3203}, {4115, 3211}, {0, 0}, {0, 0}}, - {NULL, 4, {3423, 3195}, {3710, 3195}, {0, 0}, {0, 0}}, - {NULL, 4, {3409, 3359}, {3433, 3277}, {0, 0}, {0, 0}}, - {NULL, 4, {3358, 3506}, {3385, 3441}, {0, 0}, {0, 0}}, - {NULL, 4, {3677, 3506}, {3530, 3506}, {0, 0}, {0, 0}}, - {NULL, 4, {3874, 3506}, {3825, 3506}, {0, 0}, {0, 0}}, - {NULL, 4, {3956, 3522}, {3932, 3506}, {0, 0}, {0, 0}}, - {NULL, 4, {3991, 3588}, {3980, 3539}, {0, 0}, {0, 0}}, - {NULL, 2, {4322, 5145}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {6071, 6595}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {8988, 6595}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {8923, 6291}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6006, 6291}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6071, 6595}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {5732, 5038}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {8190, 5038}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {8132, 4768}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5674, 4768}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5732, 5038}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {5646, 4555}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {8046, 4555}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {7987, 4276}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5587, 4276}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5646, 4555}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {5523, 4055}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {8046, 4055}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {7989, 3785}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5466, 3785}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5523, 4055}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {2081, 4047}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4350, 4047}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4288, 3752}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2019, 3752}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2081, 4047}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {2196, 4588}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4465, 4588}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4402, 4293}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2133, 4293}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2196, 4588}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {2066, 6447}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5351, 6447}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5284, 6128}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {1999, 6128}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2066, 6447}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {1689, 5710}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5433, 5710}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5365, 5390}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {1621, 5390}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {1689, 5710}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {3383, 6824}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {3903, 6914}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {4030, 6607}, {3973, 6783}, {0, 0}, {0, 0}}, - {NULL, 4, {4110, 6308}, {4087, 6431}, {0, 0}, {0, 0}}, - {NULL, 2, {3568, 6185}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {3507, 6500}, {3554, 6316}, {0, 0}, {0, 0}}, - {NULL, 4, {3383, 6824}, {3461, 6685}, {0, 0}, {0, 0}}, - {NULL, 1, {3008, 3129}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {3377, 3129}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {3168, 2146}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2799, 2146}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {3008, 3129}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {860, 1425}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2163, 1425}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2095, 1106}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {1136, 1106}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {776, -590}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {432, -590}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {860, 1425}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {2834, 2310}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4317, 2310}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4143, 1491}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2660, 1491}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2723, 1786}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {3853, 1786}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {3901, 2015}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2771, 2015}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2834, 2310}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {2703, 1696}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {3063, 1696}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2698, -25}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {2705, -184}, {2672, -147}, {0, 0}, {0, 0}}, - {NULL, 4, {2869, -221}, {2738, -221}, {0, 0}, {0, 0}}, - {NULL, 4, {3045, -221}, {2919, -221}, {0, 0}, {0, 0}}, - {NULL, 4, {3311, -221}, {3172, -221}, {0, 0}, {0, 0}}, - {NULL, 4, {3500, -221}, {3451, -221}, {0, 0}, {0, 0}}, - {NULL, 4, {3659, -147}, {3607, -221}, {0, 0}, {0, 0}}, - {NULL, 4, {3776, 188}, {3711, -74}, {0, 0}, {0, 0}}, - {NULL, 4, {3899, 114}, {3824, 147}, {0, 0}, {0, 0}}, - {NULL, 4, {4044, 66}, {3974, 82}, {0, 0}, {0, 0}}, - {NULL, 4, {3826, -418}, {3951, -295}, {0, 0}, {0, 0}}, - {NULL, 4, {3473, -541}, {3702, -541}, {0, 0}, {0, 0}}, - {NULL, 4, {3346, -541}, {3449, -541}, {0, 0}, {0, 0}}, - {NULL, 4, {3121, -541}, {3244, -541}, {0, 0}, {0, 0}}, - {NULL, 4, {2899, -541}, {2998, -541}, {0, 0}, {0, 0}}, - {NULL, 4, {2769, -541}, {2801, -541}, {0, 0}, {0, 0}}, - {NULL, 4, {2366, -446}, {2465, -541}, {0, 0}, {0, 0}}, - {NULL, 4, {2338, -25}, {2268, -352}, {0, 0}, {0, 0}}, - {NULL, 2, {2703, 1696}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {2189, 2474}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2462, 2335}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {2225, 2031}, {2337, 2171}, {0, 0}, {0, 0}}, - {NULL, 4, {2019, 1794}, {2114, 1892}, {0, 0}, {0, 0}}, - {NULL, 2, {1800, 1917}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {2003, 2199}, {1892, 2040}, {0, 0}, {0, 0}}, - {NULL, 4, {2189, 2474}, {2115, 2359}, {0, 0}, {0, 0}}, - {NULL, 1, {1134, 2367}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {1451, 2433}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {1517, 2166}, {1492, 2318}, {0, 0}, {0, 0}}, - {NULL, 4, {1543, 1901}, {1542, 2015}, {0, 0}, {0, 0}}, - {NULL, 2, {1204, 1810}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {1196, 2080}, {1212, 1925}, {0, 0}, {0, 0}}, - {NULL, 4, {1134, 2367}, {1180, 2236}, {0, 0}, {0, 0}}, - {NULL, 1, {2015, 1425}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2367, 1425}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2022, -197}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {1941, -426}, {1989, -352}, {0, 0}, {0, 0}}, - {NULL, 4, {1794, -541}, {1893, -500}, {0, 0}, {0, 0}}, - {NULL, 4, {1551, -586}, {1703, -582}, {0, 0}, {0, 0}}, - {NULL, 4, {1169, -590}, {1399, -590}, {0, 0}, {0, 0}}, - {NULL, 4, {1166, -430}, {1176, -516}, {0, 0}, {0, 0}}, - {NULL, 4, {1139, -270}, {1156, -344}, {0, 0}, {0, 0}}, - {NULL, 4, {1415, -279}, {1293, -279}, {0, 0}, {0, 0}}, - {NULL, 4, {1579, -279}, {1538, -279}, {0, 0}, {0, 0}}, - {NULL, 4, {1670, -197}, {1653, -279}, {0, 0}, {0, 0}}, - {NULL, 2, {2015, 1425}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {3108, 2826}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4492, 2826}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4429, 2531}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {3045, 2531}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {3108, 2826}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {2779, 1278}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4016, 1278}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {3958, 1008}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2721, 1008}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2779, 1278}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {2674, 786}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {3919, 786}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {3862, 516}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2617, 516}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2674, 786}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {2570, 295}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {3692, 295}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {3632, 16}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2510, 16}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2570, 295}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {791, 328}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {1946, 328}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {1883, 33}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {728, 33}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {791, 328}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {905, 868}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2060, 868}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {1998, 573}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {843, 573}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {905, 868}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {1016, 2736}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2769, 2736}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2701, 2417}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {948, 2417}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {1016, 2736}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {739, 1974}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2640, 1974}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2570, 1647}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {669, 1647}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {739, 1974}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {1666, 3056}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {2019, 3138}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {2100, 2887}, {2069, 3031}, {0, 0}, {0, 0}}, - {NULL, 4, {2142, 2638}, {2131, 2744}, {0, 0}, {0, 0}}, - {NULL, 2, {1756, 2515}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {1729, 2777}, {1755, 2630}, {0, 0}, {0, 0}}, - {NULL, 4, {1666, 3056}, {1703, 2925}, {0, 0}, {0, 0}}, - {NULL, 1, {6779, 3105}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {7156, 3105}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6949, 2130}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6572, 2130}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6779, 3105}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {4558, 1401}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5901, 1401}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5833, 1081}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4842, 1081}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4481, -614}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4129, -614}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4558, 1401}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {6605, 2286}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {8146, 2286}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {7974, 1475}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6433, 1475}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6495, 1769}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {7667, 1769}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {7716, 1999}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6544, 1999}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6605, 2286}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {6474, 1671}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6851, 1671}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6482, -66}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {6491, -217}, {6456, -188}, {0, 0}, {0, 0}}, - {NULL, 4, {6665, -246}, {6526, -246}, {0, 0}, {0, 0}}, - {NULL, 4, {6837, -246}, {6706, -246}, {0, 0}, {0, 0}}, - {NULL, 4, {7112, -246}, {6969, -246}, {0, 0}, {0, 0}}, - {NULL, 4, {7313, -246}, {7255, -246}, {0, 0}, {0, 0}}, - {NULL, 4, {7474, -176}, {7419, -246}, {0, 0}, {0, 0}}, - {NULL, 4, {7594, 156}, {7530, -106}, {0, 0}, {0, 0}}, - {NULL, 4, {7723, 86}, {7643, 115}, {0, 0}, {0, 0}}, - {NULL, 4, {7873, 41}, {7803, 57}, {0, 0}, {0, 0}}, - {NULL, 4, {7653, -450}, {7778, -328}, {0, 0}, {0, 0}}, - {NULL, 4, {7292, -573}, {7529, -573}, {0, 0}, {0, 0}}, - {NULL, 4, {7152, -573}, {7259, -573}, {0, 0}, {0, 0}}, - {NULL, 4, {6919, -573}, {7046, -573}, {0, 0}, {0, 0}}, - {NULL, 4, {6689, -573}, {6792, -573}, {0, 0}, {0, 0}}, - {NULL, 4, {6554, -573}, {6587, -573}, {0, 0}, {0, 0}}, - {NULL, 4, {6144, -479}, {6251, -573}, {0, 0}, {0, 0}}, - {NULL, 4, {6107, -57}, {6037, -385}, {0, 0}, {0, 0}}, - {NULL, 2, {6474, 1671}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {5928, 2449}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6217, 2310}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {5978, 2015}, {6094, 2154}, {0, 0}, {0, 0}}, - {NULL, 4, {5758, 1769}, {5863, 1876}, {0, 0}, {0, 0}}, - {NULL, 2, {5530, 1892}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {5742, 2175}, {5622, 2015}, {0, 0}, {0, 0}}, - {NULL, 4, {5928, 2449}, {5862, 2335}, {0, 0}, {0, 0}}, - {NULL, 1, {4834, 2351}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5157, 2408}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {5232, 2146}, {5208, 2302}, {0, 0}, {0, 0}}, - {NULL, 4, {5258, 1884}, {5256, 1991}, {0, 0}, {0, 0}}, - {NULL, 2, {4910, 1786}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {4894, 2060}, {4910, 1901}, {0, 0}, {0, 0}}, - {NULL, 4, {4834, 2351}, {4879, 2220}, {0, 0}, {0, 0}}, - {NULL, 1, {5746, 1401}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6106, 1401}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5763, -213}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {5684, -446}, {5728, -377}, {0, 0}, {0, 0}}, - {NULL, 4, {5541, -565}, {5641, -516}, {0, 0}, {0, 0}}, - {NULL, 4, {5280, -610}, {5433, -606}, {0, 0}, {0, 0}}, - {NULL, 4, {4891, -614}, {5128, -614}, {0, 0}, {0, 0}}, - {NULL, 4, {4888, -455}, {4899, -541}, {0, 0}, {0, 0}}, - {NULL, 4, {4852, -295}, {4878, -369}, {0, 0}, {0, 0}}, - {NULL, 4, {5138, -303}, {5007, -303}, {0, 0}, {0, 0}}, - {NULL, 4, {5311, -295}, {5269, -303}, {0, 0}, {0, 0}}, - {NULL, 4, {5401, -221}, {5385, -295}, {0, 0}, {0, 0}}, - {NULL, 2, {5746, 1401}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {6887, 2802}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {8313, 2802}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {8250, 2507}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6824, 2507}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6887, 2802}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {6549, 1253}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {7827, 1253}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {7770, 983}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6492, 983}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6549, 1253}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {6445, 762}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {7731, 762}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {7674, 492}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6388, 492}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6445, 762}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {6340, 270}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {7512, 270}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {7455, 0}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6283, 0}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6340, 270}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {4496, 303}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5692, 303}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5630, 8}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4434, 8}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4496, 303}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {4611, 844}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5807, 844}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5746, 557}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4550, 557}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4611, 844}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {4715, 2720}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6517, 2720}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6447, 2392}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4645, 2392}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4715, 2720}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {4428, 1950}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6394, 1950}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {6326, 1630}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4360, 1630}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {4428, 1950}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 1, {5370, 3023}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 2, {5739, 3105}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {5825, 2855}, {5790, 2998}, {0, 0}, {0, 0}}, - {NULL, 4, {5872, 2613}, {5860, 2712}, {0, 0}, {0, 0}}, - {NULL, 2, {5479, 2499}, {0, 0}, {0, 0}, {0, 0}}, - {NULL, 4, {5434, 2752}, {5469, 2605}, {0, 0}, {0, 0}}, - {NULL, 4, {5370, 3023}, {5400, 2900}, {0, 0}, {0, 0}}, - {NULL, 0, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, -}; - -static void freetype_outline_event_cb(lv_event_t * e); - #if OPTION_GENERATE_VECTOR_OPS_STRING static void vegravis_generate_vector_ops_string(lv_freetype_outline_event_param_t * param, char * buf, uint32_t buf_len); @@ -449,10 +90,13 @@ static void test_freetype_with_render_mode(lv_freetype_font_render_mode_t render lv_style_set_text_font(&style_italic, font_italic); lv_style_set_text_align(&style_italic, LV_TEXT_ALIGN_CENTER); - static lv_style_t style_normal; - lv_style_init(&style_normal); - lv_style_set_text_font(&style_normal, font_normal); - lv_style_set_text_align(&style_normal, LV_TEXT_ALIGN_CENTER); + static lv_style_t style_normal_with_outline; + lv_style_init(&style_normal_with_outline); + lv_style_set_text_font(&style_normal_with_outline, font_normal); + lv_style_set_text_align(&style_normal_with_outline, LV_TEXT_ALIGN_CENTER); + lv_style_set_text_outline_stroke_color(&style_normal_with_outline, lv_color_hex(0xff0000)); + lv_style_set_text_outline_stroke_width(&style_normal_with_outline, 4); + lv_style_set_text_outline_stroke_opa(&style_normal_with_outline, LV_OPA_50); static lv_style_t style_normal_small; lv_style_init(&style_normal_small); @@ -471,7 +115,7 @@ static void test_freetype_with_render_mode(lv_freetype_font_render_mode_t render lv_obj_align(label0, LV_ALIGN_TOP_MID, 0, 10); lv_obj_t * label1 = lv_label_create(lv_screen_active()); - lv_obj_add_style(label1, &style_normal, 0); + lv_obj_add_style(label1, &style_normal_with_outline, 0); lv_obj_set_width(label1, lv_obj_get_width(lv_screen_active()) - 20); lv_label_set_text(label1, UNIVERSAL_DECLARATION_OF_HUMAN_RIGHTS_EN); lv_obj_align_to(label1, label0, LV_ALIGN_OUT_BOTTOM_MID, 0, 10); @@ -496,7 +140,7 @@ static void test_freetype_with_render_mode(lv_freetype_font_render_mode_t render lv_obj_clean(lv_screen_active()); lv_style_reset(&style_italic); - lv_style_reset(&style_normal); + lv_style_reset(&style_normal_with_outline); lv_style_reset(&style_normal_small); lv_style_reset(&style_normal_emoji); lv_freetype_font_delete(font_italic); @@ -512,82 +156,7 @@ void test_freetype_render_bitmap(void) void test_freetype_render_outline(void) { -#if LV_USE_DRAW_VG_LITE - /* VG-Lite support rendering outline */ - test_freetype_with_render_mode(LV_FREETYPE_FONT_RENDER_MODE_OUTLINE, "libs/freetype_render_outline.png"); - LV_UNUSED(outline_data_U9F98); - LV_UNUSED(freetype_outline_event_cb); -#else - /* Outline rendering not supported, compare outline data only */ - /*Create a font*/ - lv_font_t * font_italic = lv_freetype_font_create("./src/test_files/fonts/noto/NotoSansSC-Regular.ttf", - LV_FREETYPE_FONT_RENDER_MODE_OUTLINE, - 24, - LV_FREETYPE_FONT_STYLE_ITALIC); - - TEST_ASSERT_NOT_NULL(font_italic); - - /*Setup outline event for generating outline drawing data*/ - lv_freetype_outline_add_event(freetype_outline_event_cb, LV_EVENT_ALL, NULL); - - lv_font_glyph_dsc_t g; - lv_font_get_glyph_dsc(font_italic, &g, 0x9F98, '\0'); - - const lv_ll_t * outline_data; - outline_data = (lv_ll_t *) lv_font_get_glyph_bitmap(&g, NULL); - - uint32_t i = 0; - lv_freetype_outline_event_param_t * param; - LV_LL_READ(outline_data, param) { -#if OPTION_GENERATE_OUTLINE_DATA - /*FOR Generate outline data*/ -#if OPTION_GENERATE_VECTOR_OPS_STRING - char buf[1024]; - vegravis_generate_vector_ops_string(param, buf, sizeof(buf)); - TEST_PRINTF("%s", buf); -#else - TEST_PRINTF("{NULL, %d, {%d, %d}, {%d, %d}, {%d, %d}}, ", param->type, param->to.x, param->to.y, param->control1.x, - param->control1.y, param->control2.x, param->control2.y); -#endif -#endif - TEST_ASSERT_EQUAL(param->type, outline_data_U9F98[i].type); - TEST_ASSERT_EQUAL(param->to.x, outline_data_U9F98[i].to.x); - TEST_ASSERT_EQUAL(param->to.y, outline_data_U9F98[i].to.y); - TEST_ASSERT_EQUAL(param->control1.x, outline_data_U9F98[i].control1.x); - TEST_ASSERT_EQUAL(param->control1.y, outline_data_U9F98[i].control1.y); - TEST_ASSERT_EQUAL(param->control2.x, outline_data_U9F98[i].control2.x); - TEST_ASSERT_EQUAL(param->control2.y, outline_data_U9F98[i].control2.y); - i++; - } - - font_italic->release_glyph(font_italic, &g); - - lv_freetype_font_delete(font_italic); -#endif -} - -static void freetype_outline_event_cb(lv_event_t * e) -{ - lv_event_code_t code = lv_event_get_code(e); - lv_freetype_outline_event_param_t * param = lv_event_get_param(e); - switch(code) { - case LV_EVENT_CREATE: - param->outline = lv_malloc_zeroed(sizeof(lv_ll_t)); - lv_ll_init(param->outline, sizeof(lv_freetype_outline_event_param_t)); - break; - case LV_EVENT_DELETE: - lv_ll_clear(param->outline); - lv_free(param->outline); - break; - case LV_EVENT_INSERT: { - void * entry = lv_ll_ins_tail(param->outline); - lv_memcpy(entry, param, sizeof(lv_freetype_outline_event_param_t)); - break; - } - default: - LV_LOG_WARN("unknown event code: %d", code); - break; - } + test_freetype_with_render_mode(LV_FREETYPE_FONT_RENDER_MODE_OUTLINE, "libs/freetype_render_outline" EXT_NAME); } #if OPTION_GENERATE_VECTOR_OPS_STRING