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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 const SkScalar kUnderlineOffset = (SK_Scalar1 / 9); | 59 const SkScalar kUnderlineOffset = (SK_Scalar1 / 9); |
60 // Fraction of the text size to use for a strike through or under-line. | 60 // Fraction of the text size to use for a strike through or under-line. |
61 const SkScalar kLineThickness = (SK_Scalar1 / 18); | 61 const SkScalar kLineThickness = (SK_Scalar1 / 18); |
62 // Fraction of the text size to use for a top margin of a diagonal strike. | 62 // Fraction of the text size to use for a top margin of a diagonal strike. |
63 const SkScalar kDiagonalStrikeMarginOffset = (SK_Scalar1 / 4); | 63 const SkScalar kDiagonalStrikeMarginOffset = (SK_Scalar1 / 4); |
64 | 64 |
65 // Invalid value of baseline. Assigning this value to |baseline_| causes | 65 // Invalid value of baseline. Assigning this value to |baseline_| causes |
66 // re-calculation of baseline. | 66 // re-calculation of baseline. |
67 const int kInvalidBaseline = INT_MAX; | 67 const int kInvalidBaseline = INT_MAX; |
68 | 68 |
69 // Returns the baseline, with which the text best appears vertically centered. | |
70 int DetermineBaselineCenteringText(const Rect& display_rect, | |
71 const FontList& font_list) { | |
72 const int display_height = display_rect.height(); | |
73 const int font_height = font_list.GetHeight(); | |
74 // Lower and upper bound of baseline shift as we try to show as much area of | |
75 // text as possible. In particular case of |display_height| == |font_height|, | |
76 // we do not want to shift the baseline. | |
77 const int min_shift = std::min(0, display_height - font_height); | |
78 const int max_shift = std::abs(display_height - font_height); | |
79 const int baseline = font_list.GetBaseline(); | |
80 const int cap_height = font_list.GetCapHeight(); | |
81 const int internal_leading = baseline - cap_height; | |
82 // Some platforms don't support getting the cap height, and simply return | |
83 // the entire font ascent from GetCapHeight(). Centering the ascent makes | |
84 // the font look too low, so if GetCapHeight() returns the ascent, center | |
85 // the entire font height instead. | |
86 const int space = | |
87 display_height - ((internal_leading != 0) ? cap_height : font_height); | |
88 const int baseline_shift = space / 2 - internal_leading; | |
89 return baseline + std::max(min_shift, std::min(max_shift, baseline_shift)); | |
90 } | |
91 | |
92 int round(float value) { | 69 int round(float value) { |
93 return static_cast<int>(floor(value + 0.5f)); | 70 return static_cast<int>(floor(value + 0.5f)); |
94 } | 71 } |
95 | 72 |
96 // Given |font| and |display_width|, returns the width of the fade gradient. | 73 // Given |font| and |display_width|, returns the width of the fade gradient. |
97 int CalculateFadeGradientWidth(const FontList& font_list, int display_width) { | 74 int CalculateFadeGradientWidth(const FontList& font_list, int display_width) { |
98 // Fade in/out about 3 characters of the beginning/end of the string. | 75 // Fade in/out about 3 characters of the beginning/end of the string. |
99 // Use a 1/3 of the display width if the display width is very short. | 76 // Use a 1/3 of the display width if the display width is very short. |
100 const int narrow_width = font_list.GetExpectedTextWidth(3); | 77 const int narrow_width = font_list.GetExpectedTextWidth(3); |
101 const int gradient_width = std::min(narrow_width, round(display_width / 3.f)); | 78 const int gradient_width = std::min(narrow_width, round(display_width / 3.f)); |
(...skipping 729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
831 const float string_size = GetStringSizeF().width(); | 808 const float string_size = GetStringSizeF().width(); |
832 // The cursor is drawn one pixel beyond the int-enclosed text bounds. | 809 // The cursor is drawn one pixel beyond the int-enclosed text bounds. |
833 return cursor_enabled_ ? std::ceil(string_size) + 1 : string_size; | 810 return cursor_enabled_ ? std::ceil(string_size) + 1 : string_size; |
834 } | 811 } |
835 | 812 |
836 int RenderText::GetContentWidth() { | 813 int RenderText::GetContentWidth() { |
837 return ToCeiledInt(GetContentWidthF()); | 814 return ToCeiledInt(GetContentWidthF()); |
838 } | 815 } |
839 | 816 |
840 int RenderText::GetBaseline() { | 817 int RenderText::GetBaseline() { |
841 if (baseline_ == kInvalidBaseline) | 818 if (baseline_ == kInvalidBaseline) { |
842 baseline_ = DetermineBaselineCenteringText(display_rect(), font_list()); | 819 baseline_ = |
| 820 DetermineBaselineCenteringText(display_rect().height(), font_list()); |
| 821 } |
843 DCHECK_NE(kInvalidBaseline, baseline_); | 822 DCHECK_NE(kInvalidBaseline, baseline_); |
844 return baseline_; | 823 return baseline_; |
845 } | 824 } |
846 | 825 |
847 void RenderText::Draw(Canvas* canvas) { | 826 void RenderText::Draw(Canvas* canvas) { |
848 EnsureLayout(); | 827 EnsureLayout(); |
849 | 828 |
850 if (clip_to_display_rect()) { | 829 if (clip_to_display_rect()) { |
851 Rect clip_rect(display_rect()); | 830 Rect clip_rect(display_rect()); |
852 clip_rect.Inset(ShadowValue::GetMargin(shadows_)); | 831 clip_rect.Inset(ShadowValue::GetMargin(shadows_)); |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1393 // static | 1372 // static |
1394 bool RenderText::RangeContainsCaret(const Range& range, | 1373 bool RenderText::RangeContainsCaret(const Range& range, |
1395 size_t caret_pos, | 1374 size_t caret_pos, |
1396 LogicalCursorDirection caret_affinity) { | 1375 LogicalCursorDirection caret_affinity) { |
1397 // NB: exploits unsigned wraparound (WG14/N1124 section 6.2.5 paragraph 9). | 1376 // NB: exploits unsigned wraparound (WG14/N1124 section 6.2.5 paragraph 9). |
1398 size_t adjacent = (caret_affinity == CURSOR_BACKWARD) ? | 1377 size_t adjacent = (caret_affinity == CURSOR_BACKWARD) ? |
1399 caret_pos - 1 : caret_pos + 1; | 1378 caret_pos - 1 : caret_pos + 1; |
1400 return range.Contains(Range(caret_pos, adjacent)); | 1379 return range.Contains(Range(caret_pos, adjacent)); |
1401 } | 1380 } |
1402 | 1381 |
| 1382 // static |
| 1383 int RenderText::DetermineBaselineCenteringText(const int display_height, |
| 1384 const FontList& font_list) { |
| 1385 const int font_height = font_list.GetHeight(); |
| 1386 // Lower and upper bound of baseline shift as we try to show as much area of |
| 1387 // text as possible. In particular case of |display_height| == |font_height|, |
| 1388 // we do not want to shift the baseline. |
| 1389 const int min_shift = std::min(0, display_height - font_height); |
| 1390 const int max_shift = std::abs(display_height - font_height); |
| 1391 const int baseline = font_list.GetBaseline(); |
| 1392 const int cap_height = font_list.GetCapHeight(); |
| 1393 const int internal_leading = baseline - cap_height; |
| 1394 // Some platforms don't support getting the cap height, and simply return |
| 1395 // the entire font ascent from GetCapHeight(). Centering the ascent makes |
| 1396 // the font look too low, so if GetCapHeight() returns the ascent, center |
| 1397 // the entire font height instead. |
| 1398 const int space = |
| 1399 display_height - ((internal_leading != 0) ? cap_height : font_height); |
| 1400 const int baseline_shift = space / 2 - internal_leading; |
| 1401 return baseline + std::max(min_shift, std::min(max_shift, baseline_shift)); |
| 1402 } |
| 1403 |
1403 void RenderText::MoveCursorTo(size_t position, bool select) { | 1404 void RenderText::MoveCursorTo(size_t position, bool select) { |
1404 size_t cursor = std::min(position, text().length()); | 1405 size_t cursor = std::min(position, text().length()); |
1405 if (IsValidCursorIndex(cursor)) | 1406 if (IsValidCursorIndex(cursor)) |
1406 SetSelectionModel(SelectionModel( | 1407 SetSelectionModel(SelectionModel( |
1407 Range(select ? selection().start() : cursor, cursor), | 1408 Range(select ? selection().start() : cursor, cursor), |
1408 (cursor == 0) ? CURSOR_FORWARD : CURSOR_BACKWARD)); | 1409 (cursor == 0) ? CURSOR_FORWARD : CURSOR_BACKWARD)); |
1409 } | 1410 } |
1410 | 1411 |
1411 void RenderText::OnTextAttributeChanged() { | 1412 void RenderText::OnTextAttributeChanged() { |
1412 layout_text_.clear(); | 1413 layout_text_.clear(); |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1695 | 1696 |
1696 for (; range_max < length; ++range_max) | 1697 for (; range_max < length; ++range_max) |
1697 if (iter.IsEndOfWord(range_max) || iter.IsStartOfWord(range_max)) | 1698 if (iter.IsEndOfWord(range_max) || iter.IsStartOfWord(range_max)) |
1698 break; | 1699 break; |
1699 | 1700 |
1700 return range.is_reversed() ? Range(range_max, range_min) | 1701 return range.is_reversed() ? Range(range_max, range_min) |
1701 : Range(range_min, range_max); | 1702 : Range(range_min, range_max); |
1702 } | 1703 } |
1703 | 1704 |
1704 } // namespace gfx | 1705 } // namespace gfx |
OLD | NEW |