| 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 |