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

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

Issue 2767163003: Vertically center multi-line RenderTextHarfBuzz that uses SetMinLineHeight(). (Closed)
Patch Set: respond to comments Created 3 years, 8 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
« no previous file with comments | « ui/gfx/render_text.h ('k') | ui/gfx/render_text_harfbuzz.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW
« no previous file with comments | « ui/gfx/render_text.h ('k') | ui/gfx/render_text_harfbuzz.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698