feat(freetype): support variable weight fonts (#9844)
Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com> Co-authored-by: AndyEveritt <38423143+AndyEveritt@users.noreply.github.com> Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
@@ -98,6 +98,17 @@ software, and can be set by using following values where style values are requir
|
||||
These values can be combined, e.g.
|
||||
<ApiLink name="LV_FREETYPE_FONT_STYLE_BOLD" display="LV_FREETYPE_FONT_STYLE_BOLD | LV_FREETYPE_FONT_STYLE_ITALIC" />.
|
||||
|
||||
<ApiLink name="LV_FREETYPE_FONT_STYLE_BOLD" /> is only supported with `LV_FREETYPE_FONT_RENDER_MODE_OUTLINE`,
|
||||
unless the font is variable weight.
|
||||
|
||||
Variable weight fonts are supported. You can set the weight of the font by using
|
||||
<ApiLink name="lv_freetype_font_create_with_info" /> and setting the `weight` field of
|
||||
<ApiLink name="lv_font_info_t" />. The weight value follows CSS conventions (1-2000,
|
||||
typical: 100-900 where 400 = normal, 700 = bold). If `weight` is 0 (default),
|
||||
the weight is determined by the style: <ApiLink name="LV_FREETYPE_FONT_STYLE_BOLD" />
|
||||
maps to 700, otherwise 400. If the font is not a variable weight font, the weight
|
||||
setting will have no effect.
|
||||
|
||||
The FreeType extension also supports colored bitmap glyphs such as emojis. Note
|
||||
that only bitmaps are supported at this time. Colored vector graphics cannot be
|
||||
rendered. An example on how to draw a colored bitmap glyph is shown below.
|
||||
|
||||
@@ -178,6 +178,7 @@ struct _lv_font_info_t {
|
||||
uint32_t size; /**< Font size in pixel*/
|
||||
uint32_t render_mode; /**< Font rendering mode, see `lv_freetype_font_render_mode_t`*/
|
||||
uint32_t style; /**< Font style, see `lv_freetype_font_style_t`*/
|
||||
int32_t weight; /**< Font weight for variable fonts (range 1-2000, CSS-like values 100-900; 0 = default: 400 normal, 700 if bold style) */
|
||||
lv_font_kerning_t kerning; /**< Font kerning, see `lv_font_kerning_t`*/
|
||||
};
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ typedef enum {
|
||||
LV_FREETYPE_OUTLINE_CONIC_TO,
|
||||
} lv_freetype_outline_type_t;
|
||||
|
||||
/* Only path string is required */
|
||||
/** Only path string is required */
|
||||
typedef const char lv_freetype_font_src_t;
|
||||
|
||||
LV_ATTRIBUTE_EXTERN_DATA extern const lv_font_class_t lv_freetype_font_class;
|
||||
@@ -101,7 +101,9 @@ lv_font_t * lv_freetype_font_create_with_info(const lv_font_info_t * font_info);
|
||||
* @param style font style(see lv_freetype_font_style_t for details).
|
||||
* @return Created font, or NULL on failure.
|
||||
*/
|
||||
lv_font_t * lv_freetype_font_create(const char * pathname, lv_freetype_font_render_mode_t render_mode, uint32_t size,
|
||||
lv_font_t * lv_freetype_font_create(const char * pathname,
|
||||
lv_freetype_font_render_mode_t render_mode,
|
||||
uint32_t size,
|
||||
lv_freetype_font_style_t style);
|
||||
|
||||
/**
|
||||
|
||||
@@ -390,9 +390,7 @@ static void freetype_outline_event_cb(lv_event_t * e)
|
||||
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
|
||||
*/
|
||||
/* It's not necessary to close the path */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -185,6 +185,7 @@ bool lv_font_info_is_equal(const lv_font_info_t * ft_info_1, const lv_font_info_
|
||||
bool is_equal = (ft_info_1->size == ft_info_2->size
|
||||
&& ft_info_1->style == ft_info_2->style
|
||||
&& ft_info_1->render_mode == ft_info_2->render_mode
|
||||
&& ft_info_1->weight == ft_info_2->weight
|
||||
&& ft_info_1->kerning == ft_info_2->kerning
|
||||
&& lv_strcmp(ft_info_1->name, ft_info_2->name) == 0);
|
||||
|
||||
|
||||
@@ -21,6 +21,20 @@
|
||||
#define ft_ctx LV_GLOBAL_DEFAULT()->ft_context
|
||||
#define LV_FREETYPE_OUTLINE_REF_SIZE_DEF 128
|
||||
|
||||
/* Temporary stack buffer size for variable-font axes.
|
||||
* Most fonts have only a few axes; use heap only when needed. */
|
||||
#define LV_FREETYPE_MAX_STACK_AXES 8
|
||||
|
||||
/* Clamp for requested variable font weight before converting to 16.16.
|
||||
* Fonts commonly use CSS-like 100..900, but some support extended ranges.
|
||||
* Keeping this bounded avoids unreasonable inputs and keeps conversion safe. */
|
||||
#define LV_FREETYPE_VAR_WEIGHT_MIN 1
|
||||
#define LV_FREETYPE_VAR_WEIGHT_MAX 2000
|
||||
|
||||
#define LV_FREETYPE_VAR_WEIGHT_DEFAULT 0 /**< 0 = resolved from style: NORMAL(400) or BOLD(700) */
|
||||
#define LV_FREETYPE_VAR_WEIGHT_NORMAL 400
|
||||
#define LV_FREETYPE_VAR_WEIGHT_BOLD 700
|
||||
|
||||
/**< This value is from the FreeType's function `FT_GlyphSlot_Oblique` in `ftsynth.c` */
|
||||
#define LV_FREETYPE_OBLIQUE_SLANT_DEF 0x0366A
|
||||
|
||||
@@ -51,6 +65,7 @@ static bool cache_node_cache_create_cb(lv_freetype_cache_node_t * node, void * u
|
||||
static void cache_node_cache_free_cb(lv_freetype_cache_node_t * node, void * user_data);
|
||||
static lv_cache_compare_res_t cache_node_cache_compare_cb(const lv_freetype_cache_node_t * lhs,
|
||||
const lv_freetype_cache_node_t * rhs);
|
||||
static bool lv_freetype_set_weight_if_variable(FT_Face face, int weight);
|
||||
|
||||
static lv_font_t * freetype_font_create_cb(const lv_font_info_t * info, const void * src);
|
||||
static void freetype_font_delete_cb(lv_font_t * font);
|
||||
@@ -135,6 +150,7 @@ void lv_freetype_init_font_info(lv_font_info_t * font_info)
|
||||
font_info->class_p = &lv_freetype_font_class;
|
||||
font_info->render_mode = LV_FREETYPE_FONT_RENDER_MODE_BITMAP;
|
||||
font_info->style = LV_FREETYPE_FONT_STYLE_NORMAL;
|
||||
font_info->weight = LV_FREETYPE_VAR_WEIGHT_DEFAULT;
|
||||
font_info->kerning = LV_FONT_KERNING_NONE;
|
||||
}
|
||||
|
||||
@@ -160,6 +176,9 @@ lv_font_t * lv_freetype_font_create_with_info(const lv_font_info_t * font_info)
|
||||
.pathname = lv_freetype_req_face_id(ctx, pathname),
|
||||
.style = font_info->style,
|
||||
.render_mode = font_info->render_mode,
|
||||
/* Normalize weight: DEFAULT(0) resolves to BOLD(700) or NORMAL(400) to avoid duplicate cache nodes */
|
||||
.weight = font_info->weight > LV_FREETYPE_VAR_WEIGHT_DEFAULT ? font_info->weight
|
||||
: ((font_info->style & LV_FREETYPE_FONT_STYLE_BOLD) ? LV_FREETYPE_VAR_WEIGHT_BOLD : LV_FREETYPE_VAR_WEIGHT_NORMAL),
|
||||
};
|
||||
|
||||
bool cache_hitting = true;
|
||||
@@ -442,8 +461,113 @@ static bool cache_node_cache_create_cb(lv_freetype_cache_node_t * node, void * u
|
||||
lv_freetype_glyph_l1_init(node);
|
||||
#endif
|
||||
|
||||
/* Apply variable font weight */
|
||||
if(!lv_freetype_set_weight_if_variable(face, node->weight)) {
|
||||
/* Only log when an explicit weight was requested, to avoid spamming logs
|
||||
* for default weights on non-variable fonts. */
|
||||
if(node->weight != LV_FREETYPE_VAR_WEIGHT_NORMAL && node->weight != LV_FREETYPE_VAR_WEIGHT_BOLD) {
|
||||
LV_LOG_INFO("font '%s' does not support variable weight, requested weight %d ignored", node->pathname, node->weight);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void lv_freetype_done_mm_var(FT_MM_Var * mm_var)
|
||||
{
|
||||
lv_freetype_context_t * ctx = lv_freetype_get_context();
|
||||
LV_ASSERT_NULL(ctx);
|
||||
LV_ASSERT_NULL(ctx->library);
|
||||
FT_Error err = FT_Done_MM_Var(ctx->library, mm_var);
|
||||
if(err != 0) {
|
||||
FT_ERROR_MSG("FT_Done_MM_Var", err);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the font is variable, set the 'wght' axis to the requested value. Returns true if applied. */
|
||||
static bool lv_freetype_set_weight_if_variable(FT_Face face, int weight)
|
||||
{
|
||||
if(!face)
|
||||
return false;
|
||||
if(!FT_HAS_MULTIPLE_MASTERS(face))
|
||||
return false;
|
||||
|
||||
FT_MM_Var * mm_var = NULL;
|
||||
FT_Error mm_err = FT_Get_MM_Var(face, &mm_var);
|
||||
if(mm_err != 0 || !mm_var || mm_var->num_axis == 0) {
|
||||
if(mm_err != 0) {
|
||||
FT_ERROR_MSG("FT_Get_MM_Var", mm_err);
|
||||
}
|
||||
else if(mm_var) {
|
||||
/* FT_Get_MM_Var succeeded but no usable axes; free to avoid leak */
|
||||
lv_freetype_done_mm_var(mm_var);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
FT_UInt axis_count = mm_var->num_axis;
|
||||
FT_Fixed coords_stack[LV_FREETYPE_MAX_STACK_AXES];
|
||||
FT_Fixed * coords = coords_stack;
|
||||
const bool use_heap = axis_count > LV_FREETYPE_MAX_STACK_AXES;
|
||||
bool applied = false;
|
||||
FT_ULong wght_tag;
|
||||
int wght_index;
|
||||
FT_UInt i;
|
||||
|
||||
if(use_heap) {
|
||||
coords = (FT_Fixed *)lv_malloc(axis_count * sizeof(FT_Fixed));
|
||||
LV_ASSERT_MALLOC(coords);
|
||||
if(!coords) {
|
||||
LV_LOG_ERROR("failed to allocate memory for %u font axes", axis_count);
|
||||
lv_freetype_done_mm_var(mm_var);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
FT_Error coord_err = FT_Get_Var_Design_Coordinates(face, axis_count, coords);
|
||||
if(coord_err != 0) {
|
||||
FT_ERROR_MSG("FT_Get_Var_Design_Coordinates", coord_err);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
wght_tag = FT_MAKE_TAG('w', 'g', 'h', 't');
|
||||
wght_index = -1;
|
||||
for(i = 0; i < axis_count; i++) {
|
||||
if(mm_var->axis[i].tag == wght_tag) {
|
||||
wght_index = (int)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(wght_index >= 0) {
|
||||
FT_Fixed min_v = mm_var->axis[wght_index].minimum;
|
||||
FT_Fixed max_v = mm_var->axis[wght_index].maximum;
|
||||
FT_Fixed target;
|
||||
FT_Error set_err;
|
||||
|
||||
weight = LV_CLAMP(LV_FREETYPE_VAR_WEIGHT_MIN, weight, LV_FREETYPE_VAR_WEIGHT_MAX);
|
||||
target = LV_CLAMP(min_v, FT_INT_TO_F16DOT16(weight), max_v);
|
||||
coords[wght_index] = target;
|
||||
|
||||
set_err = FT_Set_Var_Design_Coordinates(face, axis_count, coords);
|
||||
if(set_err != 0) {
|
||||
FT_ERROR_MSG("FT_Set_Var_Design_Coordinates", set_err);
|
||||
}
|
||||
else {
|
||||
applied = true;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if(use_heap) {
|
||||
lv_free(coords);
|
||||
}
|
||||
|
||||
lv_freetype_done_mm_var(mm_var);
|
||||
return applied;
|
||||
}
|
||||
|
||||
static void cache_node_cache_free_cb(lv_freetype_cache_node_t * node, void * user_data)
|
||||
{
|
||||
#if LV_FREETYPE_CACHE_FT_GLYPH_L1
|
||||
@@ -471,6 +595,9 @@ static lv_cache_compare_res_t cache_node_cache_compare_cb(const lv_freetype_cach
|
||||
if(lhs->style != rhs->style) {
|
||||
return lhs->style > rhs->style ? 1 : -1;
|
||||
}
|
||||
if(lhs->weight != rhs->weight) {
|
||||
return lhs->weight > rhs->weight ? 1 : -1;
|
||||
}
|
||||
|
||||
int32_t cmp_res = lv_strcmp(lhs->pathname, rhs->pathname);
|
||||
if(cmp_res != 0) {
|
||||
@@ -482,6 +609,7 @@ static lv_cache_compare_res_t cache_node_cache_compare_cb(const lv_freetype_cach
|
||||
|
||||
static lv_font_t * freetype_font_create_cb(const lv_font_info_t * info, const void * src)
|
||||
{
|
||||
LV_ASSERT_NULL(info);
|
||||
lv_font_info_t font_info = *info;
|
||||
font_info.name = src;
|
||||
return lv_freetype_font_create_with_info(&font_info);
|
||||
|
||||
@@ -130,7 +130,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->style & LV_FREETYPE_FONT_STYLE_BOLD) && !FT_HAS_MULTIPLE_MASTERS(dsc->cache_node->face) ? 1 : 0);
|
||||
lv_mutex_unlock(&dsc->cache_node->face_lock);
|
||||
|
||||
if(!outline) {
|
||||
|
||||
@@ -27,6 +27,7 @@ extern "C" {
|
||||
#include FT_IMAGE_H
|
||||
#include FT_OUTLINE_H
|
||||
#include FT_STROKER_H
|
||||
#include FT_MULTIPLE_MASTERS_H
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -90,6 +91,7 @@ struct _lv_freetype_cache_node_t {
|
||||
const char * pathname;
|
||||
lv_freetype_font_style_t style;
|
||||
lv_freetype_font_render_mode_t render_mode;
|
||||
int32_t weight; /**< Variable font weight (range 1-2000, 0 = default; values are clamped) */
|
||||
|
||||
uint32_t ref_size; /**< Reference size for calculating outline glyph's real size.*/
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 89 KiB |
@@ -61,6 +61,34 @@ static void test_freetype_with_render_mode(lv_freetype_font_render_mode_t render
|
||||
LV_FREETYPE_FONT_STYLE_NORMAL);
|
||||
TEST_ASSERT_NOT_NULL(font_normal_small);
|
||||
|
||||
lv_font_t * font_variable_default = lv_freetype_font_create(
|
||||
"./src/test_files/fonts/Montserrat-VariableFont.ttf", render_mode, 24, LV_FREETYPE_FONT_STYLE_NORMAL);
|
||||
TEST_ASSERT_NOT_NULL(font_variable_default);
|
||||
|
||||
lv_font_t * font_variable_bold = lv_freetype_font_create(
|
||||
"./src/test_files/fonts/Montserrat-VariableFont.ttf", render_mode, 24, LV_FREETYPE_FONT_STYLE_BOLD);
|
||||
TEST_ASSERT_NOT_NULL(font_variable_bold);
|
||||
|
||||
/* Use lv_font_info_t to set explicit weight */
|
||||
lv_font_info_t info_thin;
|
||||
lv_freetype_init_font_info(&info_thin);
|
||||
info_thin.name = "./src/test_files/fonts/Montserrat-VariableFont.ttf";
|
||||
info_thin.render_mode = render_mode;
|
||||
info_thin.size = 24;
|
||||
info_thin.style = LV_FREETYPE_FONT_STYLE_ITALIC;
|
||||
info_thin.weight = 300;
|
||||
lv_font_t * font_variable_thin = lv_freetype_font_create_with_info(&info_thin);
|
||||
TEST_ASSERT_NOT_NULL(font_variable_thin);
|
||||
|
||||
lv_font_info_t info_thick;
|
||||
lv_freetype_init_font_info(&info_thick);
|
||||
info_thick.name = "./src/test_files/fonts/Montserrat-VariableFont.ttf";
|
||||
info_thick.render_mode = render_mode;
|
||||
info_thick.size = 24;
|
||||
info_thick.weight = 1000;
|
||||
lv_font_t * font_variable_thick = lv_freetype_font_create_with_info(&info_thick);
|
||||
TEST_ASSERT_NOT_NULL(font_variable_thick);
|
||||
|
||||
/* Emoji is only supported in bitmap mode */
|
||||
lv_font_t * font_emoji = lv_freetype_font_create("../examples/libs/freetype/NotoColorEmoji-32.subset.ttf",
|
||||
LV_FREETYPE_FONT_RENDER_MODE_BITMAP,
|
||||
@@ -68,8 +96,7 @@ static void test_freetype_with_render_mode(lv_freetype_font_render_mode_t render
|
||||
LV_FREETYPE_FONT_STYLE_NORMAL);
|
||||
TEST_ASSERT_NOT_NULL(font_emoji);
|
||||
|
||||
lv_font_t * font_path_error = lv_freetype_font_create("ERROR_PATH", render_mode, 24,
|
||||
LV_FREETYPE_FONT_STYLE_NORMAL);
|
||||
lv_font_t * font_path_error = lv_freetype_font_create("ERROR_PATH", render_mode, 24, LV_FREETYPE_FONT_STYLE_NORMAL);
|
||||
TEST_ASSERT_NULL(font_path_error);
|
||||
|
||||
font_path_error = lv_freetype_font_create("", render_mode, 24, LV_FREETYPE_FONT_STYLE_NORMAL);
|
||||
@@ -101,30 +128,70 @@ static void test_freetype_with_render_mode(lv_freetype_font_render_mode_t render
|
||||
static lv_style_t style_normal_small;
|
||||
lv_style_init(&style_normal_small);
|
||||
lv_style_set_text_font(&style_normal_small, font_normal_small);
|
||||
lv_style_set_text_align(&style_normal_small, LV_TEXT_ALIGN_CENTER);
|
||||
|
||||
static lv_style_t style_variable_default;
|
||||
lv_style_init(&style_variable_default);
|
||||
lv_style_set_text_font(&style_variable_default, font_variable_default);
|
||||
lv_style_set_text_align(&style_variable_default, LV_TEXT_ALIGN_CENTER);
|
||||
|
||||
static lv_style_t style_variable_bold;
|
||||
lv_style_init(&style_variable_bold);
|
||||
lv_style_set_text_font(&style_variable_bold, font_variable_bold);
|
||||
lv_style_set_text_align(&style_variable_bold, LV_TEXT_ALIGN_CENTER);
|
||||
|
||||
static lv_style_t style_variable_thin;
|
||||
lv_style_init(&style_variable_thin);
|
||||
lv_style_set_text_font(&style_variable_thin, font_variable_thin);
|
||||
lv_style_set_text_align(&style_variable_thin, LV_TEXT_ALIGN_CENTER);
|
||||
|
||||
static lv_style_t style_variable_thick;
|
||||
lv_style_init(&style_variable_thick);
|
||||
lv_style_set_text_font(&style_variable_thick, font_variable_thick);
|
||||
lv_style_set_text_align(&style_variable_thick, LV_TEXT_ALIGN_CENTER);
|
||||
|
||||
static lv_style_t style_normal_emoji;
|
||||
lv_style_init(&style_normal_emoji);
|
||||
lv_style_set_text_font(&style_normal_emoji, font_emoji);
|
||||
lv_style_set_text_align(&style_normal_emoji, LV_TEXT_ALIGN_CENTER);
|
||||
|
||||
lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_COLUMN);
|
||||
|
||||
/*Create a label with the new style*/
|
||||
lv_obj_t * label0 = lv_label_create(lv_screen_active());
|
||||
lv_obj_add_style(label0, &style_italic, 0);
|
||||
lv_obj_set_width(label0, lv_obj_get_width(lv_screen_active()) - 20);
|
||||
lv_label_set_text(label0, UNIVERSAL_DECLARATION_OF_HUMAN_RIGHTS_CN);
|
||||
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_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);
|
||||
|
||||
lv_obj_t * label2 = lv_label_create(lv_screen_active());
|
||||
lv_obj_add_style(label2, &style_normal_small, 0);
|
||||
lv_obj_set_width(label2, lv_obj_get_width(lv_screen_active()) - 20);
|
||||
lv_label_set_text(label2, UNIVERSAL_DECLARATION_OF_HUMAN_RIGHTS_JP);
|
||||
lv_obj_align_to(label2, label1, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
|
||||
|
||||
lv_obj_t * label3 = lv_label_create(lv_screen_active());
|
||||
lv_obj_add_style(label3, &style_variable_default, 0);
|
||||
lv_obj_set_width(label3, lv_obj_get_width(lv_screen_active()) - 20);
|
||||
lv_label_set_text(label3, "Variable Font Default Weight");
|
||||
|
||||
lv_obj_t * label4 = lv_label_create(lv_screen_active());
|
||||
lv_obj_add_style(label4, &style_variable_bold, 0);
|
||||
lv_obj_set_width(label4, lv_obj_get_width(lv_screen_active()) - 20);
|
||||
lv_label_set_text(label4, "Variable Font Bold Weight");
|
||||
|
||||
lv_obj_t * label5 = lv_label_create(lv_screen_active());
|
||||
lv_obj_add_style(label5, &style_variable_thin, 0);
|
||||
lv_obj_set_width(label5, lv_obj_get_width(lv_screen_active()) - 20);
|
||||
lv_label_set_text(label5, "Variable Font 300 Weight");
|
||||
|
||||
lv_obj_t * label6 = lv_label_create(lv_screen_active());
|
||||
lv_obj_add_style(label6, &style_variable_thick, 0);
|
||||
lv_obj_set_width(label6, lv_obj_get_width(lv_screen_active()) - 20);
|
||||
lv_label_set_text(label6, "Variable Font 1000 Weight");
|
||||
|
||||
/* test emoji rendering
|
||||
* emoji font does not contain normal characters, use fallback to render them */
|
||||
@@ -134,19 +201,27 @@ static void test_freetype_with_render_mode(lv_freetype_font_render_mode_t render
|
||||
lv_obj_add_style(label_emoji, &style_normal_emoji, 0);
|
||||
lv_obj_set_width(label_emoji, lv_obj_get_width(lv_screen_active()) - 20);
|
||||
lv_label_set_text(label_emoji, "FreeType Emoji test: 😀");
|
||||
lv_obj_align_to(label_emoji, label2, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
|
||||
|
||||
TEST_ASSERT_EQUAL_SCREENSHOT(screenshot_name);
|
||||
|
||||
lv_obj_set_layout(lv_screen_active(), LV_LAYOUT_NONE);
|
||||
lv_obj_clean(lv_screen_active());
|
||||
lv_style_reset(&style_italic);
|
||||
lv_style_reset(&style_normal_with_outline);
|
||||
lv_style_reset(&style_normal_small);
|
||||
lv_style_reset(&style_variable_default);
|
||||
lv_style_reset(&style_variable_bold);
|
||||
lv_style_reset(&style_variable_thin);
|
||||
lv_style_reset(&style_variable_thick);
|
||||
lv_style_reset(&style_normal_emoji);
|
||||
lv_freetype_font_delete(font_italic);
|
||||
lv_freetype_font_delete(font_normal);
|
||||
lv_freetype_font_delete(font_normal_small);
|
||||
lv_freetype_font_delete(font_emoji);
|
||||
lv_freetype_font_delete(font_variable_default);
|
||||
lv_freetype_font_delete(font_variable_bold);
|
||||
lv_freetype_font_delete(font_variable_thin);
|
||||
lv_freetype_font_delete(font_variable_thick);
|
||||
}
|
||||
|
||||
void test_freetype_render_bitmap(void)
|
||||
|
||||