Commit 9fc1063c authored by Olivier Yiptong's avatar Olivier Yiptong Committed by Commit Bot

FontAccess: FontCache-based enumeration of Mac system fonts

Implements the enumeration of system fonts on Mac.
This change calls the CoreText APIs to enumerate the list of fonts
installed on a system.

It has been implemented in FontCache so that it
is accessible in the renderer process due to concerns about expensive
I/O if implemented browser-side.

Caching code will come in a subsequent CL.

Bug: 1043306
Change-Id: Iae9ce6c08174d8b4ced80eda07c795444998c746
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2091597
Commit-Queue: Olivier Yiptong <oyiptong@chromium.org>
Reviewed-by: default avatarChris Harrelson <chrishtr@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#748560}
parent b7b39c2d
...@@ -90,6 +90,12 @@ enum class AlternateFontName { ...@@ -90,6 +90,12 @@ enum class AlternateFontName {
kLastResort kLastResort
}; };
struct FontEnumerationEntry {
String postscript_name;
String full_name;
String family;
};
typedef HashMap<unsigned, typedef HashMap<unsigned,
std::unique_ptr<FontPlatformData>, std::unique_ptr<FontPlatformData>,
WTF::IntHash<unsigned>, WTF::IntHash<unsigned>,
...@@ -248,6 +254,8 @@ class PLATFORM_EXPORT FontCache { ...@@ -248,6 +254,8 @@ class PLATFORM_EXPORT FontCache {
ShouldRetain = kRetain, ShouldRetain = kRetain,
bool subpixel_ascent_descent = false); bool subpixel_ascent_descent = false);
std::vector<FontEnumerationEntry> EnumerateAvailableFonts();
void InvalidateShapeCache(); void InvalidateShapeCache();
static void CrashWithFontInfo(const FontDescription*); static void CrashWithFontInfo(const FontDescription*);
......
...@@ -89,4 +89,57 @@ TEST(FontCache, systemFont) { ...@@ -89,4 +89,57 @@ TEST(FontCache, systemFont) {
} }
#endif #endif
class EnumerationConsumer {
public:
explicit EnumerationConsumer(
const std::vector<FontEnumerationEntry>& expectations) {
for (const auto& f : expectations) {
ps_name_set_.insert(f.postscript_name.Utf8());
full_name_set_.insert(f.full_name.Utf8());
family_set_.insert(f.family.Utf8());
}
}
void Consume(const std::vector<FontEnumerationEntry>& entries) {
for (auto f : entries) {
ps_name_set_.erase(f.postscript_name.Utf8());
full_name_set_.erase(f.full_name.Utf8());
family_set_.erase(f.family.Utf8());
}
}
bool AllExpectationsMet() {
return ps_name_set_.empty() && full_name_set_.empty() &&
family_set_.empty();
}
private:
std::set<std::string> ps_name_set_;
std::set<std::string> full_name_set_;
std::set<std::string> family_set_;
};
TEST(FontCache, EnumerateAvailableFonts) {
FontCache* font_cache = FontCache::GetFontCache();
ASSERT_TRUE(font_cache);
std::vector<FontEnumerationEntry> expectations;
#if defined(OS_MACOSX)
expectations.push_back(FontEnumerationEntry{"Monaco", "Monaco", "Monaco"});
expectations.push_back(
FontEnumerationEntry{"Menlo-Regular", "Menlo Regular", "Menlo"});
expectations.push_back(
FontEnumerationEntry{"Menlo-Bold", "Menlo Bold", "Menlo"});
expectations.push_back(
FontEnumerationEntry{"Menlo-BoldItalic", "Menlo Bold Italic", "Menlo"});
#endif
auto entries = font_cache->EnumerateAvailableFonts();
auto consumer = EnumerationConsumer(expectations);
consumer.Consume(entries);
ASSERT_TRUE(consumer.AllExpectationsMet());
}
} // namespace blink } // namespace blink
...@@ -29,8 +29,11 @@ ...@@ -29,8 +29,11 @@
#import "third_party/blink/renderer/platform/fonts/font_cache.h" #import "third_party/blink/renderer/platform/fonts/font_cache.h"
#import <AppKit/AppKit.h>
#include <memory> #include <memory>
#import <AppKit/AppKit.h>
#import <CoreText/CoreText.h>
#include "base/location.h" #include "base/location.h"
#include "base/mac/foundation_util.h" #include "base/mac/foundation_util.h"
#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/platform.h"
...@@ -59,6 +62,22 @@ ...@@ -59,6 +62,22 @@
inLanguage:(id)useNil; inLanguage:(id)useNil;
@end @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 { namespace blink {
const char kColorEmojiFontMac[] = "Apple Color Emoji"; const char kColorEmojiFontMac[] = "Apple Color Emoji";
...@@ -306,4 +325,34 @@ std::unique_ptr<FontPlatformData> FontCache::CreateFontPlatformData( ...@@ -306,4 +325,34 @@ std::unique_ptr<FontPlatformData> FontCache::CreateFontPlatformData(
return platform_data; return platform_data;
} }
std::vector<FontEnumerationEntry> FontCache::EnumerateAvailableFonts() {
@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 } // namespace blink
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <memory> #include <memory>
#include <utility> #include <utility>
#include "base/logging.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "third_party/blink/public/platform/linux/web_sandbox_support.h" #include "third_party/blink/public/platform/linux/web_sandbox_support.h"
#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/platform.h"
...@@ -245,6 +246,13 @@ sk_sp<SkTypeface> FontCache::CreateTypeface( ...@@ -245,6 +246,13 @@ sk_sp<SkTypeface> FontCache::CreateTypeface(
name.c_str(), font_description.SkiaFontStyle()); name.c_str(), font_description.SkiaFontStyle());
} }
#if !defined(OS_MACOSX)
std::vector<FontEnumerationEntry> FontCache::EnumerateAvailableFonts() {
NOTIMPLEMENTED();
return std::vector<FontEnumerationEntry>();
}
#endif // !defined(OS_MACOSX)
#if !defined(OS_WIN) #if !defined(OS_WIN)
std::unique_ptr<FontPlatformData> FontCache::CreateFontPlatformData( std::unique_ptr<FontPlatformData> FontCache::CreateFontPlatformData(
const FontDescription& font_description, const FontDescription& font_description,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment