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()));