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.
5 #include "ui/gfx/font_list.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_util.h"
13 #include "testing/gtest/include/gtest/gtest.h"
17 // Helper function for comparing fonts for equality.
18 std::string
FontToString(const gfx::Font
& font
) {
19 std::string font_string
= font
.GetFontName();
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";
36 TEST(FontListTest
, ParseDescription
) {
37 std::vector
<std::string
> families
;
38 int style
= gfx::Font::NORMAL
;
41 // Parse a well-formed description containing styles and a size.
42 EXPECT_TRUE(FontList::ParseDescription("Arial,Helvetica,Bold Italic 12px",
43 &families
, &style
, &size_pixels
));
44 ASSERT_EQ(2U, families
.size());
45 EXPECT_EQ("Arial", families
[0]);
46 EXPECT_EQ("Helvetica", families
[1]);
47 EXPECT_EQ(gfx::Font::BOLD
| gfx::Font::ITALIC
, style
);
48 EXPECT_EQ(12, size_pixels
);
50 // Whitespace should be removed.
51 EXPECT_TRUE(FontList::ParseDescription(" Verdana , Italic Bold 10px ",
52 &families
, &style
, &size_pixels
));
53 ASSERT_EQ(1U, families
.size());
54 EXPECT_EQ("Verdana", families
[0]);
55 EXPECT_EQ(gfx::Font::BOLD
| gfx::Font::ITALIC
, style
);
56 EXPECT_EQ(10, size_pixels
);
58 // Invalid descriptions should be rejected.
59 EXPECT_FALSE(FontList::ParseDescription("", &families
, &style
, &size_pixels
));
60 EXPECT_FALSE(FontList::ParseDescription("Arial", &families
, &style
,
62 EXPECT_FALSE(FontList::ParseDescription("Arial,12", &families
, &style
,
64 EXPECT_FALSE(FontList::ParseDescription("Arial 12px", &families
, &style
,
66 EXPECT_FALSE(FontList::ParseDescription("Arial,12px,", &families
, &style
,
68 EXPECT_FALSE(FontList::ParseDescription("Arial,0px", &families
, &style
,
70 EXPECT_FALSE(FontList::ParseDescription("Arial,-1px", &families
, &style
,
72 EXPECT_FALSE(FontList::ParseDescription("Arial,foo 12px", &families
, &style
,
76 TEST(FontListTest
, Fonts_FromDescString
) {
77 // Test init from font name size string.
78 FontList font_list
= FontList("arial, Courier New, 13px");
79 const std::vector
<Font
>& fonts
= font_list
.GetFonts();
80 ASSERT_EQ(2U, fonts
.size());
81 EXPECT_EQ("arial|13", FontToString(fonts
[0]));
82 EXPECT_EQ("Courier New|13", FontToString(fonts
[1]));
85 TEST(FontListTest
, Fonts_FromDescStringInFlexibleFormat
) {
86 // Test init from font name size string with flexible format.
87 FontList font_list
= FontList(" arial , Courier New , 13px");
88 const std::vector
<Font
>& fonts
= font_list
.GetFonts();
89 ASSERT_EQ(2U, fonts
.size());
90 EXPECT_EQ("arial|13", FontToString(fonts
[0]));
91 EXPECT_EQ("Courier New|13", FontToString(fonts
[1]));
94 TEST(FontListTest
, Fonts_FromDescStringWithStyleInFlexibleFormat
) {
95 // Test init from font name style size string with flexible format.
96 FontList font_list
= FontList(" arial , Courier New , Bold "
98 const std::vector
<Font
>& fonts
= font_list
.GetFonts();
99 ASSERT_EQ(2U, fonts
.size());
100 EXPECT_EQ("arial|13|bold|italic", FontToString(fonts
[0]));
101 EXPECT_EQ("Courier New|13|bold|italic", FontToString(fonts
[1]));
104 TEST(FontListTest
, Fonts_FromFont
) {
105 // Test init from Font.
106 Font
font("Arial", 8);
107 FontList font_list
= FontList(font
);
108 const std::vector
<Font
>& fonts
= font_list
.GetFonts();
109 ASSERT_EQ(1U, fonts
.size());
110 EXPECT_EQ("Arial|8", FontToString(fonts
[0]));
113 TEST(FontListTest
, Fonts_FromFontWithNonNormalStyle
) {
114 // Test init from Font with non-normal style.
115 Font
font("Arial", 8);
116 FontList font_list
= FontList(font
.Derive(2, Font::BOLD
));
117 std::vector
<Font
> fonts
= font_list
.GetFonts();
118 ASSERT_EQ(1U, fonts
.size());
119 EXPECT_EQ("Arial|10|bold", FontToString(fonts
[0]));
121 font_list
= FontList(font
.Derive(-2, Font::ITALIC
));
122 fonts
= font_list
.GetFonts();
123 ASSERT_EQ(1U, fonts
.size());
124 EXPECT_EQ("Arial|6|italic", FontToString(fonts
[0]));
127 TEST(FontListTest
, Fonts_FromFontVector
) {
128 // Test init from Font vector.
129 Font
font("Arial", 8);
130 Font
font_1("Courier New", 10);
131 std::vector
<Font
> input_fonts
;
132 input_fonts
.push_back(font
.Derive(0, Font::BOLD
));
133 input_fonts
.push_back(font_1
.Derive(-2, Font::BOLD
));
134 FontList font_list
= FontList(input_fonts
);
135 const std::vector
<Font
>& fonts
= font_list
.GetFonts();
136 ASSERT_EQ(2U, fonts
.size());
137 EXPECT_EQ("Arial|8|bold", FontToString(fonts
[0]));
138 EXPECT_EQ("Courier New|8|bold", FontToString(fonts
[1]));
141 TEST(FontListTest
, FontDescString_GetStyle
) {
142 FontList font_list
= FontList("Arial,Sans serif, 8px");
143 EXPECT_EQ(Font::NORMAL
, font_list
.GetFontStyle());
145 font_list
= FontList("Arial,Sans serif,Bold 8px");
146 EXPECT_EQ(Font::BOLD
, font_list
.GetFontStyle());
148 font_list
= FontList("Arial,Sans serif,Italic 8px");
149 EXPECT_EQ(Font::ITALIC
, font_list
.GetFontStyle());
151 font_list
= FontList("Arial,Italic Bold 8px");
152 EXPECT_EQ(Font::BOLD
| Font::ITALIC
, font_list
.GetFontStyle());
155 TEST(FontListTest
, Fonts_GetStyle
) {
156 std::vector
<Font
> fonts
;
157 fonts
.push_back(gfx::Font("Arial", 8));
158 fonts
.push_back(gfx::Font("Sans serif", 8));
159 FontList font_list
= FontList(fonts
);
160 EXPECT_EQ(Font::NORMAL
, font_list
.GetFontStyle());
161 fonts
[0] = fonts
[0].Derive(0, Font::ITALIC
| Font::BOLD
);
162 fonts
[1] = fonts
[1].Derive(0, Font::ITALIC
| Font::BOLD
);
163 font_list
= FontList(fonts
);
164 EXPECT_EQ(Font::ITALIC
| Font::BOLD
, font_list
.GetFontStyle());
167 TEST(FontListTest
, Fonts_Derive
) {
168 std::vector
<Font
> fonts
;
169 fonts
.push_back(gfx::Font("Arial", 8));
170 fonts
.push_back(gfx::Font("Courier New", 8));
171 FontList font_list
= FontList(fonts
);
173 FontList derived
= font_list
.Derive(5, Font::BOLD
| Font::UNDERLINE
);
174 const std::vector
<Font
>& derived_fonts
= derived
.GetFonts();
176 EXPECT_EQ(2U, derived_fonts
.size());
177 EXPECT_EQ("Arial|13|bold|underline", FontToString(derived_fonts
[0]));
178 EXPECT_EQ("Courier New|13|bold|underline", FontToString(derived_fonts
[1]));
181 TEST(FontListTest
, Fonts_DeriveWithSizeDelta
) {
182 std::vector
<Font
> fonts
;
183 fonts
.push_back(gfx::Font("Arial", 18).Derive(0, Font::ITALIC
));
184 fonts
.push_back(gfx::Font("Courier New", 18).Derive(0, Font::ITALIC
));
185 FontList font_list
= FontList(fonts
);
187 FontList derived
= font_list
.DeriveWithSizeDelta(-5);
188 const std::vector
<Font
>& derived_fonts
= derived
.GetFonts();
190 EXPECT_EQ(2U, derived_fonts
.size());
191 EXPECT_EQ("Arial|13|italic", FontToString(derived_fonts
[0]));
192 EXPECT_EQ("Courier New|13|italic", FontToString(derived_fonts
[1]));
195 TEST(FontListTest
, Fonts_GetHeight_GetBaseline
) {
196 // If a font list has only one font, the height and baseline must be the same.
197 Font
font1("Arial", 16);
199 base::StringToLowerASCII(font1
.GetActualFontNameForTesting()));
200 FontList
font_list1("Arial, 16px");
201 EXPECT_EQ(font1
.GetHeight(), font_list1
.GetHeight());
202 EXPECT_EQ(font1
.GetBaseline(), font_list1
.GetBaseline());
204 // If there are two different fonts, the font list returns the max value
205 // for the baseline (ascent) and height.
206 Font
font2("Symbol", 16);
208 base::StringToLowerASCII(font2
.GetActualFontNameForTesting()));
209 EXPECT_NE(font1
.GetBaseline(), font2
.GetBaseline());
210 // TODO(ananta): Find a size and font pair with reliably distinct descents.
211 EXPECT_NE(font1
.GetHeight(), font2
.GetHeight());
212 std::vector
<Font
> fonts
;
213 fonts
.push_back(font1
);
214 fonts
.push_back(font2
);
215 FontList
font_list_mix(fonts
);
216 // ascent of FontList == max(ascent of Fonts)
217 EXPECT_EQ(std::max(font1
.GetBaseline(), font2
.GetBaseline()),
218 font_list_mix
.GetBaseline());
219 // descent of FontList == max(descent of Fonts)
220 EXPECT_EQ(std::max(font1
.GetHeight() - font1
.GetBaseline(),
221 font2
.GetHeight() - font2
.GetBaseline()),
222 font_list_mix
.GetHeight() - font_list_mix
.GetBaseline());
225 TEST(FontListTest
, Fonts_DeriveWithHeightUpperBound
) {
226 std::vector
<Font
> fonts
;
228 fonts
.push_back(gfx::Font("Arial", 18));
229 fonts
.push_back(gfx::Font("Sans serif", 18));
230 fonts
.push_back(gfx::Font("Symbol", 18));
231 FontList font_list
= FontList(fonts
);
233 // A smaller upper bound should derive a font list with a smaller height.
234 const int height_1
= font_list
.GetHeight() - 5;
235 FontList derived_1
= font_list
.DeriveWithHeightUpperBound(height_1
);
236 EXPECT_LE(derived_1
.GetHeight(), height_1
);
237 EXPECT_LT(derived_1
.GetHeight(), font_list
.GetHeight());
238 EXPECT_LT(derived_1
.GetFontSize(), font_list
.GetFontSize());
240 // A larger upper bound should not change the height of the font list.
241 const int height_2
= font_list
.GetHeight() + 5;
242 FontList derived_2
= font_list
.DeriveWithHeightUpperBound(height_2
);
243 EXPECT_LE(derived_2
.GetHeight(), height_2
);
244 EXPECT_EQ(font_list
.GetHeight(), derived_2
.GetHeight());
245 EXPECT_EQ(font_list
.GetFontSize(), derived_2
.GetFontSize());