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.
5 #include "ui/gfx/font_render_params.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/logging.h"
9 #include "base/macros.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "ui/gfx/font.h"
12 #include "ui/gfx/linux_font_delegate.h"
13 #include "ui/gfx/test/fontconfig_util_linux.h"
19 // Implementation of LinuxFontDelegate that returns a canned FontRenderParams
20 // struct. This is used to isolate tests from the system's local configuration.
21 class TestFontDelegate
: public LinuxFontDelegate
{
24 ~TestFontDelegate() override
{}
26 void set_params(const FontRenderParams
& params
) { params_
= params
; }
28 FontRenderParams
GetDefaultFontRenderParams() const override
{
31 void GetDefaultFontDescription(
32 std::string
* family_out
,
35 FontRenderParams
* params_out
) const override
{
40 FontRenderParams params_
;
42 DISALLOW_COPY_AND_ASSIGN(TestFontDelegate
);
47 class FontRenderParamsTest
: public testing::Test
{
49 FontRenderParamsTest() {
51 CHECK(temp_dir_
.CreateUniqueTempDir());
52 original_font_delegate_
= LinuxFontDelegate::instance();
53 LinuxFontDelegate::SetInstance(&test_font_delegate_
);
54 ClearFontRenderParamsCacheForTest();
57 ~FontRenderParamsTest() override
{
58 LinuxFontDelegate::SetInstance(
59 const_cast<LinuxFontDelegate
*>(original_font_delegate_
));
64 base::ScopedTempDir temp_dir_
;
65 const LinuxFontDelegate
* original_font_delegate_
;
66 TestFontDelegate test_font_delegate_
;
69 DISALLOW_COPY_AND_ASSIGN(FontRenderParamsTest
);
72 TEST_F(FontRenderParamsTest
, Default
) {
73 ASSERT_TRUE(LoadSystemFontIntoFontconfig("arial.ttf"));
74 ASSERT_TRUE(LoadConfigDataIntoFontconfig(temp_dir_
.path(),
75 std::string(kFontconfigFileHeader
) +
76 // Specify the desired defaults via a font match rather than a pattern
77 // match (since this is the style generally used in /etc/fonts/conf.d).
78 kFontconfigMatchFontHeader
+
79 CreateFontconfigEditStanza("antialias", "bool", "true") +
80 CreateFontconfigEditStanza("autohint", "bool", "true") +
81 CreateFontconfigEditStanza("hinting", "bool", "true") +
82 CreateFontconfigEditStanza("hintstyle", "const", "hintslight") +
83 CreateFontconfigEditStanza("rgba", "const", "rgb") +
84 kFontconfigMatchFooter
+
85 // Add a font match for Arial. Since it specifies a family, it shouldn't
86 // take effect when querying default settings.
87 kFontconfigMatchFontHeader
+
88 CreateFontconfigTestStanza("family", "eq", "string", "Arial") +
89 CreateFontconfigEditStanza("antialias", "bool", "true") +
90 CreateFontconfigEditStanza("autohint", "bool", "false") +
91 CreateFontconfigEditStanza("hinting", "bool", "true") +
92 CreateFontconfigEditStanza("hintstyle", "const", "hintfull") +
93 CreateFontconfigEditStanza("rgba", "const", "none") +
94 kFontconfigMatchFooter
+
95 // Add font matches for fonts between 10 and 20 points or pixels. Since
96 // they specify sizes, they also should not affect the defaults.
97 kFontconfigMatchFontHeader
+
98 CreateFontconfigTestStanza("size", "more_eq", "double", "10.0") +
99 CreateFontconfigTestStanza("size", "less_eq", "double", "20.0") +
100 CreateFontconfigEditStanza("antialias", "bool", "false") +
101 kFontconfigMatchFooter
+
102 kFontconfigMatchFontHeader
+
103 CreateFontconfigTestStanza("pixel_size", "more_eq", "double", "10.0") +
104 CreateFontconfigTestStanza("pixel_size", "less_eq", "double", "20.0") +
105 CreateFontconfigEditStanza("antialias", "bool", "false") +
106 kFontconfigMatchFooter
+
107 kFontconfigFileFooter
));
109 FontRenderParams params
= GetFontRenderParams(
110 FontRenderParamsQuery(), NULL
);
111 EXPECT_TRUE(params
.antialiasing
);
112 EXPECT_TRUE(params
.autohinter
);
113 EXPECT_TRUE(params
.use_bitmaps
);
114 EXPECT_EQ(FontRenderParams::HINTING_SLIGHT
, params
.hinting
);
115 EXPECT_FALSE(params
.subpixel_positioning
);
116 EXPECT_EQ(FontRenderParams::SUBPIXEL_RENDERING_RGB
,
117 params
.subpixel_rendering
);
120 TEST_F(FontRenderParamsTest
, Size
) {
121 ASSERT_TRUE(LoadSystemFontIntoFontconfig("arial.ttf"));
122 ASSERT_TRUE(LoadConfigDataIntoFontconfig(temp_dir_
.path(),
123 std::string(kFontconfigFileHeader
) +
124 kFontconfigMatchPatternHeader
+
125 CreateFontconfigEditStanza("antialias", "bool", "true") +
126 CreateFontconfigEditStanza("hinting", "bool", "true") +
127 CreateFontconfigEditStanza("hintstyle", "const", "hintfull") +
128 CreateFontconfigEditStanza("rgba", "const", "none") +
129 kFontconfigMatchFooter
+
130 kFontconfigMatchPatternHeader
+
131 CreateFontconfigTestStanza("pixelsize", "less_eq", "double", "10") +
132 CreateFontconfigEditStanza("antialias", "bool", "false") +
133 kFontconfigMatchFooter
+
134 kFontconfigMatchPatternHeader
+
135 CreateFontconfigTestStanza("size", "more_eq", "double", "20") +
136 CreateFontconfigEditStanza("hintstyle", "const", "hintslight") +
137 CreateFontconfigEditStanza("rgba", "const", "rgb") +
138 kFontconfigMatchFooter
+
139 kFontconfigFileFooter
));
141 // The defaults should be used when the supplied size isn't matched by the
142 // second or third blocks.
143 FontRenderParamsQuery query
;
144 query
.pixel_size
= 12;
145 FontRenderParams params
= GetFontRenderParams(query
, NULL
);
146 EXPECT_TRUE(params
.antialiasing
);
147 EXPECT_EQ(FontRenderParams::HINTING_FULL
, params
.hinting
);
148 EXPECT_EQ(FontRenderParams::SUBPIXEL_RENDERING_NONE
,
149 params
.subpixel_rendering
);
151 query
.pixel_size
= 10;
152 params
= GetFontRenderParams(query
, NULL
);
153 EXPECT_FALSE(params
.antialiasing
);
154 EXPECT_EQ(FontRenderParams::HINTING_FULL
, params
.hinting
);
155 EXPECT_EQ(FontRenderParams::SUBPIXEL_RENDERING_NONE
,
156 params
.subpixel_rendering
);
158 query
.pixel_size
= 0;
159 query
.point_size
= 20;
160 params
= GetFontRenderParams(query
, NULL
);
161 EXPECT_TRUE(params
.antialiasing
);
162 EXPECT_EQ(FontRenderParams::HINTING_SLIGHT
, params
.hinting
);
163 EXPECT_EQ(FontRenderParams::SUBPIXEL_RENDERING_RGB
,
164 params
.subpixel_rendering
);
167 TEST_F(FontRenderParamsTest
, Style
) {
168 ASSERT_TRUE(LoadSystemFontIntoFontconfig("arial.ttf"));
169 // Load a config that disables subpixel rendering for bold text and disables
170 // hinting for italic text.
171 ASSERT_TRUE(LoadConfigDataIntoFontconfig(temp_dir_
.path(),
172 std::string(kFontconfigFileHeader
) +
173 kFontconfigMatchPatternHeader
+
174 CreateFontconfigEditStanza("antialias", "bool", "true") +
175 CreateFontconfigEditStanza("hinting", "bool", "true") +
176 CreateFontconfigEditStanza("hintstyle", "const", "hintslight") +
177 CreateFontconfigEditStanza("rgba", "const", "rgb") +
178 kFontconfigMatchFooter
+
179 kFontconfigMatchPatternHeader
+
180 CreateFontconfigTestStanza("weight", "eq", "const", "bold") +
181 CreateFontconfigEditStanza("rgba", "const", "none") +
182 kFontconfigMatchFooter
+
183 kFontconfigMatchPatternHeader
+
184 CreateFontconfigTestStanza("slant", "eq", "const", "italic") +
185 CreateFontconfigEditStanza("hinting", "bool", "false") +
186 kFontconfigMatchFooter
+
187 kFontconfigFileFooter
));
189 FontRenderParamsQuery query
;
190 query
.style
= Font::NORMAL
;
191 FontRenderParams params
= GetFontRenderParams(query
, NULL
);
192 EXPECT_EQ(FontRenderParams::HINTING_SLIGHT
, params
.hinting
);
193 EXPECT_EQ(FontRenderParams::SUBPIXEL_RENDERING_RGB
,
194 params
.subpixel_rendering
);
196 query
.style
= Font::BOLD
;
197 params
= GetFontRenderParams(query
, NULL
);
198 EXPECT_EQ(FontRenderParams::HINTING_SLIGHT
, params
.hinting
);
199 EXPECT_EQ(FontRenderParams::SUBPIXEL_RENDERING_NONE
,
200 params
.subpixel_rendering
);
202 query
.style
= Font::ITALIC
;
203 params
= GetFontRenderParams(query
, NULL
);
204 EXPECT_EQ(FontRenderParams::HINTING_NONE
, params
.hinting
);
205 EXPECT_EQ(FontRenderParams::SUBPIXEL_RENDERING_RGB
,
206 params
.subpixel_rendering
);
208 query
.style
= Font::BOLD
| Font::ITALIC
;
209 params
= GetFontRenderParams(query
, NULL
);
210 EXPECT_EQ(FontRenderParams::HINTING_NONE
, params
.hinting
);
211 EXPECT_EQ(FontRenderParams::SUBPIXEL_RENDERING_NONE
,
212 params
.subpixel_rendering
);
215 TEST_F(FontRenderParamsTest
, Scalable
) {
216 // Load a config that only enables antialiasing for scalable fonts.
217 ASSERT_TRUE(LoadConfigDataIntoFontconfig(temp_dir_
.path(),
218 std::string(kFontconfigFileHeader
) +
219 kFontconfigMatchPatternHeader
+
220 CreateFontconfigEditStanza("antialias", "bool", "false") +
221 kFontconfigMatchFooter
+
222 kFontconfigMatchPatternHeader
+
223 CreateFontconfigTestStanza("scalable", "eq", "bool", "true") +
224 CreateFontconfigEditStanza("antialias", "bool", "true") +
225 kFontconfigMatchFooter
+
226 kFontconfigFileFooter
));
228 // Check that we specifically ask how scalable fonts should be rendered.
229 FontRenderParams params
= GetFontRenderParams(
230 FontRenderParamsQuery(), NULL
);
231 EXPECT_TRUE(params
.antialiasing
);
234 TEST_F(FontRenderParamsTest
, UseBitmaps
) {
235 ASSERT_TRUE(LoadSystemFontIntoFontconfig("arial.ttf"));
236 // Load a config that enables embedded bitmaps for fonts <= 10 pixels.
237 ASSERT_TRUE(LoadConfigDataIntoFontconfig(temp_dir_
.path(),
238 std::string(kFontconfigFileHeader
) +
239 kFontconfigMatchPatternHeader
+
240 CreateFontconfigEditStanza("embeddedbitmap", "bool", "false") +
241 kFontconfigMatchFooter
+
242 kFontconfigMatchPatternHeader
+
243 CreateFontconfigTestStanza("pixelsize", "less_eq", "double", "10") +
244 CreateFontconfigEditStanza("embeddedbitmap", "bool", "true") +
245 kFontconfigMatchFooter
+
246 kFontconfigFileFooter
));
248 FontRenderParamsQuery query
;
249 FontRenderParams params
= GetFontRenderParams(query
, NULL
);
250 EXPECT_FALSE(params
.use_bitmaps
);
252 query
.pixel_size
= 5;
253 params
= GetFontRenderParams(query
, NULL
);
254 EXPECT_TRUE(params
.use_bitmaps
);
257 TEST_F(FontRenderParamsTest
, ForceFullHintingWhenAntialiasingIsDisabled
) {
258 // Load a config that disables antialiasing and hinting while requesting
259 // subpixel rendering.
260 ASSERT_TRUE(LoadConfigDataIntoFontconfig(temp_dir_
.path(),
261 std::string(kFontconfigFileHeader
) +
262 kFontconfigMatchPatternHeader
+
263 CreateFontconfigEditStanza("antialias", "bool", "false") +
264 CreateFontconfigEditStanza("hinting", "bool", "false") +
265 CreateFontconfigEditStanza("hintstyle", "const", "hintnone") +
266 CreateFontconfigEditStanza("rgba", "const", "rgb") +
267 kFontconfigMatchFooter
+
268 kFontconfigFileFooter
));
270 // Full hinting should be forced. See the comment in GetFontRenderParams() for
272 FontRenderParams params
= GetFontRenderParams(
273 FontRenderParamsQuery(), NULL
);
274 EXPECT_FALSE(params
.antialiasing
);
275 EXPECT_EQ(FontRenderParams::HINTING_FULL
, params
.hinting
);
276 EXPECT_EQ(FontRenderParams::SUBPIXEL_RENDERING_NONE
,
277 params
.subpixel_rendering
);
278 EXPECT_FALSE(params
.subpixel_positioning
);
281 #if defined(OS_CHROMEOS)
282 TEST_F(FontRenderParamsTest
, ForceSubpixelPositioning
) {
284 FontRenderParams params
=
285 GetFontRenderParams(FontRenderParamsQuery(), NULL
);
286 EXPECT_TRUE(params
.antialiasing
);
287 EXPECT_FALSE(params
.subpixel_positioning
);
288 SetFontRenderParamsDeviceScaleFactor(1.0f
);
290 ClearFontRenderParamsCacheForTest();
291 SetFontRenderParamsDeviceScaleFactor(1.25f
);
292 // Subpixel positioning should be forced.
294 FontRenderParams params
=
295 GetFontRenderParams(FontRenderParamsQuery(), NULL
);
296 EXPECT_TRUE(params
.antialiasing
);
297 EXPECT_TRUE(params
.subpixel_positioning
);
298 SetFontRenderParamsDeviceScaleFactor(1.0f
);
303 TEST_F(FontRenderParamsTest
, OnlySetConfiguredValues
) {
304 // Configure the LinuxFontDelegate (which queries GtkSettings on desktop
305 // Linux) to request subpixel rendering.
306 FontRenderParams system_params
;
307 system_params
.subpixel_rendering
= FontRenderParams::SUBPIXEL_RENDERING_RGB
;
308 test_font_delegate_
.set_params(system_params
);
310 // Load a Fontconfig config that enables antialiasing but doesn't say anything
311 // about subpixel rendering.
312 ASSERT_TRUE(LoadConfigDataIntoFontconfig(temp_dir_
.path(),
313 std::string(kFontconfigFileHeader
) +
314 kFontconfigMatchPatternHeader
+
315 CreateFontconfigEditStanza("antialias", "bool", "true") +
316 kFontconfigMatchFooter
+
317 kFontconfigFileFooter
));
319 // The subpixel rendering setting from the delegate should make it through.
320 FontRenderParams params
= GetFontRenderParams(
321 FontRenderParamsQuery(), NULL
);
322 EXPECT_EQ(system_params
.subpixel_rendering
, params
.subpixel_rendering
);
325 TEST_F(FontRenderParamsTest
, NoFontconfigMatch
) {
326 // Don't load a Fontconfig configuration.
327 FontRenderParams system_params
;
328 system_params
.antialiasing
= true;
329 system_params
.hinting
= FontRenderParams::HINTING_MEDIUM
;
330 system_params
.subpixel_rendering
= FontRenderParams::SUBPIXEL_RENDERING_RGB
;
331 test_font_delegate_
.set_params(system_params
);
333 FontRenderParamsQuery query
;
334 query
.families
.push_back("Arial");
335 query
.families
.push_back("Times New Roman");
336 query
.pixel_size
= 10;
337 std::string suggested_family
;
338 FontRenderParams params
= GetFontRenderParams(query
, &suggested_family
);
340 // The system params and the first requested family should be returned.
341 EXPECT_EQ(system_params
.antialiasing
, params
.antialiasing
);
342 EXPECT_EQ(system_params
.hinting
, params
.hinting
);
343 EXPECT_EQ(system_params
.subpixel_rendering
, params
.subpixel_rendering
);
344 EXPECT_EQ(query
.families
[0], suggested_family
);
347 TEST_F(FontRenderParamsTest
, MissingFamily
) {
348 // With Arial and Verdana installed, request (in order) Helvetica, Arial, and
349 // Verdana and check that Arial is returned.
350 ASSERT_TRUE(LoadSystemFontIntoFontconfig("arial.ttf"));
351 ASSERT_TRUE(LoadSystemFontIntoFontconfig("verdana.ttf"));
352 FontRenderParamsQuery query
;
353 query
.families
.push_back("Helvetica");
354 query
.families
.push_back("Arial");
355 query
.families
.push_back("Verdana");
356 std::string suggested_family
;
357 GetFontRenderParams(query
, &suggested_family
);
358 EXPECT_EQ("Arial", suggested_family
);
361 TEST_F(FontRenderParamsTest
, SubstituteFamily
) {
362 // Configure Fontconfig to use Verdana for both Helvetica and Arial.
363 ASSERT_TRUE(LoadSystemFontIntoFontconfig("arial.ttf"));
364 ASSERT_TRUE(LoadSystemFontIntoFontconfig("verdana.ttf"));
365 ASSERT_TRUE(LoadConfigDataIntoFontconfig(temp_dir_
.path(),
366 std::string(kFontconfigFileHeader
) +
367 CreateFontconfigAliasStanza("Helvetica", "Verdana") +
368 kFontconfigMatchPatternHeader
+
369 CreateFontconfigTestStanza("family", "eq", "string", "Arial") +
370 CreateFontconfigEditStanza("family", "string", "Verdana") +
371 kFontconfigMatchFooter
+
372 kFontconfigFileFooter
));
374 FontRenderParamsQuery query
;
375 query
.families
.push_back("Helvetica");
376 std::string suggested_family
;
377 GetFontRenderParams(query
, &suggested_family
);
378 EXPECT_EQ("Verdana", suggested_family
);
380 query
.families
.clear();
381 query
.families
.push_back("Arial");
382 suggested_family
.clear();
383 GetFontRenderParams(query
, &suggested_family
);
384 EXPECT_EQ("Verdana", suggested_family
);