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 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 198 range = break_list->GetRange(current_break); | 198 range = break_list->GetRange(current_break); |
| 199 if (range.end() < break_list->max() && | 199 if (range.end() < break_list->max() && |
| 200 !render_text->IsValidCursorIndex(range.end())) { | 200 !render_text->IsValidCursorIndex(range.end())) { |
| 201 range.set_end( | 201 range.set_end( |
| 202 render_text->IndexOfAdjacentGrapheme(range.end(), CURSOR_FORWARD)); | 202 render_text->IndexOfAdjacentGrapheme(range.end(), CURSOR_FORWARD)); |
| 203 break_list->ApplyValue(current_break->second, range); | 203 break_list->ApplyValue(current_break->second, range); |
| 204 } | 204 } |
| 205 } | 205 } |
| 206 } | 206 } |
| 207 | 207 |
| 208 // Merges |range1| and |range2|, with the directionality of the result same as | |
| 209 // |range2|. |range1| and |range2| must at least share a point. | |
| 210 gfx::Range MergeRangesWithDirection(const Range& range1, const Range& range2) { | |
| 211 DCHECK(!(range1.GetMax() < range2.GetMin() || | |
| 212 range2.GetMax() < range1.GetMin())); | |
| 213 const uint32_t min = std::min(range1.GetMin(), range2.GetMin()); | |
| 214 const uint32_t max = std::max(range1.GetMax(), range2.GetMax()); | |
| 215 bool reversed = | |
| 216 range2.is_empty() ? !range1.is_reversed() : range2.is_reversed(); | |
| 217 return reversed ? Range(max, min) : Range(min, max); | |
| 218 } | |
| 219 | |
| 208 } // namespace | 220 } // namespace |
| 209 | 221 |
| 210 namespace internal { | 222 namespace internal { |
| 211 | 223 |
| 212 // Value of |underline_thickness_| that indicates that underline metrics have | 224 // Value of |underline_thickness_| that indicates that underline metrics have |
| 213 // not been set explicitly. | 225 // not been set explicitly. |
| 214 const SkScalar kUnderlineMetricsNotSet = -1.0f; | 226 const SkScalar kUnderlineMetricsNotSet = -1.0f; |
| 215 | 227 |
| 216 SkiaTextRenderer::SkiaTextRenderer(Canvas* canvas) | 228 SkiaTextRenderer::SkiaTextRenderer(Canvas* canvas) |
| 217 : canvas_(canvas), | 229 : canvas_(canvas), |
| (...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 597 } | 609 } |
| 598 } | 610 } |
| 599 } | 611 } |
| 600 | 612 |
| 601 void RenderText::SetCursorPosition(size_t position) { | 613 void RenderText::SetCursorPosition(size_t position) { |
| 602 MoveCursorTo(position, false); | 614 MoveCursorTo(position, false); |
| 603 } | 615 } |
| 604 | 616 |
| 605 void RenderText::MoveCursor(BreakType break_type, | 617 void RenderText::MoveCursor(BreakType break_type, |
| 606 VisualCursorDirection direction, | 618 VisualCursorDirection direction, |
| 607 bool select) { | 619 bool select, |
| 620 SelectionReversedBehavior select_behavior) { | |
| 621 // |select_behavior| is not relevant for CHARACTER_BREAK. Verify | |
| 622 // |select_behavior| has the default value for this case. | |
| 623 if (break_type == CHARACTER_BREAK) | |
| 624 DCHECK_EQ(SELECTION_DEFAULT, select_behavior); | |
| 625 | |
| 626 if (break_type == WORD_BREAK) | |
| 627 DCHECK_NE(SELECTION_EXTEND, select_behavior); | |
| 628 | |
| 608 SelectionModel cursor(cursor_position(), selection_model_.caret_affinity()); | 629 SelectionModel cursor(cursor_position(), selection_model_.caret_affinity()); |
| 609 // Cancelling a selection moves to the edge of the selection. | 630 // Cancelling a selection moves to the edge of the selection. |
| 610 if (break_type != LINE_BREAK && !selection().is_empty() && !select) { | 631 if (break_type != LINE_BREAK && !selection().is_empty() && !select) { |
| 611 SelectionModel selection_start = GetSelectionModelForSelectionStart(); | 632 SelectionModel selection_start = GetSelectionModelForSelectionStart(); |
| 612 int start_x = GetCursorBounds(selection_start, true).x(); | 633 int start_x = GetCursorBounds(selection_start, true).x(); |
| 613 int cursor_x = GetCursorBounds(cursor, true).x(); | 634 int cursor_x = GetCursorBounds(cursor, true).x(); |
| 614 // Use the selection start if it is left (when |direction| is CURSOR_LEFT) | 635 // Use the selection start if it is left (when |direction| is CURSOR_LEFT) |
| 615 // or right (when |direction| is CURSOR_RIGHT) of the selection end. | 636 // or right (when |direction| is CURSOR_RIGHT) of the selection end. |
| 616 if (direction == CURSOR_RIGHT ? start_x > cursor_x : start_x < cursor_x) | 637 if (direction == CURSOR_RIGHT ? start_x > cursor_x : start_x < cursor_x) |
| 617 cursor = selection_start; | 638 cursor = selection_start; |
| 618 // Use the nearest word boundary in the proper |direction| for word breaks. | 639 // Use the nearest word boundary in the proper |direction| for word breaks. |
| 619 if (break_type == WORD_BREAK) | 640 if (break_type == WORD_BREAK) |
| 620 cursor = GetAdjacentSelectionModel(cursor, break_type, direction); | 641 cursor = GetAdjacentSelectionModel(cursor, break_type, direction); |
| 621 // Use an adjacent selection model if the cursor is not at a valid position. | 642 // Use an adjacent selection model if the cursor is not at a valid position. |
| 622 if (!IsValidCursorIndex(cursor.caret_pos())) | 643 if (!IsValidCursorIndex(cursor.caret_pos())) |
| 623 cursor = GetAdjacentSelectionModel(cursor, CHARACTER_BREAK, direction); | 644 cursor = GetAdjacentSelectionModel(cursor, CHARACTER_BREAK, direction); |
| 624 } else { | 645 } else { |
| 625 cursor = GetAdjacentSelectionModel(cursor, break_type, direction); | 646 cursor = GetAdjacentSelectionModel(cursor, break_type, direction); |
| 626 } | 647 } |
| 627 if (select) | 648 if (select) { |
| 628 cursor.set_selection_start(selection().start()); | 649 cursor.set_selection_start(selection().start()); |
| 650 | |
| 651 // cursor now corresponds to the new selection. Take |select_behavior| into | |
| 652 // account. | |
| 653 bool selection_direction_changed = | |
| 654 !selection().is_empty() && !cursor.selection().is_empty() && | |
| 655 selection().is_reversed() != cursor.selection().is_reversed(); | |
| 656 | |
| 657 if (select_behavior == SELECTION_EXTEND) | |
|
tapted
2016/05/20 06:47:36
nit: needs curlies
karandeepb
2016/05/24 07:47:14
Done.
| |
| 658 cursor = SelectionModel( | |
| 659 MergeRangesWithDirection(selection(), cursor.selection()), | |
| 660 selection_model_.caret_affinity()); | |
| 661 else if (selection_direction_changed && select_behavior == SELECTION_CARET) | |
| 662 cursor = SelectionModel(selection().start(), | |
| 663 selection_model_.caret_affinity()); | |
| 664 } | |
| 665 | |
| 629 MoveCursorTo(cursor); | 666 MoveCursorTo(cursor); |
| 630 } | 667 } |
| 631 | 668 |
| 632 bool RenderText::MoveCursorTo(const SelectionModel& model) { | 669 bool RenderText::MoveCursorTo(const SelectionModel& model) { |
| 633 // Enforce valid selection model components. | 670 // Enforce valid selection model components. |
| 634 size_t text_length = text().length(); | 671 size_t text_length = text().length(); |
| 635 Range range(std::min(model.selection().start(), | 672 Range range(std::min(model.selection().start(), |
| 636 static_cast<uint32_t>(text_length)), | 673 static_cast<uint32_t>(text_length)), |
| 637 std::min(model.caret_pos(), text_length)); | 674 std::min(model.caret_pos(), text_length)); |
| 638 // The current model only supports caret positions at valid cursor indices. | 675 // The current model only supports caret positions at valid cursor indices. |
| (...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1559 | 1596 |
| 1560 SetDisplayOffset(display_offset_.x() + delta_x); | 1597 SetDisplayOffset(display_offset_.x() + delta_x); |
| 1561 } | 1598 } |
| 1562 | 1599 |
| 1563 void RenderText::DrawSelection(Canvas* canvas) { | 1600 void RenderText::DrawSelection(Canvas* canvas) { |
| 1564 for (const Rect& s : GetSubstringBounds(selection())) | 1601 for (const Rect& s : GetSubstringBounds(selection())) |
| 1565 canvas->FillRect(s, selection_background_focused_color_); | 1602 canvas->FillRect(s, selection_background_focused_color_); |
| 1566 } | 1603 } |
| 1567 | 1604 |
| 1568 } // namespace gfx | 1605 } // namespace gfx |
| OLD | NEW |