<!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>[193518] branches/safari-601-branch</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/193518">193518</a></dd>
<dt>Author</dt> <dd>matthew_hanson@apple.com</dd>
<dt>Date</dt> <dd>2015-12-05 10:30:14 -0800 (Sat, 05 Dec 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/189890">r189890</a>. rdar://problem/23769735</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari601branchLayoutTestsChangeLog">branches/safari-601-branch/LayoutTests/ChangeLog</a></li>
<li><a href="#branchessafari601branchLayoutTestsplatformeflTestExpectations">branches/safari-601-branch/LayoutTests/platform/efl/TestExpectations</a></li>
<li><a href="#branchessafari601branchLayoutTestsplatformwinTestExpectations">branches/safari-601-branch/LayoutTests/platform/win/TestExpectations</a></li>
<li><a href="#branchessafari601branchToolsChangeLog">branches/safari-601-branch/Tools/ChangeLog</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#branchessafari601branchLayoutTestscss3fontfeaturesettingsrendering2expectedhtml">branches/safari-601-branch/LayoutTests/css3/font-feature-settings-rendering-2-expected.html</a></li>
<li><a href="#branchessafari601branchLayoutTestscss3fontfeaturesettingsrendering2html">branches/safari-601-branch/LayoutTests/css3/font-feature-settings-rendering-2.html</a></li>
<li><a href="#branchessafari601branchLayoutTestscss3resourcesFontWithFeaturesotf">branches/safari-601-branch/LayoutTests/css3/resources/FontWithFeatures.otf</a></li>
<li>branches/safari-601-branch/Tools/FontWithFeatures/</li>
<li>branches/safari-601-branch/Tools/FontWithFeatures/FontWithFeatures/</li>
<li><a href="#branchessafari601branchToolsFontWithFeaturesFontWithFeaturesFontCreatorcpp">branches/safari-601-branch/Tools/FontWithFeatures/FontWithFeatures/FontCreator.cpp</a></li>
<li><a href="#branchessafari601branchToolsFontWithFeaturesFontWithFeaturesFontCreatorh">branches/safari-601-branch/Tools/FontWithFeatures/FontWithFeatures/FontCreator.h</a></li>
<li><a href="#branchessafari601branchToolsFontWithFeaturesFontWithFeaturesmaincpp">branches/safari-601-branch/Tools/FontWithFeatures/FontWithFeatures/main.cpp</a></li>
<li>branches/safari-601-branch/Tools/FontWithFeatures/FontWithFeatures.xcodeproj/</li>
<li><a href="#branchessafari601branchToolsFontWithFeaturesFontWithFeaturesxcodeprojprojectpbxproj">branches/safari-601-branch/Tools/FontWithFeatures/FontWithFeatures.xcodeproj/project.pbxproj</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari601branchLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-601-branch/LayoutTests/ChangeLog (193517 => 193518)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/LayoutTests/ChangeLog        2015-12-05 18:30:10 UTC (rev 193517)
+++ branches/safari-601-branch/LayoutTests/ChangeLog        2015-12-05 18:30:14 UTC (rev 193518)
</span><span class="lines">@@ -1,5 +1,22 @@
</span><span class="cx"> 2015-12-05  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r189890. rdar://problem/23769735
+
+    2015-09-16  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+            Create a font which can be used for testing font features
+            https://bugs.webkit.org/show_bug.cgi?id=149237
+
+            Reviewed by Simon Fraser.
+
+            * css3/font-feature-settings-rendering-2-expected.html: Added.
+            * css3/font-feature-settings-rendering-2.html: Added.
+            * css3/resources/FontWithFeatures.otf: Added.
+            * platform/efl/TestExpectations:
+            * platform/win/TestExpectations:
+
+2015-12-05  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
+
</ins><span class="cx">         Merge r188146. rdar://problem/23769732
</span><span class="cx"> 
</span><span class="cx">     2015-08-07  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span></span></pre></div>
<a id="branchessafari601branchLayoutTestscss3fontfeaturesettingsrendering2expectedhtml"></a>
<div class="addfile"><h4>Added: branches/safari-601-branch/LayoutTests/css3/font-feature-settings-rendering-2-expected.html (0 => 193518)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/LayoutTests/css3/font-feature-settings-rendering-2-expected.html                                (rev 0)
+++ branches/safari-601-branch/LayoutTests/css3/font-feature-settings-rendering-2-expected.html        2015-12-05 18:30:14 UTC (rev 193518)
</span><span class="lines">@@ -0,0 +1,46 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;style&gt;
+@font-face {
+    font-family: &quot;FontFeaturesTest&quot;;
+    src: url(&quot;resources/FontWithFeatures.otf&quot;) format(&quot;opentype&quot;);
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+This tests that font features are able to be turned on and off as desired. It uses a special font
+designed specifically for this purpose. The test passes if you see a sequence of alternating check
+marks and X below.
+&lt;div&gt;&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
+&lt;/div&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="branchessafari601branchLayoutTestscss3fontfeaturesettingsrendering2html"></a>
<div class="addfile"><h4>Added: branches/safari-601-branch/LayoutTests/css3/font-feature-settings-rendering-2.html (0 => 193518)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/LayoutTests/css3/font-feature-settings-rendering-2.html                                (rev 0)
+++ branches/safari-601-branch/LayoutTests/css3/font-feature-settings-rendering-2.html        2015-12-05 18:30:14 UTC (rev 193518)
</span><span class="lines">@@ -0,0 +1,60 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;style&gt;
+@font-face {
+    font-family: &quot;FontFeaturesTest&quot;;
+    src: url(&quot;resources/FontWithFeatures.otf&quot;) format(&quot;opentype&quot;);
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+This tests that font features are able to be turned on and off as desired. It uses a special font
+designed specifically for this purpose. The test passes if you see a sequence of alternating check
+marks and X below.
+&lt;div id=&quot;insertionpoint&quot;&gt;&lt;/div&gt;
+&lt;script&gt;
+var insertionpoint = document.getElementById(&quot;insertionpoint&quot;);
+function addElement(feature, c) {
+    [&quot;0&quot;, &quot;1&quot;].map(function(state) {
+        var element = document.createElement(&quot;span&quot;);
+        element.textContent = c;
+        element.style.fontFamily = &quot;FontFeaturesTest&quot;;
+        element.style.webkitFontFeatureSettings = '&quot;' + feature + '&quot; ' + state;
+        insertionpoint.appendChild(element);
+    });
+    insertionpoint.appendChild(document.createTextNode(&quot; &quot;));
+}
+addElement(&quot;liga&quot;, &quot;C&quot;);
+addElement(&quot;clig&quot;, &quot;D&quot;);
+addElement(&quot;dlig&quot;, &quot;E&quot;);
+addElement(&quot;hlig&quot;, &quot;F&quot;);
+addElement(&quot;calt&quot;, &quot;G&quot;);
+addElement(&quot;subs&quot;, &quot;H&quot;);
+addElement(&quot;sups&quot;, &quot;I&quot;);
+addElement(&quot;smcp&quot;, &quot;J&quot;);
+addElement(&quot;c2sc&quot;, &quot;K&quot;);
+addElement(&quot;pcap&quot;, &quot;L&quot;);
+addElement(&quot;c2pc&quot;, &quot;M&quot;);
+addElement(&quot;unic&quot;, &quot;N&quot;);
+addElement(&quot;titl&quot;, &quot;O&quot;);
+addElement(&quot;onum&quot;, &quot;P&quot;);
+addElement(&quot;pnum&quot;, &quot;Q&quot;);
+addElement(&quot;tnum&quot;, &quot;R&quot;);
+addElement(&quot;frac&quot;, &quot;S&quot;);
+//addElement(&quot;afrc&quot;, &quot;T&quot;);
+addElement(&quot;ordn&quot;, &quot;U&quot;);
+addElement(&quot;zero&quot;, &quot;V&quot;);
+addElement(&quot;hist&quot;, &quot;W&quot;);
+addElement(&quot;jp78&quot;, &quot;X&quot;);
+addElement(&quot;jp83&quot;, &quot;Y&quot;);
+addElement(&quot;jp90&quot;, &quot;Z&quot;);
+addElement(&quot;jp04&quot;, &quot;a&quot;);
+addElement(&quot;smpl&quot;, &quot;b&quot;);
+addElement(&quot;trad&quot;, &quot;c&quot;);
+addElement(&quot;fwid&quot;, &quot;d&quot;);
+addElement(&quot;pwid&quot;, &quot;e&quot;);
+addElement(&quot;ruby&quot;, &quot;f&quot;);
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="branchessafari601branchLayoutTestscss3resourcesFontWithFeaturesotf"></a>
<div class="addfile"><h4>Added: branches/safari-601-branch/LayoutTests/css3/resources/FontWithFeatures.otf (0 => 193518)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/LayoutTests/css3/resources/FontWithFeatures.otf                                (rev 0)
+++ branches/safari-601-branch/LayoutTests/css3/resources/FontWithFeatures.otf        2015-12-05 18:30:14 UTC (rev 193518)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+OTTO
+\x80 CFF \x94[\xA9D\xAC&quot;;GSUB\xC5b\xBB\xFE&quot;\xE8\x94OS/2H\xE0Yb'|dcmap\xD5\xAF'\xE0jheadeD\xF8(L6hheag7(\x84$hmtx(\xA8\xD4maxpk)| name\xA8)\x9C$post)\xC0 
+MylesFont9\x87\x87q\xDA
+MylesFont        
+ + !&quot;#$%&amp;'()*+,-./012345I\xA7G\xE7\x87'\xC7g\xA7G\xE7\x87'\xC7        g
+
+\xA7 G \xE7 \x87+'+\xC7g\xA7G\xE7\x87'\xC7g\xA7G\xE7\x87'\xC7g\xA7G\xE7\x87'\xC7g\xA7G\xE7 \x87\xFF\xFF\xFF\xFF\xC8\xFF\xC8\xFF\xFFX\xFFX\xFF\xFF\xFF\xFD\xA8\xFF\xFD\xA8\xFF\xFF\xFF\xFF\xFF\xC8\xFF\xF4\xFF2\xFF2\xFF\xFA\xFF\xFF\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFE&gt;\xFF\xFE&gt;\xFF\xFE\xD4\xFF,\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\x
 FF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xF
 F\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE
 \xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp
 \xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90
 \xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp
 \xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp
 \xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF
 \xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF
 2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x
 90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x
 90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\x
 FEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\
 x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF
 2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2
 \xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90
 \xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp
 \xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp
+X\xC2DFLT\xFF\xFF        
+ +liga\xB6clig\xBCdlig\xC2hlig\xC8calt\xCEsubs\xD4sups\xDAsmcp\xE0c2sc\xE6pcap\xECc2pc\xF2unic\xF8titl\xFEonumpnum
+tnumfracafrcordn&quot;zero(hist.jp784jp83:jp90@jp04FsmplLtradRfwidXpwid^rubyd        
+  +&gt;FNV^fnv~\x86\x8E\x96\x9E\xA6\xAE\xB6\xBE\xC6\xCE\xD6\xDE\xE6\xEE\xF6\xFE&amp;\xF0\xF6\xFC &amp;,28&gt;DJPV\bhntz\x80\x86\x8C\x92\x98\x9E        
+  + \xF4TKBW\xFF\xFFf\xFF\xFC\xFF\xFF \xFF\xFFD
+ (AZaz&amp;Zz\xFF\xFFAa\xFF\xFF\xFF\xDA\xFF\xA0y\xF6\x9C_&lt;\xF5f55\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF5        MylesFont
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="branchessafari601branchLayoutTestsplatformeflTestExpectations"></a>
<div class="modfile"><h4>Modified: branches/safari-601-branch/LayoutTests/platform/efl/TestExpectations (193517 => 193518)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/LayoutTests/platform/efl/TestExpectations        2015-12-05 18:30:10 UTC (rev 193517)
+++ branches/safari-601-branch/LayoutTests/platform/efl/TestExpectations        2015-12-05 18:30:14 UTC (rev 193518)
</span><span class="lines">@@ -81,6 +81,8 @@
</span><span class="cx"> # This test has been added for ios port since r185842.
</span><span class="cx"> fast/text/arabic-times-new-roman.html [ Skip ]
</span><span class="cx"> 
</span><ins>+css3/font-feature-settings-rendering-2.html [ Skip ]
+
</ins><span class="cx"> # ----------------------------------------
</span><span class="cx"> # Tests which also fail in other platforms
</span><span class="cx"> # ----------------------------------------
</span></span></pre></div>
<a id="branchessafari601branchLayoutTestsplatformwinTestExpectations"></a>
<div class="modfile"><h4>Modified: branches/safari-601-branch/LayoutTests/platform/win/TestExpectations (193517 => 193518)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/LayoutTests/platform/win/TestExpectations        2015-12-05 18:30:10 UTC (rev 193517)
+++ branches/safari-601-branch/LayoutTests/platform/win/TestExpectations        2015-12-05 18:30:14 UTC (rev 193518)
</span><span class="lines">@@ -458,6 +458,7 @@
</span><span class="cx"> 
</span><span class="cx"> # Font feature settings is not implemented.
</span><span class="cx"> css3/font-feature-settings-rendering.html [ Skip ]
</span><ins>+css3/font-feature-settings-rendering-2.html [ Skip ]
</ins><span class="cx"> 
</span><span class="cx"> # TODO HiDPI tests require test infrastructure enhancements (e.g. testRunner.setBackingScaleFactor)
</span><span class="cx"> # https://bugs.webkit.org/show_bug.cgi?id=87919
</span></span></pre></div>
<a id="branchessafari601branchToolsChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-601-branch/Tools/ChangeLog (193517 => 193518)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/Tools/ChangeLog        2015-12-05 18:30:10 UTC (rev 193517)
+++ branches/safari-601-branch/Tools/ChangeLog        2015-12-05 18:30:14 UTC (rev 193518)
</span><span class="lines">@@ -1,3 +1,118 @@
</span><ins>+2015-12-05  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
+
+        Merge r189890. rdar://problem/23769735
+
+    2015-09-16  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+            Create a font which can be used for testing font features
+            https://bugs.webkit.org/show_bug.cgi?id=149237
+
+            Reviewed by Simon Fraser.
+
+            This patch adds a new project in the Tools/ directory which generates a font which can
+            be used for testing font features. This is a standalone project consisting of two files:
+            1. A file which actually generates the byte vector representing the font. This file has
+            a single public function: std::vector&lt;uint8_t&gt; generateFont(). This file is not platform
+            specific, and only relies on the C++ STL.
+            2. A file with a main() which calls generateFont() and writes out the font, as well as
+            uses the font to render some demonstration text into a .png file. This file is platform
+            specific.
+
+            The font itself only supports the following characters:
+            ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+            However, the shape of these letters are either an X or a check mark.
+
+            The letter &quot;A&quot; always is a check mark.
+            The letter &quot;B&quot; always is an X.
+            Without any font features turned on, the rest of the letters are shown as X.
+
+            Each font feature has an letter associated with it. When the font feature is enabled,
+            that letter is shown as a check mark. For example, when &quot;smcp&quot; is enabled, &quot;J&quot; is shown
+            as a check mark.
+
+            Here are the mappings of font features to letters:
+            liga: C
+            clig: D
+            dlig: E
+            hlig: F
+            calt: G
+            subs: H
+            sups: I
+            smcp: J
+            c2sc: K
+            pcap: L
+            c2pc: M
+            unic: N
+            titl: O
+            onum: P
+            pnum: Q
+            tnum: R
+            frac: S
+            afrc: T
+            ordn: U
+            zero: V
+            hist: W
+            jp78: X
+            jp83: Y
+            jp90: Z
+            jp04: a
+            smpl: b
+            trad: c
+            fwid: d
+            pwid: e
+            ruby: f
+
+            * FontWithFeatures/FontWithFeatures.xcodeproj/project.pbxproj: Added.
+            * FontWithFeatures/FontWithFeatures/FontCreator.cpp: Added.
+            (integralLog2):
+            (roundDownToPowerOfTwo):
+            (isFourByteAligned):
+            (clampTo):
+            (append32):
+            (writeCFFEncodedNumber):
+            (CFFBuilder::CFFBuilder):
+            (CFFBuilder::takeResult):
+            (CFFBuilder::moveTo):
+            (CFFBuilder::lineTo):
+            (CFFBuilder::curveToCubic):
+            (CFFBuilder::closePath):
+            (CFFBuilder::writePoint):
+            (generateBoxCharString):
+            (generateCheckCharString):
+            (generateXCharString):
+            (charStringForGlyph):
+            (Generator::generate):
+            (Generator::Placeholder::Placeholder):
+            (Generator::Placeholder::populate):
+            (Generator::Placeholder::~Placeholder):
+            (Generator::placeholder):
+            (Generator::append16):
+            (Generator::append32):
+            (Generator::append32BitCode):
+            (Generator::overwrite16):
+            (Generator::overwrite32):
+            (Generator::appendCFFTable):
+            (Generator::appendSubstitutionSubtable):
+            (Generator::appendScriptSubtable):
+            (Generator::appendGSUBTable):
+            (Generator::appendOS2Table):
+            (Generator::appendFormat12CMAPTable):
+            (Generator::appendFormat4CMAPTable):
+            (Generator::appendCMAPTable):
+            (Generator::appendHEADTable):
+            (Generator::appendHHEATable):
+            (Generator::appendHMTXTable):
+            (Generator::appendMAXPTable):
+            (Generator::appendNAMETable):
+            (Generator::appendPOSTTable):
+            (Generator::calculateChecksum):
+            (Generator::appendTable):
+            (generateFont):
+            * FontWithFeatures/FontWithFeatures/FontCreator.h: Added.
+            * FontWithFeatures/FontWithFeatures/main.cpp: Added.
+            (drawTextWithFeature):
+            (main):
+
</ins><span class="cx"> 2015-10-27  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Merge r191395. rdar://problem/22847057
</span></span></pre></div>
<a id="branchessafari601branchToolsFontWithFeaturesFontWithFeaturesFontCreatorcpp"></a>
<div class="addfile"><h4>Added: branches/safari-601-branch/Tools/FontWithFeatures/FontWithFeatures/FontCreator.cpp (0 => 193518)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/Tools/FontWithFeatures/FontWithFeatures/FontCreator.cpp                                (rev 0)
+++ branches/safari-601-branch/Tools/FontWithFeatures/FontWithFeatures/FontCreator.cpp        2015-12-05 18:30:14 UTC (rev 193518)
</span><span class="lines">@@ -0,0 +1,788 @@
</span><ins>+//
+//  FontCreator.cpp
+//  FontWithFeatures
+//
+//  Created by Litherum on 9/15/15.
+//  Copyright © 2015 Litherum. All rights reserved.
+//
+
+#include &quot;FontCreator.h&quot;
+
+#include &lt;array&gt;
+#include &lt;cassert&gt;
+#include &lt;string&gt;
+
+static const size_t headerSize = 12;
+static const size_t directoryEntrySize = 16;
+static const int16_t unitsPerEm = 1024;
+static const uint16_t numGlyphs = 26 * 2 + 1;
+
+static inline uint16_t integralLog2(uint16_t x)
+{
+    uint16_t result = 0;
+    while (x &gt;&gt;= 1)
+        ++result;
+    return result;
+}
+
+static inline uint16_t roundDownToPowerOfTwo(uint16_t x)
+{
+    x |= x &gt;&gt; 1;
+    x |= x &gt;&gt; 2;
+    x |= x &gt;&gt; 4;
+    x |= x &gt;&gt; 8;
+    return (x &gt;&gt; 1) + 1;
+}
+
+static inline bool isFourByteAligned(size_t x)
+{
+    return !(x &amp; 3);
+}
+
+// Assumption: T2 can hold every value that a T1 can hold.
+template&lt;typename T1, typename T2&gt; static inline T1 clampTo(T2 x)
+{
+    x = std::min(x, static_cast&lt;T2&gt;(std::numeric_limits&lt;T1&gt;::max()));
+    x = std::max(x, static_cast&lt;T2&gt;(std::numeric_limits&lt;T1&gt;::min()));
+    return static_cast&lt;T1&gt;(x);
+}
+
+template &lt;typename V&gt;
+static inline void append32(V&amp; result, uint32_t value)
+{
+    result.push_back(value &gt;&gt; 24);
+    result.push_back(value &gt;&gt; 16);
+    result.push_back(value &gt;&gt; 8);
+    result.push_back(value);
+}
+
+template &lt;typename V&gt;
+static void writeCFFEncodedNumber(V&amp; vector, float number)
+{
+    vector.push_back(0xFF);
+    // Convert to 16.16 fixed-point
+    append32(vector, clampTo&lt;int32_t&gt;(number * 0x10000));
+}
+
+static const char rLineTo = 0x05;
+static const char rrCurveTo = 0x08;
+static const char endChar = 0x0e;
+static const char rMoveTo = 0x15;
+
+class CFFBuilder {
+public:
+    CFFBuilder(float width, std::pair&lt;float, float&gt; origin)
+    {
+        writeCFFEncodedNumber(result, width);
+        writeCFFEncodedNumber(result, origin.first);
+        writeCFFEncodedNumber(result, origin.second);
+        result.push_back(rMoveTo);
+    }
+
+    std::vector&lt;uint8_t&gt; takeResult()
+    {
+        result.push_back(endChar);
+        return std::move(result);
+    }
+
+    void moveTo(std::pair&lt;float, float&gt; targetPoint, bool closed)
+    {
+        if (closed &amp;&amp; !result.empty())
+            closePath();
+
+        std::pair&lt;float, float&gt; destination = targetPoint;
+
+        writePoint(destination);
+        result.push_back(rMoveTo);
+
+        startingPoint = current;
+    }
+
+    void lineTo(std::pair&lt;float, float&gt; targetPoint)
+    {
+        std::pair&lt;float, float&gt; destination = targetPoint;
+
+        writePoint(destination);
+        result.push_back(rLineTo);
+    }
+
+    void curveToCubic(std::pair&lt;float, float&gt; point1, std::pair&lt;float, float&gt; point2, std::pair&lt;float, float&gt; targetPoint)
+    {
+        std::pair&lt;float, float&gt; destination1 = point1;
+        std::pair&lt;float, float&gt; destination2 = point2;
+        std::pair&lt;float, float&gt; destination3 = targetPoint;
+
+        writePoint(destination1);
+        writePoint(destination2);
+        writePoint(destination3);
+        result.push_back(rrCurveTo);
+    }
+
+    void closePath()
+    {
+        if (current != startingPoint)
+            lineTo(startingPoint);
+    }
+
+private:
+    void writePoint(std::pair&lt;float, float&gt; destination)
+    {
+        std::pair&lt;float, float&gt; delta = std::make_pair(destination.first - current.first, destination.second - current.second);
+        writeCFFEncodedNumber(result, delta.first);
+        writeCFFEncodedNumber(result, delta.second);
+
+        current = destination;
+    }
+
+    std::vector&lt;uint8_t&gt; result;
+    std::pair&lt;float, float&gt; startingPoint;
+    std::pair&lt;float, float&gt; current;
+};
+
+std::vector&lt;uint8_t&gt; generateBoxCharString()
+{
+    CFFBuilder builder(unitsPerEm, std::make_pair(0.f, 0.f));
+    builder.moveTo(std::make_pair(200.f, 200.f), false);
+    builder.lineTo(std::make_pair(200.f, 800.f));
+    builder.lineTo(std::make_pair(800.f, 800.f));
+    builder.lineTo(std::make_pair(800.f, 200.f));
+    builder.closePath();
+    return builder.takeResult();
+}
+
+std::vector&lt;uint8_t&gt; generateCheckCharString()
+{
+    CFFBuilder builder(unitsPerEm, std::make_pair(0.f, 0.f));
+    builder.moveTo(std::make_pair(200.f, 500.f), false);
+    builder.lineTo(std::make_pair(250.f, 550.f));
+    builder.lineTo(std::make_pair(500.f, 300.f));
+    builder.lineTo(std::make_pair(900.f, 700.f));
+    builder.lineTo(std::make_pair(950.f, 650.f));
+    builder.lineTo(std::make_pair(500.f, 200.f));
+    builder.closePath();
+    return builder.takeResult();
+}
+
+std::vector&lt;uint8_t&gt; generateXCharString()
+{
+    CFFBuilder builder(unitsPerEm, std::make_pair(0.f, 0.f));
+    builder.moveTo(std::make_pair(500.0f, 550.0f), false);
+    builder.lineTo(std::make_pair(900.f, 950.f));
+    builder.lineTo(std::make_pair(950.f, 900.f));
+    builder.lineTo(std::make_pair(550.f, 500.f));
+    builder.lineTo(std::make_pair(950.f, 100.f));
+    builder.lineTo(std::make_pair(900.f,  50.f));
+    builder.lineTo(std::make_pair(500.f, 450.f));
+    builder.lineTo(std::make_pair(100.f,  50.f));
+    builder.lineTo(std::make_pair(50.f , 100.f));
+    builder.lineTo(std::make_pair(450.f, 500.f));
+    builder.lineTo(std::make_pair(50.f , 900.f));
+    builder.lineTo(std::make_pair(100.f, 950.f));
+    builder.closePath();
+    return builder.takeResult();
+}
+
+std::vector&lt;uint8_t&gt;&amp; charStringForGlyph(uint16_t glyph, std::vector&lt;uint8_t&gt;&amp; boxCharString, std::vector&lt;uint8_t&gt;&amp; checkCharString, std::vector&lt;uint8_t&gt;&amp; xCharString)
+{
+    if (!glyph)
+        return boxCharString;
+    if (glyph == 1)
+        return checkCharString;
+    return xCharString;
+}
+
+class Generator {
+public:
+    std::vector&lt;uint8_t&gt; generate()
+    {
+        uint16_t numTables = 10;
+        uint16_t roundedNumTables = roundDownToPowerOfTwo(numTables);
+        uint16_t searchRange = roundedNumTables * 16; // searchRange: &quot;(Maximum power of 2 &lt;= numTables) x 16.&quot;
+
+        result.push_back('O');
+        result.push_back('T');
+        result.push_back('T');
+        result.push_back('O');
+        append16(numTables);
+        append16(searchRange);
+        append16(integralLog2(roundedNumTables)); // entrySelector: &quot;Log2(maximum power of 2 &lt;= numTables).&quot;
+        append16(numTables * 16 - searchRange); // rangeShift: &quot;NumTables x 16-searchRange.&quot;
+
+        assert(result.size() == headerSize);
+
+        // Leave space for the directory entries.
+        for (size_t i = 0; i &lt; directoryEntrySize * numTables; ++i)
+            result.push_back(0);
+
+        appendTable(&quot;CFF &quot;, &amp;Generator::appendCFFTable);
+        appendTable(&quot;GSUB&quot;, &amp;Generator::appendGSUBTable);
+        appendTable(&quot;OS/2&quot;, &amp;Generator::appendOS2Table);
+        appendTable(&quot;cmap&quot;, &amp;Generator::appendCMAPTable);
+        auto headTableOffset = result.size();
+        appendTable(&quot;head&quot;, &amp;Generator::appendHEADTable);
+        appendTable(&quot;hhea&quot;, &amp;Generator::appendHHEATable);
+        appendTable(&quot;hmtx&quot;, &amp;Generator::appendHMTXTable);
+        appendTable(&quot;maxp&quot;, &amp;Generator::appendMAXPTable);
+        appendTable(&quot;name&quot;, &amp;Generator::appendNAMETable);
+        appendTable(&quot;post&quot;, &amp;Generator::appendPOSTTable);
+
+        assert(numTables == m_tablesAppendedCount);
+
+        // checksumAdjustment: &quot;To compute: set it to 0, calculate the checksum for the 'head' table and put it in the table directory,
+        // sum the entire font as uint32, then store B1B0AFBA - sum. The checksum for the 'head' table will now be wrong. That is OK.&quot;
+        overwrite32(headTableOffset + 8, 0xB1B0AFBAU - calculateChecksum(0, result.size()));
+        return std::move(result);
+    }
+
+private:
+    class Placeholder {
+    public:
+        Placeholder(Generator&amp; generator, size_t baseOfOffset)
+            : generator(generator)
+            , baseOfOffset(baseOfOffset)
+            , location(generator.result.size())
+        {
+            generator.append16(0);
+        }
+
+        Placeholder(Placeholder&amp;&amp; other)
+            : generator(other.generator)
+            , baseOfOffset(other.baseOfOffset)
+            , location(other.location)
+            , active(other.active)
+        {
+            other.active = false;
+        }
+
+        void populate()
+        {
+            assert(active);
+            size_t delta = generator.result.size() - baseOfOffset;
+            assert(delta &lt; std::numeric_limits&lt;uint16_t&gt;::max());
+            generator.overwrite16(location, delta);
+            active = false;
+        }
+
+        ~Placeholder()
+        {
+            assert(!active);
+        }
+
+    private:
+        Generator&amp; generator;
+        const size_t baseOfOffset;
+        const size_t location;
+        bool active { true };
+    };
+
+    Placeholder placeholder(size_t baseOfOffset)
+    {
+        return Placeholder(*this, baseOfOffset);
+    }
+
+    void append16(uint16_t value)
+    {
+        result.push_back(value &gt;&gt; 8);
+        result.push_back(value);
+    }
+
+    void append32(uint32_t value)
+    {
+        ::append32(result, value);
+    }
+
+    void append32BitCode(const char code[4])
+    {
+        result.push_back(code[0]);
+        result.push_back(code[1]);
+        result.push_back(code[2]);
+        result.push_back(code[3]);
+    }
+
+    void overwrite16(size_t location, uint16_t value)
+    {
+        assert(result.size() &gt;= location + 2);
+        result[location] = value &gt;&gt; 8;
+        result[location + 1] = value;
+    }
+
+    void overwrite32(size_t location, uint32_t value)
+    {
+        assert(result.size() &gt;= location + 4);
+        result[location] = value &gt;&gt; 24;
+        result[location + 1] = value &gt;&gt; 16;
+        result[location + 2] = value &gt;&gt; 8;
+        result[location + 3] = value;
+    }
+    
+    void appendCFFTable()
+    {
+        auto startingOffset = result.size();
+
+        // Header
+        result.push_back(1); // Major version
+        result.push_back(0); // Minor version
+        result.push_back(4); // Header size
+        result.push_back(4); // Offsets within CFF table are 4 bytes long
+
+        // Name INDEX
+        std::string fontName = &quot;MylesFont&quot;;
+        append16(1); // INDEX contains 1 element
+        result.push_back(4); // Offsets in this INDEX are 4 bytes long
+        append32(1); // 1-index offset of name data
+        append32(static_cast&lt;uint32_t&gt;(fontName.length() + 1)); // 1-index offset just past end of name data
+        for (char c : fontName)
+            result.push_back(c);
+
+        const char operand32Bit = 29;
+        const char fullNameKey = 2;
+        const char familyNameKey = 3;
+        const char fontBBoxKey = 5;
+        const char charsetIndexKey = 15;
+        const char charstringsIndexKey = 17;
+        const char privateDictIndexKey = 18;
+        const uint32_t userDefinedStringStartIndex = 391;
+        const unsigned sizeOfTopIndex = 56;
+
+        // Top DICT INDEX.
+        append16(1); // INDEX contains 1 element
+        result.push_back(4); // Offsets in this INDEX are 4 bytes long
+        append32(1); // 1-index offset of DICT data
+        append32(1 + sizeOfTopIndex); // 1-index offset just past end of DICT data
+
+        // DICT information
+        size_t topDictStart = result.size();
+        result.push_back(operand32Bit);
+        append32(userDefinedStringStartIndex);
+        result.push_back(fullNameKey);
+        result.push_back(operand32Bit);
+        append32(userDefinedStringStartIndex);
+        result.push_back(familyNameKey);
+        result.push_back(operand32Bit);
+        append32(clampTo&lt;int32_t&gt;(0)); // Bounding box x
+        result.push_back(operand32Bit);
+        append32(clampTo&lt;int32_t&gt;(0)); // Bounding box y
+        result.push_back(operand32Bit);
+        append32(clampTo&lt;int32_t&gt;(unitsPerEm)); // Bounding box max x
+        result.push_back(operand32Bit);
+        append32(clampTo&lt;int32_t&gt;(unitsPerEm)); // Bounding box max y
+        result.push_back(fontBBoxKey);
+        result.push_back(operand32Bit);
+        size_t charsetOffsetLocation = result.size();
+        append32(0); // Offset of Charset info. Will be overwritten later.
+        result.push_back(charsetIndexKey);
+        result.push_back(operand32Bit);
+        size_t charstringsOffsetLocation = result.size();
+        append32(0); // Offset of CharStrings INDEX. Will be overwritten later.
+        result.push_back(charstringsIndexKey);
+        result.push_back(operand32Bit);
+        append32(0); // 0-sized private dict
+        result.push_back(operand32Bit);
+        append32(0); // no location for private dict
+        result.push_back(privateDictIndexKey); // Private dict size and offset
+        assert(result.size() == topDictStart + sizeOfTopIndex);
+
+        // String INDEX
+        append16(1); // Number of elements in INDEX
+        result.push_back(4); // Offsets in this INDEX are 4 bytes long
+        uint32_t offset = 1;
+        append32(offset);
+        offset += fontName.length();
+        append32(offset);
+        for (char c : fontName)
+            result.push_back(c);
+
+        append16(0); // Empty subroutine INDEX
+    
+        // Charset info
+        overwrite32(charsetOffsetLocation, static_cast&lt;uint32_t&gt;(result.size() - startingOffset));
+        result.push_back(0);
+        for (int i = 1; i &lt; numGlyphs; ++i)
+            append16(i);
+
+        // CharStrings INDEX
+        std::vector&lt;uint8_t&gt; boxCharString = generateBoxCharString();
+        std::vector&lt;uint8_t&gt; checkCharString = generateCheckCharString();
+        std::vector&lt;uint8_t&gt; xCharString = generateXCharString();
+        assert(numGlyphs &gt; 26);
+        overwrite32(charstringsOffsetLocation, static_cast&lt;uint32_t&gt;(result.size() - startingOffset));
+        append16(numGlyphs);
+        result.push_back(4); // Offsets in this INDEX are 4 bytes long
+        offset = 1;
+        append32(offset);
+        for (uint16_t glyph = 0; glyph &lt; numGlyphs; ++glyph) {
+            offset += charStringForGlyph(glyph, boxCharString, checkCharString, xCharString).size();
+            append32(offset);
+        }
+        for (uint16_t glyph = 0; glyph &lt; numGlyphs; ++glyph) {
+            std::vector&lt;uint8_t&gt;&amp; charString = charStringForGlyph(glyph, boxCharString, checkCharString, xCharString);
+            result.insert(result.end(), charString.begin(), charString.end());
+        }
+    }
+
+    void appendSubstitutionSubtable(size_t subtableRecordLocation, uint16_t iGetReplaced, uint16_t replacedWithMe)
+    {
+        overwrite16(subtableRecordLocation + 6, result.size() - subtableRecordLocation);
+        auto subtableLocation = result.size();
+        append16(2); // Format 2
+        append16(0); // Placeholder for offset to coverage table, relative to beginning of substitution table
+        append16(1); // GlyphCount
+        append16(replacedWithMe); // Substitute with this glyph.
+
+        // Coverage table
+        overwrite16(subtableLocation + 2, result.size() - subtableLocation);
+        append16(1); // CoverageFormat
+        append16(1); // GlyphCount
+        append16(iGetReplaced); // This glyph is covered in the coverage.
+    }
+
+    void appendScriptSubtable(uint16_t featureCount)
+    {
+        auto dfltScriptTableLocation = result.size();
+        append16(0); // Placeholder for offset of default language system table, relative to beginning of Script table
+        append16(0); // Number of following language system tables
+
+        // LangSys table
+        overwrite16(dfltScriptTableLocation, result.size() - dfltScriptTableLocation);
+        append16(0); // LookupOrder &quot;= NULL ... reserved&quot;
+        append16(0xFFFF); // No features are required
+        append16(featureCount); // Number of FeatureIndex values
+        for (uint16_t i = 0; i &lt; featureCount; ++i)
+            append16(i); // Features indices
+    }
+
+    void appendGSUBTable()
+    {
+        std::vector&lt;std::array&lt;char, 5&gt;&gt; features {{&quot;liga&quot;}, {&quot;clig&quot;}, {&quot;dlig&quot;}, {&quot;hlig&quot;}, {&quot;calt&quot;}, {&quot;subs&quot;}, {&quot;sups&quot;}, {&quot;smcp&quot;}, {&quot;c2sc&quot;}, {&quot;pcap&quot;}, {&quot;c2pc&quot;}, {&quot;unic&quot;}, {&quot;titl&quot;}, {&quot;onum&quot;}, {&quot;pnum&quot;}, {&quot;tnum&quot;}, {&quot;frac&quot;}, {&quot;afrc&quot;}, {&quot;ordn&quot;}, {&quot;zero&quot;}, {&quot;hist&quot;}, {&quot;jp78&quot;}, {&quot;jp83&quot;}, {&quot;jp90&quot;}, {&quot;jp04&quot;}, {&quot;smpl&quot;}, {&quot;trad&quot;}, {&quot;fwid&quot;}, {&quot;pwid&quot;}, {&quot;ruby&quot;}};
+        auto tableLocation = result.size();
+        auto headerSize = 10;
+
+        append32(0x00010000); // Version
+        append16(headerSize); // Offset to ScriptList
+        Placeholder toFeatureList = placeholder(tableLocation);
+        Placeholder toLookupList = placeholder(tableLocation);
+        assert(tableLocation + headerSize == result.size());
+
+        // ScriptList
+        auto scriptListLocation = result.size();
+        append16(1); // Number of ScriptRecords
+        append32BitCode(&quot;DFLT&quot;);
+        append16(0); // Placeholder for offset of Script table, relative to beginning of ScriptList
+
+        overwrite16(scriptListLocation + 6, result.size() - scriptListLocation);
+        appendScriptSubtable(static_cast&lt;uint16_t&gt;(features.size()));
+
+        // FeatureList
+        toFeatureList.populate();
+        auto featureListLocation = result.size();
+        size_t featureListSize = 2 + 6 * features.size();
+        size_t featureTableSize = 6;
+        append16(features.size()); // FeatureCount
+        for (unsigned i = 0; i &lt; features.size(); ++i) {
+            auto&amp; code = features[i];
+            append32BitCode(code.data()); // Feature name
+            append16(featureListSize + featureTableSize * i); // Offset of feature table, relative to beginning of FeatureList table
+        }
+        assert(featureListLocation + featureListSize == result.size());
+
+        for (unsigned i = 0; i &lt; features.size(); ++i) {
+            auto featureTableStart = result.size();
+            append16(0); // FeatureParams &quot;= NULL ... reserved&quot;
+            append16(1); // LookupCount
+            append16(i); // LookupListIndex
+            assert(featureTableStart + featureTableSize == result.size());
+        }
+
+        // LookupList
+        toLookupList.populate();
+        auto lookupListLocation = result.size();
+        append16(features.size()); // LookupCount
+        for (unsigned i = 0; i &lt; features.size(); ++i)
+            append16(0); // Placeholder for offset to lookup table, relative to beginning of LookupList
+        size_t subtableRecordLocations[features.size()];
+        for (unsigned i = 0; i &lt; features.size(); ++i) {
+            subtableRecordLocations[i] = result.size();
+            overwrite16(lookupListLocation + 2 + 2 * i, result.size() - lookupListLocation);
+            append16(1); // Type 1: &quot;Replace one glyph with one glyph&quot;
+            append16(0); // LookupFlag
+            append16(1); // SubTableCount
+            append16(0); // Placeholder for offset to subtable, relative to beginning of Lookup table
+        }
+
+        for (unsigned i = 0; i &lt; features.size(); ++i)
+            appendSubstitutionSubtable(subtableRecordLocations[i], 3 + i, 1);
+    }
+
+    void appendOS2Table()
+    {
+        append16(2); // Version
+        append16(clampTo&lt;int16_t&gt;(unitsPerEm)); // Average advance
+        append16(clampTo&lt;uint16_t&gt;(500)); // Weight class
+        append16(5); // Width class
+        append16(0); // Protected font
+        // WebKit handles these superscripts and subscripts
+        append16(0); // Subscript X Size
+        append16(0); // Subscript Y Size
+        append16(0); // Subscript X Offset
+        append16(0); // Subscript Y Offset
+        append16(0); // Superscript X Size
+        append16(0); // Superscript Y Size
+        append16(0); // Superscript X Offset
+        append16(0); // Superscript Y Offset
+        append16(0); // Strikeout width
+        append16(0); // Strikeout Position
+        append16(0); // No classification
+
+        for (int i = 0; i &lt; 10; ++i)
+            result.push_back(0);
+
+        for (int i = 0; i &lt; 4; ++i)
+            append32(0); // &quot;Bit assignments are pending. Set to 0&quot;
+        append32(0x544B4257); // Font Vendor. &quot;WBKT&quot;
+        append16(0); // Font Patterns.
+        append16(0); // First unicode index
+        append16(0xFFFF); // Last unicode index
+        append16(clampTo&lt;int16_t&gt;(unitsPerEm)); // Typographical ascender
+        append16(clampTo&lt;int16_t&gt;(1)); // Typographical descender
+        append16(clampTo&lt;int16_t&gt;(unitsPerEm / 10)); // Typographical line gap
+        append16(clampTo&lt;uint16_t&gt;(unitsPerEm)); // Windows-specific ascent
+        append16(clampTo&lt;uint16_t&gt;(1)); // Windows-specific descent
+        append32(0xFF10FC07); // Bitmask for supported codepages (Part 1). Report all pages as supported.
+        append32(0x0000FFFF); // Bitmask for supported codepages (Part 2). Report all pages as supported.
+        append16(clampTo&lt;int16_t&gt;(unitsPerEm / 2)); // x-height
+        append16(clampTo&lt;int16_t&gt;(unitsPerEm)); // Cap-height
+        append16(0); // Default char
+        append16(' '); // Break character
+        append16(3); // Maximum context needed to perform font features
+        append16(3); // Smallest optical point size
+        append16(0xFFFF); // Largest optical point size
+    }
+
+    void appendFormat12CMAPTable()
+    {
+        // Braindead scheme: One segment for each character
+        auto subtableLocation = result.size();
+        append32(12 &lt;&lt; 16); // Format 12
+        append32(0); // Placeholder for byte length
+        append32(0); // Language independent
+        append32(2); //  nGroups
+        append32('A'); // startCharCode
+        append32('Z'); // endCharCode
+        append32(1); // startGlyphCode
+        append32('a'); // startCharCode
+        append32('z'); // endCharCode
+        append32(27); // startGlyphCode
+        overwrite32(subtableLocation + 4, static_cast&lt;uint32_t&gt;(result.size() - subtableLocation));
+    }
+
+    void appendFormat4CMAPTable()
+    {
+        auto subtableLocation = result.size();
+        append16(4); // Format 4
+        append16(0); // Placeholder for length in bytes
+        append16(0); // Language independent
+        uint16_t segCount = 3;
+        append16(clampTo&lt;uint16_t&gt;(2 * segCount)); // segCountX2: &quot;2 x segCount&quot;
+        uint16_t originalSearchRange = roundDownToPowerOfTwo(segCount);
+        uint16_t searchRange = clampTo&lt;uint16_t&gt;(2 * originalSearchRange); // searchRange: &quot;2 x (2**floor(log2(segCount)))&quot;
+        append16(searchRange);
+        append16(integralLog2(originalSearchRange)); // entrySelector: &quot;log2(searchRange/2)&quot;
+        append16(clampTo&lt;uint16_t&gt;((2 * segCount) - searchRange)); // rangeShift: &quot;2 x segCount - searchRange&quot;
+
+        // Ending character codes
+        append16('Z');
+        append16('z');
+        append16(0xFFFF);
+
+        append16(0); // reserved
+
+        // Starting character codes
+        append16('A');
+        append16('a');
+        append16(0xFFFF);
+
+        // idDelta
+        append16(static_cast&lt;uint16_t&gt;(27) - static_cast&lt;uint16_t&gt;('A'));
+        append16(static_cast&lt;uint16_t&gt;(1) - static_cast&lt;uint16_t&gt;('a'));
+        append16(0x0001);
+
+        // idRangeOffset
+        append16(0); // idRangeOffset
+        append16(0);
+
+        // Fonts strive to hold 2^16 glyphs, but with the current encoding scheme, we write 8 bytes per codepoint into this subtable.
+        // Because the size of this subtable must be represented as a 16-bit number, we are limiting the number of glyphs we support to 2^13.
+        // FIXME: If we hit this limit in the wild, use a more compact encoding scheme for this subtable.
+        overwrite16(subtableLocation + 2, clampTo&lt;uint16_t&gt;(result.size() - subtableLocation));
+    }
+    
+    void appendCMAPTable()
+    {
+        auto startingOffset = result.size();
+        append16(0);
+        append16(3); // Number of subtables
+
+        append16(0); // Unicode
+        append16(3); // Unicode version 2.2+
+        append32(28); // Byte offset of subtable
+
+        append16(3); // Microsoft
+        append16(1); // Unicode BMP
+        auto format4OffsetLocation = result.size();
+        append32(0); // Byte offset of subtable
+
+        append16(3); // Microsoft
+        append16(10); // Unicode
+        append32(28); // Byte offset of subtable
+
+        appendFormat12CMAPTable();
+        overwrite32(format4OffsetLocation, static_cast&lt;uint32_t&gt;(result.size() - startingOffset));
+        appendFormat4CMAPTable();
+    }
+    
+    void appendHEADTable()
+    {
+        append32(0x00010000); // Version
+        append32(0x00010000); // Revision
+        append32(0); // Checksum placeholder; to be overwritten by the caller.
+        append32(0x5F0F3CF5); // Magic number.
+        append16((1 &lt;&lt; 9) | 1);
+
+        append16(unitsPerEm);
+        append32(0); // First half of creation date
+        append32(0); // Last half of creation date
+        append32(0); // First half of modification date
+        append32(0); // Last half of modification date
+        append16(clampTo&lt;int16_t&gt;(0)); // bounding box x
+        append16(clampTo&lt;int16_t&gt;(0)); // bounding box y
+        append16(clampTo&lt;int16_t&gt;(unitsPerEm)); // bounding box max x
+        append16(clampTo&lt;int16_t&gt;(unitsPerEm)); // bounding box max y
+        append16(0); // Traits
+        append16(3); // Smallest readable size in pixels
+        append16(0); // Might contain LTR or RTL glyphs
+        append16(0); // Short offsets in the 'loca' table. However, OTF fonts don't have a 'loca' table so this is irrelevant
+        append16(0); // Glyph data format
+    }
+    
+    void appendHHEATable()
+    {
+        append32(0x00010000); // Version
+        append16(clampTo&lt;int16_t&gt;(unitsPerEm)); // ascent
+        append16(clampTo&lt;int16_t&gt;(1)); // descent
+        // WebKit SVG font rendering has hard coded the line gap to be 1/10th of the font size since 2008 (see r29719).
+        append16(clampTo&lt;int16_t&gt;(unitsPerEm / 10)); // line gap
+        append16(clampTo&lt;uint16_t&gt;(unitsPerEm)); // advance width max
+        append16(clampTo&lt;int16_t&gt;(0)); // Minimum left side bearing
+        append16(clampTo&lt;int16_t&gt;(0)); // Minimum right side bearing
+        append16(clampTo&lt;int16_t&gt;(unitsPerEm)); // X maximum extent
+        // Since WebKit draws the caret and ignores the following values, it doesn't matter what we set them to.
+        append16(1); // Vertical caret
+        append16(0); // Vertical caret
+        append16(0); // &quot;Set value to 0 for non-slanted fonts&quot;
+        append32(0); // Reserved
+        append32(0); // Reserved
+        append16(0); // Current format
+        append16(numGlyphs); // Number of advance widths in HMTX table
+    }
+    
+    void appendHMTXTable()
+    {
+        for (unsigned i = 0; i &lt; numGlyphs; ++i) {
+            append16(clampTo&lt;uint16_t&gt;(unitsPerEm)); // horizontal advance
+            append16(clampTo&lt;int16_t&gt;(0)); // left side bearing
+        }
+    }
+    
+    void appendMAXPTable()
+    {
+        append32(0x00010000); // Version
+        append16(numGlyphs); // Number of glyphs
+        append16(0xFFFF); // Maximum number of points in non-compound glyph
+        append16(0xFFFF); // Maximum number of contours in non-compound glyph
+        append16(0xFFFF); // Maximum number of points in compound glyph
+        append16(0xFFFF); // Maximum number of contours in compound glyph
+        append16(2); // Maximum number of zones
+        append16(0); // Maximum number of points used in zone 0
+        append16(0); // Maximum number of storage area locations
+        append16(0); // Maximum number of function definitions
+        append16(0); // Maximum number of instruction definitions
+        append16(0); // Maximum stack depth
+        append16(0); // Maximum size of instructions
+        append16(numGlyphs); // Maximum number of glyphs referenced at top level
+        append16(0); // No compound glyphs
+    }
+    
+    void appendNAMETable()
+    {
+        std::string fontName = &quot;MylesFont&quot;;
+
+        append16(0); // Format selector
+        append16(1); // Number of name records in table
+        append16(18); // Offset in bytes to the beginning of name character strings
+
+        append16(0); // Unicode
+        append16(3); // Unicode version 2.0 or later
+        append16(0); // Language
+        append16(1); // Name identifier. 1 = Font family
+        append16(fontName.length());
+        append16(0); // Offset into name data
+
+        for (auto codeUnit : fontName)
+            append16(codeUnit);
+    }
+    
+    void appendPOSTTable()
+    {
+        append32(0x00030000); // Format. Printing is undefined
+        append32(0); // Italic angle in degrees
+        append16(0); // Underline position
+        append16(0); // Underline thickness
+        append32(0); // Monospaced
+        append32(0); // &quot;Minimum memory usage when a TrueType font is downloaded as a Type 42 font&quot;
+        append32(0); // &quot;Maximum memory usage when a TrueType font is downloaded as a Type 42 font&quot;
+        append32(0); // &quot;Minimum memory usage when a TrueType font is downloaded as a Type 1 font&quot;
+        append32(0); // &quot;Maximum memory usage when a TrueType font is downloaded as a Type 1 font&quot;
+    }
+
+    uint32_t calculateChecksum(size_t startingOffset, size_t endingOffset) const
+    {
+        assert(isFourByteAligned(endingOffset - startingOffset));
+        uint32_t sum = 0;
+        for (size_t offset = startingOffset; offset &lt; endingOffset; offset += 4) {
+            sum += static_cast&lt;unsigned char&gt;(result[offset + 3])
+                | (static_cast&lt;unsigned char&gt;(result[offset + 2]) &lt;&lt; 8)
+                | (static_cast&lt;unsigned char&gt;(result[offset + 1]) &lt;&lt; 16)
+                | (static_cast&lt;unsigned char&gt;(result[offset]) &lt;&lt; 24);
+        }
+        return sum;
+    }
+
+    typedef void (Generator::*FontAppendingFunction)();
+    void appendTable(const char identifier[4], FontAppendingFunction appendingFunction)
+    {
+        size_t offset = result.size();
+        assert(isFourByteAligned(offset));
+        (this-&gt;*appendingFunction)();
+        size_t unpaddedSize = result.size() - offset;
+        while (!isFourByteAligned(result.size()))
+            result.push_back(0);
+        assert(isFourByteAligned(result.size()));
+        size_t directoryEntryOffset = headerSize + m_tablesAppendedCount * directoryEntrySize;
+        result[directoryEntryOffset] = identifier[0];
+        result[directoryEntryOffset + 1] = identifier[1];
+        result[directoryEntryOffset + 2] = identifier[2];
+        result[directoryEntryOffset + 3] = identifier[3];
+        overwrite32(directoryEntryOffset + 4, calculateChecksum(offset, result.size()));
+        overwrite32(directoryEntryOffset + 8, static_cast&lt;uint32_t&gt;(offset));
+        overwrite32(directoryEntryOffset + 12, static_cast&lt;uint32_t&gt;(unpaddedSize));
+        ++m_tablesAppendedCount;
+    }
+
+    unsigned m_tablesAppendedCount { 0 };
+    std::vector&lt;uint8_t&gt; result;
+};
+
+std::vector&lt;uint8_t&gt; generateFont()
+{
+    return Generator().generate();
+}
</ins></span></pre></div>
<a id="branchessafari601branchToolsFontWithFeaturesFontWithFeaturesFontCreatorh"></a>
<div class="addfile"><h4>Added: branches/safari-601-branch/Tools/FontWithFeatures/FontWithFeatures/FontCreator.h (0 => 193518)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/Tools/FontWithFeatures/FontWithFeatures/FontCreator.h                                (rev 0)
+++ branches/safari-601-branch/Tools/FontWithFeatures/FontWithFeatures/FontCreator.h        2015-12-05 18:30:14 UTC (rev 193518)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+//
+//  FontCreator.hpp
+//  FontWithFeatures
+//
+//  Created by Litherum on 9/15/15.
+//  Copyright © 2015 Litherum. All rights reserved.
+//
+
+#ifndef FontCreator_h
+#define FontCreator_h
+
+#include &lt;vector&gt;
+
+std::vector&lt;uint8_t&gt; generateFont();
+
+#endif /* FontCreator_h */
</ins></span></pre></div>
<a id="branchessafari601branchToolsFontWithFeaturesFontWithFeaturesmaincpp"></a>
<div class="addfile"><h4>Added: branches/safari-601-branch/Tools/FontWithFeatures/FontWithFeatures/main.cpp (0 => 193518)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/Tools/FontWithFeatures/FontWithFeatures/main.cpp                                (rev 0)
+++ branches/safari-601-branch/Tools/FontWithFeatures/FontWithFeatures/main.cpp        2015-12-05 18:30:14 UTC (rev 193518)
</span><span class="lines">@@ -0,0 +1,114 @@
</span><ins>+//
+//  main.cpp
+//  FontWithFeatures
+//
+//  Created by Litherum on 9/15/15.
+//  Copyright © 2015 Litherum. All rights reserved.
+//
+
+#include &quot;FontCreator.h&quot;
+
+#include &lt;CoreFoundation/CoreFoundation.h&gt;
+#include &lt;CoreGraphics/CoreGraphics.h&gt;
+#include &lt;CoreServices/CoreServices.h&gt;
+#include &lt;CoreText/CoreText.h&gt;
+#include &lt;ImageIO/ImageIO.h&gt;
+#include &lt;fstream&gt;
+
+void drawTextWithFeature(CGContextRef context, CTFontDescriptorRef fontDescriptor, CFStringRef feature, int value, CGPoint location)
+{
+    CGFloat fontSize = 25;
+    CGContextSetTextMatrix(context, CGAffineTransformScale(CGAffineTransformIdentity, 1, 1));
+    CGContextSetTextPosition(context, location.x, location.y);
+
+    CFNumberRef featureValue = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &amp;value);
+    CFTypeRef featureDictionaryKeys[] = { kCTFontOpenTypeFeatureTag, kCTFontOpenTypeFeatureValue };
+    CFTypeRef featureDictionaryValues[] = { feature, featureValue };
+    CFDictionaryRef featureDictionary = CFDictionaryCreate(kCFAllocatorDefault, featureDictionaryKeys, featureDictionaryValues, 2, &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks);
+    CFRelease(featureValue);
+
+    CFTypeRef featureSettingsValues[] = { featureDictionary };
+    CFArrayRef fontFeatureSettings = CFArrayCreate(kCFAllocatorDefault, featureSettingsValues, 1, &amp;kCFTypeArrayCallBacks);
+    CFRelease(featureDictionary);
+
+    CFTypeRef fontDescriptorKeys[] = { kCTFontFeatureSettingsAttribute };
+    CFTypeRef fontDescriptorValues[] = { fontFeatureSettings };
+    CFDictionaryRef fontDescriptorAttributes = CFDictionaryCreate(kCFAllocatorDefault, fontDescriptorKeys, fontDescriptorValues, 1, &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks);
+    CFRelease(fontFeatureSettings);
+
+    CTFontDescriptorRef modifiedFontDescriptor = CTFontDescriptorCreateCopyWithAttributes(fontDescriptor, fontDescriptorAttributes);
+    CFRelease(fontDescriptorAttributes);
+
+    CTFontRef font = CTFontCreateWithFontDescriptor(modifiedFontDescriptor, fontSize, nullptr);
+    CFRelease(modifiedFontDescriptor);
+
+    CFMutableStringRef string = CFStringCreateMutable(kCFAllocatorDefault, 0);
+    CFStringAppend(string, feature);
+    CFStringAppend(string, value ? CFSTR(&quot;  (on)&quot;) : CFSTR(&quot; (off)&quot;));
+    CFStringAppend(string, CFSTR(&quot;: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&quot;));
+
+    CGColorRef red = CGColorCreateGenericRGB(1, 0, 0, 1);
+    CFTypeRef lineKeys[] = { kCTForegroundColorAttributeName };
+    CFTypeRef lineValues[] = { red };
+    CFDictionaryRef lineAttributes = CFDictionaryCreate(kCFAllocatorDefault, lineKeys, lineValues, 1, &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks);
+    CGColorRelease(red);
+
+    CFAttributedStringRef attributedString = CFAttributedStringCreate(kCFAllocatorDefault, string, lineAttributes);
+    CFRelease(lineAttributes);
+    CFRelease(string);
+
+    CFMutableAttributedStringRef mutableAttributedString = CFAttributedStringCreateMutableCopy(kCFAllocatorDefault, 0, attributedString);
+    CFRelease(attributedString);
+
+    CTFontRef monospaceFont = CTFontCreateWithName(CFSTR(&quot;Courier&quot;), fontSize, nullptr);
+    CFAttributedStringSetAttribute(mutableAttributedString, CFRangeMake(0, 12), kCTFontAttributeName, monospaceFont);
+    CFRelease(monospaceFont);
+
+    CFAttributedStringSetAttribute(mutableAttributedString, CFRangeMake(12, 52), kCTFontAttributeName, font);
+    CFRelease(font);
+
+    CTLineRef line = CTLineCreateWithAttributedString(mutableAttributedString);
+    CFRelease(mutableAttributedString);
+
+    CTLineDraw(line, context);
+    CFRelease(line);
+}
+
+int main(int argc, const char * argv[])
+{
+    size_t width = 2000;
+    size_t height = 2000;
+    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+    CGContextRef context = CGBitmapContextCreate(nullptr, width, height, 8, width * 4, colorSpace, kCGImageAlphaNoneSkipLast);
+    CGColorSpaceRelease(colorSpace);
+    const std::vector&lt;uint8_t&gt; fontVector = generateFont();
+    std::ofstream outputFile(&quot;/Volumes/Data/home/mmaxfield/tmp/output.otf&quot;, std::ios::out | std::ios::binary);
+    for (uint8_t b : fontVector)
+        outputFile &lt;&lt; b;
+    outputFile.close();
+    
+    CFDataRef fontData = CFDataCreate(kCFAllocatorDefault, fontVector.data(), fontVector.size());
+    CTFontDescriptorRef fontDescriptor = CTFontManagerCreateFontDescriptorFromData(fontData);
+    CFRelease(fontData);
+
+    CFTypeRef featureValues[] = { CFSTR(&quot;liga&quot;), CFSTR(&quot;clig&quot;), CFSTR(&quot;dlig&quot;), CFSTR(&quot;hlig&quot;), CFSTR(&quot;calt&quot;), CFSTR(&quot;subs&quot;), CFSTR(&quot;sups&quot;), CFSTR(&quot;smcp&quot;), CFSTR(&quot;c2sc&quot;), CFSTR(&quot;pcap&quot;), CFSTR(&quot;c2pc&quot;), CFSTR(&quot;unic&quot;), CFSTR(&quot;titl&quot;), CFSTR(&quot;onum&quot;), CFSTR(&quot;pnum&quot;), CFSTR(&quot;tnum&quot;), CFSTR(&quot;frac&quot;), CFSTR(&quot;afrc&quot;), CFSTR(&quot;ordn&quot;), CFSTR(&quot;zero&quot;), CFSTR(&quot;hist&quot;), CFSTR(&quot;jp78&quot;), CFSTR(&quot;jp83&quot;), CFSTR(&quot;jp90&quot;), CFSTR(&quot;jp04&quot;), CFSTR(&quot;smpl&quot;), CFSTR(&quot;trad&quot;), CFSTR(&quot;fwid&quot;), CFSTR(&quot;pwid&quot;), CFSTR(&quot;ruby&quot;) };
+    CFArrayRef features = CFArrayCreate(kCFAllocatorDefault, featureValues, 30, &amp;kCFTypeArrayCallBacks);
+
+    for (CFIndex i = 0; i &lt; CFArrayGetCount(features); ++i) {
+        drawTextWithFeature(context, fontDescriptor, static_cast&lt;CFStringRef&gt;(CFArrayGetValueAtIndex(features, i)), 1, CGPointMake(25, 1950 - 50 * i));
+        drawTextWithFeature(context, fontDescriptor, static_cast&lt;CFStringRef&gt;(CFArrayGetValueAtIndex(features, i)), 0, CGPointMake(25, 1925 - 50 * i));
+    }
+
+    CFRelease(features);
+    CFRelease(fontDescriptor);
+    CGImageRef image = CGBitmapContextCreateImage(context);
+    CGContextRelease(context);
+    CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(&quot;/Volumes/Data/home/mmaxfield/tmp/output.png&quot;), kCFURLPOSIXPathStyle, FALSE);
+    CGImageDestinationRef imageDestination = CGImageDestinationCreateWithURL(url, kUTTypePNG, 1, nullptr);
+    CFRelease(url);
+    CGImageDestinationAddImage(imageDestination, image, nullptr);
+    CGImageRelease(image);
+    CGImageDestinationFinalize(imageDestination);
+    CFRelease(imageDestination);
+    return 0;
+}
</ins></span></pre></div>
<a id="branchessafari601branchToolsFontWithFeaturesFontWithFeaturesxcodeprojprojectpbxproj"></a>
<div class="addfile"><h4>Added: branches/safari-601-branch/Tools/FontWithFeatures/FontWithFeatures.xcodeproj/project.pbxproj (0 => 193518)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/Tools/FontWithFeatures/FontWithFeatures.xcodeproj/project.pbxproj                                (rev 0)
+++ branches/safari-601-branch/Tools/FontWithFeatures/FontWithFeatures.xcodeproj/project.pbxproj        2015-12-05 18:30:14 UTC (rev 193518)
</span><span class="lines">@@ -0,0 +1,268 @@
</span><ins>+// !$*UTF8*$!
+{
+        archiveVersion = 1;
+        classes = {
+        };
+        objectVersion = 46;
+        objects = {
+
+/* Begin PBXBuildFile section */
+                C28626A61BA902B9001961D6 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C28626A51BA902B9001961D6 /* main.cpp */; };
+                C28626AD1BA904F1001961D6 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C28626AC1BA904F1001961D6 /* CoreGraphics.framework */; };
+                C28626AF1BA9062C001961D6 /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C28626AE1BA9062C001961D6 /* ImageIO.framework */; };
+                C28626B11BA906C1001961D6 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C28626B01BA906C1001961D6 /* CoreFoundation.framework */; };
+                C28626B31BA906D1001961D6 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C28626B21BA906D1001961D6 /* CoreServices.framework */; };
+                C28626B51BA907AE001961D6 /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C28626B41BA907AE001961D6 /* CoreText.framework */; };
+                C28626B81BA91762001961D6 /* FontCreator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C28626B61BA91762001961D6 /* FontCreator.cpp */; settings = {ASSET_TAGS = (); }; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+                C28626A01BA902B9001961D6 /* CopyFiles */ = {
+                        isa = PBXCopyFilesBuildPhase;
+                        buildActionMask = 2147483647;
+                        dstPath = /usr/share/man/man1/;
+                        dstSubfolderSpec = 0;
+                        files = (
+                        );
+                        runOnlyForDeploymentPostprocessing = 1;
+                };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+                C28626A21BA902B9001961D6 /* FontWithFeatures */ = {isa = PBXFileReference; explicitFileType = &quot;compiled.mach-o.executable&quot;; includeInIndex = 0; path = FontWithFeatures; sourceTree = BUILT_PRODUCTS_DIR; };
+                C28626A51BA902B9001961D6 /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                C28626AC1BA904F1001961D6 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+                C28626AE1BA9062C001961D6 /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = System/Library/Frameworks/ImageIO.framework; sourceTree = SDKROOT; };
+                C28626B01BA906C1001961D6 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
+                C28626B21BA906D1001961D6 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
+                C28626B41BA907AE001961D6 /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };
+                C28626B61BA91762001961D6 /* FontCreator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontCreator.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                C28626B71BA91762001961D6 /* FontCreator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontCreator.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+                C286269F1BA902B9001961D6 /* Frameworks */ = {
+                        isa = PBXFrameworksBuildPhase;
+                        buildActionMask = 2147483647;
+                        files = (
+                                C28626B51BA907AE001961D6 /* CoreText.framework in Frameworks */,
+                                C28626B31BA906D1001961D6 /* CoreServices.framework in Frameworks */,
+                                C28626B11BA906C1001961D6 /* CoreFoundation.framework in Frameworks */,
+                                C28626AF1BA9062C001961D6 /* ImageIO.framework in Frameworks */,
+                                C28626AD1BA904F1001961D6 /* CoreGraphics.framework in Frameworks */,
+                        );
+                        runOnlyForDeploymentPostprocessing = 0;
+                };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+                C28626991BA902B9001961D6 = {
+                        isa = PBXGroup;
+                        children = (
+                                C28626B41BA907AE001961D6 /* CoreText.framework */,
+                                C28626B21BA906D1001961D6 /* CoreServices.framework */,
+                                C28626B01BA906C1001961D6 /* CoreFoundation.framework */,
+                                C28626AE1BA9062C001961D6 /* ImageIO.framework */,
+                                C28626AC1BA904F1001961D6 /* CoreGraphics.framework */,
+                                C28626A41BA902B9001961D6 /* FontWithFeatures */,
+                                C28626A31BA902B9001961D6 /* Products */,
+                        );
+                        sourceTree = &quot;&lt;group&gt;&quot;;
+                };
+                C28626A31BA902B9001961D6 /* Products */ = {
+                        isa = PBXGroup;
+                        children = (
+                                C28626A21BA902B9001961D6 /* FontWithFeatures */,
+                        );
+                        name = Products;
+                        sourceTree = &quot;&lt;group&gt;&quot;;
+                };
+                C28626A41BA902B9001961D6 /* FontWithFeatures */ = {
+                        isa = PBXGroup;
+                        children = (
+                                C28626A51BA902B9001961D6 /* main.cpp */,
+                                C28626B61BA91762001961D6 /* FontCreator.cpp */,
+                                C28626B71BA91762001961D6 /* FontCreator.h */,
+                        );
+                        path = FontWithFeatures;
+                        sourceTree = &quot;&lt;group&gt;&quot;;
+                };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+                C28626A11BA902B9001961D6 /* FontWithFeatures */ = {
+                        isa = PBXNativeTarget;
+                        buildConfigurationList = C28626A91BA902B9001961D6 /* Build configuration list for PBXNativeTarget &quot;FontWithFeatures&quot; */;
+                        buildPhases = (
+                                C286269E1BA902B9001961D6 /* Sources */,
+                                C286269F1BA902B9001961D6 /* Frameworks */,
+                                C28626A01BA902B9001961D6 /* CopyFiles */,
+                        );
+                        buildRules = (
+                        );
+                        dependencies = (
+                        );
+                        name = FontWithFeatures;
+                        productName = FontWithFeatures;
+                        productReference = C28626A21BA902B9001961D6 /* FontWithFeatures */;
+                        productType = &quot;com.apple.product-type.tool&quot;;
+                };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+                C286269A1BA902B9001961D6 /* Project object */ = {
+                        isa = PBXProject;
+                        attributes = {
+                                LastUpgradeCheck = 0700;
+                                ORGANIZATIONNAME = Litherum;
+                                TargetAttributes = {
+                                        C28626A11BA902B9001961D6 = {
+                                                CreatedOnToolsVersion = 7.0;
+                                        };
+                                };
+                        };
+                        buildConfigurationList = C286269D1BA902B9001961D6 /* Build configuration list for PBXProject &quot;FontWithFeatures&quot; */;
+                        compatibilityVersion = &quot;Xcode 3.2&quot;;
+                        developmentRegion = English;
+                        hasScannedForEncodings = 0;
+                        knownRegions = (
+                                en,
+                        );
+                        mainGroup = C28626991BA902B9001961D6;
+                        productRefGroup = C28626A31BA902B9001961D6 /* Products */;
+                        projectDirPath = &quot;&quot;;
+                        projectRoot = &quot;&quot;;
+                        targets = (
+                                C28626A11BA902B9001961D6 /* FontWithFeatures */,
+                        );
+                };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+                C286269E1BA902B9001961D6 /* Sources */ = {
+                        isa = PBXSourcesBuildPhase;
+                        buildActionMask = 2147483647;
+                        files = (
+                                C28626A61BA902B9001961D6 /* main.cpp in Sources */,
+                                C28626B81BA91762001961D6 /* FontCreator.cpp in Sources */,
+                        );
+                        runOnlyForDeploymentPostprocessing = 0;
+                };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+                C28626A71BA902B9001961D6 /* Debug */ = {
+                        isa = XCBuildConfiguration;
+                        buildSettings = {
+                                ALWAYS_SEARCH_USER_PATHS = NO;
+                                CLANG_CXX_LANGUAGE_STANDARD = &quot;gnu++0x&quot;;
+                                CLANG_CXX_LIBRARY = &quot;libc++&quot;;
+                                CLANG_ENABLE_MODULES = YES;
+                                CLANG_ENABLE_OBJC_ARC = YES;
+                                CLANG_WARN_BOOL_CONVERSION = YES;
+                                CLANG_WARN_CONSTANT_CONVERSION = YES;
+                                CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+                                CLANG_WARN_EMPTY_BODY = YES;
+                                CLANG_WARN_ENUM_CONVERSION = YES;
+                                CLANG_WARN_INT_CONVERSION = YES;
+                                CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                                CLANG_WARN_UNREACHABLE_CODE = YES;
+                                CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                                COPY_PHASE_STRIP = NO;
+                                DEBUG_INFORMATION_FORMAT = dwarf;
+                                ENABLE_STRICT_OBJC_MSGSEND = YES;
+                                ENABLE_TESTABILITY = YES;
+                                GCC_C_LANGUAGE_STANDARD = gnu99;
+                                GCC_DYNAMIC_NO_PIC = NO;
+                                GCC_NO_COMMON_BLOCKS = YES;
+                                GCC_OPTIMIZATION_LEVEL = 0;
+                                GCC_PREPROCESSOR_DEFINITIONS = (
+                                        &quot;DEBUG=1&quot;,
+                                        &quot;$(inherited)&quot;,
+                                );
+                                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                                GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+                                GCC_WARN_UNDECLARED_SELECTOR = YES;
+                                GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+                                GCC_WARN_UNUSED_FUNCTION = YES;
+                                GCC_WARN_UNUSED_VARIABLE = YES;
+                                MACOSX_DEPLOYMENT_TARGET = 10.11;
+                                MTL_ENABLE_DEBUG_INFO = YES;
+                                ONLY_ACTIVE_ARCH = YES;
+                                SDKROOT = macosx;
+                        };
+                        name = Debug;
+                };
+                C28626A81BA902B9001961D6 /* Release */ = {
+                        isa = XCBuildConfiguration;
+                        buildSettings = {
+                                ALWAYS_SEARCH_USER_PATHS = NO;
+                                CLANG_CXX_LANGUAGE_STANDARD = &quot;gnu++0x&quot;;
+                                CLANG_CXX_LIBRARY = &quot;libc++&quot;;
+                                CLANG_ENABLE_MODULES = YES;
+                                CLANG_ENABLE_OBJC_ARC = YES;
+                                CLANG_WARN_BOOL_CONVERSION = YES;
+                                CLANG_WARN_CONSTANT_CONVERSION = YES;
+                                CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+                                CLANG_WARN_EMPTY_BODY = YES;
+                                CLANG_WARN_ENUM_CONVERSION = YES;
+                                CLANG_WARN_INT_CONVERSION = YES;
+                                CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                                CLANG_WARN_UNREACHABLE_CODE = YES;
+                                CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                                COPY_PHASE_STRIP = NO;
+                                DEBUG_INFORMATION_FORMAT = &quot;dwarf-with-dsym&quot;;
+                                ENABLE_NS_ASSERTIONS = NO;
+                                ENABLE_STRICT_OBJC_MSGSEND = YES;
+                                GCC_C_LANGUAGE_STANDARD = gnu99;
+                                GCC_NO_COMMON_BLOCKS = YES;
+                                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                                GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+                                GCC_WARN_UNDECLARED_SELECTOR = YES;
+                                GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+                                GCC_WARN_UNUSED_FUNCTION = YES;
+                                GCC_WARN_UNUSED_VARIABLE = YES;
+                                MACOSX_DEPLOYMENT_TARGET = 10.11;
+                                MTL_ENABLE_DEBUG_INFO = NO;
+                                SDKROOT = macosx;
+                        };
+                        name = Release;
+                };
+                C28626AA1BA902B9001961D6 /* Debug */ = {
+                        isa = XCBuildConfiguration;
+                        buildSettings = {
+                                PRODUCT_NAME = &quot;$(TARGET_NAME)&quot;;
+                        };
+                        name = Debug;
+                };
+                C28626AB1BA902B9001961D6 /* Release */ = {
+                        isa = XCBuildConfiguration;
+                        buildSettings = {
+                                PRODUCT_NAME = &quot;$(TARGET_NAME)&quot;;
+                        };
+                        name = Release;
+                };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+                C286269D1BA902B9001961D6 /* Build configuration list for PBXProject &quot;FontWithFeatures&quot; */ = {
+                        isa = XCConfigurationList;
+                        buildConfigurations = (
+                                C28626A71BA902B9001961D6 /* Debug */,
+                                C28626A81BA902B9001961D6 /* Release */,
+                        );
+                        defaultConfigurationIsVisible = 0;
+                        defaultConfigurationName = Release;
+                };
+                C28626A91BA902B9001961D6 /* Build configuration list for PBXNativeTarget &quot;FontWithFeatures&quot; */ = {
+                        isa = XCConfigurationList;
+                        buildConfigurations = (
+                                C28626AA1BA902B9001961D6 /* Debug */,
+                                C28626AB1BA902B9001961D6 /* Release */,
+                        );
+                        defaultConfigurationIsVisible = 0;
+                };
+/* End XCConfigurationList section */
+        };
+        rootObject = C286269A1BA902B9001961D6 /* Project object */;
+}
</ins></span></pre>
</div>
</div>

</body>
</html>