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:
authorRichard Antalik <richardantalik@gmail.com>2019-09-14 03:22:42 +0300
committerRichard Antalik <richardantalik@gmail.com>2019-09-14 03:24:42 +0300
commita960dc451930796ca310cc88f00fb701374b2f7f (patch)
tree3bd2b69426bc36605792718e5b44e2917ac49427 /source/blender/blenfont/intern/blf_font.c
parentab3a9dc1ed28d44bd71f5e255da74ef4d6f1fdbf (diff)
BLF: make library glyph cache handling thread-safe
Functions that utilize glyph cache should lock and unlock cache by calling `blf_glyph_cache_acquire()` and `blf_glyph_cache_release()`. Function `blf_glyph_cache_acquire()` will create glyph cache, if it doesn't exist. Locking mutex is global and shared by all fonts. Reviewed By: brecht Differential Revision: https://developer.blender.org/D5701
Diffstat (limited to 'source/blender/blenfont/intern/blf_font.c')
-rw-r--r--source/blender/blenfont/intern/blf_font.c261
1 files changed, 189 insertions, 72 deletions
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index d75da6a126f..e0dfa6a2223 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -68,6 +68,7 @@ BatchBLF g_batch;
/* freetype2 handle ONLY for this file!. */
static FT_Library ft_lib;
static SpinLock ft_lib_mutex;
+static SpinLock blf_glyph_cache_mutex;
/* -------------------------------------------------------------------- */
/** \name Glyph Batching
@@ -216,6 +217,7 @@ int blf_font_init(void)
{
memset(&g_batch, 0, sizeof(g_batch));
BLI_spin_init(&ft_lib_mutex);
+ BLI_spin_init(&blf_glyph_cache_mutex);
return FT_Init_FreeType(&ft_lib);
}
@@ -223,6 +225,7 @@ void blf_font_exit(void)
{
FT_Done_FreeType(ft_lib);
BLI_spin_end(&ft_lib_mutex);
+ BLI_spin_end(&blf_glyph_cache_mutex);
blf_batch_draw_exit();
}
@@ -231,11 +234,14 @@ void blf_font_size(FontBLF *font, unsigned int size, unsigned int dpi)
GlyphCacheBLF *gc;
FT_Error err;
+ blf_glyph_cache_acquire(font);
+
gc = blf_glyph_cache_find(font, size, dpi);
if (gc) {
font->glyph_cache = gc;
/* Optimization: do not call FT_Set_Char_Size if size did not change. */
if (font->size == size && font->dpi == dpi) {
+ blf_glyph_cache_release(font);
return;
}
}
@@ -244,6 +250,8 @@ void blf_font_size(FontBLF *font, unsigned int size, unsigned int dpi)
if (err) {
/* FIXME: here we can go through the fixed size and choice a close one */
printf("The current font don't support the size, %u and dpi, %u\n", size, dpi);
+
+ blf_glyph_cache_release(font);
return;
}
@@ -259,28 +267,35 @@ void blf_font_size(FontBLF *font, unsigned int size, unsigned int dpi)
font->glyph_cache = NULL;
}
}
+ blf_glyph_cache_release(font);
}
-static void blf_font_ensure_ascii_table(FontBLF *font)
+static GlyphBLF **blf_font_ensure_ascii_table(FontBLF *font, GlyphCacheBLF *gc)
{
- GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
+ GlyphBLF **glyph_ascii_table;
+
+ glyph_ascii_table = gc->glyph_ascii_table;
/* build ascii on demand */
if (glyph_ascii_table['0'] == NULL) {
GlyphBLF *g;
unsigned int i;
for (i = 0; i < 256; i++) {
- g = blf_glyph_search(font->glyph_cache, i);
+ g = blf_glyph_search(gc, i);
if (!g) {
FT_UInt glyph_index = FT_Get_Char_Index(font->face, i);
- g = blf_glyph_add(font, glyph_index, i);
+ g = blf_glyph_add(font, gc, glyph_index, i);
}
glyph_ascii_table[i] = g;
}
}
+
+ return glyph_ascii_table;
}
-static void blf_font_ensure_ascii_kerning(FontBLF *font, const FT_UInt kern_mode)
+static void blf_font_ensure_ascii_kerning(FontBLF *font,
+ GlyphCacheBLF *gc,
+ const FT_UInt kern_mode)
{
KerningCacheBLF *kc = font->kerning_cache;
@@ -289,7 +304,7 @@ static void blf_font_ensure_ascii_kerning(FontBLF *font, const FT_UInt kern_mode
if (!kc || kc->mode != kern_mode) {
font->kerning_cache = kc = blf_kerning_cache_find(font);
if (!kc) {
- font->kerning_cache = kc = blf_kerning_cache_new(font);
+ font->kerning_cache = kc = blf_kerning_cache_new(font, gc);
}
}
}
@@ -300,16 +315,16 @@ static void blf_font_ensure_ascii_kerning(FontBLF *font, const FT_UInt kern_mode
*/
/* Note,
- * blf_font_ensure_ascii_table(font); must be called before this macro */
+ * blf_font_ensure_ascii_table(font, gc); must be called before this macro */
-#define BLF_UTF8_NEXT_FAST(_font, _g, _str, _i, _c, _glyph_ascii_table) \
+#define BLF_UTF8_NEXT_FAST(_font, _gc, _g, _str, _i, _c, _glyph_ascii_table) \
if (((_c) = (_str)[_i]) < 0x80) { \
_g = (_glyph_ascii_table)[_c]; \
_i++; \
} \
else if ((_c = BLI_str_utf8_as_unicode_step(_str, &(_i))) != BLI_UTF8_ERR) { \
- if ((_g = blf_glyph_search((_font)->glyph_cache, _c)) == NULL) { \
- _g = blf_glyph_add(_font, FT_Get_Char_Index((_font)->face, _c), _c); \
+ if ((_g = blf_glyph_search(_gc, _c)) == NULL) { \
+ _g = blf_glyph_add(_font, _gc, FT_Get_Char_Index((_font)->face, _c), _c); \
} \
} \
else { \
@@ -325,7 +340,7 @@ static void blf_font_ensure_ascii_kerning(FontBLF *font, const FT_UInt kern_mode
(FT_UInt)FT_KERNING_UNFITTED)
/* Note,
- * blf_font_ensure_ascii_kerning(font, kern_mode); must be called before this macro */
+ * blf_font_ensure_ascii_kerning(font, gc, kern_mode); must be called before this macro */
#define BLF_KERNING_STEP_FAST(_font, _kern_mode, _g_prev, _g, _c_prev, _c, _pen_x) \
{ \
@@ -353,29 +368,33 @@ static void blf_font_ensure_ascii_kerning(FontBLF *font, const FT_UInt kern_mode
} \
(void)0
-static void blf_font_draw_ex(
- FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info, int pen_y)
+static void blf_font_draw_ex(FontBLF *font,
+ GlyphCacheBLF *gc,
+ const char *str,
+ size_t len,
+ 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;
- GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
if (len == 0) {
/* early output, don't do any IMM OpenGL. */
return;
}
+ GlyphBLF **glyph_ascii_table = blf_font_ensure_ascii_table(font, gc);
+
BLF_KERNING_VARS(font, has_kerning, kern_mode);
- blf_font_ensure_ascii_table(font);
- blf_font_ensure_ascii_kerning(font, kern_mode);
+ blf_font_ensure_ascii_kerning(font, gc, kern_mode);
blf_batch_draw_begin(font);
while ((i < len) && str[i]) {
- BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
+ BLF_UTF8_NEXT_FAST(font, gc, g, str, i, c, glyph_ascii_table);
if (UNLIKELY(c == BLI_UTF8_ERR)) {
break;
@@ -388,7 +407,7 @@ static void blf_font_draw_ex(
}
/* do not return this loop if clipped, we want every character tested */
- blf_glyph_render(font, g, (float)pen_x, (float)pen_y);
+ blf_glyph_render(font, gc, g, (float)pen_x, (float)pen_y);
pen_x += g->advance_i;
g_prev = g;
@@ -404,7 +423,9 @@ static void blf_font_draw_ex(
}
void blf_font_draw(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
{
- blf_font_draw_ex(font, str, len, r_info, 0);
+ GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
+ blf_font_draw_ex(font, gc, str, len, r_info, 0);
+ blf_glyph_cache_release(font);
}
/* faster version of blf_font_draw, ascii only for view dimensions */
@@ -414,12 +435,13 @@ static void blf_font_draw_ascii_ex(
unsigned int c, c_prev = BLI_UTF8_ERR;
GlyphBLF *g, *g_prev = NULL;
int pen_x = 0;
- GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
+
+ GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
+ GlyphBLF **glyph_ascii_table = blf_font_ensure_ascii_table(font, gc);
BLF_KERNING_VARS(font, has_kerning, kern_mode);
- blf_font_ensure_ascii_table(font);
- blf_font_ensure_ascii_kerning(font, kern_mode);
+ blf_font_ensure_ascii_kerning(font, gc, kern_mode);
blf_batch_draw_begin(font);
@@ -433,7 +455,7 @@ static void blf_font_draw_ascii_ex(
}
/* do not return this loop if clipped, we want every character tested */
- blf_glyph_render(font, g, (float)pen_x, (float)pen_y);
+ blf_glyph_render(font, gc, g, (float)pen_x, (float)pen_y);
pen_x += g->advance_i;
g_prev = g;
@@ -446,7 +468,10 @@ static void blf_font_draw_ascii_ex(
r_info->lines = 1;
r_info->width = pen_x;
}
+
+ blf_glyph_cache_release(font);
}
+
void blf_font_draw_ascii(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
{
blf_font_draw_ascii_ex(font, str, len, r_info, 0);
@@ -460,14 +485,14 @@ int blf_font_draw_mono(FontBLF *font, const char *str, size_t len, int cwidth)
int col, columns = 0;
int pen_x = 0, pen_y = 0;
size_t i = 0;
- GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
- blf_font_ensure_ascii_table(font);
+ GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
+ GlyphBLF **glyph_ascii_table = blf_font_ensure_ascii_table(font, gc);
blf_batch_draw_begin(font);
while ((i < len) && str[i]) {
- BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
+ BLF_UTF8_NEXT_FAST(font, gc, g, str, i, c, glyph_ascii_table);
if (UNLIKELY(c == BLI_UTF8_ERR)) {
break;
@@ -477,7 +502,7 @@ int blf_font_draw_mono(FontBLF *font, const char *str, size_t len, int cwidth)
}
/* do not return this loop if clipped, we want every character tested */
- blf_glyph_render(font, g, (float)pen_x, (float)pen_y);
+ blf_glyph_render(font, gc, g, (float)pen_x, (float)pen_y);
col = BLI_wcwidth((wchar_t)c);
if (col < 0) {
@@ -490,19 +515,25 @@ int blf_font_draw_mono(FontBLF *font, const char *str, size_t len, int cwidth)
blf_batch_draw_end();
+ blf_glyph_cache_release(font);
return columns;
}
/* Sanity checks are done by BLF_draw_buffer() */
-static void blf_font_draw_buffer_ex(
- FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info, int pen_y)
+static void blf_font_draw_buffer_ex(FontBLF *font,
+ GlyphCacheBLF *gc,
+ const char *str,
+ size_t len,
+ struct ResultBLF *r_info,
+ int pen_y)
{
unsigned int c, c_prev = BLI_UTF8_ERR;
GlyphBLF *g, *g_prev = NULL;
int pen_x = (int)font->pos[0];
int pen_y_basis = (int)font->pos[1] + pen_y;
size_t i = 0;
- GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
+
+ GlyphBLF **glyph_ascii_table = blf_font_ensure_ascii_table(font, gc);
/* buffer specific vars */
FontBufInfoBLF *buf_info = &font->buf_info;
@@ -513,13 +544,12 @@ static void blf_font_draw_buffer_ex(
BLF_KERNING_VARS(font, has_kerning, kern_mode);
- blf_font_ensure_ascii_table(font);
- blf_font_ensure_ascii_kerning(font, kern_mode);
+ blf_font_ensure_ascii_kerning(font, gc, kern_mode);
/* another buffer specific call for color conversion */
while ((i < len) && str[i]) {
- BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
+ BLF_UTF8_NEXT_FAST(font, gc, g, str, i, c, glyph_ascii_table);
if (UNLIKELY(c == BLI_UTF8_ERR)) {
break;
@@ -647,9 +677,12 @@ static void blf_font_draw_buffer_ex(
r_info->width = pen_x;
}
}
+
void blf_font_draw_buffer(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
{
- blf_font_draw_buffer_ex(font, str, len, r_info, 0);
+ GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
+ blf_font_draw_buffer_ex(font, gc, str, len, r_info, 0);
+ blf_glyph_cache_release(font);
}
static bool blf_font_width_to_strlen_glyph_process(FontBLF *font,
@@ -684,19 +717,20 @@ size_t blf_font_width_to_strlen(
GlyphBLF *g, *g_prev;
int pen_x, width_new;
size_t i, i_prev;
- GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
+
+ GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
+ GlyphBLF **glyph_ascii_table = blf_font_ensure_ascii_table(font, gc);
const int width_i = (int)width;
BLF_KERNING_VARS(font, has_kerning, kern_mode);
- blf_font_ensure_ascii_table(font);
if (has_kerning) {
- blf_font_ensure_ascii_kerning(font, kern_mode);
+ blf_font_ensure_ascii_kerning(font, gc, kern_mode);
}
for (i_prev = i = 0, width_new = pen_x = 0, g_prev = NULL, c_prev = 0; (i < len) && str[i];
i_prev = i, width_new = pen_x, c_prev = c, g_prev = g) {
- BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
+ BLF_UTF8_NEXT_FAST(font, gc, g, str, i, c, glyph_ascii_table);
if (blf_font_width_to_strlen_glyph_process(
font, has_kerning, kern_mode, c_prev, c, g_prev, g, &pen_x, width_i)) {
@@ -708,6 +742,7 @@ size_t blf_font_width_to_strlen(
*r_width = (float)width_new;
}
+ blf_glyph_cache_release(font);
return i_prev;
}
@@ -719,14 +754,15 @@ size_t blf_font_width_to_rstrlen(
int pen_x, width_new;
size_t i, i_prev, i_tmp;
char *s, *s_prev;
- GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
+
+ GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
+ GlyphBLF **glyph_ascii_table = blf_font_ensure_ascii_table(font, gc);
const int width_i = (int)width;
BLF_KERNING_VARS(font, has_kerning, kern_mode);
- blf_font_ensure_ascii_table(font);
if (has_kerning) {
- blf_font_ensure_ascii_kerning(font, kern_mode);
+ blf_font_ensure_ascii_kerning(font, gc, kern_mode);
}
i = BLI_strnlen(str, len);
@@ -736,7 +772,7 @@ size_t blf_font_width_to_rstrlen(
i_prev = (size_t)((s_prev != NULL) ? s_prev - str : 0);
i_tmp = i;
- BLF_UTF8_NEXT_FAST(font, g, str, i_tmp, c, glyph_ascii_table);
+ BLF_UTF8_NEXT_FAST(font, gc, g, str, i_tmp, c, glyph_ascii_table);
for (width_new = pen_x = 0; (s != NULL);
i = i_prev, s = s_prev, c = c_prev, g = g_prev, g_prev = NULL, width_new = pen_x) {
s_prev = BLI_str_find_prev_char_utf8(str, s);
@@ -744,7 +780,7 @@ size_t blf_font_width_to_rstrlen(
if (s_prev != NULL) {
i_tmp = i_prev;
- BLF_UTF8_NEXT_FAST(font, g_prev, str, i_tmp, c_prev, glyph_ascii_table);
+ BLF_UTF8_NEXT_FAST(font, gc, g_prev, str, i_tmp, c_prev, glyph_ascii_table);
BLI_assert(i_tmp == i);
}
@@ -758,17 +794,24 @@ size_t blf_font_width_to_rstrlen(
*r_width = (float)width_new;
}
+ blf_glyph_cache_release(font);
return i;
}
-static void blf_font_boundbox_ex(
- FontBLF *font, const char *str, size_t len, rctf *box, struct ResultBLF *r_info, int pen_y)
+static void blf_font_boundbox_ex(FontBLF *font,
+ GlyphCacheBLF *gc,
+ const char *str,
+ size_t len,
+ rctf *box,
+ 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;
- GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
+
+ GlyphBLF **glyph_ascii_table = blf_font_ensure_ascii_table(font, gc);
rctf gbox;
@@ -779,11 +822,10 @@ static void blf_font_boundbox_ex(
box->ymin = 32000.0f;
box->ymax = -32000.0f;
- blf_font_ensure_ascii_table(font);
- blf_font_ensure_ascii_kerning(font, kern_mode);
+ blf_font_ensure_ascii_kerning(font, gc, kern_mode);
while ((i < len) && str[i]) {
- BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
+ BLF_UTF8_NEXT_FAST(font, gc, g, str, i, c, glyph_ascii_table);
if (UNLIKELY(c == BLI_UTF8_ERR)) {
break;
@@ -834,7 +876,9 @@ static void blf_font_boundbox_ex(
void blf_font_boundbox(
FontBLF *font, const char *str, size_t len, rctf *r_box, struct ResultBLF *r_info)
{
- blf_font_boundbox_ex(font, str, len, r_box, r_info, 0);
+ GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
+ blf_font_boundbox_ex(font, gc, str, len, r_box, r_info, 0);
+ blf_glyph_cache_release(font);
}
/* -------------------------------------------------------------------- */
@@ -850,23 +894,29 @@ void blf_font_boundbox(
* \note If we want rich text - we better have a higher level API to handle that
* (color, bold, switching fonts... etc).
*/
-static void blf_font_wrap_apply(
- FontBLF *font,
- const char *str,
- size_t len,
- struct ResultBLF *r_info,
- void (*callback)(FontBLF *font, const char *str, size_t len, int pen_y, void *userdata),
- void *userdata)
+static void blf_font_wrap_apply(FontBLF *font,
+ const char *str,
+ size_t len,
+ struct ResultBLF *r_info,
+ void (*callback)(FontBLF *font,
+ GlyphCacheBLF *gc,
+ const char *str,
+ size_t len,
+ int pen_y,
+ void *userdata),
+ void *userdata)
{
unsigned int c;
GlyphBLF *g, *g_prev = NULL;
FT_Vector delta;
int pen_x = 0, pen_y = 0;
size_t i = 0;
- GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
int lines = 0;
int pen_x_next = 0;
+ GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
+ GlyphBLF **glyph_ascii_table = blf_font_ensure_ascii_table(font, gc);
+
BLF_KERNING_VARS(font, has_kerning, kern_mode);
struct WordWrapVars {
@@ -874,7 +924,6 @@ static void blf_font_wrap_apply(
size_t start, last[2];
} wrap = {font->wrap_width != -1 ? font->wrap_width : INT_MAX, 0, {0, 0}};
- blf_font_ensure_ascii_table(font);
// printf("%s wrapping (%d, %d) `%s`:\n", __func__, len, strlen(str), str);
while ((i < len) && str[i]) {
@@ -882,7 +931,7 @@ static void blf_font_wrap_apply(
size_t i_curr = i;
bool do_draw = false;
- BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
+ BLF_UTF8_NEXT_FAST(font, gc, g, str, i, c, glyph_ascii_table);
if (UNLIKELY(c == BLI_UTF8_ERR)) {
break;
@@ -926,11 +975,11 @@ static void blf_font_wrap_apply(
// printf("(%03d..%03d) `%.*s`\n",
// wrap.start, wrap.last[0], (wrap.last[0] - wrap.start) - 1, &str[wrap.start]);
- callback(font, &str[wrap.start], (wrap.last[0] - wrap.start) - 1, pen_y, userdata);
+ callback(font, gc, &str[wrap.start], (wrap.last[0] - wrap.start) - 1, pen_y, userdata);
wrap.start = wrap.last[0];
i = wrap.last[1];
pen_x = 0;
- pen_y -= font->glyph_cache->glyph_height_max;
+ pen_y -= gc->glyph_height_max;
g_prev = NULL;
lines += 1;
continue;
@@ -947,13 +996,19 @@ static void blf_font_wrap_apply(
/* width of last line only (with wrapped lines) */
r_info->width = pen_x_next;
}
+
+ blf_glyph_cache_release(font);
}
/* blf_font_draw__wrap */
-static void blf_font_draw__wrap_cb(
- FontBLF *font, const char *str, size_t len, int pen_y, void *UNUSED(userdata))
+static void blf_font_draw__wrap_cb(FontBLF *font,
+ GlyphCacheBLF *gc,
+ const char *str,
+ size_t len,
+ int pen_y,
+ void *UNUSED(userdata))
{
- blf_font_draw_ex(font, str, len, NULL, pen_y);
+ blf_font_draw_ex(font, gc, str, len, NULL, pen_y);
}
void blf_font_draw__wrap(FontBLF *font, const char *str, size_t len, struct ResultBLF *r_info)
{
@@ -962,12 +1017,12 @@ void blf_font_draw__wrap(FontBLF *font, const char *str, size_t len, struct Resu
/* blf_font_boundbox__wrap */
static void blf_font_boundbox_wrap_cb(
- FontBLF *font, const char *str, size_t len, int pen_y, void *userdata)
+ FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t len, int pen_y, void *userdata)
{
rctf *box = userdata;
rctf box_single;
- blf_font_boundbox_ex(font, str, len, &box_single, NULL, pen_y);
+ blf_font_boundbox_ex(font, gc, str, len, &box_single, NULL, pen_y);
BLI_rctf_union(box, &box_single);
}
void blf_font_boundbox__wrap(
@@ -982,10 +1037,14 @@ void blf_font_boundbox__wrap(
}
/* blf_font_draw_buffer__wrap */
-static void blf_font_draw_buffer__wrap_cb(
- FontBLF *font, const char *str, size_t len, int pen_y, void *UNUSED(userdata))
+static void blf_font_draw_buffer__wrap_cb(FontBLF *font,
+ GlyphCacheBLF *gc,
+ const char *str,
+ size_t len,
+ int pen_y,
+ void *UNUSED(userdata))
{
- blf_font_draw_buffer_ex(font, str, len, NULL, pen_y);
+ blf_font_draw_buffer_ex(font, gc, str, len, NULL, pen_y);
}
void blf_font_draw_buffer__wrap(FontBLF *font,
const char *str,
@@ -1071,16 +1130,22 @@ float blf_font_height(FontBLF *font, const char *str, size_t len, struct ResultB
float blf_font_fixed_width(FontBLF *font)
{
const unsigned int c = ' ';
- GlyphBLF *g = blf_glyph_search(font->glyph_cache, c);
+
+ GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
+ blf_font_ensure_ascii_table(font, gc);
+
+ GlyphBLF *g = blf_glyph_search(gc, c);
if (!g) {
- g = blf_glyph_add(font, FT_Get_Char_Index(font->face, c), c);
+ g = blf_glyph_add(font, gc, FT_Get_Char_Index(font->face, c), c);
/* if we don't find the glyph. */
if (!g) {
+ blf_glyph_cache_release(font);
return 0.0f;
}
}
+ blf_glyph_cache_release(font);
return g->advance;
}
@@ -1111,6 +1176,7 @@ int blf_font_count_missing_chars(FontBLF *font,
void blf_font_free(FontBLF *font)
{
+ BLI_spin_lock(&blf_glyph_cache_mutex);
GlyphCacheBLF *gc;
font->glyph_cache = NULL;
@@ -1128,6 +1194,8 @@ void blf_font_free(FontBLF *font)
MEM_freeN(font->name);
}
MEM_freeN(font);
+
+ BLI_spin_unlock(&blf_glyph_cache_mutex);
}
static void blf_font_fill(FontBLF *font)
@@ -1177,6 +1245,7 @@ static void blf_font_fill(FontBLF *font)
font->ft_lib = ft_lib;
font->ft_lib_mutex = &ft_lib_mutex;
+ font->glyph_cache_mutex = &blf_glyph_cache_mutex;
}
FontBLF *blf_font_new(const char *name, const char *filename)
@@ -1250,3 +1319,51 @@ FontBLF *blf_font_new_from_mem(const char *name, const unsigned char *mem, int m
blf_font_fill(font);
return font;
}
+
+int blf_font_height_max(FontBLF *font)
+{
+ int height_max;
+
+ GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
+ blf_font_ensure_ascii_table(font, gc);
+ height_max = gc->glyph_height_max;
+
+ blf_glyph_cache_release(font);
+ return height_max;
+}
+
+int blf_font_width_max(FontBLF *font)
+{
+ int width_max;
+
+ GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
+ blf_font_ensure_ascii_table(font, gc);
+ width_max = gc->glyph_width_max;
+
+ blf_glyph_cache_release(font);
+ return width_max;
+}
+
+float blf_font_descender(FontBLF *font)
+{
+ float descender;
+
+ GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
+ blf_font_ensure_ascii_table(font, gc);
+ descender = gc->descender;
+
+ blf_glyph_cache_release(font);
+ return descender;
+}
+
+float blf_font_ascender(FontBLF *font)
+{
+ float ascender;
+
+ GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
+ blf_font_ensure_ascii_table(font, gc);
+ ascender = gc->ascender;
+
+ blf_glyph_cache_release(font);
+ return ascender;
+}