1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ui/gfx/platform_font_mac.h" 6 7 #include <Cocoa/Cocoa.h> 8 9 #include "base/basictypes.h" 10 #include "base/mac/scoped_nsobject.h" 11 #include "base/strings/sys_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h" 13 #include "ui/gfx/canvas.h" 14 #include "ui/gfx/font.h" 15 16 namespace gfx { 17 18 //////////////////////////////////////////////////////////////////////////////// 19 // PlatformFontMac, public: 20 21 PlatformFontMac::PlatformFontMac() { 22 font_size_ = [NSFont systemFontSize]; 23 style_ = gfx::Font::NORMAL; 24 NSFont* system_font = [NSFont systemFontOfSize:font_size_]; 25 font_name_ = base::SysNSStringToUTF8([system_font fontName]); 26 CalculateMetrics(); 27 } 28 29 PlatformFontMac::PlatformFontMac(NativeFont native_font) { 30 int style = 0; 31 NSFontSymbolicTraits traits = [[native_font fontDescriptor] symbolicTraits]; 32 if (traits & NSFontItalicTrait) 33 style |= Font::ITALIC; 34 if (traits & NSFontBoldTrait) 35 style |= Font::BOLD; 36 37 InitWithNameSizeAndStyle(base::SysNSStringToUTF8([native_font familyName]), 38 [native_font pointSize], 39 style); 40 } 41 42 PlatformFontMac::PlatformFontMac(const std::string& font_name, 43 int font_size) { 44 InitWithNameSizeAndStyle(font_name, font_size, gfx::Font::NORMAL); 45 } 46 47 //////////////////////////////////////////////////////////////////////////////// 48 // PlatformFontMac, PlatformFont implementation: 49 50 Font PlatformFontMac::DeriveFont(int size_delta, int style) const { 51 return Font(new PlatformFontMac(font_name_, font_size_ + size_delta, style)); 52 } 53 54 int PlatformFontMac::GetHeight() const { 55 return height_; 56 } 57 58 int PlatformFontMac::GetBaseline() const { 59 return ascent_; 60 } 61 62 int PlatformFontMac::GetAverageCharacterWidth() const { 63 return average_width_; 64 } 65 66 int PlatformFontMac::GetStringWidth(const base::string16& text) const { 67 return Canvas::GetStringWidth(text, 68 Font(const_cast<PlatformFontMac*>(this))); 69 } 70 71 int PlatformFontMac::GetExpectedTextWidth(int length) const { 72 return length * average_width_; 73 } 74 75 int PlatformFontMac::GetStyle() const { 76 return style_; 77 } 78 79 std::string PlatformFontMac::GetFontName() const { 80 return font_name_; 81 } 82 83 int PlatformFontMac::GetFontSize() const { 84 return font_size_; 85 } 86 87 NativeFont PlatformFontMac::GetNativeFont() const { 88 // We could cache this, but then we'd have to conditionally change the 89 // dtor just for MacOS. Not sure if we want to/need to do that. 90 NSFont* font = [NSFont fontWithName:base::SysUTF8ToNSString(font_name_) 91 size:font_size_]; 92 93 if (style_ & Font::BOLD) { 94 font = [[NSFontManager sharedFontManager] convertFont:font 95 toHaveTrait:NSBoldFontMask]; 96 } 97 if (style_ & Font::ITALIC) { 98 font = [[NSFontManager sharedFontManager] convertFont:font 99 toHaveTrait:NSItalicFontMask]; 100 } 101 // Mac doesn't support underline as a font trait, just drop it. Underlines 102 // can instead be added as an attribute on an NSAttributedString. 103 104 return font; 105 } 106 107 //////////////////////////////////////////////////////////////////////////////// 108 // PlatformFontMac, private: 109 110 PlatformFontMac::PlatformFontMac(const std::string& font_name, 111 int font_size, 112 int style) { 113 InitWithNameSizeAndStyle(font_name, font_size, style); 114 } 115 116 void PlatformFontMac::InitWithNameSizeAndStyle(const std::string& font_name, 117 int font_size, 118 int style) { 119 font_name_ = font_name; 120 font_size_ = font_size; 121 style_ = style; 122 CalculateMetrics(); 123 } 124 125 void PlatformFontMac::CalculateMetrics() { 126 NSFont* font = GetNativeFont(); 127 base::scoped_nsobject<NSLayoutManager> layout_manager( 128 [[NSLayoutManager alloc] init]); 129 height_ = [layout_manager defaultLineHeightForFont:font]; 130 ascent_ = [font ascender]; 131 average_width_ = 132 NSWidth([font boundingRectForGlyph:[font glyphWithName:@"x"]]); 133 } 134 135 //////////////////////////////////////////////////////////////////////////////// 136 // PlatformFont, public: 137 138 // static 139 PlatformFont* PlatformFont::CreateDefault() { 140 return new PlatformFontMac; 141 } 142 143 // static 144 PlatformFont* PlatformFont::CreateFromNativeFont(NativeFont native_font) { 145 return new PlatformFontMac(native_font); 146 } 147 148 // static 149 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name, 150 int font_size) { 151 return new PlatformFontMac(font_name, font_size); 152 } 153 154 } // namespace gfx 155 156