Title: [194287] branches/safari-601-branch
Revision
194287
Author
[email protected]
Date
2015-12-18 13:11:15 -0800 (Fri, 18 Dec 2015)

Log Message

Merge r193894. rdar://problem/23769758

Modified Paths

Added Paths

Diff

Added: branches/safari-601-branch/LayoutTests/css3/font-variant-petite-caps-synthesis-coverage-expected.html (0 => 194287)


--- 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)
@@ -0,0 +1,59 @@
+<!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>

Added: branches/safari-601-branch/LayoutTests/css3/font-variant-petite-caps-synthesis-coverage.html (0 => 194287)


--- 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)
@@ -0,0 +1,60 @@
+<!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>
\ No newline at end of file

Added: branches/safari-601-branch/LayoutTests/css3/font-variant-petite-caps-synthesis-expected.html (0 => 194287)


--- 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)
@@ -0,0 +1,59 @@
+<!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>
\ No newline at end of file

Added: branches/safari-601-branch/LayoutTests/css3/font-variant-petite-caps-synthesis.html (0 => 194287)


--- 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)
@@ -0,0 +1,60 @@
+<!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>
\ No newline at end of file

Added: branches/safari-601-branch/LayoutTests/css3/font-variant-small-caps-synthesis-coverage-expected.html (0 => 194287)


--- 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)
@@ -0,0 +1,91 @@
+<!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>

Added: branches/safari-601-branch/LayoutTests/css3/font-variant-small-caps-synthesis-coverage.html (0 => 194287)


--- 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)
@@ -0,0 +1,98 @@
+<!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>
\ No newline at end of file

Added: branches/safari-601-branch/LayoutTests/css3/font-variant-small-caps-synthesis-expected.html (0 => 194287)


--- 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)
@@ -0,0 +1,91 @@
+<!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>
\ No newline at end of file

Added: branches/safari-601-branch/LayoutTests/css3/font-variant-small-caps-synthesis.html (0 => 194287)


--- 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)
@@ -0,0 +1,98 @@
+<!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>
\ No newline at end of file

Modified: branches/safari-601-branch/LayoutTests/platform/mac/TestExpectations (194286 => 194287)


--- 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)
@@ -1372,3 +1372,7 @@
 webkit.org/b/149774 css3/font-variant-all.html [ Pass Failure ImageOnlyFailure ] 
 webkit.org/b/149774 css3/font-variant-font-face-all.html [ Pass Failure ImageOnlyFailure ] 
 webkit.org/b/149774 css3/font-variant-font-face-override.html [ Pass Failure ImageOnlyFailure ] 
+
+# 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 ]

Modified: branches/safari-601-branch/LayoutTests/platform/mac/fast/writing-mode/broken-ideograph-small-caps-expected.txt (194286 => 194287)


