<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[188871] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/188871">188871</a></dd>
<dt>Author</dt> <dd>mmaxfield@apple.com</dd>
<dt>Date</dt> <dd>2015-08-24 11:37:37 -0700 (Mon, 24 Aug 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Cocoa] Unify FontCache
https://bugs.webkit.org/show_bug.cgi?id=148358

Reviewed by Antti Koivisto.

Move all the duplicate code to FontCacheCoreText.

No new tests because there is no behavior change.

* platform/graphics/FontCache.h:
* platform/graphics/cocoa/FontCacheCoreText.cpp:
(WebCore::fontWeightFromCoreText):
(WebCore::toTraitsMask):
(WebCore::isFontWeightBold):
(WebCore::toCoreTextFontWeight):
(WebCore::invalidateFontCache):
(WebCore::fontCacheRegisteredFontsChangedNotificationCallback):
(WebCore::FontCache::platformInit):
(WebCore::FontCache::systemFontFamilies):
(WebCore::computeTraits):
(WebCore::computeNecessarySynthesis):
(WebCore::fontWhitelist):
(WebCore::FontCache::setFontWhitelist):
(WebCore::platformFontLookupWithFamily):
(WebCore::fontWithFamily):
(WebCore::shouldAutoActivateFontIfNeeded):
(WebCore::FontCache::createFontPlatformData):
(WebCore::fallbackDedupSet):
(WebCore::FontCache::platformPurgeInactiveFontData):
(WebCore::FontCache::systemFallbackForCharacters):
* platform/graphics/ios/FontCacheIOS.mm:
(WebCore::platformInvalidateFontCache):
(WebCore::getSystemFontFallbackForCharacters):
(WebCore::platformLookupFallbackFont):
(WebCore::FontCache::lastResortFallbackFont):
(WebCore::FontCache::weightOfCTFont):
(WebCore::platformFontWithFamilySpecialCase):
(WebCore::FontCache::platformInit): Deleted.
(WebCore::isFontWeightBold): Deleted.
(WebCore::FontCache::getSystemFontFallbackForCharacters): Deleted.
(WebCore::FontCache::systemFallbackForCharacters): Deleted.
(WebCore::FontCache::systemFontFamilies): Deleted.
(WebCore::createCTFontWithTextStyle): Deleted.
(WebCore::createCTFontWithFamilyNameAndWeight): Deleted.
(WebCore::toCTFontWeight): Deleted.
(WebCore::FontCache::createFontPlatformData): Deleted.
* platform/graphics/mac/FontCacheMac.mm:
(WebCore::appkitWeightToFontWeight):
(WebCore::toNSFontTraits):
(WebCore::platformFontWithFamilySpecialCase):
(WebCore::platformFontWithFamily):
(WebCore::platformInvalidateFontCache):
(WebCore::platformLookupFallbackFont):
(WebCore::FontCache::lastResortFallbackFont):
(WebCore::toCoreTextFontWeight): Deleted.
(WebCore::fontWhitelist): Deleted.
(WebCore::FontCache::setFontWhitelist): Deleted.
(WebCore::fontWithFamilySpecialCase): Deleted.
(WebCore::fontWithFamily): Deleted.
(WebCore::invalidateFontCache): Deleted.
(WebCore::fontCacheRegisteredFontsChangedNotificationCallback): Deleted.
(WebCore::FontCache::platformInit): Deleted.
(WebCore::isAppKitFontWeightBold): Deleted.
(WebCore::shouldAutoActivateFontIfNeeded): Deleted.
(WebCore::fallbackDedupSet): Deleted.
(WebCore::FontCache::platformPurgeInactiveFontData): Deleted.
(WebCore::lookupCTFont): Deleted.
(WebCore::FontCache::systemFallbackForCharacters): Deleted.
(WebCore::FontCache::systemFontFamilies): Deleted.
(WebCore::FontCache::createFontPlatformData): Deleted.
* rendering/RenderThemeIOS.mm:
(WebCore::RenderThemeIOS::updateCachedSystemFontDescription):
(WebCore::fromCTFontWeight): Deleted.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsFontCacheh">trunk/Source/WebCore/platform/graphics/FontCache.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscocoaFontCacheCoreTextcpp">trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsiosFontCacheIOSmm">trunk/Source/WebCore/platform/graphics/ios/FontCacheIOS.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsmacFontCacheMacmm">trunk/Source/WebCore/platform/graphics/mac/FontCacheMac.mm</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderThemeIOSmm">trunk/Source/WebCore/rendering/RenderThemeIOS.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (188870 => 188871)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-08-24 18:07:48 UTC (rev 188870)
+++ trunk/Source/WebCore/ChangeLog        2015-08-24 18:37:37 UTC (rev 188871)
</span><span class="lines">@@ -1,3 +1,79 @@
</span><ins>+2015-08-24  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        [Cocoa] Unify FontCache
+        https://bugs.webkit.org/show_bug.cgi?id=148358
+
+        Reviewed by Antti Koivisto.
+
+        Move all the duplicate code to FontCacheCoreText.
+
+        No new tests because there is no behavior change.
+
+        * platform/graphics/FontCache.h:
+        * platform/graphics/cocoa/FontCacheCoreText.cpp:
+        (WebCore::fontWeightFromCoreText):
+        (WebCore::toTraitsMask):
+        (WebCore::isFontWeightBold):
+        (WebCore::toCoreTextFontWeight):
+        (WebCore::invalidateFontCache):
+        (WebCore::fontCacheRegisteredFontsChangedNotificationCallback):
+        (WebCore::FontCache::platformInit):
+        (WebCore::FontCache::systemFontFamilies):
+        (WebCore::computeTraits):
+        (WebCore::computeNecessarySynthesis):
+        (WebCore::fontWhitelist):
+        (WebCore::FontCache::setFontWhitelist):
+        (WebCore::platformFontLookupWithFamily):
+        (WebCore::fontWithFamily):
+        (WebCore::shouldAutoActivateFontIfNeeded):
+        (WebCore::FontCache::createFontPlatformData):
+        (WebCore::fallbackDedupSet):
+        (WebCore::FontCache::platformPurgeInactiveFontData):
+        (WebCore::FontCache::systemFallbackForCharacters):
+        * platform/graphics/ios/FontCacheIOS.mm:
+        (WebCore::platformInvalidateFontCache):
+        (WebCore::getSystemFontFallbackForCharacters):
+        (WebCore::platformLookupFallbackFont):
+        (WebCore::FontCache::lastResortFallbackFont):
+        (WebCore::FontCache::weightOfCTFont):
+        (WebCore::platformFontWithFamilySpecialCase):
+        (WebCore::FontCache::platformInit): Deleted.
+        (WebCore::isFontWeightBold): Deleted.
+        (WebCore::FontCache::getSystemFontFallbackForCharacters): Deleted.
+        (WebCore::FontCache::systemFallbackForCharacters): Deleted.
+        (WebCore::FontCache::systemFontFamilies): Deleted.
+        (WebCore::createCTFontWithTextStyle): Deleted.
+        (WebCore::createCTFontWithFamilyNameAndWeight): Deleted.
+        (WebCore::toCTFontWeight): Deleted.
+        (WebCore::FontCache::createFontPlatformData): Deleted.
+        * platform/graphics/mac/FontCacheMac.mm:
+        (WebCore::appkitWeightToFontWeight):
+        (WebCore::toNSFontTraits):
+        (WebCore::platformFontWithFamilySpecialCase):
+        (WebCore::platformFontWithFamily):
+        (WebCore::platformInvalidateFontCache):
+        (WebCore::platformLookupFallbackFont):
+        (WebCore::FontCache::lastResortFallbackFont):
+        (WebCore::toCoreTextFontWeight): Deleted.
+        (WebCore::fontWhitelist): Deleted.
+        (WebCore::FontCache::setFontWhitelist): Deleted.
+        (WebCore::fontWithFamilySpecialCase): Deleted.
+        (WebCore::fontWithFamily): Deleted.
+        (WebCore::invalidateFontCache): Deleted.
+        (WebCore::fontCacheRegisteredFontsChangedNotificationCallback): Deleted.
+        (WebCore::FontCache::platformInit): Deleted.
+        (WebCore::isAppKitFontWeightBold): Deleted.
+        (WebCore::shouldAutoActivateFontIfNeeded): Deleted.
+        (WebCore::fallbackDedupSet): Deleted.
+        (WebCore::FontCache::platformPurgeInactiveFontData): Deleted.
+        (WebCore::lookupCTFont): Deleted.
+        (WebCore::FontCache::systemFallbackForCharacters): Deleted.
+        (WebCore::FontCache::systemFontFamilies): Deleted.
+        (WebCore::FontCache::createFontPlatformData): Deleted.
+        * rendering/RenderThemeIOS.mm:
+        (WebCore::RenderThemeIOS::updateCachedSystemFontDescription):
+        (WebCore::fromCTFontWeight): Deleted.
+
</ins><span class="cx"> 2015-08-24  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, attempt to fix iOS build after r188860
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsFontCacheh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/FontCache.h (188870 => 188871)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/FontCache.h        2015-08-24 18:07:48 UTC (rev 188870)
+++ trunk/Source/WebCore/platform/graphics/FontCache.h        2015-08-24 18:37:37 UTC (rev 188871)
</span><span class="lines">@@ -154,7 +154,7 @@
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     static float weightOfCTFont(CTFontRef);
</span><span class="cx"> #endif
</span><del>-#if PLATFORM(MAC)
</del><ins>+#if PLATFORM(COCOA)
</ins><span class="cx">     WEBCORE_EXPORT static void setFontWhitelist(const Vector&lt;String&gt;&amp;);
</span><span class="cx"> #endif
</span><span class="cx"> #if PLATFORM(WIN)
</span><span class="lines">@@ -203,9 +203,8 @@
</span><span class="cx">     FontPlatformData* getCachedFontPlatformData(const FontDescription&amp;, const AtomicString&amp; family, bool checkingAlternateName = false);
</span><span class="cx"> 
</span><span class="cx">     // These methods are implemented by each platform.
</span><del>-#if PLATFORM(IOS)
</del><ins>+#if PLATFORM(COCOA)
</ins><span class="cx">     FontPlatformData* getCustomFallbackFont(const UInt32, const FontDescription&amp;);
</span><del>-    PassRefPtr&lt;Font&gt; getSystemFontFallbackForCharacters(const FontDescription&amp;, const Font*, const UChar* characters, unsigned length);
</del><span class="cx"> #endif
</span><span class="cx">     std::unique_ptr&lt;FontPlatformData&gt; createFontPlatformData(const FontDescription&amp;, const AtomicString&amp; family);
</span><span class="cx"> 
</span><span class="lines">@@ -218,13 +217,40 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span><ins>+
+struct SynthesisPair {
+    SynthesisPair(bool needsSyntheticBold, bool needsSyntheticOblique)
+        : needsSyntheticBold(needsSyntheticBold)
+        , needsSyntheticOblique(needsSyntheticOblique)
+    {
+    }
+
+    std::pair&lt;bool, bool&gt; boldObliquePair() const
+    {
+        return std::make_pair(needsSyntheticBold, needsSyntheticOblique);
+    }
+
+    bool needsSyntheticBold;
+    bool needsSyntheticOblique;
+};
+
</ins><span class="cx"> RetainPtr&lt;CTFontRef&gt; preparePlatformFont(CTFontRef, TextRenderingMode, const FontFeatureSettings*);
</span><del>-#endif
</del><ins>+FontWeight fontWeightFromCoreText(CGFloat weight);
+uint16_t toCoreTextFontWeight(FontWeight);
+bool isFontWeightBold(FontWeight);
+void platformInvalidateFontCache();
+SynthesisPair computeNecessarySynthesis(CTFontRef, const FontDescription&amp;, bool isPlatformFont = false);
+RetainPtr&lt;CTFontRef&gt; platformFontWithFamilySpecialCase(const AtomicString&amp; family, FontWeight, CTFontSymbolicTraits, float size);
+RetainPtr&lt;CTFontRef&gt; platformFontWithFamily(const AtomicString&amp; family, CTFontSymbolicTraits, FontWeight, const FontFeatureSettings*, TextRenderingMode, float size);
+RetainPtr&lt;CTFontRef&gt; platformLookupFallbackFont(CTFontRef, FontWeight, const AtomicString&amp; locale, const UChar* characters, unsigned length);
+bool requiresCustomFallbackFont(UChar32 character);
</ins><span class="cx"> 
</span><del>-#if !PLATFORM(MAC)
</del><ins>+#else
+
</ins><span class="cx"> inline void FontCache::platformPurgeInactiveFontData()
</span><span class="cx"> {
</span><span class="cx"> }
</span><ins>+
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscocoaFontCacheCoreTextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp (188870 => 188871)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp        2015-08-24 18:07:48 UTC (rev 188870)
+++ trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp        2015-08-24 18:37:37 UTC (rev 188871)
</span><span class="lines">@@ -31,6 +31,8 @@
</span><span class="cx"> 
</span><span class="cx"> #include &lt;CoreText/SFNTLayoutTypes.h&gt;
</span><span class="cx"> 
</span><ins>+#include &lt;wtf/HashSet.h&gt;
+#include &lt;wtf/MainThread.h&gt;
</ins><span class="cx"> #include &lt;wtf/NeverDestroyed.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -130,9 +132,9 @@
</span><span class="cx">     RetainPtr&lt;CFStringRef&gt; featureKey = feature.tag().string().createCFString();
</span><span class="cx">     int rawFeatureValue = feature.value();
</span><span class="cx">     RetainPtr&lt;CFNumberRef&gt; featureValue = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &amp;rawFeatureValue));
</span><del>-    CFStringRef featureDictionaryKeys[] = { kCTFontOpenTypeFeatureTag, kCTFontOpenTypeFeatureValue };
</del><ins>+    CFTypeRef featureDictionaryKeys[] = { kCTFontOpenTypeFeatureTag, kCTFontOpenTypeFeatureValue };
</ins><span class="cx">     CFTypeRef featureDictionaryValues[] = { featureKey.get(), featureValue.get() };
</span><del>-    RetainPtr&lt;CFDictionaryRef&gt; featureDictionary = adoptCF(CFDictionaryCreate(kCFAllocatorDefault, (const void**)featureDictionaryKeys, featureDictionaryValues, WTF_ARRAY_LENGTH(featureDictionaryValues), &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks));
</del><ins>+    RetainPtr&lt;CFDictionaryRef&gt; featureDictionary = adoptCF(CFDictionaryCreate(kCFAllocatorDefault, featureDictionaryKeys, featureDictionaryValues, WTF_ARRAY_LENGTH(featureDictionaryValues), &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks));
</ins><span class="cx">     CFArrayAppendValue(features, featureDictionary.get());
</span><span class="cx"> #else
</span><span class="cx">     UNUSED_PARAM(features);
</span><span class="lines">@@ -163,36 +165,84 @@
</span><span class="cx">     return adoptCF(CTFontCreateCopyWithAttributes(originalFont, CTFontGetSize(originalFont), nullptr, descriptor.get()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+FontWeight fontWeightFromCoreText(CGFloat weight)
+{
+    if (weight &lt; -0.6)
+        return FontWeight100;
+    if (weight &lt; -0.365)
+        return FontWeight200;
+    if (weight &lt; -0.115)
+        return FontWeight300;
+    if (weight &lt;  0.130)
+        return FontWeight400;
+    if (weight &lt;  0.235)
+        return FontWeight500;
+    if (weight &lt;  0.350)
+        return FontWeight600;
+    if (weight &lt;  0.500)
+        return FontWeight700;
+    if (weight &lt;  0.700)
+        return FontWeight800;
+    return FontWeight900;
+}
+
</ins><span class="cx"> static inline FontTraitsMask toTraitsMask(CTFontSymbolicTraits ctFontTraits, CGFloat weight)
</span><span class="cx"> {
</span><del>-    FontTraitsMask weightMask = FontWeight100Mask;
-    if (weight &lt; -0.6)
</del><ins>+    FontTraitsMask weightMask;
+    switch (fontWeightFromCoreText(weight)) {
+    case FontWeight100:
</ins><span class="cx">         weightMask = FontWeight100Mask;
</span><del>-    else if (weight &lt; -0.365)
</del><ins>+        break;
+    case FontWeight200:
</ins><span class="cx">         weightMask = FontWeight200Mask;
</span><del>-    else if (weight &lt; -0.115)
</del><ins>+        break;
+    case FontWeight300:
</ins><span class="cx">         weightMask = FontWeight300Mask;
</span><del>-    else if (weight &lt;  0.130)
</del><ins>+        break;
+    case FontWeight400:
</ins><span class="cx">         weightMask = FontWeight400Mask;
</span><del>-    else if (weight &lt;  0.235)
</del><ins>+        break;
+    case FontWeight500:
</ins><span class="cx">         weightMask = FontWeight500Mask;
</span><del>-    else if (weight &lt;  0.350)
</del><ins>+        break;
+    case FontWeight600:
</ins><span class="cx">         weightMask = FontWeight600Mask;
</span><del>-    else if (weight &lt;  0.500)
</del><ins>+        break;
+    case FontWeight700:
</ins><span class="cx">         weightMask = FontWeight700Mask;
</span><del>-    else if (weight &lt;  0.700)
</del><ins>+        break;
+    case FontWeight800:
</ins><span class="cx">         weightMask = FontWeight800Mask;
</span><del>-    else
</del><ins>+        break;
+    case FontWeight900:
</ins><span class="cx">         weightMask = FontWeight900Mask;
</span><ins>+        break;
+    }
</ins><span class="cx">     return static_cast&lt;FontTraitsMask&gt;(((ctFontTraits &amp; kCTFontTraitItalic) ? FontStyleItalicMask : FontStyleNormalMask)
</span><span class="cx">         | FontVariantNormalMask | weightMask);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline bool isFontWeightBold(FontWeight fontWeight)
</del><ins>+bool isFontWeightBold(FontWeight fontWeight)
</ins><span class="cx"> {
</span><span class="cx">     return fontWeight &gt;= FontWeight600;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+uint16_t toCoreTextFontWeight(FontWeight fontWeight)
+{
+    static const int coreTextFontWeights[] = {
+        100, // FontWeight100
+        200, // FontWeight200
+        300, // FontWeight300
+        400, // FontWeight400
+        500, // FontWeight500
+        600, // FontWeight600
+        700, // FontWeight700
+        800, // FontWeight800
+        900, // FontWeight900
+    };
+    return coreTextFontWeights[fontWeight];
+}
+
</ins><span class="cx"> RefPtr&lt;Font&gt; FontCache::similarFont(const FontDescription&amp; description)
</span><span class="cx"> {
</span><span class="cx">     // Attempt to find an appropriate font using a match based on the presence of keywords in
</span><span class="lines">@@ -240,8 +290,9 @@
</span><span class="cx"> Vector&lt;FontTraitsMask&gt; FontCache::getTraitsInFamily(const AtomicString&amp; familyName)
</span><span class="cx"> {
</span><span class="cx">     RetainPtr&lt;CFStringRef&gt; familyNameStr = familyName.string().createCFString();
</span><del>-    CFStringRef familyNameStrPtr = familyNameStr.get();
-    RetainPtr&lt;CFDictionaryRef&gt; attributes = adoptCF(CFDictionaryCreate(kCFAllocatorDefault, (const void**)&amp;kCTFontFamilyNameAttribute, (const void**)&amp;familyNameStrPtr, 1, &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks));
</del><ins>+    CFTypeRef keys[] = { kCTFontFamilyNameAttribute };
+    CFTypeRef values[] = { familyNameStr.get() };
+    RetainPtr&lt;CFDictionaryRef&gt; attributes = adoptCF(CFDictionaryCreate(kCFAllocatorDefault, keys, values, WTF_ARRAY_LENGTH(keys), &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks));
</ins><span class="cx">     RetainPtr&lt;CTFontDescriptorRef&gt; fontDescriptor = adoptCF(CTFontDescriptorCreateWithAttributes(attributes.get()));
</span><span class="cx">     RetainPtr&lt;CFArrayRef&gt; matchedDescriptors = adoptCF(CTFontDescriptorCreateMatchingFontDescriptors(fontDescriptor.get(), nullptr));
</span><span class="cx">     if (!matchedDescriptors)
</span><span class="lines">@@ -268,4 +319,227 @@
</span><span class="cx">     return traitsMasks;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static void invalidateFontCache()
+{
+    if (!isMainThread()) {
+        callOnMainThread([] {
+            invalidateFontCache();
+        });
+        return;
+    }
+
+    FontCache::singleton().invalidate();
+
+    platformInvalidateFontCache();
</ins><span class="cx"> }
</span><ins>+
+static void fontCacheRegisteredFontsChangedNotificationCallback(CFNotificationCenterRef, void* observer, CFStringRef name, const void *, CFDictionaryRef)
+{
+    ASSERT_UNUSED(observer, observer == &amp;FontCache::singleton());
+    ASSERT_UNUSED(name, CFEqual(name, kCTFontManagerRegisteredFontsChangedNotification));
+
+    invalidateFontCache();
+}
+
+void FontCache::platformInit()
+{
+    CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(), this, fontCacheRegisteredFontsChangedNotificationCallback, kCTFontManagerRegisteredFontsChangedNotification, 0, CFNotificationSuspensionBehaviorDeliverImmediately);
+}
+
+Vector&lt;String&gt; FontCache::systemFontFamilies()
+{
+    // FIXME: &lt;rdar://problem/21890188&gt;
+    RetainPtr&lt;CFDictionaryRef&gt; attributes = adoptCF(CFDictionaryCreate(kCFAllocatorDefault, nullptr, nullptr, 0, &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks));
+    auto emptyFontDescriptor = adoptCF(CTFontDescriptorCreateWithAttributes(attributes.get()));
+    auto matchedDescriptors = adoptCF(CTFontDescriptorCreateMatchingFontDescriptors(emptyFontDescriptor.get(), nullptr));
+    if (!matchedDescriptors)
+        return { };
+
+    CFIndex numMatches = CFArrayGetCount(matchedDescriptors.get());
+    if (!numMatches)
+        return { };
+
+    HashSet&lt;String&gt; visited;
+    for (CFIndex i = 0; i &lt; numMatches; ++i) {
+        auto fontDescriptor = static_cast&lt;CTFontDescriptorRef&gt;(CFArrayGetValueAtIndex(matchedDescriptors.get(), i));
+        if (auto familyName = adoptCF(static_cast&lt;CFStringRef&gt;(CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontFamilyNameAttribute))))
+            visited.add(familyName.get());
+    }
+
+    Vector&lt;String&gt; result;
+    copyToVector(visited, result);
+    return result;
+}
+
+static CTFontSymbolicTraits computeTraits(const FontDescription&amp; fontDescription)
+{
+    CTFontSymbolicTraits traits = 0;
+    if (fontDescription.italic())
+        traits |= kCTFontTraitItalic;
+    if (isFontWeightBold(fontDescription.weight()))
+        traits |= kCTFontTraitBold;
+    return traits;
+}
+
+SynthesisPair computeNecessarySynthesis(CTFontRef font, const FontDescription&amp; fontDescription, bool isPlatformFont)
+{
+#if PLATFORM(IOS)
+    if (CTFontIsAppleColorEmoji(font))
+        return SynthesisPair(false, false);
+#endif
+
+    if (isPlatformFont)
+        return SynthesisPair(false, false);
+
+    CTFontSymbolicTraits desiredTraits = computeTraits(fontDescription);
+
+    CTFontSymbolicTraits actualTraits = 0;
+    if (isFontWeightBold(fontDescription.weight()) || fontDescription.italic())
+        actualTraits = CTFontGetSymbolicTraits(font);
+
+    bool needsSyntheticBold = (fontDescription.fontSynthesis() &amp; FontSynthesisWeight) &amp;&amp; (desiredTraits &amp; kCTFontTraitBold) &amp;&amp; !(actualTraits &amp; kCTFontTraitBold);
+    bool needsSyntheticOblique = (fontDescription.fontSynthesis() &amp; FontSynthesisStyle) &amp;&amp; (desiredTraits &amp; kCTFontTraitItalic) &amp;&amp; !(actualTraits &amp; kCTFontTraitItalic);
+
+    return SynthesisPair(needsSyntheticBold, needsSyntheticOblique);
+}
+
+typedef HashSet&lt;String, CaseFoldingHash&gt; Whitelist;
+static Whitelist&amp; fontWhitelist()
+{
+    static NeverDestroyed&lt;Whitelist&gt; whitelist;
+    return whitelist;
+}
+
+void FontCache::setFontWhitelist(const Vector&lt;String&gt;&amp; inputWhitelist)
+{
+    Whitelist&amp; whitelist = fontWhitelist();
+    whitelist.clear();
+    for (auto&amp; item : inputWhitelist)
+        whitelist.add(item);
+}
+
+#if ENABLE(PLATFORM_FONT_LOOKUP)
+static RetainPtr&lt;CTFontRef&gt; platformFontLookupWithFamily(const AtomicString&amp; family, CTFontSymbolicTraits requestedTraits, FontWeight weight, const FontFeatureSettings* featureSettings, TextRenderingMode textRenderingMode, float size)
+{
+    const auto&amp; whitelist = fontWhitelist();
+    if (whitelist.size() &amp;&amp; !whitelist.contains(family))
+        return nullptr;
+
+    auto foundFont = adoptCF(CTFontCreateForCSS(family.string().createCFString().get(), toCoreTextFontWeight(weight), requestedTraits, size));
+    return preparePlatformFont(foundFont.get(), textRenderingMode, featureSettings);
+}
+#endif
+
+static RetainPtr&lt;CTFontRef&gt; fontWithFamily(const AtomicString&amp; family, CTFontSymbolicTraits desiredTraits, FontWeight weight, const FontFeatureSettings* featureSettings, TextRenderingMode textRenderingMode, float size)
+{
+    if (family.isEmpty())
+        return nullptr;
+    if (auto specialCase = platformFontWithFamilySpecialCase(family, weight, desiredTraits, size))
+        return specialCase;
+#if ENABLE(PLATFORM_FONT_LOOKUP)
+    return platformFontLookupWithFamily(family, desiredTraits, weight, featureSettings, textRenderingMode, size);
+#else
+    return platformFontWithFamily(family, desiredTraits, weight, featureSettings, textRenderingMode, size);
+#endif
+}
+
+#if PLATFORM(MAC)
+static bool shouldAutoActivateFontIfNeeded(const AtomicString&amp; family)
+{
+#ifndef NDEBUG
+    // This cache is not thread safe so the following assertion is there to
+    // make sure this function is always called from the same thread.
+    static ThreadIdentifier initThreadId = currentThread();
+    ASSERT(currentThread() == initThreadId);
+#endif
+
+    static NeverDestroyed&lt;HashSet&lt;AtomicString&gt;&gt; knownFamilies;
+    static const unsigned maxCacheSize = 128;
+    ASSERT(knownFamilies.get().size() &lt;= maxCacheSize);
+    if (knownFamilies.get().size() == maxCacheSize)
+        knownFamilies.get().remove(knownFamilies.get().begin());
+
+    // Only attempt to auto-activate fonts once for performance reasons.
+    return knownFamilies.get().add(family).isNewEntry;
+}
+#endif
+
+std::unique_ptr&lt;FontPlatformData&gt; FontCache::createFontPlatformData(const FontDescription&amp; fontDescription, const AtomicString&amp; family)
+{
+    CTFontSymbolicTraits traits = computeTraits(fontDescription);
+    float size = fontDescription.computedPixelSize();
+
+    RetainPtr&lt;CTFontRef&gt; font = fontWithFamily(family, traits, fontDescription.weight(), fontDescription.featureSettings(), fontDescription.textRenderingMode(), size);
+
+#if PLATFORM(MAC)
+    if (!font) {
+        if (!shouldAutoActivateFontIfNeeded(family))
+            return nullptr;
+
+        // 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.
+        CFRelease(CTFontCreateWithName(family.string().createCFString().get(), size, nullptr));
+
+        font = platformFontWithFamily(family, traits, fontDescription.weight(), fontDescription.featureSettings(), fontDescription.textRenderingMode(), size);
+        if (!font)
+            return nullptr;
+    }
+#endif
+    if (!font)
+        return nullptr;
+
+    bool syntheticBold, syntheticOblique;
+    std::tie(syntheticBold, syntheticOblique) = computeNecessarySynthesis(font.get(), fontDescription).boldObliquePair();
+
+    return std::make_unique&lt;FontPlatformData&gt;(font.get(), size, syntheticBold, syntheticOblique, fontDescription.orientation(), fontDescription.widthVariant(), fontDescription.textRenderingMode());
+}
+
+typedef HashSet&lt;RetainPtr&lt;CTFontRef&gt;, WTF::RetainPtrObjectHash&lt;CTFontRef&gt;, WTF::RetainPtrObjectHashTraits&lt;CTFontRef&gt;&gt; FallbackDedupSet;
+static FallbackDedupSet&amp; fallbackDedupSet()
+{
+    static NeverDestroyed&lt;FallbackDedupSet&gt; dedupSet;
+    return dedupSet.get();
+}
+
+void FontCache::platformPurgeInactiveFontData()
+{
+    Vector&lt;CTFontRef&gt; toRemove;
+    for (auto&amp; font : fallbackDedupSet()) {
+        if (CFGetRetainCount(font.get()) == 1)
+            toRemove.append(font.get());
+    }
+    for (auto&amp; font : toRemove)
+        fallbackDedupSet().remove(font);
+}
+
+RefPtr&lt;Font&gt; FontCache::systemFallbackForCharacters(const FontDescription&amp; description, const Font* originalFontData, bool isPlatformFont, const UChar* characters, unsigned length)
+{
+#if PLATFORM(IOS)
+    if (length &amp;&amp; requiresCustomFallbackFont(*characters)) {
+        auto* fallback = getCustomFallbackFont(*characters, description);
+        if (!fallback)
+            return nullptr;
+        return fontForPlatformData(*fallback);
+    }
+#endif
+
+    const FontPlatformData&amp; platformData = originalFontData-&gt;platformData();
+    RetainPtr&lt;CTFontRef&gt; result = platformLookupFallbackFont(platformData.font(), description.weight(), description.locale(), characters, length);
+    result = preparePlatformFont(result.get(), description.textRenderingMode(), description.featureSettings());
+    if (!result)
+        return lastResortFallbackFont(description);
+
+    // FontCascade::drawGlyphBuffer() requires that there are no duplicate Font objects which refer to the same thing. This is enforced in
+    // FontCache::fontForPlatformData(), where our equality check is based on hashing the FontPlatformData, whose hash includes the raw CoreText
+    // font pointer.
+    CTFontRef substituteFont = fallbackDedupSet().add(result).iterator-&gt;get();
+
+    bool syntheticBold, syntheticOblique;
+    std::tie(syntheticBold, syntheticOblique) = computeNecessarySynthesis(substituteFont, description, isPlatformFont).boldObliquePair();
+
+    FontPlatformData alternateFont(substituteFont, platformData.size(), syntheticBold, syntheticOblique, platformData.m_orientation, platformData.m_widthVariant, platformData.m_textRenderingMode);
+
+    return fontForPlatformData(alternateFont);
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsiosFontCacheIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ios/FontCacheIOS.mm (188870 => 188871)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ios/FontCacheIOS.mm        2015-08-24 18:07:48 UTC (rev 188870)
+++ trunk/Source/WebCore/platform/graphics/ios/FontCacheIOS.mm        2015-08-24 18:37:37 UTC (rev 188871)
</span><span class="lines">@@ -40,122 +40,15 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-void FontCache::platformInit()
</del><ins>+void platformInvalidateFontCache()
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline bool isFontWeightBold(NSInteger fontWeight)
</del><ins>+bool requiresCustomFallbackFont(UChar32 character)
</ins><span class="cx"> {
</span><del>-    return fontWeight &gt;= FontWeight600;
-}
-
-static inline bool requiresCustomFallbackFont(const UInt32 character)
-{
</del><span class="cx">     return character == AppleLogo || character == blackCircle || character == narrowNonBreakingSpace;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-PassRefPtr&lt;Font&gt; FontCache::getSystemFontFallbackForCharacters(const FontDescription&amp; description, const Font* originalFontData, const UChar* characters, unsigned length)
-{
-    const FontPlatformData&amp; platformData = originalFontData-&gt;platformData();
-    CTFontRef ctFont = platformData.font();
-
-    RetainPtr&lt;CFStringRef&gt; localeString;
-#if __IPHONE_OS_VERSION_MIN_REQUIRED &gt; 90000
-    if (!description.locale().isNull())
-        localeString = description.locale().string().createCFString();
-#endif
-
-    CFIndex coveredLength = 0;
-    RetainPtr&lt;CTFontRef&gt; substituteFont = adoptCF(CTFontCreatePhysicalFontForCharactersWithLanguage(ctFont, (const UTF16Char*)characters, (CFIndex)length, localeString.get(), &amp;coveredLength));
-    if (!substituteFont)
-        return nullptr;
-
-    substituteFont = preparePlatformFont(substituteFont.get(), description.textRenderingMode(), description.featureSettings());
-
-    CTFontSymbolicTraits originalTraits = CTFontGetSymbolicTraits(ctFont);
-    CTFontSymbolicTraits actualTraits = 0;
-    if (isFontWeightBold(description.weight()) || description.italic())
-        actualTraits = CTFontGetSymbolicTraits(substituteFont.get());
-
-    bool syntheticBold = (originalTraits &amp; kCTFontTraitBold) &amp;&amp; !(actualTraits &amp; kCTFontTraitBold);
-    bool syntheticOblique = (originalTraits &amp; kCTFontTraitItalic) &amp;&amp; !(actualTraits &amp; kCTFontTraitItalic);
-
-    FontPlatformData alternateFont(substituteFont.get(), platformData.size(), syntheticBold, syntheticOblique, platformData.m_orientation);
-
-    return fontForPlatformData(alternateFont);
-}
-
-RefPtr&lt;Font&gt; FontCache::systemFallbackForCharacters(const FontDescription&amp; description, const Font* originalFontData, bool, const UChar* characters, unsigned length)
-{
-    // Unlike OS X, our fallback font on iPhone is Arial Unicode, which doesn't have some apple-specific glyphs like F8FF.
-    // Fall back to the Apple Fallback font in this case.
-    if (length &amp;&amp; requiresCustomFallbackFont(*characters)) {
-        auto* fallback = getCustomFallbackFont(*characters, description);
-        if (!fallback)
-            return nullptr;
-        return fontForPlatformData(*fallback);
-    }
-
-    UChar32 c = *characters;
-    if (length &gt; 1 &amp;&amp; U16_IS_LEAD(c) &amp;&amp; U16_IS_TRAIL(characters[1]))
-        c = U16_GET_SUPPLEMENTARY(c, characters[1]);
-
-    // For system fonts we use CoreText fallback mechanism.
-    if (length) {
-        RetainPtr&lt;CTFontDescriptorRef&gt; fontDescriptor = adoptCF(CTFontCopyFontDescriptor(originalFontData-&gt;getCTFont()));
-        if (CTFontDescriptorIsSystemUIFont(fontDescriptor.get()))
-            return getSystemFontFallbackForCharacters(description, originalFontData, characters, length);
-    }
-
-#if __IPHONE_OS_VERSION_MIN_REQUIRED &gt;= 90000
-    RetainPtr&lt;CTFontDescriptorRef&gt; fallbackFontDescriptor = adoptCF(CTFontCreatePhysicalFontDescriptorForCharactersWithLanguage(originalFontData-&gt;getCTFont(), characters, length, nullptr, nullptr));
-#else
-    RetainPtr&lt;CTFontRef&gt; fallbackFont = adoptCF(CTFontCreateForCharactersWithLanguage(originalFontData-&gt;getCTFont(), characters, length, nullptr, nullptr));
-    RetainPtr&lt;CTFontDescriptorRef&gt; fallbackFontDescriptor = adoptCF(CTFontCopyFontDescriptor(fallbackFont.get()));
-#endif
-    if (auto foundFontName = adoptCF(static_cast&lt;CFStringRef&gt;(CTFontDescriptorCopyAttribute(fallbackFontDescriptor.get(), kCTFontNameAttribute)))) {
-        if (c &gt;= 0x0600 &amp;&amp; c &lt;= 0x06ff) { // Arabic
-            auto familyName = adoptCF(static_cast&lt;CFStringRef&gt;(CTFontDescriptorCopyAttribute(fallbackFontDescriptor.get(), kCTFontFamilyNameAttribute)));
-            if (fontFamilyShouldNotBeUsedForArabic(familyName.get()))
-                foundFontName = isFontWeightBold(description.weight()) ? CFSTR(&quot;GeezaPro-Bold&quot;) : CFSTR(&quot;GeezaPro&quot;);
-        }
-        if (RefPtr&lt;Font&gt; font = fontForFamily(description, foundFontName.get(), false))
-            return font;
-    }
-
-    return lastResortFallbackFont(description);
-}
-
-Vector&lt;String&gt; FontCache::systemFontFamilies()
-{
-    // FIXME: &lt;rdar://problem/21890188&gt;
-    Vector&lt;String&gt; fontFamilies;
-    auto emptyFontDescriptor = adoptCF(CTFontDescriptorCreateWithAttributes((CFDictionaryRef) @{ }));
-    auto matchedDescriptors = adoptCF(CTFontDescriptorCreateMatchingFontDescriptors(emptyFontDescriptor.get(), nullptr));
-    if (!matchedDescriptors)
-        return fontFamilies;
-
-    CFIndex numMatches = CFArrayGetCount(matchedDescriptors.get());
-    if (!numMatches)
-        return fontFamilies;
-
-    HashSet&lt;String&gt; visited;
-    for (CFIndex i = 0; i &lt; numMatches; ++i) {
-        auto fontDescriptor = static_cast&lt;CTFontDescriptorRef&gt;(CFArrayGetValueAtIndex(matchedDescriptors.get(), i));
-        if (auto familyName = adoptCF(static_cast&lt;CFStringRef&gt;(CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontFamilyNameAttribute))))
-            visited.add(familyName.get());
-    }
-
-    copyToVector(visited, fontFamilies);
-    return fontFamilies;
-}
-
-Ref&lt;Font&gt; FontCache::lastResortFallbackFont(const FontDescription&amp; fontDescription)
-{
-    static NeverDestroyed&lt;AtomicString&gt; fallbackFontFamily(&quot;.PhoneFallback&quot;, AtomicString::ConstructFromLiteral);
-    return *fontForFamily(fontDescription, fallbackFontFamily, false);
-}
-
</del><span class="cx"> FontPlatformData* FontCache::getCustomFallbackFont(const UInt32 c, const FontDescription&amp; description)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(requiresCustomFallbackFont(c));
</span><span class="lines">@@ -185,134 +78,111 @@
</span><span class="cx">     return getCachedFontPlatformData(description, *family);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-float FontCache::weightOfCTFont(CTFontRef font)
</del><ins>+static RetainPtr&lt;CTFontRef&gt; getSystemFontFallbackForCharacters(CTFontRef font, const AtomicString&amp; locale, const UChar* characters, unsigned length)
</ins><span class="cx"> {
</span><del>-    float result = 0;
-    RetainPtr&lt;CFDictionaryRef&gt; traits = adoptCF(CTFontCopyTraits(font));
-    if (!traits)
-        return result;
</del><ins>+    // FIXME: Unify this with platformLookupFallbackFont()
+    RetainPtr&lt;CFStringRef&gt; localeString;
+#if __IPHONE_OS_VERSION_MIN_REQUIRED &gt; 90000
+    if (!locale.isNull())
+        localeString = locale.string().createCFString();
+#else
+    UNUSED_PARAM(locale);
+#endif
</ins><span class="cx"> 
</span><del>-    CFNumberRef resultRef = (CFNumberRef)CFDictionaryGetValue(traits.get(), kCTFontWeightTrait);
-    if (resultRef)
-        CFNumberGetValue(resultRef, kCFNumberFloatType, &amp;result);
</del><ins>+    CFIndex coveredLength = 0;
+    return adoptCF(CTFontCreatePhysicalFontForCharactersWithLanguage(font, (const UTF16Char*)characters, (CFIndex)length, localeString.get(), &amp;coveredLength));
+}
</ins><span class="cx"> 
</span><del>-    return result;
</del><ins>+RetainPtr&lt;CTFontRef&gt; platformLookupFallbackFont(CTFontRef font, FontWeight fontWeight, const AtomicString&amp; locale, const UChar* characters, unsigned length)
+{
+    // For system fonts we use CoreText fallback mechanism.
+    if (length &amp;&amp; CTFontDescriptorIsSystemUIFont(adoptCF(CTFontCopyFontDescriptor(font)).get()))
+        return getSystemFontFallbackForCharacters(font, locale, characters, length);
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED &gt;= 90000
+    RetainPtr&lt;CFStringRef&gt; localeString;
+    if (!locale.isNull())
+        localeString = locale.string().createCFString();
+    RetainPtr&lt;CTFontDescriptorRef&gt; fallbackFontDescriptor = adoptCF(CTFontCreatePhysicalFontDescriptorForCharactersWithLanguage(font, characters, length, localeString.get(), nullptr));
+#else
+    RetainPtr&lt;CTFontRef&gt; fallbackFont = adoptCF(CTFontCreateForCharactersWithLanguage(font, characters, length, nullptr, nullptr));
+    RetainPtr&lt;CTFontDescriptorRef&gt; fallbackFontDescriptor = adoptCF(CTFontCopyFontDescriptor(fallbackFont.get()));
+#endif
+    UChar32 c = *characters;
+    if (length &gt; 1 &amp;&amp; U16_IS_LEAD(c) &amp;&amp; U16_IS_TRAIL(characters[1]))
+        c = U16_GET_SUPPLEMENTARY(c, characters[1]);
+    // Arabic
+    if (c &gt;= 0x0600 &amp;&amp; c &lt;= 0x06ff) {
+        auto familyName = adoptCF(static_cast&lt;CFStringRef&gt;(CTFontDescriptorCopyAttribute(fallbackFontDescriptor.get(), kCTFontFamilyNameAttribute)));
+        if (fontFamilyShouldNotBeUsedForArabic(familyName.get())) {
+            CFStringRef newFamilyName = isFontWeightBold(fontWeight) ? CFSTR(&quot;GeezaPro-Bold&quot;) : CFSTR(&quot;GeezaPro&quot;);
+            CFTypeRef keys[] = { kCTFontFamilyNameAttribute };
+            CFTypeRef values[] = { newFamilyName };
+            RetainPtr&lt;CFDictionaryRef&gt; attributes = adoptCF(CFDictionaryCreate(kCFAllocatorDefault, keys, values, WTF_ARRAY_LENGTH(keys), &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks));
+            fallbackFontDescriptor = adoptCF(CTFontDescriptorCreateCopyWithAttributes(fallbackFontDescriptor.get(), attributes.get()));
+        }
+    }
+    return adoptCF(CTFontCreateWithFontDescriptor(fallbackFontDescriptor.get(), CTFontGetSize(font), nullptr));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static CTFontRef createCTFontWithTextStyle(const String&amp; familyName, CTFontSymbolicTraits traits, CGFloat size)
</del><ins>+Ref&lt;Font&gt; FontCache::lastResortFallbackFont(const FontDescription&amp; fontDescription)
</ins><span class="cx"> {
</span><del>-    if (familyName.isNull())
-        return nullptr;
</del><ins>+    return *fontForFamily(fontDescription, AtomicString(&quot;.PhoneFallback&quot;, AtomicString::ConstructFromLiteral), false);
+}
</ins><span class="cx"> 
</span><del>-    CTFontSymbolicTraits symbolicTraits = 0;
-    if (traits &amp; kCTFontBoldTrait)
-        symbolicTraits |= kCTFontBoldTrait;
-    if (traits &amp; kCTFontTraitItalic)
-        symbolicTraits |= kCTFontTraitItalic;
-    RetainPtr&lt;CFStringRef&gt; familyNameStr = familyName.createCFString();
-    RetainPtr&lt;CTFontDescriptorRef&gt; fontDescriptor = adoptCF(CTFontDescriptorCreateWithTextStyle(familyNameStr.get(), RenderThemeIOS::contentSizeCategory(), nullptr));
-    if (symbolicTraits)
-        fontDescriptor = adoptCF(CTFontDescriptorCreateCopyWithSymbolicTraits(fontDescriptor.get(), symbolicTraits, symbolicTraits));
</del><ins>+float FontCache::weightOfCTFont(CTFontRef font)
+{
+    RetainPtr&lt;CFDictionaryRef&gt; traits = adoptCF(CTFontCopyTraits(font));
</ins><span class="cx"> 
</span><del>-    return CTFontCreateWithFontDescriptor(fontDescriptor.get(), size, nullptr);
</del><ins>+    CFNumberRef resultRef = (CFNumberRef)CFDictionaryGetValue(traits.get(), kCTFontWeightTrait);
+    float result = 0;
+    CFNumberGetValue(resultRef, kCFNumberFloatType, &amp;result);
+
+    return result;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static CTFontRef createCTFontWithFamilyNameAndWeight(const String&amp; familyName, CTFontSymbolicTraits traits, float size, uint16_t weight)
</del><ins>+RetainPtr&lt;CTFontRef&gt; platformFontWithFamilySpecialCase(const AtomicString&amp; family, FontWeight weight, CTFontSymbolicTraits traits, float size)
</ins><span class="cx"> {
</span><del>-    if (familyName.isNull())
-        return nullptr;
</del><ins>+    if (family.startsWith(&quot;UICTFontTextStyle&quot;)) {
+        traits &amp;= (kCTFontBoldTrait | kCTFontItalicTrait);
+        RetainPtr&lt;CFStringRef&gt; familyNameStr = family.string().createCFString();
+        RetainPtr&lt;CTFontDescriptorRef&gt; fontDescriptor = adoptCF(CTFontDescriptorCreateWithTextStyle(familyNameStr.get(), RenderThemeIOS::contentSizeCategory(), nullptr));
+        if (traits)
+            fontDescriptor = adoptCF(CTFontDescriptorCreateCopyWithSymbolicTraits(fontDescriptor.get(), traits, traits));
</ins><span class="cx"> 
</span><ins>+        return adoptCF(CTFontCreateWithFontDescriptor(fontDescriptor.get(), size, nullptr));
+    }
+
</ins><span class="cx">     static NeverDestroyed&lt;AtomicString&gt; systemUIFontWithWebKitPrefix(&quot;-webkit-system-font&quot;, AtomicString::ConstructFromLiteral);
</span><span class="cx">     static NeverDestroyed&lt;AtomicString&gt; systemUIFontWithApplePrefix(&quot;-apple-system&quot;, AtomicString::ConstructFromLiteral);
</span><span class="cx">     static NeverDestroyed&lt;AtomicString&gt; systemUIFontWithAppleAlternatePrefix(&quot;-apple-system-font&quot;, AtomicString::ConstructFromLiteral);
</span><del>-    if (equalIgnoringCase(familyName, systemUIFontWithWebKitPrefix) || equalIgnoringCase(familyName, systemUIFontWithApplePrefix) || equalIgnoringCase(familyName, systemUIFontWithAppleAlternatePrefix)) {
</del><ins>+    if (equalIgnoringCase(family, systemUIFontWithWebKitPrefix) || equalIgnoringCase(family, systemUIFontWithApplePrefix) || equalIgnoringCase(family, systemUIFontWithAppleAlternatePrefix)) {
</ins><span class="cx">         CTFontUIFontType fontType = kCTFontUIFontSystem;
</span><del>-        if (weight &gt; 300) {
</del><ins>+        if (weight &gt; FontWeight300) {
</ins><span class="cx">             // The comment below has been copied from CoreText/UIFoundation. However, in WebKit we synthesize the oblique,
</span><span class="cx">             // so we should investigate the result &lt;rdar://problem/14449340&gt;:
</span><span class="cx">             if (traits &amp; kCTFontTraitBold)
</span><span class="cx">                 fontType = kCTFontUIFontEmphasizedSystem;
</span><del>-        } else if (weight &gt; 250)
</del><ins>+        } else if (weight &gt; FontWeight200)
</ins><span class="cx">             fontType = static_cast&lt;CTFontUIFontType&gt;(kCTFontUIFontSystemLight);
</span><del>-        else if (weight &gt; 150)
</del><ins>+        else if (weight &gt; FontWeight100)
</ins><span class="cx">             fontType = static_cast&lt;CTFontUIFontType&gt;(kCTFontUIFontSystemThin);
</span><span class="cx">         else
</span><span class="cx">             fontType = static_cast&lt;CTFontUIFontType&gt;(kCTFontUIFontSystemUltraLight);
</span><span class="cx">         RetainPtr&lt;CTFontDescriptorRef&gt; fontDescriptor = adoptCF(CTFontDescriptorCreateForUIType(fontType, size, nullptr));
</span><span class="cx">         if (traits &amp; kCTFontTraitItalic)
</span><span class="cx">             fontDescriptor = adoptCF(CTFontDescriptorCreateCopyWithSymbolicTraits(fontDescriptor.get(), kCTFontItalicTrait, kCTFontItalicTrait));
</span><del>-        return CTFontCreateWithFontDescriptor(fontDescriptor.get(), size, nullptr);
</del><ins>+        return adoptCF(CTFontCreateWithFontDescriptor(fontDescriptor.get(), size, nullptr));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     static NeverDestroyed&lt;AtomicString&gt; systemUIMonospacedNumbersFontWithApplePrefix(&quot;-apple-system-monospaced-numbers&quot;, AtomicString::ConstructFromLiteral);
</span><del>-    if (equalIgnoringCase(familyName, systemUIMonospacedNumbersFontWithApplePrefix)) {
</del><ins>+    if (equalIgnoringCase(family, systemUIMonospacedNumbersFontWithApplePrefix)) {
</ins><span class="cx">         RetainPtr&lt;CTFontDescriptorRef&gt; systemFontDescriptor = adoptCF(CTFontDescriptorCreateForUIType(kCTFontUIFontSystem, size, nullptr));
</span><span class="cx">         RetainPtr&lt;CTFontDescriptorRef&gt; monospaceFontDescriptor = adoptCF(CTFontDescriptorCreateCopyWithFeature(systemFontDescriptor.get(), (CFNumberRef)@(kNumberSpacingType), (CFNumberRef)@(kMonospacedNumbersSelector)));
</span><del>-        return CTFontCreateWithFontDescriptor(monospaceFontDescriptor.get(), size, nullptr);
</del><ins>+        return adoptCF(CTFontCreateWithFontDescriptor(monospaceFontDescriptor.get(), size, nullptr));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-
-    RetainPtr&lt;CFStringRef&gt; familyNameStr = familyName.createCFString();
-    CTFontSymbolicTraits requestedTraits = (CTFontSymbolicTraits)(traits &amp; (kCTFontBoldTrait | kCTFontItalicTrait));
-    return CTFontCreateForCSS(familyNameStr.get(), weight, requestedTraits, size);
</del><ins>+    return nullptr;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static uint16_t toCTFontWeight(FontWeight fontWeight)
-{
-    switch (fontWeight) {
-    case FontWeight100:
-        return 100;
-    case FontWeight200:
-        return 200;
-    case FontWeight300:
-        return 300;
-    case FontWeight400:
-        return 400;
-    case FontWeight500:
-        return 500;
-    case FontWeight600:
-        return 600;
-    case FontWeight700:
-        return 700;
-    case FontWeight800:
-        return 800;
-    case FontWeight900:
-        return 900;
-    default:
-        return 400;
-    }
-}
-
-std::unique_ptr&lt;FontPlatformData&gt; FontCache::createFontPlatformData(const FontDescription&amp; fontDescription, const AtomicString&amp; family)
-{
-    CTFontSymbolicTraits traits = 0;
-    if (fontDescription.italic())
-        traits |= kCTFontTraitItalic;
-    if (isFontWeightBold(fontDescription.weight()))
-        traits |= kCTFontTraitBold;
-    float size = fontDescription.computedPixelSize();
-
-    RetainPtr&lt;CTFontRef&gt; ctFont;
-    if (family.startsWith(&quot;UICTFontTextStyle&quot;))
-        ctFont = adoptCF(createCTFontWithTextStyle(family, traits, size));
-    else
-        ctFont = adoptCF(createCTFontWithFamilyNameAndWeight(family, traits, size, toCTFontWeight(fontDescription.weight())));
-    if (!ctFont)
-        return nullptr;
-
-    ctFont = preparePlatformFont(ctFont.get(), fontDescription.textRenderingMode(), fontDescription.featureSettings());
-
-    CTFontSymbolicTraits actualTraits = 0;
-    if (isFontWeightBold(fontDescription.weight()) || fontDescription.italic())
-        actualTraits = CTFontGetSymbolicTraits(ctFont.get());
-
-    bool isAppleColorEmoji = CTFontIsAppleColorEmoji(ctFont.get());
-
-    bool syntheticBold = (fontDescription.fontSynthesis() &amp; FontSynthesisWeight) &amp;&amp; (traits &amp; kCTFontTraitBold) &amp;&amp; !(actualTraits &amp; kCTFontTraitBold) &amp;&amp; !isAppleColorEmoji;
-    bool syntheticOblique = (fontDescription.fontSynthesis() &amp; FontSynthesisStyle) &amp;&amp; (traits &amp; kCTFontTraitItalic) &amp;&amp; !(actualTraits &amp; kCTFontTraitItalic) &amp;&amp; !isAppleColorEmoji;
-
-    auto result = std::make_unique&lt;FontPlatformData&gt;(ctFont.get(), size, syntheticBold, syntheticOblique, fontDescription.orientation(), fontDescription.widthVariant(), fontDescription.textRenderingMode());
-    return result;
-}
-
</del><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsmacFontCacheMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/mac/FontCacheMac.mm (188870 => 188871)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/mac/FontCacheMac.mm        2015-08-24 18:07:48 UTC (rev 188870)
+++ trunk/Source/WebCore/platform/graphics/mac/FontCacheMac.mm        2015-08-24 18:37:37 UTC (rev 188871)
</span><span class="lines">@@ -112,9 +112,6 @@
</span><span class="cx">     return candidateWeightDeltaMagnitude &lt; chosenWeightDeltaMagnitude;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#endif
-
-#if !ENABLE(PLATFORM_FONT_LOOKUP)
</del><span class="cx"> // Keep a cache for mapping desired font families to font families actually available on the system for performance.
</span><span class="cx"> using AvailableFamilyMap = HashMap&lt;std::pair&lt;AtomicString, NSFontTraitMask&gt;, AtomicString&gt;;
</span><span class="cx"> static AvailableFamilyMap&amp; desiredFamilyToAvailableFamilyMap()
</span><span class="lines">@@ -144,40 +141,6 @@
</span><span class="cx">     familyMapping.add(std::make_pair(desiredFamily, desiredTraits), value);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#else
-
-static uint16_t toCoreTextFontWeight(FontWeight fontWeight)
-{
-    static const int coreTextFontWeights[] = {
-        100, // FontWeight100
-        200, // FontWeight200
-        300, // FontWeight300
-        400, // FontWeight400
-        500, // FontWeight500
-        600, // FontWeight600
-        700, // FontWeight700
-        800, // FontWeight800
-        900, // FontWeight900
-    };
-    return coreTextFontWeights[fontWeight];
-}
-#endif
-
-typedef HashSet&lt;String, CaseFoldingHash&gt; Whitelist;
-static Whitelist&amp; fontWhitelist()
-{
-    static NeverDestroyed&lt;Whitelist&gt; whitelist;
-    return whitelist;
-}
-
-void FontCache::setFontWhitelist(const Vector&lt;String&gt;&amp; inputWhitelist)
-{
-    Whitelist&amp; whitelist = fontWhitelist();
-    whitelist.clear();
-    for (auto&amp; item : inputWhitelist)
-        whitelist.add(item);
-}
-
</del><span class="cx"> static int toAppKitFontWeight(FontWeight fontWeight)
</span><span class="cx"> {
</span><span class="cx">     static const int appKitFontWeights[] = {
</span><span class="lines">@@ -194,6 +157,29 @@
</span><span class="cx">     return appKitFontWeights[fontWeight];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static inline FontWeight appkitWeightToFontWeight(NSInteger appKitWeight)
+{
+    if (appKitWeight == 1)
+        return FontWeight100;
+    if (appKitWeight == 2)
+        return FontWeight200;
+    if (appKitWeight &lt;= 4)
+        return FontWeight300;
+    if (appKitWeight == 5)
+        return FontWeight400;
+    if (appKitWeight == 6)
+        return FontWeight500;
+    if (appKitWeight &lt;= 8)
+        return FontWeight600;
+    if (appKitWeight == 9)
+        return FontWeight700;
+    if (appKitWeight &lt;= 11)
+        return FontWeight800;
+    return FontWeight900;
+}
+
+#endif // PLATFORM_FONT_LOOKUP
+
</ins><span class="cx"> #if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101000
</span><span class="cx"> static CGFloat toNSFontWeight(FontWeight fontWeight)
</span><span class="cx"> {
</span><span class="lines">@@ -213,77 +199,69 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-static Optional&lt;NSFont*&gt; fontWithFamilySpecialCase(const AtomicString&amp; family, FontWeight weight, NSFontTraitMask desiredTraits, float size)
</del><ins>+static NSFontTraitMask toNSFontTraits(CTFontSymbolicTraits traits)
</ins><span class="cx"> {
</span><ins>+    NSFontTraitMask result = 0;
+    if (traits &amp; kCTFontBoldTrait)
+        result |= NSBoldFontMask;
+    if (traits &amp; kCTFontItalicTrait)
+        result |= NSItalicFontMask;
+    return result;
+}
+
+RetainPtr&lt;CTFontRef&gt; platformFontWithFamilySpecialCase(const AtomicString&amp; family, FontWeight weight, CTFontSymbolicTraits desiredTraits, float size)
+{
</ins><span class="cx">     if (equalIgnoringASCIICase(family, &quot;-webkit-system-font&quot;)
</span><span class="cx">         || equalIgnoringASCIICase(family, &quot;-apple-system&quot;)
</span><span class="cx">         || equalIgnoringASCIICase(family, &quot;-apple-system-font&quot;)) {
</span><span class="cx"> #if __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101000
</span><del>-        NSFont *result = [NSFont systemFontOfSize:size weight:toNSFontWeight(weight)];
</del><ins>+        RetainPtr&lt;CTFontRef&gt; result = toCTFont([NSFont systemFontOfSize:size weight:toNSFontWeight(weight)]);
</ins><span class="cx"> #else
</span><del>-        NSFont *result = (weight &gt;= FontWeight600) ? [NSFont boldSystemFontOfSize:size] : [NSFont systemFontOfSize:size];
</del><ins>+        RetainPtr&lt;CTFontRef&gt; result = toCTFont((weight &gt;= FontWeight600) ? [NSFont boldSystemFontOfSize:size] : [NSFont systemFontOfSize:size]);
</ins><span class="cx"> #endif
</span><del>-        if (desiredTraits &amp; NSFontItalicTrait)
-            result = [[NSFontManager sharedFontManager] convertFont:result toHaveTrait:desiredTraits];
</del><ins>+        if (desiredTraits &amp; kCTFontItalicTrait) {
+            if (auto italicizedFont = adoptCF(CTFontCreateCopyWithSymbolicTraits(result.get(), size, nullptr, desiredTraits, desiredTraits)))
+                result = italicizedFont;
+        }
</ins><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (equalIgnoringASCIICase(family, &quot;-apple-system-monospaced-numbers&quot;)) {
</span><del>-        NSArray *featureArray = @[ @{ NSFontFeatureTypeIdentifierKey : @(kNumberSpacingType),
-            NSFontFeatureSelectorIdentifierKey : @(kMonospacedNumbersSelector) } ];
</del><ins>+        int numberSpacingType = kNumberSpacingType;
+        int monospacedNumbersSelector = kMonospacedNumbersSelector;
+        RetainPtr&lt;CFNumberRef&gt; numberSpacingNumber = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &amp;numberSpacingType));
+        RetainPtr&lt;CFNumberRef&gt; monospacedNumbersNumber = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &amp;monospacedNumbersSelector));
+        CFTypeRef featureKeys[] = { kCTFontFeatureTypeIdentifierKey, kCTFontFeatureSelectorIdentifierKey };
+        CFTypeRef featureValues[] = { numberSpacingNumber.get(), monospacedNumbersNumber.get() };
+        RetainPtr&lt;CFDictionaryRef&gt; featureIdentifier = adoptCF(CFDictionaryCreate(kCFAllocatorDefault, featureKeys, featureValues, WTF_ARRAY_LENGTH(featureKeys), &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks));
+        CFTypeRef featureIdentifiers[] = { featureIdentifier.get() };
+        RetainPtr&lt;CFArrayRef&gt; featureArray = adoptCF(CFArrayCreate(kCFAllocatorDefault, featureIdentifiers, 1, &amp;kCFTypeArrayCallBacks));
+        CFTypeRef attributesKeys[] = { kCTFontFeatureSettingsAttribute };
+        CFTypeRef attributesValues[] = { featureArray.get() };
+        RetainPtr&lt;CFDictionaryRef&gt; attributes = adoptCF(CFDictionaryCreate(kCFAllocatorDefault, attributesKeys, attributesValues, WTF_ARRAY_LENGTH(attributesKeys), &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks));
</ins><span class="cx"> 
</span><del>-        NSFont* systemFont = [NSFont systemFontOfSize:size];
-        NSFontDescriptor* desc = [systemFont.fontDescriptor fontDescriptorByAddingAttributes:@{ NSFontFeatureSettingsAttribute : featureArray }];
-        return [NSFont fontWithDescriptor:desc size:size];
</del><ins>+        RetainPtr&lt;CTFontRef&gt; result = toCTFont([NSFont systemFontOfSize:size]);
+        return adoptCF(CTFontCreateCopyWithAttributes(result.get(), size, nullptr, adoptCF(CTFontDescriptorCreateWithAttributes(attributes.get())).get()));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (equalIgnoringASCIICase(family, &quot;-apple-menu&quot;))
</span><del>-        return [NSFont menuFontOfSize:size];
</del><ins>+        return toCTFont([NSFont menuFontOfSize:size]);
</ins><span class="cx"> 
</span><span class="cx">     if (equalIgnoringASCIICase(family, &quot;-apple-status-bar&quot;))
</span><del>-        return [NSFont labelFontOfSize:size];
</del><ins>+        return toCTFont([NSFont labelFontOfSize:size]);
</ins><span class="cx"> 
</span><del>-    return Optional&lt;NSFont*&gt;(Nullopt);
</del><ins>+    return nullptr;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-// Family name is somewhat of a misnomer here. We first attempt to find an exact match
-// comparing the desiredFamily to the PostScript name of the installed fonts. If that fails
-// we then do a search based on the family names of the installed fonts.
-static NSFont *fontWithFamily(const AtomicString&amp; family, NSFontTraitMask desiredTraits, FontWeight weight, const FontFeatureSettings* featureSettings, TextRenderingMode textRenderingMode, float size)
</del><ins>+#if !ENABLE(PLATFORM_FONT_LOOKUP)
+RetainPtr&lt;CTFontRef&gt; platformFontWithFamily(const AtomicString&amp; family, CTFontSymbolicTraits requestedTraits, FontWeight weight, const FontFeatureSettings*, TextRenderingMode, float size)
</ins><span class="cx"> {
</span><del>-    if (const auto&amp; specialCase = fontWithFamilySpecialCase(family, weight, desiredTraits, size))
-        return specialCase.value();
-
</del><span class="cx">     NSFontManager *fontManager = [NSFontManager sharedFontManager];
</span><span class="cx">     NSString *availableFamily;
</span><span class="cx">     int chosenWeight;
</span><span class="cx">     NSFont *font;
</span><span class="cx"> 
</span><del>-#if ENABLE(PLATFORM_FONT_LOOKUP)
-
-    const auto&amp; whitelist = fontWhitelist();
-    if (whitelist.size() &amp;&amp; !whitelist.contains(family.lower()))
-        return nil;
-    CTFontSymbolicTraits requestedTraits = 0;
-    if (desiredTraits &amp; NSFontItalicTrait)
-        requestedTraits |= kCTFontItalicTrait;
-    if (weight &gt;= FontWeight600)
-        requestedTraits |= kCTFontBoldTrait;
-
-    NSString *desiredFamily = family;
-    RetainPtr&lt;CTFontRef&gt; foundFont = adoptCF(CTFontCreateForCSS((CFStringRef)desiredFamily, toCoreTextFontWeight(weight), requestedTraits, size));
-    foundFont = preparePlatformFont(foundFont.get(), textRenderingMode, featureSettings);
-    if (!foundFont)
-        return nil;
-    font = CFBridgingRelease(CFRetain(foundFont.get()));
-    availableFamily = [font familyName];
-    chosenWeight = [fontManager weightOfFont:font];
-
-#else
-
-    UNUSED_PARAM(featureSettings);
-    UNUSED_PARAM(textRenderingMode);
-
</del><ins>+    NSFontTraitMask desiredTraits = toNSFontTraits(requestedTraits);
</ins><span class="cx">     NSFontTraitMask desiredTraitsForNameMatch = desiredTraits | (weight &gt;= FontWeight600 ? NSBoldFontMask : 0);
</span><span class="cx">     if (hasDesiredFamilyToAvailableFamilyMapping(family, desiredTraitsForNameMatch, availableFamily)) {
</span><span class="cx">         if (!availableFamily) {
</span><span class="lines">@@ -313,11 +291,11 @@
</span><span class="cx">                     // Special case Osaka-Mono. According to &lt;rdar://problem/3999467&gt;, we need to
</span><span class="cx">                     // treat Osaka-Mono as fixed pitch.
</span><span class="cx">                     if ([desiredFamily caseInsensitiveCompare:@&quot;Osaka-Mono&quot;] == NSOrderedSame &amp;&amp; !desiredTraitsForNameMatch)
</span><del>-                        return nameMatchedFont;
</del><ins>+                        return toCTFont(nameMatchedFont);
</ins><span class="cx"> 
</span><span class="cx">                     NSFontTraitMask traits = [fontManager traitsOfFont:nameMatchedFont];
</span><span class="cx">                     if ((traits &amp; desiredTraitsForNameMatch) == desiredTraitsForNameMatch)
</span><del>-                        return [fontManager convertFont:nameMatchedFont toHaveTrait:desiredTraitsForNameMatch];
</del><ins>+                        return toCTFont([fontManager convertFont:nameMatchedFont toHaveTrait:desiredTraitsForNameMatch]);
</ins><span class="cx"> 
</span><span class="cx">                     availableFamily = [nameMatchedFont familyName];
</span><span class="cx">                     break;
</span><span class="lines">@@ -372,9 +350,9 @@
</span><span class="cx">     NSFontTraitMask actualTraits = 0;
</span><span class="cx">     if (desiredTraits &amp; NSFontItalicTrait)
</span><span class="cx">         actualTraits = [fontManager traitsOfFont:font];
</span><del>-    int actualWeight = [fontManager weightOfFont:font];
</del><ins>+    FontWeight actualWeight = appkitWeightToFontWeight([fontManager weightOfFont:font]);
</ins><span class="cx"> 
</span><del>-    bool syntheticBold = toAppKitFontWeight(weight) &gt;= 7 &amp;&amp; actualWeight &lt; 7;
</del><ins>+    bool syntheticBold = isFontWeightBold(weight) &amp;&amp; isFontWeightBold(actualWeight);
</ins><span class="cx">     bool syntheticOblique = (desiredTraits &amp; NSFontItalicTrait) &amp;&amp; !(actualTraits &amp; NSFontItalicTrait);
</span><span class="cx"> 
</span><span class="cx">     // There are some malformed fonts that will be correctly returned by -fontWithFamily:traits:weight:size: as a match for a particular trait,
</span><span class="lines">@@ -396,89 +374,24 @@
</span><span class="cx">             font = fontWithoutSyntheticTraits;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    return toCTFont(font);
+}
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    return font;
-}
-
-static void invalidateFontCache()
</del><ins>+void platformInvalidateFontCache()
</ins><span class="cx"> {
</span><del>-    if (!isMainThread()) {
-        callOnMainThread([] {
-            invalidateFontCache();
-        });
-        return;
-    }
-
-    FontCache::singleton().invalidate();
-
</del><span class="cx"> #if !ENABLE(PLATFORM_FONT_LOOKUP)
</span><span class="cx">     desiredFamilyToAvailableFamilyMap().clear();
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void fontCacheRegisteredFontsChangedNotificationCallback(CFNotificationCenterRef, void* observer, CFStringRef name, const void *, CFDictionaryRef)
</del><ins>+RetainPtr&lt;CTFontRef&gt; platformLookupFallbackFont(CTFontRef font, FontWeight, const AtomicString&amp; locale, const UChar* characters, unsigned length)
</ins><span class="cx"> {
</span><del>-    ASSERT_UNUSED(observer, observer == &amp;FontCache::singleton());
-    ASSERT_UNUSED(name, CFEqual(name, kCTFontManagerRegisteredFontsChangedNotification));
-
-    invalidateFontCache();
-}
-
-void FontCache::platformInit()
-{
-    CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(), this, fontCacheRegisteredFontsChangedNotificationCallback, kCTFontManagerRegisteredFontsChangedNotification, 0, CFNotificationSuspensionBehaviorDeliverImmediately);
-}
-
-static inline bool isAppKitFontWeightBold(NSInteger appKitFontWeight)
-{
-    return appKitFontWeight &gt;= 7;
-}
-
-static bool shouldAutoActivateFontIfNeeded(const AtomicString&amp; family)
-{
-#ifndef NDEBUG
-    // This cache is not thread safe so the following assertion is there to
-    // make sure this function is always called from the same thread.
-    static ThreadIdentifier initThreadId = currentThread();
-    ASSERT(currentThread() == initThreadId);
-#endif
-
-    static NeverDestroyed&lt;HashSet&lt;AtomicString&gt;&gt; knownFamilies;
-    static const unsigned maxCacheSize = 128;
-    ASSERT(knownFamilies.get().size() &lt;= maxCacheSize);
-    if (knownFamilies.get().size() == maxCacheSize)
-        knownFamilies.get().remove(knownFamilies.get().begin());
-
-    // Only attempt to auto-activate fonts once for performance reasons.
-    return knownFamilies.get().add(family).isNewEntry;
-}
-
-typedef HashSet&lt;RetainPtr&lt;CTFontRef&gt;, WTF::RetainPtrObjectHash&lt;CTFontRef&gt;, WTF::RetainPtrObjectHashTraits&lt;CTFontRef&gt;&gt; FallbackDedupSet;
-static FallbackDedupSet&amp; fallbackDedupSet()
-{
-    static NeverDestroyed&lt;FallbackDedupSet&gt; dedupSet;
-    return dedupSet.get();
-}
-
-void FontCache::platformPurgeInactiveFontData()
-{
-    Vector&lt;CTFontRef&gt; toRemove;
-    for (auto&amp; font : fallbackDedupSet()) {
-        if (CFGetRetainCount(font.get()) == 1)
-            toRemove.append(font.get());
-    }
-    for (auto&amp; font : toRemove)
-        fallbackDedupSet().remove(font);
-}
-
-static inline RetainPtr&lt;CTFontRef&gt; lookupCTFont(CTFontRef font, float fontSize, const AtomicString&amp; locale, const UChar* characters, unsigned length)
-{
</del><span class="cx">     RetainPtr&lt;CFStringRef&gt; localeString;
</span><span class="cx"> #if __MAC_OS_X_VERSION_MIN_REQUIRED == 1090
</span><span class="cx">     UNUSED_PARAM(locale);
</span><span class="cx">     if (!font) {
</span><del>-        font = toCTFont([NSFont userFontOfSize:fontSize]);
</del><ins>+        font = toCTFont([NSFont userFontOfSize:CTFontGetSize(font)]);
</ins><span class="cx">         bool acceptable = true;
</span><span class="cx">         
</span><span class="cx">         RetainPtr&lt;CFCharacterSetRef&gt; characterSet = adoptCF(CTFontCopyCharacterSet(font));
</span><span class="lines">@@ -492,11 +405,9 @@
</span><span class="cx">             return font;
</span><span class="cx">     }
</span><span class="cx"> #elif __MAC_OS_X_VERSION_MIN_REQUIRED &gt; 101100
</span><del>-    UNUSED_PARAM(fontSize);
</del><span class="cx">     if (!locale.isNull())
</span><span class="cx">         localeString = locale.string().createCFString();
</span><span class="cx"> #else
</span><del>-    UNUSED_PARAM(fontSize);
</del><span class="cx">     UNUSED_PARAM(locale);
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -504,120 +415,20 @@
</span><span class="cx">     return adoptCF(CTFontCreateForCharactersWithLanguage(font, characters, length, localeString.get(), &amp;coveredLength));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr&lt;Font&gt; FontCache::systemFallbackForCharacters(const FontDescription&amp; description, const Font* originalFontData, bool isPlatformFont, const UChar* characters, unsigned length)
-{
-    const FontPlatformData&amp; platformData = originalFontData-&gt;platformData();
-    NSFont *nsFont = platformData.nsFont();
-    RetainPtr&lt;CTFontRef&gt; result = lookupCTFont(platformData.font(), platformData.size(), description.locale(), characters, length);
-    result = preparePlatformFont(result.get(), description.textRenderingMode(), description.featureSettings());
-    if (!result)
-        return nullptr;
-
-    // FontCascade::drawGlyphBuffer() requires that there are no duplicate Font objects which refer to the same thing. This is enforced in
-    // FontCache::fontForPlatformData(), where our equality check is based on hashing the FontPlatformData, whose hash includes the raw CoreText
-    // font pointer.
-    NSFont *substituteFont = toNSFont(fallbackDedupSet().add(result).iterator-&gt;get());
-
-    NSFontManager *fontManager = [NSFontManager sharedFontManager];
-
-    NSFontTraitMask traits = 0;
-    NSInteger weight;
-
-    if (nsFont) {
-        if (description.italic())
-            traits = [fontManager traitsOfFont:nsFont];
-        if (platformData.m_syntheticBold)
-            traits |= NSBoldFontMask;
-        if (platformData.m_syntheticOblique)
-            traits |= NSFontItalicTrait;
-        weight = [fontManager weightOfFont:nsFont];
-    } else {
-        ASSERT(!CORETEXT_WEB_FONTS);
-        traits = description.italic() ? NSFontItalicTrait : 0;
-        weight = toAppKitFontWeight(description.weight());
-    }
-
-    NSFontTraitMask substituteFontTraits = [fontManager traitsOfFont:substituteFont];
-    NSInteger substituteFontWeight = [fontManager weightOfFont:substituteFont];
-
-    FontPlatformData alternateFont(toCTFont(substituteFont), platformData.size(),
-        !isPlatformFont &amp;&amp; isAppKitFontWeightBold(weight) &amp;&amp; !isAppKitFontWeightBold(substituteFontWeight),
-        !isPlatformFont &amp;&amp; (traits &amp; NSFontItalicTrait) &amp;&amp; !(substituteFontTraits &amp; NSFontItalicTrait),
-        platformData.m_orientation, platformData.m_widthVariant, platformData.m_textRenderingMode);
-
-    return fontForPlatformData(alternateFont);
-}
-
-Vector&lt;String&gt; FontCache::systemFontFamilies()
-{
-    Vector&lt;String&gt; fontFamilies;
-    RetainPtr&lt;CFArrayRef&gt; availableFontFamilies = adoptCF(CTFontManagerCopyAvailableFontFamilyNames());
-    CFIndex count = CFArrayGetCount(availableFontFamilies.get());
-    for (CFIndex i = 0; i &lt; count; ++i) {
-        CFStringRef fontName = static_cast&lt;CFStringRef&gt;(CFArrayGetValueAtIndex(availableFontFamilies.get(), i));
-        if (CFGetTypeID(fontName) != CFStringGetTypeID()) {
-            ASSERT_NOT_REACHED();
-            continue;
-        }
-        // We don't want to make the hidden system fonts visible and since they
-        // all begin with a period, ignore all fonts that begin with a period.
-        if (CFStringHasPrefix(fontName, CFSTR(&quot;.&quot;)))
-            continue;
-        fontFamilies.append(fontName);
-    }
-    return fontFamilies;
-}
-
</del><span class="cx"> Ref&lt;Font&gt; FontCache::lastResortFallbackFont(const FontDescription&amp; fontDescription)
</span><span class="cx"> {
</span><del>-    DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, timesStr, (&quot;Times&quot;, AtomicString::ConstructFromLiteral));
-
</del><span class="cx">     // FIXME: Would be even better to somehow get the user's default font here.  For now we'll pick
</span><span class="cx">     // the default that the user would get without changing any prefs.
</span><del>-    RefPtr&lt;Font&gt; font = fontForFamily(fontDescription, timesStr, false);
-    if (font)
</del><ins>+    if (RefPtr&lt;Font&gt; font = fontForFamily(fontDescription, AtomicString(&quot;Times&quot;, AtomicString::ConstructFromLiteral), false))
</ins><span class="cx">         return *font;
</span><span class="cx"> 
</span><span class="cx">     // The Times fallback will almost always work, but in the highly unusual case where
</span><span class="cx">     // the user doesn't have it, we fall back on Lucida Grande because that's
</span><span class="cx">     // guaranteed to be there, according to Nathan Taylor. This is good enough
</span><span class="cx">     // to avoid a crash at least.
</span><del>-    DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, lucidaGrandeStr, (&quot;Lucida Grande&quot;, AtomicString::ConstructFromLiteral));
-    return *fontForFamily(fontDescription, lucidaGrandeStr, false);
</del><ins>+    return *fontForFamily(fontDescription, AtomicString(&quot;Lucida Grande&quot;, AtomicString::ConstructFromLiteral), false);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-std::unique_ptr&lt;FontPlatformData&gt; FontCache::createFontPlatformData(const FontDescription&amp; fontDescription, const AtomicString&amp; family)
-{
-    NSFontTraitMask traits = fontDescription.italic() ? NSFontItalicTrait : 0;
-    float size = fontDescription.computedPixelSize();
-
-    NSFont *nsFont = fontWithFamily(family, traits, fontDescription.weight(), fontDescription.featureSettings(), fontDescription.textRenderingMode(), size);
-    if (!nsFont) {
-        if (!shouldAutoActivateFontIfNeeded(family))
-            return nullptr;
-
-        // 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.
-        [NSFont fontWithName:family size:size];
-
-        nsFont = fontWithFamily(family, traits, fontDescription.weight(), fontDescription.featureSettings(), fontDescription.textRenderingMode(), size);
-        if (!nsFont)
-            return nullptr;
-    }
-
-    NSFontManager *fontManager = [NSFontManager sharedFontManager];
-    NSFontTraitMask actualTraits = 0;
-    if (fontDescription.italic())
-        actualTraits = [fontManager traitsOfFont:nsFont];
-    NSInteger actualWeight = [fontManager weightOfFont:nsFont];
-
-    NSFont *platformFont = [nsFont printerFont];
-    bool syntheticBold = (fontDescription.fontSynthesis() &amp; FontSynthesisWeight) &amp;&amp; isAppKitFontWeightBold(toAppKitFontWeight(fontDescription.weight())) &amp;&amp; !isAppKitFontWeightBold(actualWeight);
-    bool syntheticOblique = (fontDescription.fontSynthesis() &amp; FontSynthesisStyle) &amp;&amp; (traits &amp; NSFontItalicTrait) &amp;&amp; !(actualTraits &amp; NSFontItalicTrait);
-
-    return std::make_unique&lt;FontPlatformData&gt;(toCTFont(platformFont), size, syntheticBold, syntheticOblique, fontDescription.orientation(), fontDescription.widthVariant(), fontDescription.textRenderingMode());
-}
-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // !PLATFORM(IOS)
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderThemeIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderThemeIOS.mm (188870 => 188871)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderThemeIOS.mm        2015-08-24 18:07:48 UTC (rev 188870)
+++ trunk/Source/WebCore/rendering/RenderThemeIOS.mm        2015-08-24 18:37:37 UTC (rev 188871)
</span><span class="lines">@@ -1078,30 +1078,6 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static FontWeight fromCTFontWeight(float fontWeight)
-{
-    if (fontWeight &lt;= -0.8)
-        return FontWeight100;
-    else if (fontWeight &lt;= -0.4)
-        return FontWeight200;
-    else if (fontWeight &lt;= -0.2)
-        return FontWeight300;
-    else if (fontWeight &lt;= 0.0)
-        return FontWeight400;
-    else if (fontWeight &lt;= 0.2)
-        return FontWeight500;
-    else if (fontWeight &lt;= 0.3)
-        return FontWeight600;
-    else if (fontWeight &lt;= 0.4)
-        return FontWeight700;
-    else if (fontWeight &lt;= 0.6)
-        return FontWeight800;
-    else if (fontWeight &lt;= 0.8)
-        return FontWeight900;
-
-    return FontWeightNormal;
-}
-
</del><span class="cx"> FontDescription&amp; RenderThemeIOS::cachedSystemFontDescription(CSSValueID valueID) const
</span><span class="cx"> {
</span><span class="cx">     static NeverDestroyed&lt;FontDescription&gt; systemFont;
</span><span class="lines">@@ -1265,7 +1241,7 @@
</span><span class="cx">     fontDescription.setIsAbsoluteSize(true);
</span><span class="cx">     fontDescription.setOneFamily(textStyle);
</span><span class="cx">     fontDescription.setSpecifiedSize(CTFontGetSize(font.get()));
</span><del>-    fontDescription.setWeight(fromCTFontWeight(FontCache::weightOfCTFont(font.get())));
</del><ins>+    fontDescription.setWeight(fontWeightFromCoreText(FontCache::weightOfCTFont(font.get())));
</ins><span class="cx">     fontDescription.setItalic(FontItalicOff);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>