<!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>[189743] releases/WebKitGTK/webkit-2.10</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/189743">189743</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2015-09-14 10:58:11 -0700 (Mon, 14 Sep 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/189421">r189421</a> - Crash when font completes downloading after calling 2D canvas setText() multiple times
https://bugs.webkit.org/show_bug.cgi?id=148789

Reviewed by Darin Adler.

Source/WebCore:

The CSSFontSelector has a list of clients, and when fonts complete downloading, these
clients get a call back. CanvasRenderingContext2D::State is one such of these clients. However,
the CSSFontSelector may be destroyed and recreated at any time. We were getting into a case
where multiple CSSFontSelectors were thinking that the same CanvasRenderingContext2D::State were
their client. When the CanvasRenderingContext2D::State was destroyed, it only unregistered
itself from one of the CSSFontSelectors, which means the CSSFontSelector left over has a dangling
pointer to it.

The solution is to implement a new helper class, FontProxy, to hold the
CanvasRenderingContext2D::State's font, and maintain the invariant that this object is always
registered to exactly one CSSFontSelector, and this CSSFontSelector is the one which is associated
with the FontProxy's FontCascade object. This patch maintains this invariant, as well as protecting
all access to the State's FontCascade object so no one can reach in and change it without going
through functions which maintain the invariant.

Test: fast/canvas/font-selector-crash.html

* css/CSSFontSelector.cpp:
(WebCore::CSSFontSelector::registerForInvalidationCallbacks):
(WebCore::CSSFontSelector::unregisterForInvalidationCallbacks):
(WebCore::CSSFontSelector::dispatchInvalidationCallbacks):
* css/CSSFontSelector.h:
* dom/Document.cpp:
(WebCore::Document::fontsNeedUpdate):
(WebCore::Document::fontSelector):
(WebCore::Document::clearStyleResolver):
* dom/Document.h:
* html/canvas/CanvasRenderingContext2D.cpp:
(WebCore::CanvasRenderingContext2D::State::State):
(WebCore::CanvasRenderingContext2D::State::operator=):
(WebCore::CanvasRenderingContext2D::FontProxy::~FontProxy):
(WebCore::CanvasRenderingContext2D::FontProxy::FontProxy):
(WebCore::CanvasRenderingContext2D::FontProxy::update):
(WebCore::CanvasRenderingContext2D::FontProxy::fontsNeedUpdate):
(WebCore::CanvasRenderingContext2D::FontProxy::initialize):
(WebCore::CanvasRenderingContext2D::FontProxy::fontMetrics):
(WebCore::CanvasRenderingContext2D::FontProxy::fontDescription):
(WebCore::CanvasRenderingContext2D::FontProxy::width):
(WebCore::CanvasRenderingContext2D::FontProxy::drawBidiText):
(WebCore::CanvasRenderingContext2D::font):
(WebCore::CanvasRenderingContext2D::setFont):
(WebCore::CanvasRenderingContext2D::measureText):
(WebCore::CanvasRenderingContext2D::drawTextInternal):
(WebCore::CanvasRenderingContext2D::State::~State): Deleted.
(WebCore::CanvasRenderingContext2D::State::fontsNeedUpdate): Deleted.
(WebCore::CanvasRenderingContext2D::accessFont): Deleted.
* html/canvas/CanvasRenderingContext2D.h:
* platform/graphics/FontSelector.h:

LayoutTests:

