- add sources.
[platform/framework/web/crosswalk.git] / src / ui / gfx / platform_font_mac.mm
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 namespace {
19
20 // Returns an autoreleased NSFont created with the passed-in specifications.
21 NSFont* NSFontWithSpec(const std::string& font_name,
22                        int font_size,
23                        int font_style) {
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) };
32
33   NSDictionary* attrs = @{
34     NSFontFamilyAttribute : base::SysUTF8ToNSString(font_name),
35     NSFontTraitsAttribute : traits
36   };
37   NSFontDescriptor* descriptor =
38       [NSFontDescriptor fontDescriptorWithFontAttributes:attrs];
39   NSFont* font = [NSFont fontWithDescriptor:descriptor size:font_size];
40   if (font)
41     return font;
42
43   // Make one fallback attempt by looking up via font name rather than font
44   // family name.
45   attrs = @{
46     NSFontNameAttribute : base::SysUTF8ToNSString(font_name),
47     NSFontTraitsAttribute : traits
48   };
49   descriptor = [NSFontDescriptor fontDescriptorWithFontAttributes:attrs];
50   return [NSFont fontWithDescriptor:descriptor size:font_size];
51 }
52
53 }  // namespace
54
55 ////////////////////////////////////////////////////////////////////////////////
56 // PlatformFontMac, public:
57
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) {
63   CalculateMetrics();
64 }
65
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;
76
77   CalculateMetrics();
78 }
79
80 PlatformFontMac::PlatformFontMac(const std::string& font_name,
81                                  int font_size)
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) {
86   CalculateMetrics();
87 }
88
89 ////////////////////////////////////////////////////////////////////////////////
90 // PlatformFontMac, PlatformFont implementation:
91
92 Font PlatformFontMac::DeriveFont(int size_delta, int style) const {
93   return Font(new PlatformFontMac(font_name_, font_size_ + size_delta, style));
94 }
95
96 int PlatformFontMac::GetHeight() const {
97   return height_;
98 }
99
100 int PlatformFontMac::GetBaseline() const {
101   return ascent_;
102 }
103
104 int PlatformFontMac::GetCapHeight() const {
105   return cap_height_;
106 }
107
108 int PlatformFontMac::GetAverageCharacterWidth() const {
109   return average_width_;
110 }
111
112 int PlatformFontMac::GetStringWidth(const base::string16& text) const {
113   return Canvas::GetStringWidth(text,
114                                 Font(const_cast<PlatformFontMac*>(this)));
115 }
116
117 int PlatformFontMac::GetExpectedTextWidth(int length) const {
118   return length * average_width_;
119 }
120
121 int PlatformFontMac::GetStyle() const {
122   return font_style_;
123 }
124
125 std::string PlatformFontMac::GetFontName() const {
126   return font_name_;
127 }
128
129 int PlatformFontMac::GetFontSize() const {
130   return font_size_;
131 }
132
133 NativeFont PlatformFontMac::GetNativeFont() const {
134   return [[native_font_.get() retain] autorelease];
135 }
136
137 ////////////////////////////////////////////////////////////////////////////////
138 // PlatformFontMac, private:
139
140 PlatformFontMac::PlatformFontMac(const std::string& font_name,
141                                  int font_size,
142                                  int font_style)
143     : native_font_([NSFontWithSpec(font_name, font_size, font_style) retain]),
144       font_name_(font_name),
145       font_size_(font_size),
146       font_style_(font_style) {
147   CalculateMetrics();
148 }
149
150 PlatformFontMac::~PlatformFontMac() {
151 }
152
153 void PlatformFontMac::CalculateMetrics() {
154   NSFont* font = native_font_.get();
155   if (!font) {
156     // This object was constructed from a font name that doesn't correspond to
157     // an actual font. Don't waste time working out metrics.
158     height_ = 0;
159     ascent_ = 0;
160     cap_height_ = 0;
161     average_width_ = 0;
162     return;
163   }
164
165   base::scoped_nsobject<NSLayoutManager> layout_manager(
166       [[NSLayoutManager alloc] init]);
167   height_ = [layout_manager defaultLineHeightForFont:font];
168   ascent_ = [font ascender];
169   cap_height_ = [font capHeight];
170   average_width_ =
171       NSWidth([font boundingRectForGlyph:[font glyphWithName:@"x"]]);
172 }
173
174 ////////////////////////////////////////////////////////////////////////////////
175 // PlatformFont, public:
176
177 // static
178 PlatformFont* PlatformFont::CreateDefault() {
179   return new PlatformFontMac;
180 }
181
182 // static
183 PlatformFont* PlatformFont::CreateFromNativeFont(NativeFont native_font) {
184   return new PlatformFontMac(native_font);
185 }
186
187 // static
188 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name,
189                                                   int font_size) {
190   return new PlatformFontMac(font_name, font_size);
191 }
192
193 }  // namespace gfx