diff --git a/src/widgets/arclabel/lv_arclabel.c b/src/widgets/arclabel/lv_arclabel.c index 9efeb258dd..5a46dea8dd 100644 --- a/src/widgets/arclabel/lv_arclabel.c +++ b/src/widgets/arclabel/lv_arclabel.c @@ -415,7 +415,7 @@ static void arclabel_draw_main(lv_event_t * e) const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); const lv_color_t color = lv_obj_get_style_text_color(obj, LV_PART_MAIN); - const lv_opa_t opa = lv_obj_get_style_text_opa(obj, LV_PART_MAIN); + const lv_opa_t opa = LV_OPA_MIX2(layer->opa, lv_obj_get_style_text_opa(obj, LV_PART_MAIN)); const int32_t letter_space = lv_obj_get_style_text_letter_space(obj, LV_PART_MAIN); const int32_t line_height = font->line_height; diff --git a/tests/ref_imgs/widgets/arclabel_opacity.lp32.png b/tests/ref_imgs/widgets/arclabel_opacity.lp32.png new file mode 100644 index 0000000000..f9d5af7e2e Binary files /dev/null and b/tests/ref_imgs/widgets/arclabel_opacity.lp32.png differ diff --git a/tests/ref_imgs/widgets/arclabel_opacity.lp64.png b/tests/ref_imgs/widgets/arclabel_opacity.lp64.png new file mode 100644 index 0000000000..f9d5af7e2e Binary files /dev/null and b/tests/ref_imgs/widgets/arclabel_opacity.lp64.png differ diff --git a/tests/ref_imgs_vg_lite/widgets/arclabel_alignment.lp64.png b/tests/ref_imgs_vg_lite/widgets/arclabel_alignment.lp64.png index f46bbc85e4..f15db21ba3 100644 Binary files a/tests/ref_imgs_vg_lite/widgets/arclabel_alignment.lp64.png and b/tests/ref_imgs_vg_lite/widgets/arclabel_alignment.lp64.png differ diff --git a/tests/ref_imgs_vg_lite/widgets/arclabel_opacity.lp32.png b/tests/ref_imgs_vg_lite/widgets/arclabel_opacity.lp32.png new file mode 100644 index 0000000000..5709529fcc Binary files /dev/null and b/tests/ref_imgs_vg_lite/widgets/arclabel_opacity.lp32.png differ diff --git a/tests/ref_imgs_vg_lite/widgets/arclabel_opacity.lp64.png b/tests/ref_imgs_vg_lite/widgets/arclabel_opacity.lp64.png new file mode 100644 index 0000000000..eb086662e1 Binary files /dev/null and b/tests/ref_imgs_vg_lite/widgets/arclabel_opacity.lp64.png differ diff --git a/tests/ref_imgs_vg_lite/widgets/arclabel_overflow.lp64.png b/tests/ref_imgs_vg_lite/widgets/arclabel_overflow.lp64.png index 552fd26803..407429ef5a 100644 Binary files a/tests/ref_imgs_vg_lite/widgets/arclabel_overflow.lp64.png and b/tests/ref_imgs_vg_lite/widgets/arclabel_overflow.lp64.png differ diff --git a/tests/ref_imgs_vg_lite/widgets/arclabel_simple.lp64.png b/tests/ref_imgs_vg_lite/widgets/arclabel_simple.lp64.png index 740f94488e..149f6cf030 100644 Binary files a/tests/ref_imgs_vg_lite/widgets/arclabel_simple.lp64.png and b/tests/ref_imgs_vg_lite/widgets/arclabel_simple.lp64.png differ diff --git a/tests/src/test_cases/widgets/test_arclabel.c b/tests/src/test_cases/widgets/test_arclabel.c index 5d0a7f64de..a269d3a37f 100644 --- a/tests/src/test_cases/widgets/test_arclabel.c +++ b/tests/src/test_cases/widgets/test_arclabel.c @@ -169,5 +169,55 @@ void test_arclabel_overflow(void) TEST_ASSERT_EQUAL_SCREENSHOT("widgets/arclabel_overflow" EXT_NAME); } +void test_arclabel_opacity(void) +{ + if(!font) { + LV_LOG_ERROR("freetype font create failed."); + TEST_FAIL(); + } + lv_obj_set_scrollbar_mode(active_screen, LV_SCROLLBAR_MODE_OFF); + + const int32_t layers = 16; + const int32_t size_min = 80; + const int32_t size_step = 40; + const int32_t pos_ofs_y = layers * size_step / 6; + const int32_t pos_ofs_x = size_step; + + for(int32_t i = 0; i < layers; i++) { + lv_obj_t * arclabel = lv_arclabel_create(active_screen); + lv_obj_set_style_text_font(arclabel, font, LV_PART_MAIN); + lv_obj_set_style_text_letter_space(arclabel, 2, LV_PART_MAIN); + lv_obj_set_style_text_color(arclabel, lv_color_hex(0x666666), LV_PART_MAIN); + + int32_t size = size_min + i * size_step; + lv_obj_set_size(arclabel, size, size); + + lv_arclabel_set_angle_start(arclabel, -180); + lv_arclabel_set_text_static(arclabel, ARCLABEL_TEXT); + lv_arclabel_set_radius(arclabel, LV_PCT(100)); + lv_arclabel_set_recolor(arclabel, true); + lv_arclabel_set_text_vertical_align(arclabel, LV_ARCLABEL_TEXT_ALIGN_LEADING); + lv_arclabel_set_dir(arclabel, LV_ARCLABEL_DIR_CLOCKWISE); + + lv_obj_align(arclabel, LV_ALIGN_CENTER, pos_ofs_x, pos_ofs_y); + + /* Use fixed-point LUT for gamma-corrected opacity (base perceived brightness from 1.0 to 0.5) + * Values are pre-calculated: (pow(1.0 - (i/15.0)*0.5, 1/2.2) * 255) */ + static const uint8_t opa_gamma_lut[] = { + 255, 251, 247, 242, 238, 234, 229, 225, 220, 215, 210, 205, 200, 195, 189, 184 + }; + + int32_t opa_gamma = opa_gamma_lut[i]; + + /* Apply light attenuation: final_opa = opa_gamma / (1 + (i*k)^2) + * With k = 0.25 (1/4), the formula becomes: opa_gamma * 16 / (16 + i*i) */ + int32_t final_opa = (opa_gamma * 16) / (16 + i * i); + if(final_opa < 0) final_opa = 0; + if(final_opa > LV_OPA_COVER) final_opa = LV_OPA_COVER; + + lv_obj_set_style_opa(arclabel, final_opa, LV_PART_MAIN); + } + TEST_ASSERT_EQUAL_SCREENSHOT("widgets/arclabel_opacity" EXT_NAME); +} #endif