[Bf-blender-cvs] [b3714b1e85f] master: BLF: Refactor of blf_font_boundbox_foreach_glyph

Harley Acheson noreply at git.blender.org
Sun Sep 25 20:26:34 CEST 2022


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. @@



More information about the Bf-blender-cvs mailing list