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 |