OLD | NEW |
| (Empty) |
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 #include "ui/gfx/font_render_params.h" | |
16 | |
17 namespace gfx { | |
18 | |
19 namespace { | |
20 | |
21 // Returns an autoreleased NSFont created with the passed-in specifications. | |
22 NSFont* NSFontWithSpec(const std::string& font_name, | |
23 int font_size, | |
24 int font_style) { | |
25 NSFontSymbolicTraits trait_bits = 0; | |
26 if (font_style & Font::BOLD) | |
27 trait_bits |= NSFontBoldTrait; | |
28 if (font_style & Font::ITALIC) | |
29 trait_bits |= NSFontItalicTrait; | |
30 // The Mac doesn't support underline as a font trait, so just drop it. | |
31 // (Underlines must be added as an attribute on an NSAttributedString.) | |
32 NSDictionary* traits = @{ NSFontSymbolicTrait : @(trait_bits) }; | |
33 | |
34 NSDictionary* attrs = @{ | |
35 NSFontFamilyAttribute : base::SysUTF8ToNSString(font_name), | |
36 NSFontTraitsAttribute : traits | |
37 }; | |
38 NSFontDescriptor* descriptor = | |
39 [NSFontDescriptor fontDescriptorWithFontAttributes:attrs]; | |
40 NSFont* font = [NSFont fontWithDescriptor:descriptor size:font_size]; | |
41 if (font) | |
42 return font; | |
43 | |
44 // Make one fallback attempt by looking up via font name rather than font | |
45 // family name. | |
46 attrs = @{ | |
47 NSFontNameAttribute : base::SysUTF8ToNSString(font_name), | |
48 NSFontTraitsAttribute : traits | |
49 }; | |
50 descriptor = [NSFontDescriptor fontDescriptorWithFontAttributes:attrs]; | |
51 return [NSFont fontWithDescriptor:descriptor size:font_size]; | |
52 } | |
53 | |
54 } // namespace | |
55 | |
56 //////////////////////////////////////////////////////////////////////////////// | |
57 // PlatformFontMac, public: | |
58 | |
59 PlatformFontMac::PlatformFontMac() | |
60 : native_font_([[NSFont systemFontOfSize:[NSFont systemFontSize]] retain]), | |
61 font_name_(base::SysNSStringToUTF8([native_font_ familyName])), | |
62 font_size_([NSFont systemFontSize]), | |
63 font_style_(Font::NORMAL) { | |
64 CalculateMetrics(); | |
65 } | |
66 | |
67 PlatformFontMac::PlatformFontMac(NativeFont native_font) | |
68 : native_font_([native_font retain]), | |
69 font_name_(base::SysNSStringToUTF8([native_font_ familyName])), | |
70 font_size_([native_font_ pointSize]), | |
71 font_style_(Font::NORMAL) { | |
72 NSFontSymbolicTraits traits = [[native_font fontDescriptor] symbolicTraits]; | |
73 if (traits & NSFontItalicTrait) | |
74 font_style_ |= Font::ITALIC; | |
75 if (traits & NSFontBoldTrait) | |
76 font_style_ |= Font::BOLD; | |
77 | |
78 CalculateMetrics(); | |
79 } | |
80 | |
81 PlatformFontMac::PlatformFontMac(const std::string& font_name, | |
82 int font_size) | |
83 : native_font_([NSFontWithSpec(font_name, font_size, Font::NORMAL) retain]), | |
84 font_name_(font_name), | |
85 font_size_(font_size), | |
86 font_style_(Font::NORMAL) { | |
87 CalculateMetrics(); | |
88 } | |
89 | |
90 //////////////////////////////////////////////////////////////////////////////// | |
91 // PlatformFontMac, PlatformFont implementation: | |
92 | |
93 Font PlatformFontMac::DeriveFont(int size_delta, int style) const { | |
94 return Font(new PlatformFontMac(font_name_, font_size_ + size_delta, style)); | |
95 } | |
96 | |
97 int PlatformFontMac::GetHeight() const { | |
98 return height_; | |
99 } | |
100 | |
101 int PlatformFontMac::GetBaseline() const { | |
102 return ascent_; | |
103 } | |
104 | |
105 int PlatformFontMac::GetCapHeight() const { | |
106 return cap_height_; | |
107 } | |
108 | |
109 int PlatformFontMac::GetExpectedTextWidth(int length) const { | |
110 return length * average_width_; | |
111 } | |
112 | |
113 int PlatformFontMac::GetStyle() const { | |
114 return font_style_; | |
115 } | |
116 | |
117 std::string PlatformFontMac::GetFontName() const { | |
118 return font_name_; | |
119 } | |
120 | |
121 std::string PlatformFontMac::GetActualFontNameForTesting() const { | |
122 return base::SysNSStringToUTF8([native_font_ familyName]); | |
123 } | |
124 | |
125 int PlatformFontMac::GetFontSize() const { | |
126 return font_size_; | |
127 } | |
128 | |
129 const FontRenderParams& PlatformFontMac::GetFontRenderParams() const { | |
130 NOTIMPLEMENTED(); | |
131 static FontRenderParams params; | |
132 return params; | |
133 } | |
134 | |
135 NativeFont PlatformFontMac::GetNativeFont() const { | |
136 return [[native_font_.get() retain] autorelease]; | |
137 } | |
138 | |
139 //////////////////////////////////////////////////////////////////////////////// | |
140 // PlatformFontMac, private: | |
141 | |
142 PlatformFontMac::PlatformFontMac(const std::string& font_name, | |
143 int font_size, | |
144 int font_style) | |
145 : native_font_([NSFontWithSpec(font_name, font_size, font_style) retain]), | |
146 font_name_(font_name), | |
147 font_size_(font_size), | |
148 font_style_(font_style) { | |
149 CalculateMetrics(); | |
150 } | |
151 | |
152 PlatformFontMac::~PlatformFontMac() { | |
153 } | |
154 | |
155 void PlatformFontMac::CalculateMetrics() { | |
156 NSFont* font = native_font_.get(); | |
157 if (!font) { | |
158 // This object was constructed from a font name that doesn't correspond to | |
159 // an actual font. Don't waste time working out metrics. | |
160 height_ = 0; | |
161 ascent_ = 0; | |
162 cap_height_ = 0; | |
163 average_width_ = 0; | |
164 return; | |
165 } | |
166 | |
167 base::scoped_nsobject<NSLayoutManager> layout_manager( | |
168 [[NSLayoutManager alloc] init]); | |
169 height_ = SkScalarCeilToInt([layout_manager defaultLineHeightForFont:font]); | |
170 ascent_ = SkScalarCeilToInt([font ascender]); | |
171 cap_height_ = SkScalarCeilToInt([font capHeight]); | |
172 average_width_ = | |
173 NSWidth([font boundingRectForGlyph:[font glyphWithName:@"x"]]); | |
174 } | |
175 | |
176 //////////////////////////////////////////////////////////////////////////////// | |
177 // PlatformFont, public: | |
178 | |
179 // static | |
180 PlatformFont* PlatformFont::CreateDefault() { | |
181 return new PlatformFontMac; | |
182 } | |
183 | |
184 // static | |
185 PlatformFont* PlatformFont::CreateFromNativeFont(NativeFont native_font) { | |
186 return new PlatformFontMac(native_font); | |
187 } | |
188 | |
189 // static | |
190 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name, | |
191 int font_size) { | |
192 return new PlatformFontMac(font_name, font_size); | |
193 } | |
194 | |
195 } // namespace gfx | |
OLD | NEW |