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:
authorJulian Eisel <julian@blender.org>2020-06-05 14:09:31 +0300
committerJulian Eisel <julian@blender.org>2020-06-05 14:09:31 +0300
commit920a58d9b6d667894cf166cbbd25e4c2fbd238ea (patch)
tree7ca5a9da640753b5e070c439ac3bdd14dfad92cf /source/blender/blenfont
parentc94b6209861ca7cc3985b53474feed7d94c0221a (diff)
parenta1d55bdd530390e58c51abe9707b8d3b0ae3e861 (diff)
Merge branch 'master' into wm-drag-drop-rewritewm-drag-drop-rewrite
Diffstat (limited to 'source/blender/blenfont')
-rw-r--r--source/blender/blenfont/BLF_api.h21
-rw-r--r--source/blender/blenfont/intern/blf.c40
-rw-r--r--source/blender/blenfont/intern/blf_font.c114
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c78
-rw-r--r--source/blender/blenfont/intern/blf_internal.h14
-rw-r--r--source/blender/blenfont/intern/blf_internal_types.h16
-rw-r--r--source/blender/blenfont/intern/blf_thumbs.c4
-rw-r--r--source/blender/blenfont/intern/blf_util.c4
8 files changed, 209 insertions, 82 deletions
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index 9aee8c9b78b..ddb88cf61ed 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -37,6 +37,7 @@ extern "C" {
struct ColorManagedDisplay;
struct ResultBLF;
struct rctf;
+struct rcti;
int BLF_init(void);
void BLF_exit(void);
@@ -115,6 +116,26 @@ void BLF_draw_ascii_ex(int fontid, const char *str, size_t len, struct ResultBLF
void BLF_draw_ascii(int fontid, const char *str, size_t len) ATTR_NONNULL(2);
int BLF_draw_mono(int fontid, const char *str, size_t len, int cwidth) ATTR_NONNULL(2);
+typedef bool (*BLF_GlyphBoundsFn)(const char *str,
+ const size_t str_step_ofs,
+ const struct rcti *glyph_step_bounds,
+ const int glyph_advance_x,
+ const struct rctf *glyph_bounds,
+ const int glyph_bearing[2],
+ void *user_data);
+
+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) ATTR_NONNULL(2);
+void BLF_boundbox_foreach_glyph(int fontid,
+ const char *str,
+ size_t len,
+ BLF_GlyphBoundsFn user_fn,
+ void *user_data) ATTR_NONNULL(2);
+
/* Get the string byte offset that fits within a given width */
size_t BLF_width_to_strlen(int fontid, const char *str, size_t len, float width, float *r_width)
ATTR_NONNULL(2);
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 520456653d1..2f7d5a60a6f 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);
@@ -910,8 +946,8 @@ void BLF_buffer(int fontid,
if (font) {
font->buf_info.fbuf = fbuf;
font->buf_info.cbuf = cbuf;
- font->buf_info.w = w;
- font->buf_info.h = h;
+ font->buf_info.dims[0] = w;
+ font->buf_info.dims[1] = h;
font->buf_info.ch = nch;
font->buf_info.display = display;
}
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index 4d56f6f868f..e5e03418073 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -99,7 +99,7 @@ static void blf_batch_draw_init(void)
GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.glyph_size_loc, &g_batch.glyph_size_step);
g_batch.glyph_len = 0;
- /* A dummy vbo containing 4 points, attribs are not used. */
+ /* A dummy VBO containing 4 points, attributes are not used. */
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
GPU_vertbuf_data_alloc(vbo, 4);
@@ -613,28 +613,28 @@ static void blf_font_draw_buffer_ex(FontBLF *font,
BLF_KERNING_STEP_FAST(font, kern_mode, g_prev, g, c_prev, c, pen_x);
}
- chx = pen_x + ((int)g->pos_x);
- chy = pen_y_basis + g->height;
+ chx = pen_x + ((int)g->pos[0]);
+ chy = pen_y_basis + g->dims[1];
if (g->pitch < 0) {
- pen_y = pen_y_basis + (g->height - (int)g->pos_y);
+ pen_y = pen_y_basis + (g->dims[1] - g->pos[1]);
}
else {
- pen_y = pen_y_basis - (g->height - (int)g->pos_y);
+ pen_y = pen_y_basis - (g->dims[1] - g->pos[1]);
}
- if ((chx + g->width) >= 0 && chx < buf_info->w && (pen_y + g->height) >= 0 &&
- pen_y < buf_info->h) {
+ if ((chx + g->dims[0]) >= 0 && chx < buf_info->dims[0] && (pen_y + g->dims[1]) >= 0 &&
+ pen_y < buf_info->dims[1]) {
/* don't draw beyond the buffer bounds */
- int width_clip = g->width;
- int height_clip = g->height;
- int yb_start = g->pitch < 0 ? 0 : g->height - 1;
+ int width_clip = g->dims[0];
+ int height_clip = g->dims[1];
+ int yb_start = g->pitch < 0 ? 0 : g->dims[1] - 1;
- if (width_clip + chx > buf_info->w) {
- width_clip -= chx + width_clip - buf_info->w;
+ if (width_clip + chx > buf_info->dims[0]) {
+ width_clip -= chx + width_clip - buf_info->dims[0];
}
- if (height_clip + pen_y > buf_info->h) {
- height_clip -= pen_y + height_clip - buf_info->h;
+ if (height_clip + pen_y > buf_info->dims[1]) {
+ height_clip -= pen_y + height_clip - buf_info->dims[1];
}
/* drawing below the image? */
@@ -652,7 +652,7 @@ static void blf_font_draw_buffer_ex(FontBLF *font,
if (a_byte) {
const float a = (a_byte / 255.0f) * b_col_float[3];
const size_t buf_ofs = (((size_t)(chx + x) +
- ((size_t)(pen_y + y) * (size_t)buf_info->w)) *
+ ((size_t)(pen_y + y) * (size_t)buf_info->dims[0])) *
(size_t)buf_info->ch);
float *fbuf = buf_info->fbuf + buf_ofs;
@@ -689,7 +689,7 @@ static void blf_font_draw_buffer_ex(FontBLF *font,
if (a_byte) {
const float a = (a_byte / 255.0f) * b_col_float[3];
const size_t buf_ofs = (((size_t)(chx + x) +
- ((size_t)(pen_y + y) * (size_t)buf_info->w)) *
+ ((size_t)(pen_y + y) * (size_t)buf_info->dims[0])) *
(size_t)buf_info->ch);
unsigned char *cbuf = buf_info->cbuf + buf_ofs;
@@ -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->dims[0]);
+ gbox.ymin = pen_y;
+ gbox.ymax = gbox.ymin - g->dims[1];
+
+ pen_x += g->advance_i;
+
+ if (user_fn(str, i_curr, &gbox, g->advance_i, &g->box, g->pos, 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,
@@ -1287,8 +1365,8 @@ static void blf_font_fill(FontBLF *font)
font->buf_info.fbuf = NULL;
font->buf_info.cbuf = NULL;
- font->buf_info.w = 0;
- font->buf_info.h = 0;
+ font->buf_info.dims[0] = 0;
+ font->buf_info.dims[1] = 0;
font->buf_info.ch = 0;
font->buf_info.col_init[0] = 0;
font->buf_info.col_init[1] = 0;
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index a38cb323777..ce17069e53f 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -212,7 +212,7 @@ void blf_glyph_cache_free(GlyphCacheBLF *gc)
GlyphBLF *g;
unsigned int i;
- for (i = 0; i < 257; i++) {
+ for (i = 0; i < ARRAY_SIZE(gc->bucket); i++) {
while ((g = BLI_pophead(&gc->bucket[i]))) {
blf_glyph_free(g);
}
@@ -327,26 +327,27 @@ GlyphBLF *blf_glyph_add(FontBLF *font, GlyphCacheBLF *gc, unsigned int index, un
g->c = c;
g->idx = (FT_UInt)index;
bitmap = slot->bitmap;
- g->width = (int)bitmap.width;
- g->height = (int)bitmap.rows;
+ g->dims[0] = (int)bitmap.width;
+ g->dims[1] = (int)bitmap.rows;
- if (g->width && g->height) {
+ const int buffer_size = g->dims[0] * g->dims[1];
+
+ if (buffer_size != 0) {
if (font->flags & BLF_MONOCHROME) {
/* Font buffer uses only 0 or 1 values, Blender expects full 0..255 range */
- int i;
- for (i = 0; i < (g->width * g->height); i++) {
+ for (int i = 0; i < buffer_size; i++) {
bitmap.buffer[i] = bitmap.buffer[i] ? 255 : 0;
}
}
- g->bitmap = (unsigned char *)MEM_mallocN((size_t)g->width * (size_t)g->height, "glyph bitmap");
- memcpy((void *)g->bitmap, (void *)bitmap.buffer, (size_t)g->width * (size_t)g->height);
+ g->bitmap = MEM_mallocN((size_t)buffer_size, "glyph bitmap");
+ memcpy(g->bitmap, bitmap.buffer, (size_t)buffer_size);
}
g->advance = ((float)slot->advance.x) / 64.0f;
g->advance_i = (int)g->advance;
- g->pos_x = (float)slot->bitmap_left;
- g->pos_y = (float)slot->bitmap_top;
+ g->pos[0] = slot->bitmap_left;
+ g->pos[1] = slot->bitmap_top;
g->pitch = slot->bitmap.pitch;
FT_Outline_Get_CBox(&(slot->outline), &bbox);
@@ -431,10 +432,10 @@ static void blf_texture3_draw(const unsigned char color_in[4],
static void blf_glyph_calc_rect(rctf *rect, GlyphBLF *g, float x, float y)
{
- rect->xmin = floorf(x + g->pos_x);
- rect->xmax = rect->xmin + (float)g->width;
- rect->ymin = floorf(y + g->pos_y);
- rect->ymax = rect->ymin - (float)g->height;
+ rect->xmin = floorf(x + (float)g->pos[0]);
+ rect->xmax = rect->xmin + (float)g->dims[0];
+ rect->ymin = floorf(y + (float)g->pos[1]);
+ rect->ymax = rect->ymin - (float)g->dims[1];
}
static void blf_glyph_calc_rect_test(rctf *rect, GlyphBLF *g, float x, float y)
@@ -443,9 +444,9 @@ static void blf_glyph_calc_rect_test(rctf *rect, GlyphBLF *g, float x, float y)
* width used by BLF_width. This allows that the text slightly
* overlaps the clipping border to achieve better alignment. */
rect->xmin = floorf(x);
- rect->xmax = rect->xmin + MIN2(g->advance, (float)g->width);
+ rect->xmax = rect->xmin + MIN2(g->advance, (float)g->dims[0]);
rect->ymin = floorf(y);
- rect->ymax = rect->ymin - (float)g->height;
+ rect->ymax = rect->ymin - (float)g->dims[1];
}
static void blf_glyph_calc_rect_shadow(rctf *rect, GlyphBLF *g, float x, float y, FontBLF *font)
@@ -455,7 +456,7 @@ static void blf_glyph_calc_rect_shadow(rctf *rect, GlyphBLF *g, float x, float y
void blf_glyph_render(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, float x, float y)
{
- if ((!g->width) || (!g->height)) {
+ if ((!g->dims[0]) || (!g->dims[1])) {
return;
}
@@ -466,7 +467,7 @@ void blf_glyph_render(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, float x, fl
g->offset = gc->bitmap_len;
- int buff_size = g->width * g->height;
+ int buff_size = g->dims[0] * g->dims[1];
int bitmap_len = gc->bitmap_len + buff_size;
if (bitmap_len > gc->bitmap_len_alloc) {
@@ -514,7 +515,7 @@ void blf_glyph_render(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, float x, fl
if (font->shadow == 0) {
blf_texture_draw(font->shadow_color,
- (int[2]){g->width, g->height},
+ g->dims,
g->offset,
rect_ofs.xmin,
rect_ofs.ymin,
@@ -523,7 +524,7 @@ void blf_glyph_render(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, float x, fl
}
else if (font->shadow <= 4) {
blf_texture3_draw(font->shadow_color,
- (int[2]){g->width, g->height},
+ g->dims,
g->offset,
rect_ofs.xmin,
rect_ofs.ymin,
@@ -532,7 +533,7 @@ void blf_glyph_render(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, float x, fl
}
else {
blf_texture5_draw(font->shadow_color,
- (int[2]){g->width, g->height},
+ g->dims,
g->offset,
rect_ofs.xmin,
rect_ofs.ymin,
@@ -547,39 +548,18 @@ void blf_glyph_render(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, float x, fl
#if BLF_BLUR_ENABLE
switch (font->blur) {
case 3:
- blf_texture3_draw(font->color,
- (int[2]){g->width, g->height},
- g->offset,
- rect.xmin,
- rect.ymin,
- rect.xmax,
- rect.ymax);
+ blf_texture3_draw(
+ font->color, g->dims, g->offset, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
break;
case 5:
- blf_texture5_draw(font->color,
- (int[2]){g->width, g->height},
- g->offset,
- rect.xmin,
- rect.ymin,
- rect.xmax,
- rect.ymax);
+ blf_texture5_draw(
+ font->color, g->dims, g->offset, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
break;
default:
- blf_texture_draw(font->color,
- (int[2]){g->width, g->height},
- g->offset,
- rect.xmin,
- rect.ymin,
- rect.xmax,
- rect.ymax);
+ blf_texture_draw(
+ font->color, g->dims, g->offset, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
}
#else
- blf_texture_draw(font->color,
- (int[2]){g->width, g->height},
- g->offset,
- rect.xmin,
- rect.ymin,
- rect.xmax,
- rect.ymax);
+ blf_texture_draw(font->color, g->dims, g->offset, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
#endif
}
diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h
index efcf9e15100..4ae592d323f 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,19 @@ 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_step_ofs,
+ const struct rcti *glyph_step_bounds,
+ const int glyph_advance_x,
+ const struct rctf *glyph_bounds,
+ const int glyph_bearing[2],
+ 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_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h
index 6fae3eb4376..362cbf6730f 100644
--- a/source/blender/blenfont/intern/blf_internal_types.h
+++ b/source/blender/blenfont/intern/blf_internal_types.h
@@ -119,17 +119,16 @@ typedef struct GlyphBLF {
*/
unsigned char *bitmap;
- /* glyph width and height. */
- int width;
- int height;
+ /* Glyph width and height. */
+ int dims[2];
int pitch;
- /* X and Y bearing of the glyph.
+ /**
+ * X and Y bearing of the glyph.
* The X bearing is from the origin to the glyph left bbox edge.
* The Y bearing is from the baseline to the top of the glyph edge.
*/
- float pos_x;
- float pos_y;
+ int pos[2];
struct GlyphCacheBLF *glyph_cache;
} GlyphBLF;
@@ -141,9 +140,8 @@ typedef struct FontBufInfoBLF {
/* the same but unsigned char */
unsigned char *cbuf;
- /* buffer size, keep signed so comparisons with negative values work */
- int w;
- int h;
+ /** Buffer size, keep signed so comparisons with negative values work. */
+ int dims[2];
/* number of channels. */
int ch;
diff --git a/source/blender/blenfont/intern/blf_thumbs.c b/source/blender/blenfont/intern/blf_thumbs.c
index b7308d47d71..37eed29f6fe 100644
--- a/source/blender/blenfont/intern/blf_thumbs.c
+++ b/source/blender/blenfont/intern/blf_thumbs.c
@@ -78,8 +78,8 @@ void BLF_thumb_preview(const char *filename,
/* Would be done via the BLF API, but we're not using a fontid here */
font->buf_info.cbuf = buf;
font->buf_info.ch = channels;
- font->buf_info.w = w;
- font->buf_info.h = h;
+ font->buf_info.dims[0] = w;
+ font->buf_info.dims[1] = h;
/* Always create the image with a white font,
* the caller can theme how it likes */
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;