diff options
author | kuan@chromium.org <kuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-25 21:17:45 +0000 |
---|---|---|
committer | kuan@chromium.org <kuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-25 21:17:45 +0000 |
commit | e3e6f91a6234c552eaa915a2c6e1cab9f28d4dd7 (patch) | |
tree | a095d799c9c0c3f15bced9ebae18fb370f16aeba /ui/gfx | |
parent | cba331d1ab6ae669f3b13a05a8da5ba7ad980168 (diff) | |
download | chromium_src-e3e6f91a6234c552eaa915a2c6e1cab9f28d4dd7.zip chromium_src-e3e6f91a6234c552eaa915a2c6e1cab9f28d4dd7.tar.gz chromium_src-e3e6f91a6234c552eaa915a2c6e1cab9f28d4dd7.tar.bz2 |
Revert 231107 "Always aligns text at vertically center (Textfiel..."
> Always aligns text at vertically center (Textfield, Label).
>
> This CL makes Textfield and Label put their content text at vertically center respecting the cap height.
>
> Also this CL removes vertical alignment support, which we no longer need.
>
> I think this CL fixes all issues related to vertical alignment and font height.
>
> BUG=146236, 264436
> TEST=Test manually + ui_unittests
>
> Review URL: https://codereview.chromium.org/25039002
Cannot use kInvalidBaseLine in render_text.cc as static initializer.
TBR=yukishiino@chromium.org
Review URL: https://codereview.chromium.org/45173003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@231117 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/gfx')
-rw-r--r-- | ui/gfx/font.h | 9 | ||||
-rw-r--r-- | ui/gfx/font_unittest.cc | 4 | ||||
-rw-r--r-- | ui/gfx/platform_font_pango.cc | 4 | ||||
-rw-r--r-- | ui/gfx/render_text.cc | 48 | ||||
-rw-r--r-- | ui/gfx/render_text.h | 46 | ||||
-rw-r--r-- | ui/gfx/render_text_linux.cc | 16 | ||||
-rw-r--r-- | ui/gfx/render_text_linux.h | 2 | ||||
-rw-r--r-- | ui/gfx/render_text_mac.cc | 10 | ||||
-rw-r--r-- | ui/gfx/render_text_mac.h | 2 | ||||
-rw-r--r-- | ui/gfx/render_text_unittest.cc | 38 | ||||
-rw-r--r-- | ui/gfx/render_text_win.cc | 10 | ||||
-rw-r--r-- | ui/gfx/render_text_win.h | 2 | ||||
-rw-r--r-- | ui/gfx/text_constants.h | 10 |
13 files changed, 81 insertions, 120 deletions
diff --git a/ui/gfx/font.h b/ui/gfx/font.h index f84bfa2..020ab64 100644 --- a/ui/gfx/font.h +++ b/ui/gfx/font.h @@ -18,15 +18,6 @@ class PlatformFont; // Font provides a wrapper around an underlying font. Copy and assignment // operators are explicitly allowed, and cheap. -// -// Figure of font metrics: -// +--------+-------------------+------------------+ -// | | | internal leading | -// | | ascent (baseline) +------------------+ -// | height | | cap height | -// | |-------------------+------------------+ -// | | descent (height - baseline) | -// +--------+--------------------------------------+ class GFX_EXPORT Font { public: // The following constants indicate the font style. diff --git a/ui/gfx/font_unittest.cc b/ui/gfx/font_unittest.cc index 073ffb5..247b2f3 100644 --- a/ui/gfx/font_unittest.cc +++ b/ui/gfx/font_unittest.cc @@ -93,9 +93,9 @@ TEST_F(FontTest, CapHeight) { EXPECT_GT(cf.GetCapHeight(), 0); EXPECT_GT(cf.GetCapHeight(), cf.GetHeight() / 2); #if defined(OS_CHROMEOS) || defined(OS_LINUX) - EXPECT_EQ(cf.GetCapHeight(), cf.GetBaseline()); + EXPECT_EQ(cf.GetCapHeight(), cf.GetHeight()); #else - EXPECT_LT(cf.GetCapHeight(), cf.GetBaseline()); + EXPECT_LT(cf.GetCapHeight(), cf.GetHeight()); #endif } diff --git a/ui/gfx/platform_font_pango.cc b/ui/gfx/platform_font_pango.cc index 020cc7f..856acc2 100644 --- a/ui/gfx/platform_font_pango.cc +++ b/ui/gfx/platform_font_pango.cc @@ -183,13 +183,13 @@ int PlatformFontPango::GetBaseline() const { } int PlatformFontPango::GetCapHeight() const { - // Return the ascent as an approximation because Pango doesn't support cap + // Return the height as an approximation because Pango doesn't support cap // height. // TODO(yukishiino): Come up with a better approximation of cap height, or // support cap height metrics. Another option is to have a hard-coded table // of cap height for major fonts used in Chromium/Chrome. // See http://crbug.com/249507 - return ascent_pixels_; + return height_pixels_; } int PlatformFontPango::GetAverageCharacterWidth() const { diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc index 16520ee..fc8bad1 100644 --- a/ui/gfx/render_text.cc +++ b/ui/gfx/render_text.cc @@ -5,7 +5,6 @@ #include "ui/gfx/render_text.h" #include <algorithm> -#include <limits> #include "base/i18n/break_iterator.h" #include "base/logging.h" @@ -45,28 +44,6 @@ const SkScalar kLineThickness = (SK_Scalar1 / 18); // Fraction of the text size to use for a top margin of a diagonal strike. const SkScalar kDiagonalStrikeMarginOffset = (SK_Scalar1 / 4); -// Invalid value of baseline. Assigning this value to |baseline_| causes -// re-calculation of baseline. -const int kInvalidBaseline = std::numeric_limits<int>::max(); - -// Returns the baseline, with which the text best appears vertically centered. -int DetermineBaselineCenteringText(const Rect& display_rect, - const FontList& font_list) { - const int display_height = display_rect.height(); - const int font_height = font_list.GetHeight(); - // Lower and upper bound of baseline shift as we try to show as much area of - // text as possible. In particular case of |display_height| == |font_height|, - // we do not want to shift the baseline. - const int min_shift = std::min(0, display_height - font_height); - const int max_shift = std::abs(display_height - font_height); - const int baseline = font_list.GetBaseline(); - const int cap_height = font_list.GetCapHeight(); - const int internal_leading = baseline - cap_height; - const int baseline_shift = - (display_height - cap_height) / 2 - internal_leading; - return baseline + std::max(min_shift, std::min(max_shift, baseline_shift)); -} - // Converts |gfx::Font::FontStyle| flags to |SkTypeface::Style| flags. SkTypeface::Style ConvertFontStyleToSkiaTypefaceStyle(int font_style) { int skia_style = SkTypeface::kNormal; @@ -371,9 +348,16 @@ void RenderText::SetHorizontalAlignment(HorizontalAlignment alignment) { } } +void RenderText::SetVerticalAlignment(VerticalAlignment alignment) { + if (vertical_alignment_ != alignment) { + vertical_alignment_ = alignment; + display_offset_ = Vector2d(); + cached_bounds_and_offset_valid_ = false; + } +} + void RenderText::SetFontList(const FontList& font_list) { font_list_ = font_list; - baseline_ = kInvalidBaseline; cached_bounds_and_offset_valid_ = false; ResetLayout(); } @@ -430,7 +414,6 @@ void RenderText::SetMultiline(bool multiline) { void RenderText::SetDisplayRect(const Rect& r) { display_rect_ = r; - baseline_ = kInvalidBaseline; cached_bounds_and_offset_valid_ = false; lines_.clear(); } @@ -670,13 +653,6 @@ int RenderText::GetContentWidth() { return GetStringSize().width() + (cursor_enabled_ ? 1 : 0); } -int RenderText::GetBaseline() { - if (baseline_ == kInvalidBaseline) - baseline_ = DetermineBaselineCenteringText(display_rect(), font_list()); - DCHECK_NE(kInvalidBaseline, baseline_); - return baseline_; -} - void RenderText::Draw(Canvas* canvas) { EnsureLayout(); @@ -808,6 +784,7 @@ void RenderText::SetTextShadows(const ShadowValues& shadows) { RenderText::RenderText() : horizontal_alignment_(base::i18n::IsRTL() ? ALIGN_RIGHT : ALIGN_LEFT), + vertical_alignment_(ALIGN_VCENTER), directionality_mode_(DIRECTIONALITY_FROM_TEXT), text_direction_(base::i18n::UNKNOWN_DIRECTION), cursor_enabled_(true), @@ -829,7 +806,6 @@ RenderText::RenderText() fade_tail_(false), background_is_transparent_(false), clip_to_display_rect_(true), - baseline_(kInvalidBaseline), cached_bounds_and_offset_valid_(false) { } @@ -993,7 +969,11 @@ Vector2d RenderText::GetAlignmentOffset(size_t line_number) { if (horizontal_alignment_ == ALIGN_CENTER) offset.set_x(offset.x() / 2); } - offset.set_y(GetBaseline() - GetLayoutTextBaseline()); + if (vertical_alignment_ != ALIGN_TOP) { + offset.set_y(display_rect().height() - GetStringSize().height()); + if (vertical_alignment_ == ALIGN_VCENTER) + offset.set_y(offset.y() / 2); + } return offset; } diff --git a/ui/gfx/render_text.h b/ui/gfx/render_text.h index 6d998de..ce0a027 100644 --- a/ui/gfx/render_text.h +++ b/ui/gfx/render_text.h @@ -167,6 +167,11 @@ class GFX_EXPORT RenderText { } void SetHorizontalAlignment(HorizontalAlignment alignment); + VerticalAlignment vertical_alignment() const { + return vertical_alignment_; + } + void SetVerticalAlignment(VerticalAlignment alignment); + const FontList& font_list() const { return font_list_; } void SetFontList(const FontList& font_list); void SetFont(const Font& font); @@ -333,11 +338,9 @@ class GFX_EXPORT RenderText { // mode). Reserves room for the cursor if |cursor_enabled_| is true. int GetContentWidth(); - // Returns the common baseline of the text. The return value is the vertical - // offset from the top of |display_rect_| to the text baseline, in pixels. - // The baseline is determined from the font list and display rect, and does - // not depend on the text. - int GetBaseline(); + // Returns the common baseline of the text. The returned value is the vertical + // offset from the top of |display_rect| to the text baseline, in pixels. + virtual int GetBaseline() = 0; void Draw(Canvas* canvas); @@ -395,30 +398,6 @@ class GFX_EXPORT RenderText { const std::vector<internal::Line>& lines() const { return lines_; } void set_lines(std::vector<internal::Line>* lines) { lines_.swap(*lines); } - // Returns the baseline of the current text. The return value depends on - // the text and its layout while the return value of GetBaseline() doesn't. - // GetAlignmentOffset() takes into account the difference between them. - // - // We'd like a RenderText to show the text always on the same baseline - // regardless of the text, so the text does not jump up or down depending - // on the text. However, underlying layout engines return different baselines - // depending on the text. In general, layout engines determine the minimum - // bounding box for the text and return the baseline from the top of the - // bounding box. So the baseline changes depending on font metrics used to - // layout the text. - // - // For example, suppose there are FontA and FontB and the baseline of FontA - // is smaller than the one of FontB. If the text is laid out only with FontA, - // then the baseline of FontA may be returned. If the text includes some - // characters which are laid out with FontB, then the baseline of FontB may - // be returned. - // - // GetBaseline() returns the fixed baseline regardless of the text. - // GetLayoutTextBaseline() returns the baseline determined by the underlying - // layout engine, and it changes depending on the text. GetAlignmentOffset() - // returns the difference between them. - virtual int GetLayoutTextBaseline() = 0; - const Vector2d& GetUpdatedDisplayOffset(); void set_cached_bounds_and_offset_valid(bool valid) { @@ -563,6 +542,10 @@ class GFX_EXPORT RenderText { // default is to align left if the application UI is LTR and right if RTL. HorizontalAlignment horizontal_alignment_; + // Vertical alignment of the text with respect to |display_rect_|. The + // default is to align vertically centered. + VerticalAlignment vertical_alignment_; + // The text directionality mode, defaults to DIRECTIONALITY_FROM_TEXT. DirectionalityMode directionality_mode_; @@ -648,11 +631,6 @@ class GFX_EXPORT RenderText { // Get this point with GetUpdatedDisplayOffset (or risk using a stale value). Vector2d display_offset_; - // The baseline of the text. This is determined from the height of the - // display area and the cap height of the font list so the text is vertically - // centered. - int baseline_; - // The cached bounds and offset are invalidated by changes to the cursor, // selection, font, and other operations that adjust the visible text bounds. bool cached_bounds_and_offset_valid_; diff --git a/ui/gfx/render_text_linux.cc b/ui/gfx/render_text_linux.cc index 3166875..4b7b934 100644 --- a/ui/gfx/render_text_linux.cc +++ b/ui/gfx/render_text_linux.cc @@ -91,6 +91,15 @@ Size RenderTextLinux::GetStringSize() { return Size(width, std::max(height, font_list().GetHeight())); } +int RenderTextLinux::GetBaseline() { + EnsureLayout(); + // Keep a consistent baseline between this particular string's PangoLayout and + // potentially larger text supported by the FontList. + // See the example in GetStringSize(). + return std::max(PANGO_PIXELS(pango_layout_get_baseline(layout_)), + font_list().GetBaseline()); +} + SelectionModel RenderTextLinux::FindCursorPosition(const Point& point) { EnsureLayout(); @@ -137,11 +146,6 @@ std::vector<RenderText::FontSpan> RenderTextLinux::GetFontSpansForTesting() { return spans; } -int RenderTextLinux::GetLayoutTextBaseline() { - EnsureLayout(); - return PANGO_PIXELS(pango_layout_get_baseline(layout_)); -} - SelectionModel RenderTextLinux::AdjacentCharSelectionModel( const SelectionModel& selection, VisualCursorDirection direction) { @@ -377,7 +381,7 @@ void RenderTextLinux::DrawVisualText(Canvas* canvas) { DCHECK(layout_); // Skia will draw glyphs with respect to the baseline. - Vector2d offset(GetLineOffset(0) + Vector2d(0, GetLayoutTextBaseline())); + Vector2d offset(GetLineOffset(0) + Vector2d(0, GetBaseline())); SkScalar x = SkIntToScalar(offset.x()); SkScalar y = SkIntToScalar(offset.y()); diff --git a/ui/gfx/render_text_linux.h b/ui/gfx/render_text_linux.h index 296a3fe..1500fc0 100644 --- a/ui/gfx/render_text_linux.h +++ b/ui/gfx/render_text_linux.h @@ -20,12 +20,12 @@ class RenderTextLinux : public RenderText { // Overridden from RenderText: virtual Size GetStringSize() OVERRIDE; + virtual int GetBaseline() OVERRIDE; virtual SelectionModel FindCursorPosition(const Point& point) OVERRIDE; virtual std::vector<FontSpan> GetFontSpansForTesting() OVERRIDE; protected: // Overridden from RenderText: - virtual int GetLayoutTextBaseline() OVERRIDE; virtual SelectionModel AdjacentCharSelectionModel( const SelectionModel& selection, VisualCursorDirection direction) OVERRIDE; diff --git a/ui/gfx/render_text_mac.cc b/ui/gfx/render_text_mac.cc index 576a1c2..d86975d 100644 --- a/ui/gfx/render_text_mac.cc +++ b/ui/gfx/render_text_mac.cc @@ -33,6 +33,11 @@ SizeF RenderTextMac::GetStringSizeF() { return string_size_; } +int RenderTextMac::GetBaseline() { + EnsureLayout(); + return common_baseline_; +} + SelectionModel RenderTextMac::FindCursorPosition(const Point& point) { // TODO(asvitkine): Implement this. http://crbug.com/131618 return SelectionModel(); @@ -54,11 +59,6 @@ std::vector<RenderText::FontSpan> RenderTextMac::GetFontSpansForTesting() { return spans; } -int RenderTextMac::GetLayoutTextBaseline() { - EnsureLayout(); - return common_baseline_; -} - SelectionModel RenderTextMac::AdjacentCharSelectionModel( const SelectionModel& selection, VisualCursorDirection direction) { diff --git a/ui/gfx/render_text_mac.h b/ui/gfx/render_text_mac.h index 3a18a0f..3d25430 100644 --- a/ui/gfx/render_text_mac.h +++ b/ui/gfx/render_text_mac.h @@ -28,12 +28,12 @@ class RenderTextMac : public RenderText { // Overridden from RenderText: virtual Size GetStringSize() OVERRIDE; virtual SizeF GetStringSizeF() OVERRIDE; + virtual int GetBaseline() OVERRIDE; virtual SelectionModel FindCursorPosition(const Point& point) OVERRIDE; virtual std::vector<FontSpan> GetFontSpansForTesting() OVERRIDE; protected: // Overridden from RenderText: - virtual int GetLayoutTextBaseline() OVERRIDE; virtual SelectionModel AdjacentCharSelectionModel( const SelectionModel& selection, VisualCursorDirection direction) OVERRIDE; diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc index cfd16dd..75e985e 100644 --- a/ui/gfx/render_text_unittest.cc +++ b/ui/gfx/render_text_unittest.cc @@ -1139,7 +1139,6 @@ TEST_F(RenderTextTest, StringSizeEmptyString) { const FontList font_list("Arial,Symbol, 16px"); scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); render_text->SetFontList(font_list); - render_text->SetDisplayRect(Rect(0, 0, 0, font_list.GetHeight())); // The empty string respects FontList metrics for non-zero height // and baseline. @@ -1181,9 +1180,7 @@ TEST_F(RenderTextTest, StringSizeRespectsFontListMetrics) { // Check |smaller_font_text| is rendered with the smaller font. scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); render_text->SetText(UTF8ToUTF16(smaller_font_text)); - render_text->SetFontList(FontList(smaller_font)); - render_text->SetDisplayRect(Rect(0, 0, 0, - render_text->font_list().GetHeight())); + render_text->SetFont(smaller_font); EXPECT_EQ(smaller_font.GetHeight(), render_text->GetStringSize().height()); EXPECT_EQ(smaller_font.GetBaseline(), render_text->GetBaseline()); @@ -1195,8 +1192,6 @@ TEST_F(RenderTextTest, StringSizeRespectsFontListMetrics) { fonts.push_back(larger_font); const FontList font_list(fonts); render_text->SetFontList(font_list); - render_text->SetDisplayRect(Rect(0, 0, 0, - render_text->font_list().GetHeight())); EXPECT_LT(smaller_font.GetHeight(), render_text->GetStringSize().height()); EXPECT_LT(smaller_font.GetBaseline(), render_text->GetBaseline()); EXPECT_EQ(font_list.GetHeight(), render_text->GetStringSize().height()); @@ -1298,19 +1293,21 @@ TEST_F(RenderTextTest, GetTextOffset) { // Set display area's size equal to the font size. const Size font_size(render_text->GetContentWidth(), - render_text->font_list().GetHeight()); + render_text->GetStringSize().height()); Rect display_rect(font_size); render_text->SetDisplayRect(display_rect); Vector2d offset = render_text->GetLineOffset(0); EXPECT_TRUE(offset.IsZero()); - const int kEnlargementX = 2; - display_rect.Inset(0, 0, -kEnlargementX, 0); + // Set display area's size greater than font size. + const int kEnlargement = 2; + display_rect.Inset(0, 0, -kEnlargement, -kEnlargement); render_text->SetDisplayRect(display_rect); - // Check the default horizontal alignment. + // Check the default horizontal and vertical alignment. offset = render_text->GetLineOffset(0); + EXPECT_EQ(kEnlargement / 2, offset.y()); EXPECT_EQ(0, offset.x()); // Check explicitly setting the horizontal alignment. @@ -1319,20 +1316,21 @@ TEST_F(RenderTextTest, GetTextOffset) { EXPECT_EQ(0, offset.x()); render_text->SetHorizontalAlignment(ALIGN_CENTER); offset = render_text->GetLineOffset(0); - EXPECT_EQ(kEnlargementX / 2, offset.x()); + EXPECT_EQ(kEnlargement / 2, offset.x()); render_text->SetHorizontalAlignment(ALIGN_RIGHT); offset = render_text->GetLineOffset(0); - EXPECT_EQ(kEnlargementX, offset.x()); + EXPECT_EQ(kEnlargement, offset.x()); - // Check that text is vertically centered within taller display rects. - const int kEnlargementY = display_rect.height(); - display_rect.Inset(0, 0, 0, -kEnlargementY); - render_text->SetDisplayRect(display_rect); - const Vector2d prev_offset = render_text->GetLineOffset(0); - display_rect.Inset(0, 0, 0, -2 * kEnlargementY); - render_text->SetDisplayRect(display_rect); + // Check explicitly setting the vertical alignment. + render_text->SetVerticalAlignment(ALIGN_TOP); + offset = render_text->GetLineOffset(0); + EXPECT_EQ(0, offset.y()); + render_text->SetVerticalAlignment(ALIGN_VCENTER); + offset = render_text->GetLineOffset(0); + EXPECT_EQ(kEnlargement / 2, offset.y()); + render_text->SetVerticalAlignment(ALIGN_BOTTOM); offset = render_text->GetLineOffset(0); - EXPECT_EQ(prev_offset.y() + kEnlargementY, offset.y()); + EXPECT_EQ(kEnlargement, offset.y()); SetRTL(was_rtl); } diff --git a/ui/gfx/render_text_win.cc b/ui/gfx/render_text_win.cc index 5f159f3..dfcff0e 100644 --- a/ui/gfx/render_text_win.cc +++ b/ui/gfx/render_text_win.cc @@ -492,6 +492,11 @@ Size RenderTextWin::GetStringSize() { return multiline_string_size_; } +int RenderTextWin::GetBaseline() { + EnsureLayout(); + return lines()[0].baseline; +} + SelectionModel RenderTextWin::FindCursorPosition(const Point& point) { if (text().empty()) return SelectionModel(); @@ -535,11 +540,6 @@ std::vector<RenderText::FontSpan> RenderTextWin::GetFontSpansForTesting() { return spans; } -int RenderTextWin::GetLayoutTextBaseline() { - EnsureLayout(); - return lines()[0].baseline; -} - SelectionModel RenderTextWin::AdjacentCharSelectionModel( const SelectionModel& selection, VisualCursorDirection direction) { diff --git a/ui/gfx/render_text_win.h b/ui/gfx/render_text_win.h index 52195e5..6aca235 100644 --- a/ui/gfx/render_text_win.h +++ b/ui/gfx/render_text_win.h @@ -64,12 +64,12 @@ class RenderTextWin : public RenderText { // Overridden from RenderText: virtual Size GetStringSize() OVERRIDE; + virtual int GetBaseline() OVERRIDE; virtual SelectionModel FindCursorPosition(const Point& point) OVERRIDE; virtual std::vector<FontSpan> GetFontSpansForTesting() OVERRIDE; protected: // Overridden from RenderText: - virtual int GetLayoutTextBaseline() OVERRIDE; virtual SelectionModel AdjacentCharSelectionModel( const SelectionModel& selection, VisualCursorDirection direction) OVERRIDE; diff --git a/ui/gfx/text_constants.h b/ui/gfx/text_constants.h index 4ac788e..cafeab4 100644 --- a/ui/gfx/text_constants.h +++ b/ui/gfx/text_constants.h @@ -28,6 +28,16 @@ enum HorizontalAlignment { ALIGN_RIGHT, }; +// Vertical text alignment modes. +enum VerticalAlignment { + // Align the text's top edge with that of its display area. + ALIGN_TOP = 0, + // Align the text's center with that of its display area. + ALIGN_VCENTER, + // Align the text's bottom edge with that of its display area. + ALIGN_BOTTOM, +}; + // The directionality modes used to determine the base text direction. enum DirectionalityMode { // Use the first strong character's direction. |