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_list.h" 6 7 #include <algorithm> 8 #include <string> 9 #include <vector> 10 11 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_util.h" 13 #include "testing/gtest/include/gtest/gtest.h" 14 15 namespace { 16 17 // Helper function for comparing fonts for equality. 18 std::string FontToString(const gfx::Font& font) { 19 std::string font_string = font.GetFontName(); 20 font_string += "|"; 21 font_string += base::IntToString(font.GetFontSize()); 22 int style = font.GetStyle(); 23 if (style & gfx::Font::BOLD) 24 font_string += "|bold"; 25 if (style & gfx::Font::ITALIC) 26 font_string += "|italic"; 27 if (style & gfx::Font::UNDERLINE) 28 font_string += "|underline"; 29 return font_string; 30 } 31 32 } // namespace 33 34 namespace gfx { 35 36 TEST(FontListTest, FontDescString_FromDescString) { 37 // Test init from font name style size string. 38 FontList font_list = FontList("Droid Sans serif, Sans serif, 10px"); 39 EXPECT_EQ("Droid Sans serif, Sans serif, 10px", 40 font_list.GetFontDescriptionString()); 41 } 42 43 TEST(FontListTest, FontDescString_FromFontNamesStyleAndSize) { 44 // Test init from font names, style and size. 45 std::vector<std::string> font_names; 46 font_names.push_back("Arial"); 47 font_names.push_back("Droid Sans serif"); 48 int font_style = Font::BOLD | Font::ITALIC | Font::UNDERLINE; 49 int font_size = 11; 50 FontList font_list = FontList(font_names, font_style, font_size); 51 // "Underline" doesn't appear in the font description string. 52 EXPECT_EQ("Arial,Droid Sans serif,Bold Italic 11px", 53 font_list.GetFontDescriptionString()); 54 } 55 56 TEST(FontListTest, FontDescString_FromFont) { 57 // Test init from Font. 58 Font font("Arial", 8); 59 FontList font_list = FontList(font); 60 EXPECT_EQ("Arial,8px", font_list.GetFontDescriptionString()); 61 } 62 63 TEST(FontListTest, FontDescString_FromFontWithNonNormalStyle) { 64 // Test init from Font with non-normal style. 65 Font font("Arial", 8); 66 FontList font_list = FontList(font.Derive(2, Font::BOLD)); 67 EXPECT_EQ("Arial,Bold 10px", font_list.GetFontDescriptionString()); 68 69 font_list = FontList(font.Derive(-2, Font::ITALIC)); 70 EXPECT_EQ("Arial,Italic 6px", font_list.GetFontDescriptionString()); 71 72 // "Underline" doesn't appear in the font description string. 73 font_list = FontList(font.Derive(-4, Font::UNDERLINE)); 74 EXPECT_EQ("Arial,4px", font_list.GetFontDescriptionString()); 75 } 76 77 TEST(FontListTest, FontDescString_FromFontVector) { 78 // Test init from Font vector. 79 Font font("Arial", 8); 80 Font font_1("Sans serif", 10); 81 std::vector<Font> fonts; 82 fonts.push_back(font.Derive(0, Font::BOLD)); 83 fonts.push_back(font_1.Derive(-2, Font::BOLD)); 84 FontList font_list = FontList(fonts); 85 EXPECT_EQ("Arial,Sans serif,Bold 8px", font_list.GetFontDescriptionString()); 86 } 87 88 TEST(FontListTest, Fonts_FromDescString) { 89 // Test init from font name size string. 90 FontList font_list = FontList("serif,Sans serif, 13px"); 91 const std::vector<Font>& fonts = font_list.GetFonts(); 92 EXPECT_EQ(2U, fonts.size()); 93 EXPECT_EQ("serif|13", FontToString(fonts[0])); 94 EXPECT_EQ("Sans serif|13", FontToString(fonts[1])); 95 } 96 97 TEST(FontListTest, Fonts_FromDescStringInFlexibleFormat) { 98 // Test init from font name size string with flexible format. 99 FontList font_list = FontList(" serif , Sans serif , 13px"); 100 const std::vector<Font>& fonts = font_list.GetFonts(); 101 EXPECT_EQ(2U, fonts.size()); 102 EXPECT_EQ("serif|13", FontToString(fonts[0])); 103 EXPECT_EQ("Sans serif|13", FontToString(fonts[1])); 104 } 105 106 TEST(FontListTest, Fonts_FromDescStringWithStyleInFlexibleFormat) { 107 // Test init from font name style size string with flexible format. 108 FontList font_list = FontList(" serif , Sans serif , Bold " 109 " Italic 13px"); 110 const std::vector<Font>& fonts = font_list.GetFonts(); 111 EXPECT_EQ(2U, fonts.size()); 112 EXPECT_EQ("serif|13|bold|italic", FontToString(fonts[0])); 113 EXPECT_EQ("Sans serif|13|bold|italic", FontToString(fonts[1])); 114 } 115 116 TEST(FontListTest, Fonts_FromFont) { 117 // Test init from Font. 118 Font font("Arial", 8); 119 FontList font_list = FontList(font); 120 const std::vector<Font>& fonts = font_list.GetFonts(); 121 EXPECT_EQ(1U, fonts.size()); 122 EXPECT_EQ("Arial|8", FontToString(fonts[0])); 123 } 124 125 TEST(FontListTest, Fonts_FromFontWithNonNormalStyle) { 126 // Test init from Font with non-normal style. 127 Font font("Arial", 8); 128 FontList font_list = FontList(font.Derive(2, Font::BOLD)); 129 std::vector<Font> fonts = font_list.GetFonts(); 130 EXPECT_EQ(1U, fonts.size()); 131 EXPECT_EQ("Arial|10|bold", FontToString(fonts[0])); 132 133 font_list = FontList(font.Derive(-2, Font::ITALIC)); 134 fonts = font_list.GetFonts(); 135 EXPECT_EQ(1U, fonts.size()); 136 EXPECT_EQ("Arial|6|italic", FontToString(fonts[0])); 137 } 138 139 TEST(FontListTest, Fonts_FromFontVector) { 140 // Test init from Font vector. 141 Font font("Arial", 8); 142 Font font_1("Sans serif", 10); 143 std::vector<Font> input_fonts; 144 input_fonts.push_back(font.Derive(0, Font::BOLD)); 145 input_fonts.push_back(font_1.Derive(-2, Font::BOLD)); 146 FontList font_list = FontList(input_fonts); 147 const std::vector<Font>& fonts = font_list.GetFonts(); 148 EXPECT_EQ(2U, fonts.size()); 149 EXPECT_EQ("Arial|8|bold", FontToString(fonts[0])); 150 EXPECT_EQ("Sans serif|8|bold", FontToString(fonts[1])); 151 } 152 153 TEST(FontListTest, Fonts_DescStringWithStyleInFlexibleFormat_RoundTrip) { 154 // Test round trip from font description string to font vector to 155 // font description string. 156 FontList font_list = FontList(" serif , Sans serif , Bold " 157 " Italic 13px"); 158 159 const std::vector<Font>& fonts = font_list.GetFonts(); 160 FontList font_list_1 = FontList(fonts); 161 const std::string& desc_str = font_list_1.GetFontDescriptionString(); 162 163 EXPECT_EQ("serif,Sans serif,Bold Italic 13px", desc_str); 164 } 165 166 TEST(FontListTest, Fonts_FontVector_RoundTrip) { 167 // Test round trip from font vector to font description string to font vector. 168 Font font("Arial", 8); 169 Font font_1("Sans serif", 10); 170 std::vector<Font> input_fonts; 171 input_fonts.push_back(font.Derive(0, Font::BOLD)); 172 input_fonts.push_back(font_1.Derive(-2, Font::BOLD)); 173 FontList font_list = FontList(input_fonts); 174 175 const std::string& desc_string = font_list.GetFontDescriptionString(); 176 FontList font_list_1 = FontList(desc_string); 177 const std::vector<Font>& round_trip_fonts = font_list_1.GetFonts(); 178 179 EXPECT_EQ(2U, round_trip_fonts.size()); 180 EXPECT_EQ("Arial|8|bold", FontToString(round_trip_fonts[0])); 181 EXPECT_EQ("Sans serif|8|bold", FontToString(round_trip_fonts[1])); 182 } 183 184 TEST(FontListTest, FontDescString_GetStyle) { 185 FontList font_list = FontList("Arial,Sans serif, 8px"); 186 EXPECT_EQ(Font::NORMAL, font_list.GetFontStyle()); 187 188 font_list = FontList("Arial,Sans serif,Bold 8px"); 189 EXPECT_EQ(Font::BOLD, font_list.GetFontStyle()); 190 191 font_list = FontList("Arial,Sans serif,Italic 8px"); 192 EXPECT_EQ(Font::ITALIC, font_list.GetFontStyle()); 193 194 font_list = FontList("Arial,Italic Bold 8px"); 195 EXPECT_EQ(Font::BOLD | Font::ITALIC, font_list.GetFontStyle()); 196 } 197 198 TEST(FontListTest, Fonts_GetStyle) { 199 std::vector<Font> fonts; 200 fonts.push_back(gfx::Font("Arial", 8)); 201 fonts.push_back(gfx::Font("Sans serif", 8)); 202 FontList font_list = FontList(fonts); 203 EXPECT_EQ(Font::NORMAL, font_list.GetFontStyle()); 204 fonts[0] = fonts[0].Derive(0, Font::ITALIC | Font::BOLD); 205 fonts[1] = fonts[1].Derive(0, Font::ITALIC | Font::BOLD); 206 font_list = FontList(fonts); 207 EXPECT_EQ(Font::ITALIC | Font::BOLD, font_list.GetFontStyle()); 208 } 209 210 TEST(FontListTest, FontDescString_Derive) { 211 FontList font_list = FontList("Arial,Sans serif,Bold Italic 8px"); 212 213 FontList derived = font_list.Derive(10, Font::ITALIC | Font::UNDERLINE); 214 EXPECT_EQ("Arial,Sans serif,Italic 18px", derived.GetFontDescriptionString()); 215 EXPECT_EQ(Font::ITALIC | Font::UNDERLINE, derived.GetFontStyle()); 216 217 // FontList has a special case for Font::UNDERLINE. See if the handling of 218 // Font::UNDERLINE in GetFonts() is okay or not. 219 derived.GetFonts(); 220 EXPECT_EQ(Font::ITALIC | Font::UNDERLINE, derived.GetFontStyle()); 221 } 222 223 TEST(FontListTest, Fonts_Derive) { 224 std::vector<Font> fonts; 225 fonts.push_back(gfx::Font("Arial", 8)); 226 fonts.push_back(gfx::Font("Sans serif", 8)); 227 FontList font_list = FontList(fonts); 228 229 FontList derived = font_list.Derive(5, Font::BOLD | Font::UNDERLINE); 230 const std::vector<Font>& derived_fonts = derived.GetFonts(); 231 232 EXPECT_EQ(2U, derived_fonts.size()); 233 EXPECT_EQ("Arial|13|bold|underline", FontToString(derived_fonts[0])); 234 EXPECT_EQ("Sans serif|13|bold|underline", FontToString(derived_fonts[1])); 235 } 236 237 TEST(FontListTest, FontDescString_DeriveWithSizeDelta) { 238 FontList font_list = FontList("Arial,Sans serif,Bold 18px"); 239 240 FontList derived = font_list.DeriveWithSizeDelta(-8); 241 EXPECT_EQ("Arial,Sans serif,Bold 10px", 242 derived.GetFontDescriptionString()); 243 } 244 245 TEST(FontListTest, Fonts_DeriveWithSizeDelta) { 246 std::vector<Font> fonts; 247 fonts.push_back(gfx::Font("Arial", 18).Derive(0, Font::ITALIC)); 248 fonts.push_back(gfx::Font("Sans serif", 18).Derive(0, Font::ITALIC)); 249 FontList font_list = FontList(fonts); 250 251 FontList derived = font_list.DeriveWithSizeDelta(-5); 252 const std::vector<Font>& derived_fonts = derived.GetFonts(); 253 254 EXPECT_EQ(2U, derived_fonts.size()); 255 EXPECT_EQ("Arial|13|italic", FontToString(derived_fonts[0])); 256 EXPECT_EQ("Sans serif|13|italic", FontToString(derived_fonts[1])); 257 } 258 259 TEST(FontListTest, Fonts_GetHeight_GetBaseline) { 260 // If a font list has only one font, the height and baseline must be the same. 261 Font font1("Arial", 16); 262 ASSERT_EQ("arial", 263 base::StringToLowerASCII(font1.GetActualFontNameForTesting())); 264 FontList font_list1("Arial, 16px"); 265 EXPECT_EQ(font1.GetHeight(), font_list1.GetHeight()); 266 EXPECT_EQ(font1.GetBaseline(), font_list1.GetBaseline()); 267 268 // If there are two different fonts, the font list returns the max value 269 // for ascent and descent. 270 Font font2("Symbol", 16); 271 ASSERT_EQ("symbol", 272 base::StringToLowerASCII(font2.GetActualFontNameForTesting())); 273 EXPECT_NE(font1.GetBaseline(), font2.GetBaseline()); 274 EXPECT_NE(font1.GetHeight() - font1.GetBaseline(), 275 font2.GetHeight() - font2.GetBaseline()); 276 std::vector<Font> fonts; 277 fonts.push_back(font1); 278 fonts.push_back(font2); 279 FontList font_list_mix(fonts); 280 // ascent of FontList == max(ascent of Fonts) 281 EXPECT_EQ(std::max(font1.GetHeight() - font1.GetBaseline(), 282 font2.GetHeight() - font2.GetBaseline()), 283 font_list_mix.GetHeight() - font_list_mix.GetBaseline()); 284 // descent of FontList == max(descent of Fonts) 285 EXPECT_EQ(std::max(font1.GetBaseline(), font2.GetBaseline()), 286 font_list_mix.GetBaseline()); 287 } 288 289 TEST(FontListTest, Fonts_DeriveWithHeightUpperBound) { 290 std::vector<Font> fonts; 291 292 fonts.push_back(gfx::Font("Arial", 18)); 293 fonts.push_back(gfx::Font("Sans serif", 18)); 294 fonts.push_back(gfx::Font("Symbol", 18)); 295 FontList font_list = FontList(fonts); 296 297 // A smaller upper bound should derive a font list with a smaller height. 298 const int height_1 = font_list.GetHeight() - 5; 299 FontList derived_1 = font_list.DeriveWithHeightUpperBound(height_1); 300 EXPECT_LE(derived_1.GetHeight(), height_1); 301 EXPECT_LT(derived_1.GetHeight(), font_list.GetHeight()); 302 EXPECT_LT(derived_1.GetFontSize(), font_list.GetFontSize()); 303 304 // A larger upper bound should not change the height of the font list. 305 const int height_2 = font_list.GetHeight() + 5; 306 FontList derived_2 = font_list.DeriveWithHeightUpperBound(height_2); 307 EXPECT_LE(derived_2.GetHeight(), height_2); 308 EXPECT_EQ(font_list.GetHeight(), derived_2.GetHeight()); 309 EXPECT_EQ(font_list.GetFontSize(), derived_2.GetFontSize()); 310 } 311 312 } // namespace gfx 313