summaryrefslogtreecommitdiffstats
path: root/chrome/common
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/common')
-rw-r--r--chrome/common/gfx/chrome_font.h6
-rw-r--r--chrome/common/gfx/chrome_font_gtk.cc44
-rw-r--r--chrome/common/gfx/chrome_font_skia.cc21
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() {