--- 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)
@@ -13,8 +13,8 @@
               text run at (21,1) width 176: "\x{7B2C}\x{4E8C}\x{6BB5}\x{843D} Paragraph 2"
         RenderBlock {DIV} at (278,1) size 277x275 [bgcolor=#FFFFEE]
           RenderBlock {P} at (14,28) size 63x219 [bgcolor=#FFAAAA] [border: none (20px solid #FF8888) none (20px solid #FF8888)]
-            RenderText {#text} at (21,1) size 20x175
-              text run at (21,1) width 175: "\x{7B2C}\x{4E00}\x{6BB5}\x{843D} Paragraph 1"
+            RenderText {#text} at (21,1) size 20x156
+              text run at (21,1) width 156: "\x{7B2C}\x{4E00}\x{6BB5}\x{843D} Paragraph 1"
           RenderBlock {P} at (90,28) size 63x219 [bgcolor=#FFAAAA] [border: none (20px solid #FF8888) none (20px solid #FF8888)]
-            RenderText {#text} at (21,1) size 20x181
-              text run at (21,1) width 181: "\x{7B2C}\x{4E8C}\x{6BB5}\x{843D} Paragraph 2"
+            RenderText {#text} at (21,1) size 20x162
+              text run at (21,1) width 162: "\x{7B2C}\x{4E8C}\x{6BB5}\x{843D} Paragraph 2"

Modified: branches/safari-601-branch/Source/WebCore/ChangeLog (194286 => 194287)


--- 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)
@@ -1,3 +1,64 @@
+2015-12-17  Matthew Hanson  <[email protected]>
+
+        Merge r193894. rdar://problem/23769758
+
+    2015-12-10  Myles C. Maxfield  <[email protected]>
+
+            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:
+
 2015-12-18  Matthew Hanson  <[email protected]>
 
         Merge r192582. rdar://problem/23910980

Modified: branches/safari-601-branch/Source/WebCore/platform/graphics/Font.cpp (194286 => 194287)


--- 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)
@@ -307,6 +307,18 @@
     return m_derivedFontData->smallCaps;
 }
 
+#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
+
 PassRefPtr<Font> Font::emphasisMarkFont(const FontDescription& fontDescription) const
 {
     if (!m_derivedFontData)

Modified: branches/safari-601-branch/Source/WebCore/platform/graphics/Font.h (194286 => 194287)


--- 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)
@@ -35,6 +35,8 @@
 #if ENABLE(OPENTYPE_VERTICAL)
 #include "OpenTypeVerticalData.h"
 #endif
+#include <wtf/BitVector.h>
+#include <wtf/Optional.h>
 #include <wtf/TypeCasts.h>
 #include <wtf/text/StringHash.h>
 
@@ -104,9 +106,13 @@
     PassRefPtr<Font> emphasisMarkFont(const FontDescription&) const;
     PassRefPtr<Font> brokenIdeographFont() const;
     PassRefPtr<Font> nonSyntheticItalicFont() const;
+    const Font& noSynthesizableFeaturesFont() const;
 
     PassRefPtr<Font> variantFont(const FontDescription& description, FontVariant variant) const
     {
+#if PLATFORM(COCOA)
+        ASSERT(variant != SmallCapsVariant);
+#endif
         switch (variant) {
         case SmallCapsVariant:
             return smallCapsFont(description);
@@ -122,6 +128,8 @@
         return const_cast<Font*>(this);
     }
 
+    bool variantCapsSupportsCharacterForSynthesis(FontVariantCaps, UChar32) const;
+
     PassRefPtr<Font> verticalRightOrientationFont() const;
     PassRefPtr<Font> uprightOrientationFont() const;
 
@@ -194,7 +202,12 @@
 #endif
 #if PLATFORM(COCOA)
     CFDictionaryRef getCFStringAttributes(bool enableKerning, FontOrientation) const;
+
     bool hasCustomTracking() const { return isSystemFont(); }
+    const BitVector& glyphsSupportedBySmallCaps() const;
+    const BitVector& glyphsSupportedByAllSmallCaps() const;
+    const BitVector& glyphsSupportedByPetiteCaps() const;
+    const BitVector& glyphsSupportedByAllPetiteCaps() const;
 #endif
 
 #if PLATFORM(COCOA) || USE(HARFBUZZ)
@@ -229,6 +242,7 @@
 
     void initCharWidths();
 
+    RefPtr<Font> createFontWithoutSynthesizableFeatures() const;
     PassRefPtr<Font> createScaledFont(const FontDescription&, float scaleFactor) const;
     PassRefPtr<Font> platformCreateScaledFont(const FontDescription&, float scaleFactor) const;
 
@@ -274,6 +288,7 @@
 
         bool forCustomFont;
         RefPtr<Font> smallCaps;
+        RefPtr<Font> noSynthesizableFeatures;
         RefPtr<Font> emphasisMark;
         RefPtr<Font> brokenIdeograph;
         RefPtr<Font> verticalRightOrientation;
@@ -292,6 +307,10 @@
 
 #if PLATFORM(COCOA)
     mutable HashMap<unsigned, RetainPtr<CFDictionaryRef>> m_CFStringAttributes;
+    mutable Optional<BitVector> m_glyphsSupportedBySmallCaps;
+    mutable Optional<BitVector> m_glyphsSupportedByAllSmallCaps;
+    mutable Optional<BitVector> m_glyphsSupportedByPetiteCaps;
+    mutable Optional<BitVector> m_glyphsSupportedByAllPetiteCaps;
 #endif
 
 #if PLATFORM(COCOA) || USE(HARFBUZZ)

Modified: branches/safari-601-branch/Source/WebCore/platform/graphics/FontCascade.h (194286 => 194287)


--- 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)
@@ -191,7 +191,7 @@
     GlyphData glyphDataForCharacter(UChar32, bool mirror, FontVariant = AutoVariant) const;
     
 #if PLATFORM(COCOA)
-    const Font* fontForCombiningCharacterSequence(const UChar*, size_t length, FontVariant) const;
+    const Font* fontForCombiningCharacterSequence(const UChar*, size_t length) const;
 #endif
 
     static bool isCJKIdeograph(UChar32);

Modified: branches/safari-601-branch/Source/WebCore/platform/graphics/FontCascadeFonts.cpp (194286 => 194287)


--- 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)
@@ -296,15 +296,15 @@
         if (fontRanges.isNull())
             break;
         GlyphData data = ""
-        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;
+        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;
 
-            return variantFont->glyphDataForCharacter(c);
-        }
+        return variantFont->glyphDataForCharacter(c);
     }
 
     return glyphDataForSystemFallback(c, description, variant);
@@ -317,23 +317,23 @@
         if (fontRanges.isNull())
             break;
         GlyphData data = ""
-        if (data.font) {
-            if (data.font->platformData().orientation() == Vertical && !data.font->isTextOrientationFallback()) {
-                if (!FontCascade::isCJKIdeographOrSymbol(c))
-                    return glyphDataForNonCJKCharacterWithGlyphOrientation(c, description.nonCJKGlyphOrientation(), data);
+        if (!data.font)
+            continue;
+        if (data.font->platformData().orientation() == Vertical && !data.font->isTextOrientationFallback()) {
+            if (!FontCascade::isCJKIdeographOrSymbol(c))
+                return glyphDataForNonCJKCharacterWithGlyphOrientation(c, description.nonCJKGlyphOrientation(), data);
 
-                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);
-                }
+            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);
+            }
 #if PLATFORM(COCOA) || USE(CAIRO)
