diff options
| author | Monroe Linden <monroe@lindenlab.com> | 2010-02-18 13:40:32 -0800 | 
|---|---|---|
| committer | Monroe Linden <monroe@lindenlab.com> | 2010-02-18 13:40:32 -0800 | 
| commit | 08e3e05c0a1aa99bc6cf300191ea3c7feb97ff9a (patch) | |
| tree | 3d039671b8fab5123beef3fc566842fefce08f8d | |
| parent | 3e8320201fb89ce01bed18dc1ab7a41811fd3982 (diff) | |
Additional optimizations to text reflow for EXT-5071.
Added versions of LLFontFreeType::getXAdvance() and LLFontFreeType::getXKerning() that take LLFontGlyphInfo* instead of llwchar.  This allows code in LLFontGL that already has the LLFontGlyphInfo* to pass them instead, saving calls to LLFontFreetype::getGlyphInfo.
Reviewed by Richard.
| -rw-r--r-- | indra/llrender/llfontfreetype.cpp | 23 | ||||
| -rw-r--r-- | indra/llrender/llfontfreetype.h | 2 | ||||
| -rw-r--r-- | indra/llrender/llfontgl.cpp | 57 | 
3 files changed, 71 insertions, 11 deletions
| diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 22fad792da..a86bbbffff 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -270,6 +270,14 @@ F32 LLFontFreetype::getXAdvance(llwchar wch) const  	return (F32)mFontBitmapCachep->getMaxCharWidth();  } +F32 LLFontFreetype::getXAdvance(const LLFontGlyphInfo* glyph) const +{ +	if (mFTFace == NULL) +		return 0.0; + +	return glyph->mXAdvance; +} +  F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const  {  	if (mFTFace == NULL) @@ -289,6 +297,21 @@ F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const  	return delta.x*(1.f/64.f);  } +F32 LLFontFreetype::getXKerning(const LLFontGlyphInfo* left_glyph_info, const LLFontGlyphInfo* right_glyph_info) const +{ +	if (mFTFace == NULL) +		return 0.0; + +	U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0; +	U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0; + +	FT_Vector  delta; + +	llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, ft_kerning_unfitted, &delta)); + +	return delta.x*(1.f/64.f); +} +  BOOL LLFontFreetype::hasGlyph(llwchar wch) const  {  	llassert(!mIsFallback); diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index 7a5d029038..f60d09316d 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -128,7 +128,9 @@ public:  	};  	F32 getXAdvance(llwchar wc) const; +	F32 getXAdvance(const LLFontGlyphInfo* glyph) const;  	F32 getXKerning(llwchar char_left, llwchar char_right) const; // Get the kerning between the two characters +	F32 getXKerning(const LLFontGlyphInfo* left_glyph_info, const LLFontGlyphInfo* right_glyph_info) const; // Get the kerning between the two characters  	LLFontGlyphInfo* getGlyphInfo(llwchar wch) const; diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index b6a6b448ee..f1f86fd638 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -249,11 +249,18 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons  	// Remember last-used texture to avoid unnecesssary bind calls.  	LLImageGL *last_bound_texture = NULL; +	const LLFontGlyphInfo* next_glyph = NULL; +  	for (i = begin_offset; i < begin_offset + length; i++)  	{  		llwchar wch = wstr[i]; -		const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch); +		const LLFontGlyphInfo* fgi = next_glyph; +		next_glyph = NULL; +		if(!fgi) +		{ +			fgi = mFontFreetype->getGlyphInfo(wch); +		}  		if (!fgi)  		{  			llerrs << "Missing Glyph Info" << llendl; @@ -295,7 +302,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons  		if (next_char && (next_char < LAST_CHARACTER))  		{  			// Kern this puppy. -			cur_x += mFontFreetype->getXKerning(wch, next_char); +			next_glyph = mFontFreetype->getGlyphInfo(next_char); +			cur_x += mFontFreetype->getXKerning(fgi, next_glyph);  		}  		// Round after kerning. @@ -435,14 +443,21 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars  	F32 cur_x = 0;  	const S32 max_index = begin_offset + max_chars; +	const LLFontGlyphInfo* next_glyph = NULL; +  	F32 width_padding = 0.f;  	for (S32 i = begin_offset; i < max_index && wchars[i] != 0; i++)  	{  		llwchar wch = wchars[i]; -		const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch); +		const LLFontGlyphInfo* fgi = next_glyph; +		next_glyph = NULL; +		if(!fgi) +		{ +			fgi = mFontFreetype->getGlyphInfo(wch); +		} -		F32 advance = mFontFreetype->getXAdvance(wch); +		F32 advance = mFontFreetype->getXAdvance(fgi);  		// for the last character we want to measure the greater of its width and xadvance values  		// so keep track of the difference between these values for the each character we measure @@ -459,7 +474,8 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars  			&& (next_char < LAST_CHARACTER))  		{  			// Kern this puppy. -			cur_x += mFontFreetype->getXKerning(wch, next_char); +			next_glyph = mFontFreetype->getGlyphInfo(next_char); +			cur_x += mFontFreetype->getXKerning(fgi, next_glyph);  		}  		// Round after kerning.  		cur_x = (F32)llround(cur_x); @@ -492,6 +508,8 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch  	// avoid S32 overflow when max_pixels == S32_MAX by staying in floating point  	F32 scaled_max_pixels =	ceil(max_pixels * sScaleX);  	F32 width_padding = 0.f; +	 +	LLFontGlyphInfo* next_glyph = NULL;  	S32 i;  	for (i=0; (i < max_chars); i++) @@ -534,8 +552,13 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch  				in_word = TRUE;  			}  		} - -		LLFontGlyphInfo* fgi = mFontFreetype->getGlyphInfo(wch); +		 +		LLFontGlyphInfo* fgi = next_glyph; +		next_glyph = NULL; +		if(!fgi) +		{ +			fgi = mFontFreetype->getGlyphInfo(wch); +		}  		// account for glyphs that run beyond the starting point for the next glyphs  		width_padding = llmax(	0.f,													// always use positive padding amount @@ -554,7 +577,8 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch  		if (((i+1) < max_chars) && wchars[i+1])  		{  			// Kern this puppy. -			cur_x += mFontFreetype->getXKerning(wch, wchars[i+1]); +			next_glyph = mFontFreetype->getGlyphInfo(wchars[i+1]); +			cur_x += mFontFreetype->getXKerning(fgi, next_glyph);  		}  		// Round after kerning. @@ -660,6 +684,8 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t  	const S32 max_index = begin_offset + llmin(S32_MAX - begin_offset, max_chars);  	F32 scaled_max_pixels =	max_pixels * sScaleX; +	 +	const LLFontGlyphInfo* next_glyph = NULL;  	S32 pos;  	for (pos = begin_offset; pos < max_index; pos++) @@ -669,7 +695,15 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t  		{  			break; // done  		} -		F32 char_width = mFontFreetype->getXAdvance(wch); +		 +		const LLFontGlyphInfo* glyph = next_glyph; +		next_glyph = NULL; +		if(!glyph) +		{ +			glyph = mFontFreetype->getGlyphInfo(wch); +		} +		 +		F32 char_width = mFontFreetype->getXAdvance(glyph);  		if (round)  		{ @@ -695,11 +729,12 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t  		if (((pos + 1) < max_index)  			&& (wchars[(pos + 1)]))  		{ -			llwchar next_char = wchars[pos + 1];  			// Kern this puppy. -			cur_x += mFontFreetype->getXKerning(wch, next_char); +			next_glyph = mFontFreetype->getGlyphInfo(wchars[pos + 1]); +			cur_x += mFontFreetype->getXKerning(glyph, next_glyph);  		} +  		// Round after kerning.  		cur_x = llround(cur_x);  	} | 
