| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <fontconfig/fontconfig.h> | 8 #include <fontconfig/fontconfig.h> |
| 9 #include <map> | 9 #include <map> |
| 10 #include <pango/pango.h> | 10 #include <pango/pango.h> |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 // Find the best match font for |family_name| in the same way as Skia | 84 // Find the best match font for |family_name| in the same way as Skia |
| 85 // to make sure CreateFont() successfully creates a default font. In | 85 // to make sure CreateFont() successfully creates a default font. In |
| 86 // Skia, it only checks the best match font. If it failed to find | 86 // Skia, it only checks the best match font. If it failed to find |
| 87 // one, SkTypeface will be NULL for that font family. It eventually | 87 // one, SkTypeface will be NULL for that font family. It eventually |
| 88 // causes a segfault. For example, family_name = "Sans" and system | 88 // causes a segfault. For example, family_name = "Sans" and system |
| 89 // may have various fonts. The first font family in FcPattern will be | 89 // may have various fonts. The first font family in FcPattern will be |
| 90 // "DejaVu Sans" but a font family returned by FcFontMatch will be "VL | 90 // "DejaVu Sans" but a font family returned by FcFontMatch will be "VL |
| 91 // PGothic". In this case, SkTypeface for "Sans" returns NULL even if | 91 // PGothic". In this case, SkTypeface for "Sans" returns NULL even if |
| 92 // the system has a font for "Sans" font family. See FontMatch() in | 92 // the system has a font for "Sans" font family. See FontMatch() in |
| 93 // skia/ports/SkFontHost_fontconfig.cpp for more detail. | 93 // skia/ports/SkFontHost_fontconfig.cpp for more detail. |
| 94 string16 FindBestMatchFontFamilyName(const char* family_name) { | 94 std::string FindBestMatchFontFamilyName(const char* family_name) { |
| 95 FcPattern* pattern = FcPatternCreate(); | 95 FcPattern* pattern = FcPatternCreate(); |
| 96 FcValue fcvalue; | 96 FcValue fcvalue; |
| 97 fcvalue.type = FcTypeString; | 97 fcvalue.type = FcTypeString; |
| 98 char* family_name_copy = strdup(family_name); | 98 char* family_name_copy = strdup(family_name); |
| 99 fcvalue.u.s = reinterpret_cast<FcChar8*>(family_name_copy); | 99 fcvalue.u.s = reinterpret_cast<FcChar8*>(family_name_copy); |
| 100 FcPatternAdd(pattern, FC_FAMILY, fcvalue, 0); | 100 FcPatternAdd(pattern, FC_FAMILY, fcvalue, 0); |
| 101 FcConfigSubstitute(0, pattern, FcMatchPattern); | 101 FcConfigSubstitute(0, pattern, FcMatchPattern); |
| 102 FcDefaultSubstitute(pattern); | 102 FcDefaultSubstitute(pattern); |
| 103 FcResult result; | 103 FcResult result; |
| 104 FcPattern* match = FcFontMatch(0, pattern, &result); | 104 FcPattern* match = FcFontMatch(0, pattern, &result); |
| 105 DCHECK(match) << "Could not find font: " << family_name; | 105 DCHECK(match) << "Could not find font: " << family_name; |
| 106 FcChar8* match_family; | 106 FcChar8* match_family; |
| 107 FcPatternGetString(match, FC_FAMILY, 0, &match_family); | 107 FcPatternGetString(match, FC_FAMILY, 0, &match_family); |
| 108 | 108 |
| 109 string16 font_family = UTF8ToUTF16(reinterpret_cast<char*>(match_family)); | 109 std::string font_family(reinterpret_cast<char*>(match_family)); |
| 110 FcPatternDestroy(match); | 110 FcPatternDestroy(match); |
| 111 FcPatternDestroy(pattern); | 111 FcPatternDestroy(pattern); |
| 112 free(family_name_copy); | 112 free(family_name_copy); |
| 113 return font_family; | 113 return font_family; |
| 114 } | 114 } |
| 115 | 115 |
| 116 std::string GetDefaultFont() { | 116 std::string GetDefaultFont() { |
| 117 #if defined(USE_WAYLAND) || !defined(TOOLKIT_USES_GTK) | 117 #if defined(USE_WAYLAND) || !defined(TOOLKIT_USES_GTK) |
| 118 return "sans 10"; | 118 return "sans 10"; |
| 119 #else | 119 #else |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 } else { | 173 } else { |
| 174 // Otherwise, we need to convert from points. | 174 // Otherwise, we need to convert from points. |
| 175 size_in_pixels = | 175 size_in_pixels = |
| 176 pango_font_description_get_size(native_font) * GetPixelsInPoint() / | 176 pango_font_description_get_size(native_font) * GetPixelsInPoint() / |
| 177 PANGO_SCALE; | 177 PANGO_SCALE; |
| 178 } | 178 } |
| 179 | 179 |
| 180 // Find best match font for |family_name| to make sure we can get | 180 // Find best match font for |family_name| to make sure we can get |
| 181 // a SkTypeface for the default font. | 181 // a SkTypeface for the default font. |
| 182 // TODO(agl): remove this. | 182 // TODO(agl): remove this. |
| 183 string16 font_family = FindBestMatchFontFamilyName(family_name); | 183 std::string font_family = FindBestMatchFontFamilyName(family_name); |
| 184 | 184 |
| 185 InitWithNameAndSize(font_family, size_in_pixels); | 185 InitWithNameAndSize(font_family, size_in_pixels); |
| 186 int style = 0; | 186 int style = 0; |
| 187 if (pango_font_description_get_weight(native_font) == PANGO_WEIGHT_BOLD) { | 187 if (pango_font_description_get_weight(native_font) == PANGO_WEIGHT_BOLD) { |
| 188 // TODO(davemoore) What should we do about other weights? We currently | 188 // TODO(davemoore) What should we do about other weights? We currently |
| 189 // only support BOLD. | 189 // only support BOLD. |
| 190 style |= gfx::Font::BOLD; | 190 style |= gfx::Font::BOLD; |
| 191 } | 191 } |
| 192 if (pango_font_description_get_style(native_font) == PANGO_STYLE_ITALIC) { | 192 if (pango_font_description_get_style(native_font) == PANGO_STYLE_ITALIC) { |
| 193 // TODO(davemoore) What about PANGO_STYLE_OBLIQUE? | 193 // TODO(davemoore) What about PANGO_STYLE_OBLIQUE? |
| 194 style |= gfx::Font::ITALIC; | 194 style |= gfx::Font::ITALIC; |
| 195 } | 195 } |
| 196 if (style != 0) | 196 if (style != 0) |
| 197 style_ = style; | 197 style_ = style; |
| 198 } | 198 } |
| 199 | 199 |
| 200 PlatformFontPango::PlatformFontPango(const string16& font_name, | 200 PlatformFontPango::PlatformFontPango(const std::string& font_name, |
| 201 int font_size) { | 201 int font_size) { |
| 202 InitWithNameAndSize(font_name, font_size); | 202 InitWithNameAndSize(font_name, font_size); |
| 203 } | 203 } |
| 204 | 204 |
| 205 double PlatformFontPango::underline_position() const { | 205 double PlatformFontPango::underline_position() const { |
| 206 const_cast<PlatformFontPango*>(this)->InitPangoMetrics(); | 206 const_cast<PlatformFontPango*>(this)->InitPangoMetrics(); |
| 207 return underline_position_pixels_; | 207 return underline_position_pixels_; |
| 208 } | 208 } |
| 209 | 209 |
| 210 double PlatformFontPango::underline_thickness() const { | 210 double PlatformFontPango::underline_thickness() const { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 235 } | 235 } |
| 236 | 236 |
| 237 // If the style has changed we may need to load a new face | 237 // If the style has changed we may need to load a new face |
| 238 int skstyle = SkTypeface::kNormal; | 238 int skstyle = SkTypeface::kNormal; |
| 239 if (gfx::Font::BOLD & style) | 239 if (gfx::Font::BOLD & style) |
| 240 skstyle |= SkTypeface::kBold; | 240 skstyle |= SkTypeface::kBold; |
| 241 if (gfx::Font::ITALIC & style) | 241 if (gfx::Font::ITALIC & style) |
| 242 skstyle |= SkTypeface::kItalic; | 242 skstyle |= SkTypeface::kItalic; |
| 243 | 243 |
| 244 SkTypeface* typeface = SkTypeface::CreateFromName( | 244 SkTypeface* typeface = SkTypeface::CreateFromName( |
| 245 UTF16ToUTF8(font_family_).c_str(), | 245 font_family_.c_str(), |
| 246 static_cast<SkTypeface::Style>(skstyle)); | 246 static_cast<SkTypeface::Style>(skstyle)); |
| 247 SkAutoUnref tf_helper(typeface); | 247 SkAutoUnref tf_helper(typeface); |
| 248 | 248 |
| 249 return Font(new PlatformFontPango(typeface, | 249 return Font(new PlatformFontPango(typeface, |
| 250 font_family_, | 250 font_family_, |
| 251 font_size_pixels_ + size_delta, | 251 font_size_pixels_ + size_delta, |
| 252 style)); | 252 style)); |
| 253 } | 253 } |
| 254 | 254 |
| 255 int PlatformFontPango::GetHeight() const { | 255 int PlatformFontPango::GetHeight() const { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 274 | 274 |
| 275 int PlatformFontPango::GetExpectedTextWidth(int length) const { | 275 int PlatformFontPango::GetExpectedTextWidth(int length) const { |
| 276 double char_width = const_cast<PlatformFontPango*>(this)->GetAverageWidth(); | 276 double char_width = const_cast<PlatformFontPango*>(this)->GetAverageWidth(); |
| 277 return round(static_cast<float>(length) * char_width); | 277 return round(static_cast<float>(length) * char_width); |
| 278 } | 278 } |
| 279 | 279 |
| 280 int PlatformFontPango::GetStyle() const { | 280 int PlatformFontPango::GetStyle() const { |
| 281 return style_; | 281 return style_; |
| 282 } | 282 } |
| 283 | 283 |
| 284 string16 PlatformFontPango::GetFontName() const { | 284 std::string PlatformFontPango::GetFontName() const { |
| 285 return font_family_; | 285 return font_family_; |
| 286 } | 286 } |
| 287 | 287 |
| 288 int PlatformFontPango::GetFontSize() const { | 288 int PlatformFontPango::GetFontSize() const { |
| 289 return font_size_pixels_; | 289 return font_size_pixels_; |
| 290 } | 290 } |
| 291 | 291 |
| 292 NativeFont PlatformFontPango::GetNativeFont() const { | 292 NativeFont PlatformFontPango::GetNativeFont() const { |
| 293 PangoFontDescription* pfd = pango_font_description_new(); | 293 PangoFontDescription* pfd = pango_font_description_new(); |
| 294 pango_font_description_set_family(pfd, UTF16ToUTF8(GetFontName()).c_str()); | 294 pango_font_description_set_family(pfd, GetFontName().c_str()); |
| 295 // Set the absolute size to avoid overflowing UI elements. | 295 // Set the absolute size to avoid overflowing UI elements. |
| 296 // pango_font_description_set_absolute_size() takes a size in Pango units. | 296 // pango_font_description_set_absolute_size() takes a size in Pango units. |
| 297 // There are PANGO_SCALE Pango units in one device unit. Screen output | 297 // There are PANGO_SCALE Pango units in one device unit. Screen output |
| 298 // devices use pixels as their device units. | 298 // devices use pixels as their device units. |
| 299 pango_font_description_set_absolute_size( | 299 pango_font_description_set_absolute_size( |
| 300 pfd, font_size_pixels_ * PANGO_SCALE); | 300 pfd, font_size_pixels_ * PANGO_SCALE); |
| 301 | 301 |
| 302 switch (GetStyle()) { | 302 switch (GetStyle()) { |
| 303 case gfx::Font::NORMAL: | 303 case gfx::Font::NORMAL: |
| 304 // Nothing to do, should already be PANGO_STYLE_NORMAL. | 304 // Nothing to do, should already be PANGO_STYLE_NORMAL. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 315 break; | 315 break; |
| 316 } | 316 } |
| 317 | 317 |
| 318 return pfd; | 318 return pfd; |
| 319 } | 319 } |
| 320 | 320 |
| 321 //////////////////////////////////////////////////////////////////////////////// | 321 //////////////////////////////////////////////////////////////////////////////// |
| 322 // PlatformFontPango, private: | 322 // PlatformFontPango, private: |
| 323 | 323 |
| 324 PlatformFontPango::PlatformFontPango(SkTypeface* typeface, | 324 PlatformFontPango::PlatformFontPango(SkTypeface* typeface, |
| 325 const string16& name, | 325 const std::string& name, |
| 326 int size, | 326 int size, |
| 327 int style) { | 327 int style) { |
| 328 InitWithTypefaceNameSizeAndStyle(typeface, name, size, style); | 328 InitWithTypefaceNameSizeAndStyle(typeface, name, size, style); |
| 329 } | 329 } |
| 330 | 330 |
| 331 PlatformFontPango::~PlatformFontPango() {} | 331 PlatformFontPango::~PlatformFontPango() {} |
| 332 | 332 |
| 333 void PlatformFontPango::InitWithNameAndSize(const string16& font_name, | 333 void PlatformFontPango::InitWithNameAndSize(const std::string& font_name, |
| 334 int font_size) { | 334 int font_size) { |
| 335 DCHECK_GT(font_size, 0); | 335 DCHECK_GT(font_size, 0); |
| 336 string16 fallback; | 336 std::string fallback; |
| 337 | 337 |
| 338 SkTypeface* typeface = SkTypeface::CreateFromName( | 338 SkTypeface* typeface = SkTypeface::CreateFromName( |
| 339 UTF16ToUTF8(font_name).c_str(), SkTypeface::kNormal); | 339 font_name.c_str(), SkTypeface::kNormal); |
| 340 if (!typeface) { | 340 if (!typeface) { |
| 341 // A non-scalable font such as .pcf is specified. Falls back to a default | 341 // A non-scalable font such as .pcf is specified. Falls back to a default |
| 342 // scalable font. | 342 // scalable font. |
| 343 typeface = SkTypeface::CreateFromName( | 343 typeface = SkTypeface::CreateFromName( |
| 344 kFallbackFontFamilyName, SkTypeface::kNormal); | 344 kFallbackFontFamilyName, SkTypeface::kNormal); |
| 345 CHECK(typeface) << "Could not find any font: " | 345 CHECK(typeface) << "Could not find any font: " |
| 346 << UTF16ToUTF8(font_name) | 346 << font_name |
| 347 << ", " << kFallbackFontFamilyName; | 347 << ", " << kFallbackFontFamilyName; |
| 348 fallback = UTF8ToUTF16(kFallbackFontFamilyName); | 348 fallback = kFallbackFontFamilyName; |
| 349 } | 349 } |
| 350 SkAutoUnref typeface_helper(typeface); | 350 SkAutoUnref typeface_helper(typeface); |
| 351 | 351 |
| 352 InitWithTypefaceNameSizeAndStyle(typeface, | 352 InitWithTypefaceNameSizeAndStyle(typeface, |
| 353 fallback.empty() ? font_name : fallback, | 353 fallback.empty() ? font_name : fallback, |
| 354 font_size, | 354 font_size, |
| 355 gfx::Font::NORMAL); | 355 gfx::Font::NORMAL); |
| 356 } | 356 } |
| 357 | 357 |
| 358 void PlatformFontPango::InitWithTypefaceNameSizeAndStyle( | 358 void PlatformFontPango::InitWithTypefaceNameSizeAndStyle( |
| 359 SkTypeface* typeface, | 359 SkTypeface* typeface, |
| 360 const string16& font_family, | 360 const std::string& font_family, |
| 361 int font_size, | 361 int font_size, |
| 362 int style) { | 362 int style) { |
| 363 typeface_helper_.reset(new SkAutoUnref(typeface)); | 363 typeface_helper_.reset(new SkAutoUnref(typeface)); |
| 364 typeface_ = typeface; | 364 typeface_ = typeface; |
| 365 typeface_->ref(); | 365 typeface_->ref(); |
| 366 font_family_ = font_family; | 366 font_family_ = font_family; |
| 367 font_size_pixels_ = font_size; | 367 font_size_pixels_ = font_size; |
| 368 style_ = style; | 368 style_ = style; |
| 369 pango_metrics_inited_ = false; | 369 pango_metrics_inited_ = false; |
| 370 average_width_pixels_ = 0.0f; | 370 average_width_pixels_ = 0.0f; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 PlatformFont* PlatformFont::CreateFromFont(const Font& other) { | 457 PlatformFont* PlatformFont::CreateFromFont(const Font& other) { |
| 458 return new PlatformFontPango(other); | 458 return new PlatformFontPango(other); |
| 459 } | 459 } |
| 460 | 460 |
| 461 // static | 461 // static |
| 462 PlatformFont* PlatformFont::CreateFromNativeFont(NativeFont native_font) { | 462 PlatformFont* PlatformFont::CreateFromNativeFont(NativeFont native_font) { |
| 463 return new PlatformFontPango(native_font); | 463 return new PlatformFontPango(native_font); |
| 464 } | 464 } |
| 465 | 465 |
| 466 // static | 466 // static |
| 467 PlatformFont* PlatformFont::CreateFromNameAndSize(const string16& font_name, | 467 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name, |
| 468 int font_size) { | 468 int font_size) { |
| 469 return new PlatformFontPango(font_name, font_size); | 469 return new PlatformFontPango(font_name, font_size); |
| 470 } | 470 } |
| 471 | 471 |
| 472 } // namespace gfx | 472 } // namespace gfx |
| OLD | NEW |