diff options
Diffstat (limited to 'indra/llrender')
-rw-r--r-- | indra/llrender/llfontfreetype.cpp | 14 | ||||
-rw-r--r-- | indra/llrender/llfontgl.cpp | 482 | ||||
-rw-r--r-- | indra/llrender/llfontgl.h | 27 | ||||
-rw-r--r-- | indra/llrender/llfontregistry.cpp | 1 | ||||
-rw-r--r-- | indra/llrender/llimagegl.cpp | 20 | ||||
-rw-r--r-- | indra/llrender/llimagegl.h | 4 |
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 |