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 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1021 if (!multiline()) { | 1021 if (!multiline()) { |
| 1022 offset.Add(GetUpdatedDisplayOffset()); | 1022 offset.Add(GetUpdatedDisplayOffset()); |
| 1023 } else { | 1023 } else { |
| 1024 DCHECK_LT(line_number, lines().size()); | 1024 DCHECK_LT(line_number, lines().size()); |
| 1025 offset.Add(Vector2d(0, lines_[line_number].preceding_heights)); | 1025 offset.Add(Vector2d(0, lines_[line_number].preceding_heights)); |
| 1026 } | 1026 } |
| 1027 offset.Add(GetAlignmentOffset(line_number)); | 1027 offset.Add(GetAlignmentOffset(line_number)); |
| 1028 return offset; | 1028 return offset; |
| 1029 } | 1029 } |
| 1030 | 1030 |
| 1031 bool RenderText::GetDecoratedWordAtPoint(const Point& point, | 1031 bool RenderText::GetDecoratedWordAtPoint(const Point& point, |
|
tapted
2017/01/17 20:48:59
Note we also need a solution for doing a lookup vi
karandeepb
2017/01/19 04:38:36
Yeah shouldn't be difficult to incorporate these c
| |
| 1032 DecoratedText* decorated_word, | 1032 DecoratedText* decorated_word, |
| 1033 Point* baseline_point) { | 1033 Point* baseline_point) { |
| 1034 // FindCursorPosition doesn't currently support multiline. See | 1034 if (obscured()) |
| 1035 // http://crbug.com/650120. | |
| 1036 if (multiline() || obscured()) | |
| 1037 return false; | 1035 return false; |
| 1038 | 1036 |
| 1039 // Note: FindCursorPosition will trigger a layout via EnsureLayout. | 1037 EnsureLayout(); |
| 1040 const SelectionModel model_at_point = FindCursorPosition(point); | 1038 const SelectionModel model_at_point = FindCursorPosition(point); |
| 1041 const size_t word_index = | 1039 const size_t word_index = |
| 1042 GetNearestWordStartBoundary(model_at_point.caret_pos()); | 1040 GetNearestWordStartBoundary(model_at_point.caret_pos()); |
| 1043 if (word_index >= text().length()) | 1041 if (word_index >= text().length()) |
| 1044 return false; | 1042 return false; |
| 1045 | 1043 |
| 1046 const Range word_range = ExpandRangeToWordBoundary(Range(word_index)); | 1044 const Range word_range = ExpandRangeToWordBoundary(Range(word_index)); |
| 1047 DCHECK(!word_range.is_reversed()); | 1045 DCHECK(!word_range.is_reversed()); |
| 1048 DCHECK(!word_range.is_empty()); | 1046 DCHECK(!word_range.is_empty()); |
| 1049 | 1047 |
| 1050 const std::vector<Rect> word_bounds = GetSubstringBounds(word_range); | 1048 const std::vector<Rect> word_bounds = GetSubstringBounds(word_range); |
| 1051 if (word_bounds.empty() || | 1049 if (word_bounds.empty() || |
| 1052 !GetDecoratedTextForRange(word_range, decorated_word)) { | 1050 !GetDecoratedTextForRange(word_range, decorated_word)) { |
| 1053 return false; | 1051 return false; |
| 1054 } | 1052 } |
| 1055 | 1053 |
| 1056 // Retrieve the baseline origin of the left-most glyph. | 1054 // Retrieve the baseline origin of the left-most glyph. |
| 1057 const auto left_rect = std::min_element( | 1055 const auto left_rect = std::min_element( |
| 1058 word_bounds.begin(), word_bounds.end(), | 1056 word_bounds.begin(), word_bounds.end(), |
| 1059 [](const Rect& lhs, const Rect& rhs) { return lhs.x() < rhs.x(); }); | 1057 [](const Rect& lhs, const Rect& rhs) { return lhs.x() < rhs.x(); }); |
| 1060 *baseline_point = left_rect->origin() + Vector2d(0, GetDisplayTextBaseline()); | 1058 const int line_index = GetLineContainingYCoord(left_rect->y()); |
| 1059 if (line_index == -1 || line_index == static_cast<int>(lines().size())) | |
| 1060 return false; | |
| 1061 *baseline_point = | |
| 1062 left_rect->origin() + Vector2d(0, lines()[line_index].baseline); | |
| 1061 return true; | 1063 return true; |
| 1062 } | 1064 } |
| 1063 | 1065 |
| 1064 base::string16 RenderText::GetTextFromRange(const Range& range) const { | 1066 base::string16 RenderText::GetTextFromRange(const Range& range) const { |
| 1065 if (range.IsValid() && range.GetMin() < text().length()) | 1067 if (range.IsValid() && range.GetMin() < text().length()) |
| 1066 return text().substr(range.GetMin(), range.length()); | 1068 return text().substr(range.GetMin(), range.length()); |
| 1067 return base::string16(); | 1069 return base::string16(); |
| 1068 } | 1070 } |
| 1069 | 1071 |
| 1070 RenderText::RenderText() | 1072 RenderText::RenderText() |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1380 | 1382 |
| 1381 void RenderText::UpdateStyleLengths() { | 1383 void RenderText::UpdateStyleLengths() { |
| 1382 const size_t text_length = text_.length(); | 1384 const size_t text_length = text_.length(); |
| 1383 colors_.SetMax(text_length); | 1385 colors_.SetMax(text_length); |
| 1384 baselines_.SetMax(text_length); | 1386 baselines_.SetMax(text_length); |
| 1385 weights_.SetMax(text_length); | 1387 weights_.SetMax(text_length); |
| 1386 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) | 1388 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) |
| 1387 styles_[style].SetMax(text_length); | 1389 styles_[style].SetMax(text_length); |
| 1388 } | 1390 } |
| 1389 | 1391 |
| 1392 int RenderText::GetLineContainingYCoord(float text_y) { | |
| 1393 if (text_y < 0) | |
| 1394 return -1; | |
| 1395 | |
| 1396 for (size_t i = 0; i < lines().size(); i++) { | |
| 1397 const internal::Line& line = lines()[i]; | |
| 1398 | |
| 1399 if (text_y <= line.size.height()) | |
| 1400 return i; | |
| 1401 text_y -= line.size.height(); | |
| 1402 } | |
| 1403 | |
| 1404 return lines().size(); | |
| 1405 } | |
| 1406 | |
| 1407 int RenderText::GetLineSegmentContainingXCoord(const internal::Line& line, | |
|
tapted
2017/01/17 20:48:59
can this just go in an anonymous namespace? I can'
karandeepb
2017/01/19 04:38:36
It's similar in concept to GetLineContainingYCoord
tapted
2017/01/20 06:24:50
I see it as more of a helper function. I think hav
karandeepb
2017/01/20 07:29:10
Done.
| |
| 1408 float line_x, | |
| 1409 float* offset_relative_segment) { | |
| 1410 DCHECK(offset_relative_segment); | |
| 1411 | |
| 1412 *offset_relative_segment = 0; | |
| 1413 if (line_x < 0) | |
| 1414 return -1; | |
| 1415 for (size_t i = 0; i < line.segments.size(); i++) { | |
| 1416 const internal::LineSegment& segment = line.segments[i]; | |
| 1417 | |
| 1418 // segment.x_range is not used because it is in text space. | |
| 1419 if (line_x < segment.width()) { | |
| 1420 *offset_relative_segment = line_x; | |
| 1421 return i; | |
| 1422 } | |
| 1423 line_x -= segment.width(); | |
| 1424 } | |
| 1425 return line.segments.size(); | |
| 1426 } | |
| 1427 | |
| 1390 // static | 1428 // static |
| 1391 bool RenderText::RangeContainsCaret(const Range& range, | 1429 bool RenderText::RangeContainsCaret(const Range& range, |
| 1392 size_t caret_pos, | 1430 size_t caret_pos, |
| 1393 LogicalCursorDirection caret_affinity) { | 1431 LogicalCursorDirection caret_affinity) { |
| 1394 // NB: exploits unsigned wraparound (WG14/N1124 section 6.2.5 paragraph 9). | 1432 // NB: exploits unsigned wraparound (WG14/N1124 section 6.2.5 paragraph 9). |
| 1395 size_t adjacent = (caret_affinity == CURSOR_BACKWARD) ? | 1433 size_t adjacent = (caret_affinity == CURSOR_BACKWARD) ? |
| 1396 caret_pos - 1 : caret_pos + 1; | 1434 caret_pos - 1 : caret_pos + 1; |
| 1397 return range.Contains(Range(caret_pos, adjacent)); | 1435 return range.Contains(Range(caret_pos, adjacent)); |
| 1398 } | 1436 } |
| 1399 | 1437 |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1692 | 1730 |
| 1693 for (; range_max < length; ++range_max) | 1731 for (; range_max < length; ++range_max) |
| 1694 if (iter.IsEndOfWord(range_max) || iter.IsStartOfWord(range_max)) | 1732 if (iter.IsEndOfWord(range_max) || iter.IsStartOfWord(range_max)) |
| 1695 break; | 1733 break; |
| 1696 | 1734 |
| 1697 return range.is_reversed() ? Range(range_max, range_min) | 1735 return range.is_reversed() ? Range(range_max, range_min) |
| 1698 : Range(range_min, range_max); | 1736 : Range(range_min, range_max); |
| 1699 } | 1737 } |
| 1700 | 1738 |
| 1701 } // namespace gfx | 1739 } // namespace gfx |
| OLD | NEW |