OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/gfx/font_render_params.h" | 5 #include "ui/gfx/font_render_params.h" |
6 | 6 |
7 #include <fontconfig/fontconfig.h> | 7 #include <fontconfig/fontconfig.h> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/containers/mru_cache.h" | 10 #include "base/containers/mru_cache.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 struct SynchronizedCache { | 54 struct SynchronizedCache { |
55 SynchronizedCache() : cache(kCacheSize) {} | 55 SynchronizedCache() : cache(kCacheSize) {} |
56 | 56 |
57 base::Lock lock; | 57 base::Lock lock; |
58 Cache cache; | 58 Cache cache; |
59 }; | 59 }; |
60 | 60 |
61 base::LazyInstance<SynchronizedCache>::Leaky g_synchronized_cache = | 61 base::LazyInstance<SynchronizedCache>::Leaky g_synchronized_cache = |
62 LAZY_INSTANCE_INITIALIZER; | 62 LAZY_INSTANCE_INITIALIZER; |
63 | 63 |
64 bool IsBrowserTextSubpixelPositioningEnabled() { | 64 bool IsBrowserTextSubpixelPositioningEnabled( |
| 65 const FontRenderParamsQuery& query) { |
65 #if defined(OS_CHROMEOS) | 66 #if defined(OS_CHROMEOS) |
66 return device_scale_factor_for_internal_display > 1.0f; | 67 return query.device_scale_factor > 1.0f; |
67 #else | 68 #else |
68 return false; | 69 return false; |
69 #endif | 70 #endif |
70 } | 71 } |
71 | 72 |
72 // Converts Fontconfig FC_HINT_STYLE to FontRenderParams::Hinting. | 73 // Converts Fontconfig FC_HINT_STYLE to FontRenderParams::Hinting. |
73 FontRenderParams::Hinting ConvertFontconfigHintStyle(int hint_style) { | 74 FontRenderParams::Hinting ConvertFontconfigHintStyle(int hint_style) { |
74 switch (hint_style) { | 75 switch (hint_style) { |
75 case FC_HINT_SLIGHT: return FontRenderParams::HINTING_SLIGHT; | 76 case FC_HINT_SLIGHT: return FontRenderParams::HINTING_SLIGHT; |
76 case FC_HINT_MEDIUM: return FontRenderParams::HINTING_MEDIUM; | 77 case FC_HINT_MEDIUM: return FontRenderParams::HINTING_MEDIUM; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 params_out->subpixel_rendering = ConvertFontconfigRgba(fc_rgba); | 173 params_out->subpixel_rendering = ConvertFontconfigRgba(fc_rgba); |
173 } | 174 } |
174 | 175 |
175 FcPatternDestroy(result_pattern); | 176 FcPatternDestroy(result_pattern); |
176 return true; | 177 return true; |
177 } | 178 } |
178 | 179 |
179 // Serialize |query| into a string and hash it to a value suitable for use as a | 180 // Serialize |query| into a string and hash it to a value suitable for use as a |
180 // cache key. | 181 // cache key. |
181 uint32 HashFontRenderParamsQuery(const FontRenderParamsQuery& query) { | 182 uint32 HashFontRenderParamsQuery(const FontRenderParamsQuery& query) { |
182 return base::Hash(base::StringPrintf("%d|%d|%d|%d|%s", | 183 return base::Hash(base::StringPrintf( |
183 query.for_web_contents, query.pixel_size, query.point_size, query.style, | 184 "%d|%d|%d|%d|%s|%f", query.for_web_contents, query.pixel_size, |
184 JoinString(query.families, ',').c_str())); | 185 query.point_size, query.style, JoinString(query.families, ',').c_str(), |
| 186 query.device_scale_factor)); |
185 } | 187 } |
186 | 188 |
187 } // namespace | 189 } // namespace |
188 | 190 |
189 FontRenderParams GetFontRenderParams(const FontRenderParamsQuery& query, | 191 FontRenderParams GetFontRenderParams(const FontRenderParamsQuery& query, |
190 std::string* family_out) { | 192 std::string* family_out) { |
191 const uint32 hash = HashFontRenderParamsQuery(query); | 193 FontRenderParamsQuery actual_query(query); |
| 194 if (actual_query.device_scale_factor == 0) |
| 195 actual_query.device_scale_factor = device_scale_factor_for_internal_display; |
| 196 const uint32 hash = HashFontRenderParamsQuery(actual_query); |
192 SynchronizedCache* synchronized_cache = g_synchronized_cache.Pointer(); | 197 SynchronizedCache* synchronized_cache = g_synchronized_cache.Pointer(); |
193 | 198 |
194 { | 199 { |
195 // Try to find a cached result so Fontconfig doesn't need to be queried. | 200 // Try to find a cached result so Fontconfig doesn't need to be queried. |
196 base::AutoLock lock(synchronized_cache->lock); | 201 base::AutoLock lock(synchronized_cache->lock); |
197 Cache::const_iterator it = synchronized_cache->cache.Get(hash); | 202 Cache::const_iterator it = synchronized_cache->cache.Get(hash); |
198 if (it != synchronized_cache->cache.end()) { | 203 if (it != synchronized_cache->cache.end()) { |
199 DVLOG(1) << "Returning cached params for " << hash; | 204 DVLOG(1) << "Returning cached params for " << hash; |
200 const QueryResult& result = it->second; | 205 const QueryResult& result = it->second; |
201 if (family_out) | 206 if (family_out) |
202 *family_out = result.family; | 207 *family_out = result.family; |
203 return result.params; | 208 return result.params; |
204 } | 209 } |
205 } | 210 } |
206 | 211 |
207 DVLOG(1) << "Computing params for " << hash; | 212 DVLOG(1) << "Computing params for " << hash; |
208 if (family_out) | 213 if (family_out) |
209 family_out->clear(); | 214 family_out->clear(); |
210 | 215 |
211 // Start with the delegate's settings, but let Fontconfig have the final say. | 216 // Start with the delegate's settings, but let Fontconfig have the final say. |
212 FontRenderParams params; | 217 FontRenderParams params; |
213 const LinuxFontDelegate* delegate = LinuxFontDelegate::instance(); | 218 const LinuxFontDelegate* delegate = LinuxFontDelegate::instance(); |
214 if (delegate) | 219 if (delegate) |
215 params = delegate->GetDefaultFontRenderParams(); | 220 params = delegate->GetDefaultFontRenderParams(); |
216 QueryFontconfig(query, ¶ms, family_out); | 221 QueryFontconfig(actual_query, ¶ms, family_out); |
217 if (!params.antialiasing) { | 222 if (!params.antialiasing) { |
218 // Cairo forces full hinting when antialiasing is disabled, since anything | 223 // Cairo forces full hinting when antialiasing is disabled, since anything |
219 // less than that looks awful; do the same here. Requesting subpixel | 224 // less than that looks awful; do the same here. Requesting subpixel |
220 // rendering or positioning doesn't make sense either. | 225 // rendering or positioning doesn't make sense either. |
221 params.hinting = FontRenderParams::HINTING_FULL; | 226 params.hinting = FontRenderParams::HINTING_FULL; |
222 params.subpixel_rendering = FontRenderParams::SUBPIXEL_RENDERING_NONE; | 227 params.subpixel_rendering = FontRenderParams::SUBPIXEL_RENDERING_NONE; |
223 params.subpixel_positioning = false; | 228 params.subpixel_positioning = false; |
224 } else { | 229 } else { |
225 // Fontconfig doesn't support configuring subpixel positioning; check a | 230 // Fontconfig doesn't support configuring subpixel positioning; check a |
226 // flag. | 231 // flag. |
227 params.subpixel_positioning = | 232 params.subpixel_positioning = |
228 query.for_web_contents ? | 233 actual_query.for_web_contents |
229 CommandLine::ForCurrentProcess()->HasSwitch( | 234 ? CommandLine::ForCurrentProcess()->HasSwitch( |
230 switches::kEnableWebkitTextSubpixelPositioning) : | 235 switches::kEnableWebkitTextSubpixelPositioning) |
231 IsBrowserTextSubpixelPositioningEnabled(); | 236 : IsBrowserTextSubpixelPositioningEnabled(actual_query); |
232 | 237 |
233 // To enable subpixel positioning, we need to disable hinting. | 238 // To enable subpixel positioning, we need to disable hinting. |
234 if (params.subpixel_positioning) | 239 if (params.subpixel_positioning) |
235 params.hinting = FontRenderParams::HINTING_NONE; | 240 params.hinting = FontRenderParams::HINTING_NONE; |
236 } | 241 } |
237 | 242 |
238 // Use the first family from the list if Fontconfig didn't suggest a family. | 243 // Use the first family from the list if Fontconfig didn't suggest a family. |
239 if (family_out && family_out->empty() && !query.families.empty()) | 244 if (family_out && family_out->empty() && !actual_query.families.empty()) |
240 *family_out = query.families[0]; | 245 *family_out = actual_query.families[0]; |
241 | 246 |
242 { | 247 { |
243 // Store the result. It's fine if this overwrites a result that was cached | 248 // Store the result. It's fine if this overwrites a result that was cached |
244 // by a different thread in the meantime; the values should be identical. | 249 // by a different thread in the meantime; the values should be identical. |
245 base::AutoLock lock(synchronized_cache->lock); | 250 base::AutoLock lock(synchronized_cache->lock); |
246 synchronized_cache->cache.Put(hash, | 251 synchronized_cache->cache.Put(hash, |
247 QueryResult(params, family_out ? *family_out : std::string())); | 252 QueryResult(params, family_out ? *family_out : std::string())); |
248 } | 253 } |
249 | 254 |
250 return params; | 255 return params; |
251 } | 256 } |
252 | 257 |
253 void ClearFontRenderParamsCacheForTest() { | 258 void ClearFontRenderParamsCacheForTest() { |
254 SynchronizedCache* synchronized_cache = g_synchronized_cache.Pointer(); | 259 SynchronizedCache* synchronized_cache = g_synchronized_cache.Pointer(); |
255 base::AutoLock lock(synchronized_cache->lock); | 260 base::AutoLock lock(synchronized_cache->lock); |
256 synchronized_cache->cache.Clear(); | 261 synchronized_cache->cache.Clear(); |
257 } | 262 } |
258 | 263 |
259 #if defined(OS_CHROMEOS) | 264 #if defined(OS_CHROMEOS) |
| 265 float GetFontRenderParamsDeviceScaleFactor() { |
| 266 return device_scale_factor_for_internal_display; |
| 267 } |
| 268 |
260 void SetFontRenderParamsDeviceScaleFactor(float device_scale_factor) { | 269 void SetFontRenderParamsDeviceScaleFactor(float device_scale_factor) { |
261 device_scale_factor_for_internal_display = device_scale_factor; | 270 device_scale_factor_for_internal_display = device_scale_factor; |
262 } | 271 } |
263 #endif | 272 #endif |
264 | 273 |
265 } // namespace gfx | 274 } // namespace gfx |
OLD | NEW |