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" |
11 #include "base/hash.h" | 11 #include "base/hash.h" |
12 #include "base/lazy_instance.h" | 12 #include "base/lazy_instance.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/macros.h" | 14 #include "base/macros.h" |
| 15 #include "base/memory/scoped_ptr.h" |
15 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
16 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
17 #include "base/synchronization/lock.h" | 18 #include "base/synchronization/lock.h" |
18 #include "ui/gfx/font.h" | 19 #include "ui/gfx/font.h" |
19 #include "ui/gfx/linux_font_delegate.h" | 20 #include "ui/gfx/linux_font_delegate.h" |
20 #include "ui/gfx/switches.h" | 21 #include "ui/gfx/switches.h" |
21 | 22 |
22 namespace gfx { | 23 namespace gfx { |
23 | 24 |
24 namespace { | 25 namespace { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 case FC_RGBA_VBGR: return FontRenderParams::SUBPIXEL_RENDERING_VBGR; | 90 case FC_RGBA_VBGR: return FontRenderParams::SUBPIXEL_RENDERING_VBGR; |
90 default: return FontRenderParams::SUBPIXEL_RENDERING_NONE; | 91 default: return FontRenderParams::SUBPIXEL_RENDERING_NONE; |
91 } | 92 } |
92 } | 93 } |
93 | 94 |
94 // Queries Fontconfig for rendering settings and updates |params_out| and | 95 // Queries Fontconfig for rendering settings and updates |params_out| and |
95 // |family_out| (if non-NULL). Returns false on failure. | 96 // |family_out| (if non-NULL). Returns false on failure. |
96 bool QueryFontconfig(const FontRenderParamsQuery& query, | 97 bool QueryFontconfig(const FontRenderParamsQuery& query, |
97 FontRenderParams* params_out, | 98 FontRenderParams* params_out, |
98 std::string* family_out) { | 99 std::string* family_out) { |
99 FcPattern* query_pattern = FcPatternCreate(); | 100 struct FcPatternDeleter { |
| 101 void operator()(FcPattern* ptr) const { FcPatternDestroy(ptr); } |
| 102 }; |
| 103 typedef scoped_ptr<FcPattern, FcPatternDeleter> ScopedFcPattern; |
| 104 |
| 105 ScopedFcPattern query_pattern(FcPatternCreate()); |
100 CHECK(query_pattern); | 106 CHECK(query_pattern); |
101 | 107 |
102 FcPatternAddBool(query_pattern, FC_SCALABLE, FcTrue); | 108 FcPatternAddBool(query_pattern.get(), FC_SCALABLE, FcTrue); |
103 | 109 |
104 for (std::vector<std::string>::const_iterator it = query.families.begin(); | 110 for (std::vector<std::string>::const_iterator it = query.families.begin(); |
105 it != query.families.end(); ++it) { | 111 it != query.families.end(); ++it) { |
106 FcPatternAddString(query_pattern, | 112 FcPatternAddString(query_pattern.get(), |
107 FC_FAMILY, reinterpret_cast<const FcChar8*>(it->c_str())); | 113 FC_FAMILY, reinterpret_cast<const FcChar8*>(it->c_str())); |
108 } | 114 } |
109 if (query.pixel_size > 0) | 115 if (query.pixel_size > 0) |
110 FcPatternAddDouble(query_pattern, FC_PIXEL_SIZE, query.pixel_size); | 116 FcPatternAddDouble(query_pattern.get(), FC_PIXEL_SIZE, query.pixel_size); |
111 if (query.point_size > 0) | 117 if (query.point_size > 0) |
112 FcPatternAddInteger(query_pattern, FC_SIZE, query.point_size); | 118 FcPatternAddInteger(query_pattern.get(), FC_SIZE, query.point_size); |
113 if (query.style >= 0) { | 119 if (query.style >= 0) { |
114 FcPatternAddInteger(query_pattern, FC_SLANT, | 120 FcPatternAddInteger(query_pattern.get(), FC_SLANT, |
115 (query.style & Font::ITALIC) ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); | 121 (query.style & Font::ITALIC) ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); |
116 FcPatternAddInteger(query_pattern, FC_WEIGHT, | 122 FcPatternAddInteger(query_pattern.get(), FC_WEIGHT, |
117 (query.style & Font::BOLD) ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL); | 123 (query.style & Font::BOLD) ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL); |
118 } | 124 } |
119 | 125 |
120 FcConfigSubstitute(NULL, query_pattern, FcMatchPattern); | 126 FcConfigSubstitute(NULL, query_pattern.get(), FcMatchPattern); |
121 FcDefaultSubstitute(query_pattern); | 127 FcDefaultSubstitute(query_pattern.get()); |
122 | 128 |
123 // If the query was non-empty, match a specific font and destroy the query | 129 ScopedFcPattern result_pattern; |
124 // pattern. Otherwise, just use the query pattern. | 130 if (query.is_empty()) { |
125 FcPattern* result_pattern = query_pattern; | 131 // If the query was empty, call FcConfigSubstituteWithPat() to get |
126 if (!query.is_empty()) { | 132 // non-family-specific configuration so it can be used as the default. |
| 133 result_pattern.reset(FcPatternDuplicate(query_pattern.get())); |
| 134 if (!result_pattern) |
| 135 return false; |
| 136 FcPatternDel(result_pattern.get(), FC_FAMILY); |
| 137 FcConfigSubstituteWithPat(NULL, result_pattern.get(), query_pattern.get(), |
| 138 FcMatchFont); |
| 139 } else { |
127 FcResult result; | 140 FcResult result; |
128 result_pattern = FcFontMatch(NULL, query_pattern, &result); | 141 result_pattern.reset(FcFontMatch(NULL, query_pattern.get(), &result)); |
129 FcPatternDestroy(query_pattern); | |
130 query_pattern = NULL; | |
131 if (!result_pattern) | 142 if (!result_pattern) |
132 return false; | 143 return false; |
133 } | 144 } |
| 145 DCHECK(result_pattern); |
134 | 146 |
135 if (family_out) { | 147 if (family_out) { |
136 FcChar8* family = NULL; | 148 FcChar8* family = NULL; |
137 FcPatternGetString(result_pattern, FC_FAMILY, 0, &family); | 149 FcPatternGetString(result_pattern.get(), FC_FAMILY, 0, &family); |
138 if (family) | 150 if (family) |
139 family_out->assign(reinterpret_cast<const char*>(family)); | 151 family_out->assign(reinterpret_cast<const char*>(family)); |
140 } | 152 } |
141 | 153 |
142 if (params_out) { | 154 if (params_out) { |
143 FcBool fc_antialias = 0; | 155 FcBool fc_antialias = 0; |
144 if (FcPatternGetBool(result_pattern, FC_ANTIALIAS, 0, &fc_antialias) == | 156 if (FcPatternGetBool(result_pattern.get(), FC_ANTIALIAS, 0, |
145 FcResultMatch) { | 157 &fc_antialias) == FcResultMatch) { |
146 params_out->antialiasing = fc_antialias; | 158 params_out->antialiasing = fc_antialias; |
147 } | 159 } |
148 | 160 |
149 FcBool fc_autohint = 0; | 161 FcBool fc_autohint = 0; |
150 if (FcPatternGetBool(result_pattern, FC_AUTOHINT, 0, &fc_autohint) == | 162 if (FcPatternGetBool(result_pattern.get(), FC_AUTOHINT, 0, &fc_autohint) == |
151 FcResultMatch) { | 163 FcResultMatch) { |
152 params_out->autohinter = fc_autohint; | 164 params_out->autohinter = fc_autohint; |
153 } | 165 } |
154 | 166 |
155 FcBool fc_bitmap = 0; | 167 FcBool fc_bitmap = 0; |
156 if (FcPatternGetBool(result_pattern, FC_EMBEDDED_BITMAP, 0, &fc_bitmap) == | 168 if (FcPatternGetBool(result_pattern.get(), FC_EMBEDDED_BITMAP, 0, |
| 169 &fc_bitmap) == |
157 FcResultMatch) { | 170 FcResultMatch) { |
158 params_out->use_bitmaps = fc_bitmap; | 171 params_out->use_bitmaps = fc_bitmap; |
159 } | 172 } |
160 | 173 |
161 FcBool fc_hinting = 0; | 174 FcBool fc_hinting = 0; |
162 if (FcPatternGetBool(result_pattern, FC_HINTING, 0, &fc_hinting) == | 175 if (FcPatternGetBool(result_pattern.get(), FC_HINTING, 0, &fc_hinting) == |
163 FcResultMatch) { | 176 FcResultMatch) { |
164 int fc_hint_style = FC_HINT_NONE; | 177 int fc_hint_style = FC_HINT_NONE; |
165 if (fc_hinting) | 178 if (fc_hinting) { |
166 FcPatternGetInteger(result_pattern, FC_HINT_STYLE, 0, &fc_hint_style); | 179 FcPatternGetInteger( |
| 180 result_pattern.get(), FC_HINT_STYLE, 0, &fc_hint_style); |
| 181 } |
167 params_out->hinting = ConvertFontconfigHintStyle(fc_hint_style); | 182 params_out->hinting = ConvertFontconfigHintStyle(fc_hint_style); |
168 } | 183 } |
169 | 184 |
170 int fc_rgba = FC_RGBA_NONE; | 185 int fc_rgba = FC_RGBA_NONE; |
171 if (FcPatternGetInteger(result_pattern, FC_RGBA, 0, &fc_rgba) == | 186 if (FcPatternGetInteger(result_pattern.get(), FC_RGBA, 0, &fc_rgba) == |
172 FcResultMatch) | 187 FcResultMatch) |
173 params_out->subpixel_rendering = ConvertFontconfigRgba(fc_rgba); | 188 params_out->subpixel_rendering = ConvertFontconfigRgba(fc_rgba); |
174 } | 189 } |
175 | 190 |
176 FcPatternDestroy(result_pattern); | |
177 return true; | 191 return true; |
178 } | 192 } |
179 | 193 |
180 // Serialize |query| into a string and hash it to a value suitable for use as a | 194 // Serialize |query| into a string and hash it to a value suitable for use as a |
181 // cache key. | 195 // cache key. |
182 uint32 HashFontRenderParamsQuery(const FontRenderParamsQuery& query) { | 196 uint32 HashFontRenderParamsQuery(const FontRenderParamsQuery& query) { |
183 return base::Hash(base::StringPrintf( | 197 return base::Hash(base::StringPrintf( |
184 "%d|%d|%d|%d|%s|%f", query.for_web_contents, query.pixel_size, | 198 "%d|%d|%d|%d|%s|%f", query.for_web_contents, query.pixel_size, |
185 query.point_size, query.style, JoinString(query.families, ',').c_str(), | 199 query.point_size, query.style, JoinString(query.families, ',').c_str(), |
186 query.device_scale_factor)); | 200 query.device_scale_factor)); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 float GetFontRenderParamsDeviceScaleFactor() { | 281 float GetFontRenderParamsDeviceScaleFactor() { |
268 return device_scale_factor_for_internal_display; | 282 return device_scale_factor_for_internal_display; |
269 } | 283 } |
270 | 284 |
271 void SetFontRenderParamsDeviceScaleFactor(float device_scale_factor) { | 285 void SetFontRenderParamsDeviceScaleFactor(float device_scale_factor) { |
272 device_scale_factor_for_internal_display = device_scale_factor; | 286 device_scale_factor_for_internal_display = device_scale_factor; |
273 } | 287 } |
274 #endif | 288 #endif |
275 | 289 |
276 } // namespace gfx | 290 } // namespace gfx |
OLD | NEW |