summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authoravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-30 18:21:41 +0000
committeravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-30 18:21:41 +0000
commitf84cc47198da462b72929be0948a65a00c440c2e (patch)
tree28cb98275a7219afc2d03a460c1288f0a741f34b /ui
parente05b9d1361a9b8e1666cf569f3d0bb72a56828e0 (diff)
downloadchromium_src-f84cc47198da462b72929be0948a65a00c440c2e.zip
chromium_src-f84cc47198da462b72929be0948a65a00c440c2e.tar.gz
chromium_src-f84cc47198da462b72929be0948a65a00c440c2e.tar.bz2
Make RenderTextMac more efficient by caching fonts and taking advantage of toll-free bridging of CT/NSFont.
BUG=312436 TEST=no console spew as in bug R=asvitkine@chromium.org, mark@chromium.org, shess@chromium.org Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=231670 Reverted: https://src.chromium.org/viewvc/chrome?view=rev&revision=231685 Review URL: https://codereview.chromium.org/49503003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@231879 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/gfx/platform_font_mac.h26
-rw-r--r--ui/gfx/platform_font_mac.mm118
-rw-r--r--ui/gfx/render_text_mac.cc5
3 files changed, 92 insertions, 57 deletions
diff --git a/ui/gfx/platform_font_mac.h b/ui/gfx/platform_font_mac.h
index e9d0714..02006c3 100644
--- a/ui/gfx/platform_font_mac.h
+++ b/ui/gfx/platform_font_mac.h
@@ -6,6 +6,7 @@
#define UI_GFX_PLATFORM_FONT_MAC_H_
#include "base/compiler_specific.h"
+#include "base/mac/scoped_nsobject.h"
#include "ui/gfx/platform_font.h"
namespace gfx {
@@ -31,22 +32,25 @@ class PlatformFontMac : public PlatformFont {
virtual NativeFont GetNativeFont() const OVERRIDE;
private:
- PlatformFontMac(const std::string& font_name, int font_size, int style);
- virtual ~PlatformFontMac() {}
+ PlatformFontMac(const std::string& font_name, int font_size, int font_style);
+ virtual ~PlatformFontMac();
- // Initialize the object with the specified parameters.
- void InitWithNameSizeAndStyle(const std::string& font_name,
- int font_size,
- int style);
-
- // Calculate and cache the font metrics.
+ // Calculates and caches the font metrics.
void CalculateMetrics();
- std::string font_name_;
+ // The NSFont instance for this object. If this object was constructed from an
+ // NSFont instance, this holds that NSFont instance. Otherwise this NSFont
+ // instance is constructed from the name, size, and style, and if there is no
+ // active font that matched those criteria, this object may be nil.
+ base::scoped_nsobject<NSFont> native_font_;
+
+ // The name/size/style trio that specify the font. Initialized in the
+ // constructors.
+ std::string font_name_; // Corresponds to -[NSFont fontFamily].
int font_size_;
- int style_;
+ int font_style_;
- // Cached metrics, generated at construction.
+ // Cached metrics, generated in CalculateMetrics().
int height_;
int ascent_;
int cap_height_;
diff --git a/ui/gfx/platform_font_mac.mm b/ui/gfx/platform_font_mac.mm
index c75bf66..fa9d589 100644
--- a/ui/gfx/platform_font_mac.mm
+++ b/ui/gfx/platform_font_mac.mm
@@ -15,33 +15,75 @@
namespace gfx {
+namespace {
+
+// Returns an autoreleased NSFont created with the passed-in specifications.
+NSFont* NSFontWithSpec(const std::string& font_name,
+ int font_size,
+ int font_style) {
+ NSFontSymbolicTraits trait_bits = 0;
+ if (font_style & Font::BOLD)
+ trait_bits |= NSFontBoldTrait;
+ if (font_style & Font::ITALIC)
+ trait_bits |= NSFontItalicTrait;
+ // The Mac doesn't support underline as a font trait, so just drop it.
+ // (Underlines must be added as an attribute on an NSAttributedString.)
+ NSDictionary* traits = @{ NSFontSymbolicTrait : @(trait_bits) };
+
+ NSDictionary* attrs = @{
+ NSFontFamilyAttribute : base::SysUTF8ToNSString(font_name),
+ NSFontTraitsAttribute : traits
+ };
+ NSFontDescriptor* descriptor =
+ [NSFontDescriptor fontDescriptorWithFontAttributes:attrs];
+ NSFont* font = [NSFont fontWithDescriptor:descriptor size:font_size];
+ if (font)
+ return font;
+
+ // Make one fallback attempt by looking up via font name rather than font
+ // family name.
+ attrs = @{
+ NSFontNameAttribute : base::SysUTF8ToNSString(font_name),
+ NSFontTraitsAttribute : traits
+ };
+ descriptor = [NSFontDescriptor fontDescriptorWithFontAttributes:attrs];
+ return [NSFont fontWithDescriptor:descriptor size:font_size];
+}
+
+} // namespace
+
////////////////////////////////////////////////////////////////////////////////
// PlatformFontMac, public:
-PlatformFontMac::PlatformFontMac() {
- font_size_ = [NSFont systemFontSize];
- style_ = gfx::Font::NORMAL;
- NSFont* system_font = [NSFont systemFontOfSize:font_size_];
- font_name_ = base::SysNSStringToUTF8([system_font fontName]);
+PlatformFontMac::PlatformFontMac()
+ : native_font_([[NSFont systemFontOfSize:[NSFont systemFontSize]] retain]),
+ font_name_(base::SysNSStringToUTF8([native_font_ familyName])),
+ font_size_([NSFont systemFontSize]),
+ font_style_(Font::NORMAL) {
CalculateMetrics();
}
-PlatformFontMac::PlatformFontMac(NativeFont native_font) {
- int style = 0;
+PlatformFontMac::PlatformFontMac(NativeFont native_font)
+ : native_font_([native_font retain]),
+ font_name_(base::SysNSStringToUTF8([native_font_ familyName])),
+ font_size_([native_font_ pointSize]),
+ font_style_(Font::NORMAL) {
NSFontSymbolicTraits traits = [[native_font fontDescriptor] symbolicTraits];
if (traits & NSFontItalicTrait)
- style |= Font::ITALIC;
+ font_style_ |= Font::ITALIC;
if (traits & NSFontBoldTrait)
- style |= Font::BOLD;
+ font_style_ |= Font::BOLD;
- InitWithNameSizeAndStyle(base::SysNSStringToUTF8([native_font familyName]),
- [native_font pointSize],
- style);
+ CalculateMetrics();
}
PlatformFontMac::PlatformFontMac(const std::string& font_name,
- int font_size) {
- InitWithNameSizeAndStyle(font_name, font_size, gfx::Font::NORMAL);
+ int font_size)
+ : native_font_([NSFontWithSpec(font_name, font_size, Font::NORMAL) retain]),
+ font_name_(font_name),
+ font_size_(font_size),
+ font_style_(Font::NORMAL) {
+ CalculateMetrics();
}
////////////////////////////////////////////////////////////////////////////////
@@ -77,7 +119,7 @@ int PlatformFontMac::GetExpectedTextWidth(int length) const {
}
int PlatformFontMac::GetStyle() const {
- return style_;
+ return font_style_;
}
std::string PlatformFontMac::GetFontName() const {
@@ -89,23 +131,7 @@ int PlatformFontMac::GetFontSize() const {
}
NativeFont PlatformFontMac::GetNativeFont() const {
- // We could cache this, but then we'd have to conditionally change the
- // dtor just for MacOS. Not sure if we want to/need to do that.
- NSFont* font = [NSFont fontWithName:base::SysUTF8ToNSString(font_name_)
- size:font_size_];
-
- if (style_ & Font::BOLD) {
- font = [[NSFontManager sharedFontManager] convertFont:font
- toHaveTrait:NSBoldFontMask];
- }
- if (style_ & Font::ITALIC) {
- font = [[NSFontManager sharedFontManager] convertFont:font
- toHaveTrait:NSItalicFontMask];
- }
- // Mac doesn't support underline as a font trait, just drop it. Underlines
- // can instead be added as an attribute on an NSAttributedString.
-
- return font;
+ return [[native_font_.get() retain] autorelease];
}
////////////////////////////////////////////////////////////////////////////////
@@ -113,21 +139,29 @@ NativeFont PlatformFontMac::GetNativeFont() const {
PlatformFontMac::PlatformFontMac(const std::string& font_name,
int font_size,
- int style) {
- InitWithNameSizeAndStyle(font_name, font_size, style);
+ int font_style)
+ : native_font_([NSFontWithSpec(font_name, font_size, font_style) retain]),
+ font_name_(font_name),
+ font_size_(font_size),
+ font_style_(font_style) {
+ CalculateMetrics();
}
-void PlatformFontMac::InitWithNameSizeAndStyle(const std::string& font_name,
- int font_size,
- int style) {
- font_name_ = font_name;
- font_size_ = font_size;
- style_ = style;
- CalculateMetrics();
+PlatformFontMac::~PlatformFontMac() {
}
void PlatformFontMac::CalculateMetrics() {
- NSFont* font = GetNativeFont();
+ NSFont* font = native_font_.get();
+ if (!font) {
+ // This object was constructed from a font name that doesn't correspond to
+ // an actual font. Don't waste time working out metrics.
+ height_ = 0;
+ ascent_ = 0;
+ cap_height_ = 0;
+ average_width_ = 0;
+ return;
+ }
+
base::scoped_nsobject<NSLayoutManager> layout_manager(
[[NSLayoutManager alloc] init]);
height_ = [layout_manager defaultLineHeightForFont:font];
diff --git a/ui/gfx/render_text_mac.cc b/ui/gfx/render_text_mac.cc
index d86975d..327fc52 100644
--- a/ui/gfx/render_text_mac.cc
+++ b/ui/gfx/render_text_mac.cc
@@ -112,10 +112,7 @@ void RenderTextMac::EnsureLayout() {
runs_valid_ = false;
const Font& font = GetPrimaryFont();
- base::ScopedCFTypeRef<CFStringRef> font_name_cf_string(
- base::SysUTF8ToCFStringRef(font.GetFontName()));
- base::ScopedCFTypeRef<CTFontRef> ct_font(
- CTFontCreateWithName(font_name_cf_string, font.GetFontSize(), NULL));
+ CTFontRef ct_font = base::mac::NSToCFCast(font.GetNativeFont());
const void* keys[] = { kCTFontAttributeName };
const void* values[] = { ct_font };