From c4000467026a1ff28eebf9cafe4a7888f814a143 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 11 Sep 2011 08:12:16 +0000 Subject: speedup font drawing: for ascii characters in a utf8 string use glyph_ascii_table lookup rather than call blf_glyph_search(), otherwise fallback to blf_utf8_next() and blf_glyph_search(). --- source/blender/blenfont/intern/blf_font.c | 105 +++++++++++++++----------- source/blender/blenfont/intern/blf_internal.h | 2 +- source/blender/blenfont/intern/blf_util.c | 2 +- 3 files changed, 65 insertions(+), 44 deletions(-) (limited to 'source/blender/blenfont') diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index fb6505fe935..52aace1d3d7 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -97,14 +97,52 @@ void blf_font_size(FontBLF *font, int size, int dpi) } } +static void blf_font_ensure_ascii_table(FontBLF *font) +{ + /* build ascii on demand */ + if(font->glyph_ascii_table['0']==NULL) { + GlyphBLF *g; + unsigned int i; + for(i=0; i<256; i++) { + g= blf_glyph_search(font->glyph_cache, i); + if (!g) { + FT_UInt glyph_index= FT_Get_Char_Index(font->face, i); + g= blf_glyph_add(font, glyph_index, i); + } + font->glyph_ascii_table[i]= g; + } + } +} + +/* Fast path for runs of ASCII characters. Given that common UTF-8 + * input will consist of an overwhelming majority of ASCII + * characters. + */ + +/* Note, + * blf_font_ensure_ascii_table(font); must be called before this macro */ + +#define BLF_UTF8_NEXT_FAST(font, g, str, i, c) \ + if(((c)= (str)[i]) < 0x80) { \ + g= (font)->glyph_ascii_table[c]; \ + i++; \ + } \ + else if ((c= blf_utf8_next((unsigned char *)(str), &(i)))) { \ + if ((g= blf_glyph_search((font)->glyph_cache, c)) == NULL) { \ + g= blf_glyph_add(font, FT_Get_Char_Index((font)->face, c), c); \ + } \ + } \ + + + void blf_font_draw(FontBLF *font, const char *str, unsigned int len) { unsigned int c; GlyphBLF *g, *g_prev; FT_Vector delta; - FT_UInt glyph_index; int pen_x, pen_y; - int i, has_kerning, st; + int has_kerning, st; + unsigned int i; if (!font->glyph_cache) return; @@ -115,17 +153,15 @@ void blf_font_draw(FontBLF *font, const char *str, unsigned int len) has_kerning= FT_HAS_KERNING(font->face); g_prev= NULL; + blf_font_ensure_ascii_table(font); + while (str[i] && i < len) { - c= blf_utf8_next((unsigned char *)str, &i); + + BLF_UTF8_NEXT_FAST(font, g, str, i, c); + if (c == 0) break; - g= blf_glyph_search(font->glyph_cache, c); - if (!g) { - glyph_index= FT_Get_Char_Index(font->face, c); - g= blf_glyph_add(font, glyph_index, c); - } - /* if we don't found a glyph, skip it. */ if (!g) continue; @@ -157,9 +193,8 @@ void blf_font_draw_ascii(FontBLF *font, const char *str, unsigned int len) char c; GlyphBLF *g, *g_prev; FT_Vector delta; - FT_UInt glyph_index; int pen_x, pen_y; - int i, has_kerning, st; + int has_kerning, st; if (!font->glyph_cache) return; @@ -169,18 +204,8 @@ void blf_font_draw_ascii(FontBLF *font, const char *str, unsigned int len) has_kerning= FT_HAS_KERNING(font->face); g_prev= NULL; - /* build ascii on demand */ - if(font->glyph_ascii_table['0']==NULL) { - for(i=0; i<256; i++) { - g= blf_glyph_search(font->glyph_cache, i); - if (!g) { - glyph_index= FT_Get_Char_Index(font->face, i); - g= blf_glyph_add(font, glyph_index, i); - } - font->glyph_ascii_table[i]= g; - } - } - + blf_font_ensure_ascii_table(font); + while ((c= *(str++)) && len--) { g= font->glyph_ascii_table[c]; @@ -216,10 +241,10 @@ void blf_font_buffer(FontBLF *font, const char *str) unsigned char b_col_char[4]; GlyphBLF *g, *g_prev; FT_Vector delta; - FT_UInt glyph_index; float a, *fbuf; int pen_x, y, x; - int i, has_kerning, st, chx, chy; + int has_kerning, st, chx, chy; + unsigned int i; if (!font->glyph_cache || (!font->b_fbuf && !font->b_cbuf)) return; @@ -234,18 +259,16 @@ void blf_font_buffer(FontBLF *font, const char *str) b_col_char[2]= font->b_col[2] * 255; b_col_char[3]= font->b_col[3] * 255; + blf_font_ensure_ascii_table(font); + while (str[i]) { int pen_y; - c= blf_utf8_next((unsigned char *)str, &i); + + BLF_UTF8_NEXT_FAST(font, g, str, i, c); + if (c == 0) break; - g= blf_glyph_search(font->glyph_cache, c); - if (!g) { - glyph_index= FT_Get_Char_Index(font->face, c); - g= blf_glyph_add(font, glyph_index, c); - } - /* if we don't found a glyph, skip it. */ if (!g) continue; @@ -363,10 +386,10 @@ void blf_font_boundbox(FontBLF *font, const char *str, rctf *box) unsigned int c; GlyphBLF *g, *g_prev; FT_Vector delta; - FT_UInt glyph_index; rctf gbox; int pen_x, pen_y; - int i, has_kerning, st; + int has_kerning, st; + unsigned int i; if (!font->glyph_cache) return; @@ -382,17 +405,15 @@ void blf_font_boundbox(FontBLF *font, const char *str, rctf *box) has_kerning= FT_HAS_KERNING(font->face); g_prev= NULL; + blf_font_ensure_ascii_table(font); + while (str[i]) { - c= blf_utf8_next((unsigned char *)str, &i); + + BLF_UTF8_NEXT_FAST(font, g, str, i, c); + if (c == 0) break; - g= blf_glyph_search(font->glyph_cache, c); - if (!g) { - glyph_index= FT_Get_Char_Index(font->face, c); - g= blf_glyph_add(font, glyph_index, c); - } - /* if we don't found a glyph, skip it. */ if (!g) continue; @@ -534,7 +555,7 @@ void blf_font_free(FontBLF *font) static void blf_font_fill(FontBLF *font) { - int i; + unsigned int i; font->aspect[0]= 1.0f; font->aspect[1]= 1.0f; diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h index 9271d8d5a9e..ba0b9985dd4 100644 --- a/source/blender/blenfont/intern/blf_internal.h +++ b/source/blender/blenfont/intern/blf_internal.h @@ -40,7 +40,7 @@ struct rctf; unsigned int blf_next_p2(unsigned int x); unsigned int blf_hash(unsigned int val); -int blf_utf8_next(unsigned char *buf, int *iindex); +int blf_utf8_next(unsigned char *buf, unsigned int *iindex); char *blf_dir_search(const char *file); char *blf_dir_metrics_search(const char *filename); diff --git a/source/blender/blenfont/intern/blf_util.c b/source/blender/blenfont/intern/blf_util.c index ab6b516787e..edd23ac1ba6 100644 --- a/source/blender/blenfont/intern/blf_util.c +++ b/source/blender/blenfont/intern/blf_util.c @@ -72,7 +72,7 @@ unsigned int blf_hash(unsigned int val) * The original name: imlib_font_utf8_get_next * more info here: http://docs.enlightenment.org/api/imlib2/html/ */ -int blf_utf8_next(unsigned char *buf, int *iindex) +int blf_utf8_next(unsigned char *buf, unsigned int *iindex) { /* Reads UTF8 bytes from 'buf', starting at 'index' and * returns the code point of the next valid code point. -- cgit v1.2.3 From 156e96762b64eae7bc10d1ef58130107777ddb11 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 12 Sep 2011 09:12:34 +0000 Subject: fix for changing font sizes with recent utf8 speedup --- source/blender/blenfont/intern/blf_font.c | 27 ++++++++++++++-------- source/blender/blenfont/intern/blf_glyph.c | 11 ++++----- .../blender/blenfont/intern/blf_internal_types.h | 6 ++--- 3 files changed, 25 insertions(+), 19 deletions(-) (limited to 'source/blender/blenfont') diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index 52aace1d3d7..8a71c3de86b 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -100,7 +100,8 @@ void blf_font_size(FontBLF *font, int size, int dpi) static void blf_font_ensure_ascii_table(FontBLF *font) { /* build ascii on demand */ - if(font->glyph_ascii_table['0']==NULL) { + if(font->glyph_cache->glyph_ascii_table['0']==NULL) { + GlyphBLF **glyph_ascii_table= font->glyph_cache->glyph_ascii_table; GlyphBLF *g; unsigned int i; for(i=0; i<256; i++) { @@ -109,7 +110,7 @@ static void blf_font_ensure_ascii_table(FontBLF *font) FT_UInt glyph_index= FT_Get_Char_Index(font->face, i); g= blf_glyph_add(font, glyph_index, i); } - font->glyph_ascii_table[i]= g; + glyph_ascii_table[i]= g; } } } @@ -122,9 +123,9 @@ static void blf_font_ensure_ascii_table(FontBLF *font) /* Note, * blf_font_ensure_ascii_table(font); must be called before this macro */ -#define BLF_UTF8_NEXT_FAST(font, g, str, i, c) \ +#define BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table) \ if(((c)= (str)[i]) < 0x80) { \ - g= (font)->glyph_ascii_table[c]; \ + g= glyph_ascii_table[c]; \ i++; \ } \ else if ((c= blf_utf8_next((unsigned char *)(str), &(i)))) { \ @@ -143,9 +144,11 @@ void blf_font_draw(FontBLF *font, const char *str, unsigned int len) int pen_x, pen_y; int has_kerning, st; unsigned int i; + GlyphBLF **glyph_ascii_table; if (!font->glyph_cache) return; + glyph_ascii_table= font->glyph_cache->glyph_ascii_table; i= 0; pen_x= 0; @@ -157,7 +160,7 @@ void blf_font_draw(FontBLF *font, const char *str, unsigned int len) while (str[i] && i < len) { - BLF_UTF8_NEXT_FAST(font, g, str, i, c); + BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table); if (c == 0) break; @@ -195,9 +198,11 @@ void blf_font_draw_ascii(FontBLF *font, const char *str, unsigned int len) FT_Vector delta; int pen_x, pen_y; int has_kerning, st; + GlyphBLF **glyph_ascii_table; if (!font->glyph_cache) return; + glyph_ascii_table= font->glyph_cache->glyph_ascii_table; pen_x= 0; pen_y= 0; @@ -207,7 +212,7 @@ void blf_font_draw_ascii(FontBLF *font, const char *str, unsigned int len) blf_font_ensure_ascii_table(font); while ((c= *(str++)) && len--) { - g= font->glyph_ascii_table[c]; + g= font->glyph_cache->glyph_ascii_table[c]; /* if we don't found a glyph, skip it. */ if (!g) @@ -245,9 +250,11 @@ void blf_font_buffer(FontBLF *font, const char *str) int pen_x, y, x; int has_kerning, st, chx, chy; unsigned int i; + GlyphBLF **glyph_ascii_table; if (!font->glyph_cache || (!font->b_fbuf && !font->b_cbuf)) return; + glyph_ascii_table= font->glyph_cache->glyph_ascii_table; i= 0; pen_x= (int)font->pos[0]; @@ -264,7 +271,7 @@ void blf_font_buffer(FontBLF *font, const char *str) while (str[i]) { int pen_y; - BLF_UTF8_NEXT_FAST(font, g, str, i, c); + BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table); if (c == 0) break; @@ -390,9 +397,11 @@ void blf_font_boundbox(FontBLF *font, const char *str, rctf *box) int pen_x, pen_y; int has_kerning, st; unsigned int i; + GlyphBLF **glyph_ascii_table; if (!font->glyph_cache) return; + glyph_ascii_table= font->glyph_cache->glyph_ascii_table; box->xmin= 32000.0f; box->xmax= -32000.0f; @@ -409,7 +418,7 @@ void blf_font_boundbox(FontBLF *font, const char *str, rctf *box) while (str[i]) { - BLF_UTF8_NEXT_FAST(font, g, str, i, c); + BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table); if (c == 0) break; @@ -589,8 +598,6 @@ static void blf_font_fill(FontBLF *font) font->b_col[2]= 0; font->b_col[3]= 0; font->ft_lib= ft_lib; - - memset(font->glyph_ascii_table, 0, sizeof(font->glyph_ascii_table)); } FontBLF *blf_font_new(const char *name, const char *filename) diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c index e165012f43e..9b39cb65cba 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -74,7 +74,6 @@ GlyphCacheBLF *blf_glyph_cache_find(FontBLF *font, int size, int dpi) GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font) { GlyphCacheBLF *gc; - int i; gc= (GlyphCacheBLF *)MEM_mallocN(sizeof(GlyphCacheBLF), "blf_glyph_cache_new"); gc->next= NULL; @@ -82,10 +81,8 @@ GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font) gc->size= font->size; gc->dpi= font->dpi; - for (i= 0; i < 257; i++) { - gc->bucket[i].first= NULL; - gc->bucket[i].last= NULL; - } + memset(gc->glyph_ascii_table, 0, sizeof(gc->glyph_ascii_table)); + memset(gc->bucket, 0, sizeof(gc->bucket)); gc->textures= (GLuint *)malloc(sizeof(GLuint)*256); gc->ntex= 256; @@ -136,7 +133,9 @@ void blf_glyph_cache_clear(FontBLF *font) } } - memset(font->glyph_ascii_table, 0, sizeof(font->glyph_ascii_table)); + if(font->glyph_cache) { + memset(font->glyph_cache->glyph_ascii_table, 0, sizeof(font->glyph_cache->glyph_ascii_table)); + } } void blf_glyph_cache_free(GlyphCacheBLF *gc) diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h index c4e192626e8..9840e6446ef 100644 --- a/source/blender/blenfont/intern/blf_internal_types.h +++ b/source/blender/blenfont/intern/blf_internal_types.h @@ -46,6 +46,9 @@ typedef struct GlyphCacheBLF { /* and the glyphs. */ ListBase bucket[257]; + /* fast ascii lookup */ + struct GlyphBLF *glyph_ascii_table[256]; + /* texture array, to draw the glyphs. */ GLuint *textures; @@ -184,9 +187,6 @@ typedef struct FontBLF { /* current glyph cache, size and dpi. */ GlyphCacheBLF *glyph_cache; - - /* fast ascii lookip */ - GlyphBLF *glyph_ascii_table[256]; /* freetype2 lib handle. */ FT_Library ft_lib; -- cgit v1.2.3 From afbb207a994d09750efab29dc56cfe4c2548a709 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 14 Sep 2011 02:45:44 +0000 Subject: minor edits to ascii draw function, unused var warning. --- source/blender/blenfont/intern/blf_font.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source/blender/blenfont') diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index 8a71c3de86b..3bec7dd2626 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -99,9 +99,10 @@ void blf_font_size(FontBLF *font, int size, int dpi) static void blf_font_ensure_ascii_table(FontBLF *font) { + GlyphBLF **glyph_ascii_table= font->glyph_cache->glyph_ascii_table; + /* build ascii on demand */ - if(font->glyph_cache->glyph_ascii_table['0']==NULL) { - GlyphBLF **glyph_ascii_table= font->glyph_cache->glyph_ascii_table; + if(glyph_ascii_table['0']==NULL) { GlyphBLF *g; unsigned int i; for(i=0; i<256; i++) { @@ -125,7 +126,7 @@ static void blf_font_ensure_ascii_table(FontBLF *font) #define BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table) \ if(((c)= (str)[i]) < 0x80) { \ - g= glyph_ascii_table[c]; \ + g= (glyph_ascii_table)[c]; \ i++; \ } \ else if ((c= blf_utf8_next((unsigned char *)(str), &(i)))) { \ @@ -212,7 +213,7 @@ void blf_font_draw_ascii(FontBLF *font, const char *str, unsigned int len) blf_font_ensure_ascii_table(font); while ((c= *(str++)) && len--) { - g= font->glyph_cache->glyph_ascii_table[c]; + g= glyph_ascii_table[c]; /* if we don't found a glyph, skip it. */ if (!g) @@ -401,7 +402,6 @@ void blf_font_boundbox(FontBLF *font, const char *str, rctf *box) if (!font->glyph_cache) return; - glyph_ascii_table= font->glyph_cache->glyph_ascii_table; box->xmin= 32000.0f; box->xmax= -32000.0f; @@ -415,6 +415,7 @@ void blf_font_boundbox(FontBLF *font, const char *str, rctf *box) g_prev= NULL; blf_font_ensure_ascii_table(font); + glyph_ascii_table= font->glyph_cache->glyph_ascii_table; while (str[i]) { -- cgit v1.2.3