diff options
author | jochen <jochen@chromium.org> | 2015-01-13 23:48:22 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-14 07:49:15 +0000 |
commit | ab0d2cafe050202ea69bbf4dfd9a6f6a39584a44 (patch) | |
tree | 3edb995b65991ba3f80ca8d0877474f2d4a8cf73 /ui/gfx | |
parent | 089c3ddeec583fd9e11564727a9695b70657e681 (diff) | |
download | chromium_src-ab0d2cafe050202ea69bbf4dfd9a6f6a39584a44.zip chromium_src-ab0d2cafe050202ea69bbf4dfd9a6f6a39584a44.tar.gz chromium_src-ab0d2cafe050202ea69bbf4dfd9a6f6a39584a44.tar.bz2 |
Revert of Relanding this with font test fixes for gdi. (patchset #7 id:120001 of https://codereview.chromium.org/853553002/)
Reason for revert:
still fails on XP
https://build.chromium.org/p/chromium.win/builders/XP%20Tests%20%281%29/builds/34996/steps/gfx_unittests/logs/DeriveFontWithHeight
Original issue's description:
> Relanding this with font test fixes for gdi.
>
> Get all font unittests running with DirectWrite on Windows 7+
>
> Fixes as per below:-
> 1. Remove the addition of the fLeading value when calculating the height for the font
> with DirectWrite. fAscent + fDescent is the height of the font and adding the fLeading
> value to it returns the spacing between lines which is not what we are looking for.
>
> 2. The FontListTest.Fonts_GetHeight_GetBaseline unittest has a condition which basically validates
> whether the difference between the font height and the baseline is different for Arial and Symbol
> fonts. This fails for DirectWrite and fails for GDI with font sizes like 50, etc. Replaced this check
> with a check for the font heights are different.
>
> 3. Reworked the PlatformFontWinTest.DeriveFontWithHeight test to ensure it passes for DirectWrite and GDI.
>
> 4. Ensure that the PlatformFontWin::DeriveFontWithHeight function honors the minimum font size constraint
> in all cases.
>
> BUG=442010
> R=msw
>
> Committed: https://crrev.com/3e05f41653bf36cce40718d8295ce2293218dab6
> Cr-Commit-Position: refs/heads/master@{#311388}
TBR=msw@chromium.org,ananta@chromium.org
NOTREECHECKS=true
NOTRY=true
BUG=442010
Review URL: https://codereview.chromium.org/847283003
Cr-Commit-Position: refs/heads/master@{#311424}
Diffstat (limited to 'ui/gfx')
-rw-r--r-- | ui/gfx/font_list_unittest.cc | 12 | ||||
-rw-r--r-- | ui/gfx/platform_font_win.cc | 86 | ||||
-rw-r--r-- | ui/gfx/platform_font_win.h | 13 | ||||
-rw-r--r-- | ui/gfx/platform_font_win_unittest.cc | 57 |
4 files changed, 117 insertions, 51 deletions
diff --git a/ui/gfx/font_list_unittest.cc b/ui/gfx/font_list_unittest.cc index 826eefa..6dcbb85 100644 --- a/ui/gfx/font_list_unittest.cc +++ b/ui/gfx/font_list_unittest.cc @@ -266,24 +266,24 @@ TEST(FontListTest, Fonts_GetHeight_GetBaseline) { EXPECT_EQ(font1.GetBaseline(), font_list1.GetBaseline()); // If there are two different fonts, the font list returns the max value - // for the baseline (ascent) and height. + // for ascent and descent. Font font2("Symbol", 16); ASSERT_EQ("symbol", base::StringToLowerASCII(font2.GetActualFontNameForTesting())); EXPECT_NE(font1.GetBaseline(), font2.GetBaseline()); - // TODO(ananta): Find a size and font pair with reliably distinct descents. - EXPECT_NE(font1.GetHeight(), font2.GetHeight()); + EXPECT_NE(font1.GetHeight() - font1.GetBaseline(), + font2.GetHeight() - font2.GetBaseline()); std::vector<Font> fonts; fonts.push_back(font1); fonts.push_back(font2); FontList font_list_mix(fonts); // ascent of FontList == max(ascent of Fonts) - EXPECT_EQ(std::max(font1.GetBaseline(), font2.GetBaseline()), - font_list_mix.GetBaseline()); - // descent of FontList == max(descent of Fonts) EXPECT_EQ(std::max(font1.GetHeight() - font1.GetBaseline(), font2.GetHeight() - font2.GetBaseline()), font_list_mix.GetHeight() - font_list_mix.GetBaseline()); + // descent of FontList == max(descent of Fonts) + EXPECT_EQ(std::max(font1.GetBaseline(), font2.GetBaseline()), + font_list_mix.GetBaseline()); } TEST(FontListTest, Fonts_DeriveWithHeightUpperBound) { diff --git a/ui/gfx/platform_font_win.cc b/ui/gfx/platform_font_win.cc index b8320c1..5e9d253 100644 --- a/ui/gfx/platform_font_win.cc +++ b/ui/gfx/platform_font_win.cc @@ -211,45 +211,33 @@ PlatformFontWin::PlatformFontWin(const std::string& font_name, Font PlatformFontWin::DeriveFontWithHeight(int height, int style) { DCHECK_GE(height, 0); + if (GetHeight() == height && GetStyle() == style) + return Font(this); + + // CreateFontIndirect() doesn't return the largest size for the given height + // when decreasing the height. Iterate to find it. + if (GetHeight() > height) { + const int min_font_size = GetMinimumFontSize(); + Font font = DeriveFont(-1, style); + int font_height = font.GetHeight(); + int font_size = font.GetFontSize(); + while (font_height > height && font_size != min_font_size) { + font = font.Derive(-1, style); + if (font_height == font.GetHeight() && font_size == font.GetFontSize()) + break; + font_height = font.GetHeight(); + font_size = font.GetFontSize(); + } + return font; + } - // Create a font with a height near that of the target height. LOGFONT font_info; GetObject(GetNativeFont(), sizeof(LOGFONT), &font_info); font_info.lfHeight = height; SetLogFontStyle(style, &font_info); HFONT hfont = CreateFontIndirect(&font_info); - Font font(new PlatformFontWin(CreateHFontRef(hfont))); - - // Respect the minimum font size constraint. - const int min_font_size = GetMinimumFontSize(); - - // Used to avoid shrinking the font and expanding it. - bool ran_shrink_loop = false; - - // CreateFontIndirect() doesn't return the largest size for the given height - // when decreasing the height. Iterate to find it. - while ((font.GetHeight() > height) && - (font.GetFontSize() >= min_font_size)) { - ran_shrink_loop = true; - Font derived_font = font.Derive(-1, style); - if ((derived_font.GetFontSize() < min_font_size) || - (derived_font.GetFontSize() == font.GetFontSize())) - break; - DCHECK_LT(derived_font.GetFontSize(), font.GetFontSize()); - font = derived_font; - } - - while ((!ran_shrink_loop && font.GetHeight() <= height) || - (font.GetFontSize() < min_font_size)) { - Font derived_font = font.Derive(1, style); - if ((derived_font.GetHeight() > height) && - (font.GetFontSize() >= min_font_size)) - break; - DCHECK_GT(derived_font.GetFontSize(), font.GetFontSize()); - font = derived_font; - } - return font; + return DeriveWithCorrectedSize(hfont); } //////////////////////////////////////////////////////////////////////////////// @@ -435,6 +423,37 @@ PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRefFromGDI( ave_char_width, style); } +Font PlatformFontWin::DeriveWithCorrectedSize(HFONT base_font) { + base::win::ScopedGetDC screen_dc(NULL); + gfx::ScopedSetMapMode mode(screen_dc, MM_TEXT); + + base::win::ScopedGDIObject<HFONT> best_font(base_font); + TEXTMETRIC best_font_metrics; + GetTextMetricsForFont(screen_dc, best_font, &best_font_metrics); + + LOGFONT font_info; + GetObject(base_font, sizeof(LOGFONT), &font_info); + + // Set |lfHeight| to negative value to indicate it's the size, not the height. + font_info.lfHeight = + -(best_font_metrics.tmHeight - best_font_metrics.tmInternalLeading); + + do { + // Increment font size. Prefer font with greater size if its height isn't + // greater than height of base font. + font_info.lfHeight = AdjustFontSize(font_info.lfHeight, 1); + base::win::ScopedGDIObject<HFONT> font(CreateFontIndirect(&font_info)); + TEXTMETRIC font_metrics; + GetTextMetricsForFont(screen_dc, font, &font_metrics); + if (font_metrics.tmHeight > best_font_metrics.tmHeight) + break; + best_font.Set(font.release()); + best_font_metrics = font_metrics; + } while (true); + + return Font(new PlatformFontWin(CreateHFontRef(best_font.release()))); +} + // static PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRefFromSkia( HFONT gdi_font, @@ -499,7 +518,8 @@ PlatformFontWin::HFontRef* PlatformFontWin::CreateHFontRefFromSkia( // The calculations below are similar to those in the CreateHFontRef // function. The height, baseline and cap height are rounded up to ensure // that they match up closely with GDI. - const int height = std::ceil(skia_metrics.fDescent - skia_metrics.fAscent); + const int height = std::ceil( + skia_metrics.fDescent - skia_metrics.fAscent + skia_metrics.fLeading); const int baseline = std::max<int>(1, std::ceil(-skia_metrics.fAscent)); const int cap_height = std::ceil(paint.getTextSize() * static_cast<double>(dwrite_font_metrics.capHeight) / diff --git a/ui/gfx/platform_font_win.h b/ui/gfx/platform_font_win.h index 6f7bc21..11f94d4 100644 --- a/ui/gfx/platform_font_win.h +++ b/ui/gfx/platform_font_win.h @@ -49,10 +49,11 @@ class GFX_EXPORT PlatformFontWin : public PlatformFont { // name could not be retrieved, returns GetFontName(). std::string GetLocalizedFontName() const; - // Returns a derived Font with the specified |style| and maximum |height|. - // The returned Font will be the largest font size with a height <= |height|, - // since a size with the exact specified |height| may not necessarily exist. - // GetMinimumFontSize() may impose a font size that is taller than |height|. + // Returns a derived Font with the specified |style| and with height at most + // |height|. If the height and style of the receiver already match, it is + // returned. Otherwise, the returned Font will have the largest size such that + // its height is less than or equal to |height| (since there may not exist a + // size that matches the exact |height| specified). Font DeriveFontWithHeight(int height, int style); // Overridden from PlatformFont: @@ -171,6 +172,10 @@ class GFX_EXPORT PlatformFontWin : public PlatformFont { static HFontRef* CreateHFontRefFromGDI(HFONT font, const TEXTMETRIC& font_metrics); + // Returns a largest derived Font whose height does not exceed the height of + // |base_font|. + static Font DeriveWithCorrectedSize(HFONT base_font); + // Creates and returns a new HFontRef from the specified HFONT using metrics // from skia. Currently this is only used if we use DirectWrite for font // metrics. diff --git a/ui/gfx/platform_font_win_unittest.cc b/ui/gfx/platform_font_win_unittest.cc index c582a32..dc4ac5e 100644 --- a/ui/gfx/platform_font_win_unittest.cc +++ b/ui/gfx/platform_font_win_unittest.cc @@ -17,32 +17,72 @@ namespace gfx { +namespace { + +// Returns a font based on |base_font| with height at most |target_height| and +// font size maximized. Returns |base_font| if height is already equal. +gfx::Font AdjustFontSizeForHeight(const gfx::Font& base_font, + int target_height) { + Font expected_font = base_font; + if (base_font.GetHeight() < target_height) { + // Increase size while height is <= |target_height|. + Font larger_font = base_font.Derive(1, 0); + while (larger_font.GetHeight() <= target_height) { + expected_font = larger_font; + larger_font = larger_font.Derive(1, 0); + } + } else if (expected_font.GetHeight() > target_height) { + // Decrease size until height is <= |target_height|. + do { + expected_font = expected_font.Derive(-1, 0); + } while (expected_font.GetHeight() > target_height); + } + return expected_font; +} + +} // namespace + TEST(PlatformFontWinTest, DeriveFontWithHeight) { + // TODO(ananta): Fix this test for DirectWrite. http://crbug.com/442010 + if (gfx::win::IsDirectWriteEnabled()) + return; + const Font base_font; PlatformFontWin* platform_font = static_cast<PlatformFontWin*>(base_font.platform_font()); for (int i = -10; i < 10; i++) { const int target_height = base_font.GetHeight() + i; + Font expected_font = AdjustFontSizeForHeight(base_font, target_height); + ASSERT_LE(expected_font.GetHeight(), target_height); Font derived_font = platform_font->DeriveFontWithHeight(target_height, 0); - EXPECT_LE(derived_font.GetHeight(), target_height); - EXPECT_GT(derived_font.Derive(1, 0).GetHeight(), target_height); - EXPECT_EQ(platform_font->GetActualFontNameForTesting(), - derived_font.GetActualFontNameForTesting()); + EXPECT_EQ(expected_font.GetFontName(), derived_font.GetFontName()); + EXPECT_EQ(expected_font.GetFontSize(), derived_font.GetFontSize()); + EXPECT_LE(expected_font.GetHeight(), target_height); EXPECT_EQ(0, derived_font.GetStyle()); derived_font = platform_font->DeriveFontWithHeight(target_height, Font::BOLD); - EXPECT_LE(derived_font.GetHeight(), target_height); - EXPECT_GT(derived_font.Derive(1, 0).GetHeight(), target_height); - EXPECT_EQ(platform_font->GetActualFontNameForTesting(), - derived_font.GetActualFontNameForTesting()); + EXPECT_EQ(expected_font.GetFontName(), derived_font.GetFontName()); + EXPECT_EQ(expected_font.GetFontSize(), derived_font.GetFontSize()); + EXPECT_LE(expected_font.GetHeight(), target_height); EXPECT_EQ(Font::BOLD, derived_font.GetStyle()); + + // Test that deriving from the new font has the expected result. + Font rederived_font = derived_font.Derive(1, 0); + expected_font = Font(derived_font.GetFontName(), + derived_font.GetFontSize() + 1); + EXPECT_EQ(expected_font.GetFontName(), rederived_font.GetFontName()); + EXPECT_EQ(expected_font.GetFontSize(), rederived_font.GetFontSize()); + EXPECT_EQ(expected_font.GetHeight(), rederived_font.GetHeight()); } } TEST(PlatformFontWinTest, DeriveFontWithHeight_Consistency) { + // TODO(ananta): Fix this test for DirectWrite. http://crbug.com/442010 + if (gfx::win::IsDirectWriteEnabled()) + return; gfx::Font arial_12("Arial", 12); ASSERT_GT(16, arial_12.GetHeight()); gfx::Font derived_1 = static_cast<PlatformFontWin*>( @@ -157,4 +197,5 @@ TEST(PlatformFontWinTest, Metrics_SkiaVersusGDI) { } } + } // namespace gfx |