Title: [191050] branches/safari-601-branch

Diff

Modified: branches/safari-601-branch/LayoutTests/ChangeLog (191049 => 191050)


--- branches/safari-601-branch/LayoutTests/ChangeLog	2015-10-14 18:10:32 UTC (rev 191049)
+++ branches/safari-601-branch/LayoutTests/ChangeLog	2015-10-14 18:49:28 UTC (rev 191050)
@@ -1,3 +1,18 @@
+2015-10-13  Matthew Hanson  <matthew_han...@apple.com>
+
+        Merge r189421. rdar://problem/22802049
+
+    2015-09-04  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+            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.
+
 2015-10-08  Lucas Forschler  <lforsch...@apple.com>
 
         Merge r190602. rdar://problem/22995830

Added: branches/safari-601-branch/LayoutTests/fast/canvas/font-selector-crash-expected.txt (0 => 191050)


--- branches/safari-601-branch/LayoutTests/fast/canvas/font-selector-crash-expected.txt	                        (rev 0)
+++ branches/safari-601-branch/LayoutTests/fast/canvas/font-selector-crash-expected.txt	2015-10-14 18:49:28 UTC (rev 191050)
@@ -0,0 +1,7 @@
+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 

Added: branches/safari-601-branch/LayoutTests/fast/canvas/font-selector-crash.html (0 => 191050)


--- branches/safari-601-branch/LayoutTests/fast/canvas/font-selector-crash.html	                        (rev 0)
+++ branches/safari-601-branch/LayoutTests/fast/canvas/font-selector-crash.html	2015-10-14 18:49:28 UTC (rev 191050)
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style id="styleElement">
+p {
+    font-family: helvetica;
+}
+</style>
+<style>
+@font-face {
+    font-family: 'WebAhem';
+    src: url('resources/font-selector-crash.ttf') format('truetype');
+}
+</style>
+<script src=""
+</head>
+<body>
+<p>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.</p>
+<span id="sleepOnMe" style="font-family: WebAhem;">Test</span>
+<canvas id="canvas"></canvas>
+<script>
+function clearFontSelector() {
+    var e = document.getElementById("styleElement");
+    e.setAttribute("media", "print");
+}
+
+window.jsTestIsAsync = true;
+
+var canvasElement = document.getElementById("canvas");
+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 = "15px Times";
+// Step 3: Create a second CSSFontSelector.
+clearFontSelector();
+// Step 4: Make the second CSSFontSelector have a pointer to the State object.
+context.font = "15px Helvetica";
+// 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("document.getElementById('sleepOnMe').getClientRects()[0].width", "initialWidth", finishJSTest);
+</script>
+<script src=""
+</body>
+</html>

Added: branches/safari-601-branch/LayoutTests/fast/canvas/resources/font-selector-crash.ttf (0 => 191050)


