<!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>[196322] 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/196322">196322</a></dd>
<dt>Author</dt> <dd>mmaxfield@apple.com</dd>
<dt>Date</dt> <dd>2016-02-09 11:50:05 -0800 (Tue, 09 Feb 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Decouple font creation from font loading
https://bugs.webkit.org/show_bug.cgi?id=153414

Reviewed by Darin Adler.

Previously, CSSFontFaceSource never triggered a font download until that font was actually used. This means
that the function which triggers the download also has the goal of returning a font to use. However,
the CSS Font Loading JavaScript API requires being able to trigger a font download without this extra font
creation overhead.

In addition, this patch adds an explicit (and enforced) state transition diagram. The diagram looks like
this:
                    =&gt; Success
                  //
Pending =&gt; Loading
                  \\
                    =&gt; Failure

Therefore, the API for CSSFontFaceSource has changed to expose the concept of these new states. This means
that its user (CSSSegmentedFontFaceSource) has been updated to handle each possible state that its constituent
CSSFontFaceSources may be in.

No new tests because there is no behavior change.

* css/CSSFontFace.cpp:
(WebCore::CSSFontFace::allSourcesFailed): Renamed to make the name clearer.
(WebCore::CSSFontFace::addedToSegmentedFontFace): Use references instead of pointers.
(WebCore::CSSFontFace::removedFromSegmentedFontFace): Ditto.
(WebCore::CSSFontFace::adoptSource): Renamed to make the name clearer.
(WebCore::CSSFontFace::fontLoaded): Use references instead of pointers. Also, remove old dead code.
(WebCore::CSSFontFace::font): Adapt to the new API of CSSFontFaceSource.
(WebCore::CSSFontFace::isValid): Deleted.
(WebCore::CSSFontFace::addSource): Deleted.
(WebCore::CSSFontFace::notifyFontLoader): Deleted. Old dead code.
(WebCore::CSSFontFace::notifyLoadingDone): Deleted. Old dead code.
* css/CSSFontFace.h:
(WebCore::CSSFontFace::create): Remove old dead code.
(WebCore::CSSFontFace::CSSFontFace): Use references instead of pointers.
(WebCore::CSSFontFace::loadState): Deleted. Remove old dead code.
* css/CSSFontFaceSource.cpp:
(WebCore::CSSFontFaceSource::setStatus): Enforce state transitions.
(WebCore::CSSFontFaceSource::CSSFontFaceSource): Explicitly handle new state transitions.
(WebCore::CSSFontFaceSource::fontLoaded): Update for new states.
(WebCore::CSSFontFaceSource::load): Pulled out code from font().
(WebCore::CSSFontFaceSource::font): Moved code into load().
(WebCore::CSSFontFaceSource::isValid): Deleted.
(WebCore::CSSFontFaceSource::isDecodeError): Deleted.
(WebCore::CSSFontFaceSource::ensureFontData): Deleted.
* css/CSSFontFaceSource.h: Much cleaner API.
* css/CSSFontSelector.cpp:
(WebCore::createFontFace): Migrate to references instead of pointers. This requires a little
reorganization.
(WebCore::registerLocalFontFacesForFamily): Update to new CSSFontFaceSource API.
(WebCore::CSSFontSelector::addFontFaceRule): Ditto.
(WebCore::CSSFontSelector::getFontFace): Ditto.
* css/CSSSegmentedFontFace.cpp:
(WebCore::CSSSegmentedFontFace::CSSSegmentedFontFace): Migrate to references instead of pointers.
(WebCore::CSSSegmentedFontFace::~CSSSegmentedFontFace): Ditto.
(WebCore::CSSSegmentedFontFace::fontLoaded): Remove old dead code.
(WebCore::CSSSegmentedFontFace::appendFontFace): Cleanup.
(WebCore::CSSSegmentedFontFace::fontRanges): Adopt to new API.
(WebCore::CSSSegmentedFontFace::pruneTable): Deleted.
(WebCore::CSSSegmentedFontFace::isLoading): Deleted. Old dead code.
(WebCore::CSSSegmentedFontFace::checkFont): Deleted. Ditto.
(WebCore::CSSSegmentedFontFace::loadFont): Deleted. Ditto.
* css/CSSSegmentedFontFace.h:
(WebCore::CSSSegmentedFontFace::create): Migrate to references instead of pointers.
(WebCore::CSSSegmentedFontFace::fontSelector): Ditto.
(WebCore::CSSSegmentedFontFace::LoadFontCallback::~LoadFontCallback): Deleted.
* loader/cache/CachedFont.cpp:
(WebCore::CachedFont::didAddClient): Migrate to references instead of pointers.
(WebCore::CachedFont::checkNotify): Ditto.
* loader/cache/CachedFontClient.h:
(WebCore::CachedFontClient::fontLoaded): Ditto.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorecssCSSFontFacecpp">trunk/Source/WebCore/css/CSSFontFace.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSFontFaceh">trunk/Source/WebCore/css/CSSFontFace.h</a></li>
<li><a href="#trunkSourceWebCorecssCSSFontFaceSourcecpp">trunk/Source/WebCore/css/CSSFontFaceSource.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSFontFaceSourceh">trunk/Source/WebCore/css/CSSFontFaceSource.h</a></li>
<li><a href="#trunkSourceWebCorecssCSSFontSelectorcpp">trunk/Source/WebCore/css/CSSFontSelector.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSSegmentedFontFacecpp">trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSSegmentedFontFaceh">trunk/Source/WebCore/css/CSSSegmentedFontFace.h</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedFontcpp">trunk/Source/WebCore/loader/cache/CachedFont.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedFontClienth">trunk/Source/WebCore/loader/cache/CachedFontClient.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (196321 => 196322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-02-09 18:57:05 UTC (rev 196321)
+++ trunk/Source/WebCore/ChangeLog        2016-02-09 19:50:05 UTC (rev 196322)
</span><span class="lines">@@ -1,3 +1,80 @@
</span><ins>+2016-02-09  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        Decouple font creation from font loading
+        https://bugs.webkit.org/show_bug.cgi?id=153414
+
+        Reviewed by Darin Adler.
+
+        Previously, CSSFontFaceSource never triggered a font download until that font was actually used. This means
+        that the function which triggers the download also has the goal of returning a font to use. However,
+        the CSS Font Loading JavaScript API requires being able to trigger a font download without this extra font
+        creation overhead.
+
+        In addition, this patch adds an explicit (and enforced) state transition diagram. The diagram looks like
+        this:
+                            =&gt; Success
+                          //
+        Pending =&gt; Loading
+                          \\
+                            =&gt; Failure
+
+        Therefore, the API for CSSFontFaceSource has changed to expose the concept of these new states. This means
+        that its user (CSSSegmentedFontFaceSource) has been updated to handle each possible state that its constituent
+        CSSFontFaceSources may be in.
+
+        No new tests because there is no behavior change.
+
+        * css/CSSFontFace.cpp:
+        (WebCore::CSSFontFace::allSourcesFailed): Renamed to make the name clearer.
+        (WebCore::CSSFontFace::addedToSegmentedFontFace): Use references instead of pointers.
+        (WebCore::CSSFontFace::removedFromSegmentedFontFace): Ditto.
+        (WebCore::CSSFontFace::adoptSource): Renamed to make the name clearer.
+        (WebCore::CSSFontFace::fontLoaded): Use references instead of pointers. Also, remove old dead code.
+        (WebCore::CSSFontFace::font): Adapt to the new API of CSSFontFaceSource.
+        (WebCore::CSSFontFace::isValid): Deleted.
+        (WebCore::CSSFontFace::addSource): Deleted.
+        (WebCore::CSSFontFace::notifyFontLoader): Deleted. Old dead code.
+        (WebCore::CSSFontFace::notifyLoadingDone): Deleted. Old dead code.
+        * css/CSSFontFace.h:
+        (WebCore::CSSFontFace::create): Remove old dead code.
+        (WebCore::CSSFontFace::CSSFontFace): Use references instead of pointers.
+        (WebCore::CSSFontFace::loadState): Deleted. Remove old dead code.
+        * css/CSSFontFaceSource.cpp:
+        (WebCore::CSSFontFaceSource::setStatus): Enforce state transitions.
+        (WebCore::CSSFontFaceSource::CSSFontFaceSource): Explicitly handle new state transitions.
+        (WebCore::CSSFontFaceSource::fontLoaded): Update for new states.
+        (WebCore::CSSFontFaceSource::load): Pulled out code from font().
+        (WebCore::CSSFontFaceSource::font): Moved code into load().
+        (WebCore::CSSFontFaceSource::isValid): Deleted.
+        (WebCore::CSSFontFaceSource::isDecodeError): Deleted.
+        (WebCore::CSSFontFaceSource::ensureFontData): Deleted.
+        * css/CSSFontFaceSource.h: Much cleaner API.
+        * css/CSSFontSelector.cpp:
+        (WebCore::createFontFace): Migrate to references instead of pointers. This requires a little
+        reorganization.
+        (WebCore::registerLocalFontFacesForFamily): Update to new CSSFontFaceSource API.
+        (WebCore::CSSFontSelector::addFontFaceRule): Ditto.
+        (WebCore::CSSFontSelector::getFontFace): Ditto.
+        * css/CSSSegmentedFontFace.cpp:
+        (WebCore::CSSSegmentedFontFace::CSSSegmentedFontFace): Migrate to references instead of pointers.
+        (WebCore::CSSSegmentedFontFace::~CSSSegmentedFontFace): Ditto.
+        (WebCore::CSSSegmentedFontFace::fontLoaded): Remove old dead code.
+        (WebCore::CSSSegmentedFontFace::appendFontFace): Cleanup.
+        (WebCore::CSSSegmentedFontFace::fontRanges): Adopt to new API.
+        (WebCore::CSSSegmentedFontFace::pruneTable): Deleted.
+        (WebCore::CSSSegmentedFontFace::isLoading): Deleted. Old dead code.
+        (WebCore::CSSSegmentedFontFace::checkFont): Deleted. Ditto.
+        (WebCore::CSSSegmentedFontFace::loadFont): Deleted. Ditto.
+        * css/CSSSegmentedFontFace.h:
+        (WebCore::CSSSegmentedFontFace::create): Migrate to references instead of pointers.
+        (WebCore::CSSSegmentedFontFace::fontSelector): Ditto.
+        (WebCore::CSSSegmentedFontFace::LoadFontCallback::~LoadFontCallback): Deleted.
+        * loader/cache/CachedFont.cpp:
+        (WebCore::CachedFont::didAddClient): Migrate to references instead of pointers.
+        (WebCore::CachedFont::checkNotify): Ditto.
+        * loader/cache/CachedFontClient.h:
+        (WebCore::CachedFontClient::fontLoaded): Ditto.
+
</ins><span class="cx"> 2016-02-09  Brady Eidson  &lt;beidson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Modern IDB: IDBOpenDBRequests leak.
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSFontFacecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSFontFace.cpp (196321 => 196322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSFontFace.cpp        2016-02-09 18:57:05 UTC (rev 196321)
+++ trunk/Source/WebCore/css/CSSFontFace.cpp        2016-02-09 19:50:05 UTC (rev 196322)
</span><span class="lines">@@ -37,135 +37,74 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-bool CSSFontFace::isValid() const
</del><ins>+bool CSSFontFace::allSourcesFailed() const
</ins><span class="cx"> {
</span><del>-    size_t size = m_sources.size();
-    for (size_t i = 0; i &lt; size; i++) {
-        if (m_sources[i]-&gt;isValid())
-            return true;
</del><ins>+    for (auto&amp; source : m_sources) {
+        if (source-&gt;status() != CSSFontFaceSource::Status::Failure)
+            return false;
</ins><span class="cx">     }
</span><del>-    return false;
</del><ins>+    return true;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CSSFontFace::addedToSegmentedFontFace(CSSSegmentedFontFace* segmentedFontFace)
</del><ins>+void CSSFontFace::addedToSegmentedFontFace(CSSSegmentedFontFace&amp; segmentedFontFace)
</ins><span class="cx"> {
</span><del>-    m_segmentedFontFaces.add(segmentedFontFace);
</del><ins>+    m_segmentedFontFaces.add(&amp;segmentedFontFace);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CSSFontFace::removedFromSegmentedFontFace(CSSSegmentedFontFace* segmentedFontFace)
</del><ins>+void CSSFontFace::removedFromSegmentedFontFace(CSSSegmentedFontFace&amp; segmentedFontFace)
</ins><span class="cx"> {
</span><del>-    m_segmentedFontFaces.remove(segmentedFontFace);
</del><ins>+    m_segmentedFontFaces.remove(&amp;segmentedFontFace);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CSSFontFace::addSource(std::unique_ptr&lt;CSSFontFaceSource&gt; source)
</del><ins>+void CSSFontFace::adoptSource(std::unique_ptr&lt;CSSFontFaceSource&gt;&amp;&amp; source)
</ins><span class="cx"> {
</span><del>-    source-&gt;setFontFace(this);
</del><span class="cx">     m_sources.append(WTFMove(source));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CSSFontFace::fontLoaded(CSSFontFaceSource* source)
</del><ins>+void CSSFontFace::fontLoaded(CSSFontFaceSource&amp;)
</ins><span class="cx"> {
</span><del>-    if (source != m_activeSource)
-        return;
-
</del><span class="cx">     // FIXME: Can we assert that m_segmentedFontFaces is not empty? That may
</span><span class="cx">     // require stopping in-progress font loading when the last
</span><span class="cx">     // CSSSegmentedFontFace is removed.
</span><span class="cx">     if (m_segmentedFontFaces.isEmpty())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    // Use one of the CSSSegmentedFontFaces' font selector. They all have
-    // the same font selector, so it's wasteful to store it in the CSSFontFace.
-    CSSFontSelector* fontSelector = (*m_segmentedFontFaces.begin())-&gt;fontSelector();
-    fontSelector-&gt;fontLoaded();
</del><ins>+    (*m_segmentedFontFaces.begin())-&gt;fontSelector().fontLoaded();
</ins><span class="cx"> 
</span><del>-#if ENABLE(FONT_LOAD_EVENTS)
-    if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled() &amp;&amp; m_loadState == Loading) {
-        if (source-&gt;ensureFontData())
-            notifyFontLoader(Loaded);
-        else if (!isValid())
-            notifyFontLoader(Error);
-    }
-#endif
-
</del><span class="cx">     for (auto* face : m_segmentedFontFaces)
</span><del>-        face-&gt;fontLoaded(this);
-
-#if ENABLE(FONT_LOAD_EVENTS)
-    if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled())
-        notifyLoadingDone();
-#endif
</del><ins>+        face-&gt;fontLoaded(*this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;Font&gt; CSSFontFace::font(const FontDescription&amp; fontDescription, bool syntheticBold, bool syntheticItalic)
</span><span class="cx"> {
</span><del>-    m_activeSource = 0;
-    if (!isValid())
-        return 0;
</del><ins>+    if (allSourcesFailed())
+        return nullptr;
</ins><span class="cx"> 
</span><span class="cx">     ASSERT(!m_segmentedFontFaces.isEmpty());
</span><del>-    CSSFontSelector* fontSelector = (*m_segmentedFontFaces.begin())-&gt;fontSelector();
</del><ins>+    CSSFontSelector&amp; fontSelector = (*m_segmentedFontFaces.begin())-&gt;fontSelector();
</ins><span class="cx"> 
</span><del>-#if ENABLE(FONT_LOAD_EVENTS)
-    if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled() &amp;&amp; m_loadState == NotLoaded)
-        notifyFontLoader(Loading);
-#endif
</del><ins>+    for (auto&amp; source : m_sources) {
+        if (source-&gt;status() == CSSFontFaceSource::Status::Pending)
+            source-&gt;load(fontSelector);
</ins><span class="cx"> 
</span><del>-    size_t size = m_sources.size();
-    for (size_t i = 0; i &lt; size; ++i) {
-        if (RefPtr&lt;Font&gt; result = m_sources[i]-&gt;font(fontDescription, syntheticBold, syntheticItalic, fontSelector, m_featureSettings, m_variantSettings)) {
-            m_activeSource = m_sources[i].get();
-#if ENABLE(FONT_LOAD_EVENTS)
-            if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled() &amp;&amp; m_loadState == Loading &amp;&amp; m_sources[i]-&gt;isLoaded()) {
-                notifyFontLoader(Loaded);
-                notifyLoadingDone();
-            }
-#endif
-            return result.release();
</del><ins>+        switch (source-&gt;status()) {
+        case CSSFontFaceSource::Status::Pending:
+            ASSERT_NOT_REACHED();
+            break;
+        case CSSFontFaceSource::Status::Loading:
+            return Font::create(FontCache::singleton().lastResortFallbackFont(fontDescription)-&gt;platformData(), true, true);
+        case CSSFontFaceSource::Status::Success:
+            if (RefPtr&lt;Font&gt; result = source-&gt;font(fontDescription, syntheticBold, syntheticItalic, m_featureSettings, m_variantSettings))
+                return WTFMove(result);
+            break;
+        case CSSFontFaceSource::Status::Failure:
+            break;
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-#if ENABLE(FONT_LOAD_EVENTS)
-    if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled() &amp;&amp; m_loadState == Loading) {
-        notifyFontLoader(Error);
-        notifyLoadingDone();
-    }
-#endif
</del><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#if ENABLE(FONT_LOAD_EVENTS)
-void CSSFontFace::notifyFontLoader(LoadState newState)
-{
-    m_loadState = newState;
-
-    Document* document = (*m_segmentedFontFaces.begin())-&gt;fontSelector()-&gt;document();
-    if (!document)
-        return;
-
-    switch (newState) {
-    case Loading:
-        document-&gt;fonts()-&gt;beginFontLoading(m_rule.get());
-        break;
-    case Loaded:
-        document-&gt;fonts()-&gt;fontLoaded(m_rule.get());
-        break;
-    case Error:
-        document-&gt;fonts()-&gt;loadError(m_rule.get(), m_activeSource);
-        break;
-    default:
-        break;
-    }
-}
-
-void CSSFontFace::notifyLoadingDone()
-{
-    Document* document = (*m_segmentedFontFaces.begin())-&gt;fontSelector()-&gt;document();
-    if (document)
-        document-&gt;fonts()-&gt;loadingDone();
-}
-#endif
-
</del><span class="cx"> #if ENABLE(SVG_FONTS)
</span><span class="cx"> bool CSSFontFace::hasSVGFontFaceSource() const
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSFontFaceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSFontFace.h (196321 => 196322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSFontFace.h        2016-02-09 18:57:05 UTC (rev 196321)
+++ trunk/Source/WebCore/css/CSSFontFace.h        2016-02-09 19:50:05 UTC (rev 196322)
</span><span class="lines">@@ -45,7 +45,7 @@
</span><span class="cx"> 
</span><span class="cx"> class CSSFontFace : public RefCounted&lt;CSSFontFace&gt; {
</span><span class="cx"> public:
</span><del>-    static Ref&lt;CSSFontFace&gt; create(FontTraitsMask traitsMask, RefPtr&lt;CSSFontFaceRule&gt;&amp;&amp; rule, bool isLocalFallback = false) { return adoptRef(*new CSSFontFace(traitsMask, WTFMove(rule), isLocalFallback)); }
</del><ins>+    static Ref&lt;CSSFontFace&gt; create(FontTraitsMask traitsMask, bool isLocalFallback = false) { return adoptRef(*new CSSFontFace(traitsMask, isLocalFallback)); }
</ins><span class="cx"> 
</span><span class="cx">     FontTraitsMask traitsMask() const { return m_traitsMask; }
</span><span class="cx"> 
</span><span class="lines">@@ -72,16 +72,16 @@
</span><span class="cx">     void setVariantEastAsianWidth(FontVariantEastAsianWidth width) { m_variantSettings.eastAsianWidth = width; }
</span><span class="cx">     void setVariantEastAsianRuby(FontVariantEastAsianRuby ruby) { m_variantSettings.eastAsianRuby = ruby; }
</span><span class="cx"> 
</span><del>-    void addedToSegmentedFontFace(CSSSegmentedFontFace*);
-    void removedFromSegmentedFontFace(CSSSegmentedFontFace*);
</del><ins>+    void addedToSegmentedFontFace(CSSSegmentedFontFace&amp;);
+    void removedFromSegmentedFontFace(CSSSegmentedFontFace&amp;);
</ins><span class="cx"> 
</span><del>-    bool isValid() const;
</del><ins>+    bool allSourcesFailed() const;
</ins><span class="cx"> 
</span><span class="cx">     bool isLocalFallback() const { return m_isLocalFallback; }
</span><span class="cx"> 
</span><del>-    void addSource(std::unique_ptr&lt;CSSFontFaceSource&gt;);
</del><ins>+    void adoptSource(std::unique_ptr&lt;CSSFontFaceSource&gt;&amp;&amp;);
</ins><span class="cx"> 
</span><del>-    void fontLoaded(CSSFontFaceSource*);
</del><ins>+    void fontLoaded(CSSFontFaceSource&amp;);
</ins><span class="cx"> 
</span><span class="cx">     RefPtr&lt;Font&gt; font(const FontDescription&amp;, bool syntheticBold, bool syntheticItalic);
</span><span class="cx"> 
</span><span class="lines">@@ -104,22 +104,11 @@
</span><span class="cx">     bool hasSVGFontFaceSource() const;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-#if ENABLE(FONT_LOAD_EVENTS)
-    enum LoadState { NotLoaded, Loading, Loaded, Error };
-    LoadState loadState() const { return m_loadState; }
-#endif
-
</del><span class="cx"> private:
</span><del>-    CSSFontFace(FontTraitsMask traitsMask, RefPtr&lt;CSSFontFaceRule&gt;&amp;&amp; rule, bool isLocalFallback)
</del><ins>+    CSSFontFace(FontTraitsMask traitsMask, bool isLocalFallback)
</ins><span class="cx">         : m_traitsMask(traitsMask)
</span><del>-        , m_activeSource(0)
</del><span class="cx">         , m_isLocalFallback(isLocalFallback)
</span><del>-#if ENABLE(FONT_LOAD_EVENTS)
-        , m_loadState(isLocalFallback ? Loaded : NotLoaded)
-        , m_rule(rule)
-#endif
</del><span class="cx">     {
</span><del>-        UNUSED_PARAM(rule);
</del><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     FontTraitsMask m_traitsMask;
</span><span class="lines">@@ -128,14 +117,7 @@
</span><span class="cx">     FontFeatureSettings m_featureSettings;
</span><span class="cx">     FontVariantSettings m_variantSettings;
</span><span class="cx">     Vector&lt;std::unique_ptr&lt;CSSFontFaceSource&gt;&gt; m_sources;
</span><del>-    CSSFontFaceSource* m_activeSource;
</del><span class="cx">     bool m_isLocalFallback;
</span><del>-#if ENABLE(FONT_LOAD_EVENTS)
-    LoadState m_loadState;
-    RefPtr&lt;CSSFontFaceRule&gt; m_rule;
-    void notifyFontLoader(LoadState);
-    void notifyLoadingDone();
-#endif
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSFontFaceSourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSFontFaceSource.cpp (196321 => 196322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSFontFaceSource.cpp        2016-02-09 18:57:05 UTC (rev 196321)
+++ trunk/Source/WebCore/css/CSSFontFaceSource.cpp        2016-02-09 19:50:05 UTC (rev 196322)
</span><span class="lines">@@ -53,13 +53,42 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-CSSFontFaceSource::CSSFontFaceSource(const String&amp; str, CachedFont* font)
-    : m_string(str)
</del><ins>+inline void CSSFontFaceSource::setStatus(Status newStatus)
+{
+    switch (newStatus) {
+    case Status::Pending:
+        ASSERT_NOT_REACHED();
+        break;
+    case Status::Loading:
+        ASSERT(status() == Status::Pending);
+        break;
+    case Status::Success:
+        ASSERT(status() == Status::Loading);
+        break;
+    case Status::Failure:
+        ASSERT(status() == Status::Loading);
+        break;
+    }
+    m_status = newStatus;
+}
+
+CSSFontFaceSource::CSSFontFaceSource(CSSFontFace&amp; owner, const String&amp; familyNameOrURI, CachedFont* font, SVGFontFaceElement* fontFace)
+    : m_familyNameOrURI(familyNameOrURI)
</ins><span class="cx">     , m_font(font)
</span><del>-    , m_face(0)
</del><ins>+    , m_face(owner)
+    , m_svgFontFaceElement(fontFace)
</ins><span class="cx"> {
</span><ins>+    // This may synchronously call fontLoaded().
</ins><span class="cx">     if (m_font)
</span><span class="cx">         m_font-&gt;addClient(this);
</span><ins>+
+    if (status() == Status::Pending &amp;&amp; (!m_font || m_font-&gt;isLoaded())) {
+        setStatus(Status::Loading);
+        if (m_font &amp;&amp; m_font-&gt;errorOccurred())
+            setStatus(Status::Failure);
+        else
+            setStatus(Status::Success);
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> CSSFontFaceSource::~CSSFontFaceSource()
</span><span class="lines">@@ -68,73 +97,76 @@
</span><span class="cx">         m_font-&gt;removeClient(this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool CSSFontFaceSource::isValid() const
</del><ins>+void CSSFontFaceSource::fontLoaded(CachedFont&amp; loadedFont)
</ins><span class="cx"> {
</span><del>-    if (m_font)
-        return !m_font-&gt;errorOccurred();
-    return true;
</del><ins>+    ASSERT_UNUSED(loadedFont, &amp;loadedFont == m_font.get());
+
+    // If the font is in the cache, this will be synchronously called from CachedFont::addClient().
+    if (m_status == Status::Pending)
+        setStatus(Status::Loading);
+
+    if (m_font-&gt;errorOccurred())
+        setStatus(Status::Failure);
+    else
+        setStatus(Status::Success);
+    m_face.fontLoaded(*this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CSSFontFaceSource::fontLoaded(CachedFont*)
</del><ins>+void CSSFontFaceSource::load(CSSFontSelector&amp; fontSelector)
</ins><span class="cx"> {
</span><del>-    if (m_face)
-        m_face-&gt;fontLoaded(this);
</del><ins>+    setStatus(Status::Loading);
+
+    fontSelector.beginLoadingFontSoon(m_font.get());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr&lt;Font&gt; CSSFontFaceSource::font(const FontDescription&amp; fontDescription, bool syntheticBold, bool syntheticItalic, CSSFontSelector* fontSelector, const FontFeatureSettings&amp; fontFaceFeatures, const FontVariantSettings&amp; fontFaceVariantSettings)
</del><ins>+RefPtr&lt;Font&gt; CSSFontFaceSource::font(const FontDescription&amp; fontDescription, bool syntheticBold, bool syntheticItalic, const FontFeatureSettings&amp; fontFaceFeatures, const FontVariantSettings&amp; fontFaceVariantSettings)
</ins><span class="cx"> {
</span><del>-    // If the font hasn't loaded or an error occurred, then we've got nothing.
-    if (!isValid())
-        return nullptr;
</del><ins>+    ASSERT(status() == Status::Success);
</ins><span class="cx"> 
</span><del>-    if (!m_font
</del><ins>+    SVGFontFaceElement* fontFaceElement = nullptr;
</ins><span class="cx"> #if ENABLE(SVG_FONTS)
</span><del>-            &amp;&amp; !m_svgFontFaceElement
</del><ins>+    fontFaceElement = m_svgFontFaceElement.get();
</ins><span class="cx"> #endif
</span><del>-    ) {
</del><ins>+
+    if (!m_font &amp;&amp; !fontFaceElement) {
</ins><span class="cx">         // We're local. Just return a Font from the normal cache.
</span><span class="cx">         // We don't want to check alternate font family names here, so pass true as the checkingAlternateName parameter.
</span><del>-        return FontCache::singleton().fontForFamily(fontDescription, m_string, true);
</del><ins>+        return FontCache::singleton().fontForFamily(fontDescription, m_familyNameOrURI, true);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!m_font || m_font-&gt;isLoaded()) {
-        if (m_font) {
-            if (!m_font-&gt;ensureCustomFontData(m_string))
-                return nullptr;
</del><ins>+    if (m_font) {
+        if (!m_font-&gt;ensureCustomFontData(m_familyNameOrURI))
+            return nullptr;
</ins><span class="cx"> 
</span><del>-            return m_font-&gt;createFont(fontDescription, m_string, syntheticBold, syntheticItalic, fontFaceFeatures, fontFaceVariantSettings);
-        } else {
</del><ins>+        return m_font-&gt;createFont(fontDescription, m_familyNameOrURI, syntheticBold, syntheticItalic, fontFaceFeatures, fontFaceVariantSettings);
+    }
+
+    // In-Document SVG Fonts
+    if (!fontFaceElement)
+        return nullptr;
+
</ins><span class="cx"> #if ENABLE(SVG_FONTS)
</span><del>-            // In-Document SVG Fonts
-            if (m_svgFontFaceElement) {
</del><span class="cx"> #if ENABLE(SVG_OTF_CONVERTER)
</span><del>-                if (!m_svgFontFaceElement-&gt;parentNode() || !is&lt;SVGFontElement&gt;(m_svgFontFaceElement-&gt;parentNode()))
-                    return nullptr;
-                SVGFontElement&amp; fontElement = downcast&lt;SVGFontElement&gt;(*m_svgFontFaceElement-&gt;parentNode());
-                // FIXME: Re-run this when script modifies the element or any of its descendents
-                // FIXME: We might have already converted this font. Make existing conversions discoverable.
-                if (auto otfFont = convertSVGToOTFFont(fontElement))
-                    m_generatedOTFBuffer = SharedBuffer::adoptVector(otfFont.value());
-                if (!m_generatedOTFBuffer)
-                    return nullptr;
-                auto customPlatformData = createFontCustomPlatformData(*m_generatedOTFBuffer);
-                if (!customPlatformData)
-                    return nullptr;
-                return Font::create(customPlatformData-&gt;fontPlatformData(fontDescription, syntheticBold, syntheticItalic, fontFaceFeatures, fontFaceVariantSettings), true, false);
</del><ins>+    if (!m_svgFontFaceElement-&gt;parentNode() || !is&lt;SVGFontElement&gt;(m_svgFontFaceElement-&gt;parentNode()))
+        return nullptr;
+    SVGFontElement&amp; fontElement = downcast&lt;SVGFontElement&gt;(*m_svgFontFaceElement-&gt;parentNode());
+    // FIXME: Re-run this when script modifies the element or any of its descendents
+    // FIXME: We might have already converted this font. Make existing conversions discoverable.
+    if (auto otfFont = convertSVGToOTFFont(fontElement))
+        m_generatedOTFBuffer = SharedBuffer::adoptVector(otfFont.value());
+    if (!m_generatedOTFBuffer)
+        return nullptr;
+    m_inDocumentCustomPlatformData = createFontCustomPlatformData(*m_generatedOTFBuffer);
+    if (!m_inDocumentCustomPlatformData)
+        return nullptr;
+    return Font::create(m_inDocumentCustomPlatformData-&gt;fontPlatformData(fontDescription, syntheticBold, syntheticItalic, fontFaceFeatures, fontFaceVariantSettings), true, false);
</ins><span class="cx"> #else
</span><del>-                return Font::create(std::make_unique&lt;SVGFontData&gt;(m_svgFontFaceElement.get()), fontDescription.computedPixelSize(), syntheticBold, syntheticItalic);
</del><ins>+    return Font::create(std::make_unique&lt;SVGFontData&gt;(m_svgFontFaceElement.get()), fontDescription.computedPixelSize(), syntheticBold, syntheticItalic);
</ins><span class="cx"> #endif
</span><del>-            }
</del><span class="cx"> #endif
</span><del>-            return nullptr;
-        }
-    } else {
-        // Kick off the load. Do it soon rather than now, because we may be in the middle of layout,
-        // and the loader may invoke arbitrary delegate or event handler code.
-        fontSelector-&gt;beginLoadingFontSoon(m_font.get());
</del><span class="cx"> 
</span><del>-        return Font::create(FontCache::singleton().lastResortFallbackFont(fontDescription)-&gt;platformData(), true, true);
-    }
</del><ins>+    ASSERT_NOT_REACHED();
+    return nullptr;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(SVG_FONTS)
</span><span class="lines">@@ -144,20 +176,4 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-#if ENABLE(FONT_LOAD_EVENTS)
-bool CSSFontFaceSource::isDecodeError() const
-{
-    if (m_font)
-        return m_font-&gt;status() == CachedResource::DecodeError;
-    return false;
</del><span class="cx"> }
</span><del>-
-bool CSSFontFaceSource::ensureFontData()
-{
-    if (!m_font)
-        return false;
-    return m_font-&gt;ensureCustomFontData(m_hasExternalSVGFont, m_string);
-}
-#endif
-
-}
</del></span></pre></div>
<a id="trunkSourceWebCorecssCSSFontFaceSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSFontFaceSource.h (196321 => 196322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSFontFaceSource.h        2016-02-09 18:57:05 UTC (rev 196321)
+++ trunk/Source/WebCore/css/CSSFontFaceSource.h        2016-02-09 19:50:05 UTC (rev 196322)
</span><span class="lines">@@ -28,12 +28,6 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CachedFontClient.h&quot;
</span><span class="cx"> #include &quot;CachedResourceHandle.h&quot;
</span><del>-#include &quot;SharedBuffer.h&quot;
-#if ENABLE(SVG_FONTS)
-#include &quot;SVGFontElement.h&quot;
-#include &quot;SVGFontFaceElement.h&quot;
-#endif
-#include &quot;Timer.h&quot;
</del><span class="cx"> #include &lt;wtf/text/AtomicString.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -41,45 +35,51 @@
</span><span class="cx"> class CSSFontFace;
</span><span class="cx"> class CSSFontSelector;
</span><span class="cx"> class Font;
</span><ins>+struct FontCustomPlatformData;
</ins><span class="cx"> class FontDescription;
</span><span class="cx"> class FontFeatureSettings;
</span><span class="cx"> struct FontVariantSettings;
</span><ins>+class SVGFontFaceElement;
+class SharedBuffer;
</ins><span class="cx"> 
</span><span class="cx"> class CSSFontFaceSource final : public CachedFontClient {
</span><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><del>-    CSSFontFaceSource(const String&amp;, CachedFont* = nullptr);
-    virtual ~CSSFontFaceSource();
</del><span class="cx"> 
</span><del>-    bool isValid() const;
</del><ins>+    //                      =&gt; Succeeded
+    //                    //
+    // Pending =&gt; Loading
+    //                    \\.
+    //                      =&gt; Failed
+    enum class Status {
+        Pending,
+        Loading,
+        Success,
+        Failure
+    };
</ins><span class="cx"> 
</span><del>-    const AtomicString&amp; string() const { return m_string; }
</del><ins>+    CSSFontFaceSource(CSSFontFace&amp; owner, const String&amp; familyNameOrURI, CachedFont* = nullptr, SVGFontFaceElement* = nullptr);
+    virtual ~CSSFontFaceSource();
</ins><span class="cx"> 
</span><del>-    void setFontFace(CSSFontFace* face) { m_face = face; }
</del><ins>+    Status status() const { return m_status; }
</ins><span class="cx"> 
</span><del>-    virtual void fontLoaded(CachedFont*) override;
</del><ins>+    const AtomicString&amp; familyNameOrURI() const { return m_familyNameOrURI; }
</ins><span class="cx"> 
</span><del>-    RefPtr&lt;Font&gt; font(const FontDescription&amp;, bool syntheticBold, bool syntheticItalic, CSSFontSelector*, const FontFeatureSettings&amp;, const FontVariantSettings&amp;);
</del><ins>+    void load(CSSFontSelector&amp;);
+    RefPtr&lt;Font&gt; font(const FontDescription&amp;, bool syntheticBold, bool syntheticItalic, const FontFeatureSettings&amp;, const FontVariantSettings&amp;);
</ins><span class="cx"> 
</span><del>-    void pruneTable();
-
</del><span class="cx"> #if ENABLE(SVG_FONTS)
</span><del>-    SVGFontFaceElement* svgFontFaceElement() const { return m_svgFontFaceElement.get(); }
-    void setSVGFontFaceElement(PassRefPtr&lt;SVGFontFaceElement&gt; element) { m_svgFontFaceElement = element; }
</del><span class="cx">     bool isSVGFontFaceSource() const;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-#if ENABLE(FONT_LOAD_EVENTS)
-    bool isDecodeError() const;
-    bool ensureFontData();
-#endif
-
</del><span class="cx"> private:
</span><del>-    void startLoadingTimerFired();
</del><ins>+    virtual void fontLoaded(CachedFont&amp;) override;
</ins><span class="cx"> 
</span><del>-    AtomicString m_string; // URI for remote, built-in font name for local.
</del><ins>+    void setStatus(Status);
+
+    AtomicString m_familyNameOrURI; // URI for remote, built-in font name for local.
</ins><span class="cx">     CachedResourceHandle&lt;CachedFont&gt; m_font; // For remote fonts, a pointer to our cached resource.
</span><del>-    CSSFontFace* m_face; // Our owning font face.
</del><ins>+    CSSFontFace&amp; m_face; // Our owning font face.
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(SVG_OTF_CONVERTER)
</span><span class="cx">     RefPtr&lt;SharedBuffer&gt; m_generatedOTFBuffer;
</span><span class="lines">@@ -87,7 +87,10 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(SVG_FONTS) || ENABLE(SVG_OTF_CONVERTER)
</span><span class="cx">     RefPtr&lt;SVGFontFaceElement&gt; m_svgFontFaceElement;
</span><ins>+    std::unique_ptr&lt;FontCustomPlatformData&gt; m_inDocumentCustomPlatformData;
</ins><span class="cx"> #endif
</span><ins>+
+    Status m_status { Status::Pending };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSFontSelectorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSFontSelector.cpp (196321 => 196322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSFontSelector.cpp        2016-02-09 18:57:05 UTC (rev 196321)
+++ trunk/Source/WebCore/css/CSSFontSelector.cpp        2016-02-09 19:50:05 UTC (rev 196322)
</span><span class="lines">@@ -152,46 +152,33 @@
</span><span class="cx">     return static_cast&lt;FontTraitsMask&gt;(traitsMask);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static Ref&lt;CSSFontFace&gt; createFontFace(CSSValueList&amp; srcList, FontTraitsMask traitsMask, Document* document, const StyleRuleFontFace&amp; fontFaceRule, bool isInitiatingElementInUserAgentShadowTree)
</del><ins>+static Ref&lt;CSSFontFace&gt; createFontFace(CSSValueList&amp; srcList, FontTraitsMask traitsMask, Document* document, bool isInitiatingElementInUserAgentShadowTree)
</ins><span class="cx"> {
</span><del>-    RefPtr&lt;CSSFontFaceRule&gt; rule;
-#if ENABLE(FONT_LOAD_EVENTS)
-    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=112116 - This CSSFontFaceRule has no parent.
-    if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled())
-        rule = static_pointer_cast&lt;CSSFontFaceRule&gt;(fontFaceRule.createCSSOMWrapper());
-#else
-    UNUSED_PARAM(fontFaceRule);
-#endif
-    Ref&lt;CSSFontFace&gt; fontFace = CSSFontFace::create(traitsMask, WTFMove(rule));
</del><ins>+    Ref&lt;CSSFontFace&gt; fontFace = CSSFontFace::create(traitsMask);
</ins><span class="cx"> 
</span><del>-    int srcLength = srcList.length();
-
-    bool foundSVGFont = false;
-
-    for (int i = 0; i &lt; srcLength; i++) {
</del><ins>+    for (auto&amp; src : srcList) {
</ins><span class="cx">         // An item in the list either specifies a string (local font name) or a URL (remote font to download).
</span><del>-        CSSFontFaceSrcValue&amp; item = downcast&lt;CSSFontFaceSrcValue&gt;(*srcList.itemWithoutBoundsCheck(i));
</del><ins>+        CSSFontFaceSrcValue&amp; item = downcast&lt;CSSFontFaceSrcValue&gt;(src.get());
</ins><span class="cx">         std::unique_ptr&lt;CSSFontFaceSource&gt; source;
</span><ins>+        SVGFontFaceElement* fontFaceElement = nullptr;
+        bool foundSVGFont = false;
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(SVG_FONTS)
</span><span class="cx">         foundSVGFont = item.isSVGFontFaceSrc() || item.svgFontFaceElement();
</span><ins>+        fontFaceElement = item.svgFontFaceElement();
</ins><span class="cx"> #endif
</span><span class="cx">         if (!item.isLocal()) {
</span><span class="cx">             Settings* settings = document ? document-&gt;settings() : nullptr;
</span><span class="cx">             bool allowDownloading = foundSVGFont || (settings &amp;&amp; settings-&gt;downloadableBinaryFontsEnabled());
</span><span class="cx">             if (allowDownloading &amp;&amp; item.isSupportedFormat() &amp;&amp; document) {
</span><span class="cx">                 if (CachedFont* cachedFont = item.cachedFont(document, foundSVGFont, isInitiatingElementInUserAgentShadowTree))
</span><del>-                    source = std::make_unique&lt;CSSFontFaceSource&gt;(item.resource(), cachedFont);
</del><ins>+                    source = std::make_unique&lt;CSSFontFaceSource&gt;(fontFace.get(), item.resource(), cachedFont);
</ins><span class="cx">             }
</span><span class="cx">         } else
</span><del>-            source = std::make_unique&lt;CSSFontFaceSource&gt;(item.resource());
</del><ins>+            source = std::make_unique&lt;CSSFontFaceSource&gt;(fontFace.get(), item.resource(), nullptr, fontFaceElement);
</ins><span class="cx"> 
</span><del>-        if (source) {
-#if ENABLE(SVG_FONTS)
-            source-&gt;setSVGFontFaceElement(item.svgFontFaceElement());
-#endif
-            fontFace-&gt;addSource(WTFMove(source));
-        }
</del><ins>+        if (source)
+            fontFace-&gt;adoptSource(WTFMove(source));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return fontFace;
</span><span class="lines">@@ -234,9 +221,9 @@
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;Ref&lt;CSSFontFace&gt;&gt; faces = { };
</span><span class="cx">     for (auto mask : traitsMasks) {
</span><del>-        Ref&lt;CSSFontFace&gt; face = CSSFontFace::create(mask, nullptr, true);
-        face-&gt;addSource(std::make_unique&lt;CSSFontFaceSource&gt;(familyName));
-        ASSERT(face-&gt;isValid());
</del><ins>+        Ref&lt;CSSFontFace&gt; face = CSSFontFace::create(mask, true);
+        face-&gt;adoptSource(std::make_unique&lt;CSSFontFaceSource&gt;(face.get(), familyName));
+        ASSERT(!face-&gt;allSourcesFailed());
</ins><span class="cx">         faces.append(WTFMove(face));
</span><span class="cx">     }
</span><span class="cx">     locallyInstalledFontFaces.add(familyName, WTFMove(faces));
</span><span class="lines">@@ -273,8 +260,8 @@
</span><span class="cx">         return;
</span><span class="cx">     auto traitsMask = computedTraitsMask.value();
</span><span class="cx"> 
</span><del>-    Ref&lt;CSSFontFace&gt; fontFace = createFontFace(srcList, traitsMask, m_document, fontFaceRule, isInitiatingElementInUserAgentShadowTree);
-    if (!fontFace-&gt;isValid())
</del><ins>+    Ref&lt;CSSFontFace&gt; fontFace = createFontFace(srcList, traitsMask, m_document, isInitiatingElementInUserAgentShadowTree);
+    if (fontFace-&gt;allSourcesFailed())
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     if (rangeList) {
</span><span class="lines">@@ -486,7 +473,7 @@
</span><span class="cx">     if (face)
</span><span class="cx">         return face.get();
</span><span class="cx"> 
</span><del>-    face = CSSSegmentedFontFace::create(this);
</del><ins>+    face = CSSSegmentedFontFace::create(*this);
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;std::reference_wrapper&lt;CSSFontFace&gt;, 32&gt; candidateFontFaces;
</span><span class="cx">     for (int i = familyFontFaces.size() - 1; i &gt;= 0; --i) {
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSSegmentedFontFacecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp (196321 => 196322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp        2016-02-09 18:57:05 UTC (rev 196321)
+++ trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp        2016-02-09 19:50:05 UTC (rev 196322)
</span><span class="lines">@@ -37,45 +37,26 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-CSSSegmentedFontFace::CSSSegmentedFontFace(CSSFontSelector* fontSelector)
</del><ins>+CSSSegmentedFontFace::CSSSegmentedFontFace(CSSFontSelector&amp; fontSelector)
</ins><span class="cx">     : m_fontSelector(fontSelector)
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> CSSSegmentedFontFace::~CSSSegmentedFontFace()
</span><span class="cx"> {
</span><del>-    pruneTable();
</del><span class="cx">     for (auto&amp; face : m_fontFaces)
</span><del>-        face-&gt;removedFromSegmentedFontFace(this);
</del><ins>+        face-&gt;removedFromSegmentedFontFace(*this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CSSSegmentedFontFace::pruneTable()
</del><ins>+void CSSSegmentedFontFace::fontLoaded(CSSFontFace&amp;)
</ins><span class="cx"> {
</span><del>-    m_descriptionToRangesMap.clear();
</del><ins>+    m_cache.clear();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CSSSegmentedFontFace::fontLoaded(CSSFontFace*)
-{
-    pruneTable();
-
-#if ENABLE(FONT_LOAD_EVENTS)
-    if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled() &amp;&amp; !isLoading()) {
-        Vector&lt;RefPtr&lt;LoadFontCallback&gt;&gt; callbacks;
-        m_callbacks.swap(callbacks);
-        for (size_t index = 0; index &lt; callbacks.size(); ++index) {
-            if (checkFont())
-                callbacks[index]-&gt;notifyLoaded();
-            else
-                callbacks[index]-&gt;notifyError();
-        }
-    }
-#endif
-}
-
</del><span class="cx"> void CSSSegmentedFontFace::appendFontFace(Ref&lt;CSSFontFace&gt;&amp;&amp; fontFace)
</span><span class="cx"> {
</span><del>-    pruneTable();
-    fontFace-&gt;addedToSegmentedFontFace(this);
</del><ins>+    m_cache.clear();
+    fontFace-&gt;addedToSegmentedFontFace(*this);
</ins><span class="cx">     m_fontFaces.append(WTFMove(fontFace));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -100,12 +81,12 @@
</span><span class="cx"> {
</span><span class="cx">     FontTraitsMask desiredTraitsMask = fontDescription.traitsMask();
</span><span class="cx"> 
</span><del>-    auto addResult = m_descriptionToRangesMap.add(FontDescriptionKey(fontDescription), FontRanges());
</del><ins>+    auto addResult = m_cache.add(FontDescriptionKey(fontDescription), FontRanges());
</ins><span class="cx">     auto&amp; fontRanges = addResult.iterator-&gt;value;
</span><span class="cx"> 
</span><span class="cx">     if (addResult.isNewEntry) {
</span><span class="cx">         for (auto&amp; face : m_fontFaces) {
</span><del>-            if (!face-&gt;isValid())
</del><ins>+            if (face-&gt;allSourcesFailed())
</ins><span class="cx">                 continue;
</span><span class="cx"> 
</span><span class="cx">             FontTraitsMask traitsMask = face-&gt;traitsMask();
</span><span class="lines">@@ -119,38 +100,4 @@
</span><span class="cx">     return fontRanges;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#if ENABLE(FONT_LOAD_EVENTS)
-bool CSSSegmentedFontFace::isLoading() const
-{
-    for (auto&amp; face : m_fontFaces) {
-        if (face-&gt;loadState() == CSSFontFace::Loading)
-            return true;
-    }
-    return false;
</del><span class="cx"> }
</span><del>-
-bool CSSSegmentedFontFace::checkFont() const
-{
-    for (auto&amp; face : m_fontFaces) {
-        if (face-&gt;loadState() != CSSFontFace::Loaded)
-            return false;
-    }
-    return true;
-}
-
-void CSSSegmentedFontFace::loadFont(const FontDescription&amp; fontDescription, PassRefPtr&lt;LoadFontCallback&gt; callback)
-{
-    fontRanges(fontDescription); // Kick off the load.
-
-    if (callback) {
-        if (isLoading())
-            m_callbacks.append(callback);
-        else if (checkFont())
-            callback-&gt;notifyLoaded();
-        else
-            callback-&gt;notifyError();
-    }
-}
-#endif
-
-}
</del></span></pre></div>
<a id="trunkSourceWebCorecssCSSSegmentedFontFaceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSSegmentedFontFace.h (196321 => 196322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSSegmentedFontFace.h        2016-02-09 18:57:05 UTC (rev 196321)
+++ trunk/Source/WebCore/css/CSSSegmentedFontFace.h        2016-02-09 19:50:05 UTC (rev 196322)
</span><span class="lines">@@ -41,43 +41,23 @@
</span><span class="cx"> 
</span><span class="cx"> class CSSSegmentedFontFace : public RefCounted&lt;CSSSegmentedFontFace&gt; {
</span><span class="cx"> public:
</span><del>-    static Ref&lt;CSSSegmentedFontFace&gt; create(CSSFontSelector* selector) { return adoptRef(*new CSSSegmentedFontFace(selector)); }
</del><ins>+    static Ref&lt;CSSSegmentedFontFace&gt; create(CSSFontSelector&amp; selector) { return adoptRef(*new CSSSegmentedFontFace(selector)); }
</ins><span class="cx">     ~CSSSegmentedFontFace();
</span><span class="cx"> 
</span><del>-    CSSFontSelector* fontSelector() const { return m_fontSelector; }
</del><ins>+    CSSFontSelector&amp; fontSelector() const { return m_fontSelector; }
</ins><span class="cx"> 
</span><del>-    void fontLoaded(CSSFontFace*);
</del><ins>+    void fontLoaded(CSSFontFace&amp;);
</ins><span class="cx"> 
</span><span class="cx">     void appendFontFace(Ref&lt;CSSFontFace&gt;&amp;&amp;);
</span><span class="cx"> 
</span><span class="cx">     FontRanges fontRanges(const FontDescription&amp;);
</span><span class="cx"> 
</span><del>-#if ENABLE(FONT_LOAD_EVENTS)
-    class LoadFontCallback : public RefCounted&lt;LoadFontCallback&gt; {
-    public:
-        virtual ~LoadFontCallback() { }
-        virtual void notifyLoaded() = 0;
-        virtual void notifyError() = 0;
-    };
-
-    bool checkFont() const;
-    void loadFont(const FontDescription&amp;, PassRefPtr&lt;LoadFontCallback&gt; loadCallback);
-#endif
-
</del><span class="cx"> private:
</span><del>-    CSSSegmentedFontFace(CSSFontSelector*);
</del><ins>+    CSSSegmentedFontFace(CSSFontSelector&amp;);
</ins><span class="cx"> 
</span><del>-    void pruneTable();
-#if ENABLE(FONT_LOAD_EVENTS)
-    bool isLoading() const;
-#endif
-
-    CSSFontSelector* m_fontSelector;
-    HashMap&lt;FontDescriptionKey, FontRanges, FontDescriptionKeyHash, WTF::SimpleClassHashTraits&lt;FontDescriptionKey&gt;&gt; m_descriptionToRangesMap;
</del><ins>+    CSSFontSelector&amp; m_fontSelector;
+    HashMap&lt;FontDescriptionKey, FontRanges, FontDescriptionKeyHash, WTF::SimpleClassHashTraits&lt;FontDescriptionKey&gt;&gt; m_cache;
</ins><span class="cx">     Vector&lt;Ref&lt;CSSFontFace&gt;, 1&gt; m_fontFaces;
</span><del>-#if ENABLE(FONT_LOAD_EVENTS)
-    Vector&lt;RefPtr&lt;LoadFontCallback&gt;&gt; m_callbacks;
-#endif
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedFontcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedFont.cpp (196321 => 196322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedFont.cpp        2016-02-09 18:57:05 UTC (rev 196321)
+++ trunk/Source/WebCore/loader/cache/CachedFont.cpp        2016-02-09 19:50:05 UTC (rev 196322)
</span><span class="lines">@@ -69,11 +69,11 @@
</span><span class="cx">     m_options = options;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CachedFont::didAddClient(CachedResourceClient* c)
</del><ins>+void CachedFont::didAddClient(CachedResourceClient* client)
</ins><span class="cx"> {
</span><del>-    ASSERT(c-&gt;resourceClientType() == CachedFontClient::expectedType());
</del><ins>+    ASSERT(client-&gt;resourceClientType() == CachedFontClient::expectedType());
</ins><span class="cx">     if (!isLoading())
</span><del>-        static_cast&lt;CachedFontClient*&gt;(c)-&gt;fontLoaded(this);
</del><ins>+        static_cast&lt;CachedFontClient*&gt;(client)-&gt;fontLoaded(*this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CachedFont::finishLoading(SharedBuffer* data)
</span><span class="lines">@@ -148,9 +148,9 @@
</span><span class="cx">     if (isLoading())
</span><span class="cx">         return;
</span><span class="cx">     
</span><del>-    CachedResourceClientWalker&lt;CachedFontClient&gt; w(m_clients);
-    while (CachedFontClient* c = w.next())
-         c-&gt;fontLoaded(this);
</del><ins>+    CachedResourceClientWalker&lt;CachedFontClient&gt; walker(m_clients);
+    while (CachedFontClient* client = walker.next())
+        client-&gt;fontLoaded(*this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool CachedFont::mayTryReplaceEncodedData() const
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedFontClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedFontClient.h (196321 => 196322)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedFontClient.h        2016-02-09 18:57:05 UTC (rev 196321)
+++ trunk/Source/WebCore/loader/cache/CachedFontClient.h        2016-02-09 19:50:05 UTC (rev 196322)
</span><span class="lines">@@ -37,7 +37,7 @@
</span><span class="cx">     virtual ~CachedFontClient() { }
</span><span class="cx">     static CachedResourceClientType expectedType() { return FontType; }
</span><span class="cx">     virtual CachedResourceClientType resourceClientType() const override { return expectedType(); }
</span><del>-    virtual void fontLoaded(CachedFont*) { }
</del><ins>+    virtual void fontLoaded(CachedFont&amp;) { }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre>
</div>
</div>

</body>
</html>