Home | History | Annotate | Download | only in gfx
      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