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 771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 EnsureLayout(); | 782 EnsureLayout(); |
783 | 783 |
784 if (break_type == LINE_BREAK || text().empty()) | 784 if (break_type == LINE_BREAK || text().empty()) |
785 return EdgeSelectionModel(direction); | 785 return EdgeSelectionModel(direction); |
786 if (break_type == CHARACTER_BREAK) | 786 if (break_type == CHARACTER_BREAK) |
787 return AdjacentCharSelectionModel(current, direction); | 787 return AdjacentCharSelectionModel(current, direction); |
788 DCHECK(break_type == WORD_BREAK); | 788 DCHECK(break_type == WORD_BREAK); |
789 return AdjacentWordSelectionModel(current, direction); | 789 return AdjacentWordSelectionModel(current, direction); |
790 } | 790 } |
791 | 791 |
| 792 SelectionModel RenderText::AdjacentWordSelectionModel( |
| 793 const SelectionModel& selection, |
| 794 VisualCursorDirection direction) { |
| 795 if (obscured()) |
| 796 return EdgeSelectionModel(direction); |
| 797 |
| 798 base::i18n::BreakIterator iter(text(), base::i18n::BreakIterator::BREAK_WORD); |
| 799 bool success = iter.Init(); |
| 800 DCHECK(success); |
| 801 if (!success) |
| 802 return selection; |
| 803 |
| 804 size_t pos = 0; |
| 805 // TODO(msw): Cache a list of word breaks or add WordIterator functionality to |
| 806 // start from supplied indices and to iterate backward for better performance. |
| 807 if (direction == CURSOR_RIGHT) { |
| 808 pos = std::min(selection.caret_pos() + 1, text().length()); |
| 809 while (iter.Advance()) { |
| 810 pos = iter.pos(); |
| 811 if (iter.IsWord() && pos > selection.caret_pos()) |
| 812 break; |
| 813 } |
| 814 } else { |
| 815 pos = std::max<int>(selection.caret_pos() - 1, 0); |
| 816 while (iter.Advance()) { |
| 817 if (iter.IsWord()) { |
| 818 size_t begin = iter.pos() - iter.GetString().length(); |
| 819 if (begin == selection.caret_pos()) { |
| 820 // The cursor is at a word beginning; move it to the previous word. |
| 821 break; |
| 822 } else if (iter.pos() >= selection.caret_pos()) { |
| 823 // The cursor is at a word middle or end; move it to its beginning. |
| 824 pos = begin; |
| 825 break; |
| 826 } else { |
| 827 pos = iter.pos() - iter.GetString().length(); |
| 828 } |
| 829 } |
| 830 } |
| 831 } |
| 832 return SelectionModel(pos, CURSOR_FORWARD); |
| 833 } |
| 834 |
792 SelectionModel RenderText::EdgeSelectionModel( | 835 SelectionModel RenderText::EdgeSelectionModel( |
793 VisualCursorDirection direction) { | 836 VisualCursorDirection direction) { |
794 if (direction == GetVisualDirectionOfLogicalEnd()) | 837 if (direction == GetVisualDirectionOfLogicalEnd()) |
795 return SelectionModel(text().length(), CURSOR_FORWARD); | 838 return SelectionModel(text().length(), CURSOR_FORWARD); |
796 return SelectionModel(0, CURSOR_BACKWARD); | 839 return SelectionModel(0, CURSOR_BACKWARD); |
797 } | 840 } |
798 | 841 |
799 void RenderText::SetSelectionModel(const SelectionModel& model) { | 842 void RenderText::SetSelectionModel(const SelectionModel& model) { |
800 DCHECK_LE(model.selection().GetMax(), text().length()); | 843 DCHECK_LE(model.selection().GetMax(), text().length()); |
801 selection_model_ = model; | 844 selection_model_ = model; |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1014 cursor_bounds_ += delta_offset; | 1057 cursor_bounds_ += delta_offset; |
1015 } | 1058 } |
1016 | 1059 |
1017 void RenderText::DrawSelection(Canvas* canvas) { | 1060 void RenderText::DrawSelection(Canvas* canvas) { |
1018 const std::vector<Rect> sel = GetSubstringBounds(selection()); | 1061 const std::vector<Rect> sel = GetSubstringBounds(selection()); |
1019 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) | 1062 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) |
1020 canvas->FillRect(*i, selection_background_focused_color_); | 1063 canvas->FillRect(*i, selection_background_focused_color_); |
1021 } | 1064 } |
1022 | 1065 |
1023 } // namespace gfx | 1066 } // namespace gfx |
OLD | NEW |