Chromium Code Reviews| Index: ui/gfx/render_text.cc |
| diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc |
| index cdc706ed28193eee11213fa5154fbc1e4447a265..1c8ca71b55ed84245fe1b3262c09302a11e46f85 100644 |
| --- a/ui/gfx/render_text.cc |
| +++ b/ui/gfx/render_text.cc |
| @@ -306,8 +306,19 @@ RenderText::~RenderText() { |
| void RenderText::SetText(const base::string16& text) { |
| DCHECK(!composition_range_.IsValid()); |
| + if (text_ == text) |
| + return; |
| text_ = text; |
| + // TODO: we might be displaying obscured_text... also move somewhere better. |
|
Alexei Svitkine (slow)
2013/07/09 15:35:13
I think this should be done at the end of UpdateLa
ckocagil
2013/07/13 16:05:10
Done.
|
| + line_breaks_.clear(); |
| + base::i18n::BreakIterator iter(text_, base::i18n::BreakIterator::BREAK_LINE); |
| + bool success = iter.Init(); |
| + CHECK(success); |
| + do { |
| + line_breaks_.push_back(iter.pos()); |
| + } while (iter.Advance()); |
| + |
| // Adjust ranged styles and colors to accommodate a new text length. |
| const size_t text_length = text_.length(); |
| colors_.SetMax(text_length); |
| @@ -397,6 +408,7 @@ void RenderText::SetObscuredRevealIndex(int index) { |
| void RenderText::SetDisplayRect(const Rect& r) { |
| display_rect_ = r; |
| cached_bounds_and_offset_valid_ = false; |
| + lines_valid_ = false; |
| } |
| void RenderText::SetCursorPosition(size_t position) { |
| @@ -689,18 +701,50 @@ Rect RenderText::GetCursorBounds(const SelectionModel& caret, |
| // since there is nothing to overtype. |
| if ((GetTextDirection() == base::i18n::RIGHT_TO_LEFT) == (caret_pos == 0)) |
| x = size.width(); |
| - } else { |
| - size_t grapheme_start = (caret_affinity == CURSOR_FORWARD) ? |
| - caret_pos : IndexOfAdjacentGrapheme(caret_pos, CURSOR_BACKWARD); |
| - ui::Range xspan(GetGlyphBounds(grapheme_start)); |
| - if (insert_mode) { |
| - x = (caret_affinity == CURSOR_BACKWARD) ? xspan.end() : xspan.start(); |
| - } else { // overtype mode |
| - x = xspan.GetMin(); |
| - width = xspan.length(); |
| + } else { |
| + size_t grapheme_start = (caret_affinity == CURSOR_FORWARD) ? |
| + caret_pos : IndexOfAdjacentGrapheme(caret_pos, CURSOR_BACKWARD); |
| + ui::Range xspan(GetGlyphBounds(grapheme_start)); |
| + if (insert_mode) { |
| + x = (caret_affinity == CURSOR_BACKWARD) ? xspan.end() : xspan.start(); |
| + } else { // overtype mode |
| + x = xspan.GetMin(); |
| + width = xspan.length(); |
| + } |
| + } |
| + return Rect(ToViewPoint(Point(x, 0)), Size(width, size.height())); |
| +} |
| + |
| +std::vector<Rect> RenderText::RangeToViewRects(const ui::Range& x, int y) { |
| + std::vector<Rect> rects; |
| + |
| + int height = GetStringSize().height(); |
|
msw
2013/07/10 04:01:56
This is fine for the single line case, but each li
ckocagil
2013/07/13 16:05:10
Done.
|
| + |
| + if (!multiline()) { |
| + Point start(x.GetMin(), y); |
| + rects.push_back(Rect(ToViewPoint(start), Size(x.length(), height))); |
| + return rects; |
| + } |
| + |
| + EnsureLayout(); |
| + ComputeLines(); |
|
msw
2013/07/10 04:01:56
EnsureLayout should ComputeLines as needed, don't
ckocagil
2013/07/13 16:05:10
Done.
|
| + |
| + for (size_t line = 0; line < lines().size(); ++line) { |
|
msw
2013/07/10 04:01:56
Add a comment to explain what's happening here, it
ckocagil
2013/07/13 16:05:10
Done.
|
| + int line_x = 0; |
| + for (size_t i = 0; i < lines()[line].size(); ++i) { |
| + const internal::LineSegment* segment = lines()[line][i]; |
| + ui::Range intersection = segment->x_pos.Intersect(x); |
| + if (!intersection.is_empty()) { |
| + Rect rect(line_x + intersection.start() - segment->x_pos.start(), |
| + y + line * height, intersection.length(), height); |
|
msw
2013/07/10 04:01:56
You need to use the proper per-line heights; at le
ckocagil
2013/07/13 16:05:10
Done, it uses per-line heights now.
|
| + rect += GetTextOffset(LineWidth(line)); |
|
msw
2013/07/10 04:01:56
Cache the line's offset in the outer loop.
ckocagil
2013/07/13 16:05:10
Done.
|
| + rects.push_back(rect); |
| + } |
| + line_x += segment->x_pos.length(); |
| } |
| } |
| - return Rect(ToViewPoint(Point(x, 0)), Size(width, size.height())); |
| + |
| + return rects; |
| } |
| const Rect& RenderText::GetUpdatedCursorBounds() { |
| @@ -763,11 +807,13 @@ RenderText::RenderText() |
| composition_and_selection_styles_applied_(false), |
| obscured_(false), |
| obscured_reveal_index_(-1), |
| + multiline_(false), |
| fade_head_(false), |
| fade_tail_(false), |
| background_is_transparent_(false), |
| clip_to_display_rect_(true), |
| - cached_bounds_and_offset_valid_(false) { |
| + cached_bounds_and_offset_valid_(false), |
| + lines_valid_(false) { |
| } |
| const Vector2d& RenderText::GetUpdatedDisplayOffset() { |
| @@ -832,30 +878,45 @@ void RenderText::UndoCompositionAndSelectionStyles() { |
| composition_and_selection_styles_applied_ = false; |
| } |
| -Vector2d RenderText::GetTextOffset() { |
| +Vector2d RenderText::GetTextOffset(int line_width) { |
| Vector2d offset = display_rect().OffsetFromOrigin(); |
| - offset.Add(GetUpdatedDisplayOffset()); |
| - offset.Add(GetAlignmentOffset()); |
| + if (!multiline()) |
|
msw
2013/07/10 04:01:56
Why ignore the display offset for multi-line? Even
ckocagil
2013/07/13 16:05:10
I ignored it for now because multi-line vertical s
|
| + offset.Add(GetUpdatedDisplayOffset()); |
| + offset.Add(GetAlignmentOffset(line_width)); |
| return offset; |
| } |
| Point RenderText::ToTextPoint(const Point& point) { |
| - return point - GetTextOffset(); |
| + return point - GetTextOffset(GetContentWidth()); |
| + // TODO: implement multiline |
|
Alexei Svitkine (slow)
2013/07/09 15:35:13
TODO(ckocagil)
ckocagil
2013/07/13 16:05:10
Done.
|
| } |
| Point RenderText::ToViewPoint(const Point& point) { |
| - return point + GetTextOffset(); |
| + if (!multiline()) |
| + return point + GetTextOffset(GetContentWidth()); |
| + |
| + ComputeLines(); |
|
msw
2013/07/10 04:01:56
Don't explicitly call this here, EnsureLayout or [
ckocagil
2013/07/13 16:05:10
Done.
|
| + int x = point.x(); |
| + unsigned int line = 0; |
| + while (line < lines_.size() && x > LineWidth(line)) { |
| + x -= LineWidth(line); |
|
Alexei Svitkine (slow)
2013/07/09 15:35:13
Can you refactor this code to not call LineWidth()
ckocagil
2013/07/13 16:05:10
I will rewrite this method to support RTL soon (be
|
| + ++line; |
| + } |
| + return Point(x, point.y() + line * GetStringSize().height()) + |
|
msw
2013/07/10 04:01:56
Again, this needs per-line heights.
ckocagil
2013/07/13 16:05:10
Done.
|
| + GetTextOffset(LineWidth(line)); |
| } |
| -Vector2d RenderText::GetAlignmentOffset() { |
| +Vector2d RenderText::GetAlignmentOffset(int line_width) { |
| + |
|
msw
2013/07/10 04:01:56
nit: remove blank line.
ckocagil
2013/07/13 16:05:10
Done.
|
| Vector2d offset; |
| if (horizontal_alignment_ != ALIGN_LEFT) { |
| - offset.set_x(display_rect().width() - GetContentWidth()); |
| + offset.set_x(display_rect().width() - (multiline() ? line_width |
|
msw
2013/07/10 04:01:56
Always use |line_width|, you pass in GetContentWid
ckocagil
2013/07/13 16:05:10
I now pass 0 for single-line mode. Single-line mod
|
| + : GetContentWidth())); |
| if (horizontal_alignment_ == ALIGN_CENTER) |
| offset.set_x(offset.x() / 2); |
| } |
| if (vertical_alignment_ != ALIGN_TOP) { |
| - offset.set_y(display_rect().height() - GetStringSize().height()); |
| + offset.set_y(display_rect().height() - GetMultilineTextSize().height()); |
| if (vertical_alignment_ == ALIGN_VCENTER) |
| offset.set_y(offset.y() / 2); |
| } |
| @@ -901,7 +962,7 @@ void RenderText::ApplyFadeEffects(internal::SkiaTextRenderer* renderer) { |
| } |
| Rect text_rect = display_rect(); |
| - text_rect.Inset(GetAlignmentOffset().x(), 0, 0, 0); |
| + text_rect.Inset(GetAlignmentOffset(GetContentWidth()).x(), 0, 0, 0); |
| // TODO(msw): Use the actual text colors corresponding to each faded part. |
| skia::RefPtr<SkShader> shader = CreateFadeShader( |