summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llfontfreetype.cpp14
-rw-r--r--indra/llrender/llfontgl.cpp482
-rw-r--r--indra/llrender/llfontgl.h27
-rw-r--r--indra/llrender/llfontregistry.cpp1
-rw-r--r--indra/llrender/llimagegl.cpp20
-rw-r--r--indra/llrender/llimagegl.h4
6 files changed, 164 insertions, 384 deletions
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index 62534969b7..0be6bedbee 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -33,6 +33,7 @@
#include "linden_common.h"
#include "llfontfreetype.h"
+#include "llfontgl.h"
// Freetype stuff
#include <ft2build.h>
@@ -204,6 +205,19 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
mName = filename;
mPointSize = point_size;
+ mStyle = LLFontGL::NORMAL;
+ if(mFTFace->style_flags & FT_STYLE_FLAG_BOLD)
+ {
+ mStyle |= LLFontGL::BOLD;
+ mStyle &= ~LLFontGL::NORMAL;
+ }
+
+ if(mFTFace->style_flags & FT_STYLE_FLAG_ITALIC)
+ {
+ mStyle |= LLFontGL::ITALIC;
+ mStyle &= ~LLFontGL::NORMAL;
+ }
+
return TRUE;
}
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 32a008047c..d76b23248d 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -89,12 +89,10 @@ static F32 llfont_round_y(F32 y)
LLFontGL::LLFontGL()
{
- clearEmbeddedChars();
}
LLFontGL::~LLFontGL()
{
- clearEmbeddedChars();
}
void LLFontGL::reset()
@@ -117,8 +115,10 @@ BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dp
return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback);
}
+static LLFastTimer::DeclareTimer FTM_RENDER_FONTS("Fonts");
+
S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
- ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_embedded, BOOL use_ellipses) const
+ ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses) const
{
if(!sDisplayFont) //do not display texts
{
@@ -159,7 +159,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
F32 pixel_offset_y = llround((F32)sCurOrigin.mY) - (sCurOrigin.mY);
gGL.translatef(-pixel_offset_x, -pixel_offset_y, 0.f);
- LLFastTimer t(LLFastTimer::FTM_RENDER_FONTS);
+ LLFastTimer t(FTM_RENDER_FONTS);
gGL.color4fv( color.mV );
@@ -231,7 +231,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
BOOL draw_ellipses = FALSE;
- if (use_ellipses && halign == LEFT)
+ if (use_ellipses)
{
// check for too long of a string
if (getWidthF32(wstr.c_str(), 0, max_chars) * sScaleX > scaled_max_pixels)
@@ -251,135 +251,69 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
{
llwchar wch = wstr[i];
- // Handle embedded characters first, if they're enabled.
- // Embedded characters are a hack for notecards
- const embedded_data_t* ext_data = use_embedded ? getEmbeddedCharData(wch) : NULL;
- if (ext_data)
+ if (!mFontFreetype->hasGlyph(wch))
{
- LLImageGL* ext_image = ext_data->mImage;
- const LLWString& label = ext_data->mLabel;
-
- F32 ext_height = (F32)ext_image->getHeight() * sScaleY;
-
- F32 ext_width = (F32)ext_image->getWidth() * sScaleX;
- F32 ext_advance = (EXT_X_BEARING * sScaleX) + ext_width;
-
- if (!label.empty())
- {
- ext_advance += (EXT_X_BEARING + getFontExtChar()->getWidthF32( label.c_str() )) * sScaleX;
- }
-
- if (start_x + scaled_max_pixels < cur_x + ext_advance)
- {
- // Not enough room for this character.
- break;
- }
-
- if (last_bound_texture != ext_image)
- {
- gGL.getTexUnit(0)->bind(ext_image);
- last_bound_texture = ext_image;
- }
-
- // snap origin to whole screen pixel
- const F32 ext_x = (F32)llround(cur_render_x + (EXT_X_BEARING * sScaleX));
- const F32 ext_y = (F32)llround(cur_render_y + (EXT_Y_BEARING * sScaleY + mFontFreetype->getAscenderHeight() - mFontFreetype->getLineHeight()));
-
- LLRectf uv_rect(0.f, 1.f, 1.f, 0.f);
- LLRectf screen_rect(ext_x, ext_y + ext_height, ext_x + ext_width, ext_y);
- drawGlyph(screen_rect, uv_rect, LLColor4::white, style_to_add, shadow, drop_shadow_strength);
-
- if (!label.empty())
- {
- gGL.pushMatrix();
- //glLoadIdentity();
- //gGL.translatef(sCurOrigin.mX, sCurOrigin.mY, 0.0f);
- //glScalef(sScaleX, sScaleY, 1.f);
- getFontExtChar()->render(label, 0,
- /*llfloor*/((ext_x + (F32)ext_image->getWidth() + EXT_X_BEARING) / sScaleX),
- /*llfloor*/(cur_y / sScaleY),
- color,
- halign, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL,
- TRUE );
- gGL.popMatrix();
- }
-
- gGL.color4fv(color.mV);
+ addChar(wch);
+ }
- chars_drawn++;
- cur_x += ext_advance;
- if (((i + 1) < length) && wstr[i+1])
- {
- cur_x += EXT_KERNING * sScaleX;
- }
- cur_render_x = cur_x;
+ const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch);
+ if (!fgi)
+ {
+ llerrs << "Missing Glyph Info" << llendl;
+ break;
}
- else
+ // Per-glyph bitmap texture.
+ LLImageGL *image_gl = mFontFreetype->getFontBitmapCache()->getImageGL(fgi->mBitmapNum);
+ if (last_bound_texture != image_gl)
{
- if (!mFontFreetype->hasGlyph(wch))
- {
- addChar(wch);
- }
-
- const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch);
- if (!fgi)
- {
- llerrs << "Missing Glyph Info" << llendl;
- break;
- }
- // Per-glyph bitmap texture.
- LLImageGL *image_gl = mFontFreetype->getFontBitmapCache()->getImageGL(fgi->mBitmapNum);
- if (last_bound_texture != image_gl)
- {
- gGL.getTexUnit(0)->bind(image_gl);
- last_bound_texture = image_gl;
- }
-
- if ((start_x + scaled_max_pixels) < (cur_x + fgi->mXBearing + fgi->mWidth))
- {
- // Not enough room for this character.
- break;
- }
-
- // Draw the text at the appropriate location
- //Specify vertices and texture coordinates
- LLRectf uv_rect((fgi->mXBitmapOffset) * inv_width,
- (fgi->mYBitmapOffset + fgi->mHeight + PAD_UVY) * inv_height,
- (fgi->mXBitmapOffset + fgi->mWidth) * inv_width,
- (fgi->mYBitmapOffset - PAD_UVY) * inv_height);
- // snap glyph origin to whole screen pixel
- LLRectf screen_rect(llround(cur_render_x + (F32)fgi->mXBearing),
- llround(cur_render_y + (F32)fgi->mYBearing),
- llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,
- llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight);
-
- drawGlyph(screen_rect, uv_rect, color, style_to_add, shadow, drop_shadow_strength);
+ gGL.getTexUnit(0)->bind(image_gl);
+ last_bound_texture = image_gl;
+ }
- chars_drawn++;
- cur_x += fgi->mXAdvance;
- cur_y += fgi->mYAdvance;
+ if ((start_x + scaled_max_pixels) < (cur_x + fgi->mXBearing + fgi->mWidth))
+ {
+ // Not enough room for this character.
+ break;
+ }
- llwchar next_char = wstr[i+1];
- if (next_char && (next_char < LAST_CHARACTER))
+ // Draw the text at the appropriate location
+ //Specify vertices and texture coordinates
+ LLRectf uv_rect((fgi->mXBitmapOffset) * inv_width,
+ (fgi->mYBitmapOffset + fgi->mHeight + PAD_UVY) * inv_height,
+ (fgi->mXBitmapOffset + fgi->mWidth) * inv_width,
+ (fgi->mYBitmapOffset - PAD_UVY) * inv_height);
+ // snap glyph origin to whole screen pixel
+ LLRectf screen_rect(llround(cur_render_x + (F32)fgi->mXBearing),
+ llround(cur_render_y + (F32)fgi->mYBearing),
+ llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,
+ llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight);
+
+ drawGlyph(screen_rect, uv_rect, color, style_to_add, shadow, drop_shadow_strength);
+
+ chars_drawn++;
+ cur_x += fgi->mXAdvance;
+ cur_y += fgi->mYAdvance;
+
+ llwchar next_char = wstr[i+1];
+ if (next_char && (next_char < LAST_CHARACTER))
+ {
+ // Kern this puppy.
+ if (!mFontFreetype->hasGlyph(next_char))
{
- // Kern this puppy.
- if (!mFontFreetype->hasGlyph(next_char))
- {
- addChar(next_char);
- }
- cur_x += mFontFreetype->getXKerning(wch, next_char);
+ addChar(next_char);
}
+ cur_x += mFontFreetype->getXKerning(wch, next_char);
+ }
- // Round after kerning.
- // Must do this to cur_x, not just to cur_render_x, otherwise you
- // will squish sub-pixel kerned characters too close together.
- // For example, "CCCCC" looks bad.
- cur_x = (F32)llfloor(cur_x + 0.5f);
- //cur_y = (F32)llfloor(cur_y + 0.5f);
+ // Round after kerning.
+ // Must do this to cur_x, not just to cur_render_x, otherwise you
+ // will squish sub-pixel kerned characters too close together.
+ // For example, "CCCCC" looks bad.
+ cur_x = (F32)llfloor(cur_x + 0.5f);
+ //cur_y = (F32)llfloor(cur_y + 0.5f);
- cur_render_x = cur_x;
- cur_render_y = cur_y;
- }
+ cur_render_x = cur_x;
+ cur_render_y = cur_y;
}
if (right_x)
@@ -398,9 +332,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
gGL.end();
}
- // *FIX: get this working in all alignment cases, etc.
if (draw_ellipses)
{
+
// recursively render ellipses at end of string
// we've already reserved enough room
gGL.pushMatrix();
@@ -427,12 +361,12 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
S32 LLFontGL::render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const
{
- return render(text, begin_offset, x, y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE, FALSE);
+ return render(text, begin_offset, x, y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
}
S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses) const
{
- return render(utf8str_to_wstring(text), begin_offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, FALSE, use_ellipses);
+ return render(utf8str_to_wstring(text), begin_offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, use_ellipses);
}
S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const
@@ -478,9 +412,9 @@ S32 LLFontGL::getWidth(const std::string& utf8text, S32 begin_offset, S32 max_ch
return getWidth(wtext.c_str(), begin_offset, max_chars);
}
-S32 LLFontGL::getWidth(const llwchar* wchars, S32 begin_offset, S32 max_chars, BOOL use_embedded) const
+S32 LLFontGL::getWidth(const llwchar* wchars, S32 begin_offset, S32 max_chars) const
{
- F32 width = getWidthF32(wchars, begin_offset, max_chars, use_embedded);
+ F32 width = getWidthF32(wchars, begin_offset, max_chars);
return llround(width);
}
@@ -501,7 +435,7 @@ F32 LLFontGL::getWidthF32(const std::string& utf8text, S32 begin_offset, S32 max
return getWidthF32(wtext.c_str(), begin_offset, max_chars);
}
-F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars, BOOL use_embedded) const
+F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars) const
{
const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL;
@@ -509,34 +443,21 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars
const S32 max_index = begin_offset + max_chars;
for (S32 i = begin_offset; i < max_index; i++)
{
- const llwchar wch = wchars[i];
+ llwchar wch = wchars[i];
if (wch == 0)
{
break; // done
}
- const embedded_data_t* ext_data = use_embedded ? getEmbeddedCharData(wch) : NULL;
- if (ext_data)
- {
- // Handle crappy embedded hack
- cur_x += getEmbeddedCharAdvance(ext_data);
- if( ((i+1) < max_chars) && (i+1 < max_index))
- {
- cur_x += EXT_KERNING * sScaleX;
- }
- }
- else
- {
- cur_x += mFontFreetype->getXAdvance(wch);
- llwchar next_char = wchars[i+1];
+ cur_x += mFontFreetype->getXAdvance(wch);
+ llwchar next_char = wchars[i+1];
- if (((i + 1) < max_chars)
- && next_char
- && (next_char < LAST_CHARACTER))
- {
- // Kern this puppy.
- cur_x += mFontFreetype->getXKerning(wch, next_char);
- }
+ if (((i + 1) < begin_offset + max_chars)
+ && next_char
+ && (next_char < LAST_CHARACTER))
+ {
+ // Kern this puppy.
+ cur_x += mFontFreetype->getXKerning(wch, next_char);
}
// Round after kerning.
cur_x = (F32)llfloor(cur_x + 0.5f);
@@ -546,7 +467,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars
}
// Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels
-S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, BOOL end_on_word_boundary, BOOL use_embedded, F32* drawn_pixels) const
+S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, BOOL end_on_word_boundary) const
{
if (!wchars || !wchars[0] || max_chars == 0)
{
@@ -576,83 +497,51 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
break;
}
- const embedded_data_t* ext_data = use_embedded ? getEmbeddedCharData(wch) : NULL;
- if (ext_data)
+ if (in_word)
{
- if (in_word)
- {
- in_word = FALSE;
- }
- else
+ if (iswspace(wch))
{
- start_of_last_word = i;
- }
- cur_x += getEmbeddedCharAdvance(ext_data);
-
- if (scaled_max_pixels < cur_x)
- {
- clip = TRUE;
- break;
- }
-
- if (((i+1) < max_chars) && wchars[i+1])
- {
- cur_x += EXT_KERNING * sScaleX;
- }
-
- if( scaled_max_pixels < cur_x )
- {
- clip = TRUE;
- break;
+ if(wch !=(0x00A0))
+ {
+ in_word = FALSE;
+ }
}
- }
- else
- {
- if (in_word)
+ if (iswindividual(wch))
{
- if (iswspace(wch))
+ if (iswpunct(wchars[i+1]))
{
- if(wch !=(0x00A0))
- {
- in_word = FALSE;
- }
+ in_word=TRUE;
}
- if (iswindividual(wch))
+ else
{
- if (iswpunct(wchars[i+1]))
- {
- in_word=TRUE;
- }
- else
- {
- in_word=FALSE;
- start_of_last_word = i;
- }
+ in_word=FALSE;
+ start_of_last_word = i;
}
}
- else
+ }
+ else
+ {
+ start_of_last_word = i;
+ if (!iswspace(wch)||!iswindividual(wch))
{
- start_of_last_word = i;
- if (!iswspace(wch)||!iswindividual(wch))
- {
- in_word = TRUE;
- }
+ in_word = TRUE;
}
+ }
- cur_x += mFontFreetype->getXAdvance(wch);
-
- if (scaled_max_pixels < cur_x)
- {
- clip = TRUE;
- break;
- }
+ cur_x += mFontFreetype->getXAdvance(wch);
+
+ if (scaled_max_pixels < cur_x)
+ {
+ clip = TRUE;
+ break;
+ }
- if (((i+1) < max_chars) && wchars[i+1])
- {
- // Kern this puppy.
- cur_x += mFontFreetype->getXKerning(wch, wchars[i+1]);
- }
+ if (((i+1) < max_chars) && wchars[i+1])
+ {
+ // Kern this puppy.
+ cur_x += mFontFreetype->getXKerning(wch, wchars[i+1]);
}
+
// Round after kerning.
cur_x = (F32)llfloor(cur_x + 0.5f);
drawn_x = cur_x;
@@ -662,10 +551,6 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
{
i = start_of_last_word;
}
- if (drawn_pixels)
- {
- *drawn_pixels = drawn_x;
- }
return i;
}
@@ -686,8 +571,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
{
llwchar wch = wchars[i];
- const embedded_data_t* ext_data = getEmbeddedCharData(wch);
- F32 char_width = ext_data ? getEmbeddedCharAdvance(ext_data) : mFontFreetype->getXAdvance(wch);
+ F32 char_width = mFontFreetype->getXAdvance(wch);
if( scaled_max_pixels < (total_width + char_width) )
{
@@ -705,7 +589,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
if ( i > 0 )
{
// kerning
- total_width += ext_data ? (EXT_KERNING * sScaleX) : mFontFreetype->getXKerning(wchars[i-1], wch);
+ total_width += mFontFreetype->getXKerning(wchars[i-1], wch);
}
// Round after kerning.
@@ -715,7 +599,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
return start_pos - drawable_chars;
}
-S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round, BOOL use_embedded) const
+S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round) const
{
if (!wchars || !wchars[0] || max_chars == 0)
{
@@ -723,7 +607,6 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t
}
F32 cur_x = 0;
- S32 pos = 0;
target_x *= sScaleX;
@@ -732,113 +615,50 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t
F32 scaled_max_pixels = max_pixels * sScaleX;
- for (S32 i = begin_offset; (i < max_index); i++)
+ S32 pos;
+ for (pos = begin_offset; pos < max_index; pos++)
{
- llwchar wch = wchars[i];
+ llwchar wch = wchars[pos];
if (!wch)
{
break; // done
}
- const embedded_data_t* ext_data = use_embedded ? getEmbeddedCharData(wch) : NULL;
- if (ext_data)
- {
- F32 ext_advance = getEmbeddedCharAdvance(ext_data);
-
- if (round)
- {
- // Note: if the mouse is on the left half of the character, the pick is to the character's left
- // If it's on the right half, the pick is to the right.
- if (target_x < cur_x + ext_advance/2)
- {
- break;
- }
- }
- else
- {
- if (target_x < cur_x + ext_advance)
- {
- break;
- }
- }
+ F32 char_width = mFontFreetype->getXAdvance(wch);
- if (scaled_max_pixels < cur_x + ext_advance)
+ if (round)
+ {
+ // Note: if the mouse is on the left half of the character, the pick is to the character's left
+ // If it's on the right half, the pick is to the right.
+ if (target_x < cur_x + char_width*0.5f)
{
break;
}
-
- pos++;
- cur_x += ext_advance;
-
- if (((i + 1) < max_index)
- && (wchars[(i + 1)]))
- {
- cur_x += EXT_KERNING * sScaleX;
- }
- // Round after kerning.
- cur_x = (F32)llfloor(cur_x + 0.5f);
}
- else
+ else if (target_x < cur_x + char_width)
{
- F32 char_width = mFontFreetype->getXAdvance(wch);
-
- if (round)
- {
- // Note: if the mouse is on the left half of the character, the pick is to the character's left
- // If it's on the right half, the pick is to the right.
- if (target_x < cur_x + char_width*0.5f)
- {
- break;
- }
- }
- else if (target_x < cur_x + char_width)
- {
- break;
- }
-
- if (scaled_max_pixels < cur_x + char_width)
- {
- break;
- }
-
- pos++;
- cur_x += char_width;
-
- if (((i + 1) < max_index)
- && (wchars[(i + 1)]))
- {
- llwchar next_char = wchars[i + 1];
- // Kern this puppy.
- cur_x += mFontFreetype->getXKerning(wch, next_char);
- }
-
- // Round after kerning.
- cur_x = (F32)llfloor(cur_x + 0.5f);
+ break;
}
- }
- return pos;
-}
+ if (scaled_max_pixels < cur_x + char_width)
+ {
+ break;
+ }
-void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label ) const
-{
- LLWString wlabel = utf8str_to_wstring(label);
- addEmbeddedChar(wc, image, wlabel);
-}
+ cur_x += char_width;
-void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& wlabel ) const
-{
- embedded_data_t* ext_data = new embedded_data_t(image->getGLTexture(), wlabel);
- mEmbeddedChars[wc] = ext_data;
-}
+ if (((pos + 1) < max_index)
+ && (wchars[(pos + 1)]))
+ {
+ llwchar next_char = wchars[pos + 1];
+ // Kern this puppy.
+ cur_x += mFontFreetype->getXKerning(wch, next_char);
+ }
-void LLFontGL::removeEmbeddedChar(llwchar wc) const
-{
- embedded_map_t::iterator iter = mEmbeddedChars.find(wc);
- if (iter != mEmbeddedChars.end())
- {
- delete iter->second;
- mEmbeddedChars.erase(wc);
+ // Round after kerning.
+ cur_x = (F32)llfloor(cur_x + 0.5f);
}
+
+ return llmin(max_chars, pos - begin_offset);
}
BOOL LLFontGL::addChar(llwchar wch) const
@@ -1154,38 +974,6 @@ LLFontGL &LLFontGL::operator=(const LLFontGL &source)
return *this;
}
-const LLFontGL::embedded_data_t* LLFontGL::getEmbeddedCharData(llwchar wch) const
-{
- // Handle crappy embedded hack
- embedded_map_t::const_iterator iter = mEmbeddedChars.find(wch);
- if (iter != mEmbeddedChars.end())
- {
- return iter->second;
- }
- return NULL;
-}
-
-F32 LLFontGL::getEmbeddedCharAdvance(const embedded_data_t* ext_data) const
-{
- const LLWString& label = ext_data->mLabel;
- LLImageGL* ext_image = ext_data->mImage;
-
- F32 ext_width = (F32)ext_image->getWidth();
- if( !label.empty() )
- {
- ext_width += (EXT_X_BEARING + getFontExtChar()->getWidthF32(label.c_str())) * sScaleX;
- }
-
- return (EXT_X_BEARING * sScaleX) + ext_width;
-}
-
-void LLFontGL::clearEmbeddedChars()
-{
- for_each(mEmbeddedChars.begin(), mEmbeddedChars.end(), DeletePairedPointer());
- mEmbeddedChars.clear();
-}
-
-
void LLFontGL::renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const
{
gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h
index 42ed7a381f..af8e0909af 100644
--- a/indra/llrender/llfontgl.h
+++ b/indra/llrender/llfontgl.h
@@ -97,7 +97,7 @@ public:
BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback);
S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign = LEFT, VAlign valign = BASELINE, U8 style = NORMAL,
- ShadowType shadow = NO_SHADOW, S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX, F32* right_x=NULL, BOOL use_embedded = FALSE, BOOL use_ellipses = FALSE) const;
+ ShadowType shadow = NO_SHADOW, S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX, F32* right_x=NULL, BOOL use_ellipses = FALSE) const;
S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const;
// renderUTF8 does a conversion, so is slower!
@@ -113,28 +113,24 @@ public:
S32 getWidth(const std::string& utf8text) const;
S32 getWidth(const llwchar* wchars) const;
S32 getWidth(const std::string& utf8text, S32 offset, S32 max_chars ) const;
- S32 getWidth(const llwchar* wchars, S32 offset, S32 max_chars, BOOL use_embedded = FALSE) const;
+ S32 getWidth(const llwchar* wchars, S32 offset, S32 max_chars) const;
F32 getWidthF32(const std::string& utf8text) const;
F32 getWidthF32(const llwchar* wchars) const;
F32 getWidthF32(const std::string& text, S32 offset, S32 max_chars ) const;
- F32 getWidthF32(const llwchar* wchars, S32 offset, S32 max_chars, BOOL use_embedded = FALSE ) const;
+ F32 getWidthF32(const llwchar* wchars, S32 offset, S32 max_chars) const;
// The following are called often, frequently with large buffers, so do not use a string interface
// Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels
- S32 maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars = S32_MAX, BOOL end_on_word_boundary = FALSE, BOOL use_embedded = FALSE, F32* drawn_pixels = NULL) const;
+ S32 maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars = S32_MAX, BOOL end_on_word_boundary = FALSE) const;
// Returns the index of the first complete characters from text that can be drawn in max_pixels
// given that the character at start_pos should be the last character (or as close to last as possible).
S32 firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos=S32_MAX, S32 max_chars = S32_MAX) const;
// Returns the index of the character closest to pixel position x (ignoring text to the right of max_pixels and max_chars)
- S32 charFromPixelOffset(const llwchar* wchars, S32 char_offset, F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX, BOOL round = TRUE, BOOL use_embedded = FALSE) const;
-
- void addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label) const;
- void addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& label) const;
- void removeEmbeddedChar( llwchar wc ) const;
+ S32 charFromPixelOffset(const llwchar* wchars, S32 char_offset, F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX, BOOL round = TRUE) const;
BOOL addChar(const llwchar wch) const;
@@ -199,19 +195,6 @@ private:
LLFontDescriptor mFontDescriptor;
LLPointer<LLFontFreetype> mFontFreetype;
- struct embedded_data_t
- {
- embedded_data_t(LLImageGL* image, const LLWString& label) : mImage(image), mLabel(label) {}
- LLPointer<LLImageGL> mImage;
- LLWString mLabel;
- };
-
- typedef std::map<llwchar,embedded_data_t*> embedded_map_t;
- mutable embedded_map_t mEmbeddedChars;
-
- const embedded_data_t* getEmbeddedCharData(llwchar wch) const;
- F32 getEmbeddedCharAdvance(const embedded_data_t* ext_data) const;
- void clearEmbeddedChars();
void renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const;
void drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const;
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index 553e7b8f9d..99f364a589 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -477,7 +477,6 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
if (result)
{
- result->mFontFreetype->setStyle(match_desc->getStyle());
result->mFontDescriptor = desc;
}
else
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index c3d1d9e894..9d2cd4867a 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -516,7 +516,6 @@ void LLImageGL::setImage(const LLImageRaw* imageraw)
void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
{
-// LLFastTimer t1(LLFastTimer::FTM_TEMP1);
llpushcallstacks ;
bool is_compressed = false;
if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
@@ -524,12 +523,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
is_compressed = true;
}
-// LLFastTimer t2(LLFastTimer::FTM_TEMP2);
gGL.getTexUnit(0)->bind(this);
if (mUseMipMaps)
{
-// LLFastTimer t2(LLFastTimer::FTM_TEMP3);
if (data_hasmips)
{
// NOTE: data_in points to largest image; smaller images
@@ -546,14 +543,13 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
}
if (is_compressed)
{
-// LLFastTimer t2(LLFastTimer::FTM_TEMP4);
S32 tex_size = dataFormatBytes(mFormatPrimary, w, h);
glCompressedTexImage2DARB(mTarget, gl_level, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in);
stop_glerror();
}
else
{
-// LLFastTimer t2(LLFastTimer::FTM_TEMP4);
+// LLFastTimer t2(FTM_TEMP4);
if(mFormatSwapBytes)
{
@@ -586,7 +582,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_GENERATE_MIPMAP_SGIS, TRUE);
stop_glerror();
{
-// LLFastTimer t2(LLFastTimer::FTM_TEMP4);
+// LLFastTimer t2(FTM_TEMP4);
if(mFormatSwapBytes)
{
@@ -646,7 +642,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
}
llassert(w > 0 && h > 0 && cur_mip_data);
{
-// LLFastTimer t1(LLFastTimer::FTM_TEMP4);
+// LLFastTimer t1(FTM_TEMP4);
if(mFormatSwapBytes)
{
glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
@@ -732,7 +728,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
llpushcallstacks ;
}
-BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
+BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update)
{
llpushcallstacks ;
if (!width || !height)
@@ -750,7 +746,8 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
return FALSE;
}
- if (x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height)
+ // HACK: allow the caller to explicitly force the fast path (i.e. using glTexSubImage2D here instead of calling setImage) even when updating the full texture.
+ if (!force_fast_update && x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height)
{
setImage(datap, FALSE);
}
@@ -827,9 +824,9 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
return TRUE;
}
-BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height)
+BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update)
{
- return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height);
+ return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height, force_fast_update);
}
// Copy sub image from frame buffer
@@ -988,7 +985,6 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
LLImageGL::generateTextures(1, &mTexName);
stop_glerror();
{
-// LLFastTimer t1(LLFastTimer::FTM_TEMP6);
llverify(gGL.getTexUnit(0)->bind(this));
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel-discard_level);
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 5f32b23356..987a1dc538 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -106,8 +106,8 @@ public:
BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0);
void setImage(const LLImageRaw* imageraw);
void setImage(const U8* data_in, BOOL data_hasmips = FALSE);
- BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height);
- BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height);
+ BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
+ BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE);
BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
BOOL setDiscardLevel(S32 discard_level);
// Read back a raw image for this discard level, if it exists