diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index d2e6165a20f..8b861fab418 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1930,7 +1930,13 @@ static void widget_draw_text_ime_underline(const uiFontStyle *fstyle, } #endif /* WITH_INPUT_IME */ -static bool widget_draw_text_underline_calc_center_x(const char *UNUSED(str), +struct UnderlineData { + size_t str_offset; /* The string offset of the underlined character. */ + int width_px; /* The underline width in pixels. */ + int r_offset_px[2]; /* Write the X,Y offset here. */ +}; + +static bool widget_draw_text_underline_calc_position(const char *UNUSED(str), const size_t str_step_ofs, const rcti *glyph_step_bounds, const int UNUSED(glyph_advance_x), @@ -1938,11 +1944,13 @@ static bool widget_draw_text_underline_calc_center_x(const char *UNUSED(str), const int glyph_bearing[2], void *user_data) { - /* The index of the character to get, set to the x-position. */ - int *ul_data = user_data; - if (ul_data[0] == (int)str_step_ofs) { - ul_data[1] = glyph_step_bounds->xmin + glyph_bearing[0] + - (BLI_rctf_size_x(glyph_bounds) / 2.0f); + struct UnderlineData *ul_data = user_data; + if (ul_data->str_offset == str_step_ofs) { + /* Full width of this glyph including both bearings. */ + const float width = glyph_bounds->xmin + BLI_rctf_size_x(glyph_bounds) + glyph_bounds->xmin; + ul_data->r_offset_px[0] = glyph_step_bounds->xmin + ((width - ul_data->width_px) * 0.5f); + /* Two line-widths below the lower glyph bounds. */ + ul_data->r_offset_px[1] = glyph_bounds->ymin - U.pixelsize - U.pixelsize; /* Early exit. */ return false; } @@ -2198,23 +2206,30 @@ static void widget_draw_text(const uiFontStyle *fstyle, BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT); } - int ul_data[2] = { - ul_index, /* Character index to test. */ - 0, /* Write the x-offset here. */ + int ul_width = round_fl_to_int(BLF_width(fstyle->uifont_id, "_", 2)); + int ul_height = max_ii(fstyle->points * U.dpi_fac * 0.1f, U.pixelsize); + + struct UnderlineData ul_data = { + .str_offset = ul_index, + .width_px = ul_width, }; + BLF_boundbox_foreach_glyph(fstyle->uifont_id, drawstr_ofs, ul_index + 1, - widget_draw_text_underline_calc_center_x, - ul_data); - ul_data[1] -= BLF_width(fstyle->uifont_id, "_", 2) / 2.0f; + widget_draw_text_underline_calc_position, + &ul_data); - BLF_position(fstyle->uifont_id, - rect->xmin + font_xofs + ul_data[1], - rect->ymin + font_yofs, - 0.0f); - BLF_color4ubv(fstyle->uifont_id, wcol->text); - BLF_draw(fstyle->uifont_id, "_", 2); + GPU_blend(GPU_BLEND_ALPHA); + const uint pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor4ubv(wcol->text); + const int pos_x = rect->xmin + font_xofs + ul_data.r_offset_px[0]; + const int pos_y = rect->ymin + font_yofs + ul_data.r_offset_px[1]; + immRecti(pos, pos_x, pos_y, pos_x + ul_width, pos_y - ul_height); + immUnbindProgram(); + GPU_blend(GPU_BLEND_NONE); if (fstyle->kerning == 1) { BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);