* fast/canvas/font-selector-crash-expected.txt: Added.
* fast/canvas/font-selector-crash.html: Added.
* fast/canvas/resources/font-selector-crash.ttf: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit210LayoutTestsChangeLog">releases/WebKitGTK/webkit-2.10/LayoutTests/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceWebCoreChangeLog">releases/WebKitGTK/webkit-2.10/Source/WebCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceWebCorecssCSSFontSelectorcpp">releases/WebKitGTK/webkit-2.10/Source/WebCore/css/CSSFontSelector.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceWebCorecssCSSFontSelectorh">releases/WebKitGTK/webkit-2.10/Source/WebCore/css/CSSFontSelector.h</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceWebCoredomDocumentcpp">releases/WebKitGTK/webkit-2.10/Source/WebCore/dom/Document.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceWebCoredomDocumenth">releases/WebKitGTK/webkit-2.10/Source/WebCore/dom/Document.h</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceWebCorehtmlcanvasCanvasRenderingContext2Dcpp">releases/WebKitGTK/webkit-2.10/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceWebCorehtmlcanvasCanvasRenderingContext2Dh">releases/WebKitGTK/webkit-2.10/Source/WebCore/html/canvas/CanvasRenderingContext2D.h</a></li>
<li><a href="#releasesWebKitGTKwebkit210SourceWebCoreplatformgraphicsFontSelectorh">releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/graphics/FontSelector.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit210LayoutTestsfastcanvasfontselectorcrashexpectedtxt">releases/WebKitGTK/webkit-2.10/LayoutTests/fast/canvas/font-selector-crash-expected.txt</a></li>
<li><a href="#releasesWebKitGTKwebkit210LayoutTestsfastcanvasfontselectorcrashhtml">releases/WebKitGTK/webkit-2.10/LayoutTests/fast/canvas/font-selector-crash.html</a></li>
<li><a href="#releasesWebKitGTKwebkit210LayoutTestsfastcanvasresourcesfontselectorcrashttf">releases/WebKitGTK/webkit-2.10/LayoutTests/fast/canvas/resources/font-selector-crash.ttf</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit210LayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/LayoutTests/ChangeLog (189742 => 189743)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/LayoutTests/ChangeLog        2015-09-14 17:57:27 UTC (rev 189742)
+++ releases/WebKitGTK/webkit-2.10/LayoutTests/ChangeLog        2015-09-14 17:58:11 UTC (rev 189743)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2015-09-04  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        Crash when font completes downloading after calling 2D canvas setText() multiple times
+        https://bugs.webkit.org/show_bug.cgi?id=148789
+
+        Reviewed by Darin Adler.
+
+        * fast/canvas/font-selector-crash-expected.txt: Added.
+        * fast/canvas/font-selector-crash.html: Added.
+        * fast/canvas/resources/font-selector-crash.ttf: Added.
+
</ins><span class="cx"> 2015-09-04  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Document.body should return the first body / frameset child of the html element
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210LayoutTestsfastcanvasfontselectorcrashexpectedtxt"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.10/LayoutTests/fast/canvas/font-selector-crash-expected.txt (0 => 189743)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/LayoutTests/fast/canvas/font-selector-crash-expected.txt                                (rev 0)
+++ releases/WebKitGTK/webkit-2.10/LayoutTests/fast/canvas/font-selector-crash-expected.txt        2015-09-14 17:58:11 UTC (rev 189743)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+PASS document.getElementById('sleepOnMe').getClientRects()[0].width became different from initialWidth
+PASS successfullyParsed is true
+
+TEST COMPLETE
+This test makes sure there is no crash when the CSSFontSelector is cleared in between two canvas setFont() calls. The test is successful if there is no crash.
+
+Test 
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit210LayoutTestsfastcanvasfontselectorcrashhtml"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.10/LayoutTests/fast/canvas/font-selector-crash.html (0 => 189743)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/LayoutTests/fast/canvas/font-selector-crash.html                                (rev 0)
+++ releases/WebKitGTK/webkit-2.10/LayoutTests/fast/canvas/font-selector-crash.html        2015-09-14 17:58:11 UTC (rev 189743)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;style id=&quot;styleElement&quot;&gt;
+p {
+    font-family: helvetica;
+}
+&lt;/style&gt;
+&lt;style&gt;
+@font-face {
+    font-family: 'WebAhem';
+    src: url('resources/font-selector-crash.ttf') format('truetype');
+}
+&lt;/style&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;p&gt;This test makes sure there is no crash when the CSSFontSelector is cleared in between two canvas setFont() calls. The test is successful if there is no crash.&lt;/p&gt;
+&lt;span id=&quot;sleepOnMe&quot; style=&quot;font-family: WebAhem;&quot;&gt;Test&lt;/span&gt;
+&lt;canvas id=&quot;canvas&quot;&gt;&lt;/canvas&gt;
+&lt;script&gt;
+function clearFontSelector() {
+    var e = document.getElementById(&quot;styleElement&quot;);
+    e.setAttribute(&quot;media&quot;, &quot;print&quot;);
+}
+
+window.jsTestIsAsync = true;
+
+var canvasElement = document.getElementById(&quot;canvas&quot;);
+var context = canvasElement.getContext('2d');
+
+// Step 1: Create a State object.
+context.save();
+// Step 2: Make the CSSFontSelector have a pointer to the State object.
+context.font = &quot;15px Times&quot;;
+// Step 3: Create a second CSSFontSelector.
+clearFontSelector();
+// Step 4: Make the second CSSFontSelector have a pointer to the State object.
+context.font = &quot;15px Helvetica&quot;;
+// Step 5: Destroy the State object.
+context.restore();
+// Step 6: When a font finishes downloading, the CSSFontSelector will call back the
+// State object it has a pointer to. When we destroyed the State object, we unregistered
+// it from the second CSSFontSelector, but not the first (which is the problem). The font
+// load was already kicked off earlier because of sleepOnMe, so it targets the first
+// CSSFontSelector, which now has a dangling pointer to the State object.
+
+// Wait for the font to download
+var initialWidth = document.getElementById('sleepOnMe').getClientRects()[0].width;
+shouldBecomeDifferent(&quot;document.getElementById('sleepOnMe').getClientRects()[0].width&quot;, &quot;initialWidth&quot;, finishJSTest);
+&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit210LayoutTestsfastcanvasresourcesfontselectorcrashttf"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.10/LayoutTests/fast/canvas/resources/font-selector-crash.ttf (0 => 189743)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/LayoutTests/fast/canvas/resources/font-selector-crash.ttf                                (rev 0)
+++ releases/WebKitGTK/webkit-2.10/LayoutTests/fast/canvas/resources/font-selector-crash.ttf        2015-09-14 17:58:11 UTC (rev 189743)
</span><span class="lines">@@ -0,0 +1,29 @@
</span><ins>+ \x800OS/2xPJ\x8D8`cmap\xD6Flrgasp        0\xB0glyfI\xB3t\xDA \xE0dhead֢N\xBC6hhea
+\xF4$hmtx\xB9 }\x98\xD4loca u'&quot;&amp;D\xECmaxp\xF8         name~\x8C\xB8(0hpost\x8D\xD0\x8A.\x98BQg_&lt;\xF5        \xE8\xB3o_Y\xC0-\xABI\xFF8\xE8  \xFF8\xE8\xE8\xF5\xF5\xE8\x90\xBC\x8A\x8F\xBC\x8A\xC52        \x80\xAF HW3C@ \xF0 \xFF8 \xC8 @   \xE8}\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8
 \xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8
 \xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8L&amp;
+        
+ + !&quot;#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x80\xDB\x81\x82\x83\x84\xDD\x85\x86\x87\x88\xE3\x89\x8A\xEA\x8B\x8C\xE8\x8D\xEB\xEC\x8E\x8F\xE4\xE6\xE5\xD4\xE9\x90\x91\xD3\x92\x93\x94\x95\x96\xE7\xD1\xED\xD2\x97\x98\xDE\x9A\x9B\x9C\xCE\xCF\xD5\xD6\xD8\xD9\x9D\x9E\x9F\xEE\xA0\xD0\xE2\xA1\xE0\xE1\xDC\xA2\xD7\xDA\xDF\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC&amp;N@&amp;~\xFF1Sx\x92\xC7\xC9\xDD\x94\xA9\xBC\xC0     &quot; &amp; 0 : D!&quot;!&amp;&quot;&quot;&quot;&quot;&quot;&quot;&quot;+&quot;H&quot;`&quot;e&quot;\xF2%\xCA\xF0\xFF\xFF (\xA01Rx\x92\xC6\xC9\xD8\x94\xA9\
 xBC\xC0       &amp; 0 9 D!&quot;!&amp;&quot;&quot;&quot;&quot;&quot;&quot;&quot;+&quot;H&quot;`&quot;d&quot;\xF2%\xCA\xF0\xFF\xFF\xFF\xE3\xFF\xE2\xFF\x81\xFF|\xFFX\xFF?\xFD\xEC\xFD&gt;\xFD*\xFC\xD3\xFD\xDF\xFF\xE0\xC2\xE0\xBC\xE0\xBB\xE0\xB8\xE0\xAF\xE0\xA7\xE0\x9E\xDF\xC1߭\xDE\xE2\xDE\xCC\xDE\xD6\xDE\xCA޾ޥފއ\xDD\xFB\xDB$\xEFJ\xFE\xEC\xEE\x99\x95\x82\x83\xA1\x8E\xBD\x84\x8A\x88\x90\x97\x96\xC4\x87\xB5\x81\x8D\xC7\xC8\x89\x8F\x85\xA2\xB9\xC6\x91\x98\xCA\xC9\xCB\x94\x9A\xA5\xA3\x9Bab\x8Bc\xA7d\xA4\xA6\xAB\xA8\xA9\xAA\xBEe\xAE\xAC\xAD\x9Cf\xC5\x8C\xB1\xAF\xB0g\xC0\xC2\x86ihjlkm\x92npoqrtsuv\xBFwyxz|{\x9F\x93~}\x80\xC1\xC3\xA0\xB3\xBC\xB6\xB7\xB8\xBB\xB4\xBA\x9D\x9E\xD7\xE6\xC4\xA2\xE7&amp;N@&amp;~\xFF1Sx\x92\xC7\xC9\xDD\x94\xA9\xBC\xC0  
    &quot; &amp; 0 : D!&quot;!&amp;&quot;&quot;&quot;&quot;&quot;&quot;&quot;+&quot;H&quot;`&quot;e&quot;\xF2%\xCA\xF0\xFF\xFF (\xA01Rx\x92\xC6\xC9\xD8\x94\xA9\xBC\xC0       &amp; 0 9 D!&quot;!&amp;&quot;&quot;&quot;&quot;&quot;&quot;&quot;+&quot;H&quot;`&quot;d&quot;\xF2%\xCA\xF0\xFF\xFF\xFF\xE3\xFF\xE2\xFF\x81\xFF|\xFFX\xFF?\xFD\xEC\xFD&gt;\xFD*\xFC\xD3\xFD\xDF\xFF\xE0\xC2\xE0\xBC\xE0\xBB\xE0\xB8\xE0\xAF\xE0\xA7\xE0\x9E\xDF\xC1߭\xDE\xE2\xDE\xCC\xDE\xD6\xDE\xCA޾ޥފއ\xDD\xFB\xDB$\xEFJ\xFE\xEC\xEE\x99\x95\x82\x83\xA1\x8E\xBD\x84\x8A\x88\x90\x97\x96\xC4\x87\xB5\x81\x8D\xC7\xC8\x89\x8F\x85\xA2\xB9\xC6\x91\x98\xCA\xC9\xCB\x94\x9A\xA5\xA3\x9Bab\x8Bc\xA7d\xA4\xA6\xAB\xA8\xA9\xAA\xBEe\xAE\xAC\xAD\x9Cf\xC5\x8C\xB1\xAF\xB0g\xC0\xC2\x86ihjlkm\x92npoqrtsuv\xBFwyxz|{\x9F\
 x93~}\x80\xC1\xC3\xA0\xB3\xBC\xB6\xB7\xB8\xBB\xB4\xBA\x9D\x9E\xD7\xE6\xC4\xA2\xE7}k 3!%!!}\xEE\xFD\x8F\xF4\xFE  \xFC\xE0}&amp;\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC
 \xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC
 \xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC
 \xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE81!!\xE8\xFC\xC8\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\
 xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xE8 !!\xE8\xFC \xFC\xE0\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\
 xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\
 xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\
 xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\
 xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\
 xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\
 xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC&quot;0&gt;LZhv\x84\x92\xA0\xAE\xBC\xCA\xD8\xE6\xF4,:HVdr\x80\x8E\x9C\xAA\xB8\xC6\xD4\xE2\xF0\xFE (6DR`n|\x8A\x98\xA6\xB4\xC2\xD0\xDE\xEC\xFA$2@N\jx\x86\x94\xA2\xB0\xBE\xCC\xDA\xE8\xF6 .&lt;JXdr\x80\x8E\x9C\xAA\xB8\xC6\xD4\xE2\xF0\xFE (6DR`n|\x8A\x98\xA6\xB4\xC2\xD0\
 xDE\xEC\xFA$2@N\jx\x86\x94\xA2\xB0\xBE\xCC\xDA\xE8\xF6 .&lt;JXft\x82\x90\x9E\xAC\xBA\xC8\xD6\xE4\xF2*88FTbp~\x8C\x9A\xA8\xB6\xC4\xD2\xE0\xEE\xFC        
+                &amp;        4        B        P        ^        l        z        \x88        \x96        \xA4        \xB2        \xC0        \xCE        \xDC        \xEA        \xF8
+
+
+&quot;
+0
+&gt;
+L
+Z
+h
+v
+\x84
+\x92
+\xA0
+\xAE
+\xBC
+\xCA
+\xD8
+\xE6
+\xF4    , : H V d r \x80 \x8E \x9C \xAA \xB8 \xC6 \xD4 \xE2 \xF0 \xFE  ( 6 D R ` n | \x8A \x98 \xA6 \xB4 \xC2 \xD0 \xDE \xEC \xFA+++$+2J\x9E\x9E\xA6 \xB4\xD4\xDC\xF2\xCF\xFA\xC9\xCD\xD4\xE4 \xE8\xF3\xF7\xFB        \x9E        \xA4        \xAC         \xBA        \xDA        \xE2        \xF8                        Most characters are the em square, except &amp;EAcute and &quot;p&quot;, which show ascent/descent from the baseline. Useful for testing composition systems. Produced by Todd Fahrner for the CSS Samurai's browser testing.AhemRe
 gularVersion 1.1 AhemAhemVersion 1.1AhemMost characters are the em square, except &amp;EAcute and &quot;p&quot;, which show ascent/descent from the baseline. Useful for testing composition systems. Produced by Todd Fahrner for the CSS Samurai's browser testing.AhemRegularVersion 1.1 AhemAhemVersion 1.1AhemAhemRegularAhemMost characters are the em square, except &amp;EAcute and &quot;p&quot;, which show ascent/descent from the baseline. Useful for testing composition systems. Produced by Todd Fahrner for the CSS Samurai's browser testing.AhemRegularVersion 1.1 AhemAhemVersion 1.1AhemAhemRegularAhem\xFF{\xF5         +
  !&quot;#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x80\x81\x83\x84\x85\x86\x88\x89\x8A\x8B\x8D\x8E\x90\x91\x93\x96\x97\x9D\x9E\xA0\xA1\xA2\xA3\xA4\xA9\xAA\xAC\xAD\xAE\xAF\xB6\xB7\xB8\xBA\xBD\xC3\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xB0\xB1\xBB\xA6\xA8\x9F\x9B\xB2\xB3\xC4\xB4\xB5\xC5\x82\xC2\x87\xAB\xC6\xBE\xBF\xBC\x8C\x98\x9A\x99\xA5\x92\x9C\x8F\x94\x95\xA7\xB9\xD2\xC0\xC1NULLHTDEL\xFF\xFF
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/ChangeLog (189742 => 189743)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/WebCore/ChangeLog        2015-09-14 17:57:27 UTC (rev 189742)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/ChangeLog        2015-09-14 17:58:11 UTC (rev 189743)
</span><span class="lines">@@ -1,3 +1,59 @@
</span><ins>+2015-09-04  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        Crash when font completes downloading after calling 2D canvas setText() multiple times
+        https://bugs.webkit.org/show_bug.cgi?id=148789
+
+        Reviewed by Darin Adler.
+
+        The CSSFontSelector has a list of clients, and when fonts complete downloading, these
+        clients get a call back. CanvasRenderingContext2D::State is one such of these clients. However,
+        the CSSFontSelector may be destroyed and recreated at any time. We were getting into a case
+        where multiple CSSFontSelectors were thinking that the same CanvasRenderingContext2D::State were
+        their client. When the CanvasRenderingContext2D::State was destroyed, it only unregistered
+        itself from one of the CSSFontSelectors, which means the CSSFontSelector left over has a dangling
+        pointer to it.
+
+        The solution is to implement a new helper class, FontProxy, to hold the
+        CanvasRenderingContext2D::State's font, and maintain the invariant that this object is always
+        registered to exactly one CSSFontSelector, and this CSSFontSelector is the one which is associated
+        with the FontProxy's FontCascade object. This patch maintains this invariant, as well as protecting
+        all access to the State's FontCascade object so no one can reach in and change it without going
+        through functions which maintain the invariant.
+
+        Test: fast/canvas/font-selector-crash.html
+
+        * css/CSSFontSelector.cpp:
+        (WebCore::CSSFontSelector::registerForInvalidationCallbacks):
+        (WebCore::CSSFontSelector::unregisterForInvalidationCallbacks):
+        (WebCore::CSSFontSelector::dispatchInvalidationCallbacks):
+        * css/CSSFontSelector.h:
+        * dom/Document.cpp:
+        (WebCore::Document::fontsNeedUpdate):
+        (WebCore::Document::fontSelector):
+        (WebCore::Document::clearStyleResolver):
+        * dom/Document.h:
+        * html/canvas/CanvasRenderingContext2D.cpp:
+        (WebCore::CanvasRenderingContext2D::State::State):
+        (WebCore::CanvasRenderingContext2D::State::operator=):
+        (WebCore::CanvasRenderingContext2D::FontProxy::~FontProxy):
+        (WebCore::CanvasRenderingContext2D::FontProxy::FontProxy):
+        (WebCore::CanvasRenderingContext2D::FontProxy::update):
+        (WebCore::CanvasRenderingContext2D::FontProxy::fontsNeedUpdate):
+        (WebCore::CanvasRenderingContext2D::FontProxy::initialize):
+        (WebCore::CanvasRenderingContext2D::FontProxy::fontMetrics):
+        (WebCore::CanvasRenderingContext2D::FontProxy::fontDescription):
+        (WebCore::CanvasRenderingContext2D::FontProxy::width):
+        (WebCore::CanvasRenderingContext2D::FontProxy::drawBidiText):
+        (WebCore::CanvasRenderingContext2D::font):
+        (WebCore::CanvasRenderingContext2D::setFont):
+        (WebCore::CanvasRenderingContext2D::measureText):
+        (WebCore::CanvasRenderingContext2D::drawTextInternal):
+        (WebCore::CanvasRenderingContext2D::State::~State): Deleted.
+        (WebCore::CanvasRenderingContext2D::State::fontsNeedUpdate): Deleted.
+        (WebCore::CanvasRenderingContext2D::accessFont): Deleted.
+        * html/canvas/CanvasRenderingContext2D.h:
+        * platform/graphics/FontSelector.h:
+
</ins><span class="cx"> 2015-09-04  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Document.body should return the first body / frameset child of the html element
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceWebCorecssCSSFontSelectorcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/css/CSSFontSelector.cpp (189742 => 189743)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/WebCore/css/CSSFontSelector.cpp        2015-09-14 17:57:27 UTC (rev 189742)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/css/CSSFontSelector.cpp        2015-09-14 17:58:11 UTC (rev 189743)
</span><span class="lines">@@ -320,14 +320,14 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CSSFontSelector::registerForInvalidationCallbacks(FontSelectorClient* client)
</del><ins>+void CSSFontSelector::registerForInvalidationCallbacks(FontSelectorClient&amp; client)
</ins><span class="cx"> {
</span><del>-    m_clients.add(client);
</del><ins>+    m_clients.add(&amp;client);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CSSFontSelector::unregisterForInvalidationCallbacks(FontSelectorClient* client)
</del><ins>+void CSSFontSelector::unregisterForInvalidationCallbacks(FontSelectorClient&amp; client)
</ins><span class="cx"> {
</span><del>-    m_clients.remove(client);
</del><ins>+    m_clients.remove(&amp;client);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CSSFontSelector::dispatchInvalidationCallbacks()
</span><span class="lines">@@ -337,7 +337,7 @@
</span><span class="cx">     Vector&lt;FontSelectorClient*&gt; clients;
</span><span class="cx">     copyToVector(m_clients, clients);
</span><span class="cx">     for (size_t i = 0; i &lt; clients.size(); ++i)
</span><del>-        clients[i]-&gt;fontsNeedUpdate(this);
</del><ins>+        clients[i]-&gt;fontsNeedUpdate(*this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CSSFontSelector::fontLoaded()
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceWebCorecssCSSFontSelectorh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/css/CSSFontSelector.h (189742 => 189743)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/WebCore/css/CSSFontSelector.h        2015-09-14 17:57:27 UTC (rev 189742)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/css/CSSFontSelector.h        2015-09-14 17:58:11 UTC (rev 189743)
</span><span class="lines">@@ -74,8 +74,8 @@
</span><span class="cx"> 
</span><span class="cx">     bool isEmpty() const;
</span><span class="cx"> 
</span><del>-    virtual void registerForInvalidationCallbacks(FontSelectorClient*) override;
-    virtual void unregisterForInvalidationCallbacks(FontSelectorClient*) override;
</del><ins>+    virtual void registerForInvalidationCallbacks(FontSelectorClient&amp;) override;
+    virtual void unregisterForInvalidationCallbacks(FontSelectorClient&amp;) override;
</ins><span class="cx"> 
</span><span class="cx">     Document* document() const { return m_document; }
</span><span class="cx"> 
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceWebCoredomDocumentcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/dom/Document.cpp (189742 => 189743)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/WebCore/dom/Document.cpp        2015-09-14 17:57:27 UTC (rev 189742)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/dom/Document.cpp        2015-09-14 17:58:11 UTC (rev 189743)
</span><span class="lines">@@ -2089,7 +2089,7 @@
</span><span class="cx">     m_styleSheetCollection.combineCSSFeatureFlags();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Document::fontsNeedUpdate(FontSelector*)
</del><ins>+void Document::fontsNeedUpdate(FontSelector&amp;)
</ins><span class="cx"> {
</span><span class="cx">     if (m_styleResolver)
</span><span class="cx">         m_styleResolver-&gt;invalidateMatchedPropertiesCache();
</span><span class="lines">@@ -2102,7 +2102,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (!m_fontSelector) {
</span><span class="cx">         m_fontSelector = CSSFontSelector::create(*this);
</span><del>-        m_fontSelector-&gt;registerForInvalidationCallbacks(this);
</del><ins>+        m_fontSelector-&gt;registerForInvalidationCallbacks(*this);
</ins><span class="cx">     }
</span><span class="cx">     return *m_fontSelector;
</span><span class="cx"> }
</span><span class="lines">@@ -2114,7 +2114,7 @@
</span><span class="cx">     // FIXME: It would be better if the FontSelector could survive this operation.
</span><span class="cx">     if (m_fontSelector) {
</span><span class="cx">         m_fontSelector-&gt;clearDocument();
</span><del>-        m_fontSelector-&gt;unregisterForInvalidationCallbacks(this);
</del><ins>+        m_fontSelector-&gt;unregisterForInvalidationCallbacks(*this);
</ins><span class="cx">         m_fontSelector = nullptr;
</span><span class="cx">     }
</span><span class="cx"> }
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceWebCoredomDocumenth"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/dom/Document.h (189742 => 189743)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/WebCore/dom/Document.h        2015-09-14 17:57:27 UTC (rev 189742)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/dom/Document.h        2015-09-14 17:58:11 UTC (rev 189743)
</span><span class="lines">@@ -1305,7 +1305,7 @@
</span><span class="cx">     void processArguments(const String&amp; features, void* data, ArgumentsCallback);
</span><span class="cx"> 
</span><span class="cx">     // FontSelectorClient
</span><del>-    virtual void fontsNeedUpdate(FontSelector*) override final;
</del><ins>+    virtual void fontsNeedUpdate(FontSelector&amp;) override final;
</ins><span class="cx"> 
</span><span class="cx">     virtual bool isDocument() const override final { return true; }
</span><span class="cx"> 
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceWebCorehtmlcanvasCanvasRenderingContext2Dcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp (189742 => 189743)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp        2015-09-14 17:57:27 UTC (rev 189742)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp        2015-09-14 17:58:11 UTC (rev 189743)
</span><span class="lines">@@ -177,13 +177,11 @@
</span><span class="cx">     , m_textBaseline(AlphabeticTextBaseline)
</span><span class="cx">     , m_direction(Direction::Inherit)
</span><span class="cx">     , m_unparsedFont(defaultFont)
</span><del>-    , m_realizedFont(false)
</del><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> CanvasRenderingContext2D::State::State(const State&amp; other)
</span><del>-    : FontSelectorClient()
-    , m_unparsedStrokeColor(other.m_unparsedStrokeColor)
</del><ins>+    : m_unparsedStrokeColor(other.m_unparsedStrokeColor)
</ins><span class="cx">     , m_unparsedFillColor(other.m_unparsedFillColor)
</span><span class="cx">     , m_strokeStyle(other.m_strokeStyle)
</span><span class="cx">     , m_fillStyle(other.m_fillStyle)
</span><span class="lines">@@ -206,10 +204,7 @@
</span><span class="cx">     , m_direction(other.m_direction)
</span><span class="cx">     , m_unparsedFont(other.m_unparsedFont)
</span><span class="cx">     , m_font(other.m_font)
</span><del>-    , m_realizedFont(other.m_realizedFont)
</del><span class="cx"> {
</span><del>-    if (m_realizedFont)
-        m_font.fontSelector()-&gt;registerForInvalidationCallbacks(this);
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> CanvasRenderingContext2D::State&amp; CanvasRenderingContext2D::State::operator=(const State&amp; other)
</span><span class="lines">@@ -217,9 +212,6 @@
</span><span class="cx">     if (this == &amp;other)
</span><span class="cx">         return *this;
</span><span class="cx"> 
</span><del>-    if (m_realizedFont)
-        m_font.fontSelector()-&gt;unregisterForInvalidationCallbacks(this);
-
</del><span class="cx">     m_unparsedStrokeColor = other.m_unparsedStrokeColor;
</span><span class="cx">     m_unparsedFillColor = other.m_unparsedFillColor;
</span><span class="cx">     m_strokeStyle = other.m_strokeStyle;
</span><span class="lines">@@ -242,28 +234,87 @@
</span><span class="cx">     m_direction = other.m_direction;
</span><span class="cx">     m_unparsedFont = other.m_unparsedFont;
</span><span class="cx">     m_font = other.m_font;
</span><del>-    m_realizedFont = other.m_realizedFont;
</del><span class="cx"> 
</span><del>-    if (m_realizedFont)
-        m_font.fontSelector()-&gt;registerForInvalidationCallbacks(this);
</del><ins>+    return *this;
+}
</ins><span class="cx"> 
</span><ins>+CanvasRenderingContext2D::FontProxy::~FontProxy()
+{
+    if (realized())
+        m_font.fontSelector()-&gt;unregisterForInvalidationCallbacks(*this);
+}
+
+CanvasRenderingContext2D::FontProxy::FontProxy(const FontProxy&amp; other)
+    : m_font(other.m_font)
+{
+    if (realized())
+        m_font.fontSelector()-&gt;registerForInvalidationCallbacks(*this);
+}
+
+auto CanvasRenderingContext2D::FontProxy::operator=(const FontProxy&amp; other) -&gt; FontProxy&amp;
+{
+    if (realized())
+        m_font.fontSelector()-&gt;unregisterForInvalidationCallbacks(*this);
+
+    m_font = other.m_font;
+
+    if (realized())
+        m_font.fontSelector()-&gt;registerForInvalidationCallbacks(*this);
+
</ins><span class="cx">     return *this;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-CanvasRenderingContext2D::State::~State()
</del><ins>+inline void CanvasRenderingContext2D::FontProxy::update(FontSelector&amp; selector)
</ins><span class="cx"> {
</span><del>-    if (m_realizedFont)
-        m_font.fontSelector()-&gt;unregisterForInvalidationCallbacks(this);
</del><ins>+    ASSERT(&amp;selector == m_font.fontSelector()); // This is an invariant. We should only ever be registered for callbacks on m_font.m_fonts.m_fontSelector.
+    if (realized())
+        m_font.fontSelector()-&gt;unregisterForInvalidationCallbacks(*this);
+    m_font.update(&amp;selector);
+    if (realized())
+        m_font.fontSelector()-&gt;registerForInvalidationCallbacks(*this);
+    ASSERT(&amp;selector == m_font.fontSelector());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CanvasRenderingContext2D::State::fontsNeedUpdate(FontSelector* fontSelector)
</del><ins>+void CanvasRenderingContext2D::FontProxy::fontsNeedUpdate(FontSelector&amp; selector)
</ins><span class="cx"> {
</span><del>-    ASSERT_ARG(fontSelector, fontSelector == m_font.fontSelector());
-    ASSERT(m_realizedFont);
</del><ins>+    ASSERT_ARG(selector, &amp;selector == m_font.fontSelector());
+    ASSERT(realized());
</ins><span class="cx"> 
</span><del>-    m_font.update(fontSelector);
</del><ins>+    update(selector);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline void CanvasRenderingContext2D::FontProxy::initialize(FontSelector&amp; fontSelector, RenderStyle&amp; newStyle)
+{
+    // Beware! m_font.fontSelector() might not point to document.fontSelector()!
+    ASSERT(newStyle.fontCascade().fontSelector() == &amp;fontSelector);
+    if (realized())
+        m_font.fontSelector()-&gt;unregisterForInvalidationCallbacks(*this);
+    m_font = newStyle.fontCascade();
+    m_font.update(&amp;fontSelector);
+    ASSERT(&amp;fontSelector == m_font.fontSelector());
+    m_font.fontSelector()-&gt;registerForInvalidationCallbacks(*this);
+}
+
+inline FontMetrics CanvasRenderingContext2D::FontProxy::fontMetrics() const
+{
+    return m_font.fontMetrics();
+}
+
+inline const FontDescription&amp; CanvasRenderingContext2D::FontProxy::fontDescription() const
+{
+    return m_font.fontDescription();
+}
+
+inline float CanvasRenderingContext2D::FontProxy::width(const TextRun&amp; textRun) const
+{
+    return m_font.width(textRun);
+}
+
+inline void CanvasRenderingContext2D::FontProxy::drawBidiText(GraphicsContext&amp; context, const TextRun&amp; run, const FloatPoint&amp; point, FontCascade::CustomFontNotReadyAction action) const
+{
+    context.drawBidiText(m_font, run, point, action);
+}
+
</ins><span class="cx"> void CanvasRenderingContext2D::realizeSavesLoop()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_unrealizedSaveCount);
</span><span class="lines">@@ -2038,7 +2089,7 @@
</span><span class="cx"> 
</span><span class="cx"> String CanvasRenderingContext2D::font() const
</span><span class="cx"> {
</span><del>-    if (!state().m_realizedFont)
</del><ins>+    if (!state().m_font.realized())
</ins><span class="cx">         return defaultFont;
</span><span class="cx"> 
</span><span class="cx">     StringBuilder serializedFont;
</span><span class="lines">@@ -2052,11 +2103,11 @@
</span><span class="cx">     serializedFont.appendNumber(fontDescription.computedPixelSize());
</span><span class="cx">     serializedFont.appendLiteral(&quot;px&quot;);
</span><span class="cx"> 
</span><del>-    for (unsigned i = 0; i &lt; state().m_font.familyCount(); ++i) {
</del><ins>+    for (unsigned i = 0; i &lt; fontDescription.familyCount(); ++i) {
</ins><span class="cx">         if (i)
</span><span class="cx">             serializedFont.append(',');
</span><span class="cx">         // FIXME: We should append family directly to serializedFont rather than building a temporary string.
</span><del>-        String family = state().m_font.familyAt(i);
</del><ins>+        String family = fontDescription.familyAt(i);
</ins><span class="cx">         if (family.startsWith(&quot;-webkit-&quot;))
</span><span class="cx">             family = family.substring(8);
</span><span class="cx">         if (family.contains(' '))
</span><span class="lines">@@ -2071,7 +2122,7 @@
</span><span class="cx"> 
</span><span class="cx"> void CanvasRenderingContext2D::setFont(const String&amp; newFont)
</span><span class="cx"> {
</span><del>-    if (newFont == state().m_unparsedFont &amp;&amp; state().m_realizedFont)
</del><ins>+    if (newFont == state().m_unparsedFont &amp;&amp; state().m_font.realized())
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;MutableStyleProperties&gt; parsedStyle = MutableStyleProperties::create();
</span><span class="lines">@@ -2093,7 +2144,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Map the &lt;canvas&gt; font into the text style. If the font uses keywords like larger/smaller, these will work
</span><span class="cx">     // relative to the canvas.
</span><del>-    RefPtr&lt;RenderStyle&gt; newStyle = RenderStyle::create();
</del><ins>+    Ref&lt;RenderStyle&gt; newStyle = RenderStyle::create();
</ins><span class="cx"> 
</span><span class="cx">     Document&amp; document = canvas()-&gt;document();
</span><span class="cx">     document.updateStyleIfNeeded();
</span><span class="lines">@@ -2109,11 +2160,11 @@
</span><span class="cx">         newStyle-&gt;setFontDescription(defaultFontDescription);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    newStyle-&gt;fontCascade().update(newStyle-&gt;fontCascade().fontSelector());
</del><ins>+    newStyle-&gt;fontCascade().update(&amp;document.fontSelector());
</ins><span class="cx"> 
</span><span class="cx">     // Now map the font property longhands into the style.
</span><span class="cx">     StyleResolver&amp; styleResolver = canvas()-&gt;document().ensureStyleResolver();
</span><del>-    styleResolver.applyPropertyToStyle(CSSPropertyFontFamily, parsedStyle-&gt;getPropertyCSSValue(CSSPropertyFontFamily).get(), newStyle.get());
</del><ins>+    styleResolver.applyPropertyToStyle(CSSPropertyFontFamily, parsedStyle-&gt;getPropertyCSSValue(CSSPropertyFontFamily).get(), &amp;newStyle.get());
</ins><span class="cx">     styleResolver.applyPropertyToCurrentStyle(CSSPropertyFontStyle, parsedStyle-&gt;getPropertyCSSValue(CSSPropertyFontStyle).get());
</span><span class="cx">     styleResolver.applyPropertyToCurrentStyle(CSSPropertyFontVariant, parsedStyle-&gt;getPropertyCSSValue(CSSPropertyFontVariant).get());
</span><span class="cx">     styleResolver.applyPropertyToCurrentStyle(CSSPropertyFontWeight, parsedStyle-&gt;getPropertyCSSValue(CSSPropertyFontWeight).get());
</span><span class="lines">@@ -2126,10 +2177,7 @@
</span><span class="cx">     styleResolver.updateFont();
</span><span class="cx">     styleResolver.applyPropertyToCurrentStyle(CSSPropertyLineHeight, parsedStyle-&gt;getPropertyCSSValue(CSSPropertyLineHeight).get());
</span><span class="cx"> 
</span><del>-    modifiableState().m_font = newStyle-&gt;fontCascade();
-    modifiableState().m_font.update(&amp;document.fontSelector());
-    modifiableState().m_realizedFont = true;
-    document.fontSelector().registerForInvalidationCallbacks(&amp;modifiableState());
</del><ins>+    modifiableState().m_font.initialize(document.fontSelector(), newStyle);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> String CanvasRenderingContext2D::textAlign() const
</span><span class="lines">@@ -2265,7 +2313,7 @@
</span><span class="cx">     String normalizedText = text;
</span><span class="cx">     normalizeSpaces(normalizedText);
</span><span class="cx"> 
</span><del>-    metrics-&gt;setWidth(accessFont().width(TextRun(normalizedText)));
</del><ins>+    metrics-&gt;setWidth(fontProxy().width(TextRun(normalizedText)));
</ins><span class="cx"> 
</span><span class="cx">     return metrics;
</span><span class="cx"> }
</span><span class="lines">@@ -2291,8 +2339,8 @@
</span><span class="cx">     if (fill &amp;&amp; gradient &amp;&amp; gradient-&gt;isZeroSize())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    const FontCascade&amp; font = accessFont();
-    const FontMetrics&amp; fontMetrics = font.fontMetrics();
</del><ins>+    const auto&amp; fontProxy = this-&gt;fontProxy();
+    const FontMetrics&amp; fontMetrics = fontProxy.fontMetrics();
</ins><span class="cx"> 
</span><span class="cx">     String normalizedText = text;
</span><span class="cx">     normalizeSpaces(normalizedText);
</span><span class="lines">@@ -2326,7 +2374,7 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    float fontWidth = font.width(TextRun(normalizedText, 0, 0, AllowTrailingExpansion, direction, override));
</del><ins>+    float fontWidth = fontProxy.width(TextRun(normalizedText, 0, 0, AllowTrailingExpansion, direction, override));
</ins><span class="cx"> 
</span><span class="cx">     useMaxWidth = (useMaxWidth &amp;&amp; maxWidth &lt; fontWidth);
</span><span class="cx">     float width = useMaxWidth ? maxWidth : fontWidth;
</span><span class="lines">@@ -2388,7 +2436,7 @@
</span><span class="cx">             else
</span><span class="cx">                 c-&gt;setStrokeColor(Color::black, ColorSpaceDeviceRGB);
</span><span class="cx"> 
</span><del>-            c-&gt;drawBidiText(font, textRun, location + offset, FontCascade::UseFallbackIfFontNotReady);
</del><ins>+            fontProxy.drawBidiText(*c, textRun, location + offset, FontCascade::UseFallbackIfFontNotReady);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         std::unique_ptr&lt;ImageBuffer&gt; maskImage = c-&gt;createCompatibleBuffer(maskRect.size());
</span><span class="lines">@@ -2408,10 +2456,10 @@
</span><span class="cx">             maskImageContext-&gt;translate(location.x() - maskRect.x(), location.y() - maskRect.y());
</span><span class="cx">             // We draw when fontWidth is 0 so compositing operations (eg, a &quot;copy&quot; op) still work.
</span><span class="cx">             maskImageContext-&gt;scale(FloatSize((fontWidth &gt; 0 ? (width / fontWidth) : 0), 1));
</span><del>-            maskImageContext-&gt;drawBidiText(font, textRun, FloatPoint(0, 0), FontCascade::UseFallbackIfFontNotReady);
</del><ins>+            fontProxy.drawBidiText(maskImageContext, textRun, FloatPoint(0, 0), FontCascade::UseFallbackIfFontNotReady);
</ins><span class="cx">         } else {
</span><span class="cx">             maskImageContext-&gt;translate(-maskRect.x(), -maskRect.y());
</span><del>-            maskImageContext-&gt;drawBidiText(font, textRun, location, FontCascade::UseFallbackIfFontNotReady);
</del><ins>+            fontProxy.drawBidiText(maskImageContext, textRun, location, FontCascade::UseFallbackIfFontNotReady);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         GraphicsContextStateSaver stateSaver(*c);
</span><span class="lines">@@ -2434,15 +2482,15 @@
</span><span class="cx"> 
</span><span class="cx">     if (isFullCanvasCompositeMode(state().m_globalComposite)) {
</span><span class="cx">         beginCompositeLayer();
</span><del>-        c-&gt;drawBidiText(font, textRun, location, FontCascade::UseFallbackIfFontNotReady);
</del><ins>+        fontProxy.drawBidiText(*c, textRun, location, FontCascade::UseFallbackIfFontNotReady);
</ins><span class="cx">         endCompositeLayer();
</span><span class="cx">         didDrawEntireCanvas();
</span><span class="cx">     } else if (state().m_globalComposite == CompositeCopy) {
</span><span class="cx">         clearCanvas();
</span><del>-        c-&gt;drawBidiText(font, textRun, location, FontCascade::UseFallbackIfFontNotReady);
</del><ins>+        fontProxy.drawBidiText(*c, textRun, location, FontCascade::UseFallbackIfFontNotReady);
</ins><span class="cx">         didDrawEntireCanvas();
</span><span class="cx">     } else {
</span><del>-        c-&gt;drawBidiText(font, textRun, location, FontCascade::UseFallbackIfFontNotReady);
</del><ins>+        fontProxy.drawBidiText(*c, textRun, location, FontCascade::UseFallbackIfFontNotReady);
</ins><span class="cx">         didDraw(textRect);
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -2462,11 +2510,11 @@
</span><span class="cx">     rect.inflate(delta);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-const FontCascade&amp; CanvasRenderingContext2D::accessFont()
</del><ins>+auto CanvasRenderingContext2D::fontProxy() -&gt; const FontProxy&amp;
</ins><span class="cx"> {
</span><span class="cx">     canvas()-&gt;document().updateStyleIfNeeded();
</span><span class="cx"> 
</span><del>-    if (!state().m_realizedFont)
</del><ins>+    if (!state().m_font.realized())
</ins><span class="cx">         setFont(state().m_unparsedFont);
</span><span class="cx">     return state().m_font;
</span><span class="cx"> }
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceWebCorehtmlcanvasCanvasRenderingContext2Dh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/html/canvas/CanvasRenderingContext2D.h (189742 => 189743)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/WebCore/html/canvas/CanvasRenderingContext2D.h        2015-09-14 17:57:27 UTC (rev 189742)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/html/canvas/CanvasRenderingContext2D.h        2015-09-14 17:58:11 UTC (rev 189743)
</span><span class="lines">@@ -235,15 +235,33 @@
</span><span class="cx">         LTR
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    struct State final : FontSelectorClient {
</del><ins>+    class FontProxy : public FontSelectorClient {
+    public:
+        FontProxy() = default;
+        virtual ~FontProxy();
+        FontProxy(const FontProxy&amp;);
+        FontProxy&amp; operator=(const FontProxy&amp;);
+
+        bool realized() const { return m_font.fontSelector(); }
+        void initialize(FontSelector&amp;, RenderStyle&amp;);
+        FontMetrics fontMetrics() const;
+        const FontDescription&amp; fontDescription() const;
+        float width(const TextRun&amp;) const;
+        void drawBidiText(GraphicsContext&amp;, const TextRun&amp;, const FloatPoint&amp;, FontCascade::CustomFontNotReadyAction) const;
+
+    private:
+        void update(FontSelector&amp;);
+        virtual void fontsNeedUpdate(FontSelector&amp;) override;
+
+        FontCascade m_font;
+    };
+
+    struct State final {
</ins><span class="cx">         State();
</span><del>-        virtual ~State();
</del><span class="cx"> 
</span><span class="cx">         State(const State&amp;);
</span><span class="cx">         State&amp; operator=(const State&amp;);
</span><span class="cx"> 
</span><del>-        virtual void fontsNeedUpdate(FontSelector*) override;
-
</del><span class="cx">         String m_unparsedStrokeColor;
</span><span class="cx">         String m_unparsedFillColor;
</span><span class="cx">         CanvasStyle m_strokeStyle;
</span><span class="lines">@@ -270,8 +288,7 @@
</span><span class="cx">         Direction m_direction;
</span><span class="cx"> 
</span><span class="cx">         String m_unparsedFont;
</span><del>-        FontCascade m_font;
-        bool m_realizedFont;
</del><ins>+        FontProxy m_font;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     enum CanvasDidDrawOption {
</span><span class="lines">@@ -308,7 +325,9 @@
</span><span class="cx"> 
</span><span class="cx">     void drawTextInternal(const String&amp; text, float x, float y, bool fill, float maxWidth = 0, bool useMaxWidth = false);
</span><span class="cx"> 
</span><del>-    const FontCascade&amp; accessFont();
</del><ins>+    // The relationship between FontCascade and CanvasRenderingContext2D::FontProxy must hold certain invariants.
+    // Therefore, all font operations must pass through the State.
+    const FontProxy&amp; fontProxy();
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(DASHBOARD_SUPPORT)
</span><span class="cx">     void clearPathForDashboardBackwardCompatibilityMode();
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit210SourceWebCoreplatformgraphicsFontSelectorh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/graphics/FontSelector.h (189742 => 189743)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/graphics/FontSelector.h        2015-09-14 17:57:27 UTC (rev 189742)
+++ releases/WebKitGTK/webkit-2.10/Source/WebCore/platform/graphics/FontSelector.h        2015-09-14 17:58:11 UTC (rev 189743)
</span><span class="lines">@@ -48,8 +48,8 @@
</span><span class="cx"> 
</span><span class="cx">     virtual void fontCacheInvalidated() { }
</span><span class="cx"> 
</span><del>-    virtual void registerForInvalidationCallbacks(FontSelectorClient*) = 0;
-    virtual void unregisterForInvalidationCallbacks(FontSelectorClient*) = 0;
</del><ins>+    virtual void registerForInvalidationCallbacks(FontSelectorClient&amp;) = 0;
+    virtual void unregisterForInvalidationCallbacks(FontSelectorClient&amp;) = 0;
</ins><span class="cx"> 
</span><span class="cx">     virtual unsigned uniqueId() const = 0;
</span><span class="cx">     virtual unsigned version() const = 0;
</span><span class="lines">@@ -59,7 +59,7 @@
</span><span class="cx"> public:
</span><span class="cx">     virtual ~FontSelectorClient() { }
</span><span class="cx"> 
</span><del>-    virtual void fontsNeedUpdate(FontSelector*) = 0;
</del><ins>+    virtual void fontsNeedUpdate(FontSelector&amp;) = 0;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre>
</div>
</div>

</body>
</html>