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 <cmath>
8#include <set>
9
10#include <Cocoa/Cocoa.h>
11
12#include "base/bit_cast.h"
13#import "base/mac/foundation_util.h"
14#include "base/mac/scoped_cftyperef.h"
15#import "base/mac/scoped_nsobject.h"
16#include "base/no_destructor.h"
17#include "base/strings/sys_string_conversions.h"
18#include "base/strings/utf_string_conversions.h"
19#include "third_party/skia/include/ports/SkTypeface_mac.h"
20#include "ui/gfx/canvas.h"
21#include "ui/gfx/font.h"
22#include "ui/gfx/font_render_params.h"
23
24namespace gfx {
25
26using Weight = Font::Weight;
27
28extern "C" {
29bool CTFontDescriptorIsSystemUIFont(CTFontDescriptorRef);
30}
31
32namespace {
33
34// Returns the font style for |font|. Disregards Font::UNDERLINE, since NSFont
35// does not support it as a trait.
36int GetFontStyleFromNSFont(NSFont* font) {
37  int font_style = Font::NORMAL;
38  NSFontSymbolicTraits traits = [[font fontDescriptor] symbolicTraits];
39  if (traits & NSFontItalicTrait)
40    font_style |= Font::ITALIC;
41  return font_style;
42}
43
44// Returns the Font::Weight for |font|.
45Weight GetFontWeightFromNSFont(NSFont* font) {
46  DCHECK(font);
47
48  // Map CoreText weights in a manner similar to ct_weight_to_fontstyle() from
49  // SkFontHost_mac.cpp, but adjusted for the weights actually used by the
50  // system fonts. See PlatformFontMacTest.FontWeightAPIConsistency for details.
51  // macOS uses specific float values in its constants, but individual fonts can
52  // and do specify arbitrary values in the -1.0 to 1.0 range. Therefore, to
53  // accomodate that, and to avoid float comparison issues, use ranges.
54  constexpr struct {
55    // A range of CoreText weights.
56    CGFloat weight_lower;
57    CGFloat weight_upper;
58    Weight gfx_weight;
59  } weight_map[] = {
60      // NSFontWeight constants introduced in 10.11:
61      //   NSFontWeightUltraLight: -0.80
62      //   NSFontWeightThin: -0.60
63      //   NSFontWeightLight: -0.40
64      //   NSFontWeightRegular: 0.0
65      //   NSFontWeightMedium: 0.23
66      //   NSFontWeightSemibold: 0.30
67      //   NSFontWeightBold: 0.40
68      //   NSFontWeightHeavy: 0.56
69      //   NSFontWeightBlack: 0.62
70      //
71      // Actual system font weights:
72      //   10.10:
73      //     .HelveticaNeueDeskInterface-UltraLightP2: -0.80
74      //     .HelveticaNeueDeskInterface-Thin: -0.50
75      //     .HelveticaNeueDeskInterface-Light: -0.425
76      //     .HelveticaNeueDeskInterface-Regular: 0.0
77      //     .HelveticaNeueDeskInterface-MediumP4: 0.23
78      //     .HelveticaNeueDeskInterface-Bold (if requested as semibold): 0.24
79      //     .HelveticaNeueDeskInterface-Bold (if requested as bold): 0.4
80      //     .HelveticaNeueDeskInterface-Heavy (if requested as heavy): 0.576
81      //     .HelveticaNeueDeskInterface-Heavy (if requested as black): 0.662
82      //   10.11-:
83      //     .AppleSystemUIFontUltraLight: -0.80
84      //     .AppleSystemUIFontThin: -0.60
85      //     .AppleSystemUIFontLight: -0.40
86      //     .AppleSystemUIFont: 0.0
87      //     .AppleSystemUIFontMedium: 0.23
88      //     .AppleSystemUIFontDemi: 0.30
89      //     .AppleSystemUIFontBold (10.11): 0.40
90      //     .AppleSystemUIFontEmphasized (10.12-): 0.40
91      //     .AppleSystemUIFontHeavy: 0.56
92      //     .AppleSystemUIFontBlack: 0.62
93      {-1.0, -0.70, Weight::THIN},          // NSFontWeightUltraLight
94      {-0.70, -0.45, Weight::EXTRA_LIGHT},  // NSFontWeightThin
95      {-0.45, -0.10, Weight::LIGHT},        // NSFontWeightLight
96      {-0.10, 0.10, Weight::NORMAL},        // NSFontWeightRegular
97      {0.10, 0.27, Weight::MEDIUM},         // NSFontWeightMedium
98      {0.27, 0.35, Weight::SEMIBOLD},       // NSFontWeightSemibold
99      {0.35, 0.50, Weight::BOLD},           // NSFontWeightBold
100      {0.50, 0.60, Weight::EXTRA_BOLD},     // NSFontWeightHeavy
101      {0.60, 1.0, Weight::BLACK},           // NSFontWeightBlack
102  };
103
104  base::ScopedCFTypeRef<CFDictionaryRef> traits(
105      CTFontCopyTraits(base::mac::NSToCFCast(font)));
106  DCHECK(traits);
107  CFNumberRef cf_weight = base::mac::GetValueFromDictionary<CFNumberRef>(
108      traits, kCTFontWeightTrait);
109  // A missing weight attribute just means 0 -> NORMAL.
110  if (!cf_weight)
111    return Weight::NORMAL;
112
113  // The value of kCTFontWeightTrait empirically is a kCFNumberFloat64Type
114  // (double) on all tested versions of macOS. However, that doesn't really
115  // matter as only the first two decimal digits need to be tested. Do not check
116  // for the success of CFNumberGetValue() as it returns false for any loss of
117  // value and all that is needed here is two digits of accuracy.
118  CGFloat weight;
119  CFNumberGetValue(cf_weight, kCFNumberCGFloatType, &weight);
120  for (const auto& item : weight_map) {
121    if (item.weight_lower <= weight && weight <= item.weight_upper)
122      return item.gfx_weight;
123  }
124  return Weight::INVALID;
125}
126
127// Converts a Font::Weight value to the corresponding NSFontWeight value.
128NSFontWeight ToNSFontWeight(Weight weight) {
129  if (@available(macOS 10.11, *)) {
130    switch (weight) {
131      case Weight::THIN:
132        return NSFontWeightUltraLight;
133      case Weight::EXTRA_LIGHT:
134        return NSFontWeightThin;
135      case Weight::LIGHT:
136        return NSFontWeightLight;
137      case Weight::INVALID:
138      case Weight::NORMAL:
139        return NSFontWeightRegular;
140      case Weight::MEDIUM:
141        return NSFontWeightMedium;
142      case Weight::SEMIBOLD:
143        return NSFontWeightSemibold;
144      case Weight::BOLD:
145        return NSFontWeightBold;
146      case Weight::EXTRA_BOLD:
147        return NSFontWeightHeavy;
148      case Weight::BLACK:
149        return NSFontWeightBlack;
150    }
151  } else {
152    // See third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm.
153    uint64_t int_value = 0;
154    switch (weight) {
155      case Weight::THIN:
156        int_value = 0xbfe99999a0000000;  // NSFontWeightUltraLight;
157        break;
158      case Weight::EXTRA_LIGHT:
159        int_value = 0xbfe3333340000000;  // NSFontWeightThin;
160        break;
161      case Weight::LIGHT:
162        int_value = 0xbfd99999a0000000;  // NSFontWeightLight;
163        break;
164      case Weight::INVALID:
165      case Weight::NORMAL:
166        int_value = 0x0000000000000000;  // NSFontWeightRegular;
167        break;
168      case Weight::MEDIUM:
169        int_value = 0x3fcd70a3e0000000;  // NSFontWeightMedium;
170        break;
171      case Weight::SEMIBOLD:
172        int_value = 0x3fd3333340000000;  // NSFontWeightSemibold;
173        break;
174      case Weight::BOLD:
175        int_value = 0x3fd99999a0000000;  // NSFontWeightBold;
176        break;
177      case Weight::EXTRA_BOLD:
178        int_value = 0x3fe1eb8520000000;  // NSFontWeightHeavy;
179        break;
180      case Weight::BLACK:
181        int_value = 0x3fe3d70a40000000;  // NSFontWeightBlack;
182        break;
183    }
184
185    return bit_cast<CGFloat>(int_value);
186  }
187}
188
189// Chromium uses the ISO-style, 9-value ladder of font weights (THIN-BLACK). The
190// new font API in macOS also uses these weights, though they are constants
191// defined in terms of CGFloat with values from -1.0 to 1.0.
192//
193// However, the old API used by the NSFontManager uses integer values on a
194// "scale of 0 to 15". These values are used in:
195//
196//   -[NSFontManager availableMembersOfFontFamily:]
197//   -[NSFontManager convertWeight:ofFont:]
198//   -[NSFontManager fontWithFamily:traits:weight:size:]
199//   -[NSFontManager weightOfFont:]
200//
201// Apple provides a chart of how the ISO values correspond:
202// https://developer.apple.com/reference/appkit/nsfontmanager/1462321-convertweight
203// However, it's more complicated than that. A survey of fonts yields the
204// correspondence in this function, but the outliers imply that the ISO-style
205// weight is more along the lines of "weight role within the font family" vs
206// this number which is more like "how weighty is this font compared to all
207// other fonts".
208//
209// These numbers can't really be forced to line up; different fonts disagree on
210// how to map them. This function mostly follows the documented chart as
211// inspired by actual fonts, and should be good enough.
212NSInteger ToNSFontManagerWeight(Weight weight) {
213  switch (weight) {
214    case Weight::THIN:
215      return 2;
216    case Weight::EXTRA_LIGHT:
217      return 3;
218    case Weight::LIGHT:
219      return 4;
220    case Weight::INVALID:
221    case Weight::NORMAL:
222      return 5;
223    case Weight::MEDIUM:
224      return 6;
225    case Weight::SEMIBOLD:
226      return 8;
227    case Weight::BOLD:
228      return 9;
229    case Weight::EXTRA_BOLD:
230      return 10;
231    case Weight::BLACK:
232      return 11;
233  }
234}
235
236std::string GetFamilyNameFromTypeface(sk_sp<SkTypeface> typeface) {
237  SkString family;
238  typeface->getFamilyName(&family);
239  return family.c_str();
240}
241
242NSFont* SystemFontForConstructorOfType(PlatformFontMac::SystemFontType type) {
243  switch (type) {
244    case PlatformFontMac::SystemFontType::kGeneral:
245      return [NSFont systemFontOfSize:[NSFont systemFontSize]];
246    case PlatformFontMac::SystemFontType::kMenu:
247      return [NSFont menuFontOfSize:0];
248    case PlatformFontMac::SystemFontType::kToolTip:
249      return [NSFont toolTipsFontOfSize:0];
250  }
251}
252
253base::Optional<PlatformFontMac::SystemFontType>
254SystemFontTypeFromUndocumentedCTFontRefInternals(CTFontRef font) {
255  // The macOS APIs can't reliably derive one font from another. That's why for
256  // non-system fonts PlatformFontMac::DeriveFont() uses the family name of the
257  // font to find look up new fonts from scratch, and why, for system fonts, it
258  // uses the system font APIs to generate new system fonts.
259  //
260  // Skia's font handling assumes that given a font object, new fonts can be
261  // derived from it. That's absolutely not true on the Mac. However, this needs
262  // to be fixed, and a rewrite of how Skia handles fonts is not on the table.
263  //
264  // Therefore this sad hack. If Skia provides an SkTypeface, dig into the
265  // undocumented bowels of CoreText and magically determine if the font is a
266  // system font. This allows PlatformFontMac to correctly derive variants of
267  // the provided font.
268  //
269  // TODO(avi, etienneb): Figure out this font stuff.
270  base::ScopedCFTypeRef<CTFontDescriptorRef> descriptor(
271      CTFontCopyFontDescriptor(font));
272  if (CTFontDescriptorIsSystemUIFont(descriptor.get())) {
273    // Assume it's the standard system font. The fact that this much is known is
274    // enough.
275    return PlatformFontMac::SystemFontType::kGeneral;
276  } else {
277    return base::nullopt;
278  }
279}
280
281#if DCHECK_IS_ON()
282
283const std::set<std::string>& SystemFontNames() {
284  static const base::NoDestructor<std::set<std::string>> names([] {
285    std::set<std::string> names;
286    names.insert(base::SysNSStringToUTF8(
287        [NSFont systemFontOfSize:[NSFont systemFontSize]].familyName));
288    names.insert(base::SysNSStringToUTF8([NSFont menuFontOfSize:0].familyName));
289    names.insert(
290        base::SysNSStringToUTF8([NSFont toolTipsFontOfSize:0].familyName));
291    return names;
292  }());
293
294  return *names;
295}
296
297#endif  // DCHECK_IS_ON()
298
299}  // namespace
300
301////////////////////////////////////////////////////////////////////////////////
302// PlatformFontMac, public:
303
304PlatformFontMac::PlatformFontMac(SystemFontType system_font_type)
305    : PlatformFontMac(SystemFontForConstructorOfType(system_font_type),
306                      system_font_type) {}
307
308PlatformFontMac::PlatformFontMac(NativeFont native_font)
309    : PlatformFontMac(native_font, base::nullopt) {
310  DCHECK(native_font);  // nil should not be passed to this constructor.
311}
312
313PlatformFontMac::PlatformFontMac(const std::string& font_name, int font_size)
314    : PlatformFontMac(
315          NSFontWithSpec({font_name, font_size, Font::NORMAL, Weight::NORMAL}),
316          base::nullopt,
317          {font_name, font_size, Font::NORMAL, Weight::NORMAL}) {}
318
319PlatformFontMac::PlatformFontMac(sk_sp<SkTypeface> typeface,
320                                 int font_size_pixels,
321                                 const base::Optional<FontRenderParams>& params)
322    : PlatformFontMac(
323          base::mac::CFToNSCast(SkTypeface_GetCTFontRef(typeface.get())),
324          SystemFontTypeFromUndocumentedCTFontRefInternals(
325              SkTypeface_GetCTFontRef(typeface.get())),
326          {GetFamilyNameFromTypeface(typeface), font_size_pixels,
327           (typeface->isItalic() ? Font::ITALIC : Font::NORMAL),
328           FontWeightFromInt(typeface->fontStyle().weight())}) {}
329
330////////////////////////////////////////////////////////////////////////////////
331// PlatformFontMac, PlatformFont implementation:
332
333Font PlatformFontMac::DeriveFont(int size_delta,
334                                 int style,
335                                 Weight weight) const {
336  // What doesn't work?
337  //
338  // For all fonts, -[NSFontManager convertWeight:ofFont:] will reliably
339  // misbehave, skipping over particular weights of fonts, refusing to go
340  // lighter than regular unless you go heavier first, and in earlier versions
341  // of the system would accidentally introduce italic fonts when changing
342  // weights from a non-italic instance.
343  //
344  // For system fonts, -[NSFontManager convertFont:to(Not)HaveTrait:], if used
345  // to change weight, will sometimes switch to a compatibility system font that
346  // does not have all the weights available.
347  //
348  // For system fonts, the most reliable call to use is +[NSFont
349  // systemFontOfSize:weight:]. This uses the new-style NSFontWeight which maps
350  // perfectly to the ISO weights that Chromium uses. For non-system fonts,
351  // -[NSFontManager fontWithFamily:traits:weight:size:] is the only reasonable
352  // way to query fonts with more granularity than bold/non-bold short of
353  // walking the font family and querying their kCTFontWeightTrait values. Font
354  // descriptors hold promise but querying using them often fails to find fonts
355  // that match; hopefully their matching abilities will improve in future
356  // versions of the macOS.
357
358  if (system_font_type_ == SystemFontType::kGeneral) {
359#pragma clang diagnostic push
360#pragma clang diagnostic ignored "-Wunguarded-availability"
361    // +[NSFont systemFontOfSize:weight:] is declared as available on 10.11+,
362    // but actually it is there and works on 10.10.
363    NSFont* derived = [NSFont systemFontOfSize:font_spec_.size + size_delta
364                                        weight:ToNSFontWeight(weight)];
365#pragma clang diagnostic pop
366    NSFontTraitMask italic_trait_mask =
367        (style & Font::ITALIC) ? NSItalicFontMask : NSUnitalicFontMask;
368    derived = [[NSFontManager sharedFontManager] convertFont:derived
369                                                 toHaveTrait:italic_trait_mask];
370
371    return Font(new PlatformFontMac(
372        derived, SystemFontType::kGeneral,
373        {font_spec_.name, font_spec_.size + size_delta, style, weight}));
374  } else if (system_font_type_ == SystemFontType::kMenu) {
375    NSFont* derived = [NSFont menuFontOfSize:font_spec_.size + size_delta];
376    return Font(new PlatformFontMac(
377        derived, SystemFontType::kMenu,
378        {font_spec_.name, font_spec_.size + size_delta, style, weight}));
379  } else if (system_font_type_ == SystemFontType::kToolTip) {
380    NSFont* derived = [NSFont toolTipsFontOfSize:font_spec_.size + size_delta];
381    return Font(new PlatformFontMac(
382        derived, SystemFontType::kToolTip,
383        {font_spec_.name, font_spec_.size + size_delta, style, weight}));
384  } else {
385    NSFont* derived = NSFontWithSpec(
386        {font_spec_.name, font_spec_.size + size_delta, style, weight});
387    return Font(new PlatformFontMac(
388        derived, base::nullopt,
389        {font_spec_.name, font_spec_.size + size_delta, style, weight}));
390  }
391}
392
393int PlatformFontMac::GetHeight() {
394  return height_;
395}
396
397int PlatformFontMac::GetBaseline() {
398  return ascent_;
399}
400
401int PlatformFontMac::GetCapHeight() {
402  return cap_height_;
403}
404
405int PlatformFontMac::GetExpectedTextWidth(int length) {
406  if (!average_width_) {
407    // -[NSFont boundingRectForGlyph:] seems to always return the largest
408    // bounding rect that could be needed, which produces very wide expected
409    // widths for strings. Instead, compute the actual width of a string
410    // containing all the lowercase characters to find a reasonable guess at the
411    // average.
412    base::scoped_nsobject<NSAttributedString> attr_string(
413        [[NSAttributedString alloc]
414            initWithString:@"abcdefghijklmnopqrstuvwxyz"
415                attributes:@{NSFontAttributeName : native_font_.get()}]);
416    average_width_ = [attr_string size].width / [attr_string length];
417    DCHECK_NE(0, average_width_);
418  }
419  return ceil(length * average_width_);
420}
421
422int PlatformFontMac::GetStyle() const {
423  return font_spec_.style;
424}
425
426Weight PlatformFontMac::GetWeight() const {
427  return font_spec_.weight;
428}
429
430const std::string& PlatformFontMac::GetFontName() const {
431  return font_spec_.name;
432}
433
434std::string PlatformFontMac::GetActualFontName() const {
435  return base::SysNSStringToUTF8([native_font_ familyName]);
436}
437
438int PlatformFontMac::GetFontSize() const {
439  return font_spec_.size;
440}
441
442const FontRenderParams& PlatformFontMac::GetFontRenderParams() {
443  return render_params_;
444}
445
446NativeFont PlatformFontMac::GetNativeFont() const {
447  return [[native_font_.get() retain] autorelease];
448}
449
450sk_sp<SkTypeface> PlatformFontMac::GetNativeSkTypeface() const {
451  return SkMakeTypefaceFromCTFont(base::mac::NSToCFCast(GetNativeFont()));
452}
453
454// static
455Weight PlatformFontMac::GetFontWeightFromNSFontForTesting(NSFont* font) {
456  return GetFontWeightFromNSFont(font);
457}
458
459////////////////////////////////////////////////////////////////////////////////
460// PlatformFontMac, private:
461
462PlatformFontMac::PlatformFontMac(
463    NativeFont font,
464    base::Optional<SystemFontType> system_font_type)
465    : PlatformFontMac(
466          font,
467          system_font_type,
468          {base::SysNSStringToUTF8([font familyName]), [font pointSize],
469           GetFontStyleFromNSFont(font), GetFontWeightFromNSFont(font)}) {}
470
471PlatformFontMac::PlatformFontMac(
472    NativeFont font,
473    base::Optional<SystemFontType> system_font_type,
474    FontSpec spec)
475    : native_font_([font retain]),
476      system_font_type_(system_font_type),
477      font_spec_(spec) {
478#if DCHECK_IS_ON()
479  DCHECK(system_font_type.has_value() ||
480         SystemFontNames().count(spec.name) == 0)
481      << "Do not pass a system font (" << spec.name << ") to PlatformFontMac; "
482      << "use the SystemFontType constructor. Extend the SystemFontType enum "
483      << "if necessary.";
484#endif  // DCHECK_IS_ON()
485  CalculateMetricsAndInitRenderParams();
486}
487
488PlatformFontMac::~PlatformFontMac() {
489}
490
491void PlatformFontMac::CalculateMetricsAndInitRenderParams() {
492  NSFont* font = native_font_.get();
493  DCHECK(font);
494  ascent_ = ceil([font ascender]);
495  cap_height_ = ceil([font capHeight]);
496
497  // PlatformFontMac once used -[NSLayoutManager defaultLineHeightForFont:] to
498  // initialize |height_|. However, it has a silly rounding bug. Essentially, it
499  // gives round(ascent) + round(descent). E.g. Helvetica Neue at size 16 gives
500  // ascent=15.4634, descent=3.38208 -> 15 + 3 = 18. When the height should be
501  // at least 19. According to the OpenType specification, these values should
502  // simply be added, so do that. Note this uses the already-rounded |ascent_|
503  // to ensure GetBaseline() + descender fits within GetHeight() during layout.
504  height_ = ceil(ascent_ + std::abs([font descender]) + [font leading]);
505
506  FontRenderParamsQuery query;
507  query.families.push_back(font_spec_.name);
508  query.pixel_size = font_spec_.size;
509  query.style = font_spec_.style;
510  query.weight = font_spec_.weight;
511  render_params_ = gfx::GetFontRenderParams(query, nullptr);
512}
513
514NSFont* PlatformFontMac::NSFontWithSpec(FontSpec font_spec) const {
515  // One might think that a font descriptor with the NSFontWeightTrait/
516  // kCTFontWeightTrait trait could be used to look up a font with a specific
517  // weight. That doesn't work, though. You can ask a font for its weight, but
518  // you can't use weight to query for the font.
519  //
520  // The way that does work is to use the old-style integer weight API.
521
522  NSFontManager* font_manager = [NSFontManager sharedFontManager];
523
524  NSFontTraitMask traits = 0;
525  if (font_spec.style & Font::ITALIC)
526    traits |= NSItalicFontMask;
527  // The Mac doesn't support underline as a font trait, so just drop it.
528  // (Underlines must be added as an attribute on an NSAttributedString.) Do not
529  // add NSBoldFontMask here; if it is added then the weight parameter below
530  // will be ignored.
531
532  NSFont* font =
533      [font_manager fontWithFamily:base::SysUTF8ToNSString(font_spec.name)
534                            traits:traits
535                            weight:ToNSFontManagerWeight(font_spec.weight)
536                              size:font_spec.size];
537  if (font)
538    return font;
539
540  // Make one fallback attempt by looking up via font name rather than font
541  // family name. With this API, the available granularity of font weight is
542  // bold/not-bold, but that's what's available.
543  NSFontSymbolicTraits trait_bits = 0;
544  if (font_spec.weight >= Weight::BOLD)
545    trait_bits |= NSFontBoldTrait;
546  if (font_spec.style & Font::ITALIC)
547    trait_bits |= NSFontItalicTrait;
548
549  NSDictionary* attrs = @{
550    NSFontNameAttribute : base::SysUTF8ToNSString(font_spec.name),
551    NSFontTraitsAttribute : @{NSFontSymbolicTrait : @(trait_bits)},
552  };
553  NSFontDescriptor* descriptor =
554      [NSFontDescriptor fontDescriptorWithFontAttributes:attrs];
555
556  font = [NSFont fontWithDescriptor:descriptor size:font_spec.size];
557  if (font)
558    return font;
559
560  // If that doesn't find a font, whip up a system font to stand in for the
561  // specified font.
562  if (@available(macOS 10.11, *)) {
563    font = [NSFont systemFontOfSize:font_spec.size
564                             weight:ToNSFontWeight(font_spec.weight)];
565    return [font_manager convertFont:font toHaveTrait:traits];
566  } else {
567    font = [NSFont systemFontOfSize:font_spec.size];
568    if (font_spec.weight >= Weight::BOLD)
569      traits |= NSBoldFontMask;
570    return [font_manager convertFont:font toHaveTrait:traits];
571  }
572}
573
574////////////////////////////////////////////////////////////////////////////////
575// PlatformFont, public:
576
577// static
578PlatformFont* PlatformFont::CreateDefault() {
579  return new PlatformFontMac(PlatformFontMac::SystemFontType::kGeneral);
580}
581
582// static
583PlatformFont* PlatformFont::CreateFromNativeFont(NativeFont native_font) {
584  return new PlatformFontMac(native_font);
585}
586
587// static
588PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name,
589                                                  int font_size) {
590  return new PlatformFontMac(font_name, font_size);
591}
592
593// static
594PlatformFont* PlatformFont::CreateFromSkTypeface(
595    sk_sp<SkTypeface> typeface,
596    int font_size_pixels,
597    const base::Optional<FontRenderParams>& params) {
598  return new PlatformFontMac(typeface, font_size_pixels, params);
599}
600
601}  // namespace gfx
602