15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/platform_font_pango.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <pango/pango.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkPaint.h"
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "third_party/skia/include/core/SkString.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkTypeface.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/font.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/font_list.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/linux_font_delegate.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/pango_util.h"
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/text_utils.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The font family name which is used when a user's application font for
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GNOME/KDE is a non-scalable one. The name should be listed in the
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IsFallbackFontAllowed function in skia/ext/SkFontHost_fontconfig_direct.cpp.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kFallbackFontFamilyName = "sans";
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Creates a SkTypeface for the passed-in Font::FontStyle and family. If a
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// fallback typeface is used instead of the requested family, |family| will be
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// updated to contain the fallback's family name.
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)skia::RefPtr<SkTypeface> CreateSkTypeface(int style, std::string* family) {
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(family);
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int skia_style = SkTypeface::kNormal;
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (gfx::Font::BOLD & style)
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    skia_style |= SkTypeface::kBold;
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (gfx::Font::ITALIC & style)
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    skia_style |= SkTypeface::kItalic;
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  skia::RefPtr<SkTypeface> typeface = skia::AdoptRef(SkTypeface::CreateFromName(
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      family->c_str(), static_cast<SkTypeface::Style>(skia_style)));
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!typeface) {
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // A non-scalable font such as .pcf is specified. Fall back to a default
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // scalable font.
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    typeface = skia::AdoptRef(SkTypeface::CreateFromName(
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        kFallbackFontFamilyName, static_cast<SkTypeface::Style>(skia_style)));
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    CHECK(typeface) << "Could not find any font: " << family << ", "
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    << kFallbackFontFamilyName;
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *family = kFallbackFontFamilyName;
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return typeface;
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// static
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Font* PlatformFontPango::default_font_ = NULL;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(OS_CHROMEOS)
67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// static
68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)std::string* PlatformFontPango::default_font_description_ = NULL;
69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif
70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PlatformFontPango, public:
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PlatformFontPango::PlatformFontPango() {
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!default_font_) {
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_ptr<ScopedPangoFontDescription> description;
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(OS_CHROMEOS)
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CHECK(default_font_description_);
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    description.reset(
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        new ScopedPangoFontDescription(*default_font_description_));
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#else
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const gfx::LinuxFontDelegate* delegate = gfx::LinuxFontDelegate::instance();
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (delegate)
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      description = delegate->GetDefaultPangoFontDescription();
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!description || !description->get())
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      description.reset(new ScopedPangoFontDescription("sans 10"));
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    default_font_ = new Font(description->get());
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitFromPlatformFont(
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<PlatformFontPango*>(default_font_->platform_font()));
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PlatformFontPango::PlatformFontPango(NativeFont native_font) {
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FontRenderParamsQuery query(false);
975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::SplitString(pango_font_description_get_family(native_font), ',',
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    &query.families);
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const int pango_size =
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      pango_font_description_get_size(native_font) / PANGO_SCALE;
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (pango_font_description_get_size_is_absolute(native_font))
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    query.pixel_size = pango_size;
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  else
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    query.point_size = pango_size;
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  query.style = gfx::Font::NORMAL;
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // TODO(davemoore): Support weights other than bold?
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (pango_font_description_get_weight(native_font) == PANGO_WEIGHT_BOLD)
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    query.style |= gfx::Font::BOLD;
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // TODO(davemoore): What about PANGO_STYLE_OBLIQUE?
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (pango_font_description_get_style(native_font) == PANGO_STYLE_ITALIC)
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    query.style |= gfx::Font::ITALIC;
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string font_family;
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const FontRenderParams params = gfx::GetFontRenderParams(query, &font_family);
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  InitFromDetails(skia::RefPtr<SkTypeface>(), font_family,
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                  gfx::GetPangoFontSizeInPixels(native_font),
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                  query.style, params);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PlatformFontPango::PlatformFontPango(const std::string& font_name,
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                     int font_size_pixels) {
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FontRenderParamsQuery query(false);
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  query.families.push_back(font_name);
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  query.pixel_size = font_size_pixels;
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  query.style = gfx::Font::NORMAL;
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  InitFromDetails(skia::RefPtr<SkTypeface>(), font_name, font_size_pixels,
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                  query.style, gfx::GetFontRenderParams(query, NULL));
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PlatformFontPango, PlatformFont implementation:
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PlatformFontPango::ReloadDefaultFont() {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete default_font_;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  default_font_ = NULL;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
141d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(OS_CHROMEOS)
142d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// static
143d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void PlatformFontPango::SetDefaultFontDescription(
144d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const std::string& font_description) {
145d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  delete default_font_description_;
146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  default_font_description_ = new std::string(font_description);
147d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
148d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
149d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif
150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Font PlatformFontPango::DeriveFont(int size_delta, int style) const {
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const int new_size = font_size_pixels_ + size_delta;
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_GT(new_size, 0);
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // If the style changed, we may need to load a new face.
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string new_family = font_family_;
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  skia::RefPtr<SkTypeface> typeface =
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      (style == style_) ? typeface_ : CreateSkTypeface(style, &new_family);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FontRenderParamsQuery query(false);
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  query.families.push_back(new_family);
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  query.pixel_size = new_size;
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  query.style = style;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return Font(new PlatformFontPango(typeface, new_family, new_size, style,
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    gfx::GetFontRenderParams(query, NULL)));
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int PlatformFontPango::GetHeight() const {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return height_pixels_;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int PlatformFontPango::GetBaseline() const {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ascent_pixels_;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int PlatformFontPango::GetCapHeight() const {
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return cap_height_pixels_;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int PlatformFontPango::GetExpectedTextWidth(int length) const {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  double char_width = const_cast<PlatformFontPango*>(this)->GetAverageWidth();
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return round(static_cast<float>(length) * char_width);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int PlatformFontPango::GetStyle() const {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return style_;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string PlatformFontPango::GetFontName() const {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return font_family_;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)std::string PlatformFontPango::GetActualFontNameForTesting() const {
195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SkString family_name;
196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  typeface_->getFamilyName(&family_name);
197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return family_name.c_str();
198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int PlatformFontPango::GetFontSize() const {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return font_size_pixels_;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
204116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst FontRenderParams& PlatformFontPango::GetFontRenderParams() const {
205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return font_render_params_;
206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeFont PlatformFontPango::GetNativeFont() const {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PangoFontDescription* pfd = pango_font_description_new();
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pango_font_description_set_family(pfd, GetFontName().c_str());
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the absolute size to avoid overflowing UI elements.
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // pango_font_description_set_absolute_size() takes a size in Pango units.
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There are PANGO_SCALE Pango units in one device unit.  Screen output
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // devices use pixels as their device units.
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pango_font_description_set_absolute_size(
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pfd, font_size_pixels_ * PANGO_SCALE);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (GetStyle()) {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case gfx::Font::NORMAL:
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Nothing to do, should already be PANGO_STYLE_NORMAL.
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case gfx::Font::BOLD:
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pango_font_description_set_weight(pfd, PANGO_WEIGHT_BOLD);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case gfx::Font::ITALIC:
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pango_font_description_set_style(pfd, PANGO_STYLE_ITALIC);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case gfx::Font::UNDERLINE:
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // TODO(deanm): How to do underline?  Where do we use it?  Probably have
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // to paint it ourselves, see pango_font_metrics_get_underline_position.
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pfd;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PlatformFontPango, private:
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PlatformFontPango::PlatformFontPango(const skia::RefPtr<SkTypeface>& typeface,
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const std::string& name,
242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                     int size_pixels,
243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                     int style,
244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                     const FontRenderParams& render_params) {
245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  InitFromDetails(typeface, name, size_pixels, style, render_params);
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PlatformFontPango::~PlatformFontPango() {}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
250116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid PlatformFontPango::InitFromDetails(
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const skia::RefPtr<SkTypeface>& typeface,
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& font_family,
253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int font_size_pixels,
254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int style,
255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const FontRenderParams& render_params) {
256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_GT(font_size_pixels, 0);
257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  font_family_ = font_family;
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  typeface_ = typeface ? typeface : CreateSkTypeface(style, &font_family_);
260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  font_size_pixels_ = font_size_pixels;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  style_ = style;
263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  font_render_params_ = render_params;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint::FontMetrics metrics;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PaintSetup(&paint);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.getFontMetrics(&metrics);
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ascent_pixels_ = SkScalarCeilToInt(-metrics.fAscent);
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  height_pixels_ = ascent_pixels_ + SkScalarCeilToInt(metrics.fDescent);
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cap_height_pixels_ = SkScalarCeilToInt(metrics.fCapHeight);
272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  pango_metrics_inited_ = false;
274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  average_width_pixels_ = 0.0f;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PlatformFontPango::InitFromPlatformFont(const PlatformFontPango* other) {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typeface_ = other->typeface_;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  font_family_ = other->font_family_;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  font_size_pixels_ = other->font_size_pixels_;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  style_ = other->style_;
282116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  font_render_params_ = other->font_render_params_;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ascent_pixels_ = other->ascent_pixels_;
284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  height_pixels_ = other->height_pixels_;
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cap_height_pixels_ = other->cap_height_pixels_;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pango_metrics_inited_ = other->pango_metrics_inited_;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  average_width_pixels_ = other->average_width_pixels_;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PlatformFontPango::PaintSetup(SkPaint* paint) const {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint->setAntiAlias(false);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint->setSubpixelText(false);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint->setTextSize(font_size_pixels_);
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  paint->setTypeface(typeface_.get());
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint->setFakeBoldText((gfx::Font::BOLD & style_) && !typeface_->isBold());
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint->setTextSkewX((gfx::Font::ITALIC & style_) && !typeface_->isItalic() ?
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      -SK_Scalar1/4 : 0);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PlatformFontPango::InitPangoMetrics() {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!pango_metrics_inited_) {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pango_metrics_inited_ = true;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedPangoFontDescription pango_desc(GetNativeFont());
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PangoFontMetrics* pango_metrics = GetPangoFontMetrics(pango_desc.get());
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First get the Pango-based width (converting from Pango units to pixels).
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const double pango_width_pixels =
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pango_font_metrics_get_approximate_char_width(pango_metrics) /
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PANGO_SCALE;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Yes, this is how Microsoft recommends calculating the dialog unit
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // conversions.
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int text_width_pixels = GetStringWidth(
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::ASCIIToUTF16(
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"),
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FontList(Font(this)));
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const double dialog_units_pixels = (text_width_pixels / 26 + 1) / 2;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    average_width_pixels_ = std::min(pango_width_pixels, dialog_units_pixels);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)double PlatformFontPango::GetAverageWidth() const {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const_cast<PlatformFontPango*>(this)->InitPangoMetrics();
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return average_width_pixels_;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PlatformFont, public:
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PlatformFont* PlatformFont::CreateDefault() {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new PlatformFontPango;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PlatformFont* PlatformFont::CreateFromNativeFont(NativeFont native_font) {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new PlatformFontPango(native_font);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name,
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  int font_size) {
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new PlatformFontPango(font_name, font_size);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gfx
347