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>2021-10-29 04:49:21 +0300
committerHarley Acheson <harley.acheson@gmail.com>2021-10-29 04:49:21 +0300
commit70947ebc65a618f2d5e156427aae59780926653c (patch)
tree3469f89068aa4afdc0302eb196a70f0673be93ce
parent59534dbee2effd6a4880a0f26329e0571f943207 (diff)
BLF Refactor: blf_utf8_next_fast
Simplification of BLF glyph loading See D13026 for details. Differential Revision: https://developer.blender.org/D13026 Reviewed by Campbell Barton
-rw-r--r--source/blender/blenfont/intern/blf_font.c26
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c110
-rw-r--r--source/blender/blenfont/intern/blf_internal.h7
3 files changed, 61 insertions, 82 deletions
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index dd133e75f49..52c412a42bb 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -300,24 +300,8 @@ static void blf_batch_draw_end(void)
BLI_INLINE GlyphBLF *blf_utf8_next_fast(
FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t str_len, size_t *i_p)
{
- GlyphBLF *g;
- uint charcode = (uint)str[*i_p];
- if (charcode < GLYPH_ASCII_TABLE_SIZE) {
- g = (gc->glyph_ascii_table)[charcode];
- if (UNLIKELY(g == NULL)) {
- g = blf_glyph_add(font, gc, FT_Get_Char_Index(font->face, charcode), charcode);
- gc->glyph_ascii_table[charcode] = g;
- }
- (*i_p)++;
- }
- else {
- charcode = BLI_str_utf8_as_unicode_step(str, str_len, i_p);
- g = blf_glyph_search(gc, charcode);
- if (UNLIKELY(g == NULL)) {
- g = blf_glyph_add(font, gc, FT_Get_Char_Index(font->face, charcode), charcode);
- }
- }
- return g;
+ uint charcode = BLI_str_utf8_as_unicode_step(str, str_len, i_p);
+ return blf_glyph_ensure(font, gc, charcode);
}
BLI_INLINE int blf_kerning(FontBLF *font, const GlyphBLF *g_prev, const GlyphBLF *g)
@@ -388,7 +372,7 @@ static void blf_font_draw_ex(FontBLF *font,
pen_x += blf_kerning(font, g_prev, g);
/* do not return this loop if clipped, we want every character tested */
- blf_glyph_render(font, gc, g, (float)pen_x, (float)pen_y);
+ blf_glyph_draw(font, gc, g, (float)pen_x, (float)pen_y);
pen_x += g->advance_i;
g_prev = g;
@@ -431,7 +415,7 @@ int blf_font_draw_mono(FontBLF *font, const char *str, const size_t str_len, int
}
/* do not return this loop if clipped, we want every character tested */
- blf_glyph_render(font, gc, g, (float)pen_x, (float)pen_y);
+ blf_glyph_draw(font, gc, g, (float)pen_x, (float)pen_y);
col = BLI_wcwidth((char32_t)g->c);
if (col < 0) {
@@ -857,7 +841,7 @@ float blf_font_fixed_width(FontBLF *font)
GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
GlyphBLF *g = blf_glyph_search(gc, c);
if (!g) {
- g = blf_glyph_add(font, gc, FT_Get_Char_Index(font->face, c), c);
+ g = blf_glyph_ensure(font, gc, FT_Get_Char_Index(font->face, c));
/* if we don't find the glyph. */
if (!g) {
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index 6cdf5fc5996..e077cc91f33 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -175,33 +175,8 @@ GlyphBLF *blf_glyph_search(GlyphCacheBLF *gc, unsigned int c)
return NULL;
}
-GlyphBLF *blf_glyph_add(FontBLF *font, GlyphCacheBLF *gc, unsigned int index, unsigned int c)
+static bool blf_glyph_render(FontBLF *font, FT_UInt glyph_index)
{
- FT_GlyphSlot slot;
- GlyphBLF *g;
- FT_Error err;
- FT_Bitmap bitmap, tempbitmap;
- FT_BBox bbox;
- unsigned int key;
-
- g = blf_glyph_search(gc, c);
- if (g) {
- return g;
- }
-
- /* glyphs are dynamically created as needed by font rendering. this means that
- * to make font rendering thread safe we have to do locking here. note that this
- * must be a lock for the whole library and not just per font, because the font
- * renderer uses a shared buffer internally */
- BLI_spin_lock(font->ft_lib_mutex);
-
- /* search again after locking */
- g = blf_glyph_search(gc, c);
- if (g) {
- BLI_spin_unlock(font->ft_lib_mutex);
- return g;
- }
-
int load_flags;
int render_mode;
@@ -228,7 +203,10 @@ GlyphBLF *blf_glyph_add(FontBLF *font, GlyphCacheBLF *gc, unsigned int index, un
}
}
- err = FT_Load_Glyph(font->face, (FT_UInt)index, load_flags);
+ FT_Error err = FT_Load_Glyph(font->face, glyph_index, load_flags);
+ if (err != 0) {
+ return false;
+ }
/* Do not oblique a font that is designed to be italic! */
if (((font->flags & BLF_ITALIC) != 0) && !(font->face->style_flags & FT_STYLE_FLAG_ITALIC) &&
@@ -243,9 +221,8 @@ GlyphBLF *blf_glyph_add(FontBLF *font, GlyphCacheBLF *gc, unsigned int index, un
}
/* Do not embolden an already bold font! */
- if (((font->flags & BLF_BOLD) != 0) &&
- !(font->face->style_flags & FT_STYLE_FLAG_BOLD) &
- (font->face->glyph->format == FT_GLYPH_FORMAT_OUTLINE)) {
+ if (((font->flags & BLF_BOLD) != 0) && !(font->face->style_flags & FT_STYLE_FLAG_BOLD) &&
+ (font->face->glyph->format == FT_GLYPH_FORMAT_OUTLINE)) {
/* Strengthen the width more than the height. */
const FT_Pos extra_x = FT_MulFix(font->face->units_per_EM, font->face->size->metrics.x_scale) /
14;
@@ -263,15 +240,12 @@ GlyphBLF *blf_glyph_add(FontBLF *font, GlyphCacheBLF *gc, unsigned int index, un
}
}
- if (err) {
- BLI_spin_unlock(font->ft_lib_mutex);
- return NULL;
- }
-
/* get the glyph. */
- slot = font->face->glyph;
+ FT_GlyphSlot slot = font->face->glyph;
err = FT_Render_Glyph(slot, render_mode);
+ FT_Bitmap tempbitmap;
+
if (font->flags & BLF_MONOCHROME) {
/* Convert result from 1 bit per pixel to 8 bit per pixel */
/* Accum errors for later, fine if not interested beyond "ok vs any error" */
@@ -284,45 +258,69 @@ GlyphBLF *blf_glyph_add(FontBLF *font, GlyphCacheBLF *gc, unsigned int index, un
}
if (err || slot->format != FT_GLYPH_FORMAT_BITMAP) {
- BLI_spin_unlock(font->ft_lib_mutex);
- return NULL;
+ return false;
}
- g = (GlyphBLF *)MEM_callocN(sizeof(GlyphBLF), "blf_glyph_add");
- g->c = c;
- g->idx = (FT_UInt)index;
- bitmap = slot->bitmap;
- g->dims[0] = (int)bitmap.width;
- g->dims[1] = (int)bitmap.rows;
+ return true;
+}
- const int buffer_size = g->dims[0] * g->dims[1];
+GlyphBLF *blf_glyph_ensure(FontBLF *font, GlyphCacheBLF *gc, uint charcode)
+{
+ GlyphBLF *g = (charcode < GLYPH_ASCII_TABLE_SIZE) ? (gc->glyph_ascii_table)[charcode] :
+ blf_glyph_search(gc, charcode);
+ if (g) {
+ return g;
+ }
- if (buffer_size != 0) {
- if (font->flags & BLF_MONOCHROME) {
- /* Font buffer uses only 0 or 1 values, Blender expects full 0..255 range */
- for (int i = 0; i < buffer_size; i++) {
- bitmap.buffer[i] = bitmap.buffer[i] ? 255 : 0;
- }
- }
+ FT_UInt glyph_index = FT_Get_Char_Index(font->face, charcode);
- g->bitmap = MEM_mallocN((size_t)buffer_size, "glyph bitmap");
- memcpy(g->bitmap, bitmap.buffer, (size_t)buffer_size);
+ if (!blf_glyph_render(font, glyph_index)) {
+ return NULL;
}
+ FT_GlyphSlot slot = font->face->glyph;
+
+ /* glyphs are dynamically created as needed by font rendering. this means that
+ * to make font rendering thread safe we have to do locking here. note that this
+ * must be a lock for the whole library and not just per font, because the font
+ * renderer uses a shared buffer internally */
+ BLI_spin_lock(font->ft_lib_mutex);
+
+ g = (GlyphBLF *)MEM_callocN(sizeof(GlyphBLF), "blf_glyph_get");
+ g->c = charcode;
+ g->idx = glyph_index;
g->advance = ((float)slot->advance.x) / 64.0f;
g->advance_i = (int)g->advance;
g->pos[0] = slot->bitmap_left;
g->pos[1] = slot->bitmap_top;
+ g->dims[0] = slot->bitmap.width;
+ g->dims[1] = slot->bitmap.rows;
g->pitch = slot->bitmap.pitch;
+ FT_BBox bbox;
FT_Outline_Get_CBox(&(slot->outline), &bbox);
g->box.xmin = ((float)bbox.xMin) / 64.0f;
g->box.xmax = ((float)bbox.xMax) / 64.0f;
g->box.ymin = ((float)bbox.yMin) / 64.0f;
g->box.ymax = ((float)bbox.yMax) / 64.0f;
- key = blf_hash(g->c);
+ const int buffer_size = slot->bitmap.width * slot->bitmap.rows;
+ if (buffer_size != 0) {
+ if (font->flags & BLF_MONOCHROME) {
+ /* Font buffer uses only 0 or 1 values, Blender expects full 0..255 range */
+ for (int i = 0; i < buffer_size; i++) {
+ slot->bitmap.buffer[i] = slot->bitmap.buffer[i] ? 255 : 0;
+ }
+ }
+ g->bitmap = MEM_mallocN((size_t)buffer_size, "glyph bitmap");
+ memcpy(g->bitmap, slot->bitmap.buffer, (size_t)buffer_size);
+ }
+
+ unsigned int key = blf_hash(g->c);
BLI_addhead(&(gc->bucket[key]), g);
+ if (charcode < GLYPH_ASCII_TABLE_SIZE) {
+ gc->glyph_ascii_table[charcode] = g;
+ }
BLI_spin_unlock(font->ft_lib_mutex);
@@ -419,7 +417,7 @@ static void blf_glyph_calc_rect_shadow(rctf *rect, GlyphBLF *g, float x, float y
blf_glyph_calc_rect(rect, g, x + (float)font->shadow_x, y + (float)font->shadow_y);
}
-void blf_glyph_render(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, float x, float y)
+void blf_glyph_draw(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, float x, float y)
{
if ((!g->dims[0]) || (!g->dims[1])) {
return;
diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h
index 6fd5e8b7503..ba871ea2496 100644
--- a/source/blender/blenfont/intern/blf_internal.h
+++ b/source/blender/blenfont/intern/blf_internal.h
@@ -140,13 +140,10 @@ void blf_glyph_cache_clear(struct FontBLF *font);
void blf_glyph_cache_free(struct GlyphCacheBLF *gc);
struct GlyphBLF *blf_glyph_search(struct GlyphCacheBLF *gc, unsigned int c);
-struct GlyphBLF *blf_glyph_add(struct FontBLF *font,
- struct GlyphCacheBLF *gc,
- unsigned int index,
- unsigned int c);
+struct GlyphBLF *blf_glyph_ensure(struct FontBLF *font, struct GlyphCacheBLF *gc, uint charcode);
void blf_glyph_free(struct GlyphBLF *g);
-void blf_glyph_render(
+void blf_glyph_draw(
struct FontBLF *font, struct GlyphCacheBLF *gc, struct GlyphBLF *g, float x, float y);
#ifdef WIN32