Page MenuHome

BLF Refactor: blf_utf8_next_fast
ClosedPublic

Authored by Harley Acheson (harley) on Oct 28 2021, 11:34 PM.

Details

Summary

Simplification of BLF glyph loading


This meant to be a bookend to D13015, which simplifies peer function blf_kerning_step_fast.

We have many string printing loops that call *blf_utf8_next_fast which looks like this:

BLI_INLINE GlyphBLF *blf_utf8_next_fast(
    FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t str_len, size_t *i_p, uint *r_c)
{
  GlyphBLF *g;
  if ((*r_c = str[*i_p]) < GLYPH_ASCII_TABLE_SIZE) {
    g = (gc->glyph_ascii_table)[*r_c];
    if (UNLIKELY(g == NULL)) {
      g = blf_glyph_add(font, gc, FT_Get_Char_Index(font->face, *r_c), *r_c);
      gc->glyph_ascii_table[*r_c] = g;
    }
    (*i_p)++;
  }
  else {
    *r_c = BLI_str_utf8_as_unicode_step(str, str_len, i_p);
    g = blf_glyph_search(gc, *r_c);
    if (UNLIKELY(g == NULL)) {
      g = blf_glyph_add(font, gc, FT_Get_Char_Index(font->face, *r_c), *r_c);
    }
  }
  return g;
}

This patch reduces it to this:

BLI_INLINE GlyphBLF *blf_utf8_next_fast(
    FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t str_len, size_t *i_p, uint *UNUSED(r_c))
{
  int charcode = BLI_str_utf8_as_unicode_step(str, str_len, i_p);
  return blf_glyph_get(font, gc, charcode);
}

The current code has duplicated sections depending on whether the character is ASCII or not. But this isn't really a speedup since the "slow" path does the same check and exits just as quickly for ascii. BLI_str_utf8_as_unicode_step checks if the current character is ascii, if yes then length is one, and therefore done.

But the most confusing part of this code is that it fiddles with a cache, then calls blf_glyph_add which normally retrieves from a cache, then it fiddles with a cache again. This is really just the retrieval of a glyph based on a codepoint, and the fact it may or may not come from a cache is something that should be not be a concern for the consumer here.

To do this we first rename existing blf_glyph_render to blf_glyph_draw. To "render" a glyph in this context has very specific meaning: to have FreeType create a bitmap image from a glyph's curves. The existing blf_glyph_render doesn't do this but draws out a glyph, already rendered. Calling it "glyph_draw" fits it much better.

Existing blf_glyph_add is then broken into two pieces. We get a new blf_glyph_render that does nothing but render a single glyph based on a glyph index.

And we get a blf_glyph_get that always just returns a glyph. If it can do so from its cache it does so. If not it creates a new one, using blf_glyph_render, and then updates its cache.

Diff Detail

Repository
rB Blender

Event Timeline

Harley Acheson (harley) requested review of this revision.Oct 28 2021, 11:34 PM
Harley Acheson (harley) created this revision.

Accepting with only minor requests.

source/blender/blenfont/intern/blf_font.c
303

Should be uint (by convention). Although we could move to char32_t eventually.

source/blender/blenfont/intern/blf_glyph.c
267–273

Picky, prefer uint over unsigned int.

source/blender/blenfont/intern/blf_internal.h
142–143

Prefer ensure over get since this adds when it doesn't exist.

This revision is now accepted and ready to land.Oct 29 2021, 2:03 AM

Updated to current state of master and to incorporate all review requests.

This revision was automatically updated to reflect the committed changes.