Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarley Acheson <harley.acheson@gmail.com>2022-09-25 21:25:31 +0300
committerHarley Acheson <harley.acheson@gmail.com>2022-09-25 21:25:31 +0300
commitb3714b1e85fd81d4f7db3c562483232fd6a89807 (patch)
treee2758ecd3624bd7670df77df2c65c004cc510ea5 /source/blender/blenfont/intern/blf_font.c
parentc8ee70c96200548699a2d038a93208c5723f91e7 (diff)
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
Diffstat (limited to 'source/blender/blenfont/intern/blf_font.c')
-rw-r--r--source/blender/blenfont/intern/blf_font.c116
1 files changed, 79 insertions, 37 deletions
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;
}
/** \} */