From 4b1ad2dc1748c7c004d8829400a8296efd31576a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 26 Oct 2021 00:10:18 +1100 Subject: Fix T92361: Zooming nodes clips text labels While c7d94a7827a5be9343eea22a9638bb059f185206 exposed this bug, this was caused by text widths being calculated without taking the zoom level into account since drawing at a smaller size is often wider than the width of the larger text scaled by the zoom. --- source/blender/editors/include/UI_interface.h | 7 +++++- .../blender/editors/interface/interface_layout.c | 8 ++++-- source/blender/editors/interface/interface_style.c | 29 ++++++++++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index de6b975a910..4cd921bc61e 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -2687,7 +2687,12 @@ void UI_fontstyle_draw_simple_backdrop(const struct uiFontStyle *fs, const float col_fg[4], const float col_bg[4]); -int UI_fontstyle_string_width(const struct uiFontStyle *fs, const char *str); +int UI_fontstyle_string_width(const struct uiFontStyle *fs, + const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2); +int UI_fontstyle_string_width_with_block_aspect(const struct uiFontStyle *fs, + const char *str, + const float aspect) ATTR_WARN_UNUSED_RESULT + ATTR_NONNULL(1, 2); int UI_fontstyle_height_max(const struct uiFontStyle *fs); void UI_draw_icon_tri(float x, float y, char dir, const float[4]); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index e54b261facd..25ba0e13487 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -351,12 +351,16 @@ static int ui_text_icon_width_ex(uiLayout *layout, if (layout->alignment != UI_LAYOUT_ALIGN_EXPAND) { layout->item.flag |= UI_ITEM_FIXED_SIZE; } - const uiFontStyle *fstyle = UI_FSTYLE_WIDGET; + float margin = pad_factor->text; if (icon) { margin += pad_factor->icon; } - return UI_fontstyle_string_width(fstyle, name) + (unit_x * margin); + + const float aspect = layout->root->block->aspect; + const uiFontStyle *fstyle = UI_FSTYLE_WIDGET; + return UI_fontstyle_string_width_with_block_aspect(fstyle, name, aspect) + + (int)ceilf(unit_x * margin); } return unit_x * 10; } diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c index 6b1ff92a855..2a1cdfd447c 100644 --- a/source/blender/editors/interface/interface_style.c +++ b/source/blender/editors/interface/interface_style.c @@ -376,6 +376,35 @@ int UI_fontstyle_string_width(const uiFontStyle *fs, const char *str) return (int)BLF_width(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX); } +/** + * Return the width of `str` with the spacing & kerning of `fs` with `aspect` + * (representing #uiBlock.aspect) applied. + * + * When calculating text width, the UI layout logic calculate widths without scale, + * only applying scale when drawing. This causes problems for fonts since kerning at + * smaller sizes often makes them wider than a scaled down version of the larger text. + * Resolve this by calculating the text at the on-screen size, + * returning the result scaled back to 1:1. See T92361. + */ +int UI_fontstyle_string_width_with_block_aspect(const uiFontStyle *fs, + const char *str, + const float aspect) +{ + uiFontStyle fs_buf; + if (aspect != 1.0f) { + fs_buf = *fs; + ui_fontscale(&fs_buf.points, aspect); + fs = &fs_buf; + } + + int width = UI_fontstyle_string_width(fs, str); + + if (aspect != 1.0f) { + width = (int)ceilf(width * aspect); + } + return width; +} + int UI_fontstyle_height_max(const uiFontStyle *fs) { UI_fontstyle_set(fs); -- cgit v1.2.3