diff options
author | yukishiino@chromium.org <yukishiino@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-01 10:52:24 +0000 |
---|---|---|
committer | yukishiino@chromium.org <yukishiino@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-01 10:52:24 +0000 |
commit | c831ea9cacd4711fb3e7ff56e8c4ca30fafb1ed3 (patch) | |
tree | e3a3e0de8e7e46afad5e6b422b1d315dc589de96 /ui | |
parent | f0991b4bde7420e2cb95b4f160f20f9f55facd1b (diff) | |
download | chromium_src-c831ea9cacd4711fb3e7ff56e8c4ca30fafb1ed3.zip chromium_src-c831ea9cacd4711fb3e7ff56e8c4ca30fafb1ed3.tar.gz chromium_src-c831ea9cacd4711fb3e7ff56e8c4ca30fafb1ed3.tar.bz2 |
Supports cap height in gfx::Font and gfx::FontList.
This CL is a preparation of http://crrev.com/23601006 .
Cap height will be used to determine the fixed baseline of text, especially for Omnibox but not limited to.
Omnibox wants to show Latin characters vertically center, i.e. ABC look just center. Omnibox also wants to resize the font list so text is small enough to fit in Omnibox.
The baseline is determined from these two restrictions. All the texts are rendered based on this baseline regardless its height. Any characters within the height of the font list must fit in Omnibox.
For text controls other than Omnibox, the height of text box may be determined from the height of the font list and the cap height may not be used.
If the height of text box is smaller than the height of the font list, then the text control determines the baseline based on cap height so it shows ABC vertically center.
BUG=146236,264436
TEST=Ran ui_unittests.
Review URL: https://codereview.chromium.org/24240013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@226202 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/gfx/font.cc | 4 | ||||
-rw-r--r-- | ui/gfx/font.h | 3 | ||||
-rw-r--r-- | ui/gfx/font_list.cc | 5 | ||||
-rw-r--r-- | ui/gfx/font_list.h | 4 | ||||
-rw-r--r-- | ui/gfx/font_unittest.cc | 49 | ||||
-rw-r--r-- | ui/gfx/platform_font.h | 4 | ||||
-rw-r--r-- | ui/gfx/platform_font_ios.h | 2 | ||||
-rw-r--r-- | ui/gfx/platform_font_ios.mm | 5 | ||||
-rw-r--r-- | ui/gfx/platform_font_mac.h | 2 | ||||
-rw-r--r-- | ui/gfx/platform_font_mac.mm | 6 | ||||
-rw-r--r-- | ui/gfx/platform_font_pango.cc | 11 | ||||
-rw-r--r-- | ui/gfx/platform_font_pango.h | 1 | ||||
-rw-r--r-- | ui/gfx/platform_font_win.cc | 21 | ||||
-rw-r--r-- | ui/gfx/platform_font_win.h | 5 |
14 files changed, 93 insertions, 29 deletions
diff --git a/ui/gfx/font.cc b/ui/gfx/font.cc index aa4638c..7f6ac7c 100644 --- a/ui/gfx/font.cc +++ b/ui/gfx/font.cc @@ -54,6 +54,10 @@ int Font::GetBaseline() const { return platform_font_->GetBaseline(); } +int Font::GetCapHeight() const { + return platform_font_->GetCapHeight(); +} + int Font::GetAverageCharacterWidth() const { return platform_font_->GetAverageCharacterWidth(); } diff --git a/ui/gfx/font.h b/ui/gfx/font.h index 5187ec4..020ab64 100644 --- a/ui/gfx/font.h +++ b/ui/gfx/font.h @@ -69,6 +69,9 @@ class GFX_EXPORT Font { // Returns the baseline, or ascent, of the font. int GetBaseline() const; + // Returns the cap height of the font. + int GetCapHeight() const; + // Returns the average character width for the font. int GetAverageCharacterWidth() const; diff --git a/ui/gfx/font_list.cc b/ui/gfx/font_list.cc index e01483a..72c8777 100644 --- a/ui/gfx/font_list.cc +++ b/ui/gfx/font_list.cc @@ -177,6 +177,11 @@ int FontList::GetBaseline() const { return common_baseline_; } +int FontList::GetCapHeight() const { + // Assume the primary font is used to render Latin characters. + return GetPrimaryFont().GetCapHeight(); +} + int FontList::GetStringWidth(const base::string16& text) const { // Rely on the primary font metrics for the time being. // TODO(yukishiino): Not only the first font, all the fonts in the list should diff --git a/ui/gfx/font_list.h b/ui/gfx/font_list.h index 96398a1..2c47f4c 100644 --- a/ui/gfx/font_list.h +++ b/ui/gfx/font_list.h @@ -81,6 +81,10 @@ class GFX_EXPORT FontList { // fonts in the font list. int GetBaseline() const; + // Returns the cap height of this font list. + // Currently returns the cap height of the primary font. + int GetCapHeight() const; + // Returns the number of horizontal pixels needed to display |text|. int GetStringWidth(const base::string16& text) const; diff --git a/ui/gfx/font_unittest.cc b/ui/gfx/font_unittest.cc index 6b5cb79..247b2f3 100644 --- a/ui/gfx/font_unittest.cc +++ b/ui/gfx/font_unittest.cc @@ -59,10 +59,10 @@ int ScopedMinimumFontSizeCallback::minimum_size_ = 0; TEST_F(FontTest, LoadArial) { Font cf("Arial", 16); NativeFont native = cf.GetNativeFont(); - ASSERT_TRUE(native); - ASSERT_EQ(cf.GetStyle(), Font::NORMAL); - ASSERT_EQ(cf.GetFontSize(), 16); - ASSERT_EQ(cf.GetFontName(), "Arial"); + EXPECT_TRUE(native); + EXPECT_EQ(cf.GetStyle(), Font::NORMAL); + EXPECT_EQ(cf.GetFontSize(), 16); + EXPECT_EQ(cf.GetFontName(), "Arial"); FreeIfNecessary(native); } @@ -70,45 +70,56 @@ TEST_F(FontTest, LoadArialBold) { Font cf("Arial", 16); Font bold(cf.DeriveFont(0, Font::BOLD)); NativeFont native = bold.GetNativeFont(); - ASSERT_TRUE(native); - ASSERT_EQ(bold.GetStyle(), Font::BOLD); + EXPECT_TRUE(native); + EXPECT_EQ(bold.GetStyle(), Font::BOLD); FreeIfNecessary(native); } TEST_F(FontTest, Ascent) { Font cf("Arial", 16); - ASSERT_GT(cf.GetBaseline(), 2); - ASSERT_LE(cf.GetBaseline(), 22); + EXPECT_GT(cf.GetBaseline(), 2); + EXPECT_LE(cf.GetBaseline(), 22); } TEST_F(FontTest, Height) { Font cf("Arial", 16); - ASSERT_GE(cf.GetHeight(), 16); + EXPECT_GE(cf.GetHeight(), 16); // TODO(akalin): Figure out why height is so large on Linux. - ASSERT_LE(cf.GetHeight(), 26); + EXPECT_LE(cf.GetHeight(), 26); +} + +TEST_F(FontTest, CapHeight) { + Font cf("Arial", 16); + EXPECT_GT(cf.GetCapHeight(), 0); + EXPECT_GT(cf.GetCapHeight(), cf.GetHeight() / 2); +#if defined(OS_CHROMEOS) || defined(OS_LINUX) + EXPECT_EQ(cf.GetCapHeight(), cf.GetHeight()); +#else + EXPECT_LT(cf.GetCapHeight(), cf.GetHeight()); +#endif } TEST_F(FontTest, AvgWidths) { Font cf("Arial", 16); - ASSERT_EQ(cf.GetExpectedTextWidth(0), 0); - ASSERT_GT(cf.GetExpectedTextWidth(1), cf.GetExpectedTextWidth(0)); - ASSERT_GT(cf.GetExpectedTextWidth(2), cf.GetExpectedTextWidth(1)); - ASSERT_GT(cf.GetExpectedTextWidth(3), cf.GetExpectedTextWidth(2)); + EXPECT_EQ(cf.GetExpectedTextWidth(0), 0); + EXPECT_GT(cf.GetExpectedTextWidth(1), cf.GetExpectedTextWidth(0)); + EXPECT_GT(cf.GetExpectedTextWidth(2), cf.GetExpectedTextWidth(1)); + EXPECT_GT(cf.GetExpectedTextWidth(3), cf.GetExpectedTextWidth(2)); } TEST_F(FontTest, AvgCharWidth) { Font cf("Arial", 16); - ASSERT_GT(cf.GetAverageCharacterWidth(), 0); + EXPECT_GT(cf.GetAverageCharacterWidth(), 0); } TEST_F(FontTest, Widths) { Font cf("Arial", 16); - ASSERT_EQ(cf.GetStringWidth(base::string16()), 0); - ASSERT_GT(cf.GetStringWidth(ASCIIToUTF16("a")), + EXPECT_EQ(cf.GetStringWidth(base::string16()), 0); + EXPECT_GT(cf.GetStringWidth(ASCIIToUTF16("a")), cf.GetStringWidth(base::string16())); - ASSERT_GT(cf.GetStringWidth(ASCIIToUTF16("ab")), + EXPECT_GT(cf.GetStringWidth(ASCIIToUTF16("ab")), cf.GetStringWidth(ASCIIToUTF16("a"))); - ASSERT_GT(cf.GetStringWidth(ASCIIToUTF16("abc")), + EXPECT_GT(cf.GetStringWidth(ASCIIToUTF16("abc")), cf.GetStringWidth(ASCIIToUTF16("ab"))); } diff --git a/ui/gfx/platform_font.h b/ui/gfx/platform_font.h index 7670d47..d576bcd 100644 --- a/ui/gfx/platform_font.h +++ b/ui/gfx/platform_font.h @@ -42,6 +42,9 @@ class GFX_EXPORT PlatformFont : public base::RefCounted<PlatformFont> { // Returns the baseline, or ascent, of the font. virtual int GetBaseline() const = 0; + // Returns the cap height of the font. + virtual int GetCapHeight() const = 0; + // Returns the average character width for the font. virtual int GetAverageCharacterWidth() const = 0; @@ -76,4 +79,3 @@ class GFX_EXPORT PlatformFont : public base::RefCounted<PlatformFont> { } // namespace gfx #endif // UI_GFX_PLATFORM_FONT_H_ - diff --git a/ui/gfx/platform_font_ios.h b/ui/gfx/platform_font_ios.h index 789b591..2b30955 100644 --- a/ui/gfx/platform_font_ios.h +++ b/ui/gfx/platform_font_ios.h @@ -20,6 +20,7 @@ class PlatformFontIOS : public PlatformFont { virtual Font DeriveFont(int size_delta, int style) const OVERRIDE; virtual int GetHeight() const OVERRIDE; virtual int GetBaseline() const OVERRIDE; + virtual int GetCapHeight() const OVERRIDE; virtual int GetAverageCharacterWidth() const OVERRIDE; virtual int GetStringWidth(const base::string16& text) const OVERRIDE; virtual int GetExpectedTextWidth(int length) const OVERRIDE; @@ -47,6 +48,7 @@ class PlatformFontIOS : public PlatformFont { // Cached metrics, generated at construction. int height_; int ascent_; + int cap_height_; int average_width_; DISALLOW_COPY_AND_ASSIGN(PlatformFontIOS); diff --git a/ui/gfx/platform_font_ios.mm b/ui/gfx/platform_font_ios.mm index cfc69cf..92608d3 100644 --- a/ui/gfx/platform_font_ios.mm +++ b/ui/gfx/platform_font_ios.mm @@ -51,6 +51,10 @@ int PlatformFontIOS::GetBaseline() const { return ascent_; } +int PlatformFontIOS::GetCapHeight() const { + return cap_height_; +} + int PlatformFontIOS::GetAverageCharacterWidth() const { return average_width_; } @@ -103,6 +107,7 @@ void PlatformFontIOS::CalculateMetrics() { UIFont* font = GetNativeFont(); height_ = font.lineHeight; ascent_ = font.ascender; + cap_height_ = font.capHeight; average_width_ = [@"x" sizeWithFont:font].width; } diff --git a/ui/gfx/platform_font_mac.h b/ui/gfx/platform_font_mac.h index 13c8677..e9d0714 100644 --- a/ui/gfx/platform_font_mac.h +++ b/ui/gfx/platform_font_mac.h @@ -21,6 +21,7 @@ class PlatformFontMac : public PlatformFont { virtual Font DeriveFont(int size_delta, int style) const OVERRIDE; virtual int GetHeight() const OVERRIDE; virtual int GetBaseline() const OVERRIDE; + virtual int GetCapHeight() const OVERRIDE; virtual int GetAverageCharacterWidth() const OVERRIDE; virtual int GetStringWidth(const base::string16& text) const OVERRIDE; virtual int GetExpectedTextWidth(int length) const OVERRIDE; @@ -48,6 +49,7 @@ class PlatformFontMac : public PlatformFont { // Cached metrics, generated at construction. int height_; int ascent_; + int cap_height_; int average_width_; DISALLOW_COPY_AND_ASSIGN(PlatformFontMac); diff --git a/ui/gfx/platform_font_mac.mm b/ui/gfx/platform_font_mac.mm index bf0c0bd..c75bf66 100644 --- a/ui/gfx/platform_font_mac.mm +++ b/ui/gfx/platform_font_mac.mm @@ -59,6 +59,10 @@ int PlatformFontMac::GetBaseline() const { return ascent_; } +int PlatformFontMac::GetCapHeight() const { + return cap_height_; +} + int PlatformFontMac::GetAverageCharacterWidth() const { return average_width_; } @@ -128,6 +132,7 @@ void PlatformFontMac::CalculateMetrics() { [[NSLayoutManager alloc] init]); height_ = [layout_manager defaultLineHeightForFont:font]; ascent_ = [font ascender]; + cap_height_ = [font capHeight]; average_width_ = NSWidth([font boundingRectForGlyph:[font glyphWithName:@"x"]]); } @@ -152,4 +157,3 @@ PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name, } } // namespace gfx - diff --git a/ui/gfx/platform_font_pango.cc b/ui/gfx/platform_font_pango.cc index 0ddf363..856acc2 100644 --- a/ui/gfx/platform_font_pango.cc +++ b/ui/gfx/platform_font_pango.cc @@ -182,6 +182,16 @@ int PlatformFontPango::GetBaseline() const { return ascent_pixels_; } +int PlatformFontPango::GetCapHeight() const { + // 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 height_pixels_; +} + int PlatformFontPango::GetAverageCharacterWidth() const { const_cast<PlatformFontPango*>(this)->InitPangoMetrics(); return SkScalarRound(average_width_pixels_); @@ -381,7 +391,6 @@ void PlatformFontPango::InitPangoMetrics() { } } - double PlatformFontPango::GetAverageWidth() const { const_cast<PlatformFontPango*>(this)->InitPangoMetrics(); return average_width_pixels_; diff --git a/ui/gfx/platform_font_pango.h b/ui/gfx/platform_font_pango.h index 0846f5e..136bf671 100644 --- a/ui/gfx/platform_font_pango.h +++ b/ui/gfx/platform_font_pango.h @@ -49,6 +49,7 @@ class GFX_EXPORT PlatformFontPango : public PlatformFont { virtual Font DeriveFont(int size_delta, int style) const OVERRIDE; virtual int GetHeight() const OVERRIDE; virtual int GetBaseline() const OVERRIDE; + virtual int GetCapHeight() const OVERRIDE; virtual int GetAverageCharacterWidth() const OVERRIDE; virtual int GetStringWidth(const base::string16& text) const OVERRIDE; virtual int GetExpectedTextWidth(int length) const OVERRIDE; diff --git a/ui/gfx/platform_font_win.cc b/ui/gfx/platform_font_win.cc index 2d4c006..a97da2e 100644 --- a/ui/gfx/platform_font_win.cc +++ b/ui/gfx/platform_font_win.cc @@ -141,6 +141,10 @@ int PlatformFontWin::GetBaseline() const { return font_ref_->baseline(); } +int PlatformFontWin::GetCapHeight() const { + return font_ref_->cap_height(); +} + int PlatformFontWin::GetAverageCharacterWidth() const { return font_ref_->ave_char_width(); } @@ -235,6 +239,8 @@ PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRef(HFONT font) { const int height = std::max<int>(1, font_metrics.tmHeight); const int baseline = std::max<int>(1, font_metrics.tmAscent); + const int cap_height = + std::max<int>(1, font_metrics.tmAscent - font_metrics.tmInternalLeading); const int ave_char_width = std::max<int>(1, font_metrics.tmAveCharWidth); const int font_size = std::max<int>(1, font_metrics.tmHeight - font_metrics.tmInternalLeading); @@ -246,7 +252,8 @@ PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRef(HFONT font) { if (font_metrics.tmWeight >= kTextMetricWeightBold) style |= Font::BOLD; - return new HFontRef(font, font_size, height, baseline, ave_char_width, style); + return new HFontRef(font, font_size, height, baseline, cap_height, + ave_char_width, style); } PlatformFontWin::PlatformFontWin(HFontRef* hfont_ref) : font_ref_(hfont_ref) { @@ -256,15 +263,17 @@ PlatformFontWin::PlatformFontWin(HFontRef* hfont_ref) : font_ref_(hfont_ref) { // PlatformFontWin::HFontRef: PlatformFontWin::HFontRef::HFontRef(HFONT hfont, - int font_size, - int height, - int baseline, - int ave_char_width, - int style) + int font_size, + int height, + int baseline, + int cap_height, + int ave_char_width, + int style) : hfont_(hfont), font_size_(font_size), height_(height), baseline_(baseline), + cap_height_(cap_height), ave_char_width_(ave_char_width), style_(style), dlu_base_x_(-1), diff --git a/ui/gfx/platform_font_win.h b/ui/gfx/platform_font_win.h index 77f3658..035ce8a 100644 --- a/ui/gfx/platform_font_win.h +++ b/ui/gfx/platform_font_win.h @@ -57,6 +57,7 @@ class GFX_EXPORT PlatformFontWin : public PlatformFont { virtual Font DeriveFont(int size_delta, int style) const OVERRIDE; virtual int GetHeight() const OVERRIDE; virtual int GetBaseline() const OVERRIDE; + virtual int GetCapHeight() const OVERRIDE; virtual int GetAverageCharacterWidth() const OVERRIDE; virtual int GetStringWidth(const base::string16& text) const OVERRIDE; virtual int GetExpectedTextWidth(int length) const OVERRIDE; @@ -84,6 +85,7 @@ class GFX_EXPORT PlatformFontWin : public PlatformFont { int font_size, int height, int baseline, + int cap_height, int ave_char_width, int style); @@ -91,6 +93,7 @@ class GFX_EXPORT PlatformFontWin : public PlatformFont { HFONT hfont() const { return hfont_; } int height() const { return height_; } int baseline() const { return baseline_; } + int cap_height() const { return cap_height_; } int ave_char_width() const { return ave_char_width_; } int style() const { return style_; } const std::string& font_name() const { return font_name_; } @@ -109,6 +112,7 @@ class GFX_EXPORT PlatformFontWin : public PlatformFont { const int font_size_; const int height_; const int baseline_; + const int cap_height_; const int ave_char_width_; const int style_; // Average character width in dialog units. This is queried lazily from the @@ -155,4 +159,3 @@ class GFX_EXPORT PlatformFontWin : public PlatformFont { } // namespace gfx #endif // UI_GFX_PLATFORM_FONT_WIN_H_ - |