diff options
author | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-30 18:21:41 +0000 |
---|---|---|
committer | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-30 18:21:41 +0000 |
commit | f84cc47198da462b72929be0948a65a00c440c2e (patch) | |
tree | 28cb98275a7219afc2d03a460c1288f0a741f34b /ui | |
parent | e05b9d1361a9b8e1666cf569f3d0bb72a56828e0 (diff) | |
download | chromium_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.h | 26 | ||||
-rw-r--r-- | ui/gfx/platform_font_mac.mm | 118 | ||||
-rw-r--r-- | ui/gfx/render_text_mac.cc | 5 |
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 }; |