[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [40116] trunk/blender/source/blender/ blenfont/intern: speedup font drawing:

Campbell Barton ideasman42 at gmail.com
Sun Sep 11 10:12:18 CEST 2011


Revision: 40116
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=40116
Author:   campbellbarton
Date:     2011-09-11 08:12:16 +0000 (Sun, 11 Sep 2011)
Log Message:
-----------
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().

Modified Paths:
--------------
    trunk/blender/source/blender/blenfont/intern/blf_font.c
    trunk/blender/source/blender/blenfont/intern/blf_internal.h
    trunk/blender/source/blender/blenfont/intern/blf_util.c

Modified: trunk/blender/source/blender/blenfont/intern/blf_font.c
===================================================================
--- trunk/blender/source/blender/blenfont/intern/blf_font.c	2011-09-11 07:06:21 UTC (rev 40115)
+++ trunk/blender/source/blender/blenfont/intern/blf_font.c	2011-09-11 08:12:16 UTC (rev 40116)
@@ -97,14 +97,52 @@
 	}
 }
 
+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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 
 static void blf_font_fill(FontBLF *font)
 {
-	int i;
+	unsigned int i;
 
 	font->aspect[0]= 1.0f;
 	font->aspect[1]= 1.0f;

Modified: trunk/blender/source/blender/blenfont/intern/blf_internal.h
===================================================================
--- trunk/blender/source/blender/blenfont/intern/blf_internal.h	2011-09-11 07:06:21 UTC (rev 40115)
+++ trunk/blender/source/blender/blenfont/intern/blf_internal.h	2011-09-11 08:12:16 UTC (rev 40116)
@@ -40,7 +40,7 @@
 
 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);

Modified: trunk/blender/source/blender/blenfont/intern/blf_util.c
===================================================================
--- trunk/blender/source/blender/blenfont/intern/blf_util.c	2011-09-11 07:06:21 UTC (rev 40115)
+++ trunk/blender/source/blender/blenfont/intern/blf_util.c	2011-09-11 08:12:16 UTC (rev 40116)
@@ -72,7 +72,7 @@
  * 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.




More information about the Bf-blender-cvs mailing list