From 101963a748fe6f2be159c500ea6b050132a7c512 Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Sat, 13 Apr 2024 14:01:59 -0700 Subject: [PATCH 1/3] Refactor: BLF Extract Function BLF_str_offset_to_cursor Move into own BLF function, code that returns a text cursor (caret) position given a string offset. This code is currently just in interface_widgets.cc but should be a separate BLF function. --- source/blender/blenfont/BLF_api.hh | 6 ++ source/blender/blenfont/intern/blf.cc | 10 +++ source/blender/blenfont/intern/blf_font.cc | 45 +++++++++++++ .../blender/blenfont/intern/blf_internal.hh | 3 + .../editors/interface/interface_widgets.cc | 67 +++---------------- 5 files changed, 73 insertions(+), 58 deletions(-) diff --git a/source/blender/blenfont/BLF_api.hh b/source/blender/blenfont/BLF_api.hh index 2b644705376..552fb45510d 100644 --- a/source/blender/blenfont/BLF_api.hh +++ b/source/blender/blenfont/BLF_api.hh @@ -184,6 +184,12 @@ bool BLF_str_offset_to_glyph_bounds(int fontid, size_t str_offset, rcti *glyph_bounds) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(2, 4); +/** + * Return left edge of text cursor (caret), given a character offset and cursor width. + */ +int BLF_str_offset_to_cursor( + int fontid, const char *str, size_t str_len, size_t str_offset, float cursor_width); + /** * Get the string byte offset that fits within a given width. */ diff --git a/source/blender/blenfont/intern/blf.cc b/source/blender/blenfont/intern/blf.cc index e5a4e83d4e9..507cfcc91cb 100644 --- a/source/blender/blenfont/intern/blf.cc +++ b/source/blender/blenfont/intern/blf.cc @@ -652,6 +652,16 @@ bool BLF_str_offset_to_glyph_bounds(int fontid, return false; } +int BLF_str_offset_to_cursor( + int fontid, const char *str, size_t str_len, size_t str_offset, float cursor_width) +{ + FontBLF *font = blf_get(fontid); + if (font) { + return blf_str_offset_to_cursor(font, str, str_len, str_offset, cursor_width); + } + return 0; +} + size_t BLF_width_to_strlen( int fontid, const char *str, const size_t str_len, float width, float *r_width) { diff --git a/source/blender/blenfont/intern/blf_font.cc b/source/blender/blenfont/intern/blf_font.cc index 74700b5ff27..dfa4eab4340 100644 --- a/source/blender/blenfont/intern/blf_font.cc +++ b/source/blender/blenfont/intern/blf_font.cc @@ -1075,6 +1075,51 @@ void blf_str_offset_to_glyph_bounds(FontBLF *font, *glyph_bounds = data.bounds; } +int blf_str_offset_to_cursor( + FontBLF *font, const char *str, size_t str_len, size_t str_offset, float cursor_width) +{ + if (!str || !str[0]) { + return 0; + } + + /* Find right edge of previous character if available. */ + rcti prev = {0}; + if (str_offset > 0) { + blf_str_offset_to_glyph_bounds(font, str, str_offset - 1, &prev); + } + + /* Find left edge of next character if available. */ + rcti next = {0}; + if (str_offset < strlen(str)) { + blf_str_offset_to_glyph_bounds(font, str, str_offset, &next); + } + + if ((prev.xmax == prev.xmin) && next.xmax) { + /* Left of the first character or a space. */ + return next.xmin - int(cursor_width); + } + else if ((prev.xmax != prev.xmin) && !next.xmax) { + /* Right of the last character. */ + return prev.xmax; + } + else if (prev.xmax && next.xmax) { + /* Middle of the string, so in between. */ + if (next.xmin >= prev.xmax) { + return int((prev.xmax + next.xmin - cursor_width) / 2.0f); + } + /* Possible with RTL. */ + return int((next.xmax + prev.xmin - cursor_width) / 2.0f); + } + else if (!str_offset) { + /* Before first space character. */ + return 0 - int(cursor_width); + } + else { + /* After last character. */ + return int(blf_font_width(font, str, str_len, nullptr)); + } +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/blenfont/intern/blf_internal.hh b/source/blender/blenfont/intern/blf_internal.hh index 88de4fd7590..fb92445f26c 100644 --- a/source/blender/blenfont/intern/blf_internal.hh +++ b/source/blender/blenfont/intern/blf_internal.hh @@ -144,6 +144,9 @@ void blf_str_offset_to_glyph_bounds(FontBLF *font, size_t str_offset, rcti *glyph_bounds); +int blf_str_offset_to_cursor( + FontBLF *font, const char *str, size_t str_len, size_t str_offset, float cursor_width); + void blf_font_free(FontBLF *font); GlyphCacheBLF *blf_glyph_cache_acquire(FontBLF *font); diff --git a/source/blender/editors/interface/interface_widgets.cc b/source/blender/editors/interface/interface_widgets.cc index 3ada9d373ca..c7fc35a2d63 100644 --- a/source/blender/editors/interface/interface_widgets.cc +++ b/source/blender/editors/interface/interface_widgets.cc @@ -1988,54 +1988,12 @@ static void widget_draw_text(const uiFontStyle *fstyle, /* Draw text cursor (caret). */ if (but->pos >= but->ofs) { - int t = 0; - if (drawstr[0] != 0) { - const int pos = but_pos_ofs - but->ofs; - rcti bounds; - - /* Find right edge of previous character if available. */ - int prev_right_edge = 0; - bool has_prev = false; - if (pos > 0) { - if (BLF_str_offset_to_glyph_bounds( - fstyle->uifont_id, drawstr + but->ofs, pos - 1, &bounds)) - { - if (bounds.xmax > bounds.xmin) { - prev_right_edge = bounds.xmax; - } - else { - /* Some characters, like space, have empty bounds. */ - prev_right_edge = BLF_width(fstyle->uifont_id, drawstr + but->ofs, pos); - } - has_prev = true; - } - } - - /* Find left edge of next character if available. */ - int next_left_edge = 0; - bool has_next = false; - if (pos < strlen(drawstr + but->ofs)) { - if (BLF_str_offset_to_glyph_bounds(fstyle->uifont_id, drawstr + but->ofs, pos, &bounds)) - { - next_left_edge = bounds.xmin; - has_next = true; - } - } - - if (has_next && !has_prev) { - /* Left of the first character. */ - t = next_left_edge - U.pixelsize; - } - else if (has_prev && !has_next) { - /* Right of the last character. */ - t = prev_right_edge + U.pixelsize; - } - else if (has_prev && has_next) { - /* Middle of the string, so in between. */ - t = (prev_right_edge + next_left_edge) / 2; - } - } + int t = BLF_str_offset_to_cursor(fstyle->uifont_id, + drawstr + but->ofs, + UI_MAX_DRAW_STR, + but_pos_ofs - but->ofs, + U.pixelsize + U.pixelsize); /* We are drawing on top of widget bases. Flush cache. */ GPU_blend(GPU_BLEND_ALPHA); @@ -2048,19 +2006,12 @@ static void widget_draw_text(const uiFontStyle *fstyle, immUniformThemeColor(TH_WIDGET_TEXT_CURSOR); - /* Shape of the cursor for drawing. */ - rcti but_cursor_shape; - but_cursor_shape.xmin = (rect->xmin + t) - U.pixelsize; - but_cursor_shape.ymin = rect->ymin + U.pixelsize; - but_cursor_shape.xmax = (rect->xmin + t) + U.pixelsize; - but_cursor_shape.ymax = rect->ymax - U.pixelsize; - /* draw cursor */ immRecti(pos, - but_cursor_shape.xmin, - but_cursor_shape.ymin, - but_cursor_shape.xmax, - but_cursor_shape.ymax); + rect->xmin + t, + rect->ymin + U.pixelsize, + rect->xmin + t + int(2.0f * U.pixelsize), + rect->ymax - U.pixelsize); immUnbindProgram(); -- 2.30.2 From 41ac8a912f487d28e09722a1f08898ba1eb286bb Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Sat, 13 Apr 2024 16:30:42 -0700 Subject: [PATCH 2/3] Calm warnings. WITH_INPUT_IME error setting IME cursor. --- source/blender/blenfont/intern/blf_font.cc | 4 ++-- source/blender/editors/interface/interface_widgets.cc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/blenfont/intern/blf_font.cc b/source/blender/blenfont/intern/blf_font.cc index dfa4eab4340..3fdf7b8fb78 100644 --- a/source/blender/blenfont/intern/blf_font.cc +++ b/source/blender/blenfont/intern/blf_font.cc @@ -1105,10 +1105,10 @@ int blf_str_offset_to_cursor( else if (prev.xmax && next.xmax) { /* Middle of the string, so in between. */ if (next.xmin >= prev.xmax) { - return int((prev.xmax + next.xmin - cursor_width) / 2.0f); + return int((float(prev.xmax + next.xmin) - cursor_width) / 2.0f); } /* Possible with RTL. */ - return int((next.xmax + prev.xmin - cursor_width) / 2.0f); + return int((float(next.xmax + prev.xmin) - cursor_width) / 2.0f); } else if (!str_offset) { /* Before first space character. */ diff --git a/source/blender/editors/interface/interface_widgets.cc b/source/blender/editors/interface/interface_widgets.cc index c7fc35a2d63..14398fbf2af 100644 --- a/source/blender/editors/interface/interface_widgets.cc +++ b/source/blender/editors/interface/interface_widgets.cc @@ -2019,8 +2019,8 @@ static void widget_draw_text(const uiFontStyle *fstyle, /* IME candidate window uses cursor position. */ if (!ime_reposition_window) { ime_reposition_window = true; - ime_win_x = but_cursor_shape.xmax + 5; - ime_win_y = but_cursor_shape.ymin + 3; + ime_win_x = rect->xmin + t + 5; + ime_win_y = rect->ymin + 3; } #endif } -- 2.30.2 From 474315d93410609bd77514b639a1850ffc4960a6 Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Mon, 15 Apr 2024 09:26:28 -0700 Subject: [PATCH 3/3] Comment changes only. --- source/blender/blenfont/intern/blf_font.cc | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/source/blender/blenfont/intern/blf_font.cc b/source/blender/blenfont/intern/blf_font.cc index 1696410ee8b..47dc246841f 100644 --- a/source/blender/blenfont/intern/blf_font.cc +++ b/source/blender/blenfont/intern/blf_font.cc @@ -1082,40 +1082,39 @@ int blf_str_offset_to_cursor( return 0; } - /* Find right edge of previous character if available. */ + /* Right edge of the previous character, if available. */ rcti prev = {0}; if (str_offset > 0) { blf_str_offset_to_glyph_bounds(font, str, str_offset - 1, &prev); } - /* Find left edge of next character if available. */ + /* Left edge of the next character, if available. */ rcti next = {0}; if (str_offset < strlen(str)) { blf_str_offset_to_glyph_bounds(font, str, str_offset, &next); } if ((prev.xmax == prev.xmin) && next.xmax) { - /* Left of the first character or a space. */ + /* Nothing (or a space) to the left, so align to right character. */ return next.xmin - int(cursor_width); } else if ((prev.xmax != prev.xmin) && !next.xmax) { - /* Right of the last character. */ + /* End of string, so align to last character. */ return prev.xmax; } else if (prev.xmax && next.xmax) { - /* Middle of the string, so in between. */ + /* Between two characters, so use the center. */ if (next.xmin >= prev.xmax) { return int((float(prev.xmax + next.xmin) - cursor_width) / 2.0f); } - /* Possible with RTL. */ + /* A nicer center if reversed order - RTL. */ return int((float(next.xmax + prev.xmin) - cursor_width) / 2.0f); } else if (!str_offset) { - /* Before first space character. */ + /* Start of string. */ return 0 - int(cursor_width); } else { - /* After last character. */ return int(blf_font_width(font, str, str_len, nullptr)); } } -- 2.30.2