From a960dc451930796ca310cc88f00fb701374b2f7f Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Fri, 13 Sep 2019 17:22:42 -0700 Subject: 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 --- source/blender/blenfont/intern/blf_font.c | 261 +++++++++++++++++++++--------- 1 file changed, 189 insertions(+), 72 deletions(-) (limited to 'source/blender/blenfont/intern/blf_font.c') 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; +} -- cgit v1.2.3