summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/fonts/mac
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/fonts/mac')
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/mac/core_text_font_format_support.h1
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm62
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm5
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.h3
-rw-r--r--chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm129
5 files changed, 158 insertions, 42 deletions
diff --git a/chromium/third_party/blink/renderer/platform/fonts/mac/core_text_font_format_support.h b/chromium/third_party/blink/renderer/platform/fonts/mac/core_text_font_format_support.h
index 1816f6f49d7..b5f3ffe9738 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/mac/core_text_font_format_support.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/mac/core_text_font_format_support.h
@@ -9,6 +9,7 @@ namespace blink {
bool CoreTextVersionSupportsVariations();
bool CoreTextVersionSupportsColrCpal();
+
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_MAC_CORE_TEXT_FONT_FORMAT_SUPPORT_H_
diff --git a/chromium/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm b/chromium/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm
index f50fc36281d..fedd1b91424 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm
+++ b/chromium/third_party/blink/renderer/platform/fonts/mac/font_cache_mac.mm
@@ -29,8 +29,11 @@
#import "third_party/blink/renderer/platform/fonts/font_cache.h"
-#import <AppKit/AppKit.h>
#include <memory>
+
+#import <AppKit/AppKit.h>
+#import <CoreText/CoreText.h>
+
#include "base/location.h"
#include "base/mac/foundation_util.h"
#include "third_party/blink/public/platform/platform.h"
@@ -59,6 +62,22 @@
inLanguage:(id)useNil;
@end
+namespace {
+
+NSString* GetLocalizedString(CTFontDescriptorRef fd, CFStringRef attribute) {
+ base::ScopedCFTypeRef<CFStringRef> cf_str(base::mac::CFCast<CFStringRef>(
+ CTFontDescriptorCopyLocalizedAttribute(fd, attribute, nullptr)));
+ return [base::mac::CFToNSCast(cf_str.release()) autorelease];
+}
+
+NSString* GetString(CTFontDescriptorRef fd, CFStringRef attribute) {
+ base::ScopedCFTypeRef<CFStringRef> cf_str(base::mac::CFCast<CFStringRef>(
+ CTFontDescriptorCopyAttribute(fd, attribute)));
+ return [base::mac::CFToNSCast(cf_str.release()) autorelease];
+}
+
+} // namespace
+
namespace blink {
const char kColorEmojiFontMac[] = "Apple Color Emoji";
@@ -221,9 +240,12 @@ scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter(
substitute_font, platform_data.size(), synthetic_bold,
(traits & NSFontItalicTrait) &&
!(substitute_font_traits & NSFontItalicTrait),
- platform_data.Orientation(),
+ platform_data.Orientation(), font_description.FontOpticalSizing(),
nullptr); // No variation paramaters in fallback.
+ if (!alternate_font)
+ return nullptr;
+
return FontDataFromFontPlatformData(alternate_font.get(), kDoNotRetain);
}
@@ -295,11 +317,43 @@ std::unique_ptr<FontPlatformData> FontCache::CreateFontPlatformData(
// the returned FontPlatformData since it will not have a valid SkTypeface.
std::unique_ptr<FontPlatformData> platform_data = FontPlatformDataFromNSFont(
platform_font, size, synthetic_bold, synthetic_italic,
- font_description.Orientation(), font_description.VariationSettings());
- if (!platform_data->Typeface()) {
+ font_description.Orientation(), font_description.FontOpticalSizing(),
+ font_description.VariationSettings());
+ if (!platform_data || !platform_data->Typeface()) {
return nullptr;
}
return platform_data;
}
+std::vector<FontEnumerationEntry> FontCache::EnumeratePlatformAvailableFonts() {
+ DCHECK(RuntimeEnabledFeatures::FontAccessEnabled());
+ @autoreleasepool {
+ std::vector<FontEnumerationEntry> output;
+
+ CFTypeRef values[1] = {kCFBooleanTrue};
+ base::ScopedCFTypeRef<CFDictionaryRef> options(CFDictionaryCreate(
+ kCFAllocatorDefault,
+ (const void**)kCTFontCollectionRemoveDuplicatesOption,
+ (const void**)&values,
+ /*numValues=*/1, &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks));
+ base::ScopedCFTypeRef<CTFontCollectionRef> collection(
+ CTFontCollectionCreateFromAvailableFonts(options));
+
+ base::ScopedCFTypeRef<CFArrayRef> font_descs(
+ CTFontCollectionCreateMatchingFontDescriptors(collection));
+
+ for (CFIndex i = 0; i < CFArrayGetCount(font_descs); ++i) {
+ CTFontDescriptorRef fd = base::mac::CFCast<CTFontDescriptorRef>(
+ CFArrayGetValueAtIndex(font_descs, i));
+ NSString* postscript_name = GetString(fd, kCTFontNameAttribute);
+ NSString* full_name = GetLocalizedString(fd, kCTFontDisplayNameAttribute);
+ NSString* family = GetLocalizedString(fd, kCTFontFamilyNameAttribute);
+ output.push_back(FontEnumerationEntry{String(postscript_name),
+ String(full_name), String(family)});
+ }
+ return output;
+ }
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm b/chromium/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm
index 8d01704041c..cf25ba022f2 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm
+++ b/chromium/third_party/blink/renderer/platform/fonts/mac/font_matcher_mac.mm
@@ -46,7 +46,7 @@
namespace {
-static CGFloat toYosemiteFontWeight(blink::FontSelectionValue font_weight) {
+static CGFloat toFontWeight(blink::FontSelectionValue font_weight) {
static uint64_t ns_font_weights[] = {
0xbfe99999a0000000, // NSFontWeightUltraLight
0xbfe3333340000000, // NSFontWeightThin
@@ -181,8 +181,7 @@ NSFont* MatchNSFontFamily(const AtomicString& desired_family_string,
// On OSX 10.10+, the default system font has more weights.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
- font = [NSFont systemFontOfSize:size
- weight:toYosemiteFontWeight(desired_weight)];
+ font = [NSFont systemFontOfSize:size weight:toFontWeight(desired_weight)];
#pragma clang diagnostic pop
if (desired_traits & IMPORTANT_FONT_TRAITS)
diff --git a/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.h b/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.h
index b1224beff2c..cd0e338cdb5 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.h
+++ b/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.h
@@ -31,6 +31,8 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_MAC_FONT_PLATFORM_DATA_MAC_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_MAC_FONT_PLATFORM_DATA_MAC_H_
+#include "third_party/blink/renderer/platform/fonts/font_optical_sizing.h"
+
#include <memory>
@class NSFont;
@@ -47,6 +49,7 @@ std::unique_ptr<FontPlatformData> FontPlatformDataFromNSFont(
bool synthetic_bold,
bool synthetic_italic,
FontOrientation,
+ OpticalSizing,
FontVariationSettings*);
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm b/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm
index 16bcce4ba40..9bc59e46e5e 100644
--- a/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm
+++ b/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm
@@ -27,21 +27,26 @@
#import <AvailabilityMacros.h>
#include "base/mac/foundation_util.h"
-#include "base/mac/scoped_cftyperef.h"
#include "base/mac/scoped_nsobject.h"
#include "base/stl_util.h"
#import "third_party/blink/public/platform/mac/web_sandbox_support.h"
#import "third_party/blink/public/platform/platform.h"
#import "third_party/blink/renderer/platform/fonts/font.h"
#import "third_party/blink/renderer/platform/fonts/font_platform_data.h"
+#import "third_party/blink/renderer/platform/fonts/mac/core_text_font_format_support.h"
#import "third_party/blink/renderer/platform/fonts/opentype/font_settings.h"
#import "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_face.h"
#import "third_party/blink/renderer/platform/web_test_support.h"
#import "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#import "third_party/skia/include/core/SkFont.h"
#import "third_party/skia/include/core/SkStream.h"
+#import "third_party/skia/include/core/SkTypes.h"
#import "third_party/skia/include/ports/SkTypeface_mac.h"
+namespace {
+constexpr SkFourByteTag kOpszTag = SkSetFourByteTag('o', 'p', 's', 'z');
+}
+
namespace blink {
static bool CanLoadInProcess(NSFont* ns_font) {
@@ -53,10 +58,10 @@ static bool CanLoadInProcess(NSFont* ns_font) {
return ![font_name isEqualToString:@"LastResort"];
}
-static CTFontDescriptorRef CascadeToLastResortFontDescriptor() {
- static CTFontDescriptorRef descriptor;
- if (descriptor)
- return descriptor;
+static CFDictionaryRef CascadeToLastResortFontAttributes() {
+ static CFDictionaryRef attributes;
+ if (attributes)
+ return attributes;
base::ScopedCFTypeRef<CTFontDescriptorRef> last_resort(
CTFontDescriptorCreateWithNameAndSize(CFSTR("LastResort"), 0));
@@ -67,13 +72,10 @@ static CTFontDescriptorRef CascadeToLastResortFontDescriptor() {
const void* keys[] = {kCTFontCascadeListAttribute};
const void* values[] = {values_array};
- base::ScopedCFTypeRef<CFDictionaryRef> attributes(CFDictionaryCreate(
+ attributes = CFDictionaryCreate(
kCFAllocatorDefault, keys, values, base::size(keys),
- &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
-
- descriptor = CTFontDescriptorCreateWithAttributes(attributes);
-
- return descriptor;
+ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ return attributes;
}
static sk_sp<SkTypeface> LoadFromBrowserProcess(NSFont* ns_font,
@@ -88,20 +90,23 @@ static sk_sp<SkTypeface> LoadFromBrowserProcess(NSFont* ns_font,
return nullptr;
}
- CGFontRef loaded_cg_font;
+ base::ScopedCFTypeRef<CTFontDescriptorRef> loaded_data_descriptor;
uint32_t font_id;
if (!sandbox_support->LoadFont(base::mac::NSToCFCast(ns_font),
- &loaded_cg_font, &font_id)) {
+ &loaded_data_descriptor, &font_id)) {
// TODO crbug.com/461279: Make this appear in the inspector console?
DLOG(ERROR)
<< "Loading user font \"" << [[ns_font familyName] UTF8String]
<< "\" from non system location failed. Corrupt or missing font file?";
return nullptr;
}
- base::ScopedCFTypeRef<CGFontRef> cg_font(loaded_cg_font);
- base::ScopedCFTypeRef<CTFontRef> ct_font(CTFontCreateWithGraphicsFont(
- cg_font, text_size, 0, CascadeToLastResortFontDescriptor()));
- sk_sp<SkTypeface> return_font(SkCreateTypefaceFromCTFont(ct_font, cg_font));
+
+ base::ScopedCFTypeRef<CTFontDescriptorRef> data_descriptor_with_cascade(
+ CTFontDescriptorCreateCopyWithAttributes(
+ loaded_data_descriptor, CascadeToLastResortFontAttributes()));
+ base::ScopedCFTypeRef<CTFontRef> ct_font(CTFontCreateWithFontDescriptor(
+ data_descriptor_with_cascade.get(), text_size, 0));
+ sk_sp<SkTypeface> return_font = SkMakeTypefaceFromCTFont(ct_font);
if (!return_font.get())
// TODO crbug.com/461279: Make this appear in the inspector console?
@@ -117,11 +122,12 @@ std::unique_ptr<FontPlatformData> FontPlatformDataFromNSFont(
bool synthetic_bold,
bool synthetic_italic,
FontOrientation orientation,
+ OpticalSizing optical_sizing,
FontVariationSettings* variation_settings) {
DCHECK(ns_font);
sk_sp<SkTypeface> typeface;
if (CanLoadInProcess(ns_font)) {
- typeface.reset(SkCreateTypefaceFromCTFont(base::mac::NSToCFCast(ns_font)));
+ typeface = SkMakeTypefaceFromCTFont(base::mac::NSToCFCast(ns_font));
} else {
// In process loading fails for cases where third party font manager
// software registers fonts in non system locations such as /Library/Fonts
@@ -129,26 +135,79 @@ std::unique_ptr<FontPlatformData> FontPlatformDataFromNSFont(
typeface = LoadFromBrowserProcess(ns_font, size);
}
- if (variation_settings && variation_settings->size() < UINT16_MAX) {
- SkFontArguments::Axis axes[variation_settings->size()];
- for (size_t i = 0; i < variation_settings->size(); ++i) {
- AtomicString feature_tag = variation_settings->at(i).Tag();
- axes[i] = {AtomicStringToFourByteTag(feature_tag),
- SkFloatToScalar(variation_settings->at(i).Value())};
+ auto make_typeface_fontplatformdata = [&typeface, &size, &synthetic_bold,
+ &synthetic_italic, &orientation]() {
+ return std::make_unique<FontPlatformData>(
+ std::move(typeface), std::string(), size, synthetic_bold,
+ synthetic_italic, orientation);
+ };
+
+ wtf_size_t valid_configured_axes =
+ variation_settings && variation_settings->size() < UINT16_MAX
+ ? variation_settings->size()
+ : 0;
+
+ // No variable font requested, return static font.
+ if (!valid_configured_axes && optical_sizing == kNoneOpticalSizing)
+ return make_typeface_fontplatformdata();
+
+ if (!typeface)
+ return nullptr;
+
+ int existing_axes = typeface->getVariationDesignPosition(nullptr, 0);
+ // Don't apply variation parameters if the font does not have axes or we
+ // fail to retrieve the existing ones.
+ if (existing_axes <= 0)
+ return make_typeface_fontplatformdata();
+
+ Vector<SkFontArguments::VariationPosition::Coordinate> coordinates_to_set;
+ coordinates_to_set.resize(existing_axes);
+
+ if (typeface->getVariationDesignPosition(coordinates_to_set.data(),
+ existing_axes) != existing_axes) {
+ return make_typeface_fontplatformdata();
+ }
+
+ // Iterate over the font's axes and find a missing tag from variation
+ // settings, special case opsz, track the number of axes reconfigured.
+ bool axes_reconfigured = false;
+ for (auto& coordinate : coordinates_to_set) {
+ // Set opsz to font size but allow having it overriden by
+ // font-variation-settings in case it has 'opsz'.
+ if (coordinate.axis == kOpszTag && optical_sizing == kAutoOpticalSizing) {
+ if (coordinate.value != SkFloatToScalar(size)) {
+ coordinate.value = SkFloatToScalar(size);
+ axes_reconfigured = true;
+ }
+ }
+ FontVariationAxis found_variation_setting(AtomicString(), 0);
+ if (variation_settings &&
+ variation_settings->FindPair(FourByteTagToAtomicString(coordinate.axis),
+ &found_variation_setting)) {
+ if (coordinate.value != found_variation_setting.Value()) {
+ coordinate.value = found_variation_setting.Value();
+ axes_reconfigured = true;
+ }
}
- sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
- // TODO crbug.com/670246: Refactor this to a future Skia API that acccepts
- // axis parameters on system fonts directly.
- typeface = fm->makeFromStream(
- typeface->openStream(nullptr)->duplicate(),
- SkFontArguments().setAxes(axes, variation_settings->size()));
}
- return std::make_unique<FontPlatformData>(
- std::move(typeface),
- std::string(), // family_ doesn't exist on Mac, this avoids conversion
- // from NSString which requires including a //base header
- size, synthetic_bold, synthetic_italic, orientation);
+ if (!axes_reconfigured) {
+ // No variable axes touched, return the previous typeface.
+ return make_typeface_fontplatformdata();
+ }
+
+ SkFontArguments::VariationPosition variation_design_position{
+ coordinates_to_set.data(), coordinates_to_set.size()};
+
+ sk_sp<SkTypeface> cloned_typeface(typeface->makeClone(
+ SkFontArguments().setVariationDesignPosition(variation_design_position)));
+
+ if (!cloned_typeface) {
+ // Applying varition parameters failed, return original typeface.
+ return make_typeface_fontplatformdata();
+ }
+ typeface = cloned_typeface;
+ return make_typeface_fontplatformdata();
}
void FontPlatformData::SetupSkFont(SkFont* skfont,