diff options
Diffstat (limited to 'chrome/common')
-rw-r--r-- | chrome/common/gfx/chrome_font.h | 6 | ||||
-rw-r--r-- | chrome/common/gfx/chrome_font_gtk.cc | 44 | ||||
-rw-r--r-- | chrome/common/gfx/chrome_font_skia.cc | 21 |
3 files changed, 57 insertions, 14 deletions
diff --git a/chrome/common/gfx/chrome_font.h b/chrome/common/gfx/chrome_font.h index af68aa1..0358afc 100644 --- a/chrome/common/gfx/chrome_font.h +++ b/chrome/common/gfx/chrome_font.h @@ -50,6 +50,7 @@ class ChromeFont { }; // Creates a ChromeFont given font name (e.g. arial), font size (e.g. 12). + // Skia actually expects a family name and not a font name. static ChromeFont CreateFont(const std::wstring& font_name, int font_size); ~ChromeFont() { } @@ -91,6 +92,8 @@ class ChromeFont { int style() const; // Font Name. + // It is actually a font family name, because Skia expects a family name + // and not a font name. std::wstring FontName(); // Font Size. @@ -204,7 +207,8 @@ class ChromeFont { SkTypeface *typeface_; // Additional information about the face - std::wstring font_name_; + // Skia actually expects a family name and not a font name. + std::wstring font_family_; int font_size_; int style_; diff --git a/chrome/common/gfx/chrome_font_gtk.cc b/chrome/common/gfx/chrome_font_gtk.cc index bdb0324..f0d2120 100644 --- a/chrome/common/gfx/chrome_font_gtk.cc +++ b/chrome/common/gfx/chrome_font_gtk.cc @@ -4,12 +4,46 @@ #include "chrome/common/gfx/chrome_font.h" +#include <fontconfig/fontconfig.h> #include <gtk/gtk.h> #include "base/string_util.h" ChromeFont* ChromeFont::default_font_ = NULL; +// Find the best match font for |family_name| in the same way as Skia +// to make sure CreateFont() successfully creates default font. +// In Skia, it only checks the best match font. If it failed to find, +// SkTypeface will be NULL for that font family. It eventually causes segfault. +// For example, family_name = "Sans" and system may have various fonts. +// The first font family in FcPattern will be "DejaVu Sans" but a font family +// returned by FcFontMatch will be "VL PGothic". +// In this case, SkTypeface for "Sans" returns NULL even if system has font +// for "Sans" font family. +// See FontMatch() in skia/ports/SkFontHost_fontconfig.cpp for more detail. +static std::wstring FindBestMatchFontFamilyName(const char* family_name) { + FcPattern* pattern = FcPatternCreate(); + FcValue fcvalue; + fcvalue.type = FcTypeString; + char* family_name_copy = strdup(family_name); + fcvalue.u.s = reinterpret_cast<FcChar8*>(family_name_copy); + FcPatternAdd(pattern, FC_FAMILY, fcvalue, 0); + FcConfigSubstitute(0, pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); + FcResult result; + FcPattern* match = FcFontMatch(0, pattern, &result); + DCHECK(match) << "Could not find font: " << family_name; + FcChar8* match_family; + FcPatternGetString(match, FC_FAMILY, 0, &match_family); + + std::wstring font_family = UTF8ToWide( + reinterpret_cast<char*>(match_family)); + FcPatternDestroy(match); + FcPatternDestroy(pattern); + free(family_name_copy); + return font_family; +} + // Get the default gtk system font (name and size). ChromeFont::ChromeFont() { if (default_font_ == NULL) { @@ -31,10 +65,14 @@ ChromeFont::ChromeFont() { PangoFontDescription* desc = pango_font_description_from_string(font_ptr); gint size = pango_font_description_get_size(desc); - const char* name = pango_font_description_get_family(desc); + const char* family_name = pango_font_description_get_family(desc); + + // Find best match font for |family_name| to make sure we can get + // SkTypeface for default font. + // TODO(agl): remove this. + std::wstring font_family = FindBestMatchFontFamilyName(family_name); - default_font_ = new ChromeFont(CreateFont(UTF8ToWide(name), - size / PANGO_SCALE)); + default_font_ = new ChromeFont(CreateFont(font_family, size / PANGO_SCALE)); pango_font_description_free(desc); g_free(font_name); diff --git a/chrome/common/gfx/chrome_font_skia.cc b/chrome/common/gfx/chrome_font_skia.cc index 096513a..6c80c8d 100644 --- a/chrome/common/gfx/chrome_font_skia.cc +++ b/chrome/common/gfx/chrome_font_skia.cc @@ -19,11 +19,11 @@ ChromeFont& ChromeFont::operator=(const ChromeFont& other) { return *this; } -ChromeFont::ChromeFont(SkTypeface* tf, const std::wstring& font_name, +ChromeFont::ChromeFont(SkTypeface* tf, const std::wstring& font_family, int font_size, int style) : typeface_helper_(new SkAutoUnref(tf)), typeface_(tf), - font_name_(font_name), + font_family_(font_family), font_size_(font_size), style_(style) { tf->ref(); @@ -60,7 +60,7 @@ void ChromeFont::CopyChromeFont(const ChromeFont& other) { typeface_helper_.reset(new SkAutoUnref(other.typeface_)); typeface_ = other.typeface_; typeface_->ref(); - font_name_ = other.font_name_; + font_family_ = other.font_family_; font_size_ = other.font_size_; style_ = other.style_; height_ = other.height_; @@ -80,15 +80,16 @@ int ChromeFont::ave_char_width() const { return avg_width_; } -ChromeFont ChromeFont::CreateFont(const std::wstring& font_name, +ChromeFont ChromeFont::CreateFont(const std::wstring& font_family, int font_size) { DCHECK_GT(font_size, 0); - SkTypeface* tf = SkTypeface::Create(base::SysWideToUTF8(font_name).c_str(), + SkTypeface* tf = SkTypeface::Create(base::SysWideToUTF8(font_family).c_str(), SkTypeface::kNormal); + DCHECK(tf) << "Could not find font: " << base::SysWideToUTF8(font_family); SkAutoUnref tf_helper(tf); - return ChromeFont(tf, font_name, font_size, NORMAL); + return ChromeFont(tf, font_family, font_size, NORMAL); } ChromeFont ChromeFont::DeriveFont(int size_delta, int style) const { @@ -99,7 +100,7 @@ ChromeFont ChromeFont::DeriveFont(int size_delta, int style) const { if (style == style_) { // Fast path, we just use the same typeface at a different size - return ChromeFont(typeface_, font_name_, font_size_ + size_delta, style_); + return ChromeFont(typeface_, font_family_, font_size_ + size_delta, style_); } // If the style has changed we may need to load a new face @@ -109,11 +110,11 @@ ChromeFont ChromeFont::DeriveFont(int size_delta, int style) const { if (ITALIC & style) skstyle |= SkTypeface::kItalic; - SkTypeface* tf = SkTypeface::Create(base::SysWideToUTF8(font_name_).c_str(), + SkTypeface* tf = SkTypeface::Create(base::SysWideToUTF8(font_family_).c_str(), static_cast<SkTypeface::Style>(skstyle)); SkAutoUnref tf_helper(tf); - return ChromeFont(tf, font_name_, font_size_ + size_delta, skstyle); + return ChromeFont(tf, font_family_, font_size_ + size_delta, skstyle); } void ChromeFont::PaintSetup(SkPaint* paint) const { @@ -154,7 +155,7 @@ int ChromeFont::style() const { } std::wstring ChromeFont::FontName() { - return font_name_; + return font_family_; } int ChromeFont::FontSize() { |