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:
authorCampbell Barton <ideasman42@gmail.com>2020-04-28 06:25:43 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-04-28 06:34:56 +0300
commite78470d95411764c59af58dc996398a02bc40ae6 (patch)
treee6e325a1b5e0e017f4341ceaa65f0140b361ccdc /source/blender/blenfont/intern
parent33017e952913a3be04e7ac8b720a12fd9d33a76f (diff)
BLF: add utility function to loop over glyph bounds
Diffstat (limited to 'source/blender/blenfont/intern')
-rw-r--r--source/blender/blenfont/intern/blf.c36
-rw-r--r--source/blender/blenfont/intern/blf_font.c78
-rw-r--r--source/blender/blenfont/intern/blf_internal.h12
-rw-r--r--source/blender/blenfont/intern/blf_util.c4
4 files changed, 128 insertions, 2 deletions
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 520456653d1..394704e1c20 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -682,6 +682,42 @@ int BLF_draw_mono(int fontid, const char *str, size_t len, int cwidth)
return columns;
}
+/**
+ * Run \a user_fn for each character, with the bound-box that would be used for drawing.
+ *
+ * \param user_fn: Callback that runs on each glyph, returning false early exits.
+ * \param user_data: User argument passed to \a user_fn.
+ *
+ * \note The font position, clipping, matrix and rotation are not applied.
+ */
+void BLF_boundbox_foreach_glyph_ex(int fontid,
+ const char *str,
+ size_t len,
+ BLF_GlyphBoundsFn user_fn,
+ void *user_data,
+ struct ResultBLF *r_info)
+{
+ 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, len, user_fn, user_data, r_info);
+ }
+ }
+}
+
+void BLF_boundbox_foreach_glyph(
+ int fontid, const char *str, size_t len, BLF_GlyphBoundsFn user_fn, void *user_data)
+{
+ BLF_boundbox_foreach_glyph_ex(fontid, str, len, user_fn, user_data, NULL);
+}
+
size_t BLF_width_to_strlen(int fontid, const char *str, size_t len, float width, float *r_width)
{
FontBLF *font = blf_get(fontid);
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index 0f93f2ca07b..ed92e9aaff2 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -1201,6 +1201,84 @@ float blf_font_fixed_width(FontBLF *font)
return g->advance;
}
+/* -------------------------------------------------------------------- */
+/** \name Glyph Bound Box with Callback
+ * \{ */
+
+static void blf_font_boundbox_foreach_glyph_ex(FontBLF *font,
+ GlyphCacheBLF *gc,
+ const char *str,
+ size_t len,
+ BLF_GlyphBoundsFn user_fn,
+ void *user_data,
+ struct ResultBLF *r_info,
+ int pen_y)
+{
+ unsigned int c, c_prev = BLI_UTF8_ERR;
+ GlyphBLF *g, *g_prev = NULL;
+ int pen_x = 0;
+ size_t i = 0, i_curr;
+ rcti gbox;
+
+ if (len == 0) {
+ /* early output. */
+ return;
+ }
+
+ GlyphBLF **glyph_ascii_table = blf_font_ensure_ascii_table(font, gc);
+
+ BLF_KERNING_VARS(font, has_kerning, kern_mode);
+
+ blf_font_ensure_ascii_kerning(font, gc, kern_mode);
+
+ while ((i < len) && str[i]) {
+ i_curr = i;
+ BLF_UTF8_NEXT_FAST(font, gc, g, str, i, c, glyph_ascii_table);
+
+ if (UNLIKELY(c == BLI_UTF8_ERR)) {
+ break;
+ }
+ if (UNLIKELY(g == NULL)) {
+ continue;
+ }
+ if (has_kerning) {
+ BLF_KERNING_STEP_FAST(font, kern_mode, g_prev, g, c_prev, c, pen_x);
+ }
+
+ gbox.xmin = pen_x;
+ gbox.xmax = gbox.xmin + MIN2(g->advance_i, g->width);
+ gbox.ymin = pen_y;
+ gbox.ymax = gbox.ymin - g->height;
+
+ pen_x += g->advance_i;
+
+ if (user_fn(str, i_curr, &gbox, g->advance_i, user_data) == false) {
+ break;
+ }
+
+ g_prev = g;
+ c_prev = c;
+ }
+
+ if (r_info) {
+ r_info->lines = 1;
+ r_info->width = pen_x;
+ }
+}
+void blf_font_boundbox_foreach_glyph(FontBLF *font,
+ const char *str,
+ size_t len,
+ BLF_GlyphBoundsFn user_fn,
+ void *user_data,
+ struct ResultBLF *r_info)
+{
+ GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
+ blf_font_boundbox_foreach_glyph_ex(font, gc, str, len, user_fn, user_data, r_info, 0);
+ blf_glyph_cache_release(font);
+}
+
+/** \} */
+
int blf_font_count_missing_chars(FontBLF *font,
const char *str,
const size_t len,
diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h
index efcf9e15100..98ada87d16d 100644
--- a/source/blender/blenfont/intern/blf_internal.h
+++ b/source/blender/blenfont/intern/blf_internal.h
@@ -29,6 +29,7 @@ struct GlyphBLF;
struct GlyphCacheBLF;
struct ResultBLF;
struct rctf;
+struct rcti;
void blf_batch_draw_vao_clear(void);
void blf_batch_draw_begin(struct FontBLF *font);
@@ -98,6 +99,17 @@ int blf_font_width_max(struct FontBLF *font);
float blf_font_descender(struct FontBLF *font);
float blf_font_ascender(struct FontBLF *font);
+void blf_font_boundbox_foreach_glyph(struct FontBLF *font,
+ const char *str,
+ size_t len,
+ bool (*user_fn)(const char *str,
+ const size_t str_ofs,
+ const struct rcti *glyph_bounds,
+ const int glyph_advance_x,
+ void *user_data),
+ void *user_data,
+ struct ResultBLF *r_info);
+
int blf_font_count_missing_chars(struct FontBLF *font,
const char *str,
const size_t len,
diff --git a/source/blender/blenfont/intern/blf_util.c b/source/blender/blenfont/intern/blf_util.c
index e55759199a2..a70a9ea6819 100644
--- a/source/blender/blenfont/intern/blf_util.c
+++ b/source/blender/blenfont/intern/blf_util.c
@@ -27,10 +27,10 @@
#include <stdlib.h>
#include <string.h>
-#include "blf_internal.h"
-
#include "BLI_utildefines.h"
+#include "blf_internal.h"
+
unsigned int blf_next_p2(unsigned int x)
{
x -= 1;