summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/css/css-fonts/variations
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/tests/css/css-fonts/variations
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/css/css-fonts/variations')
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/META.yml5
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/at-font-face-descriptors.html174
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/at-font-face-font-matching.html195
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-descriptor-range-reversed-ref.html39
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-descriptor-range-reversed.html56
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-opentype-collections.html41
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-parse-numeric-stretch-style-weight.html146
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-shorthand.html69
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-slant-1-ref.html20
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-slant-1.html23
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-slant-2-ref.html18
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-slant-2a.html22
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-slant-2b.html23
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-stretch.html84
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-style-interpolation.html89
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-style-parsing.html60
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-variation-settings-inherit.html48
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-weight-interpolation.html84
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-weight-lighter-bolder.html58
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-weight-matching-installed-fonts.html114
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-weight-matching.html135
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-weight-metrics-ref.html29
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-weight-metrics.html45
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/font-weight-parsing.html53
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/FontStyleTest-slnt-VF.woff2bin0 -> 20348 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/FontStyleTest-slnt_backslant-VF.woff2bin0 -> 25612 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/Inter.var.subset.ttfbin0 -> 5080 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/ahem.ttcbin0 -> 16028 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-100-kerned.ttfbin0 -> 9044 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-1479-w1-kerned.ttfbin0 -> 9296 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-1479-w4-kerned.ttfbin0 -> 9232 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-1479-w7-kerned.ttfbin0 -> 9240 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-1479-w9-kerned.ttfbin0 -> 9240 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-15-w1-kerned.ttfbin0 -> 9252 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-15-w5-kerned.ttfbin0 -> 9200 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-200-kerned.ttfbin0 -> 9044 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-24-w2-kerned.ttfbin0 -> 9200 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-24-w4-kerned.ttfbin0 -> 9188 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-2569-w2-kerned.ttfbin0 -> 9240 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-2569-w5-kerned.ttfbin0 -> 9240 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-2569-w6-kerned.ttfbin0 -> 9240 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-2569-w9-kerned.ttfbin0 -> 9240 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-258-w2-kerned.ttfbin0 -> 9220 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-258-w5-kerned.ttfbin0 -> 9220 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-258-w8-kerned.ttfbin0 -> 9220 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-300-kerned.ttfbin0 -> 9044 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-3589-w3-kerned.ttfbin0 -> 9240 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-3589-w5-kerned.ttfbin0 -> 9240 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-3589-w8-kerned.ttfbin0 -> 9240 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-3589-w9-kerned.ttfbin0 -> 9240 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-400-kerned.ttfbin0 -> 9044 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-47-w4-kerned.ttfbin0 -> 9188 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-47-w7-kerned.ttfbin0 -> 9200 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-500-kerned.ttfbin0 -> 9044 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-600-kerned.ttfbin0 -> 9044 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-700-kerned.ttfbin0 -> 9044 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-800-kerned.ttfbin0 -> 9044 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-900-kerned.ttfbin0 -> 9044 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w1-kerned.ttfbin0 -> 9272 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w2-kerned.ttfbin0 -> 9220 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w3-kerned.ttfbin0 -> 9220 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w4-kerned.ttfbin0 -> 9212 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w5-kerned.ttfbin0 -> 9220 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w6-kerned.ttfbin0 -> 9220 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w7-kerned.ttfbin0 -> 9220 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w8-kerned.ttfbin0 -> 9220 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w9-kerned.ttfbin0 -> 9220 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/resources/variabletest_box.ttfbin0 -> 4032 bytes
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/slnt-backslant-variable-ref.html30
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/slnt-backslant-variable.html41
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/slnt-variable-ref.html25
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/slnt-variable.html36
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/variable-box-font-ref.html20
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/variable-box-font.html31
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/variable-gpos-m2b-ref.html21
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/variable-gpos-m2b.html45
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/variable-gsub-ref.html21
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/variable-gsub.html34
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/variable-opsz-ref.html27
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/variable-opsz-size-adjust-ref.html31
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/variable-opsz-size-adjust.html39
-rw-r--r--testing/web-platform/tests/css/css-fonts/variations/variable-opsz.html34
82 files changed, 2065 insertions, 0 deletions
diff --git a/testing/web-platform/tests/css/css-fonts/variations/META.yml b/testing/web-platform/tests/css/css-fonts/variations/META.yml
new file mode 100644
index 0000000000..53487a6d85
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/META.yml
@@ -0,0 +1,5 @@
+suggested_reviewers:
+ - drott
+ - fantasai
+ - litherum
+ - svgeesus
diff --git a/testing/web-platform/tests/css/css-fonts/variations/at-font-face-descriptors.html b/testing/web-platform/tests/css/css-fonts/variations/at-font-face-descriptors.html
new file mode 100644
index 0000000000..1935422d7c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/at-font-face-descriptors.html
@@ -0,0 +1,174 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Testing @font-face descriptor values introduced in CSS Fonts level 4</title>
+ <link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-face-rule" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <style id="testStyle">
+ @font-face { font-family: Test; src: local('Courier New'), local('Courier'); }
+ </style>
+</head>
+<body>
+ <div>@font-face descriptor tests</div>
+ <script>
+
+ function updateFontFaceRule(descriptorName, descriptorValue) {
+ let testRule = document.getElementById("testStyle").sheet.cssRules[0];
+
+ testRule.style.fontWeight = "normal";
+ testRule.style.fontStyle = "normal";
+ testRule.style.fontStretch = "normal";
+ assert_equals(testRule.style.fontWeight, "normal", "Can't clear @font-face.");
+ assert_equals(testRule.style.fontStyle, "normal", "Can't clear @font-face.");
+ assert_equals(testRule.style.fontStretch, "normal", "Can't clear @font-face.");
+
+ testRule.style.fontWeight = "";
+ testRule.style.fontStyle = "";
+ testRule.style.fontStretch = "";
+ assert_true(!testRule.style.fontWeight, "", "Can't clear @font-face.");
+ assert_true(!testRule.style.fontStyle, "", "Can't clear @font-face.");
+ assert_true(!testRule.style.fontStretch, "", "Can't clear @font-face.");
+
+ testRule.style[descriptorName] = descriptorValue;
+
+ return testRule;
+ }
+
+ function testDescriptor(descriptorName, testCases) {
+ var propertyName = { 'font-weight':'fontWeight', 'font-stretch':'fontStretch', 'font-style':'fontStyle' }[descriptorName];
+ testCases.forEach(function (testCase) {
+ test(() => {
+ let rule = updateFontFaceRule(descriptorName, testCase.value);
+
+ if (testCase.isValid) {
+ assert_not_equals(rule.style[propertyName], "", "Valid value should be accepted.");
+
+ let expectedValue = (testCase.expectedValue) ? testCase.expectedValue : testCase.value;
+ assert_equals(rule.style[propertyName], expectedValue, "Unexpected resulting value.");
+ }
+ else {
+ assert_equals(rule.style[propertyName], "", "No properties should be set.");
+ }
+ }, descriptorName + (testCase.isValid ? "(valid): " : "(invalid): ") + testCase.description + ": " + testCase.value);
+
+ });
+ }
+
+ testDescriptor("font-weight", [
+ // Single value, keyword
+ { value: "normal", isValid: true, description: "'normal' keyword" },
+ { value: "bold", isValid: true, description: "'bold' keyword" },
+ { value: "auto", isValid: true, description: "'auto' keyword inside @font-face" },
+ { value: "lighter", isValid: false, description: "'lighter' keyword inside @font-face" },
+ { value: "bolder", isValid: false, description: "'bolder' keyword inside @font-face" },
+ { value: "bold a", isValid: false, description: "Extra content after keyword" },
+
+ // Single value, number
+ { value: "401", isValid: true, description: "Values that are not multiple of 100 should be parsed successfully" },
+ { value: "400.1", isValid: true, description: "Non-integer values should be parsed successfully" },
+ { value: "1", isValid: true, description: "Minimum allowed value should be parsed successfully" },
+ { value: "0.999", isValid: false, description: "Values below minimum should be rejected" },
+ { value: "-100", isValid: false, description: "Values below zero should be rejected" },
+ { value: "1000", isValid: true, description: "Maximum allowed value should be parsed successfully" },
+ { value: "1000.001", isValid: false, description: "Values above maximum should be rejected" },
+ { value: "100 a", isValid: false, description: "Extra content after value" },
+
+ // Single value, calc
+ { value: "calc(100.5)", isValid: true, expectedValue: "100.5", description: "Simple calc value" },
+ { value: "calc(1001)", isValid: true, description: "Out-of-range simple calc value (should be clamped)" },
+ { value: "calc(100.5*3 + 50.5)", isValid: true, expectedValue: "352", description: "Valid calc expression" },
+ { value: "calc(100.5*3 + 800)", isValid: true, description: "Valid calc expression with out-of-range value (should be clamped)" },
+ { value: "calc(100.5px + 50.5px)", isValid: false, description: "Valid calc expression with units" },
+
+ // Value range
+ { value: "100 900", isValid: true, description: "Simple range" },
+ { value: "500 500", isValid: true, expectedValue: "500", description: "Simple range with equal upper and lower bounds" },
+ { value: "0.9 100", isValid: false, description: "Lower bound out of range" },
+ { value: "100 1001", isValid: false, description: "Upper bound out of range" },
+ { value: "calc(100 + 100) 400", isValid: true, expectedValue: "200 400", description: "Lower bound calc()" },
+ { value: "200 calc(200 + 200)", isValid: true, expectedValue: "200 400", description: "Upper bound calc()" },
+ { value: "calc(100 + 100) calc(200 + 200)", isValid: true, expectedValue: "200 400", description: "Both bounds are calc()" },
+ { value: "400 200", isValid: true, expectedValue: "400 200", description: "Bounds out of order are valid" },
+ { value: "100 200 300", isValid: false, description: "Extra content after upper bound" },
+ ]);
+
+ testDescriptor("font-stretch", [
+ // Single value, keyword
+ { value: "ultra-condensed", isValid: true, description: "'ultra-condensed' keyword" },
+ { value: "extra-condensed", isValid: true, description: "'extra-condensed' keyword" },
+ { value: "condensed", isValid: true, description: "'condensed' keyword" },
+ { value: "semi-condensed", isValid: true, description: "'semi-condensed' keyword" },
+ { value: "normal", isValid: true, description: "'normal' keyword" },
+ { value: "semi-expanded", isValid: true, description: "'semi-expanded' keyword" },
+ { value: "expanded", isValid: true, description: "'expanded' keyword" },
+ { value: "extra-expanded", isValid: true, description: "'extra-expanded' keyword" },
+ { value: "ultra-expanded", isValid: true, description: "'ultra-expanded' keyword" },
+ { value: "expanded a", isValid: false, description: "Extra content after value" },
+ { value: "auto", isValid: true, description: "'auto' keyword inside @font-face" },
+
+ // Single value, number
+ { value: "1%", isValid: true, description:"Legal percentage" },
+ { value: "10.5%", isValid: true, description:"Legal percentage" },
+ { value: "100%", isValid: true, description:"Legal percentage" },
+ { value: "1000%", isValid: true, description:"Legal percentage" },
+ { value: "100", isValid: false, description:"Only percentages, not numbers allowed" },
+ { value: "-1%", isValid: false, description:"Negative values are illegal" },
+ { value: "0%", isValid: true, description:"Zero is legal" },
+ { value: "100% a", isValid: false, description:"Extra content after value" },
+
+ // Single value, calc
+ { value: "calc(200.5%)", isValid: true, expectedValue: "200.5%", description: "Simple calc value" },
+ { value: "calc(50%*2 - 20%)", isValid: true, expectedValue: "80%", description: "Valid calc expression" },
+ { value: "calc(-100%)", isValid: true, description: "Negative calc value (to be clamped)" },
+ { value: "calc(50% - 50%*2)", isValid: true, expectedValue: "calc(-50%)", description: "Negative calc expression (to be clamped)" },
+ { value: "calc(100)", isValid: false, description: "Unit-less calc value" },
+ { value: "calc(100px)", isValid: false, description: "Calc value with units" },
+
+ // Value range
+ { value: "100% 200%", isValid: true, description: "Simple range" },
+ { value: "100% 100%", isValid: true, expectedValue: "100%", description: "Simple range with equal upper and lower bounds" },
+ { value: "-100% 100%", isValid: false, description: "Lower bound out of range" },
+ { value: "calc(10% + 10%) 30%", isValid: true, expectedValue: "20% 30%", description: "Lower bound calc()" },
+ { value: "10% calc(10% + 10%)", isValid: true, expectedValue: "10% 20%", description: "Upper bound calc()" },
+ { value: "calc(10% + 10%) calc(20% + 20%)", isValid: true, expectedValue: "20% 40%", description: "Both bounds are calc()" },
+ { value: "200% 100%", isValid: true, expectedValue: "200% 100%", description: "Bounds out of order" },
+ { value: "100% 200% 300%", isValid: false, description: "Extra content after upper bound" },
+ ]);
+
+ testDescriptor("font-style", [
+ // Single value, keyword
+ { value: "normal", isValid: true, description: "'normal' keyword" },
+ { value: "italic", isValid: true, description: "'italic' keyword" },
+ { value: "oblique", isValid: true, description: "'oblique' keyword" },
+ { value: "auto", isValid: true, description: "'auto' keyword inside @font-face" },
+
+ // Single value
+ { value: "italic 20deg", isValid: false, description: "'italic' followed by angle" },
+ { value: "italic a", isValid: false, description: "Extra content after keyword" },
+ { value: "oblique 0deg", isValid: true, description: "'oblique' followed by zero degrees" },
+ { value: "oblique 20deg", isValid: true, description: "'oblique' followed by former default 20deg angle" },
+ { value: "oblique 90deg", isValid: true, description: "'oblique' followed by maxumum 90 degree angle" },
+ { value: "oblique -90deg", isValid: true, description: "'oblique' followed by minimum -90 degree angle" },
+ { value: "oblique calc(91deg)", isValid: true, description: "'oblique' followed by calc with out of range value (should be clamped)" },
+ { value: "oblique calc(-91deg)", isValid: true, description: "'oblique' followed by calc with out of range value (should be clamped)" },
+ { value: "oblique 0rad", isValid: true, expectedValue: "oblique 0deg", description: "'oblique' followed by angle in radians" },
+ { value: "oblique 20", isValid: false, description: "'oblique' followed by unit-less number" },
+ { value: "oblique 20px", isValid: false, description: "'oblique' followed by non-angle" },
+ { value: "oblique a", isValid: false, description: "'oblique' followed by non-number" },
+ { value: "oblique -", isValid: false, description: "'oblique' followed by isolated minus" },
+ { value: "oblique - 20deg", isValid: false, description: "'oblique' followed by minus and angle separated by space" },
+ { value: "oblique -a", isValid: false, description: "'oblique' followed by minus and non-number" },
+
+ // Value range
+ { value: "oblique 10deg 20deg", isValid: true, description: "Simple range" },
+ { value: "oblique 10deg 10deg", isValid: true, expectedValue: "oblique 10deg", description: "Simple range with equal upper and lower bounds" },
+ { value: "oblique 20deg 20deg", isValid: true, description: "Simple range with former default angle for both bounds" },
+ { value: "oblique 20deg 10deg", isValid: true, expectedValue: "oblique 20deg 10deg", description: "Bounds out of order" },
+ { value: "oblique -100deg 20deg", isValid: false, description: "Lower bound out of range" },
+ { value: "oblique 20deg 100deg", isValid: false, description: "Upper bound out of range" },
+ { value: "oblique 10deg 20deg 30deg", isValid: false, description: "Extra content after upper bound" },
+ ]);
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/at-font-face-font-matching.html b/testing/web-platform/tests/css/css-fonts/variations/at-font-face-font-matching.html
new file mode 100644
index 0000000000..e56334f2da
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/at-font-face-font-matching.html
@@ -0,0 +1,195 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Testing @font-face font matching logic introduced in CSS Fonts level 4</title>
+ <link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-matching-algorithm" />
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <style>
+ .test
+ {
+ float:left;
+ border:1px solid red;
+ font-size:24pt;
+ white-space: nowrap;
+ clear:both;
+ }
+
+ @font-face { font-family: W100; src: url('./resources/csstest-weights-100-kerned.ttf'); }
+ @font-face { font-family: W200; src: url('./resources/csstest-weights-200-kerned.ttf'); }
+ @font-face { font-family: W300; src: url('./resources/csstest-weights-300-kerned.ttf'); }
+
+
+ @font-face { font-family: descriptorPriorityTest; src: url('./resources/csstest-weights-100-kerned.ttf'); font-stretch : 125%; }
+ @font-face { font-family: descriptorPriorityTest; src: url('./resources/csstest-weights-200-kerned.ttf'); font-style: italic; }
+ @font-face { font-family: descriptorPriorityTest; src: url('./resources/csstest-weights-300-kerned.ttf'); font-weight: 350; }
+ </style>
+ <style id="dynamicStyles">
+ </style>
+</head>
+<body>
+
+ <span style="position: absolute; top: -100vh;">
+ <span style="font-family: 'W100';">A</span>
+ <span style="font-family: 'W200';">A</span>
+ <span style="font-family: 'W300';">A</span>
+ <span style="font-family: 'descriptorPriorityTest'; font-stretch: 125%;">A</span>
+ <span style="font-family: 'descriptorPriorityTest'; font-style: italic;">A</span>
+ <span style="font-family: 'descriptorPriorityTest'; font-weight: 350;">A</span>
+ </span>
+
+ <div id="master" class="test">A1 A2 A2 A3 A3 A3</div>
+ <div id="test" class="test">A1 A2 A2 A3 A3 A3</div>
+ <div style="clear:both"></div>
+ <script>
+
+ // wait for the fonts to load
+ // -- this should not be necessary if the fonts are installed as required
+ // -- but if they are not, the test is otherwise unstable
+ var once_fonts_are_ready = (document.fonts ? document.fonts.ready : new Promise(function(ready) { window.onload = time => [...document.querySelectorAll('body > span:nth-child(1) > span')].every(e => e.offsetWidth > 20) ? ready() : requestAnimationFrame(window.onload) }));
+
+ var masterElement = document.getElementById("master");
+ var testElement = document.getElementById("test");
+ var dynamicStyles = document.getElementById("dynamicStyles");
+
+ function verifyFont(testFamily, testWeight, testStyle, testStretch, expectedFamily) {
+
+ testElement.style.fontWeight = "normal";
+ testElement.style.fontStyle = "normal";
+ testElement.style.fontStretch = "normal";
+
+ masterElement.style.fontFamily = expectedFamily;
+ let masterWidth = masterElement.offsetWidth;
+
+ testElement.style.fontFamily = expectedFamily;
+ assert_equals(masterWidth, testElement.offsetWidth, "Sanity test: same family name gets same width" + dynamicStyles.innerHTML);
+
+ testElement.style.fontFamily = "serif";
+ assert_not_equals(masterWidth, testElement.offsetWidth, "Sanity test: different family get different width");
+
+ testElement.style.fontWeight = testWeight;
+ testElement.style.fontStyle = testStyle;
+ testElement.style.fontStretch = testStretch;
+ testElement.style.fontFamily = testFamily;
+
+ assert_equals(masterWidth, testElement.offsetWidth, "Unexpected font on test element");
+ }
+
+ var descriptorPriorityCases = [
+ { weight: "normal", style: "oblique -5deg", stretch: "125%", expectedFamily: "'W100'", description: "Stretch has higher priority than style"},
+ { weight: "350", style: "normal", stretch: "125%", expectedFamily: "'W100'", description: "Stretch has higher priority than weight"},
+ { weight: "350", style: "oblique -5deg", stretch: "normal", expectedFamily: "'W200'", description: "Style has higher priority than weight"}
+ ];
+
+ descriptorPriorityCases.forEach(function (testCase) {
+ promise_test(() => {
+ return once_fonts_are_ready
+ .then(() => verifyFont("descriptorPriorityTest", testCase.weight, testCase.style, testCase.stretch, testCase.expectedFamily));
+ },
+ "Descriptor matching priority: " + testCase.description
+ );
+ });
+
+ function load(family, name, value) {
+ const el1 = document.createElement("span");
+ const el2 = document.createElement("span");
+ el1.innerText = "A";
+ el2.innerText = "A";
+ let value1, value2;
+ if (value.indexOf("deg") > 0) {
+ value1 = "oblique " + value.split(" ")[1];
+ value2 = "oblique " + (value.split(" ")[2] || value.split(" ")[1]);
+ } else {
+ value1 = value.split(" ")[0];
+ value2 = value.split(" ")[1] || value1;
+ }
+ el1.style[name] = value1;
+ el2.style[name] = value2;
+ document.body.appendChild(el1);
+ document.body.appendChild(el2);
+ const initialWidth1 = el1.offsetWidth;
+ const initialWidth2 = el2.offsetWidth;
+ return new Promise((resolve) => {
+ el1.style.fontFamily = family;
+ el2.style.fontFamily = family;
+ (function check() {
+ if (el1.offsetWidth !== initialWidth1 && el2.offsetWidth !== initialWidth2) {
+ el1.remove();
+ el2.remove();
+ resolve();
+ } else {
+ requestAnimationFrame(check);
+ }
+ }());
+ });
+ }
+ function createFontFaceRules(fontFaceFamily, descriptorName, expectedMatch, unexpectedMatch) {
+ dynamicStyles.innerHTML =
+ "@font-face { font-family: " + fontFaceFamily + "; src: url('./resources/csstest-weights-100-kerned.ttf'); "+ descriptorName + ": " + expectedMatch + "; }" +
+ "@font-face { font-family: " + fontFaceFamily + "; src: url('./resources/csstest-weights-200-kerned.ttf'); " + descriptorName + ": " + unexpectedMatch + "; }";
+
+ return Promise.all([
+ load(fontFaceFamily, descriptorName, expectedMatch),
+ load(fontFaceFamily, descriptorName, unexpectedMatch)
+ ]);
+ }
+
+ let familyId = 0;
+
+ function testDescriptor(descriptorName, testCases) {
+ testCases.forEach(function (testCase) {
+ // Go though test cases, checking each descriptor has higher priority than next in the list
+ for(let i = 0; i < testCase.testDescriptors.length - 1; i++) {
+ let expectedMatch = testCase.testDescriptors[i];
+ let unexpectedMatch = testCase.testDescriptors[i + 1];
+ familyId += 1;
+ const family = "MatchTestFamily" + familyId;
+
+ promise_test(
+ () => {
+ return createFontFaceRules(family, descriptorName, expectedMatch, unexpectedMatch)
+ .then(() => {
+ let testWeight = (descriptorName == "font-weight") ? testCase.value : "normal";
+ let testStyle = (descriptorName == "font-style") ? testCase.value : "normal";
+ let testStretch = (descriptorName == "font-stretch") ? testCase.value : "normal";
+
+ verifyFont(family, testWeight, testStyle, testStretch, "'W100'");
+ });
+ },
+ "Matching " + descriptorName + ": '" + testCase.value + "' should prefer '" + expectedMatch + "' over '" + unexpectedMatch + "'");
+ }
+ });
+ }
+
+ // Each case defines property value being tested and set of descriptor values in order of matching priority from highest to lowest
+
+ testDescriptor("font-weight", [
+ { value: "400", testDescriptors: ["400", "450 460", "500", "350 399", "351 398", "501 550", "502 560"] },
+ { value: "430", testDescriptors: ["420 440", "450 460", "500", "400 425", "350 399", "340 398", "501 550", "502 560"] },
+ { value: "500", testDescriptors: ["500", "450 460", "400", "350 399", "351 398", "501 550", "502 560"] },
+ { value: "501", testDescriptors: ["501", "502 510", "503 520", "500", "450 460", "390 410", "300 350"] },
+ { value: "399", testDescriptors: ["350 399", "340 360", "200 300", "400", "450 460", "500 501", "502 510"] }
+ ]);
+
+ testDescriptor("font-stretch", [
+ { value: "100%", testDescriptors: ["100%", "110% 120%", "115% 116%"] },
+ { value: "110%", testDescriptors: ["110% 120%", "115% 116%", "105%", "100%", "50% 80%", "60% 70%"] },
+ { value: "90%", testDescriptors: ["90% 100%", "50% 80%", "60% 70%", "110% 140%", "120% 130%"] },
+ ]);
+
+ testDescriptor("font-style", [
+ { value: "normal", testDescriptors: ["normal", "oblique 0deg", "oblique 10deg 40deg", "oblique 20deg 30deg", "oblique -50deg -20deg", "oblique -40deg -30deg" ] },
+ { value: "italic", testDescriptors: ["italic", "oblique 20deg", "oblique 30deg 60deg", "oblique 40deg 50deg", "oblique 5deg 10deg", "oblique 5deg", "normal", "oblique 0deg", "oblique -60deg -30deg", "oblique -50deg -40deg" ] },
+ { value: "oblique 20deg", testDescriptors: ["oblique 20deg", "oblique 30deg 60deg", "oblique 40deg 50deg", "oblique 10deg", "italic", "oblique 0deg", "oblique -50deg -20deg", "oblique -40deg -30deg" ] },
+ { value: "oblique 21deg", testDescriptors: ["oblique 21deg", "oblique 30deg 60deg", "oblique 40deg 50deg", "oblique 20deg", "oblique 10deg", "italic", "oblique 0deg", "oblique -50deg -20deg", "oblique -40deg -30deg" ] },
+ { value: "oblique 10deg", testDescriptors: ["oblique 10deg", "oblique 5deg", "oblique 15deg 20deg", "oblique 30deg 60deg", "oblique 40deg 50deg", "italic", "oblique 0deg", "oblique -50deg -20deg", "oblique -40deg -30deg" ] },
+ { value: "oblique 0deg", testDescriptors: ["oblique 0deg", "oblique 5deg", "oblique 15deg 20deg", "oblique 30deg 60deg", "oblique 40deg 50deg", "italic", "oblique -50deg -20deg", "oblique -40deg -30deg" ] },
+ { value: "oblique -10deg", testDescriptors: ["oblique -10deg", "oblique -5deg", "oblique -1deg 0deg", "oblique -20deg -15deg", "oblique -60deg -30deg", "oblique -50deg -40deg", "italic", "oblique 0deg 10deg", "oblique 40deg 50deg" ] },
+ { value: "oblique -20deg", testDescriptors: ["oblique -20deg", "oblique -60deg -40deg", "oblique -10deg", "italic", "oblique 0deg", "oblique 30deg 60deg", "oblique 40deg 50deg"] },
+ { value: "oblique -21deg", testDescriptors: ["oblique -21deg", "oblique -60deg -40deg", "oblique -10deg", "italic", "oblique 0deg", "oblique 30deg 60deg", "oblique 40deg 50deg"] },
+ ]);
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-descriptor-range-reversed-ref.html b/testing/web-platform/tests/css/css-fonts/variations/font-descriptor-range-reversed-ref.html
new file mode 100644
index 0000000000..fc2b7aca29
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-descriptor-range-reversed-ref.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<title>CSS Reference</title>
+
+<style>
+@font-face {
+ font-family: TestWeight;
+ src: url(resources/csstest-weights-100-kerned.ttf);
+ font-weight: 200 300;
+}
+@font-face {
+ font-family: TestWeight;
+ src: url(resources/csstest-weights-900-kerned.ttf);
+ font-weight: 300 400;
+}
+@font-face {
+ font-family: TestStyle;
+ src: url(resources/csstest-weights-100-kerned.ttf);
+ font-style: oblique 20deg 30deg;
+}
+@font-face {
+ font-family: TestStyle;
+ src: url(resources/csstest-weights-900-kerned.ttf);
+ font-style: oblique 30deg 40deg;
+}
+@font-face {
+ font-family: TestStretch;
+ src: url(resources/csstest-weights-100-kerned.ttf);
+ font-stretch: 110% 120%;
+}
+@font-face {
+ font-family: TestStretch;
+ src: url(resources/csstest-weights-900-kerned.ttf);
+ font-stretch: 120% 130%;
+}
+</style>
+
+<p style="font-family: TestWeight; font-weight: 250;">A</p>
+<p style="font-family: TestStyle; font-style: oblique 25deg;">A</p>
+<p style="font-family: TestStretch; font-stretch: 115%;">A</p>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-descriptor-range-reversed.html b/testing/web-platform/tests/css/css-fonts/variations/font-descriptor-range-reversed.html
new file mode 100644
index 0000000000..14d426245d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-descriptor-range-reversed.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>CSS Test: Matching @font-face font-weight, font-style, and font-stretch descriptors with reversed ranges</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-prop-desc">
+<link rel="match" href="font-descriptor-range-reversed-ref.html">
+
+<!-- Using csstest-weights-{100,900}-kerned.ttf just as two convenient
+ different fonts here with different "A" glyphs -->
+
+<style>
+@font-face {
+ font-family: TestWeight;
+ src: url(resources/csstest-weights-100-kerned.ttf);
+ font-weight: 300 200;
+}
+@font-face {
+ font-family: TestWeight;
+ src: url(resources/csstest-weights-900-kerned.ttf);
+ font-weight: 300 400;
+}
+@font-face {
+ font-family: TestStyle;
+ src: url(resources/csstest-weights-100-kerned.ttf);
+ font-style: oblique 30deg 20deg;
+}
+@font-face {
+ font-family: TestStyle;
+ src: url(resources/csstest-weights-900-kerned.ttf);
+ font-style: oblique 30deg 40deg;
+}
+@font-face {
+ font-family: TestStretch;
+ src: url(resources/csstest-weights-100-kerned.ttf);
+ font-stretch: 120% 110%;
+}
+@font-face {
+ font-family: TestStretch;
+ src: url(resources/csstest-weights-900-kerned.ttf);
+ font-stretch: 120% 130%;
+}
+</style>
+
+<!-- Matches `font-weight: 300 200;` -->
+<p style="font-family: TestWeight; font-weight: 250;">A</p>
+
+<!-- Matches `font-style: oblique 30deg 20deg;` -->
+<p style="font-family: TestStyle; font-style: oblique 25deg;">A</p>
+
+<!-- Matches `font-style: oblique 120% 110%;` -->
+<p style="font-family: TestStretch; font-stretch: 115%;">A</p>
+
+<script>
+document.fonts.ready.then(function() {
+ document.documentElement.className = "";
+});
+</script>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-opentype-collections.html b/testing/web-platform/tests/css/css-fonts/variations/font-opentype-collections.html
new file mode 100644
index 0000000000..1b403b3246
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-opentype-collections.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Testing support for OpenType collections in @font-face rules</title>
+ <link rel="help" href="https://www.w3.org/TR/css-fonts-4/#src-desc" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <style>
+ @font-face {
+ font-family: OpenType;
+ src: url(/fonts/Ahem.ttf);
+ }
+
+ @font-face {
+ font-family: OpenType-Collection;
+ src: url(./resources/ahem.ttc);
+ }
+ </style>
+</head>
+<body onload="test()">
+ <div id="opentype" style="display:inline-block; font-family:OpenType,Georgia;">Test</div><br>
+ <div id="collection" style="display:inline-block; font-family:OpenType-Collection,Verdana;">Test</div>
+ <script>
+
+ var opentypeElement = document.getElementById("opentype");
+ var collectionElement = document.getElementById("collection");
+
+ var loadTest = async_test("Verify that collection font is loaded");
+
+ function test() {
+ if (opentypeElement.offsetWidth == collectionElement.offsetWidth) {
+ loadTest.done();
+ }
+ else {
+ window.requestAnimationFrame(test);
+ }
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-parse-numeric-stretch-style-weight.html b/testing/web-platform/tests/css/css-fonts/variations/font-parse-numeric-stretch-style-weight.html
new file mode 100644
index 0000000000..19c0ded19e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-parse-numeric-stretch-style-weight.html
@@ -0,0 +1,146 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+setup({explicit_done : true});
+
+var styleValidTests = {
+ 'weight': [
+ 'bold',
+ '700',
+ '900',
+ '850',
+ '850.3',
+ 'calc(100 + 300)',
+ 'calc(0.2 + 205.5)',
+ 'calc(0 - 100)',
+ 'calc(200 + 801)',
+ ],
+ 'stretch': ['51%', '199%', 'calc(10% + 20%)', '0%'],
+ 'style' : [ 'normal', 'italic', 'oblique', 'oblique 50deg', 'oblique -90deg', 'oblique 90deg',
+ 'oblique calc(90deg + 20deg)', 'oblique calc(30deg + 20deg)' ]
+};
+
+var styleInvalidTests = {
+ 'weight': ['100 400'],
+ 'stretch': ['100% 110%', '100% 150%', 'calc(1 + 10%)'],
+ 'style' : [ 'normal 10deg', 'italic 10deg', 'oblique -91deg', 'oblique 91deg' ]
+};
+
+function testParseStyle() {
+ for (validStyleTestCategory of Object.keys(styleValidTests)) {
+ for (validStyleTest of styleValidTests[validStyleTestCategory]) {
+ test(
+ function() {
+ assert_true(
+ CSS.supports('font-' + validStyleTestCategory, validStyleTest));
+ },
+ 'Valid value ' + validStyleTest + ' for font property ' +
+ validStyleTestCategory + ' used for styling.')
+ }
+ }
+ for (invalidStyleTestCategory of Object.keys(styleInvalidTests)) {
+ for (invalidStyleTest of styleInvalidTests[invalidStyleTestCategory]) {
+ test(
+ function() {
+ assert_false(CSS.supports(
+ 'font-' + invalidStyleTestCategory, invalidStyleTest));
+ },
+ 'Invalid value ' + invalidStyleTest + ' for font property ' +
+ invalidStyleTestCategory + ' used for styling.')
+ }
+ }
+}
+
+var faceTests = {
+ 'weight': [
+ ['100', '100'], ['700', '700'], ['900', '900'], ['bold', 'bold'],
+ ['normal', 'normal'], ['100 400', '100 400'], ['100 101.5', '100 101.5'],
+ ['999.8 999.9', '999.8 999.9'],
+ [ '500 400', '500 400']
+ ],
+ 'stretch': [
+ ['0%', '0%'],
+ ['calc(0% - 10%)', 'calc(-10%)' ],
+ ['100%', '100%'],
+ ['110%', '110%'],
+ ['111.5%', '111.5%'],
+ [ "50% 200%", "50% 200%" ],
+ [ "0.1% 1%", "0.1% 1%" ],
+ [ "900% 901%", "900% 901%" ],
+ ['ultra-condensed', 'ultra-condensed'],
+ ['ultra-expanded', 'ultra-expanded'],
+ ],
+ 'style' : [
+ [ "normal", "normal" ],
+ [ "italic", "italic" ],
+ [ "oblique", "oblique" ],
+ [ "oblique 10deg", "oblique 10deg" ],
+ [ "oblique 10deg 20deg", "oblique 10deg 20deg" ]
+ ]
+};
+
+var faceInvalidTests = {
+ 'weight': [
+ '0',
+ '0.9',
+ '-100 200',
+ '100 -200',
+ '100 1001',
+ '1001',
+ '1000.5',
+ '100 200 300',
+ 'a',
+ 'a b c',
+ ],
+ 'stretch': [
+ '-0.5%', '-1%', '60% 70% 80%', 'a%', 'a b c', '0.1',
+ '-60% 80%', 'ultra-expannnned', '50% 0'
+ ],
+ 'style' : [ 'oblique 100deg', 'oblique italic', 'oblique -91deg', 'oblique 0',
+ 'oblique 10', 'iiitalic', '90deg', '11', 'italic 90deg' ]
+};
+
+function testParseFace() {
+ for (var theProperty of Object.keys(faceTests)) {
+ for (var faceTest of faceTests[theProperty]) {
+ test(
+ () => {
+ var fontFace = new FontFace('testfont', 'url()');
+ assert_equals(fontFace[theProperty], 'normal');
+ fontFace[theProperty] = faceTest[0];
+ assert_equals(fontFace[theProperty], faceTest[1]);
+ },
+ 'Valid value ' + faceTest[0] + ' matches ' + faceTest[1] + ' for ' +
+ theProperty + ' in @font-face.');
+ }
+ }
+
+ for (var theProperty of Object.keys(faceInvalidTests)) {
+ for (var faceTest of faceInvalidTests[theProperty]) {
+ test(
+ () => {
+ var fontFace = new FontFace('testfont', 'url()');
+ assert_throws_dom('SyntaxError', () => {
+ fontFace[theProperty] = faceTest;
+ }, 'Value must not be accepted as weight value.');
+ },
+ 'Value ' + faceTest + ' must not be accepted as ' + theProperty +
+ ' in @font-face.')
+ }
+ }
+}
+
+window.addEventListener('load', function() {
+ testParseStyle();
+ testParseFace();
+ done();
+});
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-shorthand.html b/testing/web-platform/tests/css/css-fonts/variations/font-shorthand.html
new file mode 100644
index 0000000000..c0f1f54196
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-shorthand.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Testing font shorthand for new values introduced in CSS Fonts level 4</title>
+ <link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-prop" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <div id="shorthand-test">Shorthand test</div>
+
+ <script>
+
+ testFontShorthand = [
+ { value: "calc(24px) Arial", isValid:true, message: "Font size specified as calc()" },
+
+ // font-weight as number
+ { value: "700.5 24px Arial", isValid:true, expectedWeight:"700.5", message: "Font weight specified as number" },
+ { value: "0.9 24px Arial", isValid:false, message: "Font weight specified as number, value less than 1" },
+ { value: "1700.5 24px Arial", isValid:false, message: "Font weight specified as number, value greater than 1000" },
+
+ // font-weight as calc()
+ { value: "calc(900.7 - 200.1 * 2) calc(12px + 12px) Arial", isValid:true, expectedWeight:"500.5", message: "Font weight specified as calc()" },
+ { value: "calc(400.5 - 200.1 * 2) 24px Arial", isValid:true, expectedWeight:"1", message: "Font weight specified as calc(), value smaller than 1" },
+ { value: "calc(400.5 + 300.1 * 2) 24px Arial", isValid:true, expectedWeight:"1000", message: "Font weight specified as calc(), value greater than 1000" },
+
+ // font-style
+ { value: "oblique 45deg 24px Arial", isValid:true, expectedStyle: "oblique 45deg", message: "'oblique' with positive angle" },
+ { value: "oblique -45deg 24px Arial", isValid:true, expectedStyle: "oblique -45deg", message: "'oblique' with negative angle" },
+ { value: "oblique 24px Arial", isValid:true, expectedStyle: "oblique", message: "'oblique' without slant angle" },
+ { value: "oblique 100deg 24px Arial", isValid:false, message: "'oblique' with positive angle, value out of range" },
+ { value: "oblique -100deg 24px Arial", isValid:false, message: "'oblique' with negative angle, value out of range" },
+
+ // font-weight and font-style combined
+ { value: "oblique 50 24px Arial", isValid:true, expectedStyle: "oblique", expectedWeight:"50", message: "'oblique' followed by valid small weight" },
+ { value: "oblique 500 24px Arial", isValid:true, expectedStyle: "oblique", expectedWeight:"500", message: "'oblique' followed by valid large weight" },
+ { value: "oblique 45deg 500 24px Arial", isValid:true, expectedStyle: "oblique 45deg", expectedWeight:"500", message: "'oblique' with positive angle followed by valid weight" },
+ { value: "oblique -45deg 500 24px Arial", isValid:true, expectedStyle: "oblique -45deg", expectedWeight:"500", message: "'oblique' with negative angle followed by valid weight" },
+
+ // font-weight and font-style combined, with calc()
+ { value: "oblique calc(200 + 300) 24px Arial", isValid:true, expectedStyle: "oblique", expectedWeight:"500", message: "'oblique' followed by valid calc() weight" },
+ { value: "oblique 30deg calc(200 + 300) 24px Arial", isValid:true, expectedStyle: "oblique 30deg", expectedWeight:"500", message: "'oblique' with angle followed by valid calc() weight" },
+ { value: "oblique calc(900 + 300) 24px Arial", isValid:true, expectedStyle: "oblique", expectedWeight:"1000", message: "'oblique' followed by a to-be-clamped calc() weight" },
+ { value: "calc(200 + 300) oblique 24px Arial", isValid:true, expectedStyle: "oblique", expectedWeight:"500", message: "calc() weight folowed by 'oblique'" },
+ { value: "calc(200 + 300) oblique 45deg 24px Arial", isValid:true, expectedStyle: "oblique 45deg", expectedWeight:"500", message: "calc() weight folowed by 'oblique' and slant angle" },
+ { value: "calc(900 + 300) oblique 45deg 24px Arial", isValid:true, expectedStyle: "oblique 45deg", expectedWeight:"1000", message: "To-be-clamped calc() weight folowed by 'oblique' and slant angle" },
+ ];
+
+ testFontShorthand.forEach(function (testCase) {
+ test(() => {
+ assert_equals(window.CSS.supports("font", testCase.value), testCase.isValid, "Font shorthand: " + testCase.message);
+
+ let expectedStyle = (testCase.expectedStyle) ? testCase.expectedStyle : "normal";
+ let expectedWeight = (testCase.expectedWeight) ? testCase.expectedWeight : "400";
+ let expectedSize = (testCase.isValid) ? "24px" : "16px";
+
+ var testElement = document.getElementById("shorthand-test");
+ testElement.setAttribute("style", "font:" + testCase.value);
+ var style = window.getComputedStyle(testElement);
+ assert_equals(style.fontStyle, expectedStyle, "Font shorthand expected style: " + testCase.message);
+ assert_equals(style.fontWeight, expectedWeight, "Font shorthand expected weight: " + testCase.message);
+ assert_equals(style.fontSize, expectedSize, "Font shorthand expected size: " + testCase.message);
+ }, "Font shorthand: " + testCase.message);
+
+ });
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-slant-1-ref.html b/testing/web-platform/tests/css/css-fonts/variations/font-slant-1-ref.html
new file mode 100644
index 0000000000..7b819bfa56
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-slant-1-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>CSS reference file: mapping of font-style:oblique to opentype 'slnt' axis</title>
+<style>
+@font-face {
+ font-family: test;
+ font-style: oblique 10deg;
+ src: url(resources/Inter.var.subset.ttf);
+}
+.test {
+ font: 32px/1.5 test;
+ font-variation-settings: 'slnt' -10;
+}
+</style>
+<body>
+<p>Test passes if all the following lines are displayed with a 10-degree rightward slant.</p>
+<div class="test">slant</div>
+<div class="test">slant</div>
+<div class="test">slant</div>
+<div class="test">slant</div>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-slant-1.html b/testing/web-platform/tests/css/css-fonts/variations/font-slant-1.html
new file mode 100644
index 0000000000..f3985defde
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-slant-1.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>CSS test: mapping of font-style:oblique to opentype 'slnt' axis</title>
+<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"/>
+<link rel="help" href="https://drafts.csswg.org/css-fonts/#valdef-font-style-oblique-angle"/>
+<link rel="match" href="font-slant-1-ref.html"/>
+<style>
+@font-face {
+ font-family: test;
+ font-style: oblique 0deg 10deg;
+ src: url(resources/Inter.var.subset.ttf);
+}
+.test {
+ font-synthesis: none;
+ font: 32px/1.5 test;
+}
+</style>
+<body>
+<p>Test passes if all the following lines are displayed with a 10-degree rightward slant.</p>
+<div class="test" style="font-variation-settings: 'slnt' -10">slant</div>
+<div class="test" style="font-style: oblique">slant</div>
+<div class="test" style="font-style: oblique 10deg">slant</div>
+<div class="test" style="font-style: italic">slant</div>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-slant-2-ref.html b/testing/web-platform/tests/css/css-fonts/variations/font-slant-2-ref.html
new file mode 100644
index 0000000000..4f109aa219
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-slant-2-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>CSS reference file: mapping of font-style:oblique to opentype 'slnt' axis</title>
+<style>
+@font-face {
+ font-family: test;
+ src: url(resources/Inter.var.subset.ttf);
+}
+.test {
+ font: 32px/1.5 test;
+}
+</style>
+<body>
+<p>Test passes if none of the following lines are displayed with a slanted font.</p>
+<div class="test">slant</div>
+<div class="test">slant</div>
+<div class="test">slant</div>
+<div class="test">slant</div>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-slant-2a.html b/testing/web-platform/tests/css/css-fonts/variations/font-slant-2a.html
new file mode 100644
index 0000000000..386ff83f8d
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-slant-2a.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>CSS test: mapping of font-style:oblique to opentype 'slnt' axis</title>
+<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"/>
+<link rel="help" href="https://drafts.csswg.org/css-fonts/#valdef-font-style-oblique-angle"/>
+<link rel="match" href="font-slant-2-ref.html"/>
+<style>
+@font-face {
+ font-family: test;
+ font-style: oblique 0deg 10deg;
+ src: url(resources/Inter.var.subset.ttf);
+}
+.test {
+ font: 32px/1.5 test;
+}
+</style>
+<body>
+<p>Test passes if none of the following lines are displayed with a slanted font.</p>
+<div class="test">slant</div>
+<div class="test" style="font-variation-settings: 'slnt' 10">slant</div>
+<div class="test" style="font-style: oblique 0deg">slant</div>
+<div class="test" style="font-style: oblique -10deg">slant</div>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-slant-2b.html b/testing/web-platform/tests/css/css-fonts/variations/font-slant-2b.html
new file mode 100644
index 0000000000..0fb280827e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-slant-2b.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>CSS test: mapping of font-style:oblique to opentype 'slnt' axis</title>
+<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com"/>
+<link rel="help" href="https://drafts.csswg.org/css-fonts/#valdef-font-style-oblique-angle"/>
+<link rel="match" href="font-slant-2-ref.html"/>
+<style>
+@font-face {
+ font-family: test;
+ font-style: oblique -10deg 0deg;
+ src: url(resources/Inter.var.subset.ttf);
+}
+.test {
+ font-synthesis: none;
+ font: 32px/1.5 test;
+}
+</style>
+<body>
+<p>Test passes if none of the following lines are displayed with a slanted font.</p>
+<div class="test">slant</div>
+<div class="test" style="font-variation-settings: 'slnt' 10">slant</div>
+<div class="test" style="font-style: oblique">slant</div>
+<div class="test" style="font-style: italic">slant</div>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-stretch.html b/testing/web-platform/tests/css/css-fonts/variations/font-stretch.html
new file mode 100644
index 0000000000..a27b251f48
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-stretch.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Testing new font-stretch values introduced in CSS Fonts level 4</title>
+ <link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-stretch-prop" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <div id="computedStyleTest">Abc</span></div>
+ <div id="inheritanceTest"><span style="font-stretch:125%;">Abc</span><span style="font-stretch:expanded;">Abc</span><span style="font-weight: 700;">Abc</span></div>
+ <script>
+
+ testStretchValues = [
+ { stretch: "100", expectedComputedStretch: "100%" , expectedIsSupported: false, message: "only percentages, not numbers allowed" },
+ { stretch: "-1%", expectedComputedStretch: "" , expectedIsSupported: false, message: "negative values are illegal" },
+ { stretch: "0%", expectedComputedStretch: "0%", expectedIsSupported: true, message: "zero is legal" },
+ { stretch: "1%", expectedComputedStretch: "1%", expectedIsSupported: true, message: "legal percentage" },
+ { stretch: "10%", expectedComputedStretch: "10%", expectedIsSupported: true, message: "legal percentage" },
+ { stretch: "100%", expectedComputedStretch: "100%", expectedIsSupported: true, message: "legal percentage" },
+ { stretch: "1000%", expectedComputedStretch: "1000%", expectedIsSupported: true, message: "legal percentage" },
+ { stretch: "1e9%", expectedComputedStretch: "1e+009%", expectedIsSupported: true, message: "huge legal percentage" },
+ { stretch: "ultra-condensed", expectedComputedStretch: "50%", expectedIsSupported: true, message: "legal enum" },
+ { stretch: "extra-condensed", expectedComputedStretch: "62.5%", expectedIsSupported: true, message: "legal enum" },
+ { stretch: "condensed", expectedComputedStretch: "75%", expectedIsSupported: true, message: "legal enum" },
+ { stretch: "semi-condensed", expectedComputedStretch: "87.5%", expectedIsSupported: true, message: "legal enum" },
+ { stretch: "normal", expectedComputedStretch: "100%", expectedIsSupported: true, message: "legal enum" },
+ { stretch: "semi-expanded", expectedComputedStretch: "112.5%", expectedIsSupported: true, message: "legal enum" },
+ { stretch: "expanded", expectedComputedStretch: "125%", expectedIsSupported: true, message: "legal enum" },
+ { stretch: "extra-expanded", expectedComputedStretch: "150%", expectedIsSupported: true, message: "legal enum" },
+ { stretch: "ultra-expanded", expectedComputedStretch: "200%", expectedIsSupported: true, message: "legal enum" },
+ { stretch: "narrower", expectedComputedStretch: "", expectedIsSupported: false, message: "deprecated" },
+ { stretch: "wider", expectedComputedStretch: "", expectedIsSupported: false, message: "deprecated" },
+ { stretch: "calc(200.5%)", expectedComputedStretch: "200.5%", expectedIsSupported: true, message: "Simple calc value" },
+ { stretch: "calc(50%*2 - 20%)", expectedComputedStretch: "80%", expectedIsSupported: true, message: "Valid calc expression" },
+ { stretch: "calc(-100%)", expectedComputedStretch: "0%", expectedIsSupported: true, message: "Negative calc value (to be clamped)" },
+ { stretch: "calc(50% - 50%*2)", expectedComputedStretch: "0%", expectedIsSupported: true, message: "Negative calc expression (to be clamped)" },
+ { stretch: "calc(100)", expectedComputedStretch: "", expectedIsSupported: false, message: "Unit-less calc value" },
+ { stretch: "calc(100px)", expectedComputedStretch: "", expectedIsSupported: false, message: "Calc value with units" },
+ { stretch: "100% 700%", expectedComputedStretch: "", expectedIsSupported: false, message: "Extra percentage after numeric value" },
+ { stretch: "100% 100", expectedComputedStretch: "", expectedIsSupported: false, message: "Extra content after numeric value" },
+ { stretch: "condensed expanded",expectedComputedStretch: "", expectedIsSupported: false, message: "Extra content after keyword value" },
+ { stretch: "calc(100%) 100%", expectedComputedStretch: "", expectedIsSupported: false, message: "Extra content after calc value" }
+ ];
+
+ testStretchValues.forEach(function (element) {
+ test(() => { assert_equals(window.CSS.supports("font-stretch", element.stretch), element.expectedIsSupported, element.message); }, "@supports: " + element.stretch + " - " + element.message);
+
+ // If supported, verify the computed style.
+ if (element.expectedIsSupported)
+ {
+ var testSpan = document.getElementById("computedStyleTest");
+ testSpan.style.fontStretch = element.stretch;
+ var actualStretch = window.getComputedStyle(testSpan).fontStretch;
+
+ test(() => { assert_equals(actualStretch, element.expectedComputedStretch, element.message); }, "@getComputedStyle: " + element.stretch + " - " + element.message);
+ }
+ });
+
+ // Verify computed inheritance of nested elements.
+ {
+ var base = document.getElementById("inheritanceTest");
+ var parentStretch = "condensed";
+ base.style.fontStretch = parentStretch;
+
+ test(() => {
+ var actualStretch = window.getComputedStyle(base.children[0]).fontStretch;
+ assert_equals(actualStretch, "125%", "Overridden value for " + parentStretch + " should match expected value.");
+ }, "Test font-stretch for overridden number " + parentStretch);
+
+ test(() => {
+ var actualStretch = window.getComputedStyle(base.children[1]).fontStretch;
+ assert_equals(actualStretch, "125%", "Inherited value " + parentStretch + " should match expected value.");
+ }, "Test font-stretch for overridden enum name resolved to number " + parentStretch);
+
+ test(() => {
+ var actualStretch = window.getComputedStyle(base.children[2]).fontStretch;
+ assert_equals(actualStretch, "75%", "Inherited value " + parentStretch + " should match expected value.");
+ }, "Test font-stretch for inherited named enum resolved to number " + parentStretch);
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-style-interpolation.html b/testing/web-platform/tests/css/css-fonts/variations/font-style-interpolation.html
new file mode 100644
index 0000000000..0fb8850c4a
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-style-interpolation.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Testing the interpolation of new font-style values introduced in CSS Fonts level 4</title>
+ <meta name="timeout" content="long">
+ <link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-style-prop" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <style>
+ @keyframes fontStyleAnimation {
+ from { font-style: oblique -12deg; }
+ to { font-style: oblique 12deg; }
+ }
+
+ #animation-test.animate {
+ animation: fontStyleAnimation 1s infinite alternate;
+ }
+
+ #transition-test {
+ font-style: oblique -12deg;
+ transition-property: font-style;
+ transition-duration: 10s;
+ }
+
+ #transition-test.animate {
+ font-style: oblique 12deg;
+ }
+
+ </style>
+</head>
+<body>
+ <div style="font-family: serif;">
+ <div id="animation-test">Animation test</div>
+ <div id="transition-test">Transition test</div>
+ </div>
+
+ <script>
+
+ async_test(function (test) {
+ var animationElement = document.getElementById("animation-test");
+
+ // Verify starting value
+ assert_equals(window.getComputedStyle(animationElement).fontStyle, "normal", "Font style before animation");
+
+ // Start animation
+ animationElement.classList.add("animate");
+
+ var waitForAnimationStep = test.step_func(function() {
+ var computedFontStyle = window.getComputedStyle(animationElement).fontStyle;
+ if (computedFontStyle != "normal" &&
+ computedFontStyle != "oblique -12deg" &&
+ computedFontStyle != "oblique 12deg") {
+ test.done();
+ }
+ else {
+ window.requestAnimationFrame(waitForAnimationStep);
+ }
+ });
+ waitForAnimationStep();
+
+ }, "font-style animation");
+
+ async_test(function (test) {
+ var transitionElement = document.getElementById("transition-test");
+
+ // Verify starting value
+ assert_equals(window.getComputedStyle(transitionElement).fontStyle, "oblique -12deg", "Font style before transition");
+
+ // Start transition
+ transitionElement.classList.add("animate");
+
+ var waitForTransitionStep = test.step_func(function() {
+ var computedFontStyle = window.getComputedStyle(transitionElement).fontStyle;
+ if (computedFontStyle != "normal" &&
+ computedFontStyle != "oblique -12deg" &&
+ computedFontStyle != "oblique 12deg") {
+ test.done();
+ }
+ else {
+ window.requestAnimationFrame(waitForTransitionStep);
+ }
+ });
+ waitForTransitionStep();
+
+ }, "font-style transition");
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-style-parsing.html b/testing/web-platform/tests/css/css-fonts/variations/font-style-parsing.html
new file mode 100644
index 0000000000..cb5e42eab4
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-style-parsing.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Testing the new font-style values introduced in CSS Fonts level 4</title>
+ <link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-style-prop" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <div id="test"></div>
+ <script>
+ var testFontStyle = [
+ { style: "italic", expectedResult: true, message: "'italic' is valid" },
+ { style: "italic 20deg", expectedResult: false, message: "'italic' followed by angle is invalid" },
+ { style: "italic a", expectedResult: false, message: "'italic' followed by non-number is invalid" },
+ { style: "oblique", expectedResult: true, message: "'oblique' is valid" },
+ { style: "oblique 0deg", expectedResult: true, message: "'oblique' followed by zero degrees is valid" },
+ { style: "oblique 20deg", expectedResult: true, message: "'oblique' followed by positive angle in degrees is valid" },
+ { style: "oblique 0.5rad", expectedResult: true, message: "'oblique' followed by positive angle in radians is valid", expectedValue: "oblique 28.6479deg" },
+ { style: "oblique 20grad", expectedResult: true, message: "'oblique' followed by positive angle in gradians is valid", expectedValue: "oblique 18deg" },
+ { style: "oblique 0.1turn", expectedResult: true, message: "'oblique' followed by positive angle in turns is valid", expectedValue: "oblique 36deg" },
+ { style: "oblique 20px", expectedResult: false, message: "'oblique' followed by number with invalid unit type is in valid" },
+ { style: "oblique -20deg", expectedResult: true, message: "'oblique' followed by negative angle is valid" },
+ { style: "oblique 20.5deg", expectedResult: true, message: "'oblique' followed by fractional angle is valid" },
+ { style: "oblique 90deg", expectedResult: true, message: "'oblique' followed by maxumum 90 degree angle is valid" },
+ { style: "oblique -90deg", expectedResult: true, message: "'oblique' followed by minimum -90 degree angle is valid" },
+ { style: "oblique 90.01deg", expectedResult: false, message: "'oblique' followed by positive out of range angle is in invalid" },
+ { style: "oblique -90.01deg", expectedResult: false, message: "'oblique' followed by negative out of range angle is in invalid" },
+ { style: "oblique 10", expectedResult: false, message: "'oblique' followed by unit-less value is invalid" },
+ { style: "oblique 30deg", expectedResult: true, message: "'oblique' followed by positive angle is valid" },
+ { style: "oblique a", expectedResult: false, message: "'oblique' followed by non-number is invalid" },
+ { style: "oblique 20deg a", expectedResult: false, message: "'oblique' and angle followed by non-number is invalid" },
+ { style: "oblique -", expectedResult: false, message: "'oblique' followed by isolated minus is invalid" },
+ { style: "oblique - 20deg", expectedResult: false, message: "'oblique' followed by minus and angle separated by space is invalid" },
+ { style: "oblique -a", expectedResult: false, message: "'oblique' followed by minus and non-number is invalid" },
+ { style: "oblique calc(50deg)", expectedResult: true, message: "'oblique' followed by calc is valid", expectedValue: "oblique 50deg" },
+ { style: "oblique calc(-120deg)", expectedResult: true, message: "'oblique' followed by calc is valid even if it must be clamped (no computation)", expectedValue: "oblique -90deg" },
+ { style: "oblique calc(6 * 20deg)", expectedResult: true, message: "'oblique' followed by calc is valid even if it must be clamped (with computation)", expectedValue: "oblique 90deg" },
+ { style: "oblique calc(10grad + 5deg)", expectedResult: true, message: "'oblique' followed by calc is valid even if it mixes units (with computation)", expectedValue: "oblique 14deg" }
+ ];
+
+ testFontStyle.forEach(function (testCase) {
+ test(() => {
+ assert_equals(window.CSS.supports("font-style", testCase.style), testCase.expectedResult, "Font-style supports: " + testCase.message);
+ }, "Font-style (supports): " + testCase.message);
+ });
+
+ testFontStyle.forEach(function (testCase) {
+ if (testCase.expectedResult) {
+ test(() => {
+ let element = document.getElementById("test");
+ element.style = "font-style: " + testCase.style;
+ let expectedValue = (testCase.expectedValue) ? testCase.expectedValue : testCase.style;
+ assert_equals(window.getComputedStyle(element).fontStyle, expectedValue, "Font-style computed style: " + testCase.message);
+ }, "Font-style (computed): " + testCase.message);
+ }
+ });
+ </script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-variation-settings-inherit.html b/testing/web-platform/tests/css/css-fonts/variations/font-variation-settings-inherit.html
new file mode 100644
index 0000000000..f0d8f0b2a5
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-variation-settings-inherit.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Testing the inheritance of the font-variation-settings property</title>
+ <link rel="help" href="https://www.w3.org/TR/css-fonts-4/#propdef-font-variation-settings" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <div id="inheritanceTestParent" style="font-variation-settings: 'xxxx' 1, 'xxxx' 2;">
+ <span id="inheritanceTestChildInherited">Abc</span>
+ <span id="inheritanceTestChildOverride" style="font-variation-settings: 'cccc' 1, 'bbbb' 2, 'aaaa' 3, 'aaaa' calc(2 + 2);">Abc</span>
+ </div>
+ <script>
+
+ // Verify computed inheritance of nested elements.
+ var elementParent = document.getElementById("inheritanceTestParent");
+ var elementChildInherited = document.getElementById("inheritanceTestChildInherited");
+ var elementChildOverride = document.getElementById("inheritanceTestChildOverride");
+
+ var parentValue = "'yyyy' 1, 'yyyy' 2";
+ elementParent.style.fontVariationSettings = parentValue;
+
+ test(() => {
+ var actualValue = window.getComputedStyle(elementParent).fontVariationSettings;
+ // The following strict test is subject to debate; softening for now:
+ // assert_equals(actualValue, "\"yyyy\" 2", "Duplicate axis tags should be removed, favoring the latter axis tag's value.");
+ assert_equals((/.*(?:"|')yyyy(?:"|') (\d)/.exec(actualValue)||[])[1], '2', "Child should override parent value.");
+ }, "Test font-variation-settings for duplicates using " + parentValue);
+
+ test(() => {
+ var actualValue = window.getComputedStyle(elementChildInherited).fontVariationSettings;
+ // The following strict test is subject to debate; softening for now:
+ // assert_equals(actualValue, "\"yyyy\" 2", "Child should inherit the parent value directly.");
+ assert_equals((/.*(?:"|')yyyy(?:"|') (\d)/.exec(actualValue)||[])[1], '2', "Child should override parent value.");
+ }, "Test font-variation-settings for child inheritance");
+
+ test(() => {
+ var actualValue = window.getComputedStyle(elementChildOverride).fontVariationSettings;
+ // The following strict test is subject to debate; softening for now:
+ // assert_equals(actualValue, "\"aaaa\" 4, \"bbbb\" 2, \"cccc\" 1", "Child should override parent value.");
+ assert_equals((/.*(?:"|')aaaa(?:"|') (\d)/.exec(actualValue)||[])[1], '4', "Child should override parent value.");
+ assert_equals((/.*(?:"|')yyyy(?:"|') (\d)/.exec(actualValue)||[])[1], undefined, "Child should override parent value.");
+ }, "Test font-variation-settings for child override");
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-weight-interpolation.html b/testing/web-platform/tests/css/css-fonts/variations/font-weight-interpolation.html
new file mode 100644
index 0000000000..745be060ab
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-weight-interpolation.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Testing the interpolation of new font-weight values introduced in CSS Fonts level 4</title>
+ <link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-weight-prop" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <style>
+ @keyframes fontWeightAnimation {
+ from { font-weight: 100; }
+ to { font-weight: 900; }
+ }
+
+ #animation-test.animate {
+ animation: fontWeightAnimation 1s infinite alternate;
+ }
+
+ #transition-test {
+ font-weight: 100;
+ transition-property: font-weight;
+ transition-duration: 10s;
+ }
+
+ #transition-test.animate {
+ font-weight: 900;
+ }
+
+ </style>
+</head>
+<body>
+ <div style="font-family: 'CSSTest Weights Full';">
+ <div id="animation-test">A</div>
+ <div id="transition-test">A</div>
+ </div>
+
+ <script>
+
+ async_test(function (test) {
+ var animationElement = document.getElementById("animation-test");
+
+ // Verify starting value
+ assert_equals(window.getComputedStyle(animationElement).fontWeight, "400", "Font weight before animation");
+
+ // Start animation
+ animationElement.classList.add("animate");
+
+ var waitForAnimationStep = test.step_func(function() {
+ var computedFontWeight = window.getComputedStyle(animationElement).fontWeight;
+ if (computedFontWeight[1] != "0" || computedFontWeight[2] != 0) { // the value should eventually not be a multiple of 100
+ test.done();
+ }
+ else {
+ window.requestAnimationFrame(waitForAnimationStep);
+ }
+ });
+ waitForAnimationStep();
+
+ }, "font-weight animation");
+
+ async_test(function (test) {
+ var transitionElement = document.getElementById("transition-test");
+
+ // Verify starting value
+ assert_equals(window.getComputedStyle(transitionElement).fontWeight, "100", "Font weight before transition");
+
+ // Start transition
+ transitionElement.classList.add("animate");
+
+ var waitForTransitionStep = test.step_func(function() {
+ var computedFontWeight = window.getComputedStyle(transitionElement).fontWeight;
+ if (computedFontWeight[1] != "0" || computedFontWeight[2] != 0) { // the value should eventually not be a multiple of 100
+ test.done();
+ }
+ else {
+ window.requestAnimationFrame(waitForTransitionStep);
+ }
+ });
+ waitForTransitionStep();
+
+ }, "font-weight transition");
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-weight-lighter-bolder.html b/testing/web-platform/tests/css/css-fonts/variations/font-weight-lighter-bolder.html
new file mode 100644
index 0000000000..68321c5075
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-weight-lighter-bolder.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Testing new font-weight lighter/bolder table introduced in CSS Fonts level 4</title>
+ <link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-weight-prop" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+
+ <div id="testcases">
+ <div class="testcase" style="font-family: 'CSSTest Weights Full';">
+ <span style="font-weight:lighter;color:red;">A</span>A<span style="font-weight:bolder;color:red;">A</span>
+ <span style="font: menu; font-size: 10px;">(default)</span>
+ </div>
+ </div>
+
+ <script>
+
+ testRelativeWeights = [
+ { baseWeight: 99, lighter: "99", bolder: "400" },
+ { baseWeight: 100, lighter: "100", bolder: "400" },
+ { baseWeight: 349, lighter: "100", bolder: "400" },
+ { baseWeight: 350, lighter: "100", bolder: "700" },
+ { baseWeight: 549, lighter: "100", bolder: "700" },
+ { baseWeight: 550, lighter: "400", bolder: "900" },
+ { baseWeight: 749, lighter: "400", bolder: "900" },
+ { baseWeight: 750, lighter: "700", bolder: "900" },
+ { baseWeight: 899, lighter: "700", bolder: "900" },
+ { baseWeight: 900, lighter: "700", bolder: "900" },
+ { baseWeight: 901, lighter: "700", bolder: "901" },
+ ];
+
+ var testcases = document.getElementById("testcases");
+ var testcase_template = testcases.firstElementChild; testcases.removeChild(testcase_template);
+ testRelativeWeights.forEach(function(element) {
+
+ var base = testcase_template.cloneNode(true);
+ base.children[2].textContent = element.baseWeight;
+ base.style.fontWeight = element.baseWeight;
+ testcases.appendChild(base);
+
+ test(() => {
+ var actualLighter = window.getComputedStyle(base.children[0]).fontWeight;
+ assert_equals(actualLighter, element.lighter, "Lighter value for " + element.baseWeight + " should match expected value.");
+ base.children[0].style.color = 'green';
+ }, "Test lighter font-weight for base weight " + element.baseWeight);
+
+ test(() => {
+ var actualBolder = window.getComputedStyle(base.children[1]).fontWeight;
+ assert_equals(actualBolder, element.bolder, "Bolder value " + element.baseWeight + " should match expected value.");
+ base.children[1].style.color = 'green';
+ }, "Test bolder font-weight for base weight " + element.baseWeight);
+ });
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-weight-matching-installed-fonts.html b/testing/web-platform/tests/css/css-fonts/variations/font-weight-matching-installed-fonts.html
new file mode 100644
index 0000000000..a290fb64fc
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-weight-matching-installed-fonts.html
@@ -0,0 +1,114 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Testing new font-matching algorithm for font-weight values introduced in CSS Fonts level 4 (for system fonts)</title>
+ <link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-matching-algorithm" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <!-- THIS TEST REQUIRES THAT YOU INSTALL THE [csstest-*.ttf] FONTS OF THE [resources] FOLDER -->
+ <style>
+
+ .testcase {
+ float:left;
+ margin: 5px;
+ font-size:48pt;
+ font-feature-settings: "kern" 1;
+ color: rgba(0,0,0,0.5);
+ background: linear-gradient(to left, lime 0%, lime 91px, red 91px);
+ }
+
+ @font-face {
+ font-family: fontMatch;
+ src: local('CSSTest Weights 900');
+ font-weight: 100;
+ }
+
+ @font-face {
+ font-family: fontMatch;
+ src: local('CSSTest Weights 800');
+ font-weight: 250;
+ }
+
+ @font-face {
+ font-family: fontMatch;
+ src: local('CSSTest Weights 700');
+ font-weight: 400;
+ }
+
+ @font-face {
+ font-family: fontMatch;
+ src: local('CSSTest Weights 600');
+ font-weight: 450;
+ }
+
+ @font-face {
+ font-family: fontMatch;
+ src: local('CSSTest Weights 300');
+ font-weight: 500;
+ }
+
+ @font-face {
+ font-family: fontMatch;
+ src: local('CSSTest Weights 200');
+ font-weight: 750;
+ }
+
+ @font-face {
+ font-family: fontMatch;
+ src: local('CSSTest Weights 100');
+ font-weight: 900;
+ }
+
+ </style>
+</head>
+<body>
+
+ <span style="position: absolute; top: -100vh;">
+ <span style="font-family: fontMatch; font-weight: 100;">A</span>
+ <span style="font-family: fontMatch; font-weight: 250;">A</span>
+ <span style="font-family: fontMatch; font-weight: 400;">A</span>
+ <span style="font-family: fontMatch; font-weight: 450;">A</span>
+ <span style="font-family: fontMatch; font-weight: 500;">A</span>
+ <span style="font-family: fontMatch; font-weight: 750;">A</span>
+ <span style="font-family: fontMatch; font-weight: 900;">A</span>
+ </span>
+
+ <div id="testcases" style="overflow: hidden">
+ <!--
+ These testcases work using the new kerned CSSTest Weights fonts.
+ The letter A and its corresponding numeric digit kern as one character.
+ -->
+ <div class="testcase" style="font-family:'CSSTest Weights W2569'; font-weight: 375;">
+ A2
+ </div>
+ <div class="testcase" style="font-family:'CSSTest Weights Full'; font-weight: 375;">
+ A3
+ </div>
+ <div class="testcase" style="font-family:'CSSTest Weights W1479'; font-weight: 475;">
+ A4
+ </div>
+ <div class="testcase" style="font-family:'CSSTest Weights Full'; font-weight: 425;">
+ A5
+ </div>
+ <div class="testcase" style="font-family:'CSSTest Weights Full'; font-weight: 525;">
+ A6
+ </div>
+ <div class="testcase" style="font-family:'CSSTest Weights Full'; font-weight: 675;">
+ A7
+ </div>
+ <br clear="all">
+ </div>
+
+ <script>
+
+ var base_testcases = document.querySelectorAll('.testcase');
+ for(var i = 0; i < base_testcases.length; i++) {
+ test(
+ assert => { assert_approx_equals(base_testcases[i].getBoundingClientRect().width, 90, 2, "@font-face should be mapped to " + base_testcases[i].style.fontFamily + "."); },
+ "Test native font matching on " + base_testcases[i].style.fontFamily + " for weight " + base_testcases[i].style.fontWeight
+ );
+ }
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-weight-matching.html b/testing/web-platform/tests/css/css-fonts/variations/font-weight-matching.html
new file mode 100644
index 0000000000..5eb9a99f87
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-weight-matching.html
@@ -0,0 +1,135 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Testing new font-matching algorithm for font-weight values introduced in CSS Fonts level 4</title>
+ <link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-matching-algorithm" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <style>
+
+ .testcase {
+ float:left;
+ margin: 5px;
+ font-size:48pt;
+ font-feature-settings: "kern" 1;
+ color: rgba(0,0,0,0.5);
+ background: linear-gradient(to left, lime 0%, lime 91px, red 91px);
+ }
+
+ @font-face {
+ font-family: fontMatch;
+ src: local('CSSTest Weights 900'), url('./resources/csstest-weights-900-kerned.ttf');
+ font-weight: 100;
+ }
+
+ @font-face {
+ font-family: fontMatch;
+ src: local('CSSTest Weights 800'), url('./resources/csstest-weights-800-kerned.ttf');
+ font-weight: 250;
+ }
+
+ @font-face {
+ font-family: fontMatch;
+ src: local('CSSTest Weights 700'), url('./resources/csstest-weights-700-kerned.ttf');
+ font-weight: 400;
+ }
+
+ @font-face {
+ font-family: fontMatch;
+ src: local('CSSTest Weights 600'), url('./resources/csstest-weights-600-kerned.ttf');
+ font-weight: 450;
+ }
+
+ @font-face {
+ font-family: fontMatch;
+ src: local('CSSTest Weights 300'), url('./resources/csstest-weights-300-kerned.ttf');
+ font-weight: 500;
+ }
+
+ @font-face {
+ font-family: fontMatch;
+ src: local('CSSTest Weights 200'), url('./resources/csstest-weights-200-kerned.ttf');
+ font-weight: 750;
+ }
+
+ @font-face {
+ font-family: fontMatch;
+ src: local('CSSTest Weights 100'), url('./resources/csstest-weights-100-kerned.ttf');
+ font-weight: 900;
+ }
+
+ </style>
+</head>
+<body>
+
+ <span style="position: absolute; top: -100vh;">
+ <span style="font-family: fontMatch; font-weight: 100;">A</span>
+ <span style="font-family: fontMatch; font-weight: 250;">A</span>
+ <span style="font-family: fontMatch; font-weight: 400;">A</span>
+ <span style="font-family: fontMatch; font-weight: 450;">A</span>
+ <span style="font-family: fontMatch; font-weight: 500;">A</span>
+ <span style="font-family: fontMatch; font-weight: 750;">A</span>
+ <span style="font-family: fontMatch; font-weight: 900;">A</span>
+ </span>
+
+ <div id="testcases" style="overflow: hidden">
+ <!--
+ These testcases work using the new kerned CSSTest Weights fonts.
+ The letter A and its corresponding numeric digit kern as one character.
+ -->
+ <div class="testcase" style="font-family:'CSSTest Weights W2569'; font-weight: 375;">
+ A2
+ </div>
+ </div>
+
+ <script>
+
+ var testFontFaceMatch = [
+ { weight: 99, expectedFont: "CSSTest Weights 900" },
+ { weight: 100, expectedFont: "CSSTest Weights 900" },
+ { weight: 249, expectedFont: "CSSTest Weights 900" },
+ { weight: 250, expectedFont: "CSSTest Weights 800" },
+ { weight: 399, expectedFont: "CSSTest Weights 800" },
+ { weight: 400, expectedFont: "CSSTest Weights 700" },
+ { weight: 420, expectedFont: "CSSTest Weights 600" },
+ { weight: 470, expectedFont: "CSSTest Weights 300" },
+ { weight: 500, expectedFont: "CSSTest Weights 300" },
+ { weight: 600, expectedFont: "CSSTest Weights 200" },
+ { weight: 750, expectedFont: "CSSTest Weights 200" },
+ { weight: 751, expectedFont: "CSSTest Weights 100" },
+ { weight: 900, expectedFont: "CSSTest Weights 100" },
+ { weight:1000, expectedFont: "CSSTest Weights 100" },
+ ];
+
+ // wait for the fonts to load
+ // -- this should not be necessary if the fonts are installed as required
+ // -- but if they are not, the test is otherwise unstable
+ var once_fonts_are_ready = (document.fonts ? document.fonts.ready : new Promise(function(ready) { window.onload = time => [...document.querySelectorAll('body > span:nth-child(1) > span')].every(e => e.offsetWidth > 20) ? ready() : requestAnimationFrame(window.onload) }));
+
+ var testcases = document.querySelector("#testcases");
+ var testcaseTemplate = document.querySelector('.testcase'); testcaseTemplate.remove();
+ testFontFaceMatch.forEach(function(element) {
+
+ var testcase = testcaseTemplate.cloneNode(true);
+
+ // setup the test case style
+ testcase.style.fontFamily = 'fontMatch';
+ testcase.style.fontWeight = element.weight;
+
+ // create the assertion
+ var assertText = 'A' + /\d/.exec(element.expectedFont)[0];
+ testcase.textContent = assertText;
+
+ // append the testcase
+ testcases.appendChild(testcase);
+
+ // verify the testcase
+ promise_test(
+ assert => once_fonts_are_ready.then(assert => { assert_approx_equals(testcase.getBoundingClientRect().width, 90, 2, "@font-face should be mapped to " + element.expectedFont + "."); }),
+ "Test @font-face matching for weight " + element.weight
+ );
+ });
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-weight-metrics-ref.html b/testing/web-platform/tests/css/css-fonts/variations/font-weight-metrics-ref.html
new file mode 100644
index 0000000000..021586c154
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-weight-metrics-ref.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<title>CSS Fonts - reference</title>
+<link rel="author" title="Jonathan Kew" href="jkew@mozilla.com">
+<meta charset="utf-8">
+
+<style>
+@font-face {
+ font-family: test;
+ font-weight: 900;
+ src: url(resources/Inter.var.subset.ttf);
+}
+div {
+ font: 32px test;
+ position: absolute;
+ margin: 1em;
+}
+.heavy {
+ background: green;
+ color: green;
+ font-weight: 900;
+}
+</style>
+
+Test passes if there is a green rectangle and <strong>no red</strong>:
+
+<div class=heavy>
+aaaaaaaaaaaaaaaaaaaaaaaaaaaa
+</div>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-weight-metrics.html b/testing/web-platform/tests/css/css-fonts/variations/font-weight-metrics.html
new file mode 100644
index 0000000000..f10e591def
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-weight-metrics.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<title>CSS Fonts - Test that variable-font glyph advances depend on applied weight</title>
+<link rel="author" title="Jonathan Kew" href="jkew@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-weight-prop"/>
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-prop-desc"/>
+<link rel="match" href="font-weight-metrics-ref.html">
+<meta name="assert" content="Ensures that glyph advances are adjusted appropriately when the weight axis is varied."/>
+<meta charset="utf-8">
+
+<style>
+@font-face {
+ font-family: test;
+ font-weight: 100 900;
+ src: url(resources/Inter.var.subset.ttf);
+}
+div {
+ font: 32px test;
+ position: absolute;
+ margin: 1em;
+}
+.light {
+ background: red;
+ color: red;
+ font-weight: 100;
+}
+.heavy {
+ background: green;
+ color: green;
+ font-weight: 900;
+}
+</style>
+
+Test passes if there is a green rectangle and <strong>no red</strong>:
+
+<!-- Red background that should be entirely covered by the div with the heavy face -->
+<div class=light>
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+</div>
+
+<!-- The string here is two characters shorter, but the advance width of the heavy
+ glyphs should be large enough that the light div is still completely covered. -->
+<div class=heavy>
+aaaaaaaaaaaaaaaaaaaaaaaaaaaa
+</div>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/font-weight-parsing.html b/testing/web-platform/tests/css/css-fonts/variations/font-weight-parsing.html
new file mode 100644
index 0000000000..657616cd29
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/font-weight-parsing.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Testing the new font-weight values introduced in CSS Fonts level 4</title>
+ <link rel="help" href="https://www.w3.org/TR/css-fonts-4/#font-weight-prop" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+
+ <div id="computedStyleTest">A</div>
+
+ <script>
+
+ var testContinuousWeights = [
+ { weight: "401", isValid: true, message: "Values that are not multiple of 100 should be parsed successfully" },
+ { weight: "400.5", isValid: true, message: "Non-integer Values should be parsed successfully" },
+ { weight: "1", isValid: true, message: "Minimum allowed value should be parsed successfully" },
+ { weight: "0.999", isValid: false, message: "Values below minimum should be rejected" },
+ { weight: "-100", isValid: false, message: "Values below zero should be rejected" },
+ { weight: "1000", isValid: true, message: "Maximum allowed value should be parsed successfully" },
+ { weight: "1000.001", isValid: false, message: "Values above maximum should be rejected" },
+ { weight: "calc(100.5)", isValid: true, expectedWeight: "100.5", message: "Simple calc value" },
+ { weight: "calc(-100)", isValid: true, expectedWeight: "1", message: "Negative simple calc value (to be clamped)" },
+ { weight: "calc(1001)", isValid: true, expectedWeight: "1000", message: "Out-of-range simple calc value (to be clamped)" },
+ { weight: "calc(100.5*3 + 50.5)", isValid: true, expectedWeight: "352", message: "Valid calc expression" },
+ { weight: "calc(100.5*3 + 800)", isValid: true, expectedWeight: "1000", message: "Valid calc expression with out-of-range value (to be clamped)" },
+ { weight: "calc(100.5px + 50.5px)", isValid: false, message: "Valid calc expression with units" },
+ { weight: "400 700", isValid: false, message: "Extra number after numeric value" },
+ { weight: "400 10px", isValid: false, message: "Extra content after numeric value" },
+ { weight: "bold 400", isValid: false, message: "Extra content after keyword value" },
+ { weight: "calc(100.5) 400", isValid: false, message: "Extra content after calc value" }
+ ];
+
+ testContinuousWeights.forEach(function (element) {
+ test(() => { assert_equals(window.CSS.supports("font-weight", element.weight), element.isValid, element.message); }, "@supports: " + element.message);
+ });
+
+ testContinuousWeights.forEach(function (element) {
+ var testElement = document.getElementById("computedStyleTest");
+
+ if (element.isValid) {
+ testElement.style.fontWeight = "300";
+ testElement.style.fontWeight = element.weight;
+ var expectedWeight = (element.expectedWeight) ? element.expectedWeight : element.weight;
+
+ test(() => { assert_equals(window.getComputedStyle(testElement).fontWeight, expectedWeight, element.message); }, "Computed style: " + element.message);
+ }
+ });
+
+ </script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/FontStyleTest-slnt-VF.woff2 b/testing/web-platform/tests/css/css-fonts/variations/resources/FontStyleTest-slnt-VF.woff2
new file mode 100644
index 0000000000..c4d365e88e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/FontStyleTest-slnt-VF.woff2
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/FontStyleTest-slnt_backslant-VF.woff2 b/testing/web-platform/tests/css/css-fonts/variations/resources/FontStyleTest-slnt_backslant-VF.woff2
new file mode 100644
index 0000000000..ea542eb06f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/FontStyleTest-slnt_backslant-VF.woff2
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/Inter.var.subset.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/Inter.var.subset.ttf
new file mode 100644
index 0000000000..d042cabef1
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/Inter.var.subset.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/ahem.ttc b/testing/web-platform/tests/css/css-fonts/variations/resources/ahem.ttc
new file mode 100644
index 0000000000..096dd600a3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/ahem.ttc
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-100-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-100-kerned.ttf
new file mode 100644
index 0000000000..33553bc3d0
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-100-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-1479-w1-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-1479-w1-kerned.ttf
new file mode 100644
index 0000000000..d3add1934c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-1479-w1-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-1479-w4-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-1479-w4-kerned.ttf
new file mode 100644
index 0000000000..813e5da8f2
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-1479-w4-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-1479-w7-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-1479-w7-kerned.ttf
new file mode 100644
index 0000000000..a446f23f58
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-1479-w7-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-1479-w9-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-1479-w9-kerned.ttf
new file mode 100644
index 0000000000..4eb89ad399
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-1479-w9-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-15-w1-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-15-w1-kerned.ttf
new file mode 100644
index 0000000000..78b0f9e5c3
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-15-w1-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-15-w5-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-15-w5-kerned.ttf
new file mode 100644
index 0000000000..ffbb5daa1f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-15-w5-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-200-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-200-kerned.ttf
new file mode 100644
index 0000000000..9713a7de45
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-200-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-24-w2-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-24-w2-kerned.ttf
new file mode 100644
index 0000000000..838d54ae91
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-24-w2-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-24-w4-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-24-w4-kerned.ttf
new file mode 100644
index 0000000000..70bb0529f1
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-24-w4-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-2569-w2-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-2569-w2-kerned.ttf
new file mode 100644
index 0000000000..0af6a94c3b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-2569-w2-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-2569-w5-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-2569-w5-kerned.ttf
new file mode 100644
index 0000000000..7ffd46fae1
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-2569-w5-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-2569-w6-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-2569-w6-kerned.ttf
new file mode 100644
index 0000000000..62c61c6c3f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-2569-w6-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-2569-w9-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-2569-w9-kerned.ttf
new file mode 100644
index 0000000000..dd4fdc0549
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-2569-w9-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-258-w2-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-258-w2-kerned.ttf
new file mode 100644
index 0000000000..8a8a09568b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-258-w2-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-258-w5-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-258-w5-kerned.ttf
new file mode 100644
index 0000000000..e7597aadef
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-258-w5-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-258-w8-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-258-w8-kerned.ttf
new file mode 100644
index 0000000000..dd274d2d69
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-258-w8-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-300-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-300-kerned.ttf
new file mode 100644
index 0000000000..7668bc70ac
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-300-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-3589-w3-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-3589-w3-kerned.ttf
new file mode 100644
index 0000000000..409bbb5fc7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-3589-w3-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-3589-w5-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-3589-w5-kerned.ttf
new file mode 100644
index 0000000000..639cf41a17
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-3589-w5-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-3589-w8-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-3589-w8-kerned.ttf
new file mode 100644
index 0000000000..e5c85c6348
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-3589-w8-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-3589-w9-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-3589-w9-kerned.ttf
new file mode 100644
index 0000000000..25e46520f0
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-3589-w9-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-400-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-400-kerned.ttf
new file mode 100644
index 0000000000..3046e3c634
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-400-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-47-w4-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-47-w4-kerned.ttf
new file mode 100644
index 0000000000..9d95fd95ef
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-47-w4-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-47-w7-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-47-w7-kerned.ttf
new file mode 100644
index 0000000000..796f4d56ad
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-47-w7-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-500-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-500-kerned.ttf
new file mode 100644
index 0000000000..d8d136d5d2
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-500-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-600-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-600-kerned.ttf
new file mode 100644
index 0000000000..ce7307e9aa
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-600-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-700-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-700-kerned.ttf
new file mode 100644
index 0000000000..a80d8688d7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-700-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-800-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-800-kerned.ttf
new file mode 100644
index 0000000000..1fb2730be7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-800-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-900-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-900-kerned.ttf
new file mode 100644
index 0000000000..faf4bbcf2e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-900-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w1-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w1-kerned.ttf
new file mode 100644
index 0000000000..8b4fc0ddc7
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w1-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w2-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w2-kerned.ttf
new file mode 100644
index 0000000000..112683da20
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w2-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w3-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w3-kerned.ttf
new file mode 100644
index 0000000000..d0ffa58d98
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w3-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w4-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w4-kerned.ttf
new file mode 100644
index 0000000000..faab448951
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w4-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w5-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w5-kerned.ttf
new file mode 100644
index 0000000000..df6e7909ae
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w5-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w6-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w6-kerned.ttf
new file mode 100644
index 0000000000..9d4819220e
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w6-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w7-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w7-kerned.ttf
new file mode 100644
index 0000000000..a358362db5
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w7-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w8-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w8-kerned.ttf
new file mode 100644
index 0000000000..458e401df8
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w8-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w9-kerned.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w9-kerned.ttf
new file mode 100644
index 0000000000..006a280997
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/csstest-weights-full-w9-kerned.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/resources/variabletest_box.ttf b/testing/web-platform/tests/css/css-fonts/variations/resources/variabletest_box.ttf
new file mode 100644
index 0000000000..0d5bf3e267
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/resources/variabletest_box.ttf
Binary files differ
diff --git a/testing/web-platform/tests/css/css-fonts/variations/slnt-backslant-variable-ref.html b/testing/web-platform/tests/css/css-fonts/variations/slnt-backslant-variable-ref.html
new file mode 100644
index 0000000000..bbb18ebbaf
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/slnt-backslant-variable-ref.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html lang="en">
+<meta charset="utf-8" />
+<title>CSS Test: Variable fonts with slant axis</title>
+<style>
+ @font-face {
+ font-family: "slnt test font";
+ src: url('resources/FontStyleTest-slnt_backslant-VF.woff2');
+ font-style: oblique -15deg 15deg;
+ }
+
+ .test {
+ font-family: "slnt test font";
+ font-size: 3em;
+ }
+
+ .slnt14 {
+ font-variation-settings: 'slnt' -14;
+ }
+
+ .backslant14 {
+ font-variation-settings: 'slnt' 14;
+ }
+
+</style>
+
+<p class="test backslant14">varfont</p>
+<p class="test slnt14">varfont</p>
+<p class="test slnt14">varfont</p>
+<p class="test">varfont</p>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/slnt-backslant-variable.html b/testing/web-platform/tests/css/css-fonts/variations/slnt-backslant-variable.html
new file mode 100644
index 0000000000..4bbe2b157f
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/slnt-backslant-variable.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html lang="en">
+<meta charset="utf-8" />
+<title>CSS Test: Variable fonts with slant axis</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#descdef-font-face-font-variation-settings" />
+<link rel="help" href="http://w3c.github.io/csswg-drafts/css-fonts-4/#valdef-font-style-oblique-angle-90deg-90deg" />
+<link rel="match" href="slnt-backslant-variable-ref.html">
+<meta name="assert"
+ content="For variable fonts, setting font-style to oblique or italic should apply forward and backward slant to variable axis.">
+<!-- Fonts used in this test are authored by Stephen Nixon, more information in the link:
+https://arrowtype.github.io/vf-slnt-test/index.html -->
+<style>
+ @font-face {
+ font-family: "slnt test font";
+ src: url('resources/FontStyleTest-slnt_backslant-VF.woff2');
+ font-style: oblique -15deg 15deg;
+ }
+
+ .test {
+ font-family: "slnt test font";
+ font-size: 3em;
+ }
+
+ .backslant {
+ font-style: oblique -14deg;
+ }
+
+ .oblique {
+ font-style: oblique;
+ }
+
+ .italic {
+ font-style: italic;
+ }
+
+</style>
+
+<p class="test backslant">varfont</p>
+<p class="test oblique">varfont</p>
+<p class="test italic">varfont</p>
+<p class="test">varfont</p>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/slnt-variable-ref.html b/testing/web-platform/tests/css/css-fonts/variations/slnt-variable-ref.html
new file mode 100644
index 0000000000..75a237c6b2
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/slnt-variable-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html lang="en">
+<meta charset="utf-8" />
+<title>CSS Test: Variable fonts with slant axis</title>
+<style>
+ @font-face {
+ font-family: "slnt test font";
+ src: url('resources/FontStyleTest-slnt-VF.woff2');
+ font-style: oblique 0deg 15deg;
+ }
+
+ .test {
+ font-family: "slnt test font";
+ font-size: 3em;
+ }
+
+ .slnt14 {
+ font-variation-settings: 'slnt' -14;
+ }
+
+</style>
+
+<p class="test slnt14">varfont</p>
+<p class="test slnt14">varfont</p>
+<p class="test">varfont</p>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/slnt-variable.html b/testing/web-platform/tests/css/css-fonts/variations/slnt-variable.html
new file mode 100644
index 0000000000..d81df09c19
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/slnt-variable.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<meta charset="utf-8" />
+<title>CSS Test: Variable fonts with slant axis</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#descdef-font-face-font-variation-settings" />
+<link rel="help" href="http://w3c.github.io/csswg-drafts/css-fonts-4/#valdef-font-style-oblique-angle-90deg-90deg" />
+<link rel="match" href="slnt-variable-ref.html">
+<meta name="assert"
+ content="For variable fonts, 'oblique' and 'italic' keywords should work equivalent to 14 degrees of slant">
+<!-- Fonts used in this test are authored by Stephen Nixon, more information in the link:
+https://arrowtype.github.io/vf-slnt-test/index.html -->
+<style>
+ @font-face {
+ font-family: "slnt test font";
+ src: url('resources/FontStyleTest-slnt-VF.woff2');
+ font-style: oblique 0deg 15deg;
+ }
+
+ .test {
+ font-family: "slnt test font";
+ font-size: 3em;
+ }
+
+ .oblique {
+ font-style: oblique;
+ }
+
+ .italic {
+ font-style: italic;
+ }
+
+</style>
+
+<p class="test oblique">varfont</p>
+<p class="test italic">varfont</p>
+<p class="test">varfont</p>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/variable-box-font-ref.html b/testing/web-platform/tests/css/css-fonts/variations/variable-box-font-ref.html
new file mode 100644
index 0000000000..142b0aa46b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/variable-box-font-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<style>
+ @font-face {
+ font-family: variabletest_box;
+ src: url(resources/variabletest_box.ttf);
+ }
+
+ body {
+ font-family: variabletest_box, sans-serif;
+ font-size: 200px;
+ }
+</style>
+▄ ▀
+<script>
+ document.fonts.ready.then(
+ () => { document.documentElement.classList.remove("reftest-wait"); });
+</script>
+
diff --git a/testing/web-platform/tests/css/css-fonts/variations/variable-box-font.html b/testing/web-platform/tests/css/css-fonts/variations/variable-box-font.html
new file mode 100644
index 0000000000..a9023fabe5
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/variable-box-font.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="match" href="variable-box-font-ref.html">
+<meta charset="utf-8">
+<style>
+ @font-face {
+ font-family: variabletest_box;
+ src: url(resources/variabletest_box.ttf);
+ }
+
+ body {
+ font-family: variabletest_box,
+ sans-serif;
+ font-size: 200px;
+ }
+
+ .a_up {
+ font-variation-settings: "UPWD" 350;
+ }
+</style>
+<!-- The variabletest_box font has an A glyph that looks like a lower half box,
+ with deltas on the 'UPWD' variation axis that allow shifting the box up. At
+ 350, the box is at the top. The font also has two glyphs for UPPER HALF BLOCK
+ and LOWER HALF BLOCK, which look identical to the respective variations of A.
+-->
+A <span class="a_up">A</span>
+<script>
+ document.fonts.ready.then(
+ () => { document.documentElement.classList.remove("reftest-wait"); });
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/variable-gpos-m2b-ref.html b/testing/web-platform/tests/css/css-fonts/variations/variable-gpos-m2b-ref.html
new file mode 100644
index 0000000000..c6b80b1b11
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/variable-gpos-m2b-ref.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<style>
+ @font-face {
+ font-family: variabletest_box;
+ src: url(resources/variabletest_box.ttf);
+ }
+
+ body {
+ font-family: variabletest_box, sans-serif;
+ sans-serif;
+ font-size: 100px;
+ }
+</style>
+M&#x033B; N&#x033B; O&#x033B;
+<script>
+ document.fonts.ready.then(
+ () => { document.documentElement.classList.remove("reftest-wait"); });
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/variable-gpos-m2b.html b/testing/web-platform/tests/css/css-fonts/variations/variable-gpos-m2b.html
new file mode 100644
index 0000000000..c39cce33a6
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/variable-gpos-m2b.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="match" href="variable-gpos-m2b-ref.html">
+<meta charset="utf-8">
+<style>
+ @font-face {
+ font-family: variabletest_box;
+ src: url(resources/variabletest_box.ttf);
+ }
+
+ body {
+ font-family: variabletest_box, sans-serif;
+ sans-serif;
+ font-size: 100px;
+ }
+
+ .gpos_m2b_left {
+ font-variation-settings: "VM2B" 0;
+ }
+
+ .gpos_m2b_middle {
+ font-variation-settings: "VM2B" 500;
+ }
+
+ .gpos_m2b_right {
+ font-variation-settings: "VM2B" 1000;
+ }
+</style>
+<!-- The variabletest_box font has an M glyph saying "m2b pos" that combines
+ with the combining box below. And it has a glyph for combining box below
+ whose mark anchor can be shifted horizontally using the VM2B axis. The font
+ also has N and O glyphs which have fixed shifted base anchor points at the
+ middle and at the right position. In this reftest we check whether
+ applying the VM2B axis works as expected and shifts the mark anchor point
+ left so that the combining mark is placed correctly at the middle and at
+ the right position. The VM2B rendering must be identical to the
+ conventional rendering with the fixed base anchor points. -->
+<span class="gpos_m2b_left">M&#x033B;</span>
+<span class="gpos_m2b_middle">M&#x033B;</span>
+<span class="gpos_m2b_right">M&#x033B;</span>
+<script>
+ document.fonts.ready.then(
+ () => { document.documentElement.classList.remove("reftest-wait"); });
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/variable-gsub-ref.html b/testing/web-platform/tests/css/css-fonts/variations/variable-gsub-ref.html
new file mode 100644
index 0000000000..3b1f7f435c
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/variable-gsub-ref.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<style>
+ @font-face {
+ font-family: variabletest_box;
+ src: url(resources/variabletest_box.ttf);
+ }
+
+ body {
+ font-family: variabletest_box, sans-serif;
+ sans-serif;
+ font-size: 100px;
+ }
+</style>
+r R
+<script>
+ document.fonts.ready.then(
+ () => { document.documentElement.classList.remove("reftest-wait"); });
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/variable-gsub.html b/testing/web-platform/tests/css/css-fonts/variations/variable-gsub.html
new file mode 100644
index 0000000000..ed432f65eb
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/variable-gsub.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="match" href="variable-gsub-ref.html">
+<meta charset="utf-8">
+<style>
+ @font-face {
+ font-family: variabletest_box;
+ src: url(resources/variabletest_box.ttf);
+ }
+
+ body {
+ font-family: variabletest_box, sans-serif;
+ sans-serif;
+ font-size: 100px;
+ }
+
+ .rvrn_replaced {
+ font-variation-settings: "FVTT" 10;
+ }
+</style>
+<!-- The variabletest_box font has an r glyph that says "rvrn base" and has
+ this as a name as well. And it has a glyph for R that says "rvrn subst"
+ where rvrn stands for the required Required Variation Alternates
+ feature. The font has an 'FVTT' axis ranging from 0 to 10, where it uses
+ a single substitution glyph lookup table for axis values starting from
+ 5, which then replaces the rvrn_base glyph with the rvrn_subst
+ glyph. So in this reftest the substituted glyph for lowercase r
+ should visually match the uppercase R glyph, both show "rvrn subst". -->
+r <span class="rvrn_replaced">r</span>
+<script>
+ document.fonts.ready.then(
+ () => { document.documentElement.classList.remove("reftest-wait"); });
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/variable-opsz-ref.html b/testing/web-platform/tests/css/css-fonts/variations/variable-opsz-ref.html
new file mode 100644
index 0000000000..24080345ba
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/variable-opsz-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<style>
+ @font-face {
+ font-family: variabletest_box;
+ src: url(resources/variabletest_box.ttf);
+ }
+
+ body {
+ font-family: variabletest_box, sans-serif;
+ font-optical-sizing: none;
+ }
+</style>
+<div style="font-size: 6px; font-variation-settings: 'opsz' 6;">B</div>
+<div style="font-size: 12px; font-variation-settings: 'opsz' 12;">B</div>
+<div style="font-size: 24px; font-variation-settings: 'opsz' 24;">B</div>
+<div style="font-size: 48px; font-variation-settings: 'opsz' 48;">B</div>
+<div style="font-size: 64px; font-variation-settings: 'opsz' 64;">B</div>
+<div style="font-size: 128px; font-variation-settings: 'opsz' 128;">B</div>
+<div style="font-size: 24px; font-variation-settings: 'opsz' 128;">B</div>
+<div style="font-size: 48px; font-variation-settings: 'opsz' 12;">B</div>
+<script>
+ document.fonts.ready.then(
+ () => { document.documentElement.classList.remove("reftest-wait"); });
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/variable-opsz-size-adjust-ref.html b/testing/web-platform/tests/css/css-fonts/variations/variable-opsz-size-adjust-ref.html
new file mode 100644
index 0000000000..4e88cace35
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/variable-opsz-size-adjust-ref.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<style>
+ @font-face {
+ font-family: variabletest_box;
+ src: url(resources/variabletest_box.ttf);
+ }
+
+ body {
+ font-family: variabletest_box, sans-serif;
+ font-optical-sizing: none;
+ }
+
+ div {
+ line-height: 64px;
+ }
+
+</style>
+<div style="font-size: 9px; font-variation-settings: 'opsz' 9;">B</div>
+<div style="font-size: 18px; font-variation-settings: 'opsz' 18;">B</div>
+<div style="font-size: 36px; font-variation-settings: 'opsz' 36;">B</div>
+<div style="font-size: 72px; font-variation-settings: 'opsz' 72;">B</div>
+<div style="font-size: 96px; font-variation-settings: 'opsz' 96;">B</div>
+<div style="font-size: 36px; font-variation-settings: 'opsz' 128;">B</div>
+<div style="font-size: 72px; font-variation-settings: 'opsz' 12;">B</div>
+<script>
+ document.fonts.ready.then(
+ () => { document.documentElement.classList.remove("reftest-wait"); });
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/variable-opsz-size-adjust.html b/testing/web-platform/tests/css/css-fonts/variations/variable-opsz-size-adjust.html
new file mode 100644
index 0000000000..b673f3cb7b
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/variable-opsz-size-adjust.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="author" title="Dominik Röttsches" href="drott@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-optical-sizing-def"/>
+<link rel="help" href="https://drafts.csswg.org/css-fonts-5/#size-adjust-desc"/>
+<meta name="assert" content="Ensures that optical size is adjusted with size-adjust to displayed font size."/>
+<link rel="match" href="variable-opsz-size-adjust-ref.html">
+<meta charset="utf-8">
+<style>
+ @font-face {
+ font-family: variabletest_box;
+ src: url(resources/variabletest_box.ttf);
+ size-adjust: 150%;
+ }
+
+ body {
+ font-family: variabletest_box, sans-serif;
+ }
+
+ div {
+ line-height: 64px;
+ }
+</style>
+<!-- The variabletest_box font file contains a glyph for letter B which moves a
+ horizontal bar up from the middle for opsz > 12 and moves it down for opsz <
+ 12 where the opsz axis ranges from 6 to 128. -->
+<div style="font-size: 6px;">B</div>
+<div style="font-size: 12px;">B</div>
+<div style="font-size: 24px;">B</div>
+<div style="font-size: 48px;">B</div>
+<div style="font-size: 64px;">B</div>
+<!-- Explicit value overrides auto. -->
+<div style="font-size: 24px; font-variation-settings: 'opsz' 128;">B</div>
+<div style="font-size: 48px; font-optical-sizing: none;">B</div>
+<script>
+ document.fonts.ready.then(
+ () => { document.documentElement.classList.remove("reftest-wait"); });
+</script>
+</html>
diff --git a/testing/web-platform/tests/css/css-fonts/variations/variable-opsz.html b/testing/web-platform/tests/css/css-fonts/variations/variable-opsz.html
new file mode 100644
index 0000000000..d274a47828
--- /dev/null
+++ b/testing/web-platform/tests/css/css-fonts/variations/variable-opsz.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="author" title="Dominik Röttsches" href="drott@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-optical-sizing-def"/>
+<meta name="assert" content="Ensures that optical size is automatically applied."/>
+<link rel="match" href="variable-opsz-ref.html">
+<meta charset="utf-8">
+<style>
+ @font-face {
+ font-family: variabletest_box;
+ src: url(resources/variabletest_box.ttf);
+ }
+
+ body {
+ font-family: variabletest_box, sans-serif;
+ }
+</style>
+<!-- The variabletest_box font file contains a glyph for letter B which moves a
+ horizontal bar up from the middle for opsz > 12 and moves it down for opsz >
+ 12 where the opsz axis ranges from 12 to 128. -->
+<div style="font-size: 6px;">B</div>
+<div style="font-size: 12px;">B</div>
+<div style="font-size: 24px;">B</div>
+<div style="font-size: 48px;">B</div>
+<div style="font-size: 64px;">B</div>
+<div style="font-size: 128px;">B</div>
+<!-- Explicit value overrides auto. -->
+<div style="font-size: 24px; font-variation-settings: 'opsz' 128;">B</div>
+<div style="font-size: 48px; font-optical-sizing: none;">B</div>
+<script>
+ document.fonts.ready.then(
+ () => { document.documentElement.classList.remove("reftest-wait"); });
+</script>
+</html>