Chromium Code Reviews| 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 "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/containers/mru_cache.h" | |
| 9 #include "base/hash.h" | |
| 8 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/macros.h" | |
| 12 #include "base/strings/string_util.h" | |
| 13 #include "base/strings/stringprintf.h" | |
| 9 #include "ui/gfx/font.h" | 14 #include "ui/gfx/font.h" |
| 10 #include "ui/gfx/linux_font_delegate.h" | 15 #include "ui/gfx/linux_font_delegate.h" |
| 11 #include "ui/gfx/switches.h" | 16 #include "ui/gfx/switches.h" |
| 12 | 17 |
| 13 #include <fontconfig/fontconfig.h> | 18 #include <fontconfig/fontconfig.h> |
| 14 | 19 |
| 15 namespace gfx { | 20 namespace gfx { |
| 16 | 21 |
| 17 namespace { | 22 namespace { |
| 18 | 23 |
| 24 // Should cache entries by dropped by the next call to GetFontRenderParams()? | |
| 25 // Used for tests. | |
| 26 bool g_drop_cache = false; | |
|
msw
2014/08/05 00:55:10
nit: g_drop_cache_for_test
Daniel Erat
2014/08/06 17:43:13
done (well, g_clear_cache_for_test to match the fu
| |
| 27 | |
| 28 // Number of recent GetFontRenderParams() results to cache. | |
| 29 const size_t kCacheSize = 10; | |
|
Daniel Erat
2014/08/04 23:44:43
i pulled this number out of the air, but it seems
msw
2014/08/05 00:55:10
Acknowledged.
| |
| 30 | |
| 19 // Converts Fontconfig FC_HINT_STYLE to FontRenderParams::Hinting. | 31 // Converts Fontconfig FC_HINT_STYLE to FontRenderParams::Hinting. |
| 20 FontRenderParams::Hinting ConvertFontconfigHintStyle(int hint_style) { | 32 FontRenderParams::Hinting ConvertFontconfigHintStyle(int hint_style) { |
| 21 switch (hint_style) { | 33 switch (hint_style) { |
| 22 case FC_HINT_SLIGHT: return FontRenderParams::HINTING_SLIGHT; | 34 case FC_HINT_SLIGHT: return FontRenderParams::HINTING_SLIGHT; |
| 23 case FC_HINT_MEDIUM: return FontRenderParams::HINTING_MEDIUM; | 35 case FC_HINT_MEDIUM: return FontRenderParams::HINTING_MEDIUM; |
| 24 case FC_HINT_FULL: return FontRenderParams::HINTING_FULL; | 36 case FC_HINT_FULL: return FontRenderParams::HINTING_FULL; |
| 25 default: return FontRenderParams::HINTING_NONE; | 37 default: return FontRenderParams::HINTING_NONE; |
| 26 } | 38 } |
| 27 } | 39 } |
| 28 | 40 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 107 | 119 |
| 108 int fc_rgba = FC_RGBA_NONE; | 120 int fc_rgba = FC_RGBA_NONE; |
| 109 if (FcPatternGetInteger(match, FC_RGBA, 0, &fc_rgba) == FcResultMatch) | 121 if (FcPatternGetInteger(match, FC_RGBA, 0, &fc_rgba) == FcResultMatch) |
| 110 params_out->subpixel_rendering = ConvertFontconfigRgba(fc_rgba); | 122 params_out->subpixel_rendering = ConvertFontconfigRgba(fc_rgba); |
| 111 } | 123 } |
| 112 | 124 |
| 113 FcPatternDestroy(match); | 125 FcPatternDestroy(match); |
| 114 return true; | 126 return true; |
| 115 } | 127 } |
| 116 | 128 |
| 129 // Serialize |query| into a string and hash it to a value suitable for use as a | |
| 130 // cache key. | |
| 131 uint32 HashFontRenderParamsQuery(const FontRenderParamsQuery& query) { | |
| 132 return base::Hash(base::StringPrintf("%d|%d|%d|%d|%s", | |
|
Daniel Erat
2014/08/04 23:44:43
this is ugly. i can't just pass the FontRenderPara
msw
2014/08/05 00:55:10
Acknowledged.
| |
| 133 query.for_web_contents, query.pixel_size, query.point_size, query.style, | |
| 134 JoinString(query.families, ',').c_str())); | |
| 135 } | |
| 136 | |
| 117 } // namespace | 137 } // namespace |
| 118 | 138 |
| 119 FontRenderParams GetFontRenderParams(const FontRenderParamsQuery& query, | 139 FontRenderParams GetFontRenderParams(const FontRenderParamsQuery& query, |
| 120 std::string* family_out) { | 140 std::string* family_out) { |
| 121 if (family_out) | 141 typedef base::MRUCache<uint32, FontRenderParams> Cache; |
|
msw
2014/08/05 00:55:10
optional nit: key on FontRenderParamsQuery and dit
Daniel Erat
2014/08/06 17:43:13
i tried this at first, but MRUCache uses std::map,
msw
2014/08/06 19:31:38
Acknowledged.
| |
| 142 CR_DEFINE_STATIC_LOCAL(Cache, cache, (kCacheSize)); | |
| 143 | |
| 144 if (g_drop_cache) { | |
|
msw
2014/08/05 00:55:10
This pattern is slightly ugly, did you consider an
Daniel Erat
2014/08/06 17:43:13
yes, but let me know if you can think of anything
msw
2014/08/06 19:31:38
Shrug, I guess it's fine as-is.
| |
| 145 cache.Clear(); | |
| 146 g_drop_cache = false; | |
| 147 } | |
| 148 | |
| 149 const uint32 hash = HashFontRenderParamsQuery(query); | |
| 150 if (!family_out) { | |
| 151 // The family returned by Fontconfig isn't part of FontRenderParams, so we | |
| 152 // can only return a value from the cache if it wasn't requested. | |
| 153 Cache::const_iterator it = cache.Get(hash); | |
| 154 if (it != cache.end()) | |
| 155 return it->second; | |
| 156 } else { | |
| 122 family_out->clear(); | 157 family_out->clear(); |
| 158 } | |
| 123 | 159 |
| 124 // Start with the delegate's settings, but let Fontconfig have the final say. | 160 // Start with the delegate's settings, but let Fontconfig have the final say. |
| 125 FontRenderParams params; | 161 FontRenderParams params; |
| 126 const LinuxFontDelegate* delegate = LinuxFontDelegate::instance(); | 162 const LinuxFontDelegate* delegate = LinuxFontDelegate::instance(); |
| 127 if (delegate) | 163 if (delegate) |
| 128 params = delegate->GetDefaultFontRenderParams(); | 164 params = delegate->GetDefaultFontRenderParams(); |
| 129 QueryFontconfig(query, ¶ms, family_out); | 165 QueryFontconfig(query, ¶ms, family_out); |
| 130 | 166 |
| 131 if (!params.antialiasing) { | 167 if (!params.antialiasing) { |
| 132 // Cairo forces full hinting when antialiasing is disabled, since anything | 168 // Cairo forces full hinting when antialiasing is disabled, since anything |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 145 | 181 |
| 146 // To enable subpixel positioning, we need to disable hinting. | 182 // To enable subpixel positioning, we need to disable hinting. |
| 147 if (params.subpixel_positioning) | 183 if (params.subpixel_positioning) |
| 148 params.hinting = FontRenderParams::HINTING_NONE; | 184 params.hinting = FontRenderParams::HINTING_NONE; |
| 149 } | 185 } |
| 150 | 186 |
| 151 // Use the first family from the list if Fontconfig didn't suggest a family. | 187 // Use the first family from the list if Fontconfig didn't suggest a family. |
| 152 if (family_out && family_out->empty() && !query.families.empty()) | 188 if (family_out && family_out->empty() && !query.families.empty()) |
| 153 *family_out = query.families[0]; | 189 *family_out = query.families[0]; |
| 154 | 190 |
| 191 cache.Put(hash, params); | |
| 155 return params; | 192 return params; |
| 156 } | 193 } |
| 157 | 194 |
| 195 void DropFontRenderParamsCacheForTest() { | |
| 196 g_drop_cache = true; | |
| 197 } | |
| 198 | |
| 158 } // namespace gfx | 199 } // namespace gfx |
| OLD | NEW |