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

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

Issue 382273002: ui/gfx: Allow for font-specific rendering settings. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix fontconfig leak Created 6 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « ui/gfx/platform_font_pango.h ('k') | ui/gfx/platform_font_win.h » ('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_pango.h" 5 #include "ui/gfx/platform_font_pango.h"
6 6
7 #include <fontconfig/fontconfig.h> 7 #include <fontconfig/fontconfig.h>
8 #include <pango/pango.h> 8 #include <pango/pango.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 13 matching lines...) Expand all
24 #include "ui/gfx/pango_util.h" 24 #include "ui/gfx/pango_util.h"
25 #include "ui/gfx/text_utils.h" 25 #include "ui/gfx/text_utils.h"
26 26
27 namespace { 27 namespace {
28 28
29 // 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
30 // 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
31 // IsFallbackFontAllowed function in skia/ext/SkFontHost_fontconfig_direct.cpp. 31 // IsFallbackFontAllowed function in skia/ext/SkFontHost_fontconfig_direct.cpp.
32 const char* kFallbackFontFamilyName = "sans"; 32 const char* kFallbackFontFamilyName = "sans";
33 33
34 // Returns the available font family that best (in FontConfig's eyes) matches
35 // the supplied list of family names.
36 std::string FindBestMatchFontFamilyName(
37 const std::vector<std::string>& family_names) {
38 FcPattern* pattern = FcPatternCreate();
39 for (std::vector<std::string>::const_iterator it = family_names.begin();
40 it != family_names.end(); ++it) {
41 FcValue fcvalue;
42 fcvalue.type = FcTypeString;
43 fcvalue.u.s = reinterpret_cast<const FcChar8*>(it->c_str());
44 FcPatternAdd(pattern, FC_FAMILY, fcvalue, FcTrue /* append */);
45 }
46
47 FcConfigSubstitute(0, pattern, FcMatchPattern);
48 FcDefaultSubstitute(pattern);
49 FcResult result;
50 FcPattern* match = FcFontMatch(0, pattern, &result);
51 DCHECK(match) << "Could not find font";
52 FcChar8* match_family = NULL;
53 FcPatternGetString(match, FC_FAMILY, 0, &match_family);
54 std::string font_family(reinterpret_cast<char*>(match_family));
55 FcPatternDestroy(pattern);
56 FcPatternDestroy(match);
57 return font_family;
58 }
59
60 } // namespace 34 } // namespace
61 35
62 namespace gfx { 36 namespace gfx {
63 37
64 // static 38 // static
65 Font* PlatformFontPango::default_font_ = NULL; 39 Font* PlatformFontPango::default_font_ = NULL;
66 40
67 #if defined(OS_CHROMEOS) 41 #if defined(OS_CHROMEOS)
68 // static 42 // static
69 std::string* PlatformFontPango::default_font_description_ = NULL; 43 std::string* PlatformFontPango::default_font_description_ = NULL;
(...skipping 17 matching lines...) Expand all
87 ScopedPangoFontDescription desc( 61 ScopedPangoFontDescription desc(
88 pango_font_description_from_string(desc_string.c_str())); 62 pango_font_description_from_string(desc_string.c_str()));
89 default_font_ = new Font(desc.get()); 63 default_font_ = new Font(desc.get());
90 } 64 }
91 65
92 InitFromPlatformFont( 66 InitFromPlatformFont(
93 static_cast<PlatformFontPango*>(default_font_->platform_font())); 67 static_cast<PlatformFontPango*>(default_font_->platform_font()));
94 } 68 }
95 69
96 PlatformFontPango::PlatformFontPango(NativeFont native_font) { 70 PlatformFontPango::PlatformFontPango(NativeFont native_font) {
71 const int pango_size =
72 pango_font_description_get_size(native_font) / PANGO_SCALE;
73 const bool pango_using_pixels =
74 pango_font_description_get_size_is_absolute(native_font);
75
76 std::string font_family;
97 std::vector<std::string> family_names; 77 std::vector<std::string> family_names;
98 base::SplitString(pango_font_description_get_family(native_font), ',', 78 base::SplitString(pango_font_description_get_family(native_font), ',',
99 &family_names); 79 &family_names);
100 std::string font_family = FindBestMatchFontFamilyName(family_names); 80 const FontRenderParams params = GetCustomFontRenderParams(
81 false, &family_names,
82 pango_using_pixels ? &pango_size : NULL /* pixel_size */,
83 !pango_using_pixels ? &pango_size : NULL /* point_size */,
84 &font_family);
101 85
102 int style = 0; 86 int style = 0;
103 // TODO(davemoore) What should we do about other weights? We currently only 87 // TODO(davemoore) What should we do about other weights? We currently only
104 // support BOLD. 88 // support BOLD.
105 if (pango_font_description_get_weight(native_font) == PANGO_WEIGHT_BOLD) 89 if (pango_font_description_get_weight(native_font) == PANGO_WEIGHT_BOLD)
106 style |= gfx::Font::BOLD; 90 style |= gfx::Font::BOLD;
107 // TODO(davemoore) What about PANGO_STYLE_OBLIQUE? 91 // TODO(davemoore) What about PANGO_STYLE_OBLIQUE?
108 if (pango_font_description_get_style(native_font) == PANGO_STYLE_ITALIC) 92 if (pango_font_description_get_style(native_font) == PANGO_STYLE_ITALIC)
109 style |= gfx::Font::ITALIC; 93 style |= gfx::Font::ITALIC;
110 94
111 InitFromDetails(skia::RefPtr<SkTypeface>(), font_family, 95 InitFromDetails(skia::RefPtr<SkTypeface>(), font_family,
112 gfx::GetPangoFontSizeInPixels(native_font), style); 96 gfx::GetPangoFontSizeInPixels(native_font), style, params);
113 } 97 }
114 98
115 PlatformFontPango::PlatformFontPango(const std::string& font_name, 99 PlatformFontPango::PlatformFontPango(const std::string& font_name,
116 int font_size) { 100 int font_size_pixels) {
117 InitFromDetails(skia::RefPtr<SkTypeface>(), font_name, font_size, 101 const std::vector<std::string> font_list(1, font_name);
118 SkTypeface::kNormal); 102 const FontRenderParams params = GetCustomFontRenderParams(
103 false, &font_list, &font_size_pixels, NULL, NULL);
104 InitFromDetails(skia::RefPtr<SkTypeface>(), font_name, font_size_pixels,
105 SkTypeface::kNormal, params);
119 } 106 }
120 107
121 double PlatformFontPango::underline_position() const { 108 double PlatformFontPango::underline_position() const {
122 const_cast<PlatformFontPango*>(this)->InitPangoMetrics(); 109 const_cast<PlatformFontPango*>(this)->InitPangoMetrics();
123 return underline_position_pixels_; 110 return underline_position_pixels_;
124 } 111 }
125 112
126 double PlatformFontPango::underline_thickness() const { 113 double PlatformFontPango::underline_thickness() const {
127 const_cast<PlatformFontPango*>(this)->InitPangoMetrics(); 114 const_cast<PlatformFontPango*>(this)->InitPangoMetrics();
128 return underline_thickness_pixels_; 115 return underline_thickness_pixels_;
(...skipping 12 matching lines...) Expand all
141 // static 128 // static
142 void PlatformFontPango::SetDefaultFontDescription( 129 void PlatformFontPango::SetDefaultFontDescription(
143 const std::string& font_description) { 130 const std::string& font_description) {
144 delete default_font_description_; 131 delete default_font_description_;
145 default_font_description_ = new std::string(font_description); 132 default_font_description_ = new std::string(font_description);
146 } 133 }
147 134
148 #endif 135 #endif
149 136
150 Font PlatformFontPango::DeriveFont(int size_delta, int style) const { 137 Font PlatformFontPango::DeriveFont(int size_delta, int style) const {
151 // If the delta is negative, if must not push the size below 1 138 const int new_size = font_size_pixels_ + size_delta;
152 if (size_delta < 0) 139 DCHECK_GT(new_size, 0);
153 DCHECK_LT(-size_delta, font_size_pixels_);
154 140
155 if (style == style_) { 141 // If the style changed, we may need to load a new face.
156 // Fast path, we just use the same typeface at a different size 142 skia::RefPtr<SkTypeface> typeface = typeface_;
157 return Font(new PlatformFontPango(typeface_, 143 if (style != style_) {
158 font_family_, 144 int skstyle = SkTypeface::kNormal;
159 font_size_pixels_ + size_delta, 145 if (gfx::Font::BOLD & style)
160 style_)); 146 skstyle |= SkTypeface::kBold;
147 if (gfx::Font::ITALIC & style)
148 skstyle |= SkTypeface::kItalic;
149 typeface = skia::AdoptRef(SkTypeface::CreateFromName(
150 font_family_.c_str(), static_cast<SkTypeface::Style>(skstyle)));
161 } 151 }
162 152
163 // If the style has changed we may need to load a new face 153 // If the size changed, get updated rendering settings.
164 int skstyle = SkTypeface::kNormal; 154 FontRenderParams render_params = font_render_params_;
165 if (gfx::Font::BOLD & style) 155 if (size_delta != 0) {
166 skstyle |= SkTypeface::kBold; 156 const std::vector<std::string> family_list(1, font_family_);
167 if (gfx::Font::ITALIC & style) 157 render_params = GetCustomFontRenderParams(
168 skstyle |= SkTypeface::kItalic; 158 false, &family_list, &new_size, NULL, NULL);
169 159 }
170 skia::RefPtr<SkTypeface> typeface = skia::AdoptRef(
171 SkTypeface::CreateFromName(
172 font_family_.c_str(),
173 static_cast<SkTypeface::Style>(skstyle)));
174 160
175 return Font(new PlatformFontPango(typeface, 161 return Font(new PlatformFontPango(typeface,
176 font_family_, 162 font_family_,
177 font_size_pixels_ + size_delta, 163 new_size,
178 style)); 164 style,
165 render_params));
179 } 166 }
180 167
181 int PlatformFontPango::GetHeight() const { 168 int PlatformFontPango::GetHeight() const {
182 return height_pixels_; 169 return height_pixels_;
183 } 170 }
184 171
185 int PlatformFontPango::GetBaseline() const { 172 int PlatformFontPango::GetBaseline() const {
186 return ascent_pixels_; 173 return ascent_pixels_;
187 } 174 }
188 175
(...skipping 17 matching lines...) Expand all
206 std::string PlatformFontPango::GetActualFontNameForTesting() const { 193 std::string PlatformFontPango::GetActualFontNameForTesting() const {
207 SkString family_name; 194 SkString family_name;
208 typeface_->getFamilyName(&family_name); 195 typeface_->getFamilyName(&family_name);
209 return family_name.c_str(); 196 return family_name.c_str();
210 } 197 }
211 198
212 int PlatformFontPango::GetFontSize() const { 199 int PlatformFontPango::GetFontSize() const {
213 return font_size_pixels_; 200 return font_size_pixels_;
214 } 201 }
215 202
203 const FontRenderParams& PlatformFontPango::GetFontRenderParams() const {
204 return font_render_params_;
205 }
206
216 NativeFont PlatformFontPango::GetNativeFont() const { 207 NativeFont PlatformFontPango::GetNativeFont() const {
217 PangoFontDescription* pfd = pango_font_description_new(); 208 PangoFontDescription* pfd = pango_font_description_new();
218 pango_font_description_set_family(pfd, GetFontName().c_str()); 209 pango_font_description_set_family(pfd, GetFontName().c_str());
219 // Set the absolute size to avoid overflowing UI elements. 210 // Set the absolute size to avoid overflowing UI elements.
220 // pango_font_description_set_absolute_size() takes a size in Pango units. 211 // pango_font_description_set_absolute_size() takes a size in Pango units.
221 // There are PANGO_SCALE Pango units in one device unit. Screen output 212 // There are PANGO_SCALE Pango units in one device unit. Screen output
222 // devices use pixels as their device units. 213 // devices use pixels as their device units.
223 pango_font_description_set_absolute_size( 214 pango_font_description_set_absolute_size(
224 pfd, font_size_pixels_ * PANGO_SCALE); 215 pfd, font_size_pixels_ * PANGO_SCALE);
225 216
(...skipping 14 matching lines...) Expand all
240 } 231 }
241 232
242 return pfd; 233 return pfd;
243 } 234 }
244 235
245 //////////////////////////////////////////////////////////////////////////////// 236 ////////////////////////////////////////////////////////////////////////////////
246 // PlatformFontPango, private: 237 // PlatformFontPango, private:
247 238
248 PlatformFontPango::PlatformFontPango(const skia::RefPtr<SkTypeface>& typeface, 239 PlatformFontPango::PlatformFontPango(const skia::RefPtr<SkTypeface>& typeface,
249 const std::string& name, 240 const std::string& name,
250 int size, 241 int size_pixels,
251 int style) { 242 int style,
252 InitFromDetails(typeface, name, size, style); 243 const FontRenderParams& render_params) {
244 InitFromDetails(typeface, name, size_pixels, style, render_params);
253 } 245 }
254 246
255 PlatformFontPango::~PlatformFontPango() {} 247 PlatformFontPango::~PlatformFontPango() {}
256 248
257 void PlatformFontPango::InitFromDetails( 249 void PlatformFontPango::InitFromDetails(
258 const skia::RefPtr<SkTypeface>& typeface, 250 const skia::RefPtr<SkTypeface>& typeface,
259 const std::string& font_family, 251 const std::string& font_family,
260 int font_size, 252 int font_size_pixels,
261 int style) { 253 int style,
262 DCHECK_GT(font_size, 0); 254 const FontRenderParams& render_params) {
255 DCHECK_GT(font_size_pixels, 0);
263 256
264 typeface_ = typeface; 257 typeface_ = typeface;
265 font_family_ = font_family; 258 font_family_ = font_family;
266 if (!typeface_) { 259 if (!typeface_) {
267 typeface_ = skia::AdoptRef( 260 typeface_ = skia::AdoptRef(
268 SkTypeface::CreateFromName(font_family.c_str(), SkTypeface::kNormal)); 261 SkTypeface::CreateFromName(font_family.c_str(), SkTypeface::kNormal));
269 if (!typeface_) { 262 if (!typeface_) {
270 // A non-scalable font such as .pcf is specified. Fall back to a default 263 // A non-scalable font such as .pcf is specified. Fall back to a default
271 // scalable font. 264 // scalable font.
272 typeface_ = skia::AdoptRef(SkTypeface::CreateFromName( 265 typeface_ = skia::AdoptRef(SkTypeface::CreateFromName(
273 kFallbackFontFamilyName, SkTypeface::kNormal)); 266 kFallbackFontFamilyName, SkTypeface::kNormal));
274 CHECK(typeface_) << "Could not find any font: " << font_family << ", " 267 CHECK(typeface_) << "Could not find any font: " << font_family << ", "
275 << kFallbackFontFamilyName; 268 << kFallbackFontFamilyName;
276 font_family_ = kFallbackFontFamilyName; 269 font_family_ = kFallbackFontFamilyName;
277 } 270 }
278 } 271 }
279 272
280 font_size_pixels_ = font_size; 273 font_size_pixels_ = font_size_pixels;
281 style_ = style; 274 style_ = style;
275 font_render_params_ = render_params;
282 276
283 SkPaint paint; 277 SkPaint paint;
284 SkPaint::FontMetrics metrics; 278 SkPaint::FontMetrics metrics;
285 PaintSetup(&paint); 279 PaintSetup(&paint);
286 paint.getFontMetrics(&metrics); 280 paint.getFontMetrics(&metrics);
287 ascent_pixels_ = SkScalarCeilToInt(-metrics.fAscent); 281 ascent_pixels_ = SkScalarCeilToInt(-metrics.fAscent);
288 height_pixels_ = ascent_pixels_ + SkScalarCeilToInt(metrics.fDescent); 282 height_pixels_ = ascent_pixels_ + SkScalarCeilToInt(metrics.fDescent);
289 cap_height_pixels_ = SkScalarCeilToInt(metrics.fCapHeight); 283 cap_height_pixels_ = SkScalarCeilToInt(metrics.fCapHeight);
290 284
291 pango_metrics_inited_ = false; 285 pango_metrics_inited_ = false;
292 average_width_pixels_ = 0.0f; 286 average_width_pixels_ = 0.0f;
293 underline_position_pixels_ = 0.0f; 287 underline_position_pixels_ = 0.0f;
294 underline_thickness_pixels_ = 0.0f; 288 underline_thickness_pixels_ = 0.0f;
295 } 289 }
296 290
297 void PlatformFontPango::InitFromPlatformFont(const PlatformFontPango* other) { 291 void PlatformFontPango::InitFromPlatformFont(const PlatformFontPango* other) {
298 typeface_ = other->typeface_; 292 typeface_ = other->typeface_;
299 font_family_ = other->font_family_; 293 font_family_ = other->font_family_;
300 font_size_pixels_ = other->font_size_pixels_; 294 font_size_pixels_ = other->font_size_pixels_;
301 style_ = other->style_; 295 style_ = other->style_;
296 font_render_params_ = other->font_render_params_;
302 ascent_pixels_ = other->ascent_pixels_; 297 ascent_pixels_ = other->ascent_pixels_;
303 height_pixels_ = other->height_pixels_; 298 height_pixels_ = other->height_pixels_;
304 cap_height_pixels_ = other->cap_height_pixels_; 299 cap_height_pixels_ = other->cap_height_pixels_;
305 pango_metrics_inited_ = other->pango_metrics_inited_; 300 pango_metrics_inited_ = other->pango_metrics_inited_;
306 average_width_pixels_ = other->average_width_pixels_; 301 average_width_pixels_ = other->average_width_pixels_;
307 underline_position_pixels_ = other->underline_position_pixels_; 302 underline_position_pixels_ = other->underline_position_pixels_;
308 underline_thickness_pixels_ = other->underline_thickness_pixels_; 303 underline_thickness_pixels_ = other->underline_thickness_pixels_;
309 } 304 }
310 305
311 void PlatformFontPango::PaintSetup(SkPaint* paint) const { 306 void PlatformFontPango::PaintSetup(SkPaint* paint) const {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 return new PlatformFontPango(native_font); 366 return new PlatformFontPango(native_font);
372 } 367 }
373 368
374 // static 369 // static
375 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name, 370 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name,
376 int font_size) { 371 int font_size) {
377 return new PlatformFontPango(font_name, font_size); 372 return new PlatformFontPango(font_name, font_size);
378 } 373 }
379 374
380 } // namespace gfx 375 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/platform_font_pango.h ('k') | ui/gfx/platform_font_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698