<!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>[194287] 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/194287">194287</a></dd>
<dt>Author</dt> <dd>matthew_hanson@apple.com</dd>
<dt>Date</dt> <dd>2015-12-18 13:11:15 -0800 (Fri, 18 Dec 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/193894">r193894</a>. rdar://problem/23769758</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari601branchLayoutTestsplatformmacTestExpectations">branches/safari-601-branch/LayoutTests/platform/mac/TestExpectations</a></li>
<li><a href="#branchessafari601branchLayoutTestsplatformmacfastwritingmodebrokenideographsmallcapsexpectedtxt">branches/safari-601-branch/LayoutTests/platform/mac/fast/writing-mode/broken-ideograph-small-caps-expected.txt</a></li>
<li><a href="#branchessafari601branchSourceWebCoreChangeLog">branches/safari-601-branch/Source/WebCore/ChangeLog</a></li>
<li><a href="#branchessafari601branchSourceWebCoreplatformgraphicsFontcpp">branches/safari-601-branch/Source/WebCore/platform/graphics/Font.cpp</a></li>
<li><a href="#branchessafari601branchSourceWebCoreplatformgraphicsFonth">branches/safari-601-branch/Source/WebCore/platform/graphics/Font.h</a></li>
<li><a href="#branchessafari601branchSourceWebCoreplatformgraphicsFontCascadeh">branches/safari-601-branch/Source/WebCore/platform/graphics/FontCascade.h</a></li>
<li><a href="#branchessafari601branchSourceWebCoreplatformgraphicsFontCascadeFontscpp">branches/safari-601-branch/Source/WebCore/platform/graphics/FontCascadeFonts.cpp</a></li>
<li><a href="#branchessafari601branchSourceWebCoreplatformgraphicsFontDescriptionh">branches/safari-601-branch/Source/WebCore/platform/graphics/FontDescription.h</a></li>
<li><a href="#branchessafari601branchSourceWebCoreplatformgraphicscocoaFontCascadeCocoamm">branches/safari-601-branch/Source/WebCore/platform/graphics/cocoa/FontCascadeCocoa.mm</a></li>
<li><a href="#branchessafari601branchSourceWebCoreplatformgraphicscocoaFontCocoamm">branches/safari-601-branch/Source/WebCore/platform/graphics/cocoa/FontCocoa.mm</a></li>
<li><a href="#branchessafari601branchSourceWebCoreplatformgraphicsiosFontCacheIOSmm">branches/safari-601-branch/Source/WebCore/platform/graphics/ios/FontCacheIOS.mm</a></li>
<li><a href="#branchessafari601branchSourceWebCoreplatformgraphicsmacComplexTextControllercpp">branches/safari-601-branch/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp</a></li>
<li><a href="#branchessafari601branchSourceWebCoreplatformspicocoaCoreTextSPIh">branches/safari-601-branch/Source/WebCore/platform/spi/cocoa/CoreTextSPI.h</a></li>
<li><a href="#branchessafari601branchSourceWebCorerenderingRenderThemeIOSmm">branches/safari-601-branch/Source/WebCore/rendering/RenderThemeIOS.mm</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#branchessafari601branchLayoutTestscss3fontvariantpetitecapssynthesiscoverageexpectedhtml">branches/safari-601-branch/LayoutTests/css3/font-variant-petite-caps-synthesis-coverage-expected.html</a></li>
<li><a href="#branchessafari601branchLayoutTestscss3fontvariantpetitecapssynthesiscoveragehtml">branches/safari-601-branch/LayoutTests/css3/font-variant-petite-caps-synthesis-coverage.html</a></li>
<li><a href="#branchessafari601branchLayoutTestscss3fontvariantpetitecapssynthesisexpectedhtml">branches/safari-601-branch/LayoutTests/css3/font-variant-petite-caps-synthesis-expected.html</a></li>
<li><a href="#branchessafari601branchLayoutTestscss3fontvariantpetitecapssynthesishtml">branches/safari-601-branch/LayoutTests/css3/font-variant-petite-caps-synthesis.html</a></li>
<li><a href="#branchessafari601branchLayoutTestscss3fontvariantsmallcapssynthesiscoverageexpectedhtml">branches/safari-601-branch/LayoutTests/css3/font-variant-small-caps-synthesis-coverage-expected.html</a></li>
<li><a href="#branchessafari601branchLayoutTestscss3fontvariantsmallcapssynthesiscoveragehtml">branches/safari-601-branch/LayoutTests/css3/font-variant-small-caps-synthesis-coverage.html</a></li>
<li><a href="#branchessafari601branchLayoutTestscss3fontvariantsmallcapssynthesisexpectedhtml">branches/safari-601-branch/LayoutTests/css3/font-variant-small-caps-synthesis-expected.html</a></li>
<li><a href="#branchessafari601branchLayoutTestscss3fontvariantsmallcapssynthesishtml">branches/safari-601-branch/LayoutTests/css3/font-variant-small-caps-synthesis.html</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari601branchLayoutTestscss3fontvariantpetitecapssynthesiscoverageexpectedhtml"></a>
<div class="addfile"><h4>Added: branches/safari-601-branch/LayoutTests/css3/font-variant-petite-caps-synthesis-coverage-expected.html (0 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/LayoutTests/css3/font-variant-petite-caps-synthesis-coverage-expected.html         (rev 0)
+++ branches/safari-601-branch/LayoutTests/css3/font-variant-petite-caps-synthesis-coverage-expected.html        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<style>
+@font-face {
+ font-family: "testfont";
+ src: url("resources/FontWithFeatures.otf") format("opentype");
+}
+.test {
+ font-size: 20px;
+ display: inline-block;
+}
+</style>
+</head>
+<body>
+This test makes sure that font-variant synthesis is correctly applied. The test passes when a particular pattern of Xs and checks appear below. Also note that the correct size of the character is required.
+<div style="border: solid black 1px;">
+<div class="test">ASDF</div>
+<div class="test"><span style="font-size: 14px;">ASDF</span></div>
+<div class="test"><span style="font-size: 14px;">AS</span>DF</div>
+<div class="test">AS<span style="font-size: 14px;">DF</span></div>
+<div class="test"><span style="font-size: 14px;">ASDF</span></div>
+<div class="test"><span style="font-size: 14px;">ASDF</span></div>
+<div class="test"><span style="font-size: 14px;">ASDF</span></div>
+<div class="test"><span style="font-size: 14px;">ASDF</span></div>
+</div>
+<div style="font-family: testfont; border: solid black 1px; margin: 5px;">
+<div class="test">AB</div>
+<div class="test">B</div>
+<div class="test">B</div>
+<div class="test">B</div>
+<div class="test"><span style="font-size: 14px;">A</span></div>
+<div class="test">A</div>
+<div class="test"><span style="font-size: 14px;">A</span>B</div>
+<div class="test">B<span style="font-size: 14px;">A</span></div>
+<div class="test">AA</div>
+<div class="test">AA</div>
+<div class="test">B</div>
+<div class="test"><span style="font-size: 14px;">A</span>K</div>
+<div class="test">K<span style="font-size: 14px;">A</span></div>
+<div class="test">AB</div>
+<div class="test">BA</div>
+</div>
+<div style="font-family: testfont; border: solid blue 1px; margin: 5px;">
+<div class="test"><span style="font-size: 14px;">A</span></div>
+<div class="test">A</div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+<div class="test">A</div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+</div>
+</div>
+</body>
+</html>
</ins></span></pre></div>
<a id="branchessafari601branchLayoutTestscss3fontvariantpetitecapssynthesiscoveragehtml"></a>
<div class="addfile"><h4>Added: branches/safari-601-branch/LayoutTests/css3/font-variant-petite-caps-synthesis-coverage.html (0 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/LayoutTests/css3/font-variant-petite-caps-synthesis-coverage.html         (rev 0)
+++ branches/safari-601-branch/LayoutTests/css3/font-variant-petite-caps-synthesis-coverage.html        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -0,0 +1,60 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<style>
+@font-face {
+ /* Opentype. "L" responds to pcap; "M" responds to c2pc */
+ font-family: "testfontotf";
+ src: url("resources/FontWithFeatures.otf") format("opentype");
+}
+.test {
+ font-size: 20px;
+ display: inline-block;
+}
+</style>
+</head>
+<body>
+This test makes sure that font-variant synthesis is correctly applied. The test passes when a particular pattern of Xs and checks appear below. Also note that the correct size of the character is required.
+<div style="border: solid black 1px;">
+<div class="test" style="font-variant-caps: petite-caps;">ASDF</div>
+<div class="test" style="font-variant-caps: petite-caps;">asdf</div>
+<div class="test" style="font-variant-caps: petite-caps;">asDF</div>
+<div class="test" style="font-variant-caps: petite-caps;">ASdf</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">ASDF</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">asdf</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">asDF</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">ASdf</div>
+</div>
+<div style="font-family: testfontotf; border: solid black 1px; margin: 5px; font-feature-settings: 'ntrl';">
+<div class="test">AB</div>
+<div class="test">a</div>
+<div class="test">L</div>
+<div class="test">M</div>
+<div class="test" style="font-variant-caps: petite-caps;">a</div>
+<div class="test" style="font-variant-caps: petite-caps;">L</div>
+<div class="test" style="font-variant-caps: petite-caps;">aL</div>
+<div class="test" style="font-variant-caps: petite-caps;">La</div>
+<div class="test" style="font-variant-caps: petite-caps;">AL</div>
+<div class="test" style="font-variant-caps: petite-caps;">LA</div>
+<div class="test" style="font-variant-caps: petite-caps;">M</div>
+<div class="test" style="font-variant-caps: petite-caps;">aM</div>
+<div class="test" style="font-variant-caps: petite-caps;">Ma</div>
+<div class="test" style="font-variant-caps: petite-caps;">AM</div>
+<div class="test" style="font-variant-caps: petite-caps;">MA</div>
+</div>
+<div style="font-family: testfontotf; border: solid blue 1px; margin: 5px; font-feature-settings: 'ntrl';">
+<div class="test" style="font-variant-caps: all-petite-caps;">a</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">L</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">aL</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">La</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">AL</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">LA</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">M</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">aM</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">Ma</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">AM</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">MA</div>
+</div>
+</div>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="branchessafari601branchLayoutTestscss3fontvariantpetitecapssynthesisexpectedhtml"></a>
<div class="addfile"><h4>Added: branches/safari-601-branch/LayoutTests/css3/font-variant-petite-caps-synthesis-expected.html (0 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/LayoutTests/css3/font-variant-petite-caps-synthesis-expected.html         (rev 0)
+++ branches/safari-601-branch/LayoutTests/css3/font-variant-petite-caps-synthesis-expected.html        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<style>
+@font-face {
+ font-family: "testfont";
+ src: url("resources/FontWithFeatures.otf") format("opentype");
+}
+.test {
+ font-size: 20px;
+ display: inline-block;
+}
+</style>
+</head>
+<body>
+This test makes sure that font-variant synthesis is correctly applied. The test passes when a particular pattern of Xs and checks appear below. Also note that the correct size of the character is required.
+<div style="border: solid black 1px;">
+<div class="test">ASDF</div>
+<div class="test"><span style="font-size: 14px;">ASDF</span></div>
+<div class="test"><span style="font-size: 14px;">AS</span>DF</div>
+<div class="test">AS<span style="font-size: 14px;">DF</span></div>
+<div class="test"><span style="font-size: 14px;">ASDF</span></div>
+<div class="test"><span style="font-size: 14px;">ASDF</span></div>
+<div class="test"><span style="font-size: 14px;">ASDF</span></div>
+<div class="test"><span style="font-size: 14px;">ASDF</span></div>
+</div>
+<div style="font-family: testfont; border: solid black 1px; margin: 5px;">
+<div class="test">AB</div>
+<div class="test">B</div>
+<div class="test">B</div>
+<div class="test">B</div>
+<div class="test"><span style="font-size: 14px;">A</span></div>
+<div class="test">A</div>
+<div class="test"><span style="font-size: 14px;">A</span>B</div>
+<div class="test">B<span style="font-size: 14px;">A</span></div>
+<div class="test">AA</div>
+<div class="test">AA</div>
+<div class="test">B</div>
+<div class="test"><span style="font-size: 14px;">A</span>K</div>
+<div class="test">K<span style="font-size: 14px;">A</span></div>
+<div class="test">AB</div>
+<div class="test">BA</div>
+</div>
+<div style="font-family: testfont; border: solid blue 1px; margin: 5px;">
+<div class="test"><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+</div>
+</div>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="branchessafari601branchLayoutTestscss3fontvariantpetitecapssynthesishtml"></a>
<div class="addfile"><h4>Added: branches/safari-601-branch/LayoutTests/css3/font-variant-petite-caps-synthesis.html (0 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/LayoutTests/css3/font-variant-petite-caps-synthesis.html         (rev 0)
+++ branches/safari-601-branch/LayoutTests/css3/font-variant-petite-caps-synthesis.html        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -0,0 +1,60 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<style>
+@font-face {
+ /* Opentype. "L" responds to pcap; "M" responds to c2pc */
+ font-family: "testfontotf";
+ src: url("resources/FontWithFeatures.otf") format("opentype");
+}
+.test {
+ font-size: 20px;
+ display: inline-block;
+}
+</style>
+</head>
+<body>
+This test makes sure that font-variant synthesis is correctly applied. The test passes when a particular pattern of Xs and checks appear below. Also note that the correct size of the character is required.
+<div style="border: solid black 1px;">
+<div class="test" style="font-variant-caps: petite-caps;">ASDF</div>
+<div class="test" style="font-variant-caps: petite-caps;">asdf</div>
+<div class="test" style="font-variant-caps: petite-caps;">asDF</div>
+<div class="test" style="font-variant-caps: petite-caps;">ASdf</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">ASDF</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">asdf</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">asDF</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">ASdf</div>
+</div>
+<div style="font-family: testfontotf; border: solid black 1px; margin: 5px; font-feature-settings: 'ntrl';">
+<div class="test">AB</div>
+<div class="test">a</div>
+<div class="test">L</div>
+<div class="test">M</div>
+<div class="test" style="font-variant-caps: petite-caps;">a</div>
+<div class="test" style="font-variant-caps: petite-caps;">L</div>
+<div class="test" style="font-variant-caps: petite-caps;">aL</div>
+<div class="test" style="font-variant-caps: petite-caps;">La</div>
+<div class="test" style="font-variant-caps: petite-caps;">AL</div>
+<div class="test" style="font-variant-caps: petite-caps;">LA</div>
+<div class="test" style="font-variant-caps: petite-caps;">M</div>
+<div class="test" style="font-variant-caps: petite-caps;">aM</div>
+<div class="test" style="font-variant-caps: petite-caps;">Ma</div>
+<div class="test" style="font-variant-caps: petite-caps;">AM</div>
+<div class="test" style="font-variant-caps: petite-caps;">MA</div>
+</div>
+<div style="font-family: testfontotf; border: solid blue 1px; margin: 5px; font-feature-settings: 'ntrl';">
+<div class="test" style="font-variant-caps: all-petite-caps;">a</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">L</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">aL</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">La</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">AL</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">LA</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">M</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">aM</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">Ma</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">AM</div>
+<div class="test" style="font-variant-caps: all-petite-caps;">MA</div>
+</div>
+</div>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="branchessafari601branchLayoutTestscss3fontvariantsmallcapssynthesiscoverageexpectedhtml"></a>
<div class="addfile"><h4>Added: branches/safari-601-branch/LayoutTests/css3/font-variant-small-caps-synthesis-coverage-expected.html (0 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/LayoutTests/css3/font-variant-small-caps-synthesis-coverage-expected.html         (rev 0)
+++ branches/safari-601-branch/LayoutTests/css3/font-variant-small-caps-synthesis-coverage-expected.html        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -0,0 +1,91 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<style>
+@font-face {
+ font-family: "testfont";
+ src: url("resources/FontWithFeatures.otf") format("opentype");
+}
+.test {
+ font-size: 20px;
+ display: inline-block;
+}
+</style>
+</head>
+<body>
+This test makes sure that font-variant synthesis is correctly applied. The test passes when a particular pattern of Xs and checks appear below. Also note that the correct size of the character is required.
+<div style="border: solid black 1px;">
+<div class="test">ASDF</div>
+<div class="test"><span style="font-size: 14px;">ASDF</span></div>
+<div class="test"><span style="font-size: 14px;">AS</span>DF</div>
+<div class="test">AS<span style="font-size: 14px;">DF</span></div>
+<div class="test"><span style="font-size: 14px;">ASDF</span></div>
+<div class="test"><span style="font-size: 14px;">ASDF</span></div>
+<div class="test"><span style="font-size: 14px;">ASDF</span></div>
+<div class="test"><span style="font-size: 14px;">ASDF</span></div>
+</div>
+<div style="font-family: testfont; border: solid black 1px; margin: 5px;">
+<div class="test">AB</div>
+<div class="test">B</div>
+<div class="test">B</div>
+<div class="test">B</div>
+<div class="test"><span style="font-size: 14px;">A</span></div>
+<div class="test">A</div>
+<div class="test"><span style="font-size: 14px;">A</span>B</div>
+<div class="test">B<span style="font-size: 14px;">A</span></div>
+<div class="test">AA</div>
+<div class="test">AA</div>
+<div class="test">B</div>
+<div class="test"><span style="font-size: 14px;">A</span>K</div>
+<div class="test">K<span style="font-size: 14px;">A</span></div>
+<div class="test">AB</div>
+<div class="test">BA</div>
+</div>
+<div style="font-family: testfont; border: solid red 1px; margin: 5px;">
+<div class="test"style="">AB</div>
+<div class="test">B</div>
+<div class="test">B</div>
+<div class="test">B</div>
+<div class="test">B</div>
+<div class="test">A</div>
+<div class="test"><span style="font-size: 14px;">A</span></div>
+<div class="test">A</div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+<div class="test">AA</div>
+<div class="test">AA</div>
+<div class="test"><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">A</span></div>
+<div class="test">A<span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span>A</div>
+</div>
+<div style="font-family: testfont; border: solid blue 1px; margin: 5px;">
+<div class="test"><span style="font-size: 14px;">A</span></div>
+<div class="test">A</div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+<div class="test">A</div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+</div>
+<div style="font-family: testfont; border: solid green 1px; margin: 5px;">
+<div class="test"><span style="font-size: 14px;">A</span></div>
+<div class="test">A</div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+<div class="test">A</div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">A</span></div>
+</div>
+</div>
+</body>
+</html>
</ins></span></pre></div>
<a id="branchessafari601branchLayoutTestscss3fontvariantsmallcapssynthesiscoveragehtml"></a>
<div class="addfile"><h4>Added: branches/safari-601-branch/LayoutTests/css3/font-variant-small-caps-synthesis-coverage.html (0 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/LayoutTests/css3/font-variant-small-caps-synthesis-coverage.html         (rev 0)
+++ branches/safari-601-branch/LayoutTests/css3/font-variant-small-caps-synthesis-coverage.html        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -0,0 +1,98 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<style>
+/* Only test OpenType fonts for now, because our TrueType font is busted when disabling features. */
+@font-face {
+ /* Opentype. "J" responds to smcp; "K" responds to c2sc */
+ font-family: "testfontotf";
+ src: url("resources/FontWithFeatures.otf") format("opentype");
+}
+@font-face {
+ /* Opentype. "f" responds to smcp; "g" responds to c2sc */
+ font-family: "testfontlowercasesmallcapsotf";
+ src: url("resources/FontWithFeaturesLowercaseSmallCaps.otf") format("opentype");
+}
+.test {
+ font-size: 20px;
+ display: inline-block;
+}
+</style>
+</head>
+<body>
+This test makes sure that font-variant synthesis is correctly applied. The test passes when a particular pattern of Xs and checks appear below. Also note that the correct size of the character is required.
+<div style="border: solid black 1px;">
+<div class="test" style="font-variant-caps: small-caps;">ASDF</div>
+<div class="test" style="font-variant-caps: small-caps;">asdf</div>
+<div class="test" style="font-variant-caps: small-caps;">asDF</div>
+<div class="test" style="font-variant-caps: small-caps;">ASdf</div>
+<div class="test" style="font-variant-caps: all-small-caps;">ASDF</div>
+<div class="test" style="font-variant-caps: all-small-caps;">asdf</div>
+<div class="test" style="font-variant-caps: all-small-caps;">asDF</div>
+<div class="test" style="font-variant-caps: all-small-caps;">ASdf</div>
+</div>
+<div style="font-family: testfontotf; border: solid black 1px; margin: 5px; font-feature-settings: 'ntrl';">
+<div class="test">AB</div>
+<div class="test">a</div>
+<div class="test">J</div>
+<div class="test">K</div>
+<div class="test" style="font-variant-caps: small-caps;">a</div>
+<div class="test" style="font-variant-caps: small-caps;">J</div>
+<div class="test" style="font-variant-caps: small-caps;">aJ</div>
+<div class="test" style="font-variant-caps: small-caps;">Ja</div>
+<div class="test" style="font-variant-caps: small-caps;">AJ</div>
+<div class="test" style="font-variant-caps: small-caps;">JA</div>
+<div class="test" style="font-variant-caps: small-caps;">K</div>
+<div class="test" style="font-variant-caps: small-caps;">aK</div>
+<div class="test" style="font-variant-caps: small-caps;">Ka</div>
+<div class="test" style="font-variant-caps: small-caps;">AK</div>
+<div class="test" style="font-variant-caps: small-caps;">KA</div>
+</div>
+<div style="font-family: testfontlowercasesmallcapsotf; border: solid red 1px; margin: 5px; font-feature-settings: 'ntrl';">
+<div class="test">AB</div>
+<div class="test">a</div>
+<div class="test">f</div>
+<div class="test">g</div>
+<div class="test">F</div>
+<div class="test">G</div>
+<div class="test" style="font-variant-caps: small-caps;">a</div>
+<div class="test" style="font-variant-caps: small-caps;">f</div>
+<div class="test" style="font-variant-caps: small-caps;">af</div>
+<div class="test" style="font-variant-caps: small-caps;">fa</div>
+<div class="test" style="font-variant-caps: small-caps;">Af</div>
+<div class="test" style="font-variant-caps: small-caps;">fA</div>
+<div class="test" style="font-variant-caps: small-caps;">g</div>
+<div class="test" style="font-variant-caps: small-caps;">ag</div>
+<div class="test" style="font-variant-caps: small-caps;">ga</div>
+<div class="test" style="font-variant-caps: small-caps;">Ag</div>
+<div class="test" style="font-variant-caps: small-caps;">gA</div>
+</div>
+<div style="font-family: testfontotf; border: solid blue 1px; margin: 5px; font-feature-settings: 'ntrl';">
+<div class="test" style="font-variant-caps: all-small-caps;">a</div>
+<div class="test" style="font-variant-caps: all-small-caps;">J</div>
+<div class="test" style="font-variant-caps: all-small-caps;">aJ</div>
+<div class="test" style="font-variant-caps: all-small-caps;">Ja</div>
+<div class="test" style="font-variant-caps: all-small-caps;">AJ</div>
+<div class="test" style="font-variant-caps: all-small-caps;">JA</div>
+<div class="test" style="font-variant-caps: all-small-caps;">K</div>
+<div class="test" style="font-variant-caps: all-small-caps;">aK</div>
+<div class="test" style="font-variant-caps: all-small-caps;">Ka</div>
+<div class="test" style="font-variant-caps: all-small-caps;">AK</div>
+<div class="test" style="font-variant-caps: all-small-caps;">KA</div>
+</div>
+<div style="font-family: testfontlowercasesmallcapsotf; border: solid green 1px; margin: 5px; font-feature-settings: 'ntrl';">
+<div class="test" style="font-variant-caps: all-small-caps;">a</div>
+<div class="test" style="font-variant-caps: all-small-caps;">f</div>
+<div class="test" style="font-variant-caps: all-small-caps;">af</div>
+<div class="test" style="font-variant-caps: all-small-caps;">fa</div>
+<div class="test" style="font-variant-caps: all-small-caps;">Af</div>
+<div class="test" style="font-variant-caps: all-small-caps;">fA</div>
+<div class="test" style="font-variant-caps: all-small-caps;">g</div>
+<div class="test" style="font-variant-caps: all-small-caps;">ag</div>
+<div class="test" style="font-variant-caps: all-small-caps;">ga</div>
+<div class="test" style="font-variant-caps: all-small-caps;">Ag</div>
+<div class="test" style="font-variant-caps: all-small-caps;">gA</div
+</div>
+</div>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="branchessafari601branchLayoutTestscss3fontvariantsmallcapssynthesisexpectedhtml"></a>
<div class="addfile"><h4>Added: branches/safari-601-branch/LayoutTests/css3/font-variant-small-caps-synthesis-expected.html (0 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/LayoutTests/css3/font-variant-small-caps-synthesis-expected.html         (rev 0)
+++ branches/safari-601-branch/LayoutTests/css3/font-variant-small-caps-synthesis-expected.html        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -0,0 +1,91 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<style>
+@font-face {
+ font-family: "testfont";
+ src: url("resources/FontWithFeatures.otf") format("opentype");
+}
+.test {
+ font-size: 20px;
+ display: inline-block;
+}
+</style>
+</head>
+<body>
+This test makes sure that font-variant synthesis is correctly applied. The test passes when a particular pattern of Xs and checks appear below. Also note that the correct size of the character is required.
+<div style="border: solid black 1px;">
+<div class="test">ASDF</div>
+<div class="test"><span style="font-size: 14px;">ASDF</span></div>
+<div class="test"><span style="font-size: 14px;">AS</span>DF</div>
+<div class="test">AS<span style="font-size: 14px;">DF</span></div>
+<div class="test"><span style="font-size: 14px;">ASDF</span></div>
+<div class="test"><span style="font-size: 14px;">ASDF</span></div>
+<div class="test"><span style="font-size: 14px;">ASDF</span></div>
+<div class="test"><span style="font-size: 14px;">ASDF</span></div>
+</div>
+<div style="font-family: testfont; border: solid black 1px; margin: 5px;">
+<div class="test">AB</div>
+<div class="test">B</div>
+<div class="test">B</div>
+<div class="test">B</div>
+<div class="test"><span style="font-size: 14px;">A</span></div>
+<div class="test">A</div>
+<div class="test"><span style="font-size: 14px;">A</span>B</div>
+<div class="test">B<span style="font-size: 14px;">A</span></div>
+<div class="test">AA</div>
+<div class="test">AA</div>
+<div class="test">B</div>
+<div class="test"><span style="font-size: 14px;">A</span>K</div>
+<div class="test">K<span style="font-size: 14px;">A</span></div>
+<div class="test">AB</div>
+<div class="test">BA</div>
+</div>
+<div style="font-family: testfont; border: solid red 1px; margin: 5px;">
+<div class="test"style="">AB</div>
+<div class="test">B</div>
+<div class="test">B</div>
+<div class="test">B</div>
+<div class="test">B</div>
+<div class="test">A</div>
+<div class="test"><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+<div class="test">A<span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span>A</div>
+<div class="test"><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">A</span></div>
+<div class="test">A<span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span>A</div>
+</div>
+<div style="font-family: testfont; border: solid blue 1px; margin: 5px;">
+<div class="test"><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+</div>
+<div style="font-family: testfont; border: solid green 1px; margin: 5px;">
+<div class="test"><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">B</span></div>
+<div class="test"><span style="font-size: 14px;">B</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">A</span></div>
+<div class="test"><span style="font-size: 14px;">A</span><span style="font-size: 14px;">A</span></div>
+</div>
+</div>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="branchessafari601branchLayoutTestscss3fontvariantsmallcapssynthesishtml"></a>
<div class="addfile"><h4>Added: branches/safari-601-branch/LayoutTests/css3/font-variant-small-caps-synthesis.html (0 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/LayoutTests/css3/font-variant-small-caps-synthesis.html         (rev 0)
+++ branches/safari-601-branch/LayoutTests/css3/font-variant-small-caps-synthesis.html        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -0,0 +1,98 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<style>
+/* Only test OpenType fonts for now, because our TrueType font is busted when disabling features. */
+@font-face {
+ /* Opentype. "J" responds to smcp; "K" responds to c2sc */
+ font-family: "testfontotf";
+ src: url("resources/FontWithFeatures.otf") format("opentype");
+}
+@font-face {
+ /* Opentype. "f" responds to smcp; "g" responds to c2sc */
+ font-family: "testfontlowercasesmallcapsotf";
+ src: url("resources/FontWithFeaturesLowercaseSmallCaps.otf") format("opentype");
+}
+.test {
+ font-size: 20px;
+ display: inline-block;
+}
+</style>
+</head>
+<body>
+This test makes sure that font-variant synthesis is correctly applied. The test passes when a particular pattern of Xs and checks appear below. Also note that the correct size of the character is required.
+<div style="border: solid black 1px;">
+<div class="test" style="font-variant-caps: small-caps;">ASDF</div>
+<div class="test" style="font-variant-caps: small-caps;">asdf</div>
+<div class="test" style="font-variant-caps: small-caps;">asDF</div>
+<div class="test" style="font-variant-caps: small-caps;">ASdf</div>
+<div class="test" style="font-variant-caps: all-small-caps;">ASDF</div>
+<div class="test" style="font-variant-caps: all-small-caps;">asdf</div>
+<div class="test" style="font-variant-caps: all-small-caps;">asDF</div>
+<div class="test" style="font-variant-caps: all-small-caps;">ASdf</div>
+</div>
+<div style="font-family: testfontotf; border: solid black 1px; margin: 5px; font-feature-settings: 'ntrl';">
+<div class="test">AB</div>
+<div class="test">a</div>
+<div class="test">J</div>
+<div class="test">K</div>
+<div class="test" style="font-variant-caps: small-caps;">a</div>
+<div class="test" style="font-variant-caps: small-caps;">J</div>
+<div class="test" style="font-variant-caps: small-caps;">aJ</div>
+<div class="test" style="font-variant-caps: small-caps;">Ja</div>
+<div class="test" style="font-variant-caps: small-caps;">AJ</div>
+<div class="test" style="font-variant-caps: small-caps;">JA</div>
+<div class="test" style="font-variant-caps: small-caps;">K</div>
+<div class="test" style="font-variant-caps: small-caps;">aK</div>
+<div class="test" style="font-variant-caps: small-caps;">Ka</div>
+<div class="test" style="font-variant-caps: small-caps;">AK</div>
+<div class="test" style="font-variant-caps: small-caps;">KA</div>
+</div>
+<div style="font-family: testfontlowercasesmallcapsotf; border: solid red 1px; margin: 5px; font-feature-settings: 'ntrl';">
+<div class="test">AB</div>
+<div class="test">a</div>
+<div class="test">f</div>
+<div class="test">g</div>
+<div class="test">F</div>
+<div class="test">G</div>
+<div class="test" style="font-variant-caps: small-caps;">a</div>
+<div class="test" style="font-variant-caps: small-caps;">f</div>
+<div class="test" style="font-variant-caps: small-caps;">af</div>
+<div class="test" style="font-variant-caps: small-caps;">fa</div>
+<div class="test" style="font-variant-caps: small-caps;">Af</div>
+<div class="test" style="font-variant-caps: small-caps;">fA</div>
+<div class="test" style="font-variant-caps: small-caps;">g</div>
+<div class="test" style="font-variant-caps: small-caps;">ag</div>
+<div class="test" style="font-variant-caps: small-caps;">ga</div>
+<div class="test" style="font-variant-caps: small-caps;">Ag</div>
+<div class="test" style="font-variant-caps: small-caps;">gA</div>
+</div>
+<div style="font-family: testfontotf; border: solid blue 1px; margin: 5px; font-feature-settings: 'ntrl';">
+<div class="test" style="font-variant-caps: all-small-caps;">a</div>
+<div class="test" style="font-variant-caps: all-small-caps;">J</div>
+<div class="test" style="font-variant-caps: all-small-caps;">aJ</div>
+<div class="test" style="font-variant-caps: all-small-caps;">Ja</div>
+<div class="test" style="font-variant-caps: all-small-caps;">AJ</div>
+<div class="test" style="font-variant-caps: all-small-caps;">JA</div>
+<div class="test" style="font-variant-caps: all-small-caps;">K</div>
+<div class="test" style="font-variant-caps: all-small-caps;">aK</div>
+<div class="test" style="font-variant-caps: all-small-caps;">Ka</div>
+<div class="test" style="font-variant-caps: all-small-caps;">AK</div>
+<div class="test" style="font-variant-caps: all-small-caps;">KA</div>
+</div>
+<div style="font-family: testfontlowercasesmallcapsotf; border: solid green 1px; margin: 5px; font-feature-settings: 'ntrl';">
+<div class="test" style="font-variant-caps: all-small-caps;">a</div>
+<div class="test" style="font-variant-caps: all-small-caps;">f</div>
+<div class="test" style="font-variant-caps: all-small-caps;">af</div>
+<div class="test" style="font-variant-caps: all-small-caps;">fa</div>
+<div class="test" style="font-variant-caps: all-small-caps;">Af</div>
+<div class="test" style="font-variant-caps: all-small-caps;">fA</div>
+<div class="test" style="font-variant-caps: all-small-caps;">g</div>
+<div class="test" style="font-variant-caps: all-small-caps;">ag</div>
+<div class="test" style="font-variant-caps: all-small-caps;">ga</div>
+<div class="test" style="font-variant-caps: all-small-caps;">Ag</div>
+<div class="test" style="font-variant-caps: all-small-caps;">gA</div
+</div>
+</div>
+</body>
+</html>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="branchessafari601branchLayoutTestsplatformmacTestExpectations"></a>
<div class="modfile"><h4>Modified: branches/safari-601-branch/LayoutTests/platform/mac/TestExpectations (194286 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/LayoutTests/platform/mac/TestExpectations        2015-12-18 21:03:53 UTC (rev 194286)
+++ branches/safari-601-branch/LayoutTests/platform/mac/TestExpectations        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -1372,3 +1372,7 @@
</span><span class="cx"> webkit.org/b/149774 css3/font-variant-all.html [ Pass Failure ImageOnlyFailure ]
</span><span class="cx"> webkit.org/b/149774 css3/font-variant-font-face-all.html [ Pass Failure ImageOnlyFailure ]
</span><span class="cx"> webkit.org/b/149774 css3/font-variant-font-face-override.html [ Pass Failure ImageOnlyFailure ]
</span><ins>+
+# Yosemite and El Capitan do not support font feature coverage queries.
+[ Yosemite ElCapitan ] css3/font-variant-small-caps-synthesis-coverage.html [ ImageOnlyFailure ]
+[ Yosemite ElCapitan ] css3/font-variant-petite-caps-synthesis-coverage.html [ ImageOnlyFailure ]
</ins></span></pre></div>
<a id="branchessafari601branchLayoutTestsplatformmacfastwritingmodebrokenideographsmallcapsexpectedtxt"></a>
<div class="modfile"><h4>Modified: branches/safari-601-branch/LayoutTests/platform/mac/fast/writing-mode/broken-ideograph-small-caps-expected.txt (194286 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/LayoutTests/platform/mac/fast/writing-mode/broken-ideograph-small-caps-expected.txt        2015-12-18 21:03:53 UTC (rev 194286)
+++ branches/safari-601-branch/LayoutTests/platform/mac/fast/writing-mode/broken-ideograph-small-caps-expected.txt        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -13,8 +13,8 @@
</span><span class="cx"> text run at (21,1) width 176: "\x{7B2C}\x{4E8C}\x{6BB5}\x{843D} Paragraph 2"
</span><span class="cx"> RenderBlock {DIV} at (278,1) size 277x275 [bgcolor=#FFFFEE]
</span><span class="cx"> RenderBlock {P} at (14,28) size 63x219 [bgcolor=#FFAAAA] [border: none (20px solid #FF8888) none (20px solid #FF8888)]
</span><del>- RenderText {#text} at (21,1) size 20x175
- text run at (21,1) width 175: "\x{7B2C}\x{4E00}\x{6BB5}\x{843D} Paragraph 1"
</del><ins>+ RenderText {#text} at (21,1) size 20x156
+ text run at (21,1) width 156: "\x{7B2C}\x{4E00}\x{6BB5}\x{843D} Paragraph 1"
</ins><span class="cx"> RenderBlock {P} at (90,28) size 63x219 [bgcolor=#FFAAAA] [border: none (20px solid #FF8888) none (20px solid #FF8888)]
</span><del>- RenderText {#text} at (21,1) size 20x181
- text run at (21,1) width 181: "\x{7B2C}\x{4E8C}\x{6BB5}\x{843D} Paragraph 2"
</del><ins>+ RenderText {#text} at (21,1) size 20x162
+ text run at (21,1) width 162: "\x{7B2C}\x{4E8C}\x{6BB5}\x{843D} Paragraph 2"
</ins></span></pre></div>
<a id="branchessafari601branchSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-601-branch/Source/WebCore/ChangeLog (194286 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/Source/WebCore/ChangeLog        2015-12-18 21:03:53 UTC (rev 194286)
+++ branches/safari-601-branch/Source/WebCore/ChangeLog        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -1,3 +1,64 @@
</span><ins>+2015-12-17 Matthew Hanson <matthew_hanson@apple.com>
+
+ Merge r193894. rdar://problem/23769758
+
+ 2015-12-10 Myles C. Maxfield <mmaxfield@apple.com>
+
+ font-variant-caps does not work if the font does not support font features
+ https://bugs.webkit.org/show_bug.cgi?id=149774
+
+ Reviewed by Antti Koivisto.
+
+ This test implements synthesis for small-caps and all-small-caps. It does so by
+ moving font variant selection into a higher level (ComplexTextController).
+ In general, the approach is to use the pure font feature until we encounter
+ a character which needs to be uppercased, and which the font feature does not
+ support uppercasing. In this situation, we try again with synthesis. In this
+ case, synthesis means artificially uppercasing letters and rendering them with
+ a smaller font.
+
+ We require system support to know which glyphs a particular font feature supports.
+ Therefore, on operating systems which do not include this support, we will simply
+ say that the font feature does not support any glyphs.
+
+ Test: css3/font-variant-small-caps-synthesis.html
+ css3/font-variant-petite-caps-synthesis.html
+
+ * platform/graphics/Font.cpp:
+ (WebCore::Font::noSmallCapsFont): Return the same font, but without smcp or c2sc.
+ This function utilizes a cache.
+ * platform/graphics/Font.h:
+ (WebCore::Font::variantFont): Small caps should never go through this function
+ anymore.
+ * platform/graphics/FontCascade.h: Because we're moving variant selection into
+ a higher level, we remove the FontVariant argument from the lower-level call.
+ * platform/graphics/FontCascadeFonts.cpp:
+ (WebCore::FontCascadeFonts::glyphDataForVariant): Use early-return style.
+ (WebCore::FontCascadeFonts::glyphDataForNormalVariant): Ditto.
+ * platform/graphics/cocoa/FontCascadeCocoa.mm:
+ (WebCore::FontCascade::fontForCombiningCharacterSequence): Because we're moving
+ variant selection into a higher level, we remove the FontVariant argument from
+ the lower-level call.
+ * platform/graphics/cocoa/FontCocoa.mm:
+ (WebCore::Font::smallCapsSupportsCharacter):
+ (WebCore::Font::allSmallCapsSupportsCharacter):
+ (WebCore::smallCapsOpenTypeDictionary): Helper function for
+ smallCapsSupportsCharacter().
+ (WebCore::smallCapsTrueTypeDictionary): Ditto.
+ (WebCore::unionBitVectors):
+ (WebCore::Font::glyphsSupportedBySmallCaps): Compute a bit vector of supported
+ glyphs.
+ (WebCore::Font::glyphsSupportedByAllSmallCaps): Ditto.
+ (WebCore::createDerivativeFont): Moving common code into its own helper function.
+ (WebCore::Font::createFontWithoutSmallCaps):
+ (WebCore::Font::platformCreateScaledFont): Use the common code.
+ * platform/graphics/mac/ComplexTextController.cpp:
+ (WebCore::capitalized): What is the capitalized form of a character?
+ (WebCore::ComplexTextController::collectComplexTextRuns): Implement the core
+ logic of this patch. This includes the retry when we encounter a character which
+ is not supported by the font feature.
+ * platform/spi/cocoa/CoreTextSPI.h:
+
</ins><span class="cx"> 2015-12-18 Matthew Hanson <matthew_hanson@apple.com>
</span><span class="cx">
</span><span class="cx"> Merge r192582. rdar://problem/23910980
</span></span></pre></div>
<a id="branchessafari601branchSourceWebCoreplatformgraphicsFontcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-601-branch/Source/WebCore/platform/graphics/Font.cpp (194286 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/Source/WebCore/platform/graphics/Font.cpp        2015-12-18 21:03:53 UTC (rev 194286)
+++ branches/safari-601-branch/Source/WebCore/platform/graphics/Font.cpp        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -307,6 +307,18 @@
</span><span class="cx"> return m_derivedFontData->smallCaps;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if PLATFORM(COCOA)
+const Font& Font::noSynthesizableFeaturesFont() const
+{
+ if (!m_derivedFontData)
+ m_derivedFontData = std::make_unique<DerivedFontData>(isCustomFont());
+ if (!m_derivedFontData->noSynthesizableFeatures)
+ m_derivedFontData->noSynthesizableFeatures = createFontWithoutSynthesizableFeatures();
+ ASSERT(m_derivedFontData->noSynthesizableFeatures != this);
+ return *m_derivedFontData->noSynthesizableFeatures;
+}
+#endif
+
</ins><span class="cx"> PassRefPtr<Font> Font::emphasisMarkFont(const FontDescription& fontDescription) const
</span><span class="cx"> {
</span><span class="cx"> if (!m_derivedFontData)
</span></span></pre></div>
<a id="branchessafari601branchSourceWebCoreplatformgraphicsFonth"></a>
<div class="modfile"><h4>Modified: branches/safari-601-branch/Source/WebCore/platform/graphics/Font.h (194286 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/Source/WebCore/platform/graphics/Font.h        2015-12-18 21:03:53 UTC (rev 194286)
+++ branches/safari-601-branch/Source/WebCore/platform/graphics/Font.h        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -35,6 +35,8 @@
</span><span class="cx"> #if ENABLE(OPENTYPE_VERTICAL)
</span><span class="cx"> #include "OpenTypeVerticalData.h"
</span><span class="cx"> #endif
</span><ins>+#include <wtf/BitVector.h>
+#include <wtf/Optional.h>
</ins><span class="cx"> #include <wtf/TypeCasts.h>
</span><span class="cx"> #include <wtf/text/StringHash.h>
</span><span class="cx">
</span><span class="lines">@@ -104,9 +106,13 @@
</span><span class="cx"> PassRefPtr<Font> emphasisMarkFont(const FontDescription&) const;
</span><span class="cx"> PassRefPtr<Font> brokenIdeographFont() const;
</span><span class="cx"> PassRefPtr<Font> nonSyntheticItalicFont() const;
</span><ins>+ const Font& noSynthesizableFeaturesFont() const;
</ins><span class="cx">
</span><span class="cx"> PassRefPtr<Font> variantFont(const FontDescription& description, FontVariant variant) const
</span><span class="cx"> {
</span><ins>+#if PLATFORM(COCOA)
+ ASSERT(variant != SmallCapsVariant);
+#endif
</ins><span class="cx"> switch (variant) {
</span><span class="cx"> case SmallCapsVariant:
</span><span class="cx"> return smallCapsFont(description);
</span><span class="lines">@@ -122,6 +128,8 @@
</span><span class="cx"> return const_cast<Font*>(this);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ bool variantCapsSupportsCharacterForSynthesis(FontVariantCaps, UChar32) const;
+
</ins><span class="cx"> PassRefPtr<Font> verticalRightOrientationFont() const;
</span><span class="cx"> PassRefPtr<Font> uprightOrientationFont() const;
</span><span class="cx">
</span><span class="lines">@@ -194,7 +202,12 @@
</span><span class="cx"> #endif
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx"> CFDictionaryRef getCFStringAttributes(bool enableKerning, FontOrientation) const;
</span><ins>+
</ins><span class="cx"> bool hasCustomTracking() const { return isSystemFont(); }
</span><ins>+ const BitVector& glyphsSupportedBySmallCaps() const;
+ const BitVector& glyphsSupportedByAllSmallCaps() const;
+ const BitVector& glyphsSupportedByPetiteCaps() const;
+ const BitVector& glyphsSupportedByAllPetiteCaps() const;
</ins><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> #if PLATFORM(COCOA) || USE(HARFBUZZ)
</span><span class="lines">@@ -229,6 +242,7 @@
</span><span class="cx">
</span><span class="cx"> void initCharWidths();
</span><span class="cx">
</span><ins>+ RefPtr<Font> createFontWithoutSynthesizableFeatures() const;
</ins><span class="cx"> PassRefPtr<Font> createScaledFont(const FontDescription&, float scaleFactor) const;
</span><span class="cx"> PassRefPtr<Font> platformCreateScaledFont(const FontDescription&, float scaleFactor) const;
</span><span class="cx">
</span><span class="lines">@@ -274,6 +288,7 @@
</span><span class="cx">
</span><span class="cx"> bool forCustomFont;
</span><span class="cx"> RefPtr<Font> smallCaps;
</span><ins>+ RefPtr<Font> noSynthesizableFeatures;
</ins><span class="cx"> RefPtr<Font> emphasisMark;
</span><span class="cx"> RefPtr<Font> brokenIdeograph;
</span><span class="cx"> RefPtr<Font> verticalRightOrientation;
</span><span class="lines">@@ -292,6 +307,10 @@
</span><span class="cx">
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx"> mutable HashMap<unsigned, RetainPtr<CFDictionaryRef>> m_CFStringAttributes;
</span><ins>+ mutable Optional<BitVector> m_glyphsSupportedBySmallCaps;
+ mutable Optional<BitVector> m_glyphsSupportedByAllSmallCaps;
+ mutable Optional<BitVector> m_glyphsSupportedByPetiteCaps;
+ mutable Optional<BitVector> m_glyphsSupportedByAllPetiteCaps;
</ins><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> #if PLATFORM(COCOA) || USE(HARFBUZZ)
</span></span></pre></div>
<a id="branchessafari601branchSourceWebCoreplatformgraphicsFontCascadeh"></a>
<div class="modfile"><h4>Modified: branches/safari-601-branch/Source/WebCore/platform/graphics/FontCascade.h (194286 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/Source/WebCore/platform/graphics/FontCascade.h        2015-12-18 21:03:53 UTC (rev 194286)
+++ branches/safari-601-branch/Source/WebCore/platform/graphics/FontCascade.h        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -191,7 +191,7 @@
</span><span class="cx"> GlyphData glyphDataForCharacter(UChar32, bool mirror, FontVariant = AutoVariant) const;
</span><span class="cx">
</span><span class="cx"> #if PLATFORM(COCOA)
</span><del>- const Font* fontForCombiningCharacterSequence(const UChar*, size_t length, FontVariant) const;
</del><ins>+ const Font* fontForCombiningCharacterSequence(const UChar*, size_t length) const;
</ins><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> static bool isCJKIdeograph(UChar32);
</span></span></pre></div>
<a id="branchessafari601branchSourceWebCoreplatformgraphicsFontCascadeFontscpp"></a>
<div class="modfile"><h4>Modified: branches/safari-601-branch/Source/WebCore/platform/graphics/FontCascadeFonts.cpp (194286 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/Source/WebCore/platform/graphics/FontCascadeFonts.cpp        2015-12-18 21:03:53 UTC (rev 194286)
+++ branches/safari-601-branch/Source/WebCore/platform/graphics/FontCascadeFonts.cpp        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -296,15 +296,15 @@
</span><span class="cx"> if (fontRanges.isNull())
</span><span class="cx"> break;
</span><span class="cx"> GlyphData data = fontRanges.glyphDataForCharacter(c);
</span><del>- if (data.font) {
- // The variantFont function should not normally return 0.
- // But if it does, we will just render the capital letter big.
- RefPtr<Font> variantFont = data.font->variantFont(description, variant);
- if (!variantFont)
- return data;
</del><ins>+ if (!data.font)
+ continue;
+ // The variantFont function should not normally return 0.
+ // But if it does, we will just render the capital letter big.
+ RefPtr<Font> variantFont = data.font->variantFont(description, variant);
+ if (!variantFont)
+ return data;
</ins><span class="cx">
</span><del>- return variantFont->glyphDataForCharacter(c);
- }
</del><ins>+ return variantFont->glyphDataForCharacter(c);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> return glyphDataForSystemFallback(c, description, variant);
</span><span class="lines">@@ -317,23 +317,23 @@
</span><span class="cx"> if (fontRanges.isNull())
</span><span class="cx"> break;
</span><span class="cx"> GlyphData data = fontRanges.glyphDataForCharacter(c);
</span><del>- if (data.font) {
- if (data.font->platformData().orientation() == Vertical && !data.font->isTextOrientationFallback()) {
- if (!FontCascade::isCJKIdeographOrSymbol(c))
- return glyphDataForNonCJKCharacterWithGlyphOrientation(c, description.nonCJKGlyphOrientation(), data);
</del><ins>+ if (!data.font)
+ continue;
+ if (data.font->platformData().orientation() == Vertical && !data.font->isTextOrientationFallback()) {
+ if (!FontCascade::isCJKIdeographOrSymbol(c))
+ return glyphDataForNonCJKCharacterWithGlyphOrientation(c, description.nonCJKGlyphOrientation(), data);
</ins><span class="cx">
</span><del>- if (!data.font->hasVerticalGlyphs()) {
- // Use the broken ideograph font data. The broken ideograph font will use the horizontal width of glyphs
- // to make sure you get a square (even for broken glyphs like symbols used for punctuation).
- return glyphDataForVariant(c, description, BrokenIdeographVariant, fallbackIndex);
- }
</del><ins>+ if (!data.font->hasVerticalGlyphs()) {
+ // Use the broken ideograph font data. The broken ideograph font will use the horizontal width of glyphs
+ // to make sure you get a square (even for broken glyphs like symbols used for punctuation).
+ return glyphDataForVariant(c, description, BrokenIdeographVariant, fallbackIndex);
+ }
</ins><span class="cx"> #if PLATFORM(COCOA) || USE(CAIRO)
</span><del>- if (data.font->platformData().syntheticOblique())
- return glyphDataForCJKCharacterWithoutSyntheticItalic(c, data);
</del><ins>+ if (data.font->platformData().syntheticOblique())
+ return glyphDataForCJKCharacterWithoutSyntheticItalic(c, data);
</ins><span class="cx"> #endif
</span><del>- }
- return data;
</del><span class="cx"> }
</span><ins>+ return data;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> return glyphDataForSystemFallback(c, description, NormalVariant);
</span></span></pre></div>
<a id="branchessafari601branchSourceWebCoreplatformgraphicsFontDescriptionh"></a>
<div class="modfile"><h4>Modified: branches/safari-601-branch/Source/WebCore/platform/graphics/FontDescription.h (194286 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/Source/WebCore/platform/graphics/FontDescription.h        2015-12-18 21:03:53 UTC (rev 194286)
+++ branches/safari-601-branch/Source/WebCore/platform/graphics/FontDescription.h        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -204,7 +204,7 @@
</span><span class="cx"> {
</span><span class="cx"> return familiesEqualForTextAutoSizing(other)
</span><span class="cx"> && m_specifiedSize == other.m_specifiedSize
</span><del>- && variantSettings() == other.other.variantSettings()
</del><ins>+ && variantSettings() == other.variantSettings()
</ins><span class="cx"> && m_isAbsoluteSize == other.m_isAbsoluteSize;
</span><span class="cx"> }
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="branchessafari601branchSourceWebCoreplatformgraphicscocoaFontCascadeCocoamm"></a>
<div class="modfile"><h4>Modified: branches/safari-601-branch/Source/WebCore/platform/graphics/cocoa/FontCascadeCocoa.mm (194286 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/Source/WebCore/platform/graphics/cocoa/FontCascadeCocoa.mm        2015-12-18 21:03:53 UTC (rev 194286)
+++ branches/safari-601-branch/Source/WebCore/platform/graphics/cocoa/FontCascadeCocoa.mm        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -756,13 +756,13 @@
</span><span class="cx"> return controller.offsetForPosition(x, includePartialGlyphs);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-const Font* FontCascade::fontForCombiningCharacterSequence(const UChar* characters, size_t length, FontVariant variant) const
</del><ins>+const Font* FontCascade::fontForCombiningCharacterSequence(const UChar* characters, size_t length) const
</ins><span class="cx"> {
</span><span class="cx"> UChar32 baseCharacter;
</span><span class="cx"> size_t baseCharacterLength = 0;
</span><span class="cx"> U16_NEXT(characters, baseCharacterLength, length, baseCharacter);
</span><span class="cx">
</span><del>- GlyphData baseCharacterGlyphData = glyphDataForCharacter(baseCharacter, false, variant);
</del><ins>+ GlyphData baseCharacterGlyphData = glyphDataForCharacter(baseCharacter, false, NormalVariant);
</ins><span class="cx">
</span><span class="cx"> if (!baseCharacterGlyphData.glyph)
</span><span class="cx"> return 0;
</span><span class="lines">@@ -780,26 +780,20 @@
</span><span class="cx"> if (baseCharacter >= 0x0600 && baseCharacter <= 0x06ff && font->shouldNotBeUsedForArabic())
</span><span class="cx"> continue;
</span><span class="cx"> #endif
</span><del>- if (variant == NormalVariant) {
- if (font->platformData().orientation() == Vertical) {
- if (isCJKIdeographOrSymbol(baseCharacter) && !font->hasVerticalGlyphs()) {
- variant = BrokenIdeographVariant;
- font = font->brokenIdeographFont().get();
- } else if (m_fontDescription.nonCJKGlyphOrientation() == NonCJKGlyphOrientationVerticalRight) {
- Font* verticalRightFont = font->verticalRightOrientationFont().get();
- Glyph verticalRightGlyph = verticalRightFont->glyphForCharacter(baseCharacter);
- if (verticalRightGlyph == baseCharacterGlyphData.glyph)
- font = verticalRightFont;
- } else {
- Font* uprightFont = font->uprightOrientationFont().get();
- Glyph uprightGlyph = uprightFont->glyphForCharacter(baseCharacter);
- if (uprightGlyph != baseCharacterGlyphData.glyph)
- font = uprightFont;
- }
</del><ins>+ if (font->platformData().orientation() == Vertical) {
+ if (isCJKIdeographOrSymbol(baseCharacter) && !font->hasVerticalGlyphs())
+ font = font->brokenIdeographFont().get();
+ else if (m_fontDescription.nonCJKGlyphOrientation() == NonCJKGlyphOrientationVerticalRight) {
+ Font* verticalRightFont = font->verticalRightOrientationFont().get();
+ Glyph verticalRightGlyph = verticalRightFont->glyphForCharacter(baseCharacter);
+ if (verticalRightGlyph == baseCharacterGlyphData.glyph)
+ font = verticalRightFont;
+ } else {
+ Font* uprightFont = font->uprightOrientationFont().get();
+ Glyph uprightGlyph = uprightFont->glyphForCharacter(baseCharacter);
+ if (uprightGlyph != baseCharacterGlyphData.glyph)
+ font = uprightFont;
</ins><span class="cx"> }
</span><del>- } else {
- if (const Font* variantFont = font->variantFont(m_fontDescription, variant).get())
- font = variantFont;
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (font == baseCharacterGlyphData.font)
</span></span></pre></div>
<a id="branchessafari601branchSourceWebCoreplatformgraphicscocoaFontCocoamm"></a>
<div class="modfile"><h4>Modified: branches/safari-601-branch/Source/WebCore/platform/graphics/cocoa/FontCocoa.mm (194286 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/Source/WebCore/platform/graphics/cocoa/FontCocoa.mm        2015-12-18 21:03:53 UTC (rev 194286)
+++ branches/safari-601-branch/Source/WebCore/platform/graphics/cocoa/FontCocoa.mm        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -40,6 +40,7 @@
</span><span class="cx"> #import <float.h>
</span><span class="cx"> #import <unicode/uchar.h>
</span><span class="cx"> #import <wtf/Assertions.h>
</span><ins>+#import <wtf/NeverDestroyed.h>
</ins><span class="cx"> #import <wtf/RetainPtr.h>
</span><span class="cx"> #import <wtf/StdLibExtras.h>
</span><span class="cx">
</span><span class="lines">@@ -314,64 +315,271 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><del>-PassRefPtr<Font> Font::platformCreateScaledFont(const FontDescription&, float scaleFactor) const
</del><ins>+bool Font::variantCapsSupportsCharacterForSynthesis(FontVariantCaps fontVariantCaps, UChar32 character) const
</ins><span class="cx"> {
</span><del>-#if !CORETEXT_WEB_FONTS
- if (isCustomFont()) {
- FontPlatformData scaledFontData(m_platformData);
- scaledFontData.m_size = scaledFontData.m_size * scaleFactor;
- return Font::create(scaledFontData, true, false);
</del><ins>+#if (PLATFORM(IOS) && TARGET_OS_IOS && __IPHONE_OS_VERSION_MIN_REQUIRED >= 90300) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100 && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101104)
+ Glyph glyph = glyphForCharacter(character);
+ if (!glyph)
+ return false;
+
+ switch (fontVariantCaps) {
+ case FontVariantCaps::Small: {
+ auto& supported = glyphsSupportedBySmallCaps();
+ return supported.size() > glyph && supported.get(glyph);
</ins><span class="cx"> }
</span><ins>+ case FontVariantCaps::Petite: {
+ auto& supported = glyphsSupportedByPetiteCaps();
+ return supported.size() > glyph && supported.get(glyph);
+ }
+ case FontVariantCaps::AllSmall: {
+ auto& supported = glyphsSupportedByAllSmallCaps();
+ return supported.size() > glyph && supported.get(glyph);
+ }
+ case FontVariantCaps::AllPetite: {
+ auto& supported = glyphsSupportedByAllPetiteCaps();
+ return supported.size() > glyph && supported.get(glyph);
+ }
+ default:
+ // Synthesis only supports the variant-caps values listed above.
+ return true;
+ }
+#else
+ UNUSED_PARAM(character);
+
+ switch (fontVariantCaps) {
+ case FontVariantCaps::Small:
+ case FontVariantCaps::Petite:
+ case FontVariantCaps::AllSmall:
+ case FontVariantCaps::AllPetite:
+ return false;
+ default:
+ // Synthesis only supports the variant-caps values listed above.
+ return true;
+ }
</ins><span class="cx"> #endif
</span><ins>+}
</ins><span class="cx">
</span><del>- float size = m_platformData.size() * scaleFactor;
</del><ins>+#if (PLATFORM(IOS) && TARGET_OS_IOS && __IPHONE_OS_VERSION_MIN_REQUIRED >= 90300) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100 && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101104)
+static RetainPtr<CFDictionaryRef> smallCapsOpenTypeDictionary(CFStringRef key, int rawValue)
+{
+ RetainPtr<CFNumberRef> value = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &rawValue));
+ CFTypeRef keys[] = { kCTFontOpenTypeFeatureTag, kCTFontOpenTypeFeatureValue };
+ CFTypeRef values[] = { key, value.get() };
+ return adoptCF(CFDictionaryCreate(kCFAllocatorDefault, keys, values, WTF_ARRAY_LENGTH(keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+}
</ins><span class="cx">
</span><del>-#if USE(APPKIT)
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
</del><ins>+static RetainPtr<CFDictionaryRef> smallCapsTrueTypeDictionary(int rawKey, int rawValue)
+{
+ CFNumberRef key = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &rawKey);
+ CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &rawValue);
+ CFTypeRef keys[] = { kCTFontFeatureTypeIdentifierKey, kCTFontFeatureSelectorIdentifierKey };
+ CFTypeRef values[] = { key, value };
+ return adoptCF(CFDictionaryCreate(kCFAllocatorDefault, keys, values, WTF_ARRAY_LENGTH(keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+}
</ins><span class="cx">
</span><del>- FontPlatformData scaledFontData(reinterpret_cast<CTFontRef>([[NSFontManager sharedFontManager] convertFont:m_platformData.nsFont() toSize:size]), size, false, false, m_platformData.orientation());
</del><ins>+static void unionBitVectors(BitVector& result, CFBitVectorRef source)
+{
+ CFIndex length = CFBitVectorGetCount(source);
+ result.ensureSize(length);
+ CFIndex min = 0;
+ while (min < length) {
+ CFIndex nextIndex = CFBitVectorGetFirstIndexOfBit(source, CFRangeMake(min, length - min), 1);
+ if (nextIndex == kCFNotFound)
+ break;
+ result.set(nextIndex, true);
+ min = nextIndex + 1;
+ }
+}
</ins><span class="cx">
</span><del>- if (scaledFontData.font()) {
- NSFontManager *fontManager = [NSFontManager sharedFontManager];
- NSFontTraitMask fontTraits = [fontManager traitsOfFont:m_platformData.nsFont()];
</del><ins>+static void injectOpenTypeCoverage(CFStringRef feature, CTFontRef font, BitVector& result)
+{
+ RetainPtr<CFBitVectorRef> source = adoptCF(CTFontCopyGlyphCoverageForFeature(font, smallCapsOpenTypeDictionary(feature, 1).get()));
+ unionBitVectors(result, source.get());
+}
</ins><span class="cx">
</span><del>- if (m_platformData.m_syntheticBold)
- fontTraits |= NSBoldFontMask;
- if (m_platformData.m_syntheticOblique)
- fontTraits |= NSItalicFontMask;
</del><ins>+static void injectTrueTypeCoverage(int type, int selector, CTFontRef font, BitVector& result)
+{
+ RetainPtr<CFBitVectorRef> source = adoptCF(CTFontCopyGlyphCoverageForFeature(font, smallCapsTrueTypeDictionary(type, selector).get()));
+ unionBitVectors(result, source.get());
+}
</ins><span class="cx">
</span><del>- NSFontTraitMask scaledFontTraits = [fontManager traitsOfFont:scaledFontData.nsFont()];
- scaledFontData.m_syntheticBold = (fontTraits & NSBoldFontMask) && !(scaledFontTraits & NSBoldFontMask);
- scaledFontData.m_syntheticOblique = (fontTraits & NSItalicFontMask) && !(scaledFontTraits & NSItalicFontMask);
</del><ins>+const BitVector& Font::glyphsSupportedBySmallCaps() const
+{
+ if (!m_glyphsSupportedBySmallCaps) {
+ m_glyphsSupportedBySmallCaps = BitVector();
+ injectOpenTypeCoverage(CFSTR("smcp"), platformData().font(), m_glyphsSupportedBySmallCaps.value());
+ injectTrueTypeCoverage(kLowerCaseType, kLowerCaseSmallCapsSelector, platformData().font(), m_glyphsSupportedBySmallCaps.value());
+ }
+ return m_glyphsSupportedBySmallCaps.value();
+}
</ins><span class="cx">
</span><del>- return Font::create(scaledFontData);
</del><ins>+const BitVector& Font::glyphsSupportedByAllSmallCaps() const
+{
+ if (!m_glyphsSupportedByAllSmallCaps) {
+ m_glyphsSupportedByAllSmallCaps = BitVector();
+ injectOpenTypeCoverage(CFSTR("smcp"), platformData().font(), m_glyphsSupportedByAllSmallCaps.value());
+ injectOpenTypeCoverage(CFSTR("c2sc"), platformData().font(), m_glyphsSupportedByAllSmallCaps.value());
+ injectTrueTypeCoverage(kLowerCaseType, kLowerCaseSmallCapsSelector, platformData().font(), m_glyphsSupportedByAllSmallCaps.value());
+ injectTrueTypeCoverage(kUpperCaseType, kUpperCaseSmallCapsSelector, platformData().font(), m_glyphsSupportedByAllSmallCaps.value());
</ins><span class="cx"> }
</span><del>- END_BLOCK_OBJC_EXCEPTIONS;
</del><ins>+ return m_glyphsSupportedByAllSmallCaps.value();
+}
</ins><span class="cx">
</span><del>- return nullptr;
-#else
- CTFontSymbolicTraits fontTraits = CTFontGetSymbolicTraits(m_platformData.font());
- RetainPtr<CTFontDescriptorRef> fontDescriptor = adoptCF(CTFontCopyFontDescriptor(m_platformData.font()));
- RetainPtr<CTFontRef> scaledFont = adoptCF(CTFontCreateWithFontDescriptor(fontDescriptor.get(), size, nullptr));
- FontPlatformData scaledFontData(scaledFont.get(), size, false, false, m_platformData.orientation());
</del><ins>+const BitVector& Font::glyphsSupportedByPetiteCaps() const
+{
+ if (!m_glyphsSupportedByPetiteCaps) {
+ m_glyphsSupportedByPetiteCaps = BitVector();
+ injectOpenTypeCoverage(CFSTR("pcap"), platformData().font(), m_glyphsSupportedByPetiteCaps.value());
+ injectTrueTypeCoverage(kLowerCaseType, kLowerCasePetiteCapsSelector, platformData().font(), m_glyphsSupportedByPetiteCaps.value());
+ }
+ return m_glyphsSupportedByPetiteCaps.value();
+}
</ins><span class="cx">
</span><del>- if (scaledFontData.font()) {
- if (m_platformData.m_syntheticBold)
- fontTraits |= kCTFontBoldTrait;
- if (m_platformData.m_syntheticOblique)
- fontTraits |= kCTFontItalicTrait;
</del><ins>+const BitVector& Font::glyphsSupportedByAllPetiteCaps() const
+{
+ if (!m_glyphsSupportedByAllPetiteCaps) {
+ m_glyphsSupportedByAllPetiteCaps = BitVector();
+ injectOpenTypeCoverage(CFSTR("pcap"), platformData().font(), m_glyphsSupportedByAllPetiteCaps.value());
+ injectOpenTypeCoverage(CFSTR("c2pc"), platformData().font(), m_glyphsSupportedByAllPetiteCaps.value());
+ injectTrueTypeCoverage(kLowerCaseType, kLowerCasePetiteCapsSelector, platformData().font(), m_glyphsSupportedByAllPetiteCaps.value());
+ injectTrueTypeCoverage(kUpperCaseType, kUpperCasePetiteCapsSelector, platformData().font(), m_glyphsSupportedByAllPetiteCaps.value());
+ }
+ return m_glyphsSupportedByAllPetiteCaps.value();
+}
+#endif
</ins><span class="cx">
</span><del>- CTFontSymbolicTraits scaledFontTraits = CTFontGetSymbolicTraits(scaledFontData.font());
- scaledFontData.m_syntheticBold = (fontTraits & kCTFontBoldTrait) && !(scaledFontTraits & kCTFontTraitBold);
- scaledFontData.m_syntheticOblique = (fontTraits & kCTFontItalicTrait) && !(scaledFontTraits & kCTFontTraitItalic);
</del><ins>+static RefPtr<Font> createDerivativeFont(CTFontRef font, float size, FontOrientation orientation, CTFontSymbolicTraits fontTraits, bool syntheticBold, bool syntheticItalic)
+{
+ if (!font)
+ return nullptr;
</ins><span class="cx">
</span><del>- return Font::create(scaledFontData);
</del><ins>+ FontPlatformData scaledFontData(font, size, false, false, orientation);
+
+ if (syntheticBold)
+ fontTraits |= kCTFontBoldTrait;
+ if (syntheticItalic)
+ fontTraits |= kCTFontItalicTrait;
+
+ CTFontSymbolicTraits scaledFontTraits = CTFontGetSymbolicTraits(scaledFontData.font());
+ scaledFontData.m_syntheticBold = (fontTraits & kCTFontBoldTrait) && !(scaledFontTraits & kCTFontTraitBold);
+ scaledFontData.m_syntheticOblique = (fontTraits & kCTFontItalicTrait) && !(scaledFontTraits & kCTFontTraitItalic);
+
+ return Font::create(scaledFontData);
+}
+
+static inline bool isOpenTypeFeature(CFDictionaryRef feature)
+{
+ return CFDictionaryContainsKey(feature, kCTFontOpenTypeFeatureTag) && CFDictionaryContainsKey(feature, kCTFontOpenTypeFeatureValue);
+}
+
+static inline bool isTrueTypeFeature(CFDictionaryRef feature)
+{
+ return CFDictionaryContainsKey(feature, kCTFontFeatureTypeIdentifierKey) && CFDictionaryContainsKey(feature, kCTFontFeatureSelectorIdentifierKey);
+}
+
+static inline Optional<CFStringRef> openTypeFeature(CFDictionaryRef feature)
+{
+ ASSERT(isOpenTypeFeature(feature));
+ CFStringRef tag = static_cast<CFStringRef>(CFDictionaryGetValue(feature, kCTFontOpenTypeFeatureTag));
+ int rawValue;
+ CFNumberRef value = static_cast<CFNumberRef>(CFDictionaryGetValue(feature, kCTFontOpenTypeFeatureValue));
+ auto success = CFNumberGetValue(value, kCFNumberIntType, &rawValue);
+ ASSERT_UNUSED(success, success);
+ return rawValue ? Optional<CFStringRef>(tag) : Nullopt;
+}
+
+static inline std::pair<int, int> trueTypeFeature(CFDictionaryRef feature)
+{
+ ASSERT(isTrueTypeFeature(feature));
+ int rawType;
+ CFNumberRef type = static_cast<CFNumberRef>(CFDictionaryGetValue(feature, kCTFontFeatureTypeIdentifierKey));
+ auto success = CFNumberGetValue(type, kCFNumberIntType, &rawType);
+ ASSERT_UNUSED(success, success);
+ int rawSelector;
+ CFNumberRef selector = static_cast<CFNumberRef>(CFDictionaryGetValue(feature, kCTFontFeatureSelectorIdentifierKey));
+ success = CFNumberGetValue(selector, kCFNumberIntType, &rawSelector);
+ ASSERT_UNUSED(success, success);
+ return std::make_pair(rawType, rawSelector);
+}
+
+static inline RetainPtr<CFDictionaryRef> removedFeature(CFDictionaryRef feature)
+{
+ bool isOpenType = isOpenTypeFeature(feature);
+ bool isTrueType = isTrueTypeFeature(feature);
+ if (!isOpenType && !isTrueType)
+ return feature; // We don't understand this font format.
+ RetainPtr<CFMutableDictionaryRef> result = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ if (isOpenType) {
+ auto featureTag = openTypeFeature(feature);
+ if (featureTag && (CFEqual(featureTag.value(), CFSTR("smcp"))
+ || CFEqual(featureTag.value(), CFSTR("c2sc"))
+ || CFEqual(featureTag.value(), CFSTR("pcap"))
+ || CFEqual(featureTag.value(), CFSTR("c2pc")))) {
+ int rawZero = 0;
+ RetainPtr<CFNumberRef> zero = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &rawZero));
+ CFDictionaryAddValue(result.get(), kCTFontOpenTypeFeatureTag, featureTag.value());
+ CFDictionaryAddValue(result.get(), kCTFontOpenTypeFeatureValue, zero.get());
+ } else {
+ CFDictionaryAddValue(result.get(), kCTFontOpenTypeFeatureTag, CFDictionaryGetValue(feature, kCTFontOpenTypeFeatureTag));
+ CFDictionaryAddValue(result.get(), kCTFontOpenTypeFeatureValue, CFDictionaryGetValue(feature, kCTFontOpenTypeFeatureValue));
+ }
</ins><span class="cx"> }
</span><ins>+ if (isTrueType) {
+ auto trueTypeFeaturePair = trueTypeFeature(feature);
+ if (trueTypeFeaturePair.first == kLowerCaseType && (trueTypeFeaturePair.second == kLowerCaseSmallCapsSelector || trueTypeFeaturePair.second == kLowerCasePetiteCapsSelector)) {
+ int rawSelector = kDefaultLowerCaseSelector;
+ RetainPtr<CFNumberRef> selector = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &rawSelector));
+ CFDictionaryAddValue(result.get(), kCTFontFeatureTypeIdentifierKey, CFDictionaryGetValue(feature, kCTFontFeatureTypeIdentifierKey));
+ CFDictionaryAddValue(result.get(), kCTFontFeatureSelectorIdentifierKey, selector.get());
+ } else if (trueTypeFeaturePair.first == kUpperCaseType && (trueTypeFeaturePair.second == kUpperCaseSmallCapsSelector || trueTypeFeaturePair.second == kUpperCasePetiteCapsSelector)) {
+ int rawSelector = kDefaultUpperCaseSelector;
+ RetainPtr<CFNumberRef> selector = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &rawSelector));
+ CFDictionaryAddValue(result.get(), kCTFontFeatureTypeIdentifierKey, CFDictionaryGetValue(feature, kCTFontFeatureTypeIdentifierKey));
+ CFDictionaryAddValue(result.get(), kCTFontFeatureSelectorIdentifierKey, selector.get());
+ } else {
+ CFDictionaryAddValue(result.get(), kCTFontFeatureTypeIdentifierKey, CFDictionaryGetValue(feature, kCTFontFeatureTypeIdentifierKey));
+ CFDictionaryAddValue(result.get(), kCTFontFeatureSelectorIdentifierKey, CFDictionaryGetValue(feature, kCTFontFeatureSelectorIdentifierKey));
+ }
+ }
+ return result;
+}
</ins><span class="cx">
</span><del>- return nullptr;
-#endif
</del><ins>+static RetainPtr<CTFontRef> createCTFontWithoutSynthesizableFeatures(CTFontRef font)
+{
+ RetainPtr<CFArrayRef> features = static_cast<CFArrayRef>(CTFontCopyAttribute(font, kCTFontFeatureSettingsAttribute));
+ if (!features)
+ return font;
+ CFIndex featureCount = CFArrayGetCount(features.get());
+ RetainPtr<CFMutableArrayRef> newFeatures = adoptCF(CFArrayCreateMutable(kCFAllocatorDefault, featureCount, &kCFTypeArrayCallBacks));
+ for (CFIndex i = 0; i < featureCount; ++i) {
+ CFDictionaryRef feature = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(features.get(), i));
+ CFArrayAppendValue(newFeatures.get(), removedFeature(feature).get());
+ }
+ CFTypeRef keys[] = { kCTFontFeatureSettingsAttribute };
+ CFTypeRef values[] = { newFeatures.get() };
+ RetainPtr<CFDictionaryRef> attributes = adoptCF(CFDictionaryCreate(kCFAllocatorDefault, keys, values, WTF_ARRAY_LENGTH(keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ RetainPtr<CTFontDescriptorRef> newDescriptor = adoptCF(CTFontDescriptorCreateWithAttributes(attributes.get()));
+ return adoptCF(CTFontCreateCopyWithAttributes(font, CTFontGetSize(font), nullptr, newDescriptor.get()));
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+RefPtr<Font> Font::createFontWithoutSynthesizableFeatures() const
+{
+ float size = m_platformData.size();
+ CTFontSymbolicTraits fontTraits = CTFontGetSymbolicTraits(m_platformData.font());
+ RetainPtr<CTFontRef> ctFont = createCTFontWithoutSynthesizableFeatures(m_platformData.font());
+ return createDerivativeFont(ctFont.get(), size, m_platformData.orientation(), fontTraits, m_platformData.m_syntheticBold, m_platformData.m_syntheticOblique);
+}
+
+PassRefPtr<Font> Font::platformCreateScaledFont(const FontDescription&, float scaleFactor) const
+{
+ float size = m_platformData.size() * scaleFactor;
+ CTFontSymbolicTraits fontTraits = CTFontGetSymbolicTraits(m_platformData.font());
+ RetainPtr<CTFontDescriptorRef> fontDescriptor = adoptCF(CTFontCopyFontDescriptor(m_platformData.font()));
+ RetainPtr<CTFontRef> scaledFont = adoptCF(CTFontCreateWithFontDescriptor(fontDescriptor.get(), size, nullptr));
+
+ return createDerivativeFont(scaledFont.get(), size, m_platformData.orientation(), fontTraits, m_platformData.m_syntheticBold, m_platformData.m_syntheticOblique);
+}
+
</ins><span class="cx"> void Font::determinePitch()
</span><span class="cx"> {
</span><span class="cx"> #if USE(APPKIT)
</span></span></pre></div>
<a id="branchessafari601branchSourceWebCoreplatformgraphicsiosFontCacheIOSmm"></a>
<div class="modfile"><h4>Modified: branches/safari-601-branch/Source/WebCore/platform/graphics/ios/FontCacheIOS.mm (194286 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/Source/WebCore/platform/graphics/ios/FontCacheIOS.mm        2015-12-18 21:03:53 UTC (rev 194286)
+++ branches/safari-601-branch/Source/WebCore/platform/graphics/ios/FontCacheIOS.mm        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -85,7 +85,7 @@
</span><span class="cx"> if (!substituteFont)
</span><span class="cx"> return nullptr;
</span><span class="cx">
</span><del>- substituteFont = applyFontFeatureSettings(substituteFont.get(), description.featureSettings(), description.variantSettings());
</del><ins>+ substituteFont = applyFontFeatureSettings(substituteFont.get(), nullptr, nullptr, description.featureSettings(), description.variantSettings());
</ins><span class="cx">
</span><span class="cx"> CTFontSymbolicTraits originalTraits = CTFontGetSymbolicTraits(ctFont);
</span><span class="cx"> CTFontSymbolicTraits actualTraits = 0;
</span><span class="lines">@@ -700,7 +700,7 @@
</span><span class="cx"> if (!ctFont)
</span><span class="cx"> return nullptr;
</span><span class="cx">
</span><del>- ctFont = applyFontFeatureSettings(ctFont.get(), fontDescription.featureSettings(), fontDescription.variantSettings());
</del><ins>+ ctFont = applyFontFeatureSettings(ctFont.get(), nullptr, nullptr, fontDescription.featureSettings(), fontDescription.variantSettings());
</ins><span class="cx">
</span><span class="cx"> CTFontSymbolicTraits actualTraits = 0;
</span><span class="cx"> if (isFontWeightBold(fontDescription.weight()) || fontDescription.italic())
</span></span></pre></div>
<a id="branchessafari601branchSourceWebCoreplatformgraphicsmacComplexTextControllercpp"></a>
<div class="modfile"><h4>Modified: branches/safari-601-branch/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp (194286 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp        2015-12-18 21:03:53 UTC (rev 194286)
+++ branches/safari-601-branch/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include "RenderText.h"
</span><span class="cx"> #include "TextBreakIterator.h"
</span><span class="cx"> #include "TextRun.h"
</span><ins>+#include <wtf/Optional.h>
</ins><span class="cx"> #include <wtf/StdLibExtras.h>
</span><span class="cx"> #include <wtf/unicode/CharacterNames.h>
</span><span class="cx">
</span><span class="lines">@@ -289,6 +290,19 @@
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+// FIXME: Capitalization is language-dependent and context-dependent and should operate on grapheme clusters instead of codepoints.
+static inline Optional<UChar32> capitalized(UChar32 baseCharacter)
+{
+ if (U_GET_GC_MASK(baseCharacter) & U_GC_M_MASK)
+ return Nullopt;
+
+ UChar32 uppercaseCharacter = u_toupper(baseCharacter);
+ ASSERT(uppercaseCharacter == baseCharacter || uppercaseCharacter <= 0xFFFF);
+ if (uppercaseCharacter != baseCharacter)
+ return uppercaseCharacter;
+ return Nullopt;
+}
+
</ins><span class="cx"> void ComplexTextController::collectComplexTextRuns()
</span><span class="cx"> {
</span><span class="cx"> if (!m_end)
</span><span class="lines">@@ -304,7 +318,11 @@
</span><span class="cx"> } else
</span><span class="cx"> cp = m_run.characters16();
</span><span class="cx">
</span><del>- if (m_font.isSmallCaps())
</del><ins>+ auto fontVariantCaps = m_font.fontDescription().variantCaps();
+ bool engageAllSmallCapsProcessing = fontVariantCaps == FontVariantCaps::AllSmall || fontVariantCaps == FontVariantCaps::AllPetite;
+ bool engageSmallCapsProcessing = engageAllSmallCapsProcessing || fontVariantCaps == FontVariantCaps::Small || fontVariantCaps == FontVariantCaps::Petite;
+
+ if (engageAllSmallCapsProcessing || engageSmallCapsProcessing)
</ins><span class="cx"> m_smallCapsBuffer.resize(m_end);
</span><span class="cx">
</span><span class="cx"> unsigned indexOfFontTransition = 0;
</span><span class="lines">@@ -312,74 +330,103 @@
</span><span class="cx"> const UChar* end = cp + m_end;
</span><span class="cx">
</span><span class="cx"> const Font* font;
</span><del>- bool isMissingGlyph;
</del><span class="cx"> const Font* nextFont;
</span><del>- bool nextIsMissingGlyph;
</del><ins>+ const Font* synthesizedFont = nullptr;
+ RefPtr<Font> smallSynthesizedFont = nullptr;
</ins><span class="cx">
</span><span class="cx"> unsigned markCount;
</span><del>- const UChar* sequenceStart = curr;
</del><span class="cx"> UChar32 baseCharacter;
</span><span class="cx"> if (!advanceByCombiningCharacterSequence(curr, end, baseCharacter, markCount))
</span><span class="cx"> return;
</span><span class="cx">
</span><del>- UChar uppercaseCharacter = 0;
</del><ins>+ nextFont = m_font.fontForCombiningCharacterSequence(cp, curr - cp);
</ins><span class="cx">
</span><del>- bool isSmallCaps;
- bool nextIsSmallCaps = m_font.isSmallCaps() && !(U_GET_GC_MASK(baseCharacter) & U_GC_M_MASK) && (uppercaseCharacter = u_toupper(baseCharacter)) != baseCharacter;
- ASSERT(uppercaseCharacter == 0 || u_toupper(baseCharacter) <= 0xFFFF);
</del><ins>+ bool isSmallCaps = false;
+ bool nextIsSmallCaps = false;
</ins><span class="cx">
</span><del>- if (nextIsSmallCaps) {
- m_smallCapsBuffer[sequenceStart - cp] = uppercaseCharacter;
- for (unsigned i = 0; i < markCount; ++i)
- m_smallCapsBuffer[sequenceStart - cp + i + 1] = sequenceStart[i + 1];
</del><ins>+ auto capitalizedBase = capitalized(baseCharacter);
+ if (nextFont && nextFont != Font::systemFallback() && (capitalizedBase || engageAllSmallCapsProcessing)
+ && !nextFont->variantCapsSupportsCharacterForSynthesis(fontVariantCaps, baseCharacter)) {
+ synthesizedFont = &nextFont->noSynthesizableFeaturesFont();
+ smallSynthesizedFont = synthesizedFont->smallCapsFont(m_font.fontDescription());
+ m_smallCapsBuffer[0] = capitalizedBase ? capitalizedBase.value() : cp[0];
+ for (unsigned i = 1; cp + i < curr; ++i)
+ m_smallCapsBuffer[i] = cp[i];
+ nextIsSmallCaps = true;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- nextIsMissingGlyph = false;
- nextFont = m_font.fontForCombiningCharacterSequence(sequenceStart, curr - sequenceStart, nextIsSmallCaps ? SmallCapsVariant : NormalVariant);
- if (!nextFont)
- nextIsMissingGlyph = true;
</del><ins>+ nextFont = m_font.fontForCombiningCharacterSequence(cp, curr - cp);
</ins><span class="cx">
</span><span class="cx"> while (curr < end) {
</span><span class="cx"> font = nextFont;
</span><del>- isMissingGlyph = nextIsMissingGlyph;
</del><span class="cx"> isSmallCaps = nextIsSmallCaps;
</span><del>- int index = curr - cp;
</del><ins>+ unsigned index = curr - cp;
</ins><span class="cx">
</span><span class="cx"> if (!advanceByCombiningCharacterSequence(curr, end, baseCharacter, markCount))
</span><span class="cx"> return;
</span><span class="cx">
</span><del>- if (m_font.isSmallCaps()) {
- ASSERT(u_toupper(baseCharacter) <= 0xFFFF);
- uppercaseCharacter = u_toupper(baseCharacter);
- nextIsSmallCaps = uppercaseCharacter != baseCharacter;
- if (nextIsSmallCaps) {
- m_smallCapsBuffer[index] = uppercaseCharacter;
</del><ins>+ if (synthesizedFont) {
+ if (auto capitalizedBase = capitalized(baseCharacter)) {
+ m_smallCapsBuffer[index] = capitalizedBase.value();
</ins><span class="cx"> for (unsigned i = 0; i < markCount; ++i)
</span><span class="cx"> m_smallCapsBuffer[index + i + 1] = cp[index + i + 1];
</span><ins>+ nextIsSmallCaps = true;
+ } else {
+ if (engageAllSmallCapsProcessing) {
+ for (unsigned i = 0; i < curr - cp - index; ++i)
+ m_smallCapsBuffer[index + i] = cp[index + i];
+ }
+ nextIsSmallCaps = engageAllSmallCapsProcessing;
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>- nextIsMissingGlyph = false;
</del><span class="cx"> if (baseCharacter == zeroWidthJoiner)
</span><span class="cx"> nextFont = font;
</span><del>- else {
- nextFont = m_font.fontForCombiningCharacterSequence(cp + index, curr - cp - index, nextIsSmallCaps ? SmallCapsVariant : NormalVariant);
- if (!nextFont)
- nextIsMissingGlyph = true;
</del><ins>+ else
+ nextFont = m_font.fontForCombiningCharacterSequence(cp + index, curr - cp - index);
+
+ capitalizedBase = capitalized(baseCharacter);
+ if (!synthesizedFont && nextFont && nextFont != Font::systemFallback() && (capitalizedBase || engageAllSmallCapsProcessing)
+ && !nextFont->variantCapsSupportsCharacterForSynthesis(fontVariantCaps, baseCharacter)) {
+ // Rather than synthesize each character individually, we should synthesize the entire "run" if any character requires synthesis.
+ synthesizedFont = &nextFont->noSynthesizableFeaturesFont();
+ smallSynthesizedFont = synthesizedFont->smallCapsFont(m_font.fontDescription());
+ nextIsSmallCaps = true;
+ curr = cp + indexOfFontTransition;
+ continue;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- if (nextFont != font || nextIsMissingGlyph != isMissingGlyph) {
- int itemStart = static_cast<int>(indexOfFontTransition);
- int itemLength = index - indexOfFontTransition;
- collectComplexTextRunsForCharacters((isSmallCaps ? m_smallCapsBuffer.data() : cp) + itemStart, itemLength, itemStart, !isMissingGlyph ? font : 0);
</del><ins>+ if (nextFont != font || nextIsSmallCaps != isSmallCaps) {
+ unsigned itemLength = index - indexOfFontTransition;
+ if (itemLength) {
+ unsigned itemStart = indexOfFontTransition;
+ if (synthesizedFont) {
+ if (isSmallCaps)
+ collectComplexTextRunsForCharacters(m_smallCapsBuffer.data() + itemStart, itemLength, itemStart, smallSynthesizedFont.get());
+ else
+ collectComplexTextRunsForCharacters(cp + itemStart, itemLength, itemStart, synthesizedFont);
+ } else
+ collectComplexTextRunsForCharacters(cp + itemStart, itemLength, itemStart, font);
+ if (nextFont != font) {
+ synthesizedFont = nullptr;
+ smallSynthesizedFont = nullptr;
+ nextIsSmallCaps = false;
+ }
+ }
</ins><span class="cx"> indexOfFontTransition = index;
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>- int itemLength = m_end - indexOfFontTransition;
</del><ins>+ unsigned itemLength = m_end - indexOfFontTransition;
</ins><span class="cx"> if (itemLength) {
</span><del>- int itemStart = indexOfFontTransition;
- collectComplexTextRunsForCharacters((nextIsSmallCaps ? m_smallCapsBuffer.data() : cp) + itemStart, itemLength, itemStart, !nextIsMissingGlyph ? nextFont : 0);
</del><ins>+ unsigned itemStart = indexOfFontTransition;
+ if (synthesizedFont) {
+ if (nextIsSmallCaps)
+ collectComplexTextRunsForCharacters(m_smallCapsBuffer.data() + itemStart, itemLength, itemStart, smallSynthesizedFont.get());
+ else
+ collectComplexTextRunsForCharacters(cp + itemStart, itemLength, itemStart, synthesizedFont);
+ } else
+ collectComplexTextRunsForCharacters(cp + itemStart, itemLength, itemStart, nextFont);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (!m_run.ltr())
</span></span></pre></div>
<a id="branchessafari601branchSourceWebCoreplatformspicocoaCoreTextSPIh"></a>
<div class="modfile"><h4>Modified: branches/safari-601-branch/Source/WebCore/platform/spi/cocoa/CoreTextSPI.h (194286 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/Source/WebCore/platform/spi/cocoa/CoreTextSPI.h        2015-12-18 21:03:53 UTC (rev 194286)
+++ branches/safari-601-branch/Source/WebCore/platform/spi/cocoa/CoreTextSPI.h        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -76,6 +76,7 @@
</span><span class="cx"> CTFontDescriptorRef CTFontDescriptorCreateForUIType(CTFontUIFontType, CGFloat size, CFStringRef language);
</span><span class="cx"> CTFontDescriptorRef CTFontDescriptorCreateWithTextStyle(CFStringRef style, CFStringRef size, CFStringRef language);
</span><span class="cx"> CTFontDescriptorRef CTFontDescriptorCreateCopyWithSymbolicTraits(CTFontDescriptorRef original, CTFontSymbolicTraits symTraitValue, CTFontSymbolicTraits symTraitMask);
</span><ins>+CFBitVectorRef CTFontCopyGlyphCoverageForFeature(CTFontRef, CFDictionaryRef feature);
</ins><span class="cx">
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx"> #if !USE(APPLE_INTERNAL_SDK)
</span></span></pre></div>
<a id="branchessafari601branchSourceWebCorerenderingRenderThemeIOSmm"></a>
<div class="modfile"><h4>Modified: branches/safari-601-branch/Source/WebCore/rendering/RenderThemeIOS.mm (194286 => 194287)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-601-branch/Source/WebCore/rendering/RenderThemeIOS.mm        2015-12-18 21:03:53 UTC (rev 194286)
+++ branches/safari-601-branch/Source/WebCore/rendering/RenderThemeIOS.mm        2015-12-18 21:11:15 UTC (rev 194287)
</span><span class="lines">@@ -1271,7 +1271,7 @@
</span><span class="cx">
</span><span class="cx"> ASSERT(fontDescriptor);
</span><span class="cx"> RetainPtr<CTFontRef> font = adoptCF(CTFontCreateWithFontDescriptor(fontDescriptor.get(), 0, nullptr));
</span><del>- font = applyFontFeatureSettings(font.get(), nullptr, nullptr, fontDescription.featureSettings(), fontDescription.variantSettings(), fontDescription.variantSettings());
</del><ins>+ font = applyFontFeatureSettings(font.get(), nullptr, nullptr, fontDescription.featureSettings(), fontDescription.variantSettings());
</ins><span class="cx"> fontDescription.setIsAbsoluteSize(true);
</span><span class="cx"> fontDescription.setOneFamily(textStyle);
</span><span class="cx"> fontDescription.setSpecifiedSize(CTFontGetSize(font.get()));
</span></span></pre>
</div>
</div>
</body>
</html>