Chromium Code Reviews| Index: ui/gfx/render_text.cc |
| diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc |
| index f2f691ee9e283f214f5606dc22edb72a7ecd425d..3b94ef4cc3564ac4e667320e80f932b0c2eb9d37 100644 |
| --- a/ui/gfx/render_text.cc |
| +++ b/ui/gfx/render_text.cc |
| @@ -205,6 +205,18 @@ void RestoreBreakList(RenderText* render_text, BreakList<T>* break_list) { |
| } |
| } |
| +// Merges |range1| and |range2|, with the directionality of the result same as |
| +// |range2|. |range1| and |range2| must at least share a point. |
| +gfx::Range MergeRangesWithDirection(const Range& range1, const Range& range2) { |
| + DCHECK(!(range1.GetMax() < range2.GetMin() || |
| + range2.GetMax() < range1.GetMin())); |
| + const uint32_t min = std::min(range1.GetMin(), range2.GetMin()); |
| + const uint32_t max = std::max(range1.GetMax(), range2.GetMax()); |
| + bool reversed = |
| + range2.is_empty() ? !range1.is_reversed() : range2.is_reversed(); |
|
tapted
2016/05/25 04:31:06
Comment about the logic here
|
| + return reversed ? Range(max, min) : Range(min, max); |
| +} |
| + |
| } // namespace |
| namespace internal { |
| @@ -604,7 +616,16 @@ void RenderText::SetCursorPosition(size_t position) { |
| void RenderText::MoveCursor(BreakType break_type, |
| VisualCursorDirection direction, |
| - bool select) { |
| + bool select, |
| + SelectionReversedBehavior select_behavior) { |
| + // |select_behavior| is not relevant for CHARACTER_BREAK. Verify |
| + // |select_behavior| has the default value for this case. |
| + if (break_type == CHARACTER_BREAK) |
| + DCHECK_EQ(SELECTION_DEFAULT, select_behavior); |
| + |
| + if (break_type == WORD_BREAK) |
| + DCHECK_NE(SELECTION_EXTEND, select_behavior); |
| + |
| SelectionModel cursor(cursor_position(), selection_model_.caret_affinity()); |
| // Cancelling a selection moves to the edge of the selection. |
| if (break_type != LINE_BREAK && !selection().is_empty() && !select) { |
| @@ -624,8 +645,26 @@ void RenderText::MoveCursor(BreakType break_type, |
| } else { |
| cursor = GetAdjacentSelectionModel(cursor, break_type, direction); |
| } |
| - if (select) |
| + if (select) { |
| cursor.set_selection_start(selection().start()); |
| + |
| + // cursor now corresponds to the new selection. Take |select_behavior| into |
|
tapted
2016/05/25 04:31:06
nit: cursor -> Cursor
|
| + // account. |
| + bool selection_direction_changed = |
| + !selection().is_empty() && !cursor.selection().is_empty() && |
| + selection().is_reversed() != cursor.selection().is_reversed(); |
| + |
| + if (select_behavior == SELECTION_EXTEND) { |
| + cursor = SelectionModel( |
| + MergeRangesWithDirection(selection(), cursor.selection()), |
| + selection_model_.caret_affinity()); |
| + } else if (selection_direction_changed && |
| + select_behavior == SELECTION_CARET) { |
| + cursor = SelectionModel(selection().start(), |
| + selection_model_.caret_affinity()); |
| + } |
| + } |
| + |
| MoveCursorTo(cursor); |
| } |