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.
5 #include "ui/gfx/platform_font_mac.h"
7 #include <Cocoa/Cocoa.h>
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"
20 // Returns an autoreleased NSFont created with the passed-in specifications.
21 NSFont* NSFontWithSpec(const std::string& font_name,
24 NSFontSymbolicTraits trait_bits = 0;
25 if (font_style & Font::BOLD)
26 trait_bits |= NSFontBoldTrait;
27 if (font_style & Font::ITALIC)
28 trait_bits |= NSFontItalicTrait;
29 // The Mac doesn't support underline as a font trait, so just drop it.
30 // (Underlines must be added as an attribute on an NSAttributedString.)
31 NSDictionary* traits = @{ NSFontSymbolicTrait : @(trait_bits) };
33 NSDictionary* attrs = @{
34 NSFontFamilyAttribute : base::SysUTF8ToNSString(font_name),
35 NSFontTraitsAttribute : traits
37 NSFontDescriptor* descriptor =
38 [NSFontDescriptor fontDescriptorWithFontAttributes:attrs];
39 NSFont* font = [NSFont fontWithDescriptor:descriptor size:font_size];
43 // Make one fallback attempt by looking up via font name rather than font
46 NSFontNameAttribute : base::SysUTF8ToNSString(font_name),
47 NSFontTraitsAttribute : traits
49 descriptor = [NSFontDescriptor fontDescriptorWithFontAttributes:attrs];
50 return [NSFont fontWithDescriptor:descriptor size:font_size];
55 ////////////////////////////////////////////////////////////////////////////////
56 // PlatformFontMac, public:
58 PlatformFontMac::PlatformFontMac()
59 : native_font_([[NSFont systemFontOfSize:[NSFont systemFontSize]] retain]),
60 font_name_(base::SysNSStringToUTF8([native_font_ familyName])),
61 font_size_([NSFont systemFontSize]),
62 font_style_(Font::NORMAL) {
66 PlatformFontMac::PlatformFontMac(NativeFont native_font)
67 : native_font_([native_font retain]),
68 font_name_(base::SysNSStringToUTF8([native_font_ familyName])),
69 font_size_([native_font_ pointSize]),
70 font_style_(Font::NORMAL) {
71 NSFontSymbolicTraits traits = [[native_font fontDescriptor] symbolicTraits];
72 if (traits & NSFontItalicTrait)
73 font_style_ |= Font::ITALIC;
74 if (traits & NSFontBoldTrait)
75 font_style_ |= Font::BOLD;
80 PlatformFontMac::PlatformFontMac(const std::string& font_name,
82 : native_font_([NSFontWithSpec(font_name, font_size, Font::NORMAL) retain]),
83 font_name_(font_name),
84 font_size_(font_size),
85 font_style_(Font::NORMAL) {
89 ////////////////////////////////////////////////////////////////////////////////
90 // PlatformFontMac, PlatformFont implementation:
92 Font PlatformFontMac::DeriveFont(int size_delta, int style) const {
93 return Font(new PlatformFontMac(font_name_, font_size_ + size_delta, style));
96 int PlatformFontMac::GetHeight() const {
100 int PlatformFontMac::GetBaseline() const {
104 int PlatformFontMac::GetCapHeight() const {
108 int PlatformFontMac::GetExpectedTextWidth(int length) const {
109 return length * average_width_;
112 int PlatformFontMac::GetStyle() const {
116 std::string PlatformFontMac::GetFontName() const {
120 std::string PlatformFontMac::GetActualFontNameForTesting() const {
121 return base::SysNSStringToUTF8([native_font_ familyName]);
124 int PlatformFontMac::GetFontSize() const {
128 NativeFont PlatformFontMac::GetNativeFont() const {
129 return [[native_font_.get() retain] autorelease];
132 ////////////////////////////////////////////////////////////////////////////////
133 // PlatformFontMac, private:
135 PlatformFontMac::PlatformFontMac(const std::string& font_name,
138 : native_font_([NSFontWithSpec(font_name, font_size, font_style) retain]),
139 font_name_(font_name),
140 font_size_(font_size),
141 font_style_(font_style) {
145 PlatformFontMac::~PlatformFontMac() {
148 void PlatformFontMac::CalculateMetrics() {
149 NSFont* font = native_font_.get();
151 // This object was constructed from a font name that doesn't correspond to
152 // an actual font. Don't waste time working out metrics.
160 base::scoped_nsobject<NSLayoutManager> layout_manager(
161 [[NSLayoutManager alloc] init]);
162 height_ = [layout_manager defaultLineHeightForFont:font];
163 ascent_ = [font ascender];
164 cap_height_ = [font capHeight];
166 NSWidth([font boundingRectForGlyph:[font glyphWithName:@"x"]]);
169 ////////////////////////////////////////////////////////////////////////////////
170 // PlatformFont, public:
173 PlatformFont* PlatformFont::CreateDefault() {
174 return new PlatformFontMac;
178 PlatformFont* PlatformFont::CreateFromNativeFont(NativeFont native_font) {
179 return new PlatformFontMac(native_font);
183 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name,
185 return new PlatformFontMac(font_name, font_size);