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); |
} |