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

Unified Diff: ui/gfx/render_text.cc

Issue 2348143003: MacViews: Implement Force Touch/Mac dictionary lookup for Textfields. (Closed)
Patch Set: Address review. Created 4 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: ui/gfx/render_text.cc
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc
index c9404fc0b14bc5411008da5f5af69919786d31b4..eb569f847b29674ab5a1f42d0b77bc7c44b60c35 100644
--- a/ui/gfx/render_text.cc
+++ b/ui/gfx/render_text.cc
@@ -721,39 +721,7 @@ void RenderText::SelectAll(bool reversed) {
}
void RenderText::SelectWord() {
- if (obscured_) {
- SelectAll(false);
- return;
- }
-
- size_t selection_max = selection().GetMax();
-
- base::i18n::BreakIterator iter(text(), base::i18n::BreakIterator::BREAK_WORD);
- bool success = iter.Init();
- DCHECK(success);
- if (!success)
- return;
-
- size_t selection_min = selection().GetMin();
- if (selection_min == text().length() && selection_min != 0)
- --selection_min;
-
- for (; selection_min != 0; --selection_min) {
- if (iter.IsStartOfWord(selection_min) ||
- iter.IsEndOfWord(selection_min))
- break;
- }
-
- if (selection_min == selection_max && selection_max != text().length())
- ++selection_max;
-
- for (; selection_max < text().length(); ++selection_max)
- if (iter.IsEndOfWord(selection_max) || iter.IsStartOfWord(selection_max))
- break;
-
- const bool reversed = selection().is_reversed();
- MoveCursorTo(reversed ? selection_max : selection_min, false);
- MoveCursorTo(reversed ? selection_min : selection_max, true);
+ SelectRange(ExpandRangeToWordBoundary(selection()));
}
void RenderText::SetCompositionRange(const Range& composition_range) {
@@ -1042,6 +1010,45 @@ Vector2d RenderText::GetLineOffset(size_t line_number) {
return offset;
}
+bool RenderText::GetDecoratedWordAtPoint(const Point& point,
+ DecoratedText* decorated_word,
+ Point* baseline_point) {
+ // FindCursorPosition doesn't currently support multiline.
+ if (multiline() || obscured())
+ return false;
+
+ const SelectionModel model_at_point = FindCursorPosition(point);
+ const size_t word_index =
+ GetNearestWordStartBoundary(model_at_point.caret_pos());
+ if (word_index >= text().length())
+ return false;
+
+ const Range word_range = ExpandRangeToWordBoundary(Range(word_index));
+ DCHECK(!word_range.is_reversed());
+ DCHECK(!word_range.is_empty());
+
+ if (!GetDecoratedTextForRange(word_range, decorated_word))
+ return false;
+
+ const std::vector<Rect> word_bounds = GetSubstringBounds(word_range);
karandeepb 2016/09/22 08:17:39 Had to change the approach here and use GetSubstri
+ if (word_bounds.empty())
+ return false;
+
+ const Rect* left_rect = &word_bounds[0];
+ for (const Rect& rect : word_bounds)
+ if (rect.x() < left_rect->x())
+ left_rect = &rect;
+
+ *baseline_point = left_rect->origin() + Vector2d(0, GetDisplayTextBaseline());
+ return true;
+}
+
+base::string16 RenderText::GetTextFromRange(const Range& range) const {
+ if (range.IsValid() && range.GetMin() < text().length())
+ return text().substr(range.GetMin(), range.length());
+ return base::string16();
+}
+
RenderText::RenderText()
: horizontal_alignment_(base::i18n::IsRTL() ? ALIGN_RIGHT : ALIGN_LEFT),
directionality_mode_(DIRECTIONALITY_FROM_TEXT),
@@ -1627,4 +1634,61 @@ void RenderText::DrawSelection(Canvas* canvas) {
canvas->FillRect(s, selection_background_focused_color_);
}
+size_t RenderText::GetNearestWordStartBoundary(size_t index) const {
+ const size_t length = text().length();
+ if (obscured())
+ return length;
+
+ base::i18n::BreakIterator iter(text(), base::i18n::BreakIterator::BREAK_WORD);
+ const bool success = iter.Init();
+ DCHECK(success);
+ if (!success)
+ return length;
+
+ // First search for the word start boundary in the CURSOR_BACKWARD direction,
+ // then in the CURSOR_FORWARD direction.
+ for (int i = std::min<int>(index, (int)length - 1); i >= 0; i--)
+ if (iter.IsStartOfWord(i))
+ return i;
+
+ for (size_t i = index + 1; i < length; i++)
+ if (iter.IsStartOfWord(i))
+ return i;
+
+ return length;
+}
+
+Range RenderText::ExpandRangeToWordBoundary(const Range& range) const {
+ const size_t length = text().length();
+ DCHECK(range.GetMax() <= length);
+ if (obscured())
+ return range.is_reversed() ? Range(length, 0) : Range(0, length);
+
+ base::i18n::BreakIterator iter(text(), base::i18n::BreakIterator::BREAK_WORD);
+ const bool success = iter.Init();
+ DCHECK(success);
+ if (!success)
+ return range;
+
+ size_t range_min = range.GetMin();
+ if (range_min == length && range_min != 0)
+ --range_min;
+
+ for (; range_min != 0; --range_min) {
+ if (iter.IsStartOfWord(range_min) || iter.IsEndOfWord(range_min))
+ break;
+ }
+
+ size_t range_max = range.GetMax();
+ if (range_min == range_max && range_max != length)
+ ++range_max;
+
+ for (; range_max < length; ++range_max)
+ if (iter.IsEndOfWord(range_max) || iter.IsStartOfWord(range_max))
+ break;
+
+ return range.is_reversed() ? Range(range_max, range_min)
+ : Range(range_min, range_max);
+}
+
} // namespace gfx

Powered by Google App Engine
This is Rietveld 408576698