diff options
-rw-r--r-- | indra/llui/lltextbase.cpp | 46 | ||||
-rw-r--r-- | indra/llui/lltextbase.h | 22 | ||||
-rw-r--r-- | indra/newview/llexpandabletextbox.cpp | 4 | ||||
-rw-r--r-- | indra/newview/llviewertexteditor.cpp | 2 |
4 files changed, 53 insertions, 21 deletions
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 20be739286..88a5c3a587 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1522,6 +1522,7 @@ void LLTextBase::reflow() } S32 line_height = 0; + S32 seg_line_offset = line_count; while(seg_iter != mSegments.end()) { @@ -1534,7 +1535,8 @@ void LLTextBase::reflow() S32 character_count = segment->getNumChars(getWordWrap() ? llmax(0, remaining_pixels) : S32_MAX, seg_offset, cur_index - line_start_index, - S32_MAX); + S32_MAX, + line_count - seg_line_offset); S32 segment_width, segment_height; bool force_newline = segment->getDimensions(seg_offset, character_count, segment_width, segment_height); @@ -1597,6 +1599,7 @@ void LLTextBase::reflow() } ++seg_iter; seg_offset = 0; + seg_line_offset = force_newline ? line_count + 1 : line_count; } if (force_newline) { @@ -3065,7 +3068,7 @@ LLTextSegment::~LLTextSegment() bool LLTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const { width = 0; height = 0; return false;} S32 LLTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const { return 0; } -S32 LLTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const { return 0; } +S32 LLTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const { return 0; } void LLTextSegment::updateLayout(const LLTextBase& editor) {} F32 LLTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect) { return draw_rect.mLeft; } bool LLTextSegment::canEdit() const { return false; } @@ -3335,7 +3338,7 @@ S32 LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, round); } -S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const +S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const { const LLWString &text = getWText(); @@ -3352,7 +3355,7 @@ S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin // if no character yet displayed on this line, don't require word wrapping since // we can just move to the next line, otherwise insist on it so we make forward progress - LLFontGL::EWordWrapStyle word_wrap_style = (line_offset == 0) + LLFontGL::EWordWrapStyle word_wrap_style = (line_offset == 0) ? LLFontGL::WORD_BOUNDARY_IF_POSSIBLE : LLFontGL::ONLY_WORD_BOUNDARIES; @@ -3490,12 +3493,26 @@ LLInlineViewSegment::~LLInlineViewSegment() bool LLInlineViewSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const { - if (first_char == 0 && num_chars == 0) + if (first_char == 0 && num_chars == 0) { - // we didn't fit on a line, the widget will fall on the next line - // so dimensions here are 0 + // We didn't fit on a line or were forced to new string + // the widget will fall on the next line, so width here is 0 width = 0; - height = 0; + + if (mForceNewLine) + { + // Chat, string can't be smaller then font height even if it is empty + LLStyleSP s(new LLStyle(LLStyle::Params().visible(true))); + height = s->getFont()->getLineHeight(); + + return true; // new line + } + else + { + // height from previous segment in same string will be used, word-wrap + height = 0; + } + } else { @@ -3506,13 +3523,16 @@ bool LLInlineViewSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt return false; } -S32 LLInlineViewSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const +S32 LLInlineViewSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const { // if putting a widget anywhere but at the beginning of a line // and the widget doesn't fit or mForceNewLine is true // then return 0 chars for that line, and all characters for the next - if (line_offset != 0 - && (mForceNewLine || num_pixels < mView->getRect().getWidth())) + if (mForceNewLine && line_ind == 0) + { + return 0; + } + else if (line_offset != 0 && num_pixels < mView->getRect().getWidth()) { return 0; } @@ -3565,7 +3585,7 @@ bool LLLineBreakTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& w return true; } -S32 LLLineBreakTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const +S32 LLLineBreakTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const { return 1; } @@ -3601,7 +3621,7 @@ bool LLImageTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width return false; } -S32 LLImageTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const +S32 LLImageTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const { LLUIImagePtr image = mStyle->getImage(); diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 3d3a6ca869..c7b6203445 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -64,7 +64,19 @@ public: virtual bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const; virtual S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const; - virtual S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const; + + /** + * Get number of chars that fit into free part of current line. + * + * @param num_pixels - maximum width of rect + * @param segment_offset - symbol in segment we start processing line from + * @param line_offset - symbol in line after which segment starts + * @param max_chars - limit of symbols that will fit in current line + * @param line_ind - index of not word-wrapped string inside segment for multi-line segments. + * Two string separated by word-wrap will have same index. + * @return number of chars that will fit into current line + */ + virtual S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const; virtual void updateLayout(const class LLTextBase& editor); virtual F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect); virtual bool canEdit() const; @@ -116,7 +128,7 @@ public: /*virtual*/ bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const; /*virtual*/ S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const; - /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const; + /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const; /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect); /*virtual*/ bool canEdit() const { return true; } /*virtual*/ const LLColor4& getColor() const { return mStyle->getColor(); } @@ -201,7 +213,7 @@ public: LLInlineViewSegment(const Params& p, S32 start, S32 end); ~LLInlineViewSegment(); /*virtual*/ bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const; - /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const; + /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const; /*virtual*/ void updateLayout(const class LLTextBase& editor); /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect); /*virtual*/ bool canEdit() const { return false; } @@ -225,7 +237,7 @@ public: LLLineBreakTextSegment(S32 pos); ~LLLineBreakTextSegment(); bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const; - S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const; + S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const; F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect); private: @@ -238,7 +250,7 @@ public: LLImageTextSegment(LLStyleConstSP style,S32 pos,class LLTextBase& editor); ~LLImageTextSegment(); bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const; - S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const; + S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 char_offset, S32 max_chars, S32 line_ind) const; F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect); /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask); diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp index f0331f20d8..314b859cea 100644 --- a/indra/newview/llexpandabletextbox.cpp +++ b/indra/newview/llexpandabletextbox.cpp @@ -63,10 +63,10 @@ public: { return start_offset; } - /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const + /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const { // require full line to ourselves - if (line_offset == 0) + if (line_offset == 0) { // print all our text return getEnd() - getStart(); diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 7323a5b2f3..9e09971ced 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -191,7 +191,7 @@ public: return false; } - /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const + /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const { // always draw at beginning of line if (line_offset == 0) |