Chromium Code Reviews| Index: ui/gfx/render_text.cc |
| diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc |
| index 05435e5a08491481294f1c9243ef645804e09664..710c6097df7752e47a0d62f5e0904431a71929a6 100644 |
| --- a/ui/gfx/render_text.cc |
| +++ b/ui/gfx/render_text.cc |
| @@ -207,6 +207,20 @@ 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() || |
|
tapted
2016/08/11 03:44:07
DCHECK(range1.Intersects(range2))?
karandeepb
2016/08/16 10:24:51
Removed this function. Also Range::Intersects is w
|
| + range2.GetMax() < range1.GetMin())); |
| + const uint32_t min = std::min(range1.GetMin(), range2.GetMin()); |
| + const uint32_t max = std::max(range1.GetMax(), range2.GetMax()); |
| + |
| + // If |range2| is empty, use the direction opposition to the one of |range1|. |
| + bool reversed = |
| + range2.is_empty() ? !range1.is_reversed() : range2.is_reversed(); |
| + return reversed ? Range(max, min) : Range(min, max); |
| +} |
|
tapted
2016/08/11 03:44:07
ui/gfx OWNERS might be interested in a Range::Unio
|
| + |
| } // namespace |
| namespace internal { |
| @@ -613,7 +627,8 @@ void RenderText::SetCursorPosition(size_t position) { |
| void RenderText::MoveCursor(BreakType break_type, |
| VisualCursorDirection direction, |
| - bool select) { |
| + bool select, |
| + SelectionReversedBehavior 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) { |
| @@ -633,8 +648,34 @@ void RenderText::MoveCursor(BreakType break_type, |
| } else { |
| cursor = GetAdjacentSelectionModel(cursor, break_type, direction); |
| } |
| - if (select) |
| + if (select) { |
| + // |select_behavior| is not relevant for CHARACTER_BREAK. Verify |
| + // |select_behavior| has the default value for this case. |
| + DCHECK(break_type != CHARACTER_BREAK || |
| + select_behavior == SELECTION_DEFAULT); |
| + |
| + // SELECTION_EXTEND is only relevant for LINE_BREAK. |
| + DCHECK(select_behavior != SELECTION_EXTEND || break_type == LINE_BREAK); |
|
tapted
2016/08/11 03:44:07
What's the behaviour if these DCHECKs fail? (is it
karandeepb
2016/08/16 10:24:51
Removed the DCHECK. The behavior is now correct an
|
| + |
| cursor.set_selection_start(selection().start()); |
| + |
| + // cursor now corresponds to the new selection. Take |select_behavior| into |
|
tapted
2016/08/11 03:44:07
cursor -> Cursor, or "The cursor"
karandeepb
2016/08/16 10:24:51
Changed to |cursor| since I want to refer to the l
|
| + // 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); |
| } |