Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Unified Diff: gfx/platform_font_gtk.cc

Issue 6246027: Move src/gfx/ to src/ui/gfx... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gfx/platform_font_gtk.h ('k') | gfx/platform_font_mac.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gfx/platform_font_gtk.cc
===================================================================
--- gfx/platform_font_gtk.cc (revision 73487)
+++ gfx/platform_font_gtk.cc (working copy)
@@ -1,450 +0,0 @@
-// Copyright (c) 2010 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 "gfx/platform_font_gtk.h"
-
-#include <algorithm>
-#include <fontconfig/fontconfig.h>
-#include <gdk/gdk.h>
-#include <gtk/gtk.h>
-#include <map>
-#include <pango/pango.h>
-
-#include "base/logging.h"
-#include "base/string_piece.h"
-#include "base/utf_string_conversions.h"
-#include "gfx/canvas_skia.h"
-#include "gfx/font.h"
-#include "gfx/gtk_util.h"
-#include "third_party/skia/include/core/SkTypeface.h"
-#include "third_party/skia/include/core/SkPaint.h"
-
-namespace {
-
-// The font family name which is used when a user's application font for
-// GNOME/KDE is a non-scalable one. The name should be listed in the
-// IsFallbackFontAllowed function in skia/ext/SkFontHost_fontconfig_direct.cpp.
-const char* kFallbackFontFamilyName = "sans";
-
-// Returns the number of pixels in a point.
-// - multiply a point size by this to get pixels ("device units")
-// - divide a pixel size by this to get points
-float GetPixelsInPoint() {
- static float pixels_in_point = 1.0;
- static bool determined_value = false;
-
- if (!determined_value) {
- // http://goo.gl/UIh5m: "This is a scale factor between points specified in
- // a PangoFontDescription and Cairo units. The default value is 96, meaning
- // that a 10 point font will be 13 units high. (10 * 96. / 72. = 13.3)."
- double pango_dpi = gfx::GetPangoResolution();
- if (pango_dpi <= 0)
- pango_dpi = 96.0;
- pixels_in_point = pango_dpi / 72.0; // 72 points in an inch
- determined_value = true;
- }
-
- return pixels_in_point;
-}
-
-// Retrieves the pango metrics for a pango font description. Caches the metrics
-// and never frees them. The metrics objects are relatively small and
-// very expensive to look up.
-PangoFontMetrics* GetPangoFontMetrics(PangoFontDescription* desc) {
- static std::map<int, PangoFontMetrics*>* desc_to_metrics = NULL;
- static PangoContext* context = NULL;
-
- if (!context) {
- context = gdk_pango_context_get_for_screen(gdk_screen_get_default());
- pango_context_set_language(context, pango_language_get_default());
- }
-
- if (!desc_to_metrics) {
- desc_to_metrics = new std::map<int, PangoFontMetrics*>();
- }
-
- int desc_hash = pango_font_description_hash(desc);
- std::map<int, PangoFontMetrics*>::iterator i =
- desc_to_metrics->find(desc_hash);
-
- if (i == desc_to_metrics->end()) {
- PangoFontMetrics* metrics = pango_context_get_metrics(context, desc, NULL);
- (*desc_to_metrics)[desc_hash] = metrics;
- return metrics;
- } else {
- return i->second;
- }
-}
-
-// 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.
-string16 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);
-
- string16 font_family = UTF8ToUTF16(reinterpret_cast<char*>(match_family));
- FcPatternDestroy(match);
- FcPatternDestroy(pattern);
- free(family_name_copy);
- return font_family;
-}
-
-} // namespace
-
-namespace gfx {
-
-Font* PlatformFontGtk::default_font_ = NULL;
-
-////////////////////////////////////////////////////////////////////////////////
-// PlatformFontGtk, public:
-
-PlatformFontGtk::PlatformFontGtk() {
- if (default_font_ == NULL) {
- GtkSettings* settings = gtk_settings_get_default();
-
- gchar* font_name = NULL;
- g_object_get(settings, "gtk-font-name", &font_name, NULL);
-
- // Temporary CHECK for helping track down
- // http://code.google.com/p/chromium/issues/detail?id=12530
- CHECK(font_name) << " Unable to get gtk-font-name for default font.";
-
- PangoFontDescription* desc =
- pango_font_description_from_string(font_name);
- default_font_ = new Font(desc);
- pango_font_description_free(desc);
- g_free(font_name);
-
- DCHECK(default_font_);
- }
-
- InitFromPlatformFont(
- static_cast<PlatformFontGtk*>(default_font_->platform_font()));
-}
-
-PlatformFontGtk::PlatformFontGtk(const Font& other) {
- InitFromPlatformFont(
- static_cast<PlatformFontGtk*>(other.platform_font()));
-}
-
-PlatformFontGtk::PlatformFontGtk(NativeFont native_font) {
- const char* family_name = pango_font_description_get_family(native_font);
-
- gint size_in_pixels = 0;
- if (pango_font_description_get_size_is_absolute(native_font)) {
- // If the size is absolute, then it's in Pango units rather than points.
- // There are PANGO_SCALE Pango units in a device unit (pixel).
- size_in_pixels = pango_font_description_get_size(native_font) / PANGO_SCALE;
- } else {
- // Otherwise, we need to convert from points.
- size_in_pixels =
- pango_font_description_get_size(native_font) * GetPixelsInPoint() /
- PANGO_SCALE;
- }
-
- // Find best match font for |family_name| to make sure we can get
- // a SkTypeface for the default font.
- // TODO(agl): remove this.
- string16 font_family = FindBestMatchFontFamilyName(family_name);
-
- InitWithNameAndSize(font_family, size_in_pixels);
- 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;
-}
-
-PlatformFontGtk::PlatformFontGtk(const string16& font_name,
- int font_size) {
- InitWithNameAndSize(font_name, font_size);
-}
-
-double PlatformFontGtk::underline_position() const {
- const_cast<PlatformFontGtk*>(this)->InitPangoMetrics();
- return underline_position_pixels_;
-}
-
-double PlatformFontGtk::underline_thickness() const {
- const_cast<PlatformFontGtk*>(this)->InitPangoMetrics();
- return underline_thickness_pixels_;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// PlatformFontGtk, PlatformFont implementation:
-
-Font PlatformFontGtk::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 PlatformFontGtk(typeface_,
- font_family_,
- font_size_pixels_ + size_delta,
- style_));
- }
-
- // 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;
-
- SkTypeface* typeface = SkTypeface::CreateFromName(
- UTF16ToUTF8(font_family_).c_str(),
- static_cast<SkTypeface::Style>(skstyle));
- SkAutoUnref tf_helper(typeface);
-
- return Font(new PlatformFontGtk(typeface,
- font_family_,
- font_size_pixels_ + size_delta,
- style));
-}
-
-int PlatformFontGtk::GetHeight() const {
- return height_pixels_;
-}
-
-int PlatformFontGtk::GetBaseline() const {
- return ascent_pixels_;
-}
-
-int PlatformFontGtk::GetAverageCharacterWidth() const {
- return SkScalarRound(average_width_pixels_);
-}
-
-int PlatformFontGtk::GetStringWidth(const string16& text) const {
- int width = 0, height = 0;
- CanvasSkia::SizeStringInt(text, Font(const_cast<PlatformFontGtk*>(this)),
- &width, &height, gfx::Canvas::NO_ELLIPSIS);
- return width;
-}
-
-int PlatformFontGtk::GetExpectedTextWidth(int length) const {
- double char_width = const_cast<PlatformFontGtk*>(this)->GetAverageWidth();
- return round(static_cast<float>(length) * char_width);
-}
-
-int PlatformFontGtk::GetStyle() const {
- return style_;
-}
-
-string16 PlatformFontGtk::GetFontName() const {
- return font_family_;
-}
-
-int PlatformFontGtk::GetFontSize() const {
- return font_size_pixels_;
-}
-
-NativeFont PlatformFontGtk::GetNativeFont() const {
- PangoFontDescription* pfd = pango_font_description_new();
- pango_font_description_set_family(pfd, UTF16ToUTF8(GetFontName()).c_str());
- // Set the absolute size to avoid overflowing UI elements.
- // pango_font_description_set_absolute_size() takes a size in Pango units.
- // There are PANGO_SCALE Pango units in one device unit. Screen output
- // devices use pixels as their device units.
- pango_font_description_set_absolute_size(
- pfd, font_size_pixels_ * PANGO_SCALE);
-
- switch (GetStyle()) {
- case gfx::Font::NORMAL:
- // Nothing to do, should already be PANGO_STYLE_NORMAL.
- break;
- case gfx::Font::BOLD:
- pango_font_description_set_weight(pfd, PANGO_WEIGHT_BOLD);
- break;
- case gfx::Font::ITALIC:
- pango_font_description_set_style(pfd, PANGO_STYLE_ITALIC);
- break;
- case gfx::Font::UNDERLINED:
- // TODO(deanm): How to do underlined? Where do we use it? Probably have
- // to paint it ourselves, see pango_font_metrics_get_underline_position.
- break;
- }
-
- return pfd;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// PlatformFontGtk, private:
-
-PlatformFontGtk::PlatformFontGtk(SkTypeface* typeface,
- const string16& name,
- int size,
- int style) {
- InitWithTypefaceNameSizeAndStyle(typeface, name, size, style);
-}
-
-PlatformFontGtk::~PlatformFontGtk() {}
-
-void PlatformFontGtk::InitWithNameAndSize(const string16& font_name,
- int font_size) {
- DCHECK_GT(font_size, 0);
- string16 fallback;
-
- SkTypeface* typeface = SkTypeface::CreateFromName(
- UTF16ToUTF8(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 = SkTypeface::CreateFromName(
- kFallbackFontFamilyName, SkTypeface::kNormal);
- CHECK(typeface) << "Could not find any font: "
- << UTF16ToUTF8(font_name)
- << ", " << kFallbackFontFamilyName;
- fallback = UTF8ToUTF16(kFallbackFontFamilyName);
- }
- SkAutoUnref typeface_helper(typeface);
-
- InitWithTypefaceNameSizeAndStyle(typeface,
- fallback.empty() ? font_name : fallback,
- font_size,
- gfx::Font::NORMAL);
-}
-
-void PlatformFontGtk::InitWithTypefaceNameSizeAndStyle(
- SkTypeface* typeface,
- const string16& font_family,
- int font_size,
- int style) {
- typeface_helper_.reset(new SkAutoUnref(typeface));
- typeface_ = typeface;
- typeface_->ref();
- font_family_ = font_family;
- font_size_pixels_ = font_size;
- style_ = style;
- pango_metrics_inited_ = false;
- average_width_pixels_ = 0.0f;
- underline_position_pixels_ = 0.0f;
- underline_thickness_pixels_ = 0.0f;
-
- SkPaint paint;
- SkPaint::FontMetrics metrics;
- PaintSetup(&paint);
- paint.getFontMetrics(&metrics);
-
- ascent_pixels_ = SkScalarCeil(-metrics.fAscent);
- height_pixels_ = ascent_pixels_ + SkScalarCeil(metrics.fDescent);
-}
-
-void PlatformFontGtk::InitFromPlatformFont(const PlatformFontGtk* other) {
- typeface_helper_.reset(new SkAutoUnref(other->typeface_));
- typeface_ = other->typeface_;
- typeface_->ref();
- font_family_ = other->font_family_;
- font_size_pixels_ = other->font_size_pixels_;
- style_ = other->style_;
- height_pixels_ = other->height_pixels_;
- ascent_pixels_ = other->ascent_pixels_;
- pango_metrics_inited_ = other->pango_metrics_inited_;
- average_width_pixels_ = other->average_width_pixels_;
- underline_position_pixels_ = other->underline_position_pixels_;
- underline_thickness_pixels_ = other->underline_thickness_pixels_;
-}
-
-void PlatformFontGtk::PaintSetup(SkPaint* paint) const {
- paint->setAntiAlias(false);
- paint->setSubpixelText(false);
- paint->setTextSize(font_size_pixels_);
- paint->setTypeface(typeface_);
- paint->setFakeBoldText((gfx::Font::BOLD & style_) && !typeface_->isBold());
- paint->setTextSkewX((gfx::Font::ITALIC & style_) && !typeface_->isItalic() ?
- -SK_Scalar1/4 : 0);
-}
-
-void PlatformFontGtk::InitPangoMetrics() {
- if (!pango_metrics_inited_) {
- pango_metrics_inited_ = true;
- PangoFontDescription* pango_desc = GetNativeFont();
- PangoFontMetrics* pango_metrics = GetPangoFontMetrics(pango_desc);
-
- underline_position_pixels_ =
- pango_font_metrics_get_underline_position(pango_metrics) /
- PANGO_SCALE;
-
- // TODO(davemoore): Come up with a better solution.
- // This is a hack, but without doing this the underlines
- // we get end up fuzzy. So we align to the midpoint of a pixel.
- underline_position_pixels_ /= 2;
-
- underline_thickness_pixels_ =
- pango_font_metrics_get_underline_thickness(pango_metrics) /
- PANGO_SCALE;
-
- // First get the Pango-based width (converting from Pango units to pixels).
- double pango_width_pixels =
- pango_font_metrics_get_approximate_char_width(pango_metrics) /
- PANGO_SCALE;
-
- // Yes, this is how Microsoft recommends calculating the dialog unit
- // conversions.
- int text_width_pixels = GetStringWidth(
- ASCIIToUTF16("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));
- double dialog_units_pixels = (text_width_pixels / 26 + 1) / 2;
- average_width_pixels_ = std::min(pango_width_pixels, dialog_units_pixels);
- pango_font_description_free(pango_desc);
- }
-}
-
-
-double PlatformFontGtk::GetAverageWidth() const {
- const_cast<PlatformFontGtk*>(this)->InitPangoMetrics();
- return average_width_pixels_;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// PlatformFont, public:
-
-// static
-PlatformFont* PlatformFont::CreateDefault() {
- return new PlatformFontGtk;
-}
-
-// static
-PlatformFont* PlatformFont::CreateFromFont(const Font& other) {
- return new PlatformFontGtk(other);
-}
-
-// static
-PlatformFont* PlatformFont::CreateFromNativeFont(NativeFont native_font) {
- return new PlatformFontGtk(native_font);
-}
-
-// static
-PlatformFont* PlatformFont::CreateFromNameAndSize(const string16& font_name,
- int font_size) {
- return new PlatformFontGtk(font_name, font_size);
-}
-
-} // namespace gfx
« no previous file with comments | « gfx/platform_font_gtk.h ('k') | gfx/platform_font_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698