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(); | |
tapted
2016/05/25 04:31:06
Comment about the logic here
| |
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 | |
tapted
2016/05/25 04:31:06
nit: cursor -> Cursor
| |
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) { | |
658 cursor = SelectionModel( | |
659 MergeRangesWithDirection(selection(), cursor.selection()), | |
660 selection_model_.caret_affinity()); | |
661 } else if (selection_direction_changed && | |
662 select_behavior == SELECTION_CARET) { | |
663 cursor = SelectionModel(selection().start(), | |
664 selection_model_.caret_affinity()); | |
665 } | |
666 } | |
667 | |
629 MoveCursorTo(cursor); | 668 MoveCursorTo(cursor); |
630 } | 669 } |
631 | 670 |
632 bool RenderText::MoveCursorTo(const SelectionModel& model) { | 671 bool RenderText::MoveCursorTo(const SelectionModel& model) { |
633 // Enforce valid selection model components. | 672 // Enforce valid selection model components. |
634 size_t text_length = text().length(); | 673 size_t text_length = text().length(); |
635 Range range(std::min(model.selection().start(), | 674 Range range(std::min(model.selection().start(), |
636 static_cast<uint32_t>(text_length)), | 675 static_cast<uint32_t>(text_length)), |
637 std::min(model.caret_pos(), text_length)); | 676 std::min(model.caret_pos(), text_length)); |
638 // The current model only supports caret positions at valid cursor indices. | 677 // 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 | 1598 |
1560 SetDisplayOffset(display_offset_.x() + delta_x); | 1599 SetDisplayOffset(display_offset_.x() + delta_x); |
1561 } | 1600 } |
1562 | 1601 |
1563 void RenderText::DrawSelection(Canvas* canvas) { | 1602 void RenderText::DrawSelection(Canvas* canvas) { |
1564 for (const Rect& s : GetSubstringBounds(selection())) | 1603 for (const Rect& s : GetSubstringBounds(selection())) |
1565 canvas->FillRect(s, selection_background_focused_color_); | 1604 canvas->FillRect(s, selection_background_focused_color_); |
1566 } | 1605 } |
1567 | 1606 |
1568 } // namespace gfx | 1607 } // namespace gfx |
OLD | NEW |