Commit: b3714b1e85fd81d4f7db3c562483232fd6a89807 Author: Harley Acheson Date: Sun Sep 25 11:25:31 2022 -0700 Branches: master https://developer.blender.org/rBb3714b1e85fd81d4f7db3c562483232fd6a89807
BLF: Refactor of blf_font_boundbox_foreach_glyph Refactor of `BLF_boundbox_foreach_glyph` and simplification of its usage by only passing translated glyph bounds to callbacks. See D15765 for more details. Differential Revision: https://developer.blender.org/D15765 Reviewed by Campbell Barton =================================================================== M source/blender/blenfont/BLF_api.h M source/blender/blenfont/intern/blf.c M source/blender/blenfont/intern/blf_font.c M source/blender/blenfont/intern/blf_internal.h M source/blender/editors/interface/interface_handlers.c M source/blender/editors/interface/interface_widgets.c =================================================================== diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h index af2e4fd1784..01b6d1d8942 100644 --- a/source/blender/blenfont/BLF_api.h +++ b/source/blender/blenfont/BLF_api.h @@ -118,10 +118,7 @@ int BLF_draw_mono(int fontid, const char *str, size_t str_len, int cwidth) ATTR_ typedef bool (*BLF_GlyphBoundsFn)(const char *str, size_t str_step_ofs, - const struct rcti *glyph_step_bounds, - int glyph_advance_x, - const struct rcti *glyph_bounds, - const int glyph_bearing[2], + const struct rcti *bounds, void *user_data); /** @@ -132,18 +129,28 @@ typedef bool (*BLF_GlyphBoundsFn)(const char *str, * * \note The font position, clipping, matrix and rotation are not applied. */ -void BLF_boundbox_foreach_glyph_ex(int fontid, - const char *str, - size_t str_len, - BLF_GlyphBoundsFn user_fn, - void *user_data, - struct ResultBLF *r_info) ATTR_NONNULL(2); void BLF_boundbox_foreach_glyph(int fontid, const char *str, size_t str_len, BLF_GlyphBoundsFn user_fn, void *user_data) ATTR_NONNULL(2); +/** + * Get the byte offset within a string, selected by mouse at a horizontal location. + */ +size_t BLF_str_offset_from_cursor_position(int fontid, + const char *str, + size_t str_len, + int location_x); + +/** + * Return bounds of the glyph rect at the string offset. + */ +bool BLF_str_offset_to_glyph_bounds(int fontid, + const char *str, + size_t str_offset, + struct rcti *glyph_bounds); + /** * Get the string byte offset that fits within a given width. */ diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index df8a9734c9a..57c1e280e8d 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -563,32 +563,45 @@ int BLF_draw_mono(int fontid, const char *str, const size_t str_len, int cwidth) return columns; } -void BLF_boundbox_foreach_glyph_ex(int fontid, - const char *str, - size_t str_len, - BLF_GlyphBoundsFn user_fn, - void *user_data, - struct ResultBLF *r_info) +void BLF_boundbox_foreach_glyph( + int fontid, const char *str, size_t str_len, BLF_GlyphBoundsFn user_fn, void *user_data) { FontBLF *font = blf_get(fontid); - BLF_RESULT_CHECK_INIT(r_info); - if (font) { if (font->flags & BLF_WORD_WRAP) { /* TODO: word-wrap support. */ BLI_assert(0); } else { - blf_font_boundbox_foreach_glyph(font, str, str_len, user_fn, user_data, r_info); + blf_font_boundbox_foreach_glyph(font, str, str_len, user_fn, user_data); } } } -void BLF_boundbox_foreach_glyph( - int fontid, const char *str, const size_t str_len, BLF_GlyphBoundsFn user_fn, void *user_data) +size_t BLF_str_offset_from_cursor_position(int fontid, + const char *str, + size_t str_len, + int location_x) { - BLF_boundbox_foreach_glyph_ex(fontid, str, str_len, user_fn, user_data, NULL); + FontBLF *font = blf_get(fontid); + if (font) { + return blf_str_offset_from_cursor_position(font, str, str_len, location_x); + } + return 0; +} + +bool BLF_str_offset_to_glyph_bounds(int fontid, + const char *str, + size_t str_offset, + rcti *glyph_bounds) +{ + FontBLF *font = blf_get(fontid); + if (font) { + blf_str_offset_to_glyph_bounds(font, str, str_offset, glyph_bounds); + return true; + } + return false; } size_t BLF_width_to_strlen( diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index 9ea7e529df2..cbf656289b5 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -901,25 +901,23 @@ float blf_font_fixed_width(FontBLF *font) return width; } -static void blf_font_boundbox_foreach_glyph_ex(FontBLF *font, - GlyphCacheBLF *gc, - const char *str, - const size_t str_len, - BLF_GlyphBoundsFn user_fn, - void *user_data, - struct ResultBLF *r_info, - ft_pix pen_y) +void blf_font_boundbox_foreach_glyph(FontBLF *font, + const char *str, + const size_t str_len, + BLF_GlyphBoundsFn user_fn, + void *user_data) { GlyphBLF *g, *g_prev = NULL; ft_pix pen_x = 0; size_t i = 0, i_curr; - rcti gbox_px; if (str_len == 0 || str[0] == 0) { /* early output. */ return; } + GlyphCacheBLF *gc = blf_glyph_cache_acquire(font); + while ((i < str_len) && str[i]) { i_curr = i; g = blf_glyph_from_utf8_and_step(font, gc, str, str_len, &i); @@ -928,44 +926,88 @@ static void blf_font_boundbox_foreach_glyph_ex(FontBLF *font, continue; } pen_x += blf_kerning(font, g_prev, g); - const ft_pix pen_x_next = ft_pix_round_advance(pen_x, g->advance_x); - - gbox_px.xmin = ft_pix_to_int_floor(pen_x); - gbox_px.xmax = ft_pix_to_int_ceil(pen_x_next); - gbox_px.ymin = ft_pix_to_int_floor(pen_y); - gbox_px.ymax = gbox_px.ymin - g->dims[1]; - const int advance_x_px = gbox_px.xmax - gbox_px.xmin; - - pen_x = pen_x_next; - rcti box_px; - box_px.xmin = ft_pix_to_int_floor(g->box_xmin); - box_px.xmax = ft_pix_to_int_ceil(g->box_xmax); - box_px.ymin = ft_pix_to_int_floor(g->box_ymin); - box_px.ymax = ft_pix_to_int_ceil(g->box_ymax); + rcti bounds; + bounds.xmin = ft_pix_to_int_floor(pen_x) + ft_pix_to_int_floor(g->box_xmin); + bounds.xmax = ft_pix_to_int_floor(pen_x) + ft_pix_to_int_ceil(g->box_xmax); + bounds.ymin = ft_pix_to_int_floor(g->box_ymin); + bounds.ymax = ft_pix_to_int_ceil(g->box_ymax); - if (user_fn(str, i_curr, &gbox_px, advance_x_px, &box_px, g->pos, user_data) == false) { + if (user_fn(str, i_curr, &bounds, user_data) == false) { break; } - + pen_x = ft_pix_round_advance(pen_x, g->advance_x); g_prev = g; } - if (r_info) { - r_info->lines = 1; - r_info->width = ft_pix_to_int(pen_x); + blf_glyph_cache_release(font); +} + +typedef struct CursorPositionForeachGlyph_Data { + /** Horizontal position to test. */ + int location_x; + /** Write the character offset here. */ + size_t r_offset; +} CursorPositionForeachGlyph_Data; + +static bool blf_cursor_position_foreach_glyph(const char *UNUSED(str), + const size_t str_step_ofs, + const rcti *bounds, + void *user_data) +{ + CursorPositionForeachGlyph_Data *data = user_data; + if (data->location_x < (bounds->xmin + bounds->xmax) / 2) { + data->r_offset = str_step_ofs; + return false; } + return true; } -void blf_font_boundbox_foreach_glyph(FontBLF *font, - const char *str, - const size_t str_len, - BLF_GlyphBoundsFn user_fn, - void *user_data, - struct ResultBLF *r_info) + +size_t blf_str_offset_from_cursor_position(struct FontBLF *font, + const char *str, + size_t str_len, + int location_x) { - GlyphCacheBLF *gc = blf_glyph_cache_acquire(font); - blf_font_boundbox_foreach_glyph_ex(font, gc, str, str_len, user_fn, user_data, r_info, 0); - blf_glyph_cache_release(font); + CursorPositionForeachGlyph_Data data = { + .location_x = location_x, + .r_offset = (size_t)-1, + }; + blf_font_boundbox_foreach_glyph(font, str, str_len, blf_cursor_position_foreach_glyph, &data); + if (data.r_offset == (size_t)-1) { + data.r_offset = BLI_strnlen(str, str_len); + } + return data.r_offset; +} + +typedef struct StrOffsetToGlyphBounds_Data { + size_t str_offset; + rcti bounds; +} StrOffsetToGlyphBounds_Data; + +static bool blf_str_offset_foreach_glyph(const char *UNUSED(str), + const size_t str_step_ofs, + const rcti *bounds, + void *user_data) +{ + StrOffsetToGlyphBounds_Data *data = user_data; + if (data->str_offset == str_step_ofs) { + data->bounds = *bounds; + return false; + } + return true; +} + +void blf_str_offset_to_glyph_bounds(struct FontBLF *font, + const char *str, + size_t str_offset, + rcti *glyph_bounds) +{ + StrOffsetToGlyphBounds_Data data = { + .str_offset = str_offset, + .bounds = {0}, + }; + blf_font_boundbox_foreach_glyph(font, str, str_offset + 1, blf_str_offset_foreach_glyph, &data); + *glyph_bounds = data.bounds; } /** \} @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs