Cleanup in llfontgl, as well as more aggressive bounds checking.
This commit is contained in:
@@ -155,6 +155,12 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (max_chars == -1)
|
||||
max_chars = S32_MAX;
|
||||
const S32 max_index = llmin(begin_offset + max_chars, S32(wstr.length()));
|
||||
if (max_index <= 0 || begin_offset >= max_index || max_pixels <= 0)
|
||||
return 0;
|
||||
|
||||
gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
S32 scaled_max_pixels = max_pixels == S32_MAX ? S32_MAX : llceil((F32)max_pixels * sScaleX);
|
||||
@@ -186,16 +192,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
|
||||
S32 chars_drawn = 0;
|
||||
S32 i;
|
||||
S32 length;
|
||||
|
||||
if (-1 == max_chars)
|
||||
{
|
||||
length = (S32)wstr.length() - begin_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
length = llmin((S32)wstr.length() - begin_offset, max_chars );
|
||||
}
|
||||
S32 length = max_index - begin_offset;
|
||||
|
||||
F32 cur_x, cur_y, cur_render_x, cur_render_y;
|
||||
|
||||
@@ -256,7 +253,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
if (use_ellipses && halign == LEFT)
|
||||
{
|
||||
// check for too long of a string
|
||||
S32 string_width = llmath::llround(getWidthF32(wstr.c_str(), begin_offset, max_chars) * sScaleX);
|
||||
S32 string_width = llmath::llround(getWidthF32(wstr, begin_offset, max_chars) * sScaleX);
|
||||
if (string_width > scaled_max_pixels)
|
||||
{
|
||||
// use four dots for ellipsis width to generate padding
|
||||
@@ -490,26 +487,11 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
||||
return chars_drawn;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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, use_ellipses);
|
||||
}
|
||||
|
||||
S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const
|
||||
{
|
||||
return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
|
||||
}
|
||||
|
||||
S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow) const
|
||||
{
|
||||
return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, halign, valign, style, shadow, S32_MAX, S32_MAX, NULL, FALSE);
|
||||
}
|
||||
|
||||
// font metrics - override for LLFontFreetype that returns units of virtual pixels
|
||||
F32 LLFontGL::getAscenderHeight() const
|
||||
{
|
||||
@@ -526,66 +508,45 @@ F32 LLFontGL::getLineHeight() const
|
||||
return (F32)llmath::llround(mFontFreetype->getLineHeight() / sScaleY);
|
||||
}
|
||||
|
||||
S32 LLFontGL::getWidth(const std::string& utf8text) const
|
||||
S32 LLFontGL::getWidth(const std::string& utf8text, const S32 begin_offset, const S32 max_chars, BOOL use_embedded) const
|
||||
{
|
||||
LLWString wtext = utf8str_to_wstring(utf8text);
|
||||
return getWidth(wtext.c_str(), 0, S32_MAX);
|
||||
return getWidth(utf8str_to_wstring(utf8text), begin_offset, max_chars, use_embedded);
|
||||
}
|
||||
|
||||
S32 LLFontGL::getWidth(const llwchar* wchars) const
|
||||
S32 LLFontGL::getWidth(const LLWString& utf32text, const S32 begin_offset, const S32 max_chars, BOOL use_embedded) const
|
||||
{
|
||||
return getWidth(wchars, 0, S32_MAX);
|
||||
}
|
||||
|
||||
S32 LLFontGL::getWidth(const std::string& utf8text, const S32 begin_offset, const S32 max_chars) const
|
||||
{
|
||||
LLWString wtext = utf8str_to_wstring(utf8text);
|
||||
return getWidth(wtext.c_str(), begin_offset, max_chars);
|
||||
}
|
||||
|
||||
S32 LLFontGL::getWidth(const llwchar* wchars, const S32 begin_offset, const S32 max_chars, BOOL use_embedded) const
|
||||
{
|
||||
F32 width = getWidthF32(wchars, begin_offset, max_chars, use_embedded);
|
||||
F32 width = getWidthF32(utf32text, begin_offset, max_chars, use_embedded);
|
||||
return llmath::llround(width);
|
||||
}
|
||||
|
||||
F32 LLFontGL::getWidthF32(const std::string& utf8text) const
|
||||
F32 LLFontGL::getWidthF32(const std::string& utf8text, const S32 begin_offset, const S32 max_chars, BOOL use_embedded) const
|
||||
{
|
||||
LLWString wtext = utf8str_to_wstring(utf8text);
|
||||
return getWidthF32(wtext.c_str(), 0, S32_MAX);
|
||||
return getWidthF32(utf8str_to_wstring(utf8text), begin_offset, max_chars, use_embedded);
|
||||
}
|
||||
|
||||
F32 LLFontGL::getWidthF32(const llwchar* wchars) const
|
||||
{
|
||||
return getWidthF32(wchars, 0, S32_MAX);
|
||||
}
|
||||
|
||||
F32 LLFontGL::getWidthF32(const std::string& utf8text, const S32 begin_offset, const S32 max_chars ) const
|
||||
{
|
||||
LLWString wtext = utf8str_to_wstring(utf8text);
|
||||
return getWidthF32(wtext.c_str(), begin_offset, max_chars);
|
||||
}
|
||||
|
||||
F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S32 max_chars, BOOL use_embedded) const
|
||||
F32 LLFontGL::getWidthF32(const LLWString& utf32text, const S32 begin_offset, const S32 max_chars, BOOL use_embedded) const
|
||||
{
|
||||
const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL;
|
||||
|
||||
const S32 max_index = llmin(begin_offset + max_chars, S32(utf32text.length()));
|
||||
if (max_index <= 0 || begin_offset >= max_index)
|
||||
return 0;
|
||||
|
||||
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++)
|
||||
for (S32 i = begin_offset; i < max_index; i++)
|
||||
{
|
||||
const llwchar wch = wchars[i];
|
||||
const llwchar wch = utf32text[i];
|
||||
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))
|
||||
if( ((i+1) < max_index) && (i+1 < max_index))
|
||||
{
|
||||
cur_x += EXT_KERNING * sScaleX;
|
||||
}
|
||||
@@ -609,15 +570,15 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S
|
||||
(F32)(fgi->mWidth + fgi->mXBearing) - advance); // difference between width of this character and advance to next character
|
||||
|
||||
cur_x += advance;
|
||||
llwchar next_char = wchars[i+1];
|
||||
|
||||
if (((i + 1) < begin_offset + max_chars)
|
||||
&& next_char
|
||||
&& (next_char < LAST_CHARACTER))
|
||||
if ((i + 1) < max_index)
|
||||
{
|
||||
// Kern this puppy.
|
||||
next_glyph = mFontFreetype->getGlyphInfo(next_char);
|
||||
cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
|
||||
llwchar next_char = utf32text[i+1];
|
||||
if (next_char < LAST_CHARACTER)
|
||||
{
|
||||
// Kern this puppy.
|
||||
next_glyph = mFontFreetype->getGlyphInfo(next_char);
|
||||
cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
|
||||
}
|
||||
}
|
||||
// Round after kerning.
|
||||
cur_x = (F32)llmath::llround(cur_x);
|
||||
@@ -633,20 +594,13 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S
|
||||
|
||||
|
||||
// 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,
|
||||
S32 LLFontGL::maxDrawableChars(const LLWString& utf32text, F32 max_pixels, S32 max_chars,
|
||||
EWordWrapStyle end_on_word_boundary, const BOOL use_embedded,
|
||||
F32* drawn_pixels) const
|
||||
{
|
||||
if (!wchars || !wchars[0] || max_chars == 0)
|
||||
{
|
||||
const S32 max_index = llmin(max_chars, S32(utf32text.length()));
|
||||
if (max_index <= 0 || max_pixels <= 0.f)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//llassert(max_pixels >= 0.f);
|
||||
//llassert(max_chars >= 0);
|
||||
if(max_pixels < 0.f || max_chars < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL clip = FALSE;
|
||||
F32 cur_x = 0;
|
||||
@@ -662,15 +616,9 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
|
||||
LLFontGlyphInfo* next_glyph = NULL;
|
||||
|
||||
S32 i;
|
||||
for (i=0; (i < max_chars); i++)
|
||||
for (i=0; (i < max_index); i++)
|
||||
{
|
||||
llwchar wch = wchars[i];
|
||||
|
||||
if(wch == 0)
|
||||
{
|
||||
// Null terminator. We're done.
|
||||
break;
|
||||
}
|
||||
llwchar wch = utf32text[i];
|
||||
|
||||
const embedded_data_t* ext_data = use_embedded ? getEmbeddedCharData(wch) : NULL;
|
||||
if (ext_data)
|
||||
@@ -691,7 +639,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
|
||||
break;
|
||||
}
|
||||
|
||||
if (((i+1) < max_chars) && wchars[i+1])
|
||||
if ((i+1) < max_index)
|
||||
{
|
||||
cur_x += EXT_KERNING * sScaleX;
|
||||
}
|
||||
@@ -741,10 +689,10 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
|
||||
break;
|
||||
}
|
||||
|
||||
if (((i+1) < max_chars) && wchars[i+1])
|
||||
if ((i+1) < max_index)
|
||||
{
|
||||
// Kern this puppy.
|
||||
next_glyph = mFontFreetype->getGlyphInfo(wchars[i+1]);
|
||||
next_glyph = mFontFreetype->getGlyphInfo(utf32text[i + 1]);
|
||||
cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
|
||||
}
|
||||
}
|
||||
@@ -782,22 +730,21 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
|
||||
}
|
||||
|
||||
|
||||
S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos, S32 max_chars) const
|
||||
S32 LLFontGL::firstDrawableChar(const LLWString& utf32text, F32 max_pixels, S32 start_pos, S32 max_chars) const
|
||||
{
|
||||
if (!wchars || !wchars[0] || max_chars == 0)
|
||||
{
|
||||
const S32 max_index = llmin(max_chars, S32(utf32text.length()));
|
||||
if (max_index <= 0 || start_pos >= max_index || max_pixels <= 0.f || start_pos < 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
F32 total_width = 0.0;
|
||||
S32 drawable_chars = 0;
|
||||
|
||||
F32 scaled_max_pixels = max_pixels * sScaleX;
|
||||
|
||||
S32 start = llmin(start_pos, text_len - 1);
|
||||
S32 start = llmin(start_pos, max_index - 1);
|
||||
for (S32 i = start; i >= 0; i--)
|
||||
{
|
||||
llwchar wch = wchars[i];
|
||||
llwchar wch = utf32text[i];
|
||||
|
||||
const embedded_data_t* ext_data = getEmbeddedCharData(wch);
|
||||
F32 width = 0;
|
||||
@@ -825,7 +772,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
|
||||
total_width += width;
|
||||
drawable_chars++;
|
||||
|
||||
if( max_chars >= 0 && drawable_chars >= max_chars )
|
||||
if( max_index >= 0 && drawable_chars >= max_index )
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -833,7 +780,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 += ext_data ? (EXT_KERNING * sScaleX) : mFontFreetype->getXKerning(utf32text[i - 1], wch);
|
||||
}
|
||||
|
||||
// Round after kerning.
|
||||
@@ -854,20 +801,16 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
|
||||
}
|
||||
|
||||
|
||||
S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round, BOOL use_embedded) const
|
||||
S32 LLFontGL::charFromPixelOffset(const LLWString& utf32text, const S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round, BOOL use_embedded) const
|
||||
{
|
||||
if (!wchars || !wchars[0] || max_chars == 0)
|
||||
{
|
||||
const S32 max_index = llmin(begin_offset + max_chars, S32(utf32text.length()));
|
||||
if (max_index <= 0 || begin_offset >= max_index || max_pixels <= 0.f)
|
||||
return 0;
|
||||
}
|
||||
|
||||
F32 cur_x = 0;
|
||||
|
||||
target_x *= sScaleX;
|
||||
|
||||
// max_chars is S32_MAX by default, so make sure we don't get overflow
|
||||
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;
|
||||
@@ -875,7 +818,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset,
|
||||
S32 pos;
|
||||
for (pos = begin_offset; pos < max_index; pos++)
|
||||
{
|
||||
llwchar wch = wchars[pos];
|
||||
llwchar wch = utf32text[pos];
|
||||
if (!wch)
|
||||
{
|
||||
break; // done
|
||||
@@ -912,8 +855,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset,
|
||||
|
||||
cur_x += char_width;
|
||||
|
||||
if (((pos + 1) < max_index)
|
||||
&& (wchars[(pos + 1)]))
|
||||
if ((pos + 1) < max_index)
|
||||
{
|
||||
|
||||
if(ext_data)
|
||||
@@ -922,7 +864,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset,
|
||||
}
|
||||
else
|
||||
{
|
||||
next_glyph = mFontFreetype->getGlyphInfo(wchars[pos + 1]);
|
||||
next_glyph = mFontFreetype->getGlyphInfo(utf32text[pos + 1]);
|
||||
cur_x += mFontFreetype->getXKerning(glyph, next_glyph);
|
||||
}
|
||||
}
|
||||
@@ -933,7 +875,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset,
|
||||
|
||||
}
|
||||
|
||||
return llmin(max_chars, pos - begin_offset);
|
||||
return pos - begin_offset;
|
||||
}
|
||||
|
||||
const LLFontDescriptor& LLFontGL::getFontDesc() const
|
||||
|
||||
@@ -111,27 +111,19 @@ public:
|
||||
BOOL use_embedded = FALSE,
|
||||
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!
|
||||
S32 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;
|
||||
S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const;
|
||||
S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const;
|
||||
S32 renderUTF8(const std::string &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_ellipses = FALSE) const;
|
||||
|
||||
// font metrics - override for LLFont that returns units of virtual pixels
|
||||
F32 getAscenderHeight() const;
|
||||
F32 getDescenderHeight() const;
|
||||
F32 getLineHeight() const;
|
||||
|
||||
S32 getWidth(const std::string& utf8text) const;
|
||||
S32 getWidth(const llwchar* wchars) const;
|
||||
S32 getWidth(const std::string& utf8text, const S32 offset, const S32 max_chars ) const;
|
||||
S32 getWidth(const llwchar* wchars, const S32 offset, const S32 max_chars, BOOL use_embedded = FALSE) const;
|
||||
S32 getWidth(const std::string& utf8str, const S32 offset = 0, const S32 max_chars = S32_MAX, BOOL use_embedded = FALSE) const;
|
||||
S32 getWidth(const LLWString& utf32str, const S32 offset = 0, const S32 max_chars = S32_MAX, BOOL use_embedded = FALSE) const;
|
||||
|
||||
F32 getWidthF32(const std::string& utf8text) const;
|
||||
F32 getWidthF32(const llwchar* wchars) const;
|
||||
F32 getWidthF32(const std::string& text, const S32 offset, const S32 max_chars ) const;
|
||||
F32 getWidthF32(const llwchar* wchars, const S32 offset, const S32 max_chars, BOOL use_embedded = FALSE ) const;
|
||||
F32 getWidthF32(const std::string& utf8str, const S32 offset = 0, const S32 max_chars = S32_MAX, BOOL use_embedded = FALSE) const;
|
||||
F32 getWidthF32(const LLWString& utf32str, const S32 offset = 0, const S32 max_chars = S32_MAX, BOOL use_embedded = FALSE) const;
|
||||
|
||||
// The following are called often, frequently with large buffers, so do not use a string interface
|
||||
|
||||
@@ -142,15 +134,15 @@ public:
|
||||
WORD_BOUNDARY_IF_POSSIBLE,
|
||||
ANYWHERE
|
||||
} EWordWrapStyle ;
|
||||
S32 maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars = S32_MAX, EWordWrapStyle end_on_word_boundary = ANYWHERE,
|
||||
S32 maxDrawableChars(const LLWString& utf32str, F32 max_pixels = F32_MAX, S32 max_chars = S32_MAX, EWordWrapStyle end_on_word_boundary = ANYWHERE,
|
||||
const BOOL use_embedded = FALSE, F32* drawn_pixels = NULL) 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;
|
||||
S32 firstDrawableChar(const LLWString& utf32str, F32 max_pixels = F32_MAX, 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, const S32 char_offset, F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX, BOOL round = TRUE, BOOL use_embedded = FALSE) const;
|
||||
S32 charFromPixelOffset(const LLWString& utf32str, const S32 char_offset, F32 x, F32 max_pixels = F32_MAX, S32 max_chars = S32_MAX, BOOL round = TRUE, BOOL use_embedded = FALSE) const;
|
||||
|
||||
const LLFontDescriptor& getFontDesc() const;
|
||||
|
||||
|
||||
@@ -396,15 +396,16 @@ void LLLineEditor::setCursor( S32 pos )
|
||||
S32 pixels_after_scroll = findPixelNearestPos();
|
||||
if( pixels_after_scroll > mMaxHPixels )
|
||||
{
|
||||
S32 width_chars_to_left = mGLFont->getWidth(mText.getWString().c_str(), 0, mScrollHPos);
|
||||
S32 last_visible_char = mGLFont->maxDrawableChars(mText.getWString().c_str(), llmax(0.f, (F32)(mMaxHPixels - mMinHPixels + width_chars_to_left)));
|
||||
const LLWString& utf32text = mText.getWString();
|
||||
S32 width_chars_to_left = mGLFont->getWidth(utf32text, 0, mScrollHPos);
|
||||
S32 last_visible_char = mGLFont->maxDrawableChars(utf32text, llmax(0.f, (F32)(mMaxHPixels - mMinHPixels + width_chars_to_left)));
|
||||
// character immediately to left of cursor should be last one visible (SCROLL_INCREMENT_ADD will scroll in more characters)
|
||||
// or first character if cursor is at beginning
|
||||
S32 new_last_visible_char = llmax(0, getCursor() - 1);
|
||||
S32 min_scroll = mGLFont->firstDrawableChar(mText.getWString().c_str(), (F32)(mMaxHPixels - mMinHPixels - UI_LINEEDITOR_CURSOR_THICKNESS - UI_LINEEDITOR_H_PAD), mText.length(), new_last_visible_char);
|
||||
S32 min_scroll = mGLFont->firstDrawableChar(utf32text, (F32)(mMaxHPixels - mMinHPixels - UI_LINEEDITOR_CURSOR_THICKNESS - UI_LINEEDITOR_H_PAD), new_last_visible_char);
|
||||
if (old_cursor_pos == last_visible_char)
|
||||
{
|
||||
mScrollHPos = llmin(mText.length(), llmax(min_scroll, mScrollHPos + SCROLL_INCREMENT_ADD));
|
||||
mScrollHPos = llmin(utf32text.length(), LLWString::size_type(llmax(min_scroll, mScrollHPos + SCROLL_INCREMENT_ADD)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -564,8 +564,9 @@ void LLMenuItemGL::draw( void )
|
||||
std::string::size_type offset = upper_case_label.find(mJumpKey);
|
||||
if (offset != std::string::npos)
|
||||
{
|
||||
S32 x_begin = LEFT_PLAIN_PIXELS + mFont->getWidth(mLabel, 0, offset);
|
||||
S32 x_end = LEFT_PLAIN_PIXELS + mFont->getWidth(mLabel, 0, offset + 1);
|
||||
const LLWString& utf32text = mLabel.getWString();
|
||||
S32 x_begin = LEFT_PLAIN_PIXELS + mFont->getWidth(utf32text, 0, offset);
|
||||
S32 x_end = LEFT_PLAIN_PIXELS + mFont->getWidth(utf32text, 0, offset + 1);
|
||||
gl_line_2d(x_begin, (MENU_ITEM_PADDING / 2) + 1, x_end, (MENU_ITEM_PADDING / 2) + 1);
|
||||
}
|
||||
}
|
||||
@@ -1826,9 +1827,10 @@ void LLMenuItemBranchDownGL::draw( void )
|
||||
std::string::size_type offset = upper_case_label.find(getJumpKey());
|
||||
if (offset != std::string::npos)
|
||||
{
|
||||
S32 x_offset = llmath::llround((F32)getRect().getWidth() / 2.f - getFont()->getWidthF32(mLabel.getString(), 0, S32_MAX) / 2.f);
|
||||
S32 x_begin = x_offset + getFont()->getWidth(mLabel, 0, offset);
|
||||
S32 x_end = x_offset + getFont()->getWidth(mLabel, 0, offset + 1);
|
||||
const LLWString& utf32text = mLabel.getWString();
|
||||
S32 x_offset = llmath::llround((F32)getRect().getWidth() / 2.f - getFont()->getWidthF32(utf32text, 0, S32_MAX) / 2.f);
|
||||
S32 x_begin = x_offset + getFont()->getWidth(utf32text, 0, offset);
|
||||
S32 x_end = x_offset + getFont()->getWidth(utf32text, 0, offset + 1);
|
||||
gl_line_2d(x_begin, LABEL_BOTTOM_PAD_PIXELS, x_end, LABEL_BOTTOM_PAD_PIXELS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -572,7 +572,7 @@ S32 LLScrollListCtrl::calcMaxContentWidth()
|
||||
{
|
||||
mColumnWidthsDirty = false;
|
||||
// update max content width for this column, by looking at all items
|
||||
column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0;
|
||||
column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel.getWString()) + mColumnPadding + HEADING_TEXT_PADDING : 0;
|
||||
item_list::iterator iter;
|
||||
for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
|
||||
{
|
||||
|
||||
@@ -3462,12 +3462,12 @@ void LLTextEditor::drawText()
|
||||
{
|
||||
const LLFontGL *num_font = LLFontGL::getFontMonospace();
|
||||
F32 y_top = text_y + ((F32)llmath::llround(num_font->getLineHeight()) / 2);
|
||||
const LLWString ltext = utf8str_to_wstring(llformat("%*d", UI_TEXTEDITOR_LINE_NUMBER_DIGITS, cur_line_num ));
|
||||
BOOL is_cur_line = getCurrentLine() == cur_line_num;
|
||||
const U8 style = is_cur_line ? LLFontGL::BOLD : LLFontGL::NORMAL;
|
||||
const LLColor4 fg_color = is_cur_line ? mCursorColor : mReadOnlyFgColor;
|
||||
num_font->render(
|
||||
ltext, // string to draw
|
||||
|
||||
num_font->renderUTF8(
|
||||
llformat("%*d", UI_TEXTEDITOR_LINE_NUMBER_DIGITS, cur_line_num), // string to draw
|
||||
0, // begin offset
|
||||
3., // x
|
||||
y_top, // y
|
||||
@@ -3477,7 +3477,8 @@ void LLTextEditor::drawText()
|
||||
style,
|
||||
LLFontGL::NO_SHADOW,
|
||||
S32_MAX, // max chars
|
||||
UI_TEXTEDITOR_LINE_NUMBER_MARGIN); // max pixels
|
||||
UI_TEXTEDITOR_LINE_NUMBER_MARGIN,
|
||||
NULL); // max pixels
|
||||
}
|
||||
|
||||
S32 seg_start = line_start;
|
||||
|
||||
Reference in New Issue
Block a user