-                if (data.font->platformData().syntheticOblique())
-                    return glyphDataForCJKCharacterWithoutSyntheticItalic(c, data);
+            if (data.font->platformData().syntheticOblique())
+                return glyphDataForCJKCharacterWithoutSyntheticItalic(c, data);
 #endif
-            }
-            return data;
         }
+        return data;
     }
 
     return glyphDataForSystemFallback(c, description, NormalVariant);

Modified: branches/safari-601-branch/Source/WebCore/platform/graphics/FontDescription.h (194286 => 194287)


--- 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)
@@ -204,7 +204,7 @@
     {
         return familiesEqualForTextAutoSizing(other)
             && m_specifiedSize == other.m_specifiedSize
-            && variantSettings() == other.other.variantSettings()
+            && variantSettings() == other.variantSettings()
             && m_isAbsoluteSize == other.m_isAbsoluteSize;
     }
 #endif

Modified: branches/safari-601-branch/Source/WebCore/platform/graphics/cocoa/FontCascadeCocoa.mm (194286 => 194287)


--- 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)
@@ -756,13 +756,13 @@
     return controller.offsetForPosition(x, includePartialGlyphs);
 }
 
-const Font* FontCascade::fontForCombiningCharacterSequence(const UChar* characters, size_t length, FontVariant variant) const
+const Font* FontCascade::fontForCombiningCharacterSequence(const UChar* characters, size_t length) const
 {
     UChar32 baseCharacter;
     size_t baseCharacterLength = 0;
     U16_NEXT(characters, baseCharacterLength, length, baseCharacter);
 
-    GlyphData baseCharacterGlyphData = glyphDataForCharacter(baseCharacter, false, variant);
+    GlyphData baseCharacterGlyphData = glyphDataForCharacter(baseCharacter, false, NormalVariant);
 
     if (!baseCharacterGlyphData.glyph)
         return 0;
@@ -780,26 +780,20 @@
         if (baseCharacter >= 0x0600 && baseCharacter <= 0x06ff && font->shouldNotBeUsedForArabic())
             continue;
 #endif
-        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;
-                }
+        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;
             }
