| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 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_render_params.h" | |
| 6 | |
| 7 #include "base/files/file_path.h" | |
| 8 #include "base/files/scoped_temp_dir.h" | |
| 9 #include "base/logging.h" | |
| 10 #include "base/macros.h" | |
| 11 #include "testing/gtest/include/gtest/gtest.h" | |
| 12 #include "ui/gfx/font.h" | |
| 13 #include "ui/gfx/linux_font_delegate.h" | |
| 14 #include "ui/gfx/pango_util.h" | |
| 15 #include "ui/gfx/test/fontconfig_util_linux.h" | |
| 16 | |
| 17 namespace gfx { | |
| 18 | |
| 19 namespace { | |
| 20 | |
| 21 // Implementation of LinuxFontDelegate that returns a canned FontRenderParams | |
| 22 // struct. This is used to isolate tests from the system's local configuration. | |
| 23 class TestFontDelegate : public LinuxFontDelegate { | |
| 24 public: | |
| 25 TestFontDelegate() {} | |
| 26 virtual ~TestFontDelegate() {} | |
| 27 | |
| 28 void set_params(const FontRenderParams& params) { params_ = params; } | |
| 29 | |
| 30 virtual FontRenderParams GetDefaultFontRenderParams() const override { | |
| 31 return params_; | |
| 32 } | |
| 33 virtual scoped_ptr<ScopedPangoFontDescription> | |
| 34 GetDefaultPangoFontDescription() const override { | |
| 35 NOTIMPLEMENTED(); | |
| 36 return scoped_ptr<ScopedPangoFontDescription>(); | |
| 37 } | |
| 38 virtual double GetFontDPI() const override { | |
| 39 NOTIMPLEMENTED(); | |
| 40 return 96.0; | |
| 41 } | |
| 42 | |
| 43 private: | |
| 44 FontRenderParams params_; | |
| 45 | |
| 46 DISALLOW_COPY_AND_ASSIGN(TestFontDelegate); | |
| 47 }; | |
| 48 | |
| 49 // Loads the first system font defined by fontconfig_util_linux.h with a base | |
| 50 // filename of |basename|. Case is ignored. | |
| 51 bool LoadSystemFont(const std::string& basename) { | |
| 52 for (size_t i = 0; i < kNumSystemFontsForFontconfig; ++i) { | |
| 53 base::FilePath path(gfx::kSystemFontsForFontconfig[i]); | |
| 54 if (strcasecmp(path.BaseName().value().c_str(), basename.c_str()) == 0) | |
| 55 return LoadFontIntoFontconfig(path); | |
| 56 } | |
| 57 LOG(ERROR) << "Unable to find system font named " << basename; | |
| 58 return false; | |
| 59 } | |
| 60 | |
| 61 } // namespace | |
| 62 | |
| 63 class FontRenderParamsTest : public testing::Test { | |
| 64 public: | |
| 65 FontRenderParamsTest() { | |
| 66 SetUpFontconfig(); | |
| 67 CHECK(temp_dir_.CreateUniqueTempDir()); | |
| 68 original_font_delegate_ = LinuxFontDelegate::instance(); | |
| 69 LinuxFontDelegate::SetInstance(&test_font_delegate_); | |
| 70 ClearFontRenderParamsCacheForTest(); | |
| 71 } | |
| 72 | |
| 73 virtual ~FontRenderParamsTest() { | |
| 74 LinuxFontDelegate::SetInstance( | |
| 75 const_cast<LinuxFontDelegate*>(original_font_delegate_)); | |
| 76 TearDownFontconfig(); | |
| 77 } | |
| 78 | |
| 79 protected: | |
| 80 base::ScopedTempDir temp_dir_; | |
| 81 const LinuxFontDelegate* original_font_delegate_; | |
| 82 TestFontDelegate test_font_delegate_; | |
| 83 | |
| 84 private: | |
| 85 DISALLOW_COPY_AND_ASSIGN(FontRenderParamsTest); | |
| 86 }; | |
| 87 | |
| 88 TEST_F(FontRenderParamsTest, Default) { | |
| 89 // Fontconfig needs to know about at least one font to return a match. | |
| 90 ASSERT_TRUE(LoadSystemFont("arial.ttf")); | |
| 91 ASSERT_TRUE(LoadConfigDataIntoFontconfig(temp_dir_.path(), | |
| 92 std::string(kFontconfigFileHeader) + | |
| 93 kFontconfigMatchHeader + | |
| 94 CreateFontconfigEditStanza("antialias", "bool", "true") + | |
| 95 CreateFontconfigEditStanza("autohint", "bool", "false") + | |
| 96 CreateFontconfigEditStanza("hinting", "bool", "true") + | |
| 97 CreateFontconfigEditStanza("hintstyle", "const", "hintfull") + | |
| 98 CreateFontconfigEditStanza("rgba", "const", "rgb") + | |
| 99 kFontconfigMatchFooter + | |
| 100 kFontconfigFileFooter)); | |
| 101 | |
| 102 FontRenderParams params = GetFontRenderParams( | |
| 103 FontRenderParamsQuery(true), NULL); | |
| 104 EXPECT_TRUE(params.antialiasing); | |
| 105 EXPECT_FALSE(params.autohinter); | |
| 106 EXPECT_TRUE(params.use_bitmaps); | |
| 107 EXPECT_EQ(FontRenderParams::HINTING_FULL, params.hinting); | |
| 108 EXPECT_FALSE(params.subpixel_positioning); | |
| 109 EXPECT_EQ(FontRenderParams::SUBPIXEL_RENDERING_RGB, | |
| 110 params.subpixel_rendering); | |
| 111 } | |
| 112 | |
| 113 TEST_F(FontRenderParamsTest, Size) { | |
| 114 ASSERT_TRUE(LoadSystemFont("arial.ttf")); | |
| 115 ASSERT_TRUE(LoadConfigDataIntoFontconfig(temp_dir_.path(), | |
| 116 std::string(kFontconfigFileHeader) + | |
| 117 kFontconfigMatchHeader + | |
| 118 CreateFontconfigEditStanza("antialias", "bool", "true") + | |
| 119 CreateFontconfigEditStanza("hinting", "bool", "true") + | |
| 120 CreateFontconfigEditStanza("hintstyle", "const", "hintfull") + | |
| 121 CreateFontconfigEditStanza("rgba", "const", "none") + | |
| 122 kFontconfigMatchFooter + | |
| 123 kFontconfigMatchHeader + | |
| 124 CreateFontconfigTestStanza("pixelsize", "less_eq", "double", "10") + | |
| 125 CreateFontconfigEditStanza("antialias", "bool", "false") + | |
| 126 kFontconfigMatchFooter + | |
| 127 kFontconfigMatchHeader + | |
| 128 CreateFontconfigTestStanza("size", "more_eq", "double", "20") + | |
| 129 CreateFontconfigEditStanza("hintstyle", "const", "hintslight") + | |
| 130 CreateFontconfigEditStanza("rgba", "const", "rgb") + | |
| 131 kFontconfigMatchFooter + | |
| 132 kFontconfigFileFooter)); | |
| 133 | |
| 134 // The defaults should be used when the supplied size isn't matched by the | |
| 135 // second or third blocks. | |
| 136 FontRenderParamsQuery query(false); | |
| 137 query.pixel_size = 12; | |
| 138 FontRenderParams params = GetFontRenderParams(query, NULL); | |
| 139 EXPECT_TRUE(params.antialiasing); | |
| 140 EXPECT_EQ(FontRenderParams::HINTING_FULL, params.hinting); | |
| 141 EXPECT_EQ(FontRenderParams::SUBPIXEL_RENDERING_NONE, | |
| 142 params.subpixel_rendering); | |
| 143 | |
| 144 query.pixel_size = 10; | |
| 145 params = GetFontRenderParams(query, NULL); | |
| 146 EXPECT_FALSE(params.antialiasing); | |
| 147 EXPECT_EQ(FontRenderParams::HINTING_FULL, params.hinting); | |
| 148 EXPECT_EQ(FontRenderParams::SUBPIXEL_RENDERING_NONE, | |
| 149 params.subpixel_rendering); | |
| 150 | |
| 151 query.pixel_size = 0; | |
| 152 query.point_size = 20; | |
| 153 params = GetFontRenderParams(query, NULL); | |
| 154 EXPECT_TRUE(params.antialiasing); | |
| 155 EXPECT_EQ(FontRenderParams::HINTING_SLIGHT, params.hinting); | |
| 156 EXPECT_EQ(FontRenderParams::SUBPIXEL_RENDERING_RGB, | |
| 157 params.subpixel_rendering); | |
| 158 } | |
| 159 | |
| 160 TEST_F(FontRenderParamsTest, Style) { | |
| 161 ASSERT_TRUE(LoadSystemFont("arial.ttf")); | |
| 162 // Load a config that disables subpixel rendering for bold text and disables | |
| 163 // hinting for italic text. | |
| 164 ASSERT_TRUE(LoadConfigDataIntoFontconfig(temp_dir_.path(), | |
| 165 std::string(kFontconfigFileHeader) + | |
| 166 kFontconfigMatchHeader + | |
| 167 CreateFontconfigEditStanza("antialias", "bool", "true") + | |
| 168 CreateFontconfigEditStanza("hinting", "bool", "true") + | |
| 169 CreateFontconfigEditStanza("hintstyle", "const", "hintslight") + | |
| 170 CreateFontconfigEditStanza("rgba", "const", "rgb") + | |
| 171 kFontconfigMatchFooter + | |
| 172 kFontconfigMatchHeader + | |
| 173 CreateFontconfigTestStanza("weight", "eq", "const", "bold") + | |
| 174 CreateFontconfigEditStanza("rgba", "const", "none") + | |
| 175 kFontconfigMatchFooter + | |
| 176 kFontconfigMatchHeader + | |
| 177 CreateFontconfigTestStanza("slant", "eq", "const", "italic") + | |
| 178 CreateFontconfigEditStanza("hinting", "bool", "false") + | |
| 179 kFontconfigMatchFooter + | |
| 180 kFontconfigFileFooter)); | |
| 181 | |
| 182 FontRenderParamsQuery query(false); | |
| 183 query.style = Font::NORMAL; | |
| 184 FontRenderParams params = GetFontRenderParams(query, NULL); | |
| 185 EXPECT_EQ(FontRenderParams::HINTING_SLIGHT, params.hinting); | |
| 186 EXPECT_EQ(FontRenderParams::SUBPIXEL_RENDERING_RGB, | |
| 187 params.subpixel_rendering); | |
| 188 | |
| 189 query.style = Font::BOLD; | |
| 190 params = GetFontRenderParams(query, NULL); | |
| 191 EXPECT_EQ(FontRenderParams::HINTING_SLIGHT, params.hinting); | |
| 192 EXPECT_EQ(FontRenderParams::SUBPIXEL_RENDERING_NONE, | |
| 193 params.subpixel_rendering); | |
| 194 | |
| 195 query.style = Font::ITALIC; | |
| 196 params = GetFontRenderParams(query, NULL); | |
| 197 EXPECT_EQ(FontRenderParams::HINTING_NONE, params.hinting); | |
| 198 EXPECT_EQ(FontRenderParams::SUBPIXEL_RENDERING_RGB, | |
| 199 params.subpixel_rendering); | |
| 200 | |
| 201 query.style = Font::BOLD | Font::ITALIC; | |
| 202 params = GetFontRenderParams(query, NULL); | |
| 203 EXPECT_EQ(FontRenderParams::HINTING_NONE, params.hinting); | |
| 204 EXPECT_EQ(FontRenderParams::SUBPIXEL_RENDERING_NONE, | |
| 205 params.subpixel_rendering); | |
| 206 } | |
| 207 | |
| 208 TEST_F(FontRenderParamsTest, Scalable) { | |
| 209 ASSERT_TRUE(LoadSystemFont("arial.ttf")); | |
| 210 // Load a config that only enables antialiasing for scalable fonts. | |
| 211 ASSERT_TRUE(LoadConfigDataIntoFontconfig(temp_dir_.path(), | |
| 212 std::string(kFontconfigFileHeader) + | |
| 213 kFontconfigMatchHeader + | |
| 214 CreateFontconfigEditStanza("antialias", "bool", "false") + | |
| 215 kFontconfigMatchFooter + | |
| 216 kFontconfigMatchHeader + | |
| 217 CreateFontconfigTestStanza("scalable", "eq", "bool", "true") + | |
| 218 CreateFontconfigEditStanza("antialias", "bool", "true") + | |
| 219 kFontconfigMatchFooter + | |
| 220 kFontconfigFileFooter)); | |
| 221 | |
| 222 // Check that we specifically ask how scalable fonts should be rendered. | |
| 223 FontRenderParams params = GetFontRenderParams( | |
| 224 FontRenderParamsQuery(false), NULL); | |
| 225 EXPECT_TRUE(params.antialiasing); | |
| 226 } | |
| 227 | |
| 228 TEST_F(FontRenderParamsTest, UseBitmaps) { | |
| 229 ASSERT_TRUE(LoadSystemFont("arial.ttf")); | |
| 230 // Load a config that enables embedded bitmaps for fonts <= 10 pixels. | |
| 231 ASSERT_TRUE(LoadConfigDataIntoFontconfig(temp_dir_.path(), | |
| 232 std::string(kFontconfigFileHeader) + | |
| 233 kFontconfigMatchHeader + | |
| 234 CreateFontconfigEditStanza("embeddedbitmap", "bool", "false") + | |
| 235 kFontconfigMatchFooter + | |
| 236 kFontconfigMatchHeader + | |
| 237 CreateFontconfigTestStanza("pixelsize", "less_eq", "double", "10") + | |
| 238 CreateFontconfigEditStanza("embeddedbitmap", "bool", "true") + | |
| 239 kFontconfigMatchFooter + | |
| 240 kFontconfigFileFooter)); | |
| 241 | |
| 242 FontRenderParamsQuery query(false); | |
| 243 FontRenderParams params = GetFontRenderParams(query, NULL); | |
| 244 EXPECT_FALSE(params.use_bitmaps); | |
| 245 | |
| 246 query.pixel_size = 5; | |
| 247 params = GetFontRenderParams(query, NULL); | |
| 248 EXPECT_TRUE(params.use_bitmaps); | |
| 249 } | |
| 250 | |
| 251 TEST_F(FontRenderParamsTest, ForceFullHintingWhenAntialiasingIsDisabled) { | |
| 252 // Load a config that disables antialiasing and hinting while requesting | |
| 253 // subpixel rendering. | |
| 254 ASSERT_TRUE(LoadSystemFont("arial.ttf")); | |
| 255 ASSERT_TRUE(LoadConfigDataIntoFontconfig(temp_dir_.path(), | |
| 256 std::string(kFontconfigFileHeader) + | |
| 257 kFontconfigMatchHeader + | |
| 258 CreateFontconfigEditStanza("antialias", "bool", "false") + | |
| 259 CreateFontconfigEditStanza("hinting", "bool", "false") + | |
| 260 CreateFontconfigEditStanza("hintstyle", "const", "hintnone") + | |
| 261 CreateFontconfigEditStanza("rgba", "const", "rgb") + | |
| 262 kFontconfigMatchFooter + | |
| 263 kFontconfigFileFooter)); | |
| 264 | |
| 265 // Full hinting should be forced. See the comment in GetFontRenderParams() for | |
| 266 // more information. | |
| 267 FontRenderParams params = GetFontRenderParams( | |
| 268 FontRenderParamsQuery(false), NULL); | |
| 269 EXPECT_FALSE(params.antialiasing); | |
| 270 EXPECT_EQ(FontRenderParams::HINTING_FULL, params.hinting); | |
| 271 EXPECT_EQ(FontRenderParams::SUBPIXEL_RENDERING_NONE, | |
| 272 params.subpixel_rendering); | |
| 273 EXPECT_FALSE(params.subpixel_positioning); | |
| 274 } | |
| 275 | |
| 276 #if defined(OS_CHROMEOS) | |
| 277 TEST_F(FontRenderParamsTest, ForceSubpixelPositioning) { | |
| 278 { | |
| 279 FontRenderParams params = | |
| 280 GetFontRenderParams(FontRenderParamsQuery(false), NULL); | |
| 281 EXPECT_TRUE(params.antialiasing); | |
| 282 EXPECT_FALSE(params.subpixel_positioning); | |
| 283 SetFontRenderParamsDeviceScaleFactor(1.0f); | |
| 284 } | |
| 285 ClearFontRenderParamsCacheForTest(); | |
| 286 SetFontRenderParamsDeviceScaleFactor(1.25f); | |
| 287 // Subpixel positioning should be forced. | |
| 288 { | |
| 289 FontRenderParams params = | |
| 290 GetFontRenderParams(FontRenderParamsQuery(false), NULL); | |
| 291 EXPECT_TRUE(params.antialiasing); | |
| 292 EXPECT_TRUE(params.subpixel_positioning); | |
| 293 SetFontRenderParamsDeviceScaleFactor(1.0f); | |
| 294 } | |
| 295 } | |
| 296 #endif | |
| 297 | |
| 298 TEST_F(FontRenderParamsTest, OnlySetConfiguredValues) { | |
| 299 // Configure the LinuxFontDelegate (which queries GtkSettings on desktop | |
| 300 // Linux) to request subpixel rendering. | |
| 301 FontRenderParams system_params; | |
| 302 system_params.subpixel_rendering = FontRenderParams::SUBPIXEL_RENDERING_RGB; | |
| 303 test_font_delegate_.set_params(system_params); | |
| 304 | |
| 305 // Load a Fontconfig config that enables antialiasing but doesn't say anything | |
| 306 // about subpixel rendering. | |
| 307 ASSERT_TRUE(LoadSystemFont("arial.ttf")); | |
| 308 ASSERT_TRUE(LoadConfigDataIntoFontconfig(temp_dir_.path(), | |
| 309 std::string(kFontconfigFileHeader) + | |
| 310 kFontconfigMatchHeader + | |
| 311 CreateFontconfigEditStanza("antialias", "bool", "true") + | |
| 312 kFontconfigMatchFooter + | |
| 313 kFontconfigFileFooter)); | |
| 314 | |
| 315 // The subpixel rendering setting from the delegate should make it through. | |
| 316 FontRenderParams params = GetFontRenderParams( | |
| 317 FontRenderParamsQuery(false), NULL); | |
| 318 EXPECT_EQ(system_params.subpixel_rendering, params.subpixel_rendering); | |
| 319 } | |
| 320 | |
| 321 TEST_F(FontRenderParamsTest, NoFontconfigMatch) { | |
| 322 // Don't load a Fontconfig configuration. | |
| 323 FontRenderParams system_params; | |
| 324 system_params.antialiasing = true; | |
| 325 system_params.hinting = FontRenderParams::HINTING_MEDIUM; | |
| 326 system_params.subpixel_rendering = FontRenderParams::SUBPIXEL_RENDERING_RGB; | |
| 327 test_font_delegate_.set_params(system_params); | |
| 328 | |
| 329 FontRenderParamsQuery query(false); | |
| 330 query.families.push_back("Arial"); | |
| 331 query.families.push_back("Times New Roman"); | |
| 332 query.pixel_size = 10; | |
| 333 std::string suggested_family; | |
| 334 FontRenderParams params = GetFontRenderParams(query, &suggested_family); | |
| 335 | |
| 336 // The system params and the first requested family should be returned. | |
| 337 EXPECT_EQ(system_params.antialiasing, params.antialiasing); | |
| 338 EXPECT_EQ(system_params.hinting, params.hinting); | |
| 339 EXPECT_EQ(system_params.subpixel_rendering, params.subpixel_rendering); | |
| 340 EXPECT_EQ(query.families[0], suggested_family); | |
| 341 } | |
| 342 | |
| 343 TEST_F(FontRenderParamsTest, MissingFamily) { | |
| 344 // With Arial and Verdana installed, request (in order) Helvetica, Arial, and | |
| 345 // Verdana and check that Arial is returned. | |
| 346 ASSERT_TRUE(LoadSystemFont("arial.ttf")); | |
| 347 ASSERT_TRUE(LoadSystemFont("verdana.ttf")); | |
| 348 FontRenderParamsQuery query(false); | |
| 349 query.families.push_back("Helvetica"); | |
| 350 query.families.push_back("Arial"); | |
| 351 query.families.push_back("Verdana"); | |
| 352 std::string suggested_family; | |
| 353 GetFontRenderParams(query, &suggested_family); | |
| 354 EXPECT_EQ("Arial", suggested_family); | |
| 355 } | |
| 356 | |
| 357 TEST_F(FontRenderParamsTest, SubstituteFamily) { | |
| 358 // Configure Fontconfig to use Verdana for both Helvetica and Arial. | |
| 359 ASSERT_TRUE(LoadSystemFont("arial.ttf")); | |
| 360 ASSERT_TRUE(LoadSystemFont("verdana.ttf")); | |
| 361 ASSERT_TRUE(LoadConfigDataIntoFontconfig(temp_dir_.path(), | |
| 362 std::string(kFontconfigFileHeader) + | |
| 363 CreateFontconfigAliasStanza("Helvetica", "Verdana") + | |
| 364 kFontconfigMatchHeader + | |
| 365 CreateFontconfigTestStanza("family", "eq", "string", "Arial") + | |
| 366 CreateFontconfigEditStanza("family", "string", "Verdana") + | |
| 367 kFontconfigMatchFooter + | |
| 368 kFontconfigFileFooter)); | |
| 369 | |
| 370 FontRenderParamsQuery query(false); | |
| 371 query.families.push_back("Helvetica"); | |
| 372 std::string suggested_family; | |
| 373 GetFontRenderParams(query, &suggested_family); | |
| 374 EXPECT_EQ("Verdana", suggested_family); | |
| 375 | |
| 376 query.families.clear(); | |
| 377 query.families.push_back("Arial"); | |
| 378 suggested_family.clear(); | |
| 379 GetFontRenderParams(query, &suggested_family); | |
| 380 EXPECT_EQ("Verdana", suggested_family); | |
| 381 } | |
| 382 | |
| 383 } // namespace gfx | |
| OLD | NEW |