--- branches/safari-601-branch/LayoutTests/fast/canvas/resources/font-selector-crash.ttf	                        (rev 0)
+++ branches/safari-601-branch/LayoutTests/fast/canvas/resources/font-selector-crash.ttf	2015-10-14 18:49:28 UTC (rev 191050)
@@ -0,0 +1,29 @@
+\x800OS/2xPJ\x8D8`cmap\xD6Flrgasp	0\xB0glyfI\xB3t\xDA\xE0dhead֢N\xBC6hhea
+\xF4$hmtx\xB9 }\x98\xD4loca u'"&D\xECmaxp\xF8	 name~\x8C\xB8(0hpost\x8D\xD0\x8A.\x98BQg_<\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&
+	
++ !"#$%&'()*+,-./0123456789:;<=>?@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&N@&~\xFF1Sx\x92\xC7\xC9\xDD\x94\xA9\xBC\xC0     " & 0 : D!"!&"""""""+"H"`"e"\xF2%\xCA\xF0\xFF\xFF (\xA01Rx\x92\xC6\xC9\xD8\x94\xA9\
 xBC\xC0       & 0 9 D!"!&"""""""+"H"`"d"\xF2%\xCA\xF0\xFF\xFF\xFF\xE3\xFF\xE2\xFF\x81\xFF|\xFFX\xFF?\xFD\xEC\xFD>\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&N@&~\xFF1Sx\x92\xC7\xC9\xDD\x94\xA9\xBC\xC0  
    " & 0 : D!"!&"""""""+"H"`"e"\xF2%\xCA\xF0\xFF\xFF (\xA01Rx\x92\xC6\xC9\xD8\x94\xA9\xBC\xC0       & 0 9 D!"!&"""""""+"H"`"d"\xF2%\xCA\xF0\xFF\xFF\xFF\xE3\xFF\xE2\xFF\x81\xFF|\xFFX\xFF?\xFD\xEC\xFD>\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}&\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"0>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 .<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 .<JXft\x82\x90\x9E\xAC\xBA\xC8\xD6\xE4\xF2*88FTbp~\x8C\x9A\xA8\xB6\xC4\xD2\xE0\xEE\xFC	
+		&	4	B	P	^	l	z	\x88	\x96	\xA4	\xB2	\xC0	\xCE	\xDC	\xEA	\xF8
+
+
+"
+0
+>
+L
+Z
+h
+v
+\x84
+\x92
+\xA0
+\xAE
+\xBC
+\xCA
+\xD8
+\xE6
+\xF4,:HVdr\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 &EAcute and "p", 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 &EAcute and "p", 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 &EAcute and "p", 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	+
  !"#$%&'()*+,-./0123456789:;<=>?@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
\ No newline at end of file

Modified: branches/safari-601-branch/Source/WebCore/ChangeLog (191049 => 191050)


--- branches/safari-601-branch/Source/WebCore/ChangeLog	2015-10-14 18:10:32 UTC (rev 191049)
+++ branches/safari-601-branch/Source/WebCore/ChangeLog	2015-10-14 18:49:28 UTC (rev 191050)
@@ -1,5 +1,65 @@
 2015-10-13  Matthew Hanson  <matthew_han...@apple.com>
 
+        Merge r189421. rdar://problem/22802049
+
+    2015-09-04  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+            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:
+
+2015-10-13  Matthew Hanson  <matthew_han...@apple.com>
+
         Merge r189834. rdar://problem/22801966
 
     2015-09-15  Joseph Pecoraro  <pecor...@apple.com>

Modified: branches/safari-601-branch/Source/WebCore/css/CSSFontSelector.cpp (191049 => 191050)


--- branches/safari-601-branch/Source/WebCore/css/CSSFontSelector.cpp	2015-10-14 18:10:32 UTC (rev 191049)
+++ branches/safari-601-branch/Source/WebCore/css/CSSFontSelector.cpp	2015-10-14 18:49:28 UTC (rev 191050)
@@ -320,14 +320,14 @@
     }
 }
 
-void CSSFontSelector::registerForInvalidationCallbacks(FontSelectorClient* client)
+void CSSFontSelector::registerForInvalidationCallbacks(FontSelectorClient& client)
 {
-    m_clients.add(client);
+    m_clients.add(&client);
 }
 
-void CSSFontSelector::unregisterForInvalidationCallbacks(FontSelectorClient* client)
+void CSSFontSelector::unregisterForInvalidationCallbacks(FontSelectorClient& client)
 {
-    m_clients.remove(client);
+    m_clients.remove(&client);
 }
 
 void CSSFontSelector::dispatchInvalidationCallbacks()
@@ -337,7 +337,7 @@
     Vector<FontSelectorClient*> clients;
     copyToVector(m_clients, clients);
     for (size_t i = 0; i < clients.size(); ++i)
-        clients[i]->fontsNeedUpdate(this);
+        clients[i]->fontsNeedUpdate(*this);
 }
 
 void CSSFontSelector::fontLoaded()

Modified: branches/safari-601-branch/Source/WebCore/css/CSSFontSelector.h (191049 => 191050)


--- branches/safari-601-branch/Source/WebCore/css/CSSFontSelector.h	2015-10-14 18:10:32 UTC (rev 191049)
+++ branches/safari-601-branch/Source/WebCore/css/CSSFontSelector.h	2015-10-14 18:49:28 UTC (rev 191050)
@@ -74,8 +74,8 @@
 
     bool isEmpty() const;
 
-    virtual void registerForInvalidationCallbacks(FontSelectorClient*) override;
-    virtual void unregisterForInvalidationCallbacks(FontSelectorClient*) override;
+    virtual void registerForInvalidationCallbacks(FontSelectorClient&) override;
+    virtual void unregisterForInvalidationCallbacks(FontSelectorClient&) override;
 
     Document* document() const { return m_document; }
 

Modified: branches/safari-601-branch/Source/WebCore/dom/Document.cpp (191049 => 191050)


--- branches/safari-601-branch/Source/WebCore/dom/Document.cpp	2015-10-14 18:10:32 UTC (rev 191049)
+++ branches/safari-601-branch/Source/WebCore/dom/Document.cpp	2015-10-14 18:49:28 UTC (rev 191050)
@@ -2091,7 +2091,7 @@
     m_styleSheetCollection.combineCSSFeatureFlags();
 }
 
-void Document::fontsNeedUpdate(FontSelector*)
+void Document::fontsNeedUpdate(FontSelector&)
 {
     if (m_styleResolver)
         m_styleResolver->invalidateMatchedPropertiesCache();
@@ -2104,7 +2104,7 @@
 {
     if (!m_fontSelector) {
         m_fontSelector = CSSFontSelector::create(*this);
-        m_fontSelector->registerForInvalidationCallbacks(this);
+        m_fontSelector->registerForInvalidationCallbacks(*this);
     }
     return *m_fontSelector;
 }
@@ -2116,7 +2116,7 @@
     // FIXME: It would be better if the FontSelector could survive this operation.
     if (m_fontSelector) {
         m_fontSelector->clearDocument();
-        m_fontSelector->unregisterForInvalidationCallbacks(this);
+        m_fontSelector->unregisterForInvalidationCallbacks(*this);
         m_fontSelector = nullptr;
     }
 }

Modified: branches/safari-601-branch/Source/WebCore/dom/Document.h (191049 => 191050)


--- branches/safari-601-branch/Source/WebCore/dom/Document.h	2015-10-14 18:10:32 UTC (rev 191049)
+++ branches/safari-601-branch/Source/WebCore/dom/Document.h	2015-10-14 18:49:28 UTC (rev 191050)
@@ -1303,7 +1303,7 @@
     void processArguments(const String& features, void* data, ArgumentsCallback);
 
     // FontSelectorClient
-    virtual void fontsNeedUpdate(FontSelector*) override final;
+    virtual void fontsNeedUpdate(FontSelector&) override final;
 
     virtual bool isDocument() const override final { return true; }
 

Modified: branches/safari-601-branch/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp (191049 => 191050)


--- branches/safari-601-branch/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp	2015-10-14 18:10:32 UTC (rev 191049)
+++ branches/safari-601-branch/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp	2015-10-14 18:49:28 UTC (rev 191050)
@@ -177,13 +177,11 @@
     , m_textBaseline(AlphabeticTextBaseline)
     , m_direction(Direction::Inherit)
     , m_unparsedFont(defaultFont)
-    , m_realizedFont(false)
 {
 }
 
 CanvasRenderingContext2D::State::State(const State& other)
-    : FontSelectorClient()
-    , m_unparsedStrokeColor(other.m_unparsedStrokeColor)
+    : m_unparsedStrokeColor(other.m_unparsedStrokeColor)
     , m_unparsedFillColor(other.m_unparsedFillColor)
     , m_strokeStyle(other.m_strokeStyle)
     , m_fillStyle(other.m_fillStyle)
@@ -206,10 +204,7 @@
     , m_direction(other.m_direction)
     , m_unparsedFont(other.m_unparsedFont)
     , m_font(other.m_font)
-    , m_realizedFont(other.m_realizedFont)
 {
-    if (m_realizedFont)
-        m_font.fontSelector()->registerForInvalidationCallbacks(this);
 }
 
 CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(const State& other)
@@ -217,9 +212,6 @@
     if (this == &other)
         return *this;
 
-    if (m_realizedFont)
-        m_font.fontSelector()->unregisterForInvalidationCallbacks(this);
-
     m_unparsedStrokeColor = other.m_unparsedStrokeColor;
     m_unparsedFillColor = other.m_unparsedFillColor;
     m_strokeStyle = other.m_strokeStyle;
@@ -242,28 +234,87 @@
     m_direction = other.m_direction;
     m_unparsedFont = other.m_unparsedFont;
     m_font = other.m_font;
-    m_realizedFont = other.m_realizedFont;
 
-    if (m_realizedFont)
-        m_font.fontSelector()->registerForInvalidationCallbacks(this);
+    return *this;
+}
 
+CanvasRenderingContext2D::FontProxy::~FontProxy()
+{
+    if (realized())
+        m_font.fontSelector()->unregisterForInvalidationCallbacks(*this);
+}
+
+CanvasRenderingContext2D::FontProxy::FontProxy(const FontProxy& other)
+    : m_font(other.m_font)
+{
+    if (realized())
+        m_font.fontSelector()->registerForInvalidationCallbacks(*this);
+}
+
+auto CanvasRenderingContext2D::FontProxy::operator=(const FontProxy& other) -> FontProxy&
+{
+    if (realized())
+        m_font.fontSelector()->unregisterForInvalidationCallbacks(*this);
+
+    m_font = other.m_font;
+
+    if (realized())
+        m_font.fontSelector()->registerForInvalidationCallbacks(*this);
+
     return *this;
 }
 
-CanvasRenderingContext2D::State::~State()
+inline void CanvasRenderingContext2D::FontProxy::update(FontSelector& selector)
 {
-    if (m_realizedFont)
-        m_font.fontSelector()->unregisterForInvalidationCallbacks(this);
+    ASSERT(&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()->unregisterForInvalidationCallbacks(*this);
+    m_font.update(&selector);
+    if (realized())
+        m_font.fontSelector()->registerForInvalidationCallbacks(*this);
+    ASSERT(&selector == m_font.fontSelector());
 }
 
-void CanvasRenderingContext2D::State::fontsNeedUpdate(FontSelector* fontSelector)
+void CanvasRenderingContext2D::FontProxy::fontsNeedUpdate(FontSelector& selector)
 {
-    ASSERT_ARG(fontSelector, fontSelector == m_font.fontSelector());
-    ASSERT(m_realizedFont);
+    ASSERT_ARG(selector, &selector == m_font.fontSelector());
+    ASSERT(realized());
 
-    m_font.update(fontSelector);
+    update(selector);
 }
 
+inline void CanvasRenderingContext2D::FontProxy::initialize(FontSelector& fontSelector, RenderStyle& newStyle)
+{
+    // Beware! m_font.fontSelector() might not point to document.fontSelector()!
+    ASSERT(newStyle.fontCascade().fontSelector() == &fontSelector);
+    if (realized())
+        m_font.fontSelector()->unregisterForInvalidationCallbacks(*this);
+    m_font = newStyle.fontCascade();
+    m_font.update(&fontSelector);
+    ASSERT(&fontSelector == m_font.fontSelector());
+    m_font.fontSelector()->registerForInvalidationCallbacks(*this);
+}
+
+inline FontMetrics CanvasRenderingContext2D::FontProxy::fontMetrics() const
+{
+    return m_font.fontMetrics();
+}
+
+inline const FontDescription& CanvasRenderingContext2D::FontProxy::fontDescription() const
+{
+    return m_font.fontDescription();
+}
+
+inline float CanvasRenderingContext2D::FontProxy::width(const TextRun& textRun) const
+{
+    return m_font.width(textRun);
+}
+
+inline void CanvasRenderingContext2D::FontProxy::drawBidiText(GraphicsContext& context, const TextRun& run, const FloatPoint& point, FontCascade::CustomFontNotReadyAction action) const
+{
+    context.drawBidiText(m_font, run, point, action);
+}
+
 void CanvasRenderingContext2D::realizeSavesLoop()
 {
     ASSERT(m_unrealizedSaveCount);
@@ -2038,7 +2089,7 @@
 
 String CanvasRenderingContext2D::font() const
 {
-    if (!state().m_realizedFont)
+    if (!state().m_font.realized())
         return defaultFont;
 
     StringBuilder serializedFont;
@@ -2052,11 +2103,11 @@
     serializedFont.appendNumber(fontDescription.computedPixelSize());
     serializedFont.appendLiteral("px");
 
-    for (unsigned i = 0; i < state().m_font.familyCount(); ++i) {
+    for (unsigned i = 0; i < fontDescription.familyCount(); ++i) {
         if (i)
             serializedFont.append(',');
         // FIXME: We should append family directly to serializedFont rather than building a temporary string.
-        String family = state().m_font.familyAt(i);
+        String family = fontDescription.familyAt(i);
         if (family.startsWith("-webkit-"))
             family = family.substring(8);
         if (family.contains(' '))
@@ -2071,7 +2122,7 @@
 
 void CanvasRenderingContext2D::setFont(const String& newFont)
 {
-    if (newFont == state().m_unparsedFont && state().m_realizedFont)
+    if (newFont == state().m_unparsedFont && state().m_font.realized())
         return;
 
     RefPtr<MutableStyleProperties> parsedStyle = MutableStyleProperties::create();
@@ -2093,7 +2144,7 @@
 
     // Map the <canvas> font into the text style. If the font uses keywords like larger/smaller, these will work
     // relative to the canvas.
-    RefPtr<RenderStyle> newStyle = RenderStyle::create();
+    Ref<RenderStyle> newStyle = RenderStyle::create();
 
     Document& document = canvas()->document();
     document.updateStyleIfNeeded();
@@ -2109,11 +2160,11 @@
         newStyle->setFontDescription(defaultFontDescription);
     }
 
-    newStyle->fontCascade().update(newStyle->fontCascade().fontSelector());
+    newStyle->fontCascade().update(&document.fontSelector());
 
     // Now map the font property longhands into the style.
     StyleResolver& styleResolver = canvas()->document().ensureStyleResolver();
-    styleResolver.applyPropertyToStyle(CSSPropertyFontFamily, parsedStyle->getPropertyCSSValue(CSSPropertyFontFamily).get(), newStyle.get());
+    styleResolver.applyPropertyToStyle(CSSPropertyFontFamily, parsedStyle->getPropertyCSSValue(CSSPropertyFontFamily).get(), &newStyle.get());
     styleResolver.applyPropertyToCurrentStyle(CSSPropertyFontStyle, parsedStyle->getPropertyCSSValue(CSSPropertyFontStyle).get());
     styleResolver.applyPropertyToCurrentStyle(CSSPropertyFontVariant, parsedStyle->getPropertyCSSValue(CSSPropertyFontVariant).get());
     styleResolver.applyPropertyToCurrentStyle(CSSPropertyFontWeight, parsedStyle->getPropertyCSSValue(CSSPropertyFontWeight).get());
@@ -2126,10 +2177,7 @@
     styleResolver.updateFont();
     styleResolver.applyPropertyToCurrentStyle(CSSPropertyLineHeight, parsedStyle->getPropertyCSSValue(CSSPropertyLineHeight).get());
 
-    modifiableState().m_font = newStyle->fontCascade();
-    modifiableState().m_font.update(&document.fontSelector());
-    modifiableState().m_realizedFont = true;
-    document.fontSelector().registerForInvalidationCallbacks(&modifiableState());
+    modifiableState().m_font.initialize(document.fontSelector(), newStyle);
 }
 
 String CanvasRenderingContext2D::textAlign() const
@@ -2265,7 +2313,7 @@
     String normalizedText = text;
     normalizeSpaces(normalizedText);
 
-    metrics->setWidth(accessFont().width(TextRun(normalizedText)));
+    metrics->setWidth(fontProxy().width(TextRun(normalizedText)));
 
     return metrics;
 }
@@ -2291,8 +2339,8 @@
     if (fill && gradient && gradient->isZeroSize())
         return;
 
-    const FontCascade& font = accessFont();
-    const FontMetrics& fontMetrics = font.fontMetrics();
+    const auto& fontProxy = this->fontProxy();
+    const FontMetrics& fontMetrics = fontProxy.fontMetrics();
 
     String normalizedText = text;
     normalizeSpaces(normalizedText);
@@ -2326,7 +2374,7 @@
         break;
     }
 
-    float fontWidth = font.width(TextRun(normalizedText, 0, 0, AllowTrailingExpansion, direction, override));
+    float fontWidth = fontProxy.width(TextRun(normalizedText, 0, 0, AllowTrailingExpansion, direction, override));
 
     useMaxWidth = (useMaxWidth && maxWidth < fontWidth);
     float width = useMaxWidth ? maxWidth : fontWidth;
@@ -2388,7 +2436,7 @@
             else
                 c->setStrokeColor(Color::black, ColorSpaceDeviceRGB);
 
-            c->drawBidiText(font, textRun, location + offset, FontCascade::UseFallbackIfFontNotReady);
+            fontProxy.drawBidiText(*c, textRun, location + offset, FontCascade::UseFallbackIfFontNotReady);
         }
 
         std::unique_ptr<ImageBuffer> maskImage = c->createCompatibleBuffer(maskRect.size());
@@ -2408,10 +2456,10 @@
             maskImageContext->translate(location.x() - maskRect.x(), location.y() - maskRect.y());
             // We draw when fontWidth is 0 so compositing operations (eg, a "copy" op) still work.
             maskImageContext->scale(FloatSize((fontWidth > 0 ? (width / fontWidth) : 0), 1));
-            maskImageContext->drawBidiText(font, textRun, FloatPoint(0, 0), FontCascade::UseFallbackIfFontNotReady);
+            fontProxy.drawBidiText(*maskImageContext, textRun, FloatPoint(0, 0), FontCascade::UseFallbackIfFontNotReady);
         } else {
             maskImageContext->translate(-maskRect.x(), -maskRect.y());
-            maskImageContext->drawBidiText(font, textRun, location, FontCascade::UseFallbackIfFontNotReady);
+            fontProxy.drawBidiText(*maskImageContext, textRun, location, FontCascade::UseFallbackIfFontNotReady);
         }
 
         GraphicsContextStateSaver stateSaver(*c);
@@ -2434,15 +2482,15 @@
 
     if (isFullCanvasCompositeMode(state().m_globalComposite)) {
         beginCompositeLayer();
-        c->drawBidiText(font, textRun, location, FontCascade::UseFallbackIfFontNotReady);
+        fontProxy.drawBidiText(*c, textRun, location, FontCascade::UseFallbackIfFontNotReady);
         endCompositeLayer();
         didDrawEntireCanvas();
     } else if (state().m_globalComposite == CompositeCopy) {
         clearCanvas();
-        c->drawBidiText(font, textRun, location, FontCascade::UseFallbackIfFontNotReady);
+        fontProxy.drawBidiText(*c, textRun, location, FontCascade::UseFallbackIfFontNotReady);
         didDrawEntireCanvas();
     } else {
-        c->drawBidiText(font, textRun, location, FontCascade::UseFallbackIfFontNotReady);
+        fontProxy.drawBidiText(*c, textRun, location, FontCascade::UseFallbackIfFontNotReady);
         didDraw(textRect);
     }
 }
@@ -2462,11 +2510,11 @@
     rect.inflate(delta);
 }
 
-const FontCascade& CanvasRenderingContext2D::accessFont()
+auto CanvasRenderingContext2D::fontProxy() -> const FontProxy&
 {
     canvas()->document().updateStyleIfNeeded();
 
-    if (!state().m_realizedFont)
+    if (!state().m_font.realized())
         setFont(state().m_unparsedFont);
     return state().m_font;
 }

Modified: branches/safari-601-branch/Source/WebCore/html/canvas/CanvasRenderingContext2D.h (191049 => 191050)


--- branches/safari-601-branch/Source/WebCore/html/canvas/CanvasRenderingContext2D.h	2015-10-14 18:10:32 UTC (rev 191049)
+++ branches/safari-601-branch/Source/WebCore/html/canvas/CanvasRenderingContext2D.h	2015-10-14 18:49:28 UTC (rev 191050)
@@ -235,15 +235,33 @@
         LTR
     };
 
-    struct State final : FontSelectorClient {
+    class FontProxy : public FontSelectorClient {
+    public:
+        FontProxy() = default;
+        virtual ~FontProxy();
+        FontProxy(const FontProxy&);
+        FontProxy& operator=(const FontProxy&);
+
+        bool realized() const { return m_font.fontSelector(); }
+        void initialize(FontSelector&, RenderStyle&);
+        FontMetrics fontMetrics() const;
+        const FontDescription& fontDescription() const;
+        float width(const TextRun&) const;
+        void drawBidiText(GraphicsContext&, const TextRun&, const FloatPoint&, FontCascade::CustomFontNotReadyAction) const;
+
+    private:
+        void update(FontSelector&);
+        virtual void fontsNeedUpdate(FontSelector&) override;
+
+        FontCascade m_font;
+    };
+
+    struct State final {
         State();
-        virtual ~State();
 
         State(const State&);
         State& operator=(const State&);
 
-        virtual void fontsNeedUpdate(FontSelector*) override;
-
         String m_unparsedStrokeColor;
         String m_unparsedFillColor;
         CanvasStyle m_strokeStyle;
@@ -270,8 +288,7 @@
         Direction m_direction;
 
         String m_unparsedFont;
-        FontCascade m_font;
-        bool m_realizedFont;
+        FontProxy m_font;
     };
 
     enum CanvasDidDrawOption {
@@ -308,7 +325,9 @@
 
     void drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth = 0, bool useMaxWidth = false);
 
-    const FontCascade& accessFont();
+    // The relationship between FontCascade and CanvasRenderingContext2D::FontProxy must hold certain invariants.
+    // Therefore, all font operations must pass through the State.
+    const FontProxy& fontProxy();
 
 #if ENABLE(DASHBOARD_SUPPORT)
     void clearPathForDashboardBackwardCompatibilityMode();

Modified: branches/safari-601-branch/Source/WebCore/platform/graphics/FontSelector.h (191049 => 191050)


--- branches/safari-601-branch/Source/WebCore/platform/graphics/FontSelector.h	2015-10-14 18:10:32 UTC (rev 191049)
+++ branches/safari-601-branch/Source/WebCore/platform/graphics/FontSelector.h	2015-10-14 18:49:28 UTC (rev 191050)
@@ -48,8 +48,8 @@
 
     virtual void fontCacheInvalidated() { }
 
-    virtual void registerForInvalidationCallbacks(FontSelectorClient*) = 0;
-    virtual void unregisterForInvalidationCallbacks(FontSelectorClient*) = 0;
+    virtual void registerForInvalidationCallbacks(FontSelectorClient&) = 0;
+    virtual void unregisterForInvalidationCallbacks(FontSelectorClient&) = 0;
 
     virtual unsigned uniqueId() const = 0;
     virtual unsigned version() const = 0;
@@ -59,7 +59,7 @@
 public:
     virtual ~FontSelectorClient() { }
 
-    virtual void fontsNeedUpdate(FontSelector*) = 0;
+    virtual void fontsNeedUpdate(FontSelector&) = 0;
 };
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to