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 <limits.h> | 7 #include <limits.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <climits> | 10 #include <climits> |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 200 range = break_list->GetRange(current_break); | 200 range = break_list->GetRange(current_break); |
| 201 if (range.end() < break_list->max() && | 201 if (range.end() < break_list->max() && |
| 202 !render_text->IsValidCursorIndex(range.end())) { | 202 !render_text->IsValidCursorIndex(range.end())) { |
| 203 range.set_end( | 203 range.set_end( |
| 204 render_text->IndexOfAdjacentGrapheme(range.end(), CURSOR_FORWARD)); | 204 render_text->IndexOfAdjacentGrapheme(range.end(), CURSOR_FORWARD)); |
| 205 break_list->ApplyValue(current_break->second, range); | 205 break_list->ApplyValue(current_break->second, range); |
| 206 } | 206 } |
| 207 } | 207 } |
| 208 } | 208 } |
| 209 | 209 |
| 210 // Merges |range1| and |range2|, with the directionality of the result same as | |
| 211 // |range2|. |range1| and |range2| must at least share a point. | |
| 212 gfx::Range MergeRangesWithDirection(const Range& range1, const Range& range2) { | |
| 213 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
| |
| 214 range2.GetMax() < range1.GetMin())); | |
| 215 const uint32_t min = std::min(range1.GetMin(), range2.GetMin()); | |
| 216 const uint32_t max = std::max(range1.GetMax(), range2.GetMax()); | |
| 217 | |
| 218 // If |range2| is empty, use the direction opposition to the one of |range1|. | |
| 219 bool reversed = | |
| 220 range2.is_empty() ? !range1.is_reversed() : range2.is_reversed(); | |
| 221 return reversed ? Range(max, min) : Range(min, max); | |
| 222 } | |
|
tapted
2016/08/11 03:44:07
ui/gfx OWNERS might be interested in a Range::Unio
| |
| 223 | |
| 210 } // namespace | 224 } // namespace |
| 211 | 225 |
| 212 namespace internal { | 226 namespace internal { |
| 213 | 227 |
| 214 // Value of |underline_thickness_| that indicates that underline metrics have | 228 // Value of |underline_thickness_| that indicates that underline metrics have |
| 215 // not been set explicitly. | 229 // not been set explicitly. |
| 216 const SkScalar kUnderlineMetricsNotSet = -1.0f; | 230 const SkScalar kUnderlineMetricsNotSet = -1.0f; |
| 217 | 231 |
| 218 SkiaTextRenderer::SkiaTextRenderer(Canvas* canvas) | 232 SkiaTextRenderer::SkiaTextRenderer(Canvas* canvas) |
| 219 : canvas_(canvas), | 233 : canvas_(canvas), |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 606 } | 620 } |
| 607 } | 621 } |
| 608 } | 622 } |
| 609 | 623 |
| 610 void RenderText::SetCursorPosition(size_t position) { | 624 void RenderText::SetCursorPosition(size_t position) { |
| 611 MoveCursorTo(position, false); | 625 MoveCursorTo(position, false); |
| 612 } | 626 } |
| 613 | 627 |
| 614 void RenderText::MoveCursor(BreakType break_type, | 628 void RenderText::MoveCursor(BreakType break_type, |
| 615 VisualCursorDirection direction, | 629 VisualCursorDirection direction, |
| 616 bool select) { | 630 bool select, |
| 631 SelectionReversedBehavior select_behavior) { | |
| 617 SelectionModel cursor(cursor_position(), selection_model_.caret_affinity()); | 632 SelectionModel cursor(cursor_position(), selection_model_.caret_affinity()); |
| 618 // Cancelling a selection moves to the edge of the selection. | 633 // Cancelling a selection moves to the edge of the selection. |
| 619 if (break_type != LINE_BREAK && !selection().is_empty() && !select) { | 634 if (break_type != LINE_BREAK && !selection().is_empty() && !select) { |
| 620 SelectionModel selection_start = GetSelectionModelForSelectionStart(); | 635 SelectionModel selection_start = GetSelectionModelForSelectionStart(); |
| 621 int start_x = GetCursorBounds(selection_start, true).x(); | 636 int start_x = GetCursorBounds(selection_start, true).x(); |
| 622 int cursor_x = GetCursorBounds(cursor, true).x(); | 637 int cursor_x = GetCursorBounds(cursor, true).x(); |
| 623 // Use the selection start if it is left (when |direction| is CURSOR_LEFT) | 638 // Use the selection start if it is left (when |direction| is CURSOR_LEFT) |
| 624 // or right (when |direction| is CURSOR_RIGHT) of the selection end. | 639 // or right (when |direction| is CURSOR_RIGHT) of the selection end. |
| 625 if (direction == CURSOR_RIGHT ? start_x > cursor_x : start_x < cursor_x) | 640 if (direction == CURSOR_RIGHT ? start_x > cursor_x : start_x < cursor_x) |
| 626 cursor = selection_start; | 641 cursor = selection_start; |
| 627 // Use the nearest word boundary in the proper |direction| for word breaks. | 642 // Use the nearest word boundary in the proper |direction| for word breaks. |
| 628 if (break_type == WORD_BREAK) | 643 if (break_type == WORD_BREAK) |
| 629 cursor = GetAdjacentSelectionModel(cursor, break_type, direction); | 644 cursor = GetAdjacentSelectionModel(cursor, break_type, direction); |
| 630 // Use an adjacent selection model if the cursor is not at a valid position. | 645 // Use an adjacent selection model if the cursor is not at a valid position. |
| 631 if (!IsValidCursorIndex(cursor.caret_pos())) | 646 if (!IsValidCursorIndex(cursor.caret_pos())) |
| 632 cursor = GetAdjacentSelectionModel(cursor, CHARACTER_BREAK, direction); | 647 cursor = GetAdjacentSelectionModel(cursor, CHARACTER_BREAK, direction); |
| 633 } else { | 648 } else { |
| 634 cursor = GetAdjacentSelectionModel(cursor, break_type, direction); | 649 cursor = GetAdjacentSelectionModel(cursor, break_type, direction); |
| 635 } | 650 } |
| 636 if (select) | 651 if (select) { |
| 652 // |select_behavior| is not relevant for CHARACTER_BREAK. Verify | |
| 653 // |select_behavior| has the default value for this case. | |
| 654 DCHECK(break_type != CHARACTER_BREAK || | |
| 655 select_behavior == SELECTION_DEFAULT); | |
| 656 | |
| 657 // SELECTION_EXTEND is only relevant for LINE_BREAK. | |
| 658 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
| |
| 659 | |
| 637 cursor.set_selection_start(selection().start()); | 660 cursor.set_selection_start(selection().start()); |
| 661 | |
| 662 // 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
| |
| 663 // account. | |
| 664 bool selection_direction_changed = | |
| 665 !selection().is_empty() && !cursor.selection().is_empty() && | |
| 666 selection().is_reversed() != cursor.selection().is_reversed(); | |
| 667 | |
| 668 if (select_behavior == SELECTION_EXTEND) { | |
| 669 cursor = SelectionModel( | |
| 670 MergeRangesWithDirection(selection(), cursor.selection()), | |
| 671 selection_model_.caret_affinity()); | |
| 672 } else if (selection_direction_changed && | |
| 673 select_behavior == SELECTION_CARET) { | |
| 674 cursor = SelectionModel(selection().start(), | |
| 675 selection_model_.caret_affinity()); | |
| 676 } | |
| 677 } | |
| 678 | |
| 638 MoveCursorTo(cursor); | 679 MoveCursorTo(cursor); |
| 639 } | 680 } |
| 640 | 681 |
| 641 bool RenderText::MoveCursorTo(const SelectionModel& model) { | 682 bool RenderText::MoveCursorTo(const SelectionModel& model) { |
| 642 // Enforce valid selection model components. | 683 // Enforce valid selection model components. |
| 643 size_t text_length = text().length(); | 684 size_t text_length = text().length(); |
| 644 Range range(std::min(model.selection().start(), | 685 Range range(std::min(model.selection().start(), |
| 645 static_cast<uint32_t>(text_length)), | 686 static_cast<uint32_t>(text_length)), |
| 646 std::min(model.caret_pos(), text_length)); | 687 std::min(model.caret_pos(), text_length)); |
| 647 // The current model only supports caret positions at valid cursor indices. | 688 // The current model only supports caret positions at valid cursor indices. |
| (...skipping 939 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1587 | 1628 |
| 1588 SetDisplayOffset(display_offset_.x() + delta_x); | 1629 SetDisplayOffset(display_offset_.x() + delta_x); |
| 1589 } | 1630 } |
| 1590 | 1631 |
| 1591 void RenderText::DrawSelection(Canvas* canvas) { | 1632 void RenderText::DrawSelection(Canvas* canvas) { |
| 1592 for (const Rect& s : GetSubstringBounds(selection())) | 1633 for (const Rect& s : GetSubstringBounds(selection())) |
| 1593 canvas->FillRect(s, selection_background_focused_color_); | 1634 canvas->FillRect(s, selection_background_focused_color_); |
| 1594 } | 1635 } |
| 1595 | 1636 |
| 1596 } // namespace gfx | 1637 } // namespace gfx |
| OLD | NEW |