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 3 // found in the LICENSE file. 4 5 #include "ui/gfx/font.h" 6 7 #include "base/strings/string16.h" 8 #include "base/strings/string_util.h" 9 #include "base/strings/utf_string_conversions.h" 10 #include "testing/gtest/include/gtest/gtest.h" 11 12 #if defined(OS_LINUX) && !defined(USE_OZONE) 13 #include <pango/pango.h> 14 #elif defined(OS_WIN) 15 #include "ui/gfx/platform_font_win.h" 16 #endif 17 18 namespace gfx { 19 namespace { 20 21 class FontTest : public testing::Test { 22 public: 23 // Fulfills the memory management contract as outlined by the comment at 24 // gfx::Font::GetNativeFont(). 25 void FreeIfNecessary(NativeFont font) { 26 #if defined(OS_LINUX) && !defined(USE_OZONE) 27 pango_font_description_free(font); 28 #endif 29 } 30 }; 31 32 #if defined(OS_WIN) 33 class ScopedMinimumFontSizeCallback { 34 public: 35 explicit ScopedMinimumFontSizeCallback(int minimum_size) { 36 minimum_size_ = minimum_size; 37 old_callback_ = PlatformFontWin::get_minimum_font_size_callback; 38 PlatformFontWin::get_minimum_font_size_callback = &GetMinimumFontSize; 39 } 40 41 ~ScopedMinimumFontSizeCallback() { 42 PlatformFontWin::get_minimum_font_size_callback = old_callback_; 43 } 44 45 private: 46 static int GetMinimumFontSize() { 47 return minimum_size_; 48 } 49 50 PlatformFontWin::GetMinimumFontSizeCallback old_callback_; 51 static int minimum_size_; 52 53 DISALLOW_COPY_AND_ASSIGN(ScopedMinimumFontSizeCallback); 54 }; 55 56 int ScopedMinimumFontSizeCallback::minimum_size_ = 0; 57 #endif // defined(OS_WIN) 58 59 60 TEST_F(FontTest, LoadArial) { 61 Font cf("Arial", 16); 62 NativeFont native = cf.GetNativeFont(); 63 EXPECT_TRUE(native); 64 EXPECT_EQ(cf.GetStyle(), Font::NORMAL); 65 EXPECT_EQ(cf.GetFontSize(), 16); 66 EXPECT_EQ(cf.GetFontName(), "Arial"); 67 EXPECT_EQ("arial", StringToLowerASCII(cf.GetActualFontNameForTesting())); 68 FreeIfNecessary(native); 69 } 70 71 TEST_F(FontTest, LoadArialBold) { 72 Font cf("Arial", 16); 73 Font bold(cf.DeriveFont(0, Font::BOLD)); 74 NativeFont native = bold.GetNativeFont(); 75 EXPECT_TRUE(native); 76 EXPECT_EQ(bold.GetStyle(), Font::BOLD); 77 EXPECT_EQ("arial", StringToLowerASCII(cf.GetActualFontNameForTesting())); 78 FreeIfNecessary(native); 79 } 80 81 TEST_F(FontTest, Ascent) { 82 Font cf("Arial", 16); 83 EXPECT_GT(cf.GetBaseline(), 2); 84 EXPECT_LE(cf.GetBaseline(), 22); 85 } 86 87 TEST_F(FontTest, Height) { 88 Font cf("Arial", 16); 89 EXPECT_GE(cf.GetHeight(), 16); 90 // TODO(akalin): Figure out why height is so large on Linux. 91 EXPECT_LE(cf.GetHeight(), 26); 92 } 93 94 TEST_F(FontTest, CapHeight) { 95 Font cf("Arial", 16); 96 EXPECT_GT(cf.GetCapHeight(), 0); 97 EXPECT_GT(cf.GetCapHeight(), cf.GetHeight() / 2); 98 #if defined(OS_CHROMEOS) || defined(OS_LINUX) 99 EXPECT_EQ(cf.GetCapHeight(), cf.GetBaseline()); 100 #else 101 EXPECT_LT(cf.GetCapHeight(), cf.GetBaseline()); 102 #endif 103 } 104 105 TEST_F(FontTest, AvgWidths) { 106 Font cf("Arial", 16); 107 EXPECT_EQ(cf.GetExpectedTextWidth(0), 0); 108 EXPECT_GT(cf.GetExpectedTextWidth(1), cf.GetExpectedTextWidth(0)); 109 EXPECT_GT(cf.GetExpectedTextWidth(2), cf.GetExpectedTextWidth(1)); 110 EXPECT_GT(cf.GetExpectedTextWidth(3), cf.GetExpectedTextWidth(2)); 111 } 112 113 TEST_F(FontTest, AvgCharWidth) { 114 Font cf("Arial", 16); 115 EXPECT_GT(cf.GetAverageCharacterWidth(), 0); 116 } 117 118 TEST_F(FontTest, Widths) { 119 Font cf("Arial", 16); 120 EXPECT_EQ(cf.GetStringWidth(base::string16()), 0); 121 EXPECT_GT(cf.GetStringWidth(ASCIIToUTF16("a")), 122 cf.GetStringWidth(base::string16())); 123 EXPECT_GT(cf.GetStringWidth(ASCIIToUTF16("ab")), 124 cf.GetStringWidth(ASCIIToUTF16("a"))); 125 EXPECT_GT(cf.GetStringWidth(ASCIIToUTF16("abc")), 126 cf.GetStringWidth(ASCIIToUTF16("ab"))); 127 } 128 129 #if !defined(OS_WIN) 130 // On Windows, Font::GetActualFontNameForTesting() doesn't work well for now. 131 // http://crbug.com/327287 132 TEST_F(FontTest, GetActualFontNameForTesting) { 133 Font arial("Arial", 16); 134 EXPECT_EQ("arial", StringToLowerASCII(arial.GetActualFontNameForTesting())); 135 Font symbol("Symbol", 16); 136 EXPECT_EQ("symbol", StringToLowerASCII(symbol.GetActualFontNameForTesting())); 137 138 const char* const invalid_font_name = "no_such_font_name"; 139 Font fallback_font(invalid_font_name, 16); 140 EXPECT_NE(invalid_font_name, 141 StringToLowerASCII(fallback_font.GetActualFontNameForTesting())); 142 } 143 #endif 144 145 #if defined(OS_WIN) 146 TEST_F(FontTest, DeriveFontResizesIfSizeTooSmall) { 147 Font cf("Arial", 8); 148 // The minimum font size is set to 5 in browser_main.cc. 149 ScopedMinimumFontSizeCallback minimum_size(5); 150 151 Font derived_font = cf.DeriveFont(-4); 152 EXPECT_EQ(5, derived_font.GetFontSize()); 153 } 154 155 TEST_F(FontTest, DeriveFontKeepsOriginalSizeIfHeightOk) { 156 Font cf("Arial", 8); 157 // The minimum font size is set to 5 in browser_main.cc. 158 ScopedMinimumFontSizeCallback minimum_size(5); 159 160 Font derived_font = cf.DeriveFont(-2); 161 EXPECT_EQ(6, derived_font.GetFontSize()); 162 } 163 #endif // defined(OS_WIN) 164 165 } // namespace 166 } // namespace gfx 167