Only grant permissions to new extensions from sync if they have the expected version
[chromium-blink-merge.git] / ui / gfx / platform_font_linux.cc
blobeb5b7a35242c09f5d4a50784a48027cd47389912
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
3 // found in the LICENSE file.
5 #include "ui/gfx/platform_font_linux.h"
7 #include <algorithm>
8 #include <string>
10 #include "base/lazy_instance.h"
11 #include "base/logging.h"
12 #include "base/strings/string_piece.h"
13 #include "base/strings/string_split.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "third_party/skia/include/core/SkPaint.h"
16 #include "third_party/skia/include/core/SkString.h"
17 #include "third_party/skia/include/core/SkTypeface.h"
18 #include "ui/gfx/canvas.h"
19 #include "ui/gfx/font.h"
20 #include "ui/gfx/font_list.h"
21 #include "ui/gfx/linux_font_delegate.h"
22 #include "ui/gfx/text_utils.h"
24 namespace gfx {
25 namespace {
27 // The font family name which is used when a user's application font for
28 // GNOME/KDE is a non-scalable one. The name should be listed in the
29 // IsFallbackFontAllowed function in skia/ext/SkFontHost_fontconfig_direct.cpp.
30 #if defined(OS_ANDROID)
31 const char* kFallbackFontFamilyName = "serif";
32 #else
33 const char* kFallbackFontFamilyName = "sans";
34 #endif
36 // The default font, used for the default constructor.
37 base::LazyInstance<scoped_refptr<PlatformFontLinux>>::Leaky g_default_font =
38 LAZY_INSTANCE_INITIALIZER;
40 // Creates a SkTypeface for the passed-in Font::FontStyle and family. If a
41 // fallback typeface is used instead of the requested family, |family| will be
42 // updated to contain the fallback's family name.
43 skia::RefPtr<SkTypeface> CreateSkTypeface(int style, std::string* family) {
44 DCHECK(family);
46 int skia_style = SkTypeface::kNormal;
47 if (Font::BOLD & style)
48 skia_style |= SkTypeface::kBold;
49 if (Font::ITALIC & style)
50 skia_style |= SkTypeface::kItalic;
52 skia::RefPtr<SkTypeface> typeface = skia::AdoptRef(SkTypeface::CreateFromName(
53 family->c_str(), static_cast<SkTypeface::Style>(skia_style)));
54 if (!typeface) {
55 // A non-scalable font such as .pcf is specified. Fall back to a default
56 // scalable font.
57 typeface = skia::AdoptRef(SkTypeface::CreateFromName(
58 kFallbackFontFamilyName, static_cast<SkTypeface::Style>(skia_style)));
59 CHECK(typeface) << "Could not find any font: " << family << ", "
60 << kFallbackFontFamilyName;
61 *family = kFallbackFontFamilyName;
63 return typeface;
66 } // namespace
68 #if defined(OS_CHROMEOS)
69 std::string* PlatformFontLinux::default_font_description_ = NULL;
70 #endif
72 ////////////////////////////////////////////////////////////////////////////////
73 // PlatformFontLinux, public:
75 PlatformFontLinux::PlatformFontLinux() {
76 if (!g_default_font.Get()) {
77 std::string family = kFallbackFontFamilyName;
78 int size_pixels = 12;
79 int style = Font::NORMAL;
80 FontRenderParams params;
82 #if defined(OS_CHROMEOS)
83 // On Chrome OS, a FontList font description string is stored as a
84 // translatable resource and passed in via SetDefaultFontDescription().
85 if (default_font_description_) {
86 FontRenderParamsQuery query;
87 CHECK(FontList::ParseDescription(*default_font_description_,
88 &query.families, &query.style,
89 &query.pixel_size))
90 << "Failed to parse font description " << *default_font_description_;
91 params = gfx::GetFontRenderParams(query, &family);
92 size_pixels = query.pixel_size;
93 style = query.style;
95 #else
96 // On Linux, LinuxFontDelegate is used to query the native toolkit (e.g.
97 // GTK+) for the default UI font.
98 const LinuxFontDelegate* delegate = LinuxFontDelegate::instance();
99 if (delegate) {
100 delegate->GetDefaultFontDescription(
101 &family, &size_pixels, &style, &params);
103 #endif
105 g_default_font.Get() = new PlatformFontLinux(
106 CreateSkTypeface(style, &family), family, size_pixels, style, params);
109 InitFromPlatformFont(g_default_font.Get().get());
112 PlatformFontLinux::PlatformFontLinux(const std::string& font_name,
113 int font_size_pixels) {
114 FontRenderParamsQuery query;
115 query.families.push_back(font_name);
116 query.pixel_size = font_size_pixels;
117 query.style = Font::NORMAL;
118 InitFromDetails(skia::RefPtr<SkTypeface>(), font_name, font_size_pixels,
119 query.style, gfx::GetFontRenderParams(query, NULL));
122 ////////////////////////////////////////////////////////////////////////////////
123 // PlatformFontLinux, PlatformFont implementation:
125 // static
126 void PlatformFontLinux::ReloadDefaultFont() {
127 // Reset the scoped_refptr.
128 g_default_font.Get() = nullptr;
131 #if defined(OS_CHROMEOS)
132 // static
133 void PlatformFontLinux::SetDefaultFontDescription(
134 const std::string& font_description) {
135 delete default_font_description_;
136 default_font_description_ = new std::string(font_description);
139 #endif
141 Font PlatformFontLinux::DeriveFont(int size_delta, int style) const {
142 const int new_size = font_size_pixels_ + size_delta;
143 DCHECK_GT(new_size, 0);
145 // If the style changed, we may need to load a new face.
146 std::string new_family = font_family_;
147 skia::RefPtr<SkTypeface> typeface =
148 (style == style_) ? typeface_ : CreateSkTypeface(style, &new_family);
150 FontRenderParamsQuery query;
151 query.families.push_back(new_family);
152 query.pixel_size = new_size;
153 query.style = style;
155 return Font(new PlatformFontLinux(typeface, new_family, new_size, style,
156 gfx::GetFontRenderParams(query, NULL)));
159 int PlatformFontLinux::GetHeight() const {
160 return height_pixels_;
163 int PlatformFontLinux::GetBaseline() const {
164 return ascent_pixels_;
167 int PlatformFontLinux::GetCapHeight() const {
168 return cap_height_pixels_;
171 int PlatformFontLinux::GetExpectedTextWidth(int length) const {
172 return round(static_cast<float>(length) * average_width_pixels_);
175 int PlatformFontLinux::GetStyle() const {
176 return style_;
179 std::string PlatformFontLinux::GetFontName() const {
180 return font_family_;
183 std::string PlatformFontLinux::GetActualFontNameForTesting() const {
184 SkString family_name;
185 typeface_->getFamilyName(&family_name);
186 return family_name.c_str();
189 int PlatformFontLinux::GetFontSize() const {
190 return font_size_pixels_;
193 const FontRenderParams& PlatformFontLinux::GetFontRenderParams() {
194 #if defined(OS_CHROMEOS)
195 float current_scale_factor = GetFontRenderParamsDeviceScaleFactor();
196 if (current_scale_factor != device_scale_factor_) {
197 FontRenderParamsQuery query;
198 query.families.push_back(font_family_);
199 query.pixel_size = font_size_pixels_;
200 query.style = style_;
201 query.device_scale_factor = current_scale_factor;
202 font_render_params_ = gfx::GetFontRenderParams(query, nullptr);
203 device_scale_factor_ = current_scale_factor;
205 #endif
206 return font_render_params_;
209 ////////////////////////////////////////////////////////////////////////////////
210 // PlatformFontLinux, private:
212 PlatformFontLinux::PlatformFontLinux(const skia::RefPtr<SkTypeface>& typeface,
213 const std::string& family,
214 int size_pixels,
215 int style,
216 const FontRenderParams& render_params) {
217 InitFromDetails(typeface, family, size_pixels, style, render_params);
220 PlatformFontLinux::~PlatformFontLinux() {}
222 void PlatformFontLinux::InitFromDetails(
223 const skia::RefPtr<SkTypeface>& typeface,
224 const std::string& font_family,
225 int font_size_pixels,
226 int style,
227 const FontRenderParams& render_params) {
228 DCHECK_GT(font_size_pixels, 0);
230 font_family_ = font_family;
231 typeface_ = typeface ? typeface : CreateSkTypeface(style, &font_family_);
233 font_size_pixels_ = font_size_pixels;
234 style_ = style;
235 #if defined(OS_CHROMEOS)
236 device_scale_factor_ = GetFontRenderParamsDeviceScaleFactor();
237 #endif
238 font_render_params_ = render_params;
240 SkPaint paint;
241 paint.setAntiAlias(false);
242 paint.setSubpixelText(false);
243 paint.setTextSize(font_size_pixels_);
244 paint.setTypeface(typeface_.get());
245 paint.setFakeBoldText((Font::BOLD & style_) && !typeface_->isBold());
246 paint.setTextSkewX((Font::ITALIC & style_) && !typeface_->isItalic() ?
247 -SK_Scalar1/4 : 0);
248 SkPaint::FontMetrics metrics;
249 paint.getFontMetrics(&metrics);
250 ascent_pixels_ = SkScalarCeilToInt(-metrics.fAscent);
251 height_pixels_ = ascent_pixels_ + SkScalarCeilToInt(metrics.fDescent);
252 cap_height_pixels_ = SkScalarCeilToInt(metrics.fCapHeight);
253 average_width_pixels_ = SkScalarToDouble(metrics.fAvgCharWidth);
256 void PlatformFontLinux::InitFromPlatformFont(const PlatformFontLinux* other) {
257 typeface_ = other->typeface_;
258 font_family_ = other->font_family_;
259 font_size_pixels_ = other->font_size_pixels_;
260 style_ = other->style_;
261 #if defined(OS_CHROMEOS)
262 device_scale_factor_ = other->device_scale_factor_;
263 #endif
264 font_render_params_ = other->font_render_params_;
265 ascent_pixels_ = other->ascent_pixels_;
266 height_pixels_ = other->height_pixels_;
267 cap_height_pixels_ = other->cap_height_pixels_;
268 average_width_pixels_ = other->average_width_pixels_;
271 ////////////////////////////////////////////////////////////////////////////////
272 // PlatformFont, public:
274 // static
275 PlatformFont* PlatformFont::CreateDefault() {
276 return new PlatformFontLinux;
279 // static
280 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name,
281 int font_size) {
282 return new PlatformFontLinux(font_name, font_size);
285 } // namespace gfx