Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(447)

Side by Side Diff: ui/gfx/render_text.cc

Issue 2348143003: MacViews: Implement Force Touch/Mac dictionary lookup for Textfields. (Closed)
Patch Set: Fix compile. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 703 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 } 714 }
715 715
716 void RenderText::SelectAll(bool reversed) { 716 void RenderText::SelectAll(bool reversed) {
717 const size_t length = text().length(); 717 const size_t length = text().length();
718 const Range all = reversed ? Range(length, 0) : Range(0, length); 718 const Range all = reversed ? Range(length, 0) : Range(0, length);
719 const bool success = SelectRange(all); 719 const bool success = SelectRange(all);
720 DCHECK(success); 720 DCHECK(success);
721 } 721 }
722 722
723 void RenderText::SelectWord() { 723 void RenderText::SelectWord() {
724 if (obscured_) { 724 SelectRange(ExpandRangeToWordBoundary(selection()));
725 SelectAll(false);
726 return;
727 }
728
729 size_t selection_max = selection().GetMax();
730
731 base::i18n::BreakIterator iter(text(), base::i18n::BreakIterator::BREAK_WORD);
732 bool success = iter.Init();
733 DCHECK(success);
734 if (!success)
735 return;
736
737 size_t selection_min = selection().GetMin();
738 if (selection_min == text().length() && selection_min != 0)
739 --selection_min;
740
741 for (; selection_min != 0; --selection_min) {
742 if (iter.IsStartOfWord(selection_min) ||
743 iter.IsEndOfWord(selection_min))
744 break;
745 }
746
747 if (selection_min == selection_max && selection_max != text().length())
748 ++selection_max;
749
750 for (; selection_max < text().length(); ++selection_max)
751 if (iter.IsEndOfWord(selection_max) || iter.IsStartOfWord(selection_max))
752 break;
753
754 const bool reversed = selection().is_reversed();
755 MoveCursorTo(reversed ? selection_max : selection_min, false);
756 MoveCursorTo(reversed ? selection_min : selection_max, true);
757 } 725 }
758 726
759 void RenderText::SetCompositionRange(const Range& composition_range) { 727 void RenderText::SetCompositionRange(const Range& composition_range) {
760 CHECK(!composition_range.IsValid() || 728 CHECK(!composition_range.IsValid() ||
761 Range(0, text_.length()).Contains(composition_range)); 729 Range(0, text_.length()).Contains(composition_range));
762 composition_range_.set_end(composition_range.end()); 730 composition_range_.set_end(composition_range.end());
763 composition_range_.set_start(composition_range.start()); 731 composition_range_.set_start(composition_range.start());
764 // TODO(oshima|msw): Altering composition underlines shouldn't 732 // TODO(oshima|msw): Altering composition underlines shouldn't
765 // require layout changes. It's currently necessary because 733 // require layout changes. It's currently necessary because
766 // RenderTextHarfBuzz paints text decorations by run, and 734 // RenderTextHarfBuzz paints text decorations by run, and
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 Vector2d offset = display_rect().OffsetFromOrigin(); 1003 Vector2d offset = display_rect().OffsetFromOrigin();
1036 // TODO(ckocagil): Apply the display offset for multiline scrolling. 1004 // TODO(ckocagil): Apply the display offset for multiline scrolling.
1037 if (!multiline()) 1005 if (!multiline())
1038 offset.Add(GetUpdatedDisplayOffset()); 1006 offset.Add(GetUpdatedDisplayOffset());
1039 else 1007 else
1040 offset.Add(Vector2d(0, lines_[line_number].preceding_heights)); 1008 offset.Add(Vector2d(0, lines_[line_number].preceding_heights));
1041 offset.Add(GetAlignmentOffset(line_number)); 1009 offset.Add(GetAlignmentOffset(line_number));
1042 return offset; 1010 return offset;
1043 } 1011 }
1044 1012
1013 bool RenderText::GetDecoratedWordAtPoint(const Point& point,
1014 DecoratedText* decorated_word,
1015 Point* baseline_point) {
1016 // FindCursorPosition doesn't currently support multiline. See
1017 // http://crbug.com/650120.
1018 if (multiline() || obscured())
1019 return false;
1020
1021 // Note: FindCursorPosition will trigger a layout via EnsureLayout.
1022 const SelectionModel model_at_point = FindCursorPosition(point);
1023 const size_t word_index =
1024 GetNearestWordStartBoundary(model_at_point.caret_pos());
1025 if (word_index >= text().length())
1026 return false;
1027
1028 const Range word_range = ExpandRangeToWordBoundary(Range(word_index));
1029 DCHECK(!word_range.is_reversed());
1030 DCHECK(!word_range.is_empty());
1031
1032 const std::vector<Rect> word_bounds = GetSubstringBounds(word_range);
1033 if (word_bounds.empty())
1034 return false;
1035
1036 if (!GetDecoratedTextForRange(word_range, decorated_word))
1037 return false;
1038
1039 // Retrieve the baseline origin of the left-most glyph.
1040 const Rect* left_rect = &word_bounds[0];
1041 for (const Rect& rect : word_bounds)
1042 if (rect.x() < left_rect->x())
1043 left_rect = &rect;
1044
1045 *baseline_point = left_rect->origin() + Vector2d(0, GetDisplayTextBaseline());
1046 return true;
1047 }
1048
1049 base::string16 RenderText::GetTextFromRange(const Range& range) const {
1050 if (range.IsValid() && range.GetMin() < text().length())
msw 2016/10/04 01:52:37 I see that you simply moved this code, but maybe i
karandeepb 2016/10/04 12:04:24 Checked that substr does the right thing (return t
msw 2016/10/05 00:24:48 Acknowledged; thanks.
1051 return text().substr(range.GetMin(), range.length());
msw 2016/10/04 01:52:37 This may split multi-char glyphs, yielding an inva
karandeepb 2016/10/04 12:04:24 Currently, Textfield::GetTextFromRange does not ch
msw 2016/10/05 00:24:48 Acknowledged.
1052 return base::string16();
1053 }
1054
1045 RenderText::RenderText() 1055 RenderText::RenderText()
1046 : horizontal_alignment_(base::i18n::IsRTL() ? ALIGN_RIGHT : ALIGN_LEFT), 1056 : horizontal_alignment_(base::i18n::IsRTL() ? ALIGN_RIGHT : ALIGN_LEFT),
1047 directionality_mode_(DIRECTIONALITY_FROM_TEXT), 1057 directionality_mode_(DIRECTIONALITY_FROM_TEXT),
1048 text_direction_(base::i18n::UNKNOWN_DIRECTION), 1058 text_direction_(base::i18n::UNKNOWN_DIRECTION),
1049 cursor_enabled_(true), 1059 cursor_enabled_(true),
1050 cursor_visible_(false), 1060 cursor_visible_(false),
1051 cursor_color_(kDefaultColor), 1061 cursor_color_(kDefaultColor),
1052 selection_color_(kDefaultColor), 1062 selection_color_(kDefaultColor),
1053 selection_background_focused_color_(kDefaultSelectionBackgroundColor), 1063 selection_background_focused_color_(kDefaultSelectionBackgroundColor),
1054 focused_(false), 1064 focused_(false),
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after
1620 } 1630 }
1621 1631
1622 SetDisplayOffset(display_offset_.x() + delta_x); 1632 SetDisplayOffset(display_offset_.x() + delta_x);
1623 } 1633 }
1624 1634
1625 void RenderText::DrawSelection(Canvas* canvas) { 1635 void RenderText::DrawSelection(Canvas* canvas) {
1626 for (const Rect& s : GetSubstringBounds(selection())) 1636 for (const Rect& s : GetSubstringBounds(selection()))
1627 canvas->FillRect(s, selection_background_focused_color_); 1637 canvas->FillRect(s, selection_background_focused_color_);
1628 } 1638 }
1629 1639
1640 size_t RenderText::GetNearestWordStartBoundary(size_t index) const {
1641 const size_t length = text().length();
1642 if (obscured())
msw 2016/10/04 01:52:37 nit: return |length| if |length == 0|
karandeepb 2016/10/04 12:04:24 Done.
1643 return length;
1644
1645 base::i18n::BreakIterator iter(text(), base::i18n::BreakIterator::BREAK_WORD);
1646 const bool success = iter.Init();
1647 DCHECK(success);
1648 if (!success)
1649 return length;
1650
1651 // First search for the word start boundary in the CURSOR_BACKWARD direction,
1652 // then in the CURSOR_FORWARD direction.
1653 for (int i = std::min<int>(index, (int)length - 1); i >= 0; i--)
msw 2016/10/04 01:52:37 nit: static_cast<int>(length) if necessary
karandeepb 2016/10/04 12:04:24 Removed the cast, which is not necessary now since
1654 if (iter.IsStartOfWord(i))
1655 return i;
1656
1657 for (size_t i = index + 1; i < length; i++)
1658 if (iter.IsStartOfWord(i))
1659 return i;
1660
1661 return length;
1662 }
1663
1664 Range RenderText::ExpandRangeToWordBoundary(const Range& range) const {
1665 const size_t length = text().length();
1666 DCHECK(range.GetMax() <= length);
msw 2016/10/04 01:52:37 optional nit: DCHECK_LE
karandeepb 2016/10/04 12:04:24 Done.
1667 if (obscured())
1668 return range.is_reversed() ? Range(length, 0) : Range(0, length);
1669
1670 base::i18n::BreakIterator iter(text(), base::i18n::BreakIterator::BREAK_WORD);
1671 const bool success = iter.Init();
1672 DCHECK(success);
1673 if (!success)
1674 return range;
1675
1676 size_t range_min = range.GetMin();
1677 if (range_min == length && range_min != 0)
1678 --range_min;
1679
1680 for (; range_min != 0; --range_min) {
msw 2016/10/04 01:52:37 nit: remove curlies here (or add them for the corr
karandeepb 2016/10/04 12:04:24 Done.
1681 if (iter.IsStartOfWord(range_min) || iter.IsEndOfWord(range_min))
1682 break;
1683 }
1684
1685 size_t range_max = range.GetMax();
1686 if (range_min == range_max && range_max != length)
1687 ++range_max;
1688
1689 for (; range_max < length; ++range_max)
1690 if (iter.IsEndOfWord(range_max) || iter.IsStartOfWord(range_max))
1691 break;
1692
1693 return range.is_reversed() ? Range(range_max, range_min)
1694 : Range(range_min, range_max);
1695 }
1696
1630 } // namespace gfx 1697 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698