// IsFallbackFontAllowed function in skia/ext/SkFontHost_fontconfig_direct.cpp.
const char* kFallbackFontFamilyName = "sans";
-// 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();
- 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 */);
- }
+// Creates a SkTypeface for the passed-in Font::FontStyle and family. If a
+// fallback typeface is used instead of the requested family, |family| will be
+// updated to contain the fallback's family name.
+skia::RefPtr<SkTypeface> CreateSkTypeface(int style, std::string* family) {
+ DCHECK(family);
+
+ int skia_style = SkTypeface::kNormal;
+ if (gfx::Font::BOLD & style)
+ skia_style |= SkTypeface::kBold;
+ if (gfx::Font::ITALIC & style)
+ skia_style |= SkTypeface::kItalic;
- FcConfigSubstitute(0, pattern, FcMatchPattern);
- FcDefaultSubstitute(pattern);
- FcResult result;
- FcPattern* match = FcFontMatch(0, pattern, &result);
- 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(pattern);
- FcPatternDestroy(match);
- return font_family;
+ skia::RefPtr<SkTypeface> typeface = skia::AdoptRef(SkTypeface::CreateFromName(
+ family->c_str(), static_cast<SkTypeface::Style>(skia_style)));
+ if (!typeface) {
+ // A non-scalable font such as .pcf is specified. Fall back to a default
+ // scalable font.
+ typeface = skia::AdoptRef(SkTypeface::CreateFromName(
+ kFallbackFontFamilyName, static_cast<SkTypeface::Style>(skia_style)));
+ CHECK(typeface) << "Could not find any font: " << family << ", "
+ << kFallbackFontFamilyName;
+ *family = kFallbackFontFamilyName;
+ }
+ return typeface;
}
} // namespace
// PlatformFontPango, public:
PlatformFontPango::PlatformFontPango() {
- if (default_font_ == NULL) {
- std::string font_name = GetDefaultFont();
-
- ScopedPangoFontDescription desc(
- pango_font_description_from_string(font_name.c_str()));
- default_font_ = new Font(desc.get());
-
- DCHECK(default_font_);
+ if (!default_font_) {
+ scoped_ptr<ScopedPangoFontDescription> description;
+#if defined(OS_CHROMEOS)
+ CHECK(default_font_description_);
+ description.reset(
+ new ScopedPangoFontDescription(*default_font_description_));
+#else
+ const gfx::LinuxFontDelegate* delegate = gfx::LinuxFontDelegate::instance();
+ if (delegate)
+ description = delegate->GetDefaultPangoFontDescription();
+#endif
+ if (!description || !description->get())
+ description.reset(new ScopedPangoFontDescription("sans 10"));
+ default_font_ = new Font(description->get());
}
InitFromPlatformFont(
}
PlatformFontPango::PlatformFontPango(NativeFont native_font) {
- std::vector<std::string> family_names;
+ FontRenderParamsQuery query(false);
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
- // only support BOLD.
- style |= gfx::Font::BOLD;
- }
- if (pango_font_description_get_style(native_font) == PANGO_STYLE_ITALIC) {
- // TODO(davemoore) What about PANGO_STYLE_OBLIQUE?
- style |= gfx::Font::ITALIC;
- }
- if (style != 0)
- style_ = style;
+ &query.families);
+
+ const int pango_size =
+ pango_font_description_get_size(native_font) / PANGO_SCALE;
+ if (pango_font_description_get_size_is_absolute(native_font))
+ query.pixel_size = pango_size;
+ else
+ query.point_size = pango_size;
+
+ query.style = gfx::Font::NORMAL;
+ // TODO(davemoore): Support weights other than bold?
+ if (pango_font_description_get_weight(native_font) == PANGO_WEIGHT_BOLD)
+ query.style |= gfx::Font::BOLD;
+ // TODO(davemoore): What about PANGO_STYLE_OBLIQUE?
+ if (pango_font_description_get_style(native_font) == PANGO_STYLE_ITALIC)
+ query.style |= gfx::Font::ITALIC;
+
+ std::string font_family;
+ const FontRenderParams params = gfx::GetFontRenderParams(query, &font_family);
+ InitFromDetails(skia::RefPtr<SkTypeface>(), font_family,
+ gfx::GetPangoFontSizeInPixels(native_font),
+ query.style, params);
}
PlatformFontPango::PlatformFontPango(const std::string& font_name,
- int font_size) {
- InitWithNameAndSize(font_name, font_size);
+ int font_size_pixels) {
+ FontRenderParamsQuery query(false);
+ query.families.push_back(font_name);
+ query.pixel_size = font_size_pixels;
+ query.style = gfx::Font::NORMAL;
+ InitFromDetails(skia::RefPtr<SkTypeface>(), font_name, font_size_pixels,
+ query.style, gfx::GetFontRenderParams(query, NULL));
}
double PlatformFontPango::underline_position() const {
#endif
Font PlatformFontPango::DeriveFont(int size_delta, int style) const {
- // If the delta is negative, if must not push the size below 1
- if (size_delta < 0)
- DCHECK_LT(-size_delta, font_size_pixels_);
-
- if (style == style_) {
- // Fast path, we just use the same typeface at a different size
- return Font(new PlatformFontPango(typeface_,
- font_family_,
- font_size_pixels_ + size_delta,
- style_));
- }
+ const int new_size = font_size_pixels_ + size_delta;
+ DCHECK_GT(new_size, 0);
- // If the style has changed we may need to load a new face
- int skstyle = SkTypeface::kNormal;
- if (gfx::Font::BOLD & style)
- skstyle |= SkTypeface::kBold;
- if (gfx::Font::ITALIC & style)
- skstyle |= SkTypeface::kItalic;
+ // If the style changed, we may need to load a new face.
+ std::string new_family = font_family_;
+ skia::RefPtr<SkTypeface> typeface =
+ (style == style_) ? typeface_ : CreateSkTypeface(style, &new_family);
- skia::RefPtr<SkTypeface> typeface = skia::AdoptRef(
- SkTypeface::CreateFromName(
- font_family_.c_str(),
- static_cast<SkTypeface::Style>(skstyle)));
+ FontRenderParamsQuery query(false);
+ query.families.push_back(new_family);
+ query.pixel_size = new_size;
+ query.style = style;
- return Font(new PlatformFontPango(typeface,
- font_family_,
- font_size_pixels_ + size_delta,
- style));
+ return Font(new PlatformFontPango(typeface, new_family, new_size, style,
+ gfx::GetFontRenderParams(query, NULL)));
}
int PlatformFontPango::GetHeight() const {
return font_size_pixels_;
}
+const FontRenderParams& PlatformFontPango::GetFontRenderParams() const {
+ return font_render_params_;
+}
+
NativeFont PlatformFontPango::GetNativeFont() const {
PangoFontDescription* pfd = pango_font_description_new();
pango_font_description_set_family(pfd, GetFontName().c_str());
PlatformFontPango::PlatformFontPango(const skia::RefPtr<SkTypeface>& typeface,
const std::string& name,
- int size,
- int style) {
- InitWithTypefaceNameSizeAndStyle(typeface, name, size, style);
+ int size_pixels,
+ int style,
+ const FontRenderParams& render_params) {
+ InitFromDetails(typeface, name, size_pixels, style, render_params);
}
PlatformFontPango::~PlatformFontPango() {}
-// static
-std::string PlatformFontPango::GetDefaultFont() {
-#if defined(OS_CHROMEOS)
- // Font name must have been provided by way of SetDefaultFontDescription().
- CHECK(default_font_description_);
- return *default_font_description_;
-#else
- const gfx::LinuxFontDelegate* delegate = gfx::LinuxFontDelegate::instance();
- if (delegate)
- return delegate->GetDefaultFontName();
-
- return "sans 10";
-#endif // defined(OS_CHROMEOS)
-}
-
-void PlatformFontPango::InitWithNameAndSize(const std::string& font_name,
- int font_size) {
- DCHECK_GT(font_size, 0);
- std::string fallback;
-
- skia::RefPtr<SkTypeface> typeface = skia::AdoptRef(
- SkTypeface::CreateFromName(font_name.c_str(), SkTypeface::kNormal));
- if (!typeface) {
- // A non-scalable font such as .pcf is specified. Falls back to a default
- // scalable font.
- typeface = skia::AdoptRef(
- SkTypeface::CreateFromName(
- kFallbackFontFamilyName, SkTypeface::kNormal));
- CHECK(typeface) << "Could not find any font: "
- << font_name
- << ", " << kFallbackFontFamilyName;
- fallback = kFallbackFontFamilyName;
- }
-
- InitWithTypefaceNameSizeAndStyle(typeface,
- fallback.empty() ? font_name : fallback,
- font_size,
- gfx::Font::NORMAL);
-}
-
-void PlatformFontPango::InitWithTypefaceNameSizeAndStyle(
+void PlatformFontPango::InitFromDetails(
const skia::RefPtr<SkTypeface>& typeface,
const std::string& font_family,
- int font_size,
- int style) {
- typeface_ = typeface;
+ int font_size_pixels,
+ int style,
+ const FontRenderParams& render_params) {
+ DCHECK_GT(font_size_pixels, 0);
+
font_family_ = font_family;
- font_size_pixels_ = font_size;
+ typeface_ = typeface ? typeface : CreateSkTypeface(style, &font_family_);
+
+ font_size_pixels_ = font_size_pixels;
style_ = style;
- pango_metrics_inited_ = false;
- average_width_pixels_ = 0.0f;
- underline_position_pixels_ = 0.0f;
- underline_thickness_pixels_ = 0.0f;
+ font_render_params_ = render_params;
SkPaint paint;
SkPaint::FontMetrics metrics;
PaintSetup(&paint);
paint.getFontMetrics(&metrics);
-
ascent_pixels_ = SkScalarCeilToInt(-metrics.fAscent);
height_pixels_ = ascent_pixels_ + SkScalarCeilToInt(metrics.fDescent);
cap_height_pixels_ = SkScalarCeilToInt(metrics.fCapHeight);
+
+ pango_metrics_inited_ = false;
+ average_width_pixels_ = 0.0f;
+ underline_position_pixels_ = 0.0f;
+ underline_thickness_pixels_ = 0.0f;
}
void PlatformFontPango::InitFromPlatformFont(const PlatformFontPango* other) {
font_family_ = other->font_family_;
font_size_pixels_ = other->font_size_pixels_;
style_ = other->style_;
- height_pixels_ = other->height_pixels_;
+ font_render_params_ = other->font_render_params_;
ascent_pixels_ = other->ascent_pixels_;
+ height_pixels_ = other->height_pixels_;
cap_height_pixels_ = other->cap_height_pixels_;
pango_metrics_inited_ = other->pango_metrics_inited_;
average_width_pixels_ = other->average_width_pixels_;