Index: app/gfx/font_skia.cc |
=================================================================== |
--- app/gfx/font_skia.cc (revision 42303) |
+++ app/gfx/font_skia.cc (working copy) |
@@ -1,277 +0,0 @@ |
-// Copyright (c) 2006-2008 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 "app/gfx/font.h" |
- |
-#include <gdk/gdk.h> |
-#include <map> |
-#include <pango/pango.h> |
- |
-#include "app/gfx/canvas.h" |
-#include "base/logging.h" |
-#include "base/string_piece.h" |
-#include "base/sys_string_conversions.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"; |
- |
-// Pango scales font sizes. This returns the scale factor. See |
-// pango_cairo_context_set_resolution for details. |
-// NOTE: this isn't entirely accurate, in that Pango also consults the |
-// FC_PIXEL_SIZE first (see get_font_size in pangocairo-fcfont), but this |
-// seems to give us the same sizes as used by Pango for all our fonts in both |
-// English and Thia. |
-static double GetPangoScaleFactor() { |
- static float scale_factor = 0; |
- static bool determined_scale = false; |
- if (!determined_scale) { |
- PangoContext* context = gdk_pango_context_get(); |
- scale_factor = pango_cairo_context_get_resolution(context); |
- g_object_unref(context); |
- if (scale_factor <= 0) |
- scale_factor = 1; |
- else |
- scale_factor /= 72.0; |
- determined_scale = true; |
- } |
- return scale_factor; |
-} |
- |
-// 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. |
-static 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; |
- } |
-} |
- |
-} // namespace |
- |
-namespace gfx { |
- |
-Font::Font(const Font& other) { |
- CopyFont(other); |
-} |
- |
-Font& Font::operator=(const Font& other) { |
- CopyFont(other); |
- return *this; |
-} |
- |
-Font::Font(SkTypeface* tf, const std::wstring& font_family, int font_size, |
- int style) |
- : typeface_helper_(new SkAutoUnref(tf)), |
- typeface_(tf), |
- font_family_(font_family), |
- font_size_(font_size), |
- style_(style), |
- pango_metrics_inited_(false), |
- avg_width_(0.0), |
- underline_position_(0.0), |
- underline_thickness_(0.0) { |
- tf->ref(); |
- calculateMetrics(); |
-} |
- |
-void Font::calculateMetrics() { |
- SkPaint paint; |
- SkPaint::FontMetrics metrics; |
- PaintSetup(&paint); |
- paint.getFontMetrics(&metrics); |
- |
- ascent_ = SkScalarCeil(-metrics.fAscent); |
- height_ = ascent_ + SkScalarCeil(metrics.fDescent); |
- |
-} |
- |
-void Font::CopyFont(const Font& other) { |
- typeface_helper_.reset(new SkAutoUnref(other.typeface_)); |
- typeface_ = other.typeface_; |
- typeface_->ref(); |
- font_family_ = other.font_family_; |
- font_size_ = other.font_size_; |
- style_ = other.style_; |
- height_ = other.height_; |
- ascent_ = other.ascent_; |
- pango_metrics_inited_ = other.pango_metrics_inited_; |
- avg_width_ = other.avg_width_; |
- underline_position_ = other.underline_position_; |
- underline_thickness_ = other.underline_thickness_; |
-} |
- |
-int Font::height() const { |
- return height_; |
-} |
- |
-int Font::baseline() const { |
- return ascent_; |
-} |
- |
-int Font::ave_char_width() const { |
- return SkScalarRound(avg_width()); |
-} |
- |
-Font Font::CreateFont(const std::wstring& font_family, int font_size) { |
- DCHECK_GT(font_size, 0); |
- std::wstring fallback; |
- |
- SkTypeface* tf = SkTypeface::CreateFromName( |
- base::SysWideToUTF8(font_family).c_str(), SkTypeface::kNormal); |
- if (!tf) { |
- // A non-scalable font such as .pcf is specified. Falls back to a default |
- // scalable font. |
- tf = SkTypeface::CreateFromName( |
- kFallbackFontFamilyName, SkTypeface::kNormal); |
- CHECK(tf) << "Could not find any font: " |
- << base::SysWideToUTF8(font_family) |
- << ", " << kFallbackFontFamilyName; |
- fallback = base::SysUTF8ToWide(kFallbackFontFamilyName); |
- } |
- SkAutoUnref tf_helper(tf); |
- |
- return Font( |
- tf, fallback.empty() ? font_family : fallback, font_size, NORMAL); |
-} |
- |
-Font Font::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_); |
- } |
- |
- if (style == style_) { |
- // Fast path, we just use the same typeface at a different size |
- return Font(typeface_, font_family_, font_size_ + size_delta, style_); |
- } |
- |
- // If the style has changed we may need to load a new face |
- int skstyle = SkTypeface::kNormal; |
- if (BOLD & style) |
- skstyle |= SkTypeface::kBold; |
- if (ITALIC & style) |
- skstyle |= SkTypeface::kItalic; |
- |
- SkTypeface* tf = SkTypeface::CreateFromName( |
- base::SysWideToUTF8(font_family_).c_str(), |
- static_cast<SkTypeface::Style>(skstyle)); |
- SkAutoUnref tf_helper(tf); |
- |
- return Font(tf, font_family_, font_size_ + size_delta, style); |
-} |
- |
-void Font::PaintSetup(SkPaint* paint) const { |
- paint->setAntiAlias(false); |
- paint->setSubpixelText(false); |
- paint->setTextSize(SkFloatToScalar(font_size_ * GetPangoScaleFactor())); |
- paint->setTypeface(typeface_); |
- paint->setFakeBoldText((BOLD & style_) && !typeface_->isBold()); |
- paint->setTextSkewX((ITALIC & style_) && !typeface_->isItalic() ? |
- -SK_Scalar1/4 : 0); |
-} |
- |
-int Font::GetStringWidth(const std::wstring& text) const { |
- int width = 0, height = 0; |
- |
- Canvas::SizeStringInt(text, *this, &width, &height, 0); |
- return width; |
-} |
- |
-void Font::InitPangoMetrics() { |
- if (!pango_metrics_inited_) { |
- pango_metrics_inited_ = true; |
- PangoFontDescription* pango_desc = PangoFontFromGfxFont(*this); |
- PangoFontMetrics* pango_metrics = GetPangoFontMetrics(pango_desc); |
- |
- underline_position_ = |
- pango_font_metrics_get_underline_position(pango_metrics); |
- underline_position_ /= 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_ /= 2; |
- |
- underline_thickness_ = |
- pango_font_metrics_get_underline_thickness(pango_metrics); |
- underline_thickness_ /= PANGO_SCALE; |
- |
- // First get the pango based width |
- double pango_width = |
- pango_font_metrics_get_approximate_char_width(pango_metrics); |
- pango_width /= PANGO_SCALE; |
- |
- // Yes, this is how Microsoft recommends calculating the dialog unit |
- // conversions. |
- int text_width = GetStringWidth( |
- L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); |
- double dialog_units = (text_width / 26 + 1) / 2; |
- avg_width_ = std::min(pango_width, dialog_units); |
- pango_font_description_free(pango_desc); |
- } |
-} |
- |
-double Font::avg_width() const { |
- const_cast<Font*>(this)->InitPangoMetrics(); |
- return avg_width_; |
-} |
- |
-double Font::underline_position() const { |
- const_cast<Font*>(this)->InitPangoMetrics(); |
- return underline_position_; |
-} |
- |
-double Font::underline_thickness() const { |
- const_cast<Font*>(this)->InitPangoMetrics(); |
- return underline_thickness_; |
-} |
- |
-int Font::GetExpectedTextWidth(int length) const { |
- double char_width = const_cast<Font*>(this)->avg_width(); |
- return round(static_cast<float>(length) * char_width); |
-} |
- |
-int Font::style() const { |
- return style_; |
-} |
- |
-const std::wstring& Font::FontName() const { |
- return font_family_; |
-} |
- |
-int Font::FontSize() { |
- return font_size_; |
-} |
- |
-NativeFont Font::nativeFont() const { |
- return typeface_; |
-} |
- |
-} // namespace gfx |