Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: ui/gfx/platform_font_linux.cc

Issue 1819753003: Allow various font weights in gfx. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add a lost comment and modify a render text unittest to not test black because of test env font con… Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/gfx/platform_font_linux.h ('k') | ui/gfx/platform_font_linux_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/platform_font_linux.h" 5 #include "ui/gfx/platform_font_linux.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/strings/string_piece.h" 12 #include "base/strings/string_piece.h"
13 #include "base/strings/string_split.h" 13 #include "base/strings/string_split.h"
14 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 #include "build/build_config.h" 15 #include "build/build_config.h"
16 #include "third_party/skia/include/core/SkFontStyle.h"
16 #include "third_party/skia/include/core/SkPaint.h" 17 #include "third_party/skia/include/core/SkPaint.h"
17 #include "third_party/skia/include/core/SkString.h" 18 #include "third_party/skia/include/core/SkString.h"
18 #include "third_party/skia/include/core/SkTypeface.h" 19 #include "third_party/skia/include/core/SkTypeface.h"
19 #include "ui/gfx/canvas.h" 20 #include "ui/gfx/canvas.h"
20 #include "ui/gfx/font.h" 21 #include "ui/gfx/font.h"
21 #include "ui/gfx/font_list.h" 22 #include "ui/gfx/font_list.h"
22 #include "ui/gfx/linux_font_delegate.h" 23 #include "ui/gfx/linux_font_delegate.h"
23 #include "ui/gfx/text_utils.h" 24 #include "ui/gfx/text_utils.h"
24 25
25 namespace gfx { 26 namespace gfx {
26 namespace { 27 namespace {
27 28
28 // The font family name which is used when a user's application font for 29 // The font family name which is used when a user's application font for
29 // GNOME/KDE is a non-scalable one. The name should be listed in the 30 // GNOME/KDE is a non-scalable one. The name should be listed in the
30 // IsFallbackFontAllowed function in skia/ext/SkFontHost_fontconfig_direct.cpp. 31 // IsFallbackFontAllowed function in skia/ext/SkFontHost_fontconfig_direct.cpp.
31 #if defined(OS_ANDROID) 32 #if defined(OS_ANDROID)
32 const char* kFallbackFontFamilyName = "serif"; 33 const char* kFallbackFontFamilyName = "serif";
33 #else 34 #else
34 const char* kFallbackFontFamilyName = "sans"; 35 const char* kFallbackFontFamilyName = "sans";
35 #endif 36 #endif
36 37
37 // The default font, used for the default constructor. 38 // The default font, used for the default constructor.
38 base::LazyInstance<scoped_refptr<PlatformFontLinux>>::Leaky g_default_font = 39 base::LazyInstance<scoped_refptr<PlatformFontLinux>>::Leaky g_default_font =
39 LAZY_INSTANCE_INITIALIZER; 40 LAZY_INSTANCE_INITIALIZER;
40 41
41 // Creates a SkTypeface for the passed-in Font::FontStyle and family. If a 42 // Creates a SkTypeface for the passed-in Font::FontStyle and family. If a
42 // fallback typeface is used instead of the requested family, |family| will be 43 // fallback typeface is used instead of the requested family, |family| will be
43 // updated to contain the fallback's family name. 44 // updated to contain the fallback's family name.
44 sk_sp<SkTypeface> CreateSkTypeface(int style, std::string* family) { 45 sk_sp<SkTypeface> CreateSkTypeface(bool italic,
46 gfx::Font::Weight weight,
47 std::string* family) {
45 DCHECK(family); 48 DCHECK(family);
46 49
47 int skia_style = SkTypeface::kNormal; 50 const int font_weight = (weight == Font::Weight::INVALID)
48 if (Font::BOLD & style) 51 ? static_cast<int>(Font::Weight::NORMAL)
49 skia_style |= SkTypeface::kBold; 52 : static_cast<int>(weight);
50 if (Font::ITALIC & style) 53 SkFontStyle sk_style(
51 skia_style |= SkTypeface::kItalic; 54 font_weight, SkFontStyle::kNormal_Width,
52 55 italic ? SkFontStyle::kItalic_Slant : SkFontStyle::kUpright_Slant);
53 sk_sp<SkTypeface> typeface(SkTypeface::CreateFromName( 56 sk_sp<SkTypeface> typeface =
54 family->c_str(), static_cast<SkTypeface::Style>(skia_style))); 57 SkTypeface::MakeFromName(family->c_str(), sk_style);
55 if (!typeface) { 58 if (!typeface) {
56 // A non-scalable font such as .pcf is specified. Fall back to a default 59 // A non-scalable font such as .pcf is specified. Fall back to a default
57 // scalable font. 60 // scalable font.
58 typeface = sk_sp<SkTypeface>(SkTypeface::CreateFromName( 61 typeface = sk_sp<SkTypeface>(SkTypeface::MakeFromName(
59 kFallbackFontFamilyName, static_cast<SkTypeface::Style>(skia_style))); 62 kFallbackFontFamilyName, sk_style));
60 CHECK(typeface) << "Could not find any font: " << family << ", " 63 CHECK(typeface) << "Could not find any font: " << family << ", "
61 << kFallbackFontFamilyName; 64 << kFallbackFontFamilyName;
62 *family = kFallbackFontFamilyName; 65 *family = kFallbackFontFamilyName;
63 } 66 }
64 return typeface; 67 return typeface;
65 } 68 }
66 69
67 } // namespace 70 } // namespace
68 71
69 #if defined(OS_CHROMEOS) 72 #if defined(OS_CHROMEOS)
70 std::string* PlatformFontLinux::default_font_description_ = NULL; 73 std::string* PlatformFontLinux::default_font_description_ = NULL;
71 #endif 74 #endif
72 75
73 //////////////////////////////////////////////////////////////////////////////// 76 ////////////////////////////////////////////////////////////////////////////////
74 // PlatformFontLinux, public: 77 // PlatformFontLinux, public:
75 78
76 PlatformFontLinux::PlatformFontLinux() { 79 PlatformFontLinux::PlatformFontLinux() {
77 if (!g_default_font.Get()) { 80 if (!g_default_font.Get()) {
78 std::string family = kFallbackFontFamilyName; 81 std::string family = kFallbackFontFamilyName;
79 int size_pixels = 12; 82 int size_pixels = 12;
80 int style = Font::NORMAL; 83 bool italic = false;
84 Font::Weight weight = Font::Weight::NORMAL;
81 FontRenderParams params; 85 FontRenderParams params;
82 86
83 #if defined(OS_CHROMEOS) 87 #if defined(OS_CHROMEOS)
84 // On Chrome OS, a FontList font description string is stored as a 88 // On Chrome OS, a FontList font description string is stored as a
85 // translatable resource and passed in via SetDefaultFontDescription(). 89 // translatable resource and passed in via SetDefaultFontDescription().
86 if (default_font_description_) { 90 if (default_font_description_) {
87 FontRenderParamsQuery query; 91 FontRenderParamsQuery query;
88 CHECK(FontList::ParseDescription(*default_font_description_, 92 CHECK(FontList::ParseDescription(*default_font_description_,
89 &query.families, &query.style, 93 &query.families, &query.style,
90 &query.pixel_size)) 94 &query.pixel_size, &query.weight))
91 << "Failed to parse font description " << *default_font_description_; 95 << "Failed to parse font description " << *default_font_description_;
92 params = gfx::GetFontRenderParams(query, &family); 96 params = gfx::GetFontRenderParams(query, &family);
93 size_pixels = query.pixel_size; 97 size_pixels = query.pixel_size;
94 style = query.style; 98 italic = query.style & gfx::Font::ITALIC;
99 weight = query.weight;
95 } 100 }
96 #else 101 #else
97 // On Linux, LinuxFontDelegate is used to query the native toolkit (e.g. 102 // On Linux, LinuxFontDelegate is used to query the native toolkit (e.g.
98 // GTK+) for the default UI font. 103 // GTK+) for the default UI font.
99 const LinuxFontDelegate* delegate = LinuxFontDelegate::instance(); 104 const LinuxFontDelegate* delegate = LinuxFontDelegate::instance();
100 if (delegate) { 105 if (delegate) {
101 delegate->GetDefaultFontDescription( 106 delegate->GetDefaultFontDescription(&family, &size_pixels, &italic,
102 &family, &size_pixels, &style, &params); 107 &weight, &params);
103 } 108 }
104 #endif 109 #endif
105 110
106 g_default_font.Get() = new PlatformFontLinux( 111 g_default_font.Get() =
107 CreateSkTypeface(style, &family), family, size_pixels, style, params); 112 new PlatformFontLinux(CreateSkTypeface(italic, weight, &family), family,
113 size_pixels, italic, weight, params);
108 } 114 }
109 115
110 InitFromPlatformFont(g_default_font.Get().get()); 116 InitFromPlatformFont(g_default_font.Get().get());
111 } 117 }
112 118
113 PlatformFontLinux::PlatformFontLinux(const std::string& font_name, 119 PlatformFontLinux::PlatformFontLinux(const std::string& font_name,
114 int font_size_pixels) { 120 int font_size_pixels) {
115 FontRenderParamsQuery query; 121 FontRenderParamsQuery query;
116 query.families.push_back(font_name); 122 query.families.push_back(font_name);
117 query.pixel_size = font_size_pixels; 123 query.pixel_size = font_size_pixels;
118 query.style = Font::NORMAL; 124 query.weight = Font::Weight::NORMAL;
119 InitFromDetails(nullptr, font_name, font_size_pixels, 125 InitFromDetails(nullptr, font_name, font_size_pixels,
120 query.style, gfx::GetFontRenderParams(query, NULL)); 126 false, query.weight, gfx::GetFontRenderParams(query, NULL));
121 } 127 }
122 128
123 //////////////////////////////////////////////////////////////////////////////// 129 ////////////////////////////////////////////////////////////////////////////////
124 // PlatformFontLinux, PlatformFont implementation: 130 // PlatformFontLinux, PlatformFont implementation:
125 131
126 // static 132 // static
127 void PlatformFontLinux::ReloadDefaultFont() { 133 void PlatformFontLinux::ReloadDefaultFont() {
128 // Reset the scoped_refptr. 134 // Reset the scoped_refptr.
129 g_default_font.Get() = nullptr; 135 g_default_font.Get() = nullptr;
130 } 136 }
131 137
132 #if defined(OS_CHROMEOS) 138 #if defined(OS_CHROMEOS)
133 // static 139 // static
134 void PlatformFontLinux::SetDefaultFontDescription( 140 void PlatformFontLinux::SetDefaultFontDescription(
135 const std::string& font_description) { 141 const std::string& font_description) {
136 delete default_font_description_; 142 delete default_font_description_;
137 default_font_description_ = new std::string(font_description); 143 default_font_description_ = new std::string(font_description);
138 } 144 }
139 145
140 #endif 146 #endif
141 147
142 Font PlatformFontLinux::DeriveFont(int size_delta, int style) const { 148 Font PlatformFontLinux::DeriveFont(int size_delta,
149 int style,
150 Font::Weight weight) const {
143 const int new_size = font_size_pixels_ + size_delta; 151 const int new_size = font_size_pixels_ + size_delta;
144 DCHECK_GT(new_size, 0); 152 DCHECK_GT(new_size, 0);
145 153
154 const int current_style = italic_ ? Font::ITALIC : Font::NORMAL;
155
146 // If the style changed, we may need to load a new face. 156 // If the style changed, we may need to load a new face.
147 std::string new_family = font_family_; 157 std::string new_family = font_family_;
148 sk_sp<SkTypeface> typeface = 158 sk_sp<SkTypeface> typeface =
149 (style == style_) ? typeface_ : CreateSkTypeface(style, &new_family); 159 (weight == weight_ && style == current_style)
160 ? typeface_
161 : CreateSkTypeface(style, weight, &new_family);
150 162
151 FontRenderParamsQuery query; 163 FontRenderParamsQuery query;
152 query.families.push_back(new_family); 164 query.families.push_back(new_family);
153 query.pixel_size = new_size; 165 query.pixel_size = new_size;
154 query.style = style; 166 // TODO(mboc): Support UNDERLINE on Linux, if possible.
167 query.style = style & Font::ITALIC;
155 168
156 return Font(new PlatformFontLinux(std::move(typeface), new_family, new_size, 169 return Font(new PlatformFontLinux(std::move(typeface), new_family, new_size,
157 style, gfx::GetFontRenderParams(query, NULL))); 170 style & Font::ITALIC, weight, gfx::GetFontRenderParams(query, NULL)));
158 } 171 }
159 172
160 int PlatformFontLinux::GetHeight() { 173 int PlatformFontLinux::GetHeight() {
161 ComputeMetricsIfNecessary(); 174 ComputeMetricsIfNecessary();
162 return height_pixels_; 175 return height_pixels_;
163 } 176 }
164 177
178 Font::Weight PlatformFontLinux::GetWeight() const {
179 return weight_;
180 }
181
165 int PlatformFontLinux::GetBaseline() { 182 int PlatformFontLinux::GetBaseline() {
166 ComputeMetricsIfNecessary(); 183 ComputeMetricsIfNecessary();
167 return ascent_pixels_; 184 return ascent_pixels_;
168 } 185 }
169 186
170 int PlatformFontLinux::GetCapHeight() { 187 int PlatformFontLinux::GetCapHeight() {
171 ComputeMetricsIfNecessary(); 188 ComputeMetricsIfNecessary();
172 return cap_height_pixels_; 189 return cap_height_pixels_;
173 } 190 }
174 191
175 int PlatformFontLinux::GetExpectedTextWidth(int length) { 192 int PlatformFontLinux::GetExpectedTextWidth(int length) {
176 ComputeMetricsIfNecessary(); 193 ComputeMetricsIfNecessary();
177 return round(static_cast<float>(length) * average_width_pixels_); 194 return round(static_cast<float>(length) * average_width_pixels_);
178 } 195 }
179 196
180 int PlatformFontLinux::GetStyle() const { 197 int PlatformFontLinux::GetStyle() const {
181 return style_; 198 return italic_ ? Font::ITALIC : Font::NORMAL;
182 } 199 }
183 200
184 const std::string& PlatformFontLinux::GetFontName() const { 201 const std::string& PlatformFontLinux::GetFontName() const {
185 return font_family_; 202 return font_family_;
186 } 203 }
187 204
188 std::string PlatformFontLinux::GetActualFontNameForTesting() const { 205 std::string PlatformFontLinux::GetActualFontNameForTesting() const {
189 SkString family_name; 206 SkString family_name;
190 typeface_->getFamilyName(&family_name); 207 typeface_->getFamilyName(&family_name);
191 return family_name.c_str(); 208 return family_name.c_str();
192 } 209 }
193 210
194 int PlatformFontLinux::GetFontSize() const { 211 int PlatformFontLinux::GetFontSize() const {
195 return font_size_pixels_; 212 return font_size_pixels_;
196 } 213 }
197 214
198 const FontRenderParams& PlatformFontLinux::GetFontRenderParams() { 215 const FontRenderParams& PlatformFontLinux::GetFontRenderParams() {
199 float current_scale_factor = GetFontRenderParamsDeviceScaleFactor(); 216 float current_scale_factor = GetFontRenderParamsDeviceScaleFactor();
200 if (current_scale_factor != device_scale_factor_) { 217 if (current_scale_factor != device_scale_factor_) {
201 FontRenderParamsQuery query; 218 FontRenderParamsQuery query;
202 query.families.push_back(font_family_); 219 query.families.push_back(font_family_);
203 query.pixel_size = font_size_pixels_; 220 query.pixel_size = font_size_pixels_;
204 query.style = style_; 221 query.style = italic_ ? Font::ITALIC : Font::NORMAL;
222 query.weight = weight_;
205 query.device_scale_factor = current_scale_factor; 223 query.device_scale_factor = current_scale_factor;
206 font_render_params_ = gfx::GetFontRenderParams(query, nullptr); 224 font_render_params_ = gfx::GetFontRenderParams(query, nullptr);
207 device_scale_factor_ = current_scale_factor; 225 device_scale_factor_ = current_scale_factor;
208 } 226 }
209 return font_render_params_; 227 return font_render_params_;
210 } 228 }
211 229
212 //////////////////////////////////////////////////////////////////////////////// 230 ////////////////////////////////////////////////////////////////////////////////
213 // PlatformFontLinux, private: 231 // PlatformFontLinux, private:
214 232
215 PlatformFontLinux::PlatformFontLinux(sk_sp<SkTypeface> typeface, 233 PlatformFontLinux::PlatformFontLinux(sk_sp<SkTypeface> typeface,
216 const std::string& family, 234 const std::string& family,
217 int size_pixels, 235 int size_pixels,
218 int style, 236 bool italic,
237 Font::Weight weight,
219 const FontRenderParams& render_params) { 238 const FontRenderParams& render_params) {
220 InitFromDetails(std::move(typeface), family, size_pixels, style, 239 InitFromDetails(std::move(typeface), family, size_pixels, italic, weight,
221 render_params); 240 render_params);
222 } 241 }
223 242
224 PlatformFontLinux::~PlatformFontLinux() {} 243 PlatformFontLinux::~PlatformFontLinux() {}
225 244
226 void PlatformFontLinux::InitFromDetails( 245 void PlatformFontLinux::InitFromDetails(
227 sk_sp<SkTypeface> typeface, 246 sk_sp<SkTypeface> typeface,
228 const std::string& font_family, 247 const std::string& font_family,
229 int font_size_pixels, 248 int font_size_pixels,
230 int style, 249 bool italic,
250 Font::Weight weight,
231 const FontRenderParams& render_params) { 251 const FontRenderParams& render_params) {
232 DCHECK_GT(font_size_pixels, 0); 252 DCHECK_GT(font_size_pixels, 0);
233 253
234 font_family_ = font_family; 254 font_family_ = font_family;
235 typeface_ = typeface ? std::move(typeface) : 255 typeface_ = typeface ? std::move(typeface) :
236 CreateSkTypeface(style, &font_family_); 256 CreateSkTypeface(italic, weight, &font_family_);
237 257
238 font_size_pixels_ = font_size_pixels; 258 font_size_pixels_ = font_size_pixels;
239 style_ = style; 259 italic_ = italic;
260 weight_ = weight;
240 device_scale_factor_ = GetFontRenderParamsDeviceScaleFactor(); 261 device_scale_factor_ = GetFontRenderParamsDeviceScaleFactor();
241 font_render_params_ = render_params; 262 font_render_params_ = render_params;
242
243 } 263 }
244 264
245 void PlatformFontLinux::InitFromPlatformFont(const PlatformFontLinux* other) { 265 void PlatformFontLinux::InitFromPlatformFont(const PlatformFontLinux* other) {
246 typeface_ = other->typeface_; 266 typeface_ = other->typeface_;
247 font_family_ = other->font_family_; 267 font_family_ = other->font_family_;
248 font_size_pixels_ = other->font_size_pixels_; 268 font_size_pixels_ = other->font_size_pixels_;
249 style_ = other->style_; 269 italic_ = other->italic_;
270 weight_ = other->weight_;
250 device_scale_factor_ = other->device_scale_factor_; 271 device_scale_factor_ = other->device_scale_factor_;
251 font_render_params_ = other->font_render_params_; 272 font_render_params_ = other->font_render_params_;
252 273
253 if (!other->metrics_need_computation_) { 274 if (!other->metrics_need_computation_) {
254 metrics_need_computation_ = false; 275 metrics_need_computation_ = false;
255 ascent_pixels_ = other->ascent_pixels_; 276 ascent_pixels_ = other->ascent_pixels_;
256 height_pixels_ = other->height_pixels_; 277 height_pixels_ = other->height_pixels_;
257 cap_height_pixels_ = other->cap_height_pixels_; 278 cap_height_pixels_ = other->cap_height_pixels_;
258 average_width_pixels_ = other->average_width_pixels_; 279 average_width_pixels_ = other->average_width_pixels_;
259 } 280 }
260 } 281 }
261 282
262 void PlatformFontLinux::ComputeMetricsIfNecessary() { 283 void PlatformFontLinux::ComputeMetricsIfNecessary() {
263 if (metrics_need_computation_) { 284 if (metrics_need_computation_) {
264 metrics_need_computation_ = false; 285 metrics_need_computation_ = false;
265 286
266 SkPaint paint; 287 SkPaint paint;
267 paint.setAntiAlias(false); 288 paint.setAntiAlias(false);
268 paint.setSubpixelText(false); 289 paint.setSubpixelText(false);
269 paint.setTextSize(font_size_pixels_); 290 paint.setTextSize(font_size_pixels_);
270 paint.setTypeface(typeface_.get()); 291 paint.setTypeface(typeface_.get());
271 paint.setFakeBoldText((Font::BOLD & style_) && !typeface_->isBold()); 292 paint.setFakeBoldText(weight_ >= Font::Weight::BOLD &&
272 paint.setTextSkewX((Font::ITALIC & style_) && !typeface_->isItalic() ? 293 !typeface_->isBold());
273 -SK_Scalar1/4 : 0); 294 paint.setTextSkewX(italic_ && !typeface_->isItalic() ? -SK_Scalar1 / 4 : 0);
274 SkPaint::FontMetrics metrics; 295 SkPaint::FontMetrics metrics;
275 paint.getFontMetrics(&metrics); 296 paint.getFontMetrics(&metrics);
276 ascent_pixels_ = SkScalarCeilToInt(-metrics.fAscent); 297 ascent_pixels_ = SkScalarCeilToInt(-metrics.fAscent);
277 height_pixels_ = ascent_pixels_ + SkScalarCeilToInt(metrics.fDescent); 298 height_pixels_ = ascent_pixels_ + SkScalarCeilToInt(metrics.fDescent);
278 cap_height_pixels_ = SkScalarCeilToInt(metrics.fCapHeight); 299 cap_height_pixels_ = SkScalarCeilToInt(metrics.fCapHeight);
279 average_width_pixels_ = SkScalarToDouble(metrics.fAvgCharWidth); 300 average_width_pixels_ = SkScalarToDouble(metrics.fAvgCharWidth);
280 } 301 }
281 } 302 }
282 303
283 //////////////////////////////////////////////////////////////////////////////// 304 ////////////////////////////////////////////////////////////////////////////////
284 // PlatformFont, public: 305 // PlatformFont, public:
285 306
286 // static 307 // static
287 PlatformFont* PlatformFont::CreateDefault() { 308 PlatformFont* PlatformFont::CreateDefault() {
288 return new PlatformFontLinux; 309 return new PlatformFontLinux;
289 } 310 }
290 311
291 // static 312 // static
292 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name, 313 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name,
293 int font_size) { 314 int font_size) {
294 return new PlatformFontLinux(font_name, font_size); 315 return new PlatformFontLinux(font_name, font_size);
295 } 316 }
296 317
297 } // namespace gfx 318 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/platform_font_linux.h ('k') | ui/gfx/platform_font_linux_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698