diff options
-rw-r--r-- | ui/gfx/platform_font_pango.cc | 51 | ||||
-rw-r--r-- | ui/gfx/platform_font_pango_unittest.cc | 28 | ||||
-rw-r--r-- | ui/ui_unittests.gypi | 5 |
3 files changed, 56 insertions, 28 deletions
diff --git a/ui/gfx/platform_font_pango.cc b/ui/gfx/platform_font_pango.cc index 9ce18d1..5037829 100644 --- a/ui/gfx/platform_font_pango.cc +++ b/ui/gfx/platform_font_pango.cc @@ -12,6 +12,7 @@ #include "base/logging.h" #include "base/string_piece.h" +#include "base/string_split.h" #include "base/utf_string_conversions.h" #include "grit/app_locale_settings.h" #include "third_party/skia/include/core/SkTypeface.h" @@ -63,38 +64,34 @@ PangoFontMetrics* GetPangoFontMetrics(PangoFontDescription* desc) { } } -// Find the best match font for |family_name| in the same way as Skia -// to make sure CreateFont() successfully creates a default font. In -// Skia, it only checks the best match font. If it failed to find -// one, SkTypeface will be NULL for that font family. It eventually -// causes a 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 -// the system has a font for "Sans" font family. See FontMatch() in -// skia/ports/SkFontHost_fontconfig.cpp for more detail. -std::string FindBestMatchFontFamilyName(const char* family_name) { +// Returns the available font family that best (in FontConfig's eyes) matches +// the supplied list of family names. +std::string FindBestMatchFontFamilyName( + const std::vector<std::string>& family_names) { 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); + for (std::vector<std::string>::const_iterator it = family_names.begin(); + it != family_names.end(); ++it) { + FcValue fcvalue; + fcvalue.type = FcTypeString; + fcvalue.u.s = reinterpret_cast<const FcChar8*>(it->c_str()); + FcPatternAdd(pattern, FC_FAMILY, fcvalue, FcTrue /* append */); + } + 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; + DCHECK(match) << "Could not find font"; + FcChar8* match_family = NULL; FcPatternGetString(match, FC_FAMILY, 0, &match_family); - std::string font_family(reinterpret_cast<char*>(match_family)); - FcPatternDestroy(match); FcPatternDestroy(pattern); - free(family_name_copy); + FcPatternDestroy(match); return font_family; } +// Returns a Pango font description (suitable for parsing by +// pango_font_description_from_string()) for the default UI font. std::string GetDefaultFont() { #if defined(USE_WAYLAND) || !defined(TOOLKIT_USES_GTK) #if defined(OS_CHROMEOS) @@ -149,14 +146,12 @@ PlatformFontPango::PlatformFontPango(const Font& other) { } PlatformFontPango::PlatformFontPango(NativeFont native_font) { - const char* family_name = pango_font_description_get_family(native_font); - - // Find best match font for |family_name| to make sure we can get - // a SkTypeface for the default font. - // TODO(agl): remove this. - std::string font_family = FindBestMatchFontFamilyName(family_name); - + std::vector<std::string> family_names; + base::SplitString(pango_font_description_get_family(native_font), ',', + &family_names); + std::string font_family = FindBestMatchFontFamilyName(family_names); InitWithNameAndSize(font_family, gfx::GetPangoFontSizeInPixels(native_font)); + int style = 0; if (pango_font_description_get_weight(native_font) == PANGO_WEIGHT_BOLD) { // TODO(davemoore) What should we do about other weights? We currently diff --git a/ui/gfx/platform_font_pango_unittest.cc b/ui/gfx/platform_font_pango_unittest.cc new file mode 100644 index 0000000..b36046c --- /dev/null +++ b/ui/gfx/platform_font_pango_unittest.cc @@ -0,0 +1,28 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/platform_font_pango.h" + +#include <string> + +#include "base/memory/ref_counted.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/pango_util.h" + +// Test that PlatformFontPango is able to cope with PangoFontDescriptions +// containing multiple font families. The first family should be preferred. +TEST(PlatformFontPangoTest, FamilyList) { + PangoFontDescription* desc = + pango_font_description_from_string("Arial,Times New Roman, 13px"); + scoped_refptr<gfx::PlatformFontPango> font(new gfx::PlatformFontPango(desc)); + pango_font_description_free(desc); + EXPECT_EQ("Arial", font->GetFontName()); + EXPECT_EQ(13, font->GetFontSize()); + + desc = pango_font_description_from_string("Times New Roman,Arial, 15px"); + scoped_refptr<gfx::PlatformFontPango> font2(new gfx::PlatformFontPango(desc)); + pango_font_description_free(desc); + EXPECT_EQ("Times New Roman", font2->GetFontName()); + EXPECT_EQ(15, font2->GetFontSize()); +} diff --git a/ui/ui_unittests.gypi b/ui/ui_unittests.gypi index 638ddb2..bbc56c7 100644 --- a/ui/ui_unittests.gypi +++ b/ui/ui_unittests.gypi @@ -127,6 +127,11 @@ ], }, }], + ['OS == "linux"', { + 'sources': [ + 'gfx/platform_font_pango_unittest.cc', + ], + }], ['OS == "linux" and toolkit_views==1', { 'sources': [ 'base/x/events_x_unittest.cc', |