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

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: Address Alexei's issues Created 4 years, 8 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
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 skia::RefPtr<SkTypeface> CreateSkTypeface(int style, std::string* family) { 45 skia::RefPtr<SkTypeface> CreateSkTypeface(bool italic,
46 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 skia::RefPtr<SkTypeface> typeface = skia::AdoptRef(SkTypeface::CreateFromName( 56 skia::RefPtr<SkTypeface> typeface =
54 family->c_str(), static_cast<SkTypeface::Style>(skia_style))); 57 skia::AdoptRef(SkTypeface::CreateFromName(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 = skia::AdoptRef(SkTypeface::CreateFromName( 61 typeface = skia::AdoptRef(
59 kFallbackFontFamilyName, static_cast<SkTypeface::Style>(skia_style))); 62 SkTypeface::CreateFromName(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))
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 style = query.style;
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;
119 InitFromDetails(skia::RefPtr<SkTypeface>(), font_name, font_size_pixels, 124 InitFromDetails(skia::RefPtr<SkTypeface>(), font_name, font_size_pixels,
120 query.style, gfx::GetFontRenderParams(query, NULL)); 125 false, query.weight, gfx::GetFontRenderParams(query, NULL));
121 } 126 }
122 127
123 //////////////////////////////////////////////////////////////////////////////// 128 ////////////////////////////////////////////////////////////////////////////////
124 // PlatformFontLinux, PlatformFont implementation: 129 // PlatformFontLinux, PlatformFont implementation:
125 130
126 // static 131 // static
127 void PlatformFontLinux::ReloadDefaultFont() { 132 void PlatformFontLinux::ReloadDefaultFont() {
128 // Reset the scoped_refptr. 133 // Reset the scoped_refptr.
129 g_default_font.Get() = nullptr; 134 g_default_font.Get() = nullptr;
130 } 135 }
131 136
132 #if defined(OS_CHROMEOS) 137 #if defined(OS_CHROMEOS)
133 // static 138 // static
134 void PlatformFontLinux::SetDefaultFontDescription( 139 void PlatformFontLinux::SetDefaultFontDescription(
135 const std::string& font_description) { 140 const std::string& font_description) {
136 delete default_font_description_; 141 delete default_font_description_;
137 default_font_description_ = new std::string(font_description); 142 default_font_description_ = new std::string(font_description);
138 } 143 }
139 144
140 #endif 145 #endif
141 146
142 Font PlatformFontLinux::DeriveFont(int size_delta, int style) const { 147 Font PlatformFontLinux::DeriveFont(int size_delta,
148 int style,
149 gfx::Font::Weight weight) const {
Alexei Svitkine (slow) 2016/04/05 16:38:52 Remove gfx::
143 const int new_size = font_size_pixels_ + size_delta; 150 const int new_size = font_size_pixels_ + size_delta;
144 DCHECK_GT(new_size, 0); 151 DCHECK_GT(new_size, 0);
145 152
153 const int current_style = italic_ ? gfx::Font::ITALIC : gfx::Font::NORMAL;
Alexei Svitkine (slow) 2016/04/05 16:38:52 Remove gfx::
154
146 // If the style changed, we may need to load a new face. 155 // If the style changed, we may need to load a new face.
147 std::string new_family = font_family_; 156 std::string new_family = font_family_;
148 skia::RefPtr<SkTypeface> typeface = 157 skia::RefPtr<SkTypeface> typeface =
149 (style == style_) ? typeface_ : CreateSkTypeface(style, &new_family); 158 (style == current_style) ? typeface_
159 : CreateSkTypeface(style, weight, &new_family);
150 160
151 FontRenderParamsQuery query; 161 FontRenderParamsQuery query;
152 query.families.push_back(new_family); 162 query.families.push_back(new_family);
153 query.pixel_size = new_size; 163 query.pixel_size = new_size;
154 query.style = style; 164 query.style = style;
155 165
156 return Font(new PlatformFontLinux(typeface, new_family, new_size, style, 166 return Font(new PlatformFontLinux(typeface, new_family, new_size, style,
167 weight,
157 gfx::GetFontRenderParams(query, NULL))); 168 gfx::GetFontRenderParams(query, NULL)));
158 } 169 }
159 170
160 int PlatformFontLinux::GetHeight() { 171 int PlatformFontLinux::GetHeight() {
161 ComputeMetricsIfNecessary(); 172 ComputeMetricsIfNecessary();
162 return height_pixels_; 173 return height_pixels_;
163 } 174 }
164 175
176 gfx::Font::Weight PlatformFontLinux::GetWeight() const {
Alexei Svitkine (slow) 2016/04/05 16:38:52 Remove gfx::
177 return weight_;
178 }
179
165 int PlatformFontLinux::GetBaseline() { 180 int PlatformFontLinux::GetBaseline() {
166 ComputeMetricsIfNecessary(); 181 ComputeMetricsIfNecessary();
167 return ascent_pixels_; 182 return ascent_pixels_;
168 } 183 }
169 184
170 int PlatformFontLinux::GetCapHeight() { 185 int PlatformFontLinux::GetCapHeight() {
171 ComputeMetricsIfNecessary(); 186 ComputeMetricsIfNecessary();
172 return cap_height_pixels_; 187 return cap_height_pixels_;
173 } 188 }
174 189
175 int PlatformFontLinux::GetExpectedTextWidth(int length) { 190 int PlatformFontLinux::GetExpectedTextWidth(int length) {
176 ComputeMetricsIfNecessary(); 191 ComputeMetricsIfNecessary();
177 return round(static_cast<float>(length) * average_width_pixels_); 192 return round(static_cast<float>(length) * average_width_pixels_);
178 } 193 }
179 194
180 int PlatformFontLinux::GetStyle() const { 195 int PlatformFontLinux::GetStyle() const {
181 return style_; 196 return italic_ ? gfx::Font::ITALIC : gfx::Font::NORMAL;
182 } 197 }
183 198
184 const std::string& PlatformFontLinux::GetFontName() const { 199 const std::string& PlatformFontLinux::GetFontName() const {
185 return font_family_; 200 return font_family_;
186 } 201 }
187 202
188 std::string PlatformFontLinux::GetActualFontNameForTesting() const { 203 std::string PlatformFontLinux::GetActualFontNameForTesting() const {
189 SkString family_name; 204 SkString family_name;
190 typeface_->getFamilyName(&family_name); 205 typeface_->getFamilyName(&family_name);
191 return family_name.c_str(); 206 return family_name.c_str();
(...skipping 18 matching lines...) Expand all
210 #endif 225 #endif
211 return font_render_params_; 226 return font_render_params_;
212 } 227 }
213 228
214 //////////////////////////////////////////////////////////////////////////////// 229 ////////////////////////////////////////////////////////////////////////////////
215 // PlatformFontLinux, private: 230 // PlatformFontLinux, private:
216 231
217 PlatformFontLinux::PlatformFontLinux(const skia::RefPtr<SkTypeface>& typeface, 232 PlatformFontLinux::PlatformFontLinux(const skia::RefPtr<SkTypeface>& typeface,
218 const std::string& family, 233 const std::string& family,
219 int size_pixels, 234 int size_pixels,
220 int style, 235 bool italic,
236 gfx::Font::Weight weight,
Alexei Svitkine (slow) 2016/04/05 16:38:52 Remove gfx::
221 const FontRenderParams& render_params) { 237 const FontRenderParams& render_params) {
222 InitFromDetails(typeface, family, size_pixels, style, render_params); 238 InitFromDetails(typeface, family, size_pixels, italic, weight, render_params);
223 } 239 }
224 240
225 PlatformFontLinux::~PlatformFontLinux() {} 241 PlatformFontLinux::~PlatformFontLinux() {}
226 242
227 void PlatformFontLinux::InitFromDetails( 243 void PlatformFontLinux::InitFromDetails(
228 const skia::RefPtr<SkTypeface>& typeface, 244 const skia::RefPtr<SkTypeface>& typeface,
229 const std::string& font_family, 245 const std::string& font_family,
230 int font_size_pixels, 246 int font_size_pixels,
231 int style, 247 bool italic,
248 gfx::Font::Weight weight,
Alexei Svitkine (slow) 2016/04/05 16:38:52 Remove gfx::
232 const FontRenderParams& render_params) { 249 const FontRenderParams& render_params) {
233 DCHECK_GT(font_size_pixels, 0); 250 DCHECK_GT(font_size_pixels, 0);
234 251
235 font_family_ = font_family; 252 font_family_ = font_family;
236 typeface_ = typeface ? typeface : CreateSkTypeface(style, &font_family_); 253 typeface_ =
254 typeface ? typeface : CreateSkTypeface(italic, weight, &font_family_);
237 255
238 font_size_pixels_ = font_size_pixels; 256 font_size_pixels_ = font_size_pixels;
239 style_ = style; 257 italic_ = italic;
258 weight_ = weight;
240 #if defined(OS_CHROMEOS) 259 #if defined(OS_CHROMEOS)
241 device_scale_factor_ = GetFontRenderParamsDeviceScaleFactor(); 260 device_scale_factor_ = GetFontRenderParamsDeviceScaleFactor();
242 #endif 261 #endif
243 font_render_params_ = render_params; 262 font_render_params_ = render_params;
244
245 } 263 }
246 264
247 void PlatformFontLinux::InitFromPlatformFont(const PlatformFontLinux* other) { 265 void PlatformFontLinux::InitFromPlatformFont(const PlatformFontLinux* other) {
248 typeface_ = other->typeface_; 266 typeface_ = other->typeface_;
249 font_family_ = other->font_family_; 267 font_family_ = other->font_family_;
250 font_size_pixels_ = other->font_size_pixels_; 268 font_size_pixels_ = other->font_size_pixels_;
251 style_ = other->style_; 269 italic_ = other->italic_;
270 weight_ = other->weight_;
252 #if defined(OS_CHROMEOS) 271 #if defined(OS_CHROMEOS)
253 device_scale_factor_ = other->device_scale_factor_; 272 device_scale_factor_ = other->device_scale_factor_;
254 #endif 273 #endif
255 font_render_params_ = other->font_render_params_; 274 font_render_params_ = other->font_render_params_;
256 275
257 if (!other->metrics_need_computation_) { 276 if (!other->metrics_need_computation_) {
258 metrics_need_computation_ = false; 277 metrics_need_computation_ = false;
259 ascent_pixels_ = other->ascent_pixels_; 278 ascent_pixels_ = other->ascent_pixels_;
260 height_pixels_ = other->height_pixels_; 279 height_pixels_ = other->height_pixels_;
261 cap_height_pixels_ = other->cap_height_pixels_; 280 cap_height_pixels_ = other->cap_height_pixels_;
262 average_width_pixels_ = other->average_width_pixels_; 281 average_width_pixels_ = other->average_width_pixels_;
263 } 282 }
264 } 283 }
265 284
266 void PlatformFontLinux::ComputeMetricsIfNecessary() { 285 void PlatformFontLinux::ComputeMetricsIfNecessary() {
267 if (metrics_need_computation_) { 286 if (metrics_need_computation_) {
268 metrics_need_computation_ = false; 287 metrics_need_computation_ = false;
269 288
270 SkPaint paint; 289 SkPaint paint;
271 paint.setAntiAlias(false); 290 paint.setAntiAlias(false);
272 paint.setSubpixelText(false); 291 paint.setSubpixelText(false);
273 paint.setTextSize(font_size_pixels_); 292 paint.setTextSize(font_size_pixels_);
274 paint.setTypeface(typeface_.get()); 293 paint.setTypeface(typeface_.get());
275 paint.setFakeBoldText((Font::BOLD & style_) && !typeface_->isBold()); 294 paint.setFakeBoldText(weight_ >= gfx::Font::Weight::BOLD &&
276 paint.setTextSkewX((Font::ITALIC & style_) && !typeface_->isItalic() ? 295 !typeface_->isBold());
277 -SK_Scalar1/4 : 0); 296 paint.setTextSkewX(italic_ && !typeface_->isItalic() ? -SK_Scalar1 / 4 : 0);
278 SkPaint::FontMetrics metrics; 297 SkPaint::FontMetrics metrics;
279 paint.getFontMetrics(&metrics); 298 paint.getFontMetrics(&metrics);
280 ascent_pixels_ = SkScalarCeilToInt(-metrics.fAscent); 299 ascent_pixels_ = SkScalarCeilToInt(-metrics.fAscent);
281 height_pixels_ = ascent_pixels_ + SkScalarCeilToInt(metrics.fDescent); 300 height_pixels_ = ascent_pixels_ + SkScalarCeilToInt(metrics.fDescent);
282 cap_height_pixels_ = SkScalarCeilToInt(metrics.fCapHeight); 301 cap_height_pixels_ = SkScalarCeilToInt(metrics.fCapHeight);
283 average_width_pixels_ = SkScalarToDouble(metrics.fAvgCharWidth); 302 average_width_pixels_ = SkScalarToDouble(metrics.fAvgCharWidth);
284 } 303 }
285 } 304 }
286 305
287 //////////////////////////////////////////////////////////////////////////////// 306 ////////////////////////////////////////////////////////////////////////////////
288 // PlatformFont, public: 307 // PlatformFont, public:
289 308
290 // static 309 // static
291 PlatformFont* PlatformFont::CreateDefault() { 310 PlatformFont* PlatformFont::CreateDefault() {
292 return new PlatformFontLinux; 311 return new PlatformFontLinux;
293 } 312 }
294 313
295 // static 314 // static
296 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name, 315 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name,
297 int font_size) { 316 int font_size) {
298 return new PlatformFontLinux(font_name, font_size); 317 return new PlatformFontLinux(font_name, font_size);
299 } 318 }
300 319
301 } // namespace gfx 320 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698