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