font_list_unittest.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  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. #include "ui/gfx/font_list.h"
  5. #include <algorithm>
  6. #include <string>
  7. #include <vector>
  8. #include "base/strings/string_number_conversions.h"
  9. #include "base/strings/string_util.h"
  10. #include "build/build_config.h"
  11. #include "testing/gtest/include/gtest/gtest.h"
  12. #include "ui/gfx/font_names_testing.h"
  13. namespace gfx {
  14. namespace {
  15. // Helper function for comparing fonts for equality.
  16. std::string FontToString(const Font& font) {
  17. std::string font_string = font.GetFontName();
  18. font_string += "|";
  19. font_string += base::NumberToString(font.GetFontSize());
  20. int style = font.GetStyle();
  21. if (style & Font::ITALIC)
  22. font_string += "|italic";
  23. if (style & Font::UNDERLINE)
  24. font_string += "|underline";
  25. auto weight = font.GetWeight();
  26. if (weight == Font::Weight::BLACK)
  27. font_string += "|black";
  28. else if (weight == Font::Weight::BOLD)
  29. font_string += "|bold";
  30. else if (weight == Font::Weight::EXTRA_BOLD)
  31. font_string += "|extrabold";
  32. else if (weight == Font::Weight::EXTRA_LIGHT)
  33. font_string += "|extralight";
  34. else if (weight == Font::Weight::LIGHT)
  35. font_string += "|light";
  36. else if (weight == Font::Weight::MEDIUM)
  37. font_string += "|medium";
  38. else if (weight == Font::Weight::NORMAL)
  39. font_string += "|normal";
  40. else if (weight == Font::Weight::SEMIBOLD)
  41. font_string += "|semibold";
  42. else if (weight == Font::Weight::THIN)
  43. font_string += "|thin";
  44. return font_string;
  45. }
  46. } // namespace
  47. TEST(FontListTest, ParseDescription) {
  48. std::vector<std::string> families;
  49. int style = Font::NORMAL;
  50. int size_pixels = 0;
  51. Font::Weight weight = Font::Weight::NORMAL;
  52. // Parse a well-formed description containing styles and a size.
  53. EXPECT_TRUE(FontList::ParseDescription("Arial,Helvetica,Bold Italic 12px",
  54. &families, &style, &size_pixels,
  55. &weight));
  56. ASSERT_EQ(2U, families.size());
  57. EXPECT_EQ("Arial", families[0]);
  58. EXPECT_EQ("Helvetica", families[1]);
  59. EXPECT_EQ(Font::ITALIC, style);
  60. EXPECT_EQ(Font::Weight::BOLD, weight);
  61. EXPECT_EQ(12, size_pixels);
  62. // Whitespace should be removed.
  63. EXPECT_TRUE(FontList::ParseDescription(" Verdana , Italic Bold 10px ",
  64. &families, &style, &size_pixels,
  65. &weight));
  66. ASSERT_EQ(1U, families.size());
  67. EXPECT_EQ("Verdana", families[0]);
  68. EXPECT_EQ(Font::ITALIC, style);
  69. EXPECT_EQ(Font::Weight::BOLD, weight);
  70. EXPECT_EQ(10, size_pixels);
  71. // Invalid descriptions should be rejected.
  72. EXPECT_FALSE(
  73. FontList::ParseDescription("", &families, &style, &size_pixels, &weight));
  74. EXPECT_FALSE(FontList::ParseDescription("Arial", &families, &style,
  75. &size_pixels, &weight));
  76. EXPECT_FALSE(FontList::ParseDescription("Arial,12", &families, &style,
  77. &size_pixels, &weight));
  78. EXPECT_FALSE(FontList::ParseDescription("Arial 12px", &families, &style,
  79. &size_pixels, &weight));
  80. EXPECT_FALSE(FontList::ParseDescription("Arial,12px,", &families, &style,
  81. &size_pixels, &weight));
  82. EXPECT_FALSE(FontList::ParseDescription("Arial,0px", &families, &style,
  83. &size_pixels, &weight));
  84. EXPECT_FALSE(FontList::ParseDescription("Arial,-1px", &families, &style,
  85. &size_pixels, &weight));
  86. EXPECT_FALSE(FontList::ParseDescription("Arial,foo 12px", &families, &style,
  87. &size_pixels, &weight));
  88. }
  89. TEST(FontListTest, Fonts_FromDescString) {
  90. // Test init from font name size string.
  91. FontList font_list = FontList("arial, Courier New, 13px");
  92. const std::vector<Font>& fonts = font_list.GetFonts();
  93. ASSERT_EQ(2U, fonts.size());
  94. EXPECT_EQ("arial|13|normal", FontToString(fonts[0]));
  95. EXPECT_EQ("Courier New|13|normal", FontToString(fonts[1]));
  96. }
  97. TEST(FontListTest, Fonts_FromDescStringInFlexibleFormat) {
  98. // Test init from font name size string with flexible format.
  99. FontList font_list = FontList(" arial , Courier New , 13px");
  100. const std::vector<Font>& fonts = font_list.GetFonts();
  101. ASSERT_EQ(2U, fonts.size());
  102. EXPECT_EQ("arial|13|normal", FontToString(fonts[0]));
  103. EXPECT_EQ("Courier New|13|normal", FontToString(fonts[1]));
  104. }
  105. TEST(FontListTest, Fonts_FromDescStringWithStyleInFlexibleFormat) {
  106. // Test init from font name style size string with flexible format.
  107. FontList font_list = FontList(
  108. " arial , Courier New , Bold "
  109. " Italic 13px");
  110. const std::vector<Font>& fonts = font_list.GetFonts();
  111. ASSERT_EQ(2U, fonts.size());
  112. EXPECT_EQ("arial|13|italic|bold", FontToString(fonts[0]));
  113. EXPECT_EQ("Courier New|13|italic|bold", FontToString(fonts[1]));
  114. }
  115. TEST(FontListTest, Fonts_FromFont) {
  116. // Test init from Font.
  117. Font font("Arial", 8);
  118. FontList font_list = FontList(font);
  119. const std::vector<Font>& fonts = font_list.GetFonts();
  120. ASSERT_EQ(1U, fonts.size());
  121. EXPECT_EQ("Arial|8|normal", FontToString(fonts[0]));
  122. }
  123. TEST(FontListTest, Fonts_FromFontWithNonNormalStyle) {
  124. // Test init from Font with non-normal style.
  125. Font font("Arial", 8);
  126. FontList font_list(font.Derive(2, Font::NORMAL, Font::Weight::BOLD));
  127. std::vector<Font> fonts = font_list.GetFonts();
  128. ASSERT_EQ(1U, fonts.size());
  129. EXPECT_EQ("Arial|10|bold", FontToString(fonts[0]));
  130. font_list = FontList(font.Derive(-2, Font::ITALIC, Font::Weight::NORMAL));
  131. fonts = font_list.GetFonts();
  132. ASSERT_EQ(1U, fonts.size());
  133. EXPECT_EQ("Arial|6|italic|normal", FontToString(fonts[0]));
  134. }
  135. TEST(FontListTest, Fonts_FromFontVector) {
  136. // Test init from Font vector.
  137. Font font("Arial", 8);
  138. Font font_1("Courier New", 10);
  139. std::vector<Font> input_fonts;
  140. input_fonts.push_back(font.Derive(0, Font::NORMAL, Font::Weight::BOLD));
  141. input_fonts.push_back(font_1.Derive(-2, Font::NORMAL, Font::Weight::BOLD));
  142. FontList font_list = FontList(input_fonts);
  143. const std::vector<Font>& fonts = font_list.GetFonts();
  144. ASSERT_EQ(2U, fonts.size());
  145. EXPECT_EQ("Arial|8|bold", FontToString(fonts[0]));
  146. EXPECT_EQ("Courier New|8|bold", FontToString(fonts[1]));
  147. }
  148. TEST(FontListTest, FontDescString_GetStyle) {
  149. FontList font_list = FontList("Arial,Sans serif, 8px");
  150. EXPECT_EQ(Font::NORMAL, font_list.GetFontStyle());
  151. EXPECT_EQ(Font::Weight::NORMAL, font_list.GetFontWeight());
  152. font_list = FontList("Arial,Sans serif,Bold 8px");
  153. EXPECT_EQ(Font::NORMAL, font_list.GetFontStyle());
  154. EXPECT_EQ(Font::Weight::BOLD, font_list.GetFontWeight());
  155. font_list = FontList("Arial,Sans serif,Italic 8px");
  156. EXPECT_EQ(Font::ITALIC, font_list.GetFontStyle());
  157. EXPECT_EQ(Font::Weight::NORMAL, font_list.GetFontWeight());
  158. font_list = FontList("Arial,Italic Bold 8px");
  159. EXPECT_EQ(Font::ITALIC, font_list.GetFontStyle());
  160. EXPECT_EQ(Font::Weight::BOLD, font_list.GetFontWeight());
  161. }
  162. TEST(FontListTest, Fonts_GetStyle) {
  163. std::vector<Font> fonts;
  164. fonts.push_back(Font("Arial", 8));
  165. fonts.push_back(Font("Sans serif", 8));
  166. FontList font_list = FontList(fonts);
  167. EXPECT_EQ(Font::NORMAL, font_list.GetFontStyle());
  168. fonts[0] = fonts[0].Derive(0, Font::ITALIC, Font::Weight::BOLD);
  169. fonts[1] = fonts[1].Derive(0, Font::ITALIC, Font::Weight::BOLD);
  170. font_list = FontList(fonts);
  171. EXPECT_EQ(Font::ITALIC, font_list.GetFontStyle());
  172. EXPECT_EQ(Font::Weight::BOLD, font_list.GetFontWeight());
  173. }
  174. TEST(FontListTest, Fonts_Derive) {
  175. std::vector<Font> fonts;
  176. fonts.push_back(Font("Arial", 8));
  177. fonts.push_back(Font("Courier New", 8));
  178. FontList font_list = FontList(fonts);
  179. FontList derived = font_list.Derive(5, Font::ITALIC, Font::Weight::BOLD);
  180. const std::vector<Font>& derived_fonts = derived.GetFonts();
  181. EXPECT_EQ(2U, derived_fonts.size());
  182. EXPECT_EQ("Arial|13|italic|bold", FontToString(derived_fonts[0]));
  183. EXPECT_EQ("Courier New|13|italic|bold", FontToString(derived_fonts[1]));
  184. derived = font_list.Derive(5, Font::UNDERLINE, Font::Weight::BOLD);
  185. const std::vector<Font>& underline_fonts = derived.GetFonts();
  186. EXPECT_EQ(2U, underline_fonts.size());
  187. EXPECT_EQ("Arial|13|underline|bold", FontToString(underline_fonts[0]));
  188. EXPECT_EQ("Courier New|13|underline|bold", FontToString(underline_fonts[1]));
  189. }
  190. TEST(FontListTest, Fonts_DeriveWithSizeDelta) {
  191. std::vector<Font> fonts;
  192. fonts.push_back(
  193. Font("Arial", 18).Derive(0, Font::ITALIC, Font::Weight::NORMAL));
  194. fonts.push_back(Font("Courier New", 18)
  195. .Derive(0, Font::ITALIC, Font::Weight::NORMAL));
  196. FontList font_list = FontList(fonts);
  197. FontList derived = font_list.DeriveWithSizeDelta(-5);
  198. const std::vector<Font>& derived_fonts = derived.GetFonts();
  199. EXPECT_EQ(2U, derived_fonts.size());
  200. EXPECT_EQ("Arial|13|italic|normal", FontToString(derived_fonts[0]));
  201. EXPECT_EQ("Courier New|13|italic|normal", FontToString(derived_fonts[1]));
  202. }
  203. TEST(FontListTest, Fonts_GetHeight_GetBaseline) {
  204. // If a font list has only one font, the height and baseline must be the same.
  205. Font font1(kTestFontName, 16);
  206. ASSERT_EQ(base::ToLowerASCII(kTestFontName),
  207. base::ToLowerASCII(font1.GetActualFontName()));
  208. FontList font_list1(std::string(kTestFontName) + ", 16px");
  209. EXPECT_EQ(font1.GetHeight(), font_list1.GetHeight());
  210. EXPECT_EQ(font1.GetBaseline(), font_list1.GetBaseline());
  211. // If there are two different fonts, the font list returns the max value
  212. // for the baseline (ascent) and height.
  213. // NOTE: On most platforms, kCJKFontName has different metrics than
  214. // kTestFontName, but on Android it does not.
  215. Font font2(kCJKFontName, 16);
  216. ASSERT_EQ(base::ToLowerASCII(kCJKFontName),
  217. base::ToLowerASCII(font2.GetActualFontName()));
  218. std::vector<Font> fonts;
  219. fonts.push_back(font1);
  220. fonts.push_back(font2);
  221. FontList font_list_mix(fonts);
  222. // ascent of FontList == max(ascent of Fonts)
  223. EXPECT_EQ(std::max(font1.GetBaseline(), font2.GetBaseline()),
  224. font_list_mix.GetBaseline());
  225. // descent of FontList == max(descent of Fonts)
  226. EXPECT_EQ(std::max(font1.GetHeight() - font1.GetBaseline(),
  227. font2.GetHeight() - font2.GetBaseline()),
  228. font_list_mix.GetHeight() - font_list_mix.GetBaseline());
  229. }
  230. TEST(FontListTest, Fonts_DeriveWithHeightUpperBound) {
  231. std::vector<Font> fonts;
  232. fonts.push_back(Font("Arial", 18));
  233. fonts.push_back(Font("Sans serif", 18));
  234. fonts.push_back(Font(kSymbolFontName, 18));
  235. FontList font_list = FontList(fonts);
  236. // A smaller upper bound should derive a font list with a smaller height.
  237. const int height_1 = font_list.GetHeight() - 5;
  238. FontList derived_1 = font_list.DeriveWithHeightUpperBound(height_1);
  239. EXPECT_LE(derived_1.GetHeight(), height_1);
  240. EXPECT_LT(derived_1.GetHeight(), font_list.GetHeight());
  241. EXPECT_LT(derived_1.GetFontSize(), font_list.GetFontSize());
  242. // A larger upper bound should not change the height of the font list.
  243. const int height_2 = font_list.GetHeight() + 5;
  244. FontList derived_2 = font_list.DeriveWithHeightUpperBound(height_2);
  245. EXPECT_LE(derived_2.GetHeight(), height_2);
  246. EXPECT_EQ(font_list.GetHeight(), derived_2.GetHeight());
  247. EXPECT_EQ(font_list.GetFontSize(), derived_2.GetFontSize());
  248. }
  249. TEST(FontListTest, FirstAvailableOrFirst) {
  250. EXPECT_TRUE(FontList::FirstAvailableOrFirst("").empty());
  251. EXPECT_TRUE(FontList::FirstAvailableOrFirst(std::string()).empty());
  252. EXPECT_EQ("Arial", FontList::FirstAvailableOrFirst("Arial"));
  253. EXPECT_EQ("not exist", FontList::FirstAvailableOrFirst("not exist"));
  254. EXPECT_EQ("Arial", FontList::FirstAvailableOrFirst("Arial, not exist"));
  255. EXPECT_EQ("Arial", FontList::FirstAvailableOrFirst("not exist, Arial"));
  256. EXPECT_EQ("Arial",
  257. FontList::FirstAvailableOrFirst("not exist, Arial, not exist"));
  258. EXPECT_EQ("not exist",
  259. FontList::FirstAvailableOrFirst("not exist, not exist 2"));
  260. EXPECT_EQ("Arial", FontList::FirstAvailableOrFirst(", not exist, Arial"));
  261. EXPECT_EQ("not exist",
  262. FontList::FirstAvailableOrFirst(", not exist, not exist"));
  263. }
  264. } // namespace gfx