Diff
Modified: trunk/Source/WebCore/ChangeLog (201550 => 201551)
--- trunk/Source/WebCore/ChangeLog 2016-06-01 11:57:55 UTC (rev 201550)
+++ trunk/Source/WebCore/ChangeLog 2016-06-01 14:29:30 UTC (rev 201551)
@@ -1,3 +1,85 @@
+2016-05-31 Antti Koivisto <[email protected]>
+
+ Precache primary font in a secondary thread
+ https://bugs.webkit.org/show_bug.cgi?id=158243
+
+ Reviewed by Andreas Kling.
+
+ We know the font families and descriptions to use on style resolution. The actual fonts are only needed for
+ layout. There is often time to load and cache fonts asynchronously before they are accessed. This can substantially
+ reduce font related workload in the main thread.
+
+ * css/CSSFontFace.cpp:
+ (WebCore::CSSFontFace::font):
+ (WebCore::CSSFontFace::resolveFamilies):
+ (WebCore::CSSFontFace::hasSVGFontFaceSource):
+ * css/CSSFontFace.h:
+ * css/CSSFontFaceSource.cpp:
+ (WebCore::CSSFontFaceSource::font):
+ (WebCore::CSSFontFaceSource::url):
+ (WebCore::CSSFontFaceSource::isSVGFontFaceSource):
+ * css/CSSFontFaceSource.h:
+ * css/CSSFontSelector.cpp:
+ (WebCore::CSSFontSelector::fallbackFontAt):
+ (WebCore::CSSFontSelector::resolveFamilies):
+
+ Add a function for resolving font families of a cascade to their final values.
+
+ * css/CSSFontSelector.h:
+ * css/CSSSegmentedFontFace.cpp:
+ (WebCore::CSSSegmentedFontFace::fontRanges):
+ (WebCore::CSSSegmentedFontFace::resolveFamilies):
+ * css/CSSSegmentedFontFace.h:
+ * platform/graphics/FontCache.cpp:
+ (WebCore::fontPlatformDataCache):
+ (WebCore::precacheTasksInProgress):
+ (WebCore::alternateFamilyName):
+ (WebCore::FontCache::getCachedFontPlatformData):
+ (WebCore::FontCache::invalidate):
+ (WebCore::FontCache::precache):
+
+ Precache fonts by trying to load them asyncronously one by one. On success the font is cached into font platform data cache.
+
+ (WebCore::FontCache::similarFont):
+ * platform/graphics/FontCache.h:
+ * platform/graphics/FontCascade.cpp:
+ (WebCore::pruneSystemFallbackFonts):
+ (WebCore::precachePrimaryFamily):
+
+ When initializing a new font cascade resolve any platform fonts to their actual names using FontSelector,
+ then precache the primary font for the cascade.
+
+ Web fonts are ignored for now.
+
+ (WebCore::retrieveOrAddCachedFonts):
+ * platform/graphics/FontSelector.h:
+ (WebCore::FontSelector::~FontSelector):
+ * platform/graphics/cocoa/FontCacheCoreText.cpp:
+ (WebCore::FontCache::setFontWhitelist):
+ (WebCore::fontWithFamily):
+ (WebCore::autoActivateFont):
+ (WebCore::createFontPlatformDataThreadSafe):
+
+ Factor thread safe part of createFontPlatformData to a function.
+
+ (WebCore::FontCache::createFontPlatformData):
+
+ Do the main thread only hash lookups here then call to createFontPlatformDataThreadSafe.
+
+ (WebCore::fallbackDedupSet):
+ (WebCore::FontCache::systemFallbackForCharacters):
+ (WebCore::FontCache::platformPrecache):
+
+ Try to initialize font asynchronously in a dispatch queue, call completion handler on success or failure.
+
+ (WebCore::FontCache::platformCancelPrecache):
+
+ Cancel ongoing precache operation.
+
+ (WebCore::platformFontLookupWithFamily): Deleted.
+
+ This was inlined to the only client, fontWithFamily.
+
2016-06-01 Adam Bergkvist <[email protected]>
WebRTC: Add RTCRtpTransceiver interface and RTCPeerConnection.addTransceiver()
Modified: trunk/Source/WebCore/css/CSSFontFace.cpp (201550 => 201551)
--- trunk/Source/WebCore/css/CSSFontFace.cpp 2016-06-01 11:57:55 UTC (rev 201550)
+++ trunk/Source/WebCore/css/CSSFontFace.cpp 2016-06-01 14:29:30 UTC (rev 201551)
@@ -520,6 +520,19 @@
return nullptr;
}
+Vector<ResolvedFontFamily> CSSFontFace::resolveFamilies() const
+{
+ Vector<ResolvedFontFamily> result;
+ for (auto& source : m_sources) {
+ if (source->familyNameOrURI().isEmpty())
+ continue;
+ if (source->status() == CSSFontFaceSource::Status::Failure)
+ continue;
+ result.append({ source->familyNameOrURI(), source->url() });
+ }
+ return result;
+}
+
#if ENABLE(SVG_FONTS)
bool CSSFontFace::hasSVGFontFaceSource() const
{
Modified: trunk/Source/WebCore/css/CSSFontFace.h (201550 => 201551)
--- trunk/Source/WebCore/css/CSSFontFace.h 2016-06-01 11:57:55 UTC (rev 201550)
+++ trunk/Source/WebCore/css/CSSFontFace.h 2016-06-01 14:29:30 UTC (rev 201551)
@@ -27,6 +27,7 @@
#include "CSSFontFaceRule.h"
#include "FontFeatureSettings.h"
+#include "FontSelector.h"
#include "TextFlags.h"
#include <memory>
#include <wtf/Forward.h>
@@ -135,6 +136,8 @@
// We don't guarantee that the FontFace wrapper will be the same every time you ask for it.
Ref<FontFace> wrapper();
+ Vector<ResolvedFontFamily> resolveFamilies() const;
+
#if ENABLE(SVG_FONTS)
bool hasSVGFontFaceSource() const;
#endif
Modified: trunk/Source/WebCore/css/CSSFontFaceSource.cpp (201550 => 201551)
--- trunk/Source/WebCore/css/CSSFontFaceSource.cpp 2016-06-01 11:57:55 UTC (rev 201550)
+++ trunk/Source/WebCore/css/CSSFontFaceSource.cpp 2016-06-01 14:29:30 UTC (rev 201551)
@@ -188,6 +188,13 @@
return nullptr;
}
+Optional<URL> CSSFontFaceSource::url() const
+{
+ if (!m_font)
+ return Nullopt;
+ return m_font->url();
+}
+
#if ENABLE(SVG_FONTS)
bool CSSFontFaceSource::isSVGFontFaceSource() const
{
Modified: trunk/Source/WebCore/css/CSSFontFaceSource.h (201550 => 201551)
--- trunk/Source/WebCore/css/CSSFontFaceSource.h 2016-06-01 11:57:55 UTC (rev 201550)
+++ trunk/Source/WebCore/css/CSSFontFaceSource.h 2016-06-01 14:29:30 UTC (rev 201551)
@@ -28,6 +28,7 @@
#include "CachedFontClient.h"
#include "CachedResourceHandle.h"
+#include "URL.h"
#include <runtime/ArrayBufferView.h>
#include <wtf/text/AtomicString.h>
@@ -71,6 +72,8 @@
bool isSVGFontFaceSource() const;
#endif
+ Optional<URL> url() const;
+
private:
void fontLoaded(CachedFont&) override;
Modified: trunk/Source/WebCore/css/CSSFontSelector.cpp (201550 => 201551)
--- trunk/Source/WebCore/css/CSSFontSelector.cpp 2016-06-01 11:57:55 UTC (rev 201550)
+++ trunk/Source/WebCore/css/CSSFontSelector.cpp 2016-06-01 14:29:30 UTC (rev 201551)
@@ -334,4 +334,22 @@
return FontCache::singleton().fontForFamily(fontDescription, settings->pictographFontFamily());
}
+Vector<ResolvedFontFamily> CSSFontSelector::resolveFamilies(const Vector<AtomicString>& families, const FontDescription& fontDescription, UChar32 character)
+{
+ Vector<ResolvedFontFamily> result;
+
+ for (auto& family : families) {
+ if (family.isEmpty())
+ continue;
+ auto* segmentedFace = m_cssFontFaceSet->getFontFace(fontDescription.traitsMask(), family);
+ if (!segmentedFace) {
+ result.append({ resolveGenericFamily(m_document, fontDescription, family), { } });
+ continue;
+ }
+ result.appendVector(segmentedFace->resolveFamilies(character));
+ }
+
+ return result;
}
+
+}
Modified: trunk/Source/WebCore/css/CSSFontSelector.h (201550 => 201551)
--- trunk/Source/WebCore/css/CSSFontSelector.h 2016-06-01 11:57:55 UTC (rev 201550)
+++ trunk/Source/WebCore/css/CSSFontSelector.h 2016-06-01 14:29:30 UTC (rev 201551)
@@ -64,6 +64,8 @@
size_t fallbackFontCount() override;
RefPtr<Font> fallbackFontAt(const FontDescription&, size_t) override;
+ Vector<ResolvedFontFamily> resolveFamilies(const Vector<AtomicString>&, const FontDescription&, UChar32) override;
+
void clearDocument();
void addFontFaceRule(StyleRuleFontFace&, bool isInitiatingElementInUserAgentShadowTree);
Modified: trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp (201550 => 201551)
--- trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp 2016-06-01 11:57:55 UTC (rev 201550)
+++ trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp 2016-06-01 14:29:30 UTC (rev 201551)
@@ -138,4 +138,20 @@
return result;
}
+Vector<ResolvedFontFamily> CSSSegmentedFontFace::resolveFamilies(UChar32 character) const
+{
+ for (auto& face : m_fontFaces) {
+ bool inRange = face->ranges().isEmpty();
+ for (auto& range : face->ranges()) {
+ if (character >= range.from && character <= range.to) {
+ inRange = true;
+ break;
+ }
+ }
+ if (inRange)
+ return face->resolveFamilies();
+ }
+ return { };
}
+
+}
Modified: trunk/Source/WebCore/css/CSSSegmentedFontFace.h (201550 => 201551)
--- trunk/Source/WebCore/css/CSSSegmentedFontFace.h 2016-06-01 11:57:55 UTC (rev 201550)
+++ trunk/Source/WebCore/css/CSSSegmentedFontFace.h 2016-06-01 14:29:30 UTC (rev 201551)
@@ -28,6 +28,7 @@
#include "CSSFontFace.h"
#include "FontCache.h"
+#include "FontSelector.h"
#include <wtf/HashMap.h>
#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
@@ -57,6 +58,8 @@
void ref() override { RefCounted<CSSSegmentedFontFace>::ref(); }
void deref() override { RefCounted<CSSSegmentedFontFace>::deref(); }
+ Vector<ResolvedFontFamily> resolveFamilies(UChar32 character) const;
+
private:
CSSSegmentedFontFace();
void fontLoaded(CSSFontFace&) override;
Modified: trunk/Source/WebCore/platform/graphics/FontCache.cpp (201550 => 201551)
--- trunk/Source/WebCore/platform/graphics/FontCache.cpp 2016-06-01 11:57:55 UTC (rev 201550)
+++ trunk/Source/WebCore/platform/graphics/FontCache.cpp 2016-06-01 14:29:30 UTC (rev 201551)
@@ -106,6 +106,7 @@
, m_fontFaceFeatures(fontFaceFeatures ? *fontFaceFeatures : FontFeatureSettings())
, m_fontFaceVariantSettings(fontFaceVariantSettings ? *fontFaceVariantSettings : FontVariantSettings())
{ }
+ FontPlatformDataCacheKey(const FontPlatformDataCacheKey&) = default;
explicit FontPlatformDataCacheKey(HashTableDeletedValueType t)
: m_fontDescriptionKey(t)
@@ -159,6 +160,16 @@
return cache;
}
+#if PLATFORM(COCOA) && ENABLE(PLATFORM_FONT_LOOKUP)
+using PrecacheMap = HashMap<FontPlatformDataCacheKey, FontCache::PrecacheTask*, FontPlatformDataCacheKeyHash, WTF::SimpleClassHashTraits<FontPlatformDataCacheKey>>;
+
+static PrecacheMap& precacheTasksInProgress()
+{
+ static NeverDestroyed<PrecacheMap> map;
+ return map;
+}
+#endif
+
static AtomicString alternateFamilyName(const AtomicString& familyName)
{
switch (familyName.length()) {
@@ -243,6 +254,12 @@
FontPlatformDataCacheKey key(familyName, fontDescription, fontFaceFeatures, fontFaceVariantSettings);
+#if PLATFORM(COCOA) && ENABLE(PLATFORM_FONT_LOOKUP)
+ auto* precacheTask = precacheTasksInProgress().get(key);
+ if (precacheTask)
+ platformCancelPrecache(*precacheTask);
+#endif
+
auto addResult = fontPlatformDataCache().add(key, nullptr);
FontPlatformDataCache::iterator it = addResult.iterator;
if (addResult.isNewEntry) {
@@ -489,6 +506,67 @@
purgeInactiveFontData();
}
+#if PLATFORM(COCOA) && ENABLE(PLATFORM_FONT_LOOKUP)
+void FontCache::precache(const Vector<AtomicString>& resolvedFamilies, const FontDescription& fontDescription)
+{
+ if (resolvedFamilies.isEmpty())
+ return;
+ auto& family = resolvedFamilies.first();
+
+ FontPlatformDataCacheKey key(family, fontDescription, nullptr, nullptr);
+
+ // Maybe we have it already?
+ auto it = fontPlatformDataCache().find(key);
+ if (it != fontPlatformDataCache().end()) {
+ if (it->value)
+ return;
+
+ // We already know this font isn't available. Try the next.
+ Vector<AtomicString> remainingFamilies;
+ remainingFamilies.appendRange(resolvedFamilies.begin() + 1, resolvedFamilies.end());
+ precache(remainingFamilies, fontDescription);
+ return;
+ }
+
+ auto taskAdd = precacheTasksInProgress().add(key, nullptr);
+ if (!taskAdd.isNewEntry)
+ return;
+
+ auto& task = platformPrecache(family, fontDescription, [key, resolvedFamilies, fontDescription] (auto platformData, bool wasCanceled) {
+ precacheTasksInProgress().remove(key);
+
+ if (wasCanceled)
+ return;
+
+ if (platformData) {
+ auto r = fontPlatformDataCache().add(key, WTFMove(platformData));
+ fprintf(stderr, "success %d\n", r.isNewEntry);
+ return;
+ }
+
+ // Didn't find the font. Try the next one.
+ Vector<AtomicString> remainingFamilies;
+
+ auto alternateName = alternateFamilyName(resolvedFamilies.first());
+ if (!alternateName.isNull()) {
+ remainingFamilies = resolvedFamilies;
+ remainingFamilies.first() = alternateName;
+ } else {
+ fontPlatformDataCache().add(key, nullptr);
+ remainingFamilies.appendRange(resolvedFamilies.begin() + 1, resolvedFamilies.end());
+ }
+
+ singleton().precache(remainingFamilies, fontDescription);
+ });
+
+ taskAdd.iterator->value = &task;
+}
+#else
+void FontCache::precache(const Vector<AtomicString>&, const FontDescription&)
+{
+}
+#endif
+
#if !PLATFORM(COCOA)
RefPtr<Font> FontCache::similarFont(const FontDescription&, const AtomicString&)
{
Modified: trunk/Source/WebCore/platform/graphics/FontCache.h (201550 => 201551)
--- trunk/Source/WebCore/platform/graphics/FontCache.h 2016-06-01 11:57:55 UTC (rev 201550)
+++ trunk/Source/WebCore/platform/graphics/FontCache.h 2016-06-01 14:29:30 UTC (rev 201551)
@@ -193,6 +193,8 @@
WEBCORE_EXPORT Ref<Font> fontForPlatformData(const FontPlatformData&);
RefPtr<Font> similarFont(const FontDescription&, const AtomicString& family);
+ void precache(const Vector<AtomicString>& resolvedFamilies, const FontDescription&);
+
void addClient(FontSelector&);
void removeClient(FontSelector&);
@@ -212,6 +214,8 @@
RefPtr<OpenTypeVerticalData> verticalData(const FontPlatformData&);
#endif
+ struct PrecacheTask;
+
private:
FontCache();
~FontCache() = delete;
@@ -227,6 +231,12 @@
#endif
std::unique_ptr<FontPlatformData> createFontPlatformData(const FontDescription&, const AtomicString& family, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings);
+#if PLATFORM(COCOA) && ENABLE(PLATFORM_FONT_LOOKUP)
+ using PrecacheCompletionHandler = std::function<void (std::unique_ptr<FontPlatformData>, bool wasCanceled)>;
+ PrecacheTask& platformPrecache(const AtomicString& family, const FontDescription&, PrecacheCompletionHandler&&);
+ void platformCancelPrecache(PrecacheTask&);
+#endif
+
Timer m_purgeTimer;
#if PLATFORM(COCOA)
Modified: trunk/Source/WebCore/platform/graphics/FontCascade.cpp (201550 => 201551)
--- trunk/Source/WebCore/platform/graphics/FontCascade.cpp 2016-06-01 11:57:55 UTC (rev 201550)
+++ trunk/Source/WebCore/platform/graphics/FontCascade.cpp 2016-06-01 14:29:30 UTC (rev 201551)
@@ -261,6 +261,29 @@
entry->fonts->pruneSystemFallbacks();
}
+static void precachePrimaryFamily(const FontCascadeDescription& fontDescription, FontSelector& fontSelector)
+{
+ Vector<AtomicString> families;
+ for (unsigned i = 0; i < fontDescription.familyCount(); ++i)
+ families.append(fontDescription.familyAt(i));
+
+ // Primary family lookup falls back to the standard family.
+ families.append(standardFamily);
+
+ auto resolvedPrimaryFamilies = fontSelector.resolveFamilies(families, fontDescription, ' ');
+
+ Vector<AtomicString> resolvedPrimaryFamilyNames;
+ for (auto& family : resolvedPrimaryFamilies) {
+ // This doesn't handle web fonts for now.
+ if (family.url)
+ break;
+ resolvedPrimaryFamilyNames.append(family.name);
+ }
+
+ // Asynchronously find first available font and precache it so it is likely to be available when needed.
+ FontCache::singleton().precache(resolvedPrimaryFamilyNames, fontDescription);
+}
+
static Ref<FontCascadeFonts> retrieveOrAddCachedFonts(const FontCascadeDescription& fontDescription, RefPtr<FontSelector>&& fontSelector)
{
auto key = makeFontCascadeCacheKey(fontDescription, fontSelector.get());
@@ -270,6 +293,9 @@
if (!addResult.isNewEntry && keysMatch(addResult.iterator->value->key, key))
return addResult.iterator->value->fonts.get();
+ if (fontSelector)
+ precachePrimaryFamily(fontDescription, *fontSelector);
+
auto& newEntry = addResult.iterator->value;
newEntry = std::make_unique<FontCascadeCacheEntry>(WTFMove(key), FontCascadeFonts::create(WTFMove(fontSelector)));
Ref<FontCascadeFonts> glyphs = newEntry->fonts.get();
Modified: trunk/Source/WebCore/platform/graphics/FontSelector.h (201550 => 201551)
--- trunk/Source/WebCore/platform/graphics/FontSelector.h 2016-06-01 11:57:55 UTC (rev 201550)
+++ trunk/Source/WebCore/platform/graphics/FontSelector.h 2016-06-01 14:29:30 UTC (rev 201551)
@@ -26,6 +26,7 @@
#pragma once
#include "FontRanges.h"
+#include "URL.h"
#include <wtf/Forward.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -44,6 +45,11 @@
virtual bool isLoading() const = 0;
};
+struct ResolvedFontFamily {
+ AtomicString name;
+ Optional<URL> url;
+};
+
class FontSelector : public RefCounted<FontSelector> {
public:
virtual ~FontSelector() { }
@@ -58,6 +64,8 @@
virtual void registerForInvalidationCallbacks(FontSelectorClient&) = 0;
virtual void unregisterForInvalidationCallbacks(FontSelectorClient&) = 0;
+ virtual Vector<ResolvedFontFamily> resolveFamilies(const Vector<AtomicString>& families, const FontDescription&, UChar32 character) = 0;
+
virtual unsigned uniqueId() const = 0;
virtual unsigned version() const = 0;
};
Modified: trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp (201550 => 201551)
--- trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp 2016-06-01 11:57:55 UTC (rev 201550)
+++ trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp 2016-06-01 14:29:30 UTC (rev 201551)
@@ -34,6 +34,8 @@
#include <wtf/HashSet.h>
#include <wtf/MainThread.h>
#include <wtf/NeverDestroyed.h>
+#include <wtf/RunLoop.h>
+#include <wtf/WorkQueue.h>
namespace WebCore {
@@ -660,27 +662,19 @@
whitelist.add(item);
}
-#if ENABLE(PLATFORM_FONT_LOOKUP)
-static RetainPtr<CTFontRef> platformFontLookupWithFamily(const AtomicString& family, CTFontSymbolicTraits requestedTraits, FontWeight weight, float size)
+static RetainPtr<CTFontRef> fontWithFamily(const String& family, CTFontSymbolicTraits desiredTraits, FontWeight weight, const FontFeatureSettings& featureSettings, const FontVariantSettings& variantSettings, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings, const TextRenderingMode& textRenderingMode, float size, bool isWhitelisted)
{
- const auto& whitelist = fontWhitelist();
- if (whitelist.size() && !whitelist.contains(family))
- return nullptr;
-
- return adoptCF(CTFontCreateForCSS(family.string().createCFString().get(), toCoreTextFontWeight(weight), requestedTraits, size));
-}
-#endif
-
-static RetainPtr<CTFontRef> fontWithFamily(const AtomicString& family, CTFontSymbolicTraits desiredTraits, FontWeight weight, const FontFeatureSettings& featureSettings, const FontVariantSettings& variantSettings, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings, const TextRenderingMode& textRenderingMode, float size)
-{
if (family.isEmpty())
return nullptr;
RetainPtr<CTFontRef> foundFont = platformFontWithFamilySpecialCase(family, weight, desiredTraits, size);
if (!foundFont) {
#if ENABLE(PLATFORM_FONT_LOOKUP)
- foundFont = platformFontLookupWithFamily(family, desiredTraits, weight, size);
+ if (!isWhitelisted)
+ return nullptr;
+ foundFont = adoptCF(CTFontCreateForCSS(family.createCFString().get(), toCoreTextFontWeight(weight), desiredTraits, size));
#else
+ UNUSED_PARAM(isWhitelisted);
foundFont = platformFontWithFamily(family, desiredTraits, weight, textRenderingMode, size);
#endif
}
@@ -719,24 +713,24 @@
}
#endif
-std::unique_ptr<FontPlatformData> FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings)
+// This is only thread safe with ENABLE(PLATFORM_FONT_LOOKUP) due to fontWithFamily() implementation
+static std::unique_ptr<FontPlatformData> createFontPlatformDataThreadSafe(const FontDescription& fontDescription, const String& family, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings, bool isWhitelisted, bool shouldAutoActivateIfNeeded)
{
CTFontSymbolicTraits traits = computeTraits(fontDescription);
float size = fontDescription.computedPixelSize();
- RetainPtr<CTFontRef> font = fontWithFamily(family, traits, fontDescription.weight(), fontDescription.featureSettings(), fontDescription.variantSettings(), fontFaceFeatures, fontFaceVariantSettings, fontDescription.textRenderingMode(), size);
+ RetainPtr<CTFontRef> font = fontWithFamily(family, traits, fontDescription.weight(), fontDescription.featureSettings(), fontDescription.variantSettings(), fontFaceFeatures, fontFaceVariantSettings, fontDescription.textRenderingMode(), size, isWhitelisted);
#if PLATFORM(MAC)
- if (!font) {
- if (!shouldAutoActivateFontIfNeeded(family))
- return nullptr;
-
+ if (!font && shouldAutoActivateIfNeeded) {
// Auto activate the font before looking for it a second time.
// Ignore the result because we want to use our own algorithm to actually find the font.
- autoActivateFont(family.string(), size);
+ autoActivateFont(family, size);
- font = fontWithFamily(family, traits, fontDescription.weight(), fontDescription.featureSettings(), fontDescription.variantSettings(), fontFaceFeatures, fontFaceVariantSettings, fontDescription.textRenderingMode(), size);
+ font = fontWithFamily(family, traits, fontDescription.weight(), fontDescription.featureSettings(), fontDescription.variantSettings(), fontFaceFeatures, fontFaceVariantSettings, fontDescription.textRenderingMode(), size, isWhitelisted);
}
+#else
+ UNUSED_PARAM(shouldAutoActivateIfNeeded);
#endif
if (!font)
@@ -748,6 +742,19 @@
return std::make_unique<FontPlatformData>(font.get(), size, syntheticBold, syntheticOblique, fontDescription.orientation(), fontDescription.widthVariant(), fontDescription.textRenderingMode());
}
+std::unique_ptr<FontPlatformData> FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings)
+{
+ const auto& whitelist = fontWhitelist();
+ bool isWhitelisted = whitelist.isEmpty() || whitelist.contains(family);
+
+ bool shouldAutoActivateIfNeeded = false;
+#if PLATFORM(MAC)
+ shouldAutoActivateIfNeeded = shouldAutoActivateFontIfNeeded(family);
+#endif
+
+ return createFontPlatformDataThreadSafe(fontDescription, family, fontFaceFeatures, fontFaceVariantSettings, isWhitelisted, shouldAutoActivateIfNeeded);
+}
+
typedef HashSet<RetainPtr<CTFontRef>, WTF::RetainPtrObjectHash<CTFontRef>, WTF::RetainPtrObjectHashTraits<CTFontRef>> FallbackDedupSet;
static FallbackDedupSet& fallbackDedupSet()
{
@@ -796,4 +803,53 @@
return fontForPlatformData(alternateFont);
}
+#if ENABLE(PLATFORM_FONT_LOOKUP)
+struct FontCache::PrecacheTask {
+ String family;
+ FontDescription fontDescription;
+ bool shouldAutoActivateIfNeeded { false };
+ bool isWhitelisted { true };
+ PrecacheCompletionHandler completionHandler;
+
+ std::unique_ptr<FontPlatformData> result;
+ std::atomic_bool isCanceled { false };
+};
+
+FontCache::PrecacheTask& FontCache::platformPrecache(const AtomicString& family, const FontDescription& fontDescription, PrecacheCompletionHandler&& completionHandler)
+{
+ static WorkQueue& queue = WorkQueue::create("org.webkit.font-precache", WorkQueue::Type::Serial, WorkQueue::QOS::UserInitiated).leakRef();
+
+ auto task = std::make_unique<PrecacheTask>();
+ task->family = family;
+ task->fontDescription = fontDescription;
+ const auto& whitelist = fontWhitelist();
+ task->isWhitelisted = whitelist.isEmpty() || whitelist.contains(family);
+#if PLATFORM(MAC)
+ task->shouldAutoActivateIfNeeded = shouldAutoActivateFontIfNeeded(family);
+#endif
+ task->completionHandler = WTFMove(completionHandler);
+
+ auto& resultTask = *task;
+
+ queue.dispatch([task = task.release()] {
+ if (!task->isCanceled) {
+ auto family = task->family.isolatedCopy();
+ task->result = createFontPlatformDataThreadSafe(task->fontDescription, family, nullptr, nullptr, task->isWhitelisted, task->shouldAutoActivateIfNeeded);
+ }
+
+ RunLoop::main().dispatch([task] {
+ std::unique_ptr<PrecacheTask> deleter(task);
+ task->completionHandler(WTFMove(task->result), task->isCanceled);
+ });
+ });
+
+ return resultTask;
}
+
+void FontCache::platformCancelPrecache(FontCache::PrecacheTask& task)
+{
+ task.isCanceled = true;
+}
+#endif
+
+}