diff options
author | Harley Acheson <harley.acheson@gmail.com> | 2021-06-07 20:50:10 +0300 |
---|---|---|
committer | Harley Acheson <harley.acheson@gmail.com> | 2021-06-07 20:56:20 +0300 |
commit | 0fcc063fd99c922af0f1b80d2d19b96596b2d4bb (patch) | |
tree | 8b3d83071506cdc5e87a6f6874cfc831493397e1 /source | |
parent | 1949643ee58c533036395ab2ad4299489460e44b (diff) |
Fix T88801: Positioning of Menu Underlines
This patch improves the positioning of the little mnemonic underlines
shown under some hotkey letters in menus, especially when using custom
fonts.
see D11521 for details and examples.
Differential Revision: https://developer.blender.org/D11521
Reviewed by Campbell Barton
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/interface/interface_widgets.c | 53 |
1 files changed, 34 insertions, 19 deletions
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; - - 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); + widget_draw_text_underline_calc_position, + &ul_data); + + 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); |