Skip to content
Snippets Groups Projects
Commit 08e3e05c authored by Monroe Linden's avatar Monroe Linden
Browse files

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.
parent 3e832020
No related branches found
No related tags found
No related merge requests found
......@@ -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);
......
......@@ -128,7 +128,9 @@ class LLFontFreetype : public LLRefCount
};
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;
......
......@@ -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);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment