fix(span): prevent false ellipsis when text fits within container width
Arduino Lint / lint (push) Has been cancelled
Build Examples with C++ Compiler / build-examples (push) Has been cancelled
MicroPython CI / Build esp32 port (push) Has been cancelled
MicroPython CI / Build rp2 port (push) Has been cancelled
MicroPython CI / Build stm32 port (push) Has been cancelled
MicroPython CI / Build unix port (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_NORMAL_8BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_SDL - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build ESP IDF ESP32S3 (push) Has been cancelled
C/C++ CI / Run tests with 32bit build (push) Has been cancelled
C/C++ CI / Run tests with 64bit build (push) Has been cancelled
BOM Check / bom-check (push) Has been cancelled
Verify that lv_conf_internal.h matches repository state / verify-conf-internal (push) Has been cancelled
Verify GDB constants are up-to-date / verify-gdb-consts (push) Has been cancelled
Verify the widget property name / verify-property-name (push) Has been cancelled
Verify code formatting / verify-formatting (push) Has been cancelled
Compare file templates with file names / template-check (push) Has been cancelled
Test API JSON generator / Test API JSON (push) Has been cancelled
Install LVGL using CMake / build-examples (push) Has been cancelled
Check Makefile / Build using Makefile (push) Has been cancelled
Check Makefile for UEFI / Build using Makefile for UEFI (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/benchmark_results_comment/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/filter_docker_logs/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/serialize_results/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark 32b - lv_conf_perf32b (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark 64b - lv_conf_perf64b (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Save PR Number (push) Has been cancelled
Hardware Performance Test / Hardware Performance Benchmark (push) Has been cancelled
Hardware Performance Test / HW Benchmark - Save PR Number (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_32B - Ubuntu (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_64B - Ubuntu (push) Has been cancelled
Port repo release update / run-release-branch-updater (push) Has been cancelled
Verify Font License / verify-font-license (push) Has been cancelled
Verify Kconfig / verify-kconfig (push) Has been cancelled

Change-Id: I0787a3f0466acb699fac6f3a9e60b5efa53275b2
Signed-off-by: zhangyan63 <zhangyan63@xiaomi.com>

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
This commit is contained in:
zhangyan63
2026-03-10 15:14:52 +08:00
committed by Gabor Kiss-Vamosi
parent 2c888ecd32
commit 2faaf78f3d
6 changed files with 90 additions and 2 deletions
+7 -2
View File
@@ -1230,15 +1230,20 @@ static void lv_draw_span(lv_obj_t * obj, lv_layer_t * layer)
{
lv_snippet_t * last_snippet = lv_get_snippet(item_cnt - 1);
int32_t next_line_h = last_snippet->line_h;
if(last_snippet->txt[last_snippet->bytes] == '\0') {
bool has_more_content = last_snippet->txt[last_snippet->bytes] != '\0';
if(!has_more_content) {
next_line_h = 0;
lv_span_t * next_span = lv_ll_get_next(&spans->child_ll, last_snippet->span);
while(next_span && (!next_span->txt || next_span->txt[0] == '\0')) {
next_span = lv_ll_get_next(&spans->child_ll, next_span);
}
if(next_span && next_span->txt && next_span->txt[0]) { /* have the next line */
next_line_h = lv_font_get_line_height(lv_span_get_style_text_font(obj, next_span)) + line_space;
has_more_content = true;
}
}
if(txt_pos.y + max_line_h + next_line_h - line_space > coords.y2 + 1) { /* for overflow if is end line. */
ellipsis_valid = spans->overflow == LV_SPAN_OVERFLOW_ELLIPSIS;
ellipsis_valid = has_more_content && spans->overflow == LV_SPAN_OVERFLOW_ELLIPSIS;
is_end_line = true;
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

+83
View File
@@ -644,4 +644,87 @@ void test_span_properties(void)
#endif
}
/*
* Ellipsis should not appear when all text fits horizontally but max-height is smaller than font line_height.
*/
#if LV_USE_FREETYPE && __WORDSIZE == 64
void test_spangroup_ellipsis_not_shown_when_text_fits(void)
{
lv_font_t * font = lv_freetype_font_create("src/test_files/fonts/noto/NotoSansSC-Regular.ttf",
LV_FREETYPE_FONT_RENDER_MODE_BITMAP, 24, LV_FREETYPE_FONT_STYLE_NORMAL);
if(!font) {
LV_LOG_ERROR("freetype font create failed.");
TEST_FAIL();
}
int32_t font_h = lv_font_get_line_height(font);
int32_t constrained_h = font_h - 2; /* ensure max-height < line_height */
active_screen = lv_screen_active();
/* Case 1: width = text width, text fits — no ellipsis expected */
lv_obj_t * spangroup1 = lv_spangroup_create(active_screen);
lv_obj_set_style_text_font(spangroup1, font, 0);
lv_obj_set_style_outline_width(spangroup1, 1, 0);
lv_spangroup_set_overflow(spangroup1, LV_SPAN_OVERFLOW_ELLIPSIS);
lv_spangroup_set_mode(spangroup1, LV_SPAN_MODE_BREAK);
lv_span_t * span1 = lv_spangroup_add_span(spangroup1);
lv_span_set_text(span1, "消息免打扰");
/* Set width to exactly fit the text, like CSS width: fit-content */
uint32_t text_w1 = lv_spangroup_get_expand_width(spangroup1, UINT32_MAX);
lv_obj_set_width(spangroup1, text_w1);
lv_obj_set_style_max_height(spangroup1, constrained_h, 0);
/* Case 2: text overflows width — ellipsis expected */
lv_obj_t * spangroup2 = lv_spangroup_create(active_screen);
lv_obj_set_style_text_font(spangroup2, font, 0);
lv_obj_set_style_outline_width(spangroup2, 1, 0);
lv_spangroup_set_overflow(spangroup2, LV_SPAN_OVERFLOW_ELLIPSIS);
lv_spangroup_set_mode(spangroup2, LV_SPAN_MODE_BREAK);
lv_obj_set_y(spangroup2, 40);
lv_obj_set_width(spangroup2, 250);
lv_obj_set_style_max_height(spangroup2, constrained_h, 0);
lv_span_t * span2 = lv_spangroup_add_span(spangroup2);
lv_span_set_text(span2, "这是一段很长的中文文字用来测试文本溢出省略号的显示效果");
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/span_16.png");
lv_obj_set_style_text_font(spangroup1, LV_FONT_DEFAULT, 0);
lv_obj_set_style_text_font(spangroup2, LV_FONT_DEFAULT, 0);
lv_freetype_font_delete(font);
}
#else
void test_spangroup_ellipsis_not_shown_when_text_fits(void)
{
}
#endif
/* Text wraps to 3+ lines, max-height fits 2 — ellipsis on last visible line */
void test_spangroup_ellipsis_multiline_truncated(void)
{
active_screen = lv_screen_active();
spangroup = lv_spangroup_create(active_screen);
int32_t line_h = lv_font_get_line_height(LV_FONT_DEFAULT);
lv_obj_set_style_outline_width(spangroup, 1, 0);
lv_obj_set_width(spangroup, 100);
lv_obj_set_style_max_height(spangroup, line_h * 2, 0);
lv_spangroup_set_overflow(spangroup, LV_SPAN_OVERFLOW_ELLIPSIS);
lv_spangroup_set_mode(spangroup, LV_SPAN_MODE_BREAK);
lv_span_t * span = lv_spangroup_add_span(spangroup);
lv_span_set_text(span, "This text is long enough to wrap into three or more lines in a 100px container");
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/span_17.png");
}
#endif