Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/gfx/render_text.h" | 5 #include "ui/gfx/render_text.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/i18n/break_iterator.h" | 9 #include "base/i18n/break_iterator.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 294 range = range.Intersect(styles_[i].GetRange(style_[i])); | 294 range = range.Intersect(styles_[i].GetRange(style_[i])); |
| 295 return range; | 295 return range; |
| 296 } | 296 } |
| 297 | 297 |
| 298 void StyleIterator::UpdatePosition(size_t position) { | 298 void StyleIterator::UpdatePosition(size_t position) { |
| 299 color_ = colors_.GetBreak(position); | 299 color_ = colors_.GetBreak(position); |
| 300 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) | 300 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) |
| 301 style_[i] = styles_[i].GetBreak(position); | 301 style_[i] = styles_[i].GetBreak(position); |
| 302 } | 302 } |
| 303 | 303 |
| 304 LineSegment::LineSegment() : run(0) {} | |
| 305 | |
| 306 Line::Line() : preceding_heights(0), baseline(0) {} | |
| 307 | |
| 304 } // namespace internal | 308 } // namespace internal |
| 305 | 309 |
| 306 RenderText::~RenderText() { | 310 RenderText::~RenderText() { |
| 307 } | 311 } |
| 308 | 312 |
| 309 void RenderText::SetText(const base::string16& text) { | 313 void RenderText::SetText(const base::string16& text) { |
| 310 DCHECK(!composition_range_.IsValid()); | 314 DCHECK(!composition_range_.IsValid()); |
| 315 if (text_ == text) | |
| 316 return; | |
| 311 text_ = text; | 317 text_ = text; |
| 312 | 318 |
| 313 // Adjust ranged styles and colors to accommodate a new text length. | 319 // Adjust ranged styles and colors to accommodate a new text length. |
| 314 const size_t text_length = text_.length(); | 320 const size_t text_length = text_.length(); |
| 315 colors_.SetMax(text_length); | 321 colors_.SetMax(text_length); |
| 316 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) | 322 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) |
| 317 styles_[style].SetMax(text_length); | 323 styles_[style].SetMax(text_length); |
| 318 cached_bounds_and_offset_valid_ = false; | 324 cached_bounds_and_offset_valid_ = false; |
| 319 | 325 |
| 320 // Reset selection model. SetText should always followed by SetSelectionModel | 326 // Reset selection model. SetText should always followed by SetSelectionModel |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 387 void RenderText::SetObscuredRevealIndex(int index) { | 393 void RenderText::SetObscuredRevealIndex(int index) { |
| 388 if (obscured_reveal_index_ == index) | 394 if (obscured_reveal_index_ == index) |
| 389 return; | 395 return; |
| 390 | 396 |
| 391 obscured_reveal_index_ = index; | 397 obscured_reveal_index_ = index; |
| 392 cached_bounds_and_offset_valid_ = false; | 398 cached_bounds_and_offset_valid_ = false; |
| 393 UpdateLayoutText(); | 399 UpdateLayoutText(); |
| 394 ResetLayout(); | 400 ResetLayout(); |
| 395 } | 401 } |
| 396 | 402 |
| 403 void RenderText::SetMultiline(bool multiline) { | |
| 404 if (multiline != multiline_) { | |
| 405 multiline_ = multiline; | |
| 406 cached_bounds_and_offset_valid_ = false; | |
| 407 ResetLayout(); | |
|
Alexei Svitkine (slow)
2013/08/28 21:27:46
Is it necessary to reset the complete layout here
ckocagil
2013/08/30 16:53:36
Done.
| |
| 408 } | |
| 409 } | |
| 410 | |
| 397 void RenderText::SetDisplayRect(const Rect& r) { | 411 void RenderText::SetDisplayRect(const Rect& r) { |
| 398 display_rect_ = r; | 412 display_rect_ = r; |
| 399 cached_bounds_and_offset_valid_ = false; | 413 cached_bounds_and_offset_valid_ = false; |
| 414 lines_.clear(); | |
| 400 } | 415 } |
| 401 | 416 |
| 402 void RenderText::SetCursorPosition(size_t position) { | 417 void RenderText::SetCursorPosition(size_t position) { |
| 403 MoveCursorTo(position, false); | 418 MoveCursorTo(position, false); |
| 404 } | 419 } |
| 405 | 420 |
| 406 void RenderText::MoveCursor(BreakType break_type, | 421 void RenderText::MoveCursor(BreakType break_type, |
| 407 VisualCursorDirection direction, | 422 VisualCursorDirection direction, |
| 408 bool select) { | 423 bool select) { |
| 409 SelectionModel position(cursor_position(), selection_model_.caret_affinity()); | 424 SelectionModel position(cursor_position(), selection_model_.caret_affinity()); |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 768 selection_color_(kDefaultColor), | 783 selection_color_(kDefaultColor), |
| 769 selection_background_focused_color_(kDefaultSelectionBackgroundColor), | 784 selection_background_focused_color_(kDefaultSelectionBackgroundColor), |
| 770 focused_(false), | 785 focused_(false), |
| 771 composition_range_(ui::Range::InvalidRange()), | 786 composition_range_(ui::Range::InvalidRange()), |
| 772 colors_(kDefaultColor), | 787 colors_(kDefaultColor), |
| 773 styles_(NUM_TEXT_STYLES), | 788 styles_(NUM_TEXT_STYLES), |
| 774 composition_and_selection_styles_applied_(false), | 789 composition_and_selection_styles_applied_(false), |
| 775 obscured_(false), | 790 obscured_(false), |
| 776 obscured_reveal_index_(-1), | 791 obscured_reveal_index_(-1), |
| 777 truncate_length_(0), | 792 truncate_length_(0), |
| 793 multiline_(false), | |
| 778 fade_head_(false), | 794 fade_head_(false), |
| 779 fade_tail_(false), | 795 fade_tail_(false), |
| 780 background_is_transparent_(false), | 796 background_is_transparent_(false), |
| 781 clip_to_display_rect_(true), | 797 clip_to_display_rect_(true), |
| 782 cached_bounds_and_offset_valid_(false) { | 798 cached_bounds_and_offset_valid_(false) { |
| 783 } | 799 } |
| 784 | 800 |
| 785 const Vector2d& RenderText::GetUpdatedDisplayOffset() { | 801 const Vector2d& RenderText::GetUpdatedDisplayOffset() { |
| 786 UpdateCachedBoundsAndOffset(); | 802 UpdateCachedBoundsAndOffset(); |
| 787 return display_offset_; | 803 return display_offset_; |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 811 void RenderText::SetSelectionModel(const SelectionModel& model) { | 827 void RenderText::SetSelectionModel(const SelectionModel& model) { |
| 812 DCHECK_LE(model.selection().GetMax(), text().length()); | 828 DCHECK_LE(model.selection().GetMax(), text().length()); |
| 813 selection_model_ = model; | 829 selection_model_ = model; |
| 814 cached_bounds_and_offset_valid_ = false; | 830 cached_bounds_and_offset_valid_ = false; |
| 815 } | 831 } |
| 816 | 832 |
| 817 const base::string16& RenderText::GetLayoutText() const { | 833 const base::string16& RenderText::GetLayoutText() const { |
| 818 return layout_text_.empty() ? text_ : layout_text_; | 834 return layout_text_.empty() ? text_ : layout_text_; |
| 819 } | 835 } |
| 820 | 836 |
| 837 const BreakList<size_t>& RenderText::GetLineBreaks() { | |
| 838 if (line_breaks_.max()) | |
|
msw
2013/08/30 00:42:28
nit: add an explicit "!= 0"
ckocagil
2013/08/30 16:53:36
Done.
| |
| 839 return line_breaks_; | |
| 840 | |
| 841 const string16& layout_text = GetLayoutText(); | |
| 842 const size_t text_length = layout_text.length(); | |
| 843 line_breaks_.SetValue(0); | |
| 844 line_breaks_.SetMax(text_length); | |
| 845 base::i18n::BreakIterator iter(layout_text, | |
| 846 base::i18n::BreakIterator::BREAK_LINE); | |
| 847 bool success = iter.Init(); | |
| 848 DCHECK(success); | |
| 849 if (success) { | |
| 850 do { | |
| 851 line_breaks_.ApplyValue(iter.pos(), ui::Range(iter.pos(), text_length)); | |
| 852 } while (iter.Advance()); | |
| 853 } | |
| 854 return line_breaks_; | |
| 855 } | |
| 856 | |
| 821 void RenderText::ApplyCompositionAndSelectionStyles() { | 857 void RenderText::ApplyCompositionAndSelectionStyles() { |
| 822 // Save the underline and color breaks to undo the temporary styles later. | 858 // Save the underline and color breaks to undo the temporary styles later. |
| 823 DCHECK(!composition_and_selection_styles_applied_); | 859 DCHECK(!composition_and_selection_styles_applied_); |
| 824 saved_colors_ = colors_; | 860 saved_colors_ = colors_; |
| 825 saved_underlines_ = styles_[UNDERLINE]; | 861 saved_underlines_ = styles_[UNDERLINE]; |
| 826 | 862 |
| 827 // Apply an underline to the composition range in |underlines|. | 863 // Apply an underline to the composition range in |underlines|. |
| 828 if (composition_range_.IsValid() && !composition_range_.is_empty()) | 864 if (composition_range_.IsValid() && !composition_range_.is_empty()) |
| 829 styles_[UNDERLINE].ApplyValue(true, composition_range_); | 865 styles_[UNDERLINE].ApplyValue(true, composition_range_); |
| 830 | 866 |
| 831 // Apply the selected text color to the [un-reversed] selection range. | 867 // Apply the selected text color to the [un-reversed] selection range. |
| 832 if (!selection().is_empty()) { | 868 if (!selection().is_empty()) { |
| 833 const ui::Range range(selection().GetMin(), selection().GetMax()); | 869 const ui::Range range(selection().GetMin(), selection().GetMax()); |
| 834 colors_.ApplyValue(selection_color_, range); | 870 colors_.ApplyValue(selection_color_, range); |
| 835 } | 871 } |
| 836 composition_and_selection_styles_applied_ = true; | 872 composition_and_selection_styles_applied_ = true; |
| 837 } | 873 } |
| 838 | 874 |
| 839 void RenderText::UndoCompositionAndSelectionStyles() { | 875 void RenderText::UndoCompositionAndSelectionStyles() { |
| 840 // Restore the underline and color breaks to undo the temporary styles. | 876 // Restore the underline and color breaks to undo the temporary styles. |
| 841 DCHECK(composition_and_selection_styles_applied_); | 877 DCHECK(composition_and_selection_styles_applied_); |
| 842 colors_ = saved_colors_; | 878 colors_ = saved_colors_; |
| 843 styles_[UNDERLINE] = saved_underlines_; | 879 styles_[UNDERLINE] = saved_underlines_; |
| 844 composition_and_selection_styles_applied_ = false; | 880 composition_and_selection_styles_applied_ = false; |
| 845 } | 881 } |
| 846 | 882 |
| 847 Vector2d RenderText::GetTextOffset() { | 883 Vector2d RenderText::GetLineOffset(size_t line_number) { |
| 848 Vector2d offset = display_rect().OffsetFromOrigin(); | 884 Vector2d offset = display_rect().OffsetFromOrigin(); |
| 849 offset.Add(GetUpdatedDisplayOffset()); | 885 if (!multiline()) |
| 850 offset.Add(GetAlignmentOffset()); | 886 offset.Add(GetUpdatedDisplayOffset()); |
| 887 else | |
| 888 offset.Add(Vector2d(0, lines_[line_number].preceding_heights)); | |
| 889 offset.Add(GetAlignmentOffset(line_number)); | |
| 851 return offset; | 890 return offset; |
| 852 } | 891 } |
| 853 | 892 |
| 854 Point RenderText::ToTextPoint(const Point& point) { | 893 Point RenderText::ToTextPoint(const Point& point) { |
| 855 return point - GetTextOffset(); | 894 return point - GetLineOffset(0); |
| 895 // TODO(ckocagil): implement multiline. | |
| 856 } | 896 } |
| 857 | 897 |
| 858 Point RenderText::ToViewPoint(const Point& point) { | 898 Point RenderText::ToViewPoint(const Point& point) { |
| 859 return point + GetTextOffset(); | 899 if (!multiline()) |
| 900 return point + GetLineOffset(0); | |
| 901 | |
| 902 // TODO(ckocagil): refactor this to traverse all line segments to support rtl. | |
| 903 DCHECK(!lines_.empty()); | |
| 904 int x = point.x(); | |
| 905 size_t line = 0; | |
| 906 while (line < lines_.size() && x > lines_[line].size.width()) { | |
| 907 x -= lines_[line].size.width(); | |
| 908 ++line; | |
| 909 } | |
| 910 return Point(x, point.y()) + GetLineOffset(line); | |
| 860 } | 911 } |
| 861 | 912 |
| 862 Vector2d RenderText::GetAlignmentOffset() { | 913 std::vector<Rect> RenderText::TextBoundsToViewBounds(const ui::Range& x) { |
| 914 std::vector<Rect> rects; | |
| 915 | |
| 916 if (!multiline()) { | |
| 917 rects.push_back(Rect(ToViewPoint(Point(x.GetMin(), 0)), | |
| 918 Size(x.length(), GetStringSize().height()))); | |
| 919 return rects; | |
| 920 } | |
| 921 | |
| 922 EnsureLayout(); | |
| 923 | |
| 924 // Each line segment keeps its position in text coordinates. Traverse all line | |
| 925 // segments and if the segment intersects with the given range, add the view | |
| 926 // rect corresponding to the intersection to |rects|. | |
| 927 for (size_t line = 0; line < lines_.size(); ++line) { | |
| 928 int line_x = 0; | |
| 929 Vector2d offset = GetLineOffset(line); | |
| 930 for (size_t i = 0; i < lines_[line].segments.size(); ++i) { | |
| 931 const internal::LineSegment* segment = &lines_[line].segments[i]; | |
| 932 const ui::Range intersection = segment->x_range.Intersect(x); | |
| 933 if (!intersection.is_empty()) { | |
| 934 Rect rect(line_x + intersection.start() - segment->x_range.start(), | |
| 935 0, intersection.length(), lines_[line].size.height()); | |
| 936 rects.push_back(rect + offset); | |
| 937 } | |
| 938 line_x += segment->x_range.length(); | |
| 939 } | |
| 940 } | |
| 941 | |
| 942 return rects; | |
| 943 } | |
| 944 | |
| 945 Vector2d RenderText::GetAlignmentOffset(size_t line_number) { | |
| 946 DCHECK_LT(line_number, lines_.size()); | |
| 863 Vector2d offset; | 947 Vector2d offset; |
| 864 if (horizontal_alignment_ != ALIGN_LEFT) { | 948 if (horizontal_alignment_ != ALIGN_LEFT) { |
| 865 offset.set_x(display_rect().width() - GetContentWidth()); | 949 const int width = lines_[line_number].size.width() + |
| 950 (cursor_enabled_ ? 1 : 0); | |
| 951 offset.set_x(display_rect().width() - width); | |
| 866 if (horizontal_alignment_ == ALIGN_CENTER) | 952 if (horizontal_alignment_ == ALIGN_CENTER) |
| 867 offset.set_x(offset.x() / 2); | 953 offset.set_x(offset.x() / 2); |
| 868 } | 954 } |
| 869 if (vertical_alignment_ != ALIGN_TOP) { | 955 if (vertical_alignment_ != ALIGN_TOP) { |
| 870 offset.set_y(display_rect().height() - GetStringSize().height()); | 956 offset.set_y(display_rect().height() - GetMultilineTextSize().height()); |
| 871 if (vertical_alignment_ == ALIGN_VCENTER) | 957 if (vertical_alignment_ == ALIGN_VCENTER) |
| 872 offset.set_y(offset.y() / 2); | 958 offset.set_y(offset.y() / 2); |
| 873 } | 959 } |
| 874 return offset; | 960 return offset; |
| 875 } | 961 } |
| 876 | 962 |
| 877 void RenderText::ApplyFadeEffects(internal::SkiaTextRenderer* renderer) { | 963 void RenderText::ApplyFadeEffects(internal::SkiaTextRenderer* renderer) { |
| 878 if (!fade_head() && !fade_tail()) | 964 if (multiline() || !fade_head() && !fade_tail()) |
| 879 return; | 965 return; |
| 880 | 966 |
| 881 const int text_width = GetStringSize().width(); | |
| 882 const int display_width = display_rect().width(); | 967 const int display_width = display_rect().width(); |
| 883 | 968 |
| 884 // If the text fits as-is, no need to fade. | 969 // If the text fits as-is, no need to fade. |
| 885 if (text_width <= display_width) | 970 if (GetStringSize().width() <= display_width) |
| 886 return; | 971 return; |
| 887 | 972 |
| 888 int gradient_width = CalculateFadeGradientWidth(GetPrimaryFont(), | 973 int gradient_width = CalculateFadeGradientWidth(GetPrimaryFont(), |
| 889 display_width); | 974 display_width); |
| 890 if (gradient_width == 0) | 975 if (gradient_width == 0) |
| 891 return; | 976 return; |
| 892 | 977 |
| 893 bool fade_left = fade_head(); | 978 bool fade_left = fade_head(); |
| 894 bool fade_right = fade_tail(); | 979 bool fade_right = fade_tail(); |
| 895 // Under RTL, |fade_right| == |fade_head|. | 980 // Under RTL, |fade_right| == |fade_head|. |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 907 left_part.Inset(0, 0, solid_part.width() - gradient_width, 0); | 992 left_part.Inset(0, 0, solid_part.width() - gradient_width, 0); |
| 908 solid_part.Inset(gradient_width, 0, 0, 0); | 993 solid_part.Inset(gradient_width, 0, 0, 0); |
| 909 } | 994 } |
| 910 if (fade_right) { | 995 if (fade_right) { |
| 911 right_part = solid_part; | 996 right_part = solid_part; |
| 912 right_part.Inset(solid_part.width() - gradient_width, 0, 0, 0); | 997 right_part.Inset(solid_part.width() - gradient_width, 0, 0, 0); |
| 913 solid_part.Inset(0, 0, gradient_width, 0); | 998 solid_part.Inset(0, 0, gradient_width, 0); |
| 914 } | 999 } |
| 915 | 1000 |
| 916 Rect text_rect = display_rect(); | 1001 Rect text_rect = display_rect(); |
| 917 text_rect.Inset(GetAlignmentOffset().x(), 0, 0, 0); | 1002 text_rect.Inset(GetAlignmentOffset(0).x(), 0, 0, 0); |
| 918 | 1003 |
| 919 // TODO(msw): Use the actual text colors corresponding to each faded part. | 1004 // TODO(msw): Use the actual text colors corresponding to each faded part. |
| 920 skia::RefPtr<SkShader> shader = CreateFadeShader( | 1005 skia::RefPtr<SkShader> shader = CreateFadeShader( |
| 921 text_rect, left_part, right_part, colors_.breaks().front().second); | 1006 text_rect, left_part, right_part, colors_.breaks().front().second); |
| 922 if (shader) | 1007 if (shader) |
| 923 renderer->SetShader(shader.get(), display_rect()); | 1008 renderer->SetShader(shader.get(), display_rect()); |
| 924 } | 1009 } |
| 925 | 1010 |
| 926 void RenderText::ApplyTextShadows(internal::SkiaTextRenderer* renderer) { | 1011 void RenderText::ApplyTextShadows(internal::SkiaTextRenderer* renderer) { |
| 927 skia::RefPtr<SkDrawLooper> looper = CreateShadowDrawLooper(text_shadows_); | 1012 skia::RefPtr<SkDrawLooper> looper = CreateShadowDrawLooper(text_shadows_); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 941 void RenderText::MoveCursorTo(size_t position, bool select) { | 1026 void RenderText::MoveCursorTo(size_t position, bool select) { |
| 942 size_t cursor = std::min(position, text().length()); | 1027 size_t cursor = std::min(position, text().length()); |
| 943 if (IsCursorablePosition(cursor)) | 1028 if (IsCursorablePosition(cursor)) |
| 944 SetSelectionModel(SelectionModel( | 1029 SetSelectionModel(SelectionModel( |
| 945 ui::Range(select ? selection().start() : cursor, cursor), | 1030 ui::Range(select ? selection().start() : cursor, cursor), |
| 946 (cursor == 0) ? CURSOR_FORWARD : CURSOR_BACKWARD)); | 1031 (cursor == 0) ? CURSOR_FORWARD : CURSOR_BACKWARD)); |
| 947 } | 1032 } |
| 948 | 1033 |
| 949 void RenderText::UpdateLayoutText() { | 1034 void RenderText::UpdateLayoutText() { |
| 950 layout_text_.clear(); | 1035 layout_text_.clear(); |
| 1036 line_breaks_.SetMax(0); | |
| 951 | 1037 |
| 952 if (obscured_) { | 1038 if (obscured_) { |
| 953 size_t obscured_text_length = | 1039 size_t obscured_text_length = |
| 954 static_cast<size_t>(ui::UTF16IndexToOffset(text_, 0, text_.length())); | 1040 static_cast<size_t>(ui::UTF16IndexToOffset(text_, 0, text_.length())); |
| 955 layout_text_.assign(obscured_text_length, kPasswordReplacementChar); | 1041 layout_text_.assign(obscured_text_length, kPasswordReplacementChar); |
| 956 | 1042 |
| 957 if (obscured_reveal_index_ >= 0 && | 1043 if (obscured_reveal_index_ >= 0 && |
| 958 obscured_reveal_index_ < static_cast<int>(text_.length())) { | 1044 obscured_reveal_index_ < static_cast<int>(text_.length())) { |
| 959 // Gets the index range in |text_| to be revealed. | 1045 // Gets the index range in |text_| to be revealed. |
| 960 size_t start = obscured_reveal_index_; | 1046 size_t start = obscured_reveal_index_; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 977 icu::StringCharacterIterator iter(text.c_str()); | 1063 icu::StringCharacterIterator iter(text.c_str()); |
| 978 iter.setIndex32(truncate_length_ - 1); | 1064 iter.setIndex32(truncate_length_ - 1); |
| 979 layout_text_.assign(text.substr(0, iter.getIndex()) + ui::kEllipsisUTF16); | 1065 layout_text_.assign(text.substr(0, iter.getIndex()) + ui::kEllipsisUTF16); |
| 980 } | 1066 } |
| 981 } | 1067 } |
| 982 | 1068 |
| 983 void RenderText::UpdateCachedBoundsAndOffset() { | 1069 void RenderText::UpdateCachedBoundsAndOffset() { |
| 984 if (cached_bounds_and_offset_valid_) | 1070 if (cached_bounds_and_offset_valid_) |
| 985 return; | 1071 return; |
| 986 | 1072 |
| 1073 // TODO(ckocagil): Add vertical offset support for scrolling multi-line text. | |
| 1074 | |
| 987 // First, set the valid flag true to calculate the current cursor bounds using | 1075 // First, set the valid flag true to calculate the current cursor bounds using |
| 988 // the stale |display_offset_|. Applying |delta_offset| at the end of this | 1076 // the stale |display_offset_|. Applying |delta_offset| at the end of this |
| 989 // function will set |cursor_bounds_| and |display_offset_| to correct values. | 1077 // function will set |cursor_bounds_| and |display_offset_| to correct values. |
| 990 cached_bounds_and_offset_valid_ = true; | 1078 cached_bounds_and_offset_valid_ = true; |
| 991 cursor_bounds_ = GetCursorBounds(selection_model_, insert_mode_); | 1079 cursor_bounds_ = GetCursorBounds(selection_model_, insert_mode_); |
| 992 | 1080 |
| 993 // Update |display_offset_| to ensure the current cursor is visible. | 1081 // Update |display_offset_| to ensure the current cursor is visible. |
| 994 const int display_width = display_rect_.width(); | 1082 const int display_width = display_rect_.width(); |
| 995 const int content_width = GetContentWidth(); | 1083 const int content_width = GetContentWidth(); |
| 996 | 1084 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1027 cursor_bounds_ += delta_offset; | 1115 cursor_bounds_ += delta_offset; |
| 1028 } | 1116 } |
| 1029 | 1117 |
| 1030 void RenderText::DrawSelection(Canvas* canvas) { | 1118 void RenderText::DrawSelection(Canvas* canvas) { |
| 1031 const std::vector<Rect> sel = GetSubstringBounds(selection()); | 1119 const std::vector<Rect> sel = GetSubstringBounds(selection()); |
| 1032 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) | 1120 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) |
| 1033 canvas->FillRect(*i, selection_background_focused_color_); | 1121 canvas->FillRect(*i, selection_background_focused_color_); |
| 1034 } | 1122 } |
| 1035 | 1123 |
| 1036 } // namespace gfx | 1124 } // namespace gfx |
| OLD | NEW |