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
This commit is contained in:
Harley Acheson 2021-06-07 10:50:10 -07:00
parent 1949643ee5
commit 0fcc063fd9
Notes: blender-bot 2023-02-14 05:16:25 +01:00
Referenced by commit aee04d4960, Fix T89246: No Mnemonic Underlines in Dialogs
Referenced by issue #88801, Mnemonics underline in menus is off center and needs some extra padding with custom fonts
1 changed files with 33 additions and 18 deletions

View File

@ -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);