| // Copyright (c) 2012 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 "ui/gfx/platform_font_mac.h" |
| |
| #include <Cocoa/Cocoa.h> |
| |
| #include "base/basictypes.h" |
| #include "base/mac/scoped_nsobject.h" |
| #include "base/strings/sys_string_conversions.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "ui/gfx/canvas.h" |
| #include "ui/gfx/font.h" |
| #include "ui/gfx/font_render_params.h" |
| |
| 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() |
| : 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) |
| : 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) |
| font_style_ |= Font::ITALIC; |
| if (traits & NSFontBoldTrait) |
| font_style_ |= Font::BOLD; |
| |
| CalculateMetrics(); |
| } |
| |
| PlatformFontMac::PlatformFontMac(const std::string& font_name, |
| 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(); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // PlatformFontMac, PlatformFont implementation: |
| |
| Font PlatformFontMac::DeriveFont(int size_delta, int style) const { |
| return Font(new PlatformFontMac(font_name_, font_size_ + size_delta, style)); |
| } |
| |
| int PlatformFontMac::GetHeight() const { |
| return height_; |
| } |
| |
| int PlatformFontMac::GetBaseline() const { |
| return ascent_; |
| } |
| |
| int PlatformFontMac::GetCapHeight() const { |
| return cap_height_; |
| } |
| |
| int PlatformFontMac::GetExpectedTextWidth(int length) const { |
| return length * average_width_; |
| } |
| |
| int PlatformFontMac::GetStyle() const { |
| return font_style_; |
| } |
| |
| std::string PlatformFontMac::GetFontName() const { |
| return font_name_; |
| } |
| |
| std::string PlatformFontMac::GetActualFontNameForTesting() const { |
| return base::SysNSStringToUTF8([native_font_ familyName]); |
| } |
| |
| int PlatformFontMac::GetFontSize() const { |
| return font_size_; |
| } |
| |
| const FontRenderParams& PlatformFontMac::GetFontRenderParams() const { |
| NOTIMPLEMENTED(); |
| static FontRenderParams params; |
| return params; |
| } |
| |
| NativeFont PlatformFontMac::GetNativeFont() const { |
| return [[native_font_.get() retain] autorelease]; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // PlatformFontMac, private: |
| |
| PlatformFontMac::PlatformFontMac(const std::string& font_name, |
| int font_size, |
| 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(); |
| } |
| |
| PlatformFontMac::~PlatformFontMac() { |
| } |
| |
| void PlatformFontMac::CalculateMetrics() { |
| 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_ = SkScalarCeilToInt([layout_manager defaultLineHeightForFont:font]); |
| ascent_ = SkScalarCeilToInt([font ascender]); |
| cap_height_ = SkScalarCeilToInt([font capHeight]); |
| average_width_ = |
| NSWidth([font boundingRectForGlyph:[font glyphWithName:@"x"]]); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // PlatformFont, public: |
| |
| // static |
| PlatformFont* PlatformFont::CreateDefault() { |
| return new PlatformFontMac; |
| } |
| |
| // static |
| PlatformFont* PlatformFont::CreateFromNativeFont(NativeFont native_font) { |
| return new PlatformFontMac(native_font); |
| } |
| |
| // static |
| PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name, |
| int font_size) { |
| return new PlatformFontMac(font_name, font_size); |
| } |
| |
| } // namespace gfx |