-        } else {
-            if (const Font* variantFont = font->variantFont(m_fontDescription, variant).get())
-                font = variantFont;
         }
 
         if (font == baseCharacterGlyphData.font)

Modified: branches/safari-601-branch/Source/WebCore/platform/graphics/cocoa/FontCocoa.mm (194286 => 194287)


--- 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)
@@ -40,6 +40,7 @@
 #import <float.h>
 #import <unicode/uchar.h>
 #import <wtf/Assertions.h>
+#import <wtf/NeverDestroyed.h>
 #import <wtf/RetainPtr.h>
 #import <wtf/StdLibExtras.h>
 
@@ -314,64 +315,271 @@
 {
 }
 
-PassRefPtr<Font> Font::platformCreateScaledFont(const FontDescription&, float scaleFactor) const
+bool Font::variantCapsSupportsCharacterForSynthesis(FontVariantCaps fontVariantCaps, UChar32 character) const
 {
-#if !CORETEXT_WEB_FONTS
-    if (isCustomFont()) {
-        FontPlatformData scaledFontData(m_platformData);
-        scaledFontData.m_size = scaledFontData.m_size * scaleFactor;
-        return Font::create(scaledFontData, true, false);
+#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);
     }
+    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;
+    }
 #endif
+}
 
-    float size = m_platformData.size() * scaleFactor;
+#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));
+}
 
-#if USE(APPKIT)
-    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+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));
+}
 
-    FontPlatformData scaledFontData(reinterpret_cast<CTFontRef>([[NSFontManager sharedFontManager] convertFont:m_platformData.nsFont() toSize:size]), size, false, false, m_platformData.orientation());
+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;
+    }
+}
 
-    if (scaledFontData.font()) {
-        NSFontManager *fontManager = [NSFontManager sharedFontManager];
-        NSFontTraitMask fontTraits = [fontManager traitsOfFont:m_platformData.nsFont()];
+static void injectOpenTypeCoverage(CFStringRef feature, CTFontRef font, BitVector& result)
+{
+    RetainPtr<CFBitVectorRef> source = adoptCF(CTFontCopyGlyphCoverageForFeature(font, smallCapsOpenTypeDictionary(feature, 1).get()));
+    unionBitVectors(result, source.get());
+}
 
-        if (m_platformData.m_syntheticBold)
-            fontTraits |= NSBoldFontMask;
-        if (m_platformData.m_syntheticOblique)
-            fontTraits |= NSItalicFontMask;
+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());
+}
 
-        NSFontTraitMask scaledFontTraits = [fontManager traitsOfFont:scaledFontData.nsFont()];
-        scaledFontData.m_syntheticBold = (fontTraits & NSBoldFontMask) && !(scaledFontTraits & NSBoldFontMask);
-        scaledFontData.m_syntheticOblique = (fontTraits & NSItalicFontMask) && !(scaledFontTraits & NSItalicFontMask);
+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();
+}
 
-        return Font::create(scaledFontData);
+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());
     }
-    END_BLOCK_OBJC_EXCEPTIONS;
+    return m_glyphsSupportedByAllSmallCaps.value();
+}
 
-    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());
+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();
+}
 
-    if (scaledFontData.font()) {
-        if (m_platformData.m_syntheticBold)
-            fontTraits |= kCTFontBoldTrait;
-        if (m_platformData.m_syntheticOblique)
-            fontTraits |= kCTFontItalicTrait;
+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
 
-        CTFontSymbolicTraits scaledFontTraits = CTFontGetSymbolicTraits(scaledFontData.font());
-        scaledFontData.m_syntheticBold = (fontTraits & kCTFontBoldTrait) && !(scaledFontTraits & kCTFontTraitBold);
-        scaledFontData.m_syntheticOblique = (fontTraits & kCTFontItalicTrait) && !(scaledFontTraits & kCTFontTraitItalic);
+static RefPtr<Font> createDerivativeFont(CTFontRef font, float size, FontOrientation orientation, CTFontSymbolicTraits fontTraits, bool syntheticBold, bool syntheticItalic)
+{
+    if (!font)
+        return nullptr;
 
-        return Font::create(scaledFontData);
+    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));
+        }
     }
+    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;
+}
 
-    return nullptr;
-#endif
+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()));
 }
 
+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);
+}
+
 void Font::determinePitch()
 {
 #if USE(APPKIT)

Modified: branches/safari-601-branch/Source/WebCore/platform/graphics/ios/FontCacheIOS.mm (194286 => 194287)


--- 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)
@@ -85,7 +85,7 @@
     if (!substituteFont)
         return nullptr;
 
-    substituteFont = applyFontFeatureSettings(substituteFont.get(), description.featureSettings(), description.variantSettings());
+    substituteFont = applyFontFeatureSettings(substituteFont.get(), nullptr, nullptr, description.featureSettings(), description.variantSettings());
 
     CTFontSymbolicTraits originalTraits = CTFontGetSymbolicTraits(ctFont);
     CTFontSymbolicTraits actualTraits = 0;
@@ -700,7 +700,7 @@
     if (!ctFont)
         return nullptr;
 
-    ctFont = applyFontFeatureSettings(ctFont.get(), fontDescription.featureSettings(), fontDescription.variantSettings());
+    ctFont = applyFontFeatureSettings(ctFont.get(), nullptr, nullptr, fontDescription.featureSettings(), fontDescription.variantSettings());
 
     CTFontSymbolicTraits actualTraits = 0;
     if (isFontWeightBold(fontDescription.weight()) || fontDescription.italic())

Modified: branches/safari-601-branch/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp (194286 => 194287)


--- 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)
@@ -32,6 +32,7 @@
 #include "RenderText.h"
 #include "TextBreakIterator.h"
 #include "TextRun.h"
+#include <wtf/Optional.h>
 #include <wtf/StdLibExtras.h>
 #include <wtf/unicode/CharacterNames.h>
 
@@ -289,6 +290,19 @@
     return true;
 }
 
+// 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;
+}
+
 void ComplexTextController::collectComplexTextRuns()
 {
     if (!m_end)
@@ -304,7 +318,11 @@
     } else
         cp = m_run.characters16();
 
-    if (m_font.isSmallCaps())
+    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)
         m_smallCapsBuffer.resize(m_end);
 
     unsigned indexOfFontTransition = 0;
@@ -312,74 +330,103 @@
     const UChar* end = cp + m_end;
 
     const Font* font;
-    bool isMissingGlyph;
     const Font* nextFont;
-    bool nextIsMissingGlyph;
+    const Font* synthesizedFont = nullptr;
+    RefPtr<Font> smallSynthesizedFont = nullptr;
 
     unsigned markCount;
-    const UChar* sequenceStart = curr;
     UChar32 baseCharacter;
     if (!advanceByCombiningCharacterSequence(curr, end, baseCharacter, markCount))
         return;
 
-    UChar uppercaseCharacter = 0;
+    nextFont = m_font.fontForCombiningCharacterSequence(cp, curr - cp);
 
-    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);
+    bool isSmallCaps = false;
+    bool nextIsSmallCaps = false;
 
-    if (nextIsSmallCaps) {
-        m_smallCapsBuffer[sequenceStart - cp] = uppercaseCharacter;
-        for (unsigned i = 0; i < markCount; ++i)
-            m_smallCapsBuffer[sequenceStart - cp + i + 1] = sequenceStart[i + 1];
+    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;
     }
 
-    nextIsMissingGlyph = false;
-    nextFont = m_font.fontForCombiningCharacterSequence(sequenceStart, curr - sequenceStart, nextIsSmallCaps ? SmallCapsVariant : NormalVariant);
-    if (!nextFont)
-        nextIsMissingGlyph = true;
+    nextFont = m_font.fontForCombiningCharacterSequence(cp, curr - cp);
 
     while (curr < end) {
         font = nextFont;
-        isMissingGlyph = nextIsMissingGlyph;
         isSmallCaps = nextIsSmallCaps;
-        int index = curr - cp;
+        unsigned index = curr - cp;
 
         if (!advanceByCombiningCharacterSequence(curr, end, baseCharacter, markCount))
             return;
 
-        if (m_font.isSmallCaps()) {
-            ASSERT(u_toupper(baseCharacter) <= 0xFFFF);
-            uppercaseCharacter = u_toupper(baseCharacter);
-            nextIsSmallCaps = uppercaseCharacter != baseCharacter;
-            if (nextIsSmallCaps) {
-                m_smallCapsBuffer[index] = uppercaseCharacter;
+        if (synthesizedFont) {
+            if (auto capitalizedBase = capitalized(baseCharacter)) {
+                m_smallCapsBuffer[index] = capitalizedBase.value();
                 for (unsigned i = 0; i < markCount; ++i)
                     m_smallCapsBuffer[index + i + 1] = cp[index + i + 1];
+                nextIsSmallCaps = true;
+            } else {
+                if (engageAllSmallCapsProcessing) {
+                    for (unsigned i = 0; i < curr - cp - index; ++i)
+                        m_smallCapsBuffer[index + i] = cp[index + i];
+                }
+                nextIsSmallCaps = engageAllSmallCapsProcessing;
             }
         }
 
-        nextIsMissingGlyph = false;
         if (baseCharacter == zeroWidthJoiner)
             nextFont = font;
-        else {
-            nextFont = m_font.fontForCombiningCharacterSequence(cp + index, curr - cp - index, nextIsSmallCaps ? SmallCapsVariant : NormalVariant);
-            if (!nextFont)
-                nextIsMissingGlyph = true;
+        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;
         }
 
-        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);
+        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;
+                }
+            }
             indexOfFontTransition = index;
         }
     }
 
-    int itemLength = m_end - indexOfFontTransition;
+    unsigned itemLength = m_end - indexOfFontTransition;
     if (itemLength) {
-        int itemStart = indexOfFontTransition;
-        collectComplexTextRunsForCharacters((nextIsSmallCaps ? m_smallCapsBuffer.data() : cp) + itemStart, itemLength, itemStart, !nextIsMissingGlyph ? nextFont : 0);
+        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);
     }
 
     if (!m_run.ltr())

Modified: branches/safari-601-branch/Source/WebCore/platform/spi/cocoa/CoreTextSPI.h (194286 => 194287)


--- 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)
@@ -76,6 +76,7 @@
 CTFontDescriptorRef CTFontDescriptorCreateForUIType(CTFontUIFontType, CGFloat size, CFStringRef language);
 CTFontDescriptorRef CTFontDescriptorCreateWithTextStyle(CFStringRef style, CFStringRef size, CFStringRef language);
 CTFontDescriptorRef CTFontDescriptorCreateCopyWithSymbolicTraits(CTFontDescriptorRef original, CTFontSymbolicTraits symTraitValue, CTFontSymbolicTraits symTraitMask);
+CFBitVectorRef CTFontCopyGlyphCoverageForFeature(CTFontRef, CFDictionaryRef feature);
 
 #if PLATFORM(COCOA)
 #if !USE(APPLE_INTERNAL_SDK)

Modified: branches/safari-601-branch/Source/WebCore/rendering/RenderThemeIOS.mm (194286 => 194287)


--- 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)
@@ -1271,7 +1271,7 @@
 
     ASSERT(fontDescriptor);
     RetainPtr<CTFontRef> font = adoptCF(CTFontCreateWithFontDescriptor(fontDescriptor.get(), 0, nullptr));
-    font = applyFontFeatureSettings(font.get(), nullptr, nullptr, fontDescription.featureSettings(), fontDescription.variantSettings(), fontDescription.variantSettings());
+    font = applyFontFeatureSettings(font.get(), nullptr, nullptr, fontDescription.featureSettings(), fontDescription.variantSettings());
     fontDescription.setIsAbsoluteSize(true);
     fontDescription.setOneFamily(textStyle);
     fontDescription.setSpecifiedSize(CTFontGetSize(font.get()));
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to