Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[CSS Fonts] Implement the from-font value for font-size-adjust
https://bugs.webkit.org/show_bug.cgi?id=254790

Reviewed by Myles C. Maxfield and Tim Nguyen.

The 'from-font' value is newly added to CSS Font Module Level 5 [1], which allows
the browser to automatically determine a font-size-adjust value based on the primary font.
This change implements it.

The following tests have merged into the latest WPT [2] and are backported in this patch.

Test:
    imported/w3c/web-platform-tests/css/css-fonts/font-size-adjust-013.html
    imported/w3c/web-platform-tests/css/css-fonts/parsing/font-size-adjust-computed.html
    imported/w3c/web-platform-tests/css/css-fonts/parsing/font-size-adjust-invalid.html
    imported/w3c/web-platform-tests/css/css-fonts/parsing/font-size-adjust-valid.html

[1] https://www.w3.org/TR/css-fonts-5/#valdef-font-size-adjust-from-font
[2] web-platform-tests/wpt#39380

* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/font-size-adjust-013-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/font-size-adjust-013.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/parsing/font-size-adjust-computed-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/parsing/font-size-adjust-computed.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/parsing/font-size-adjust-invalid-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/parsing/font-size-adjust-invalid.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/parsing/font-size-adjust-valid-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/parsing/font-size-adjust-valid.html:
* Source/WebCore/css/CSSProperties.json:
* Source/WebCore/css/CSSValueKeywords.in:
* Source/WebCore/css/ComputedStyleExtractor.cpp:
(WebCore::fontSizeAdjustFromStyle):
* Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp:
(WebCore::CSSPropertyParserHelpers::consumeFontSizeAdjust):
* Source/WebCore/platform/graphics/FontSizeAdjust.h:
(WebCore::FontSizeAdjust::operator== const):
(WebCore::operator<<):
* Source/WebCore/style/StyleBuilderConverter.h:
(WebCore::Style::BuilderConverter::convertFontSizeAdjust):
* Source/WebCore/style/StyleFontSizeFunctions.cpp:
(WebCore::Style::aspectValueOfPrimaryFont):
* Source/WebCore/style/StyleFontSizeFunctions.h:

Canonical link: https://commits.webkit.org/262800@main
  • Loading branch information
shivamidow committed Apr 11, 2023
1 parent 7279cac commit 0f2621d
Show file tree
Hide file tree
Showing 16 changed files with 339 additions and 23 deletions.
@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Test: font-size-adjust property</title>
<link rel="help" href="https://www.w3.org/TR/css-fonts-5/#font-size-adjust-prop">
<meta name="assert" content="Test whether from-font automatically determines a font-size-adjust value based on the primary font.">
<style>
@font-face {
font-family: 'primary-font-ahem-ex-500';
src: url('./resources/ahem-ex-500.otf');
}
@font-face {
font-family: 'secondary-font-ahem-ex-250';
src: url('./resources/ahem-ex-250.otf');
}
.test {
font-family: 'primary-font-ahem-ex-500', 'secondary-font-ahem-ex-250';
font-size: 50px;
color: peru;
height: 50px;
margin-bottom: 24px;
}
.tall-inline-block {
display: inline-block;
height: 100px;
}
.description {
font-family: serif;
font-size: 16px;
}
</style>
</head>
<body>
<div>
<div class="description">
1. Same glyphs, two 'x' in different spans with two different fonts. The primary font (AhemEx500) has a double aspect value (i.e., x-height/size = 0.5) of the secondary font (AhemEx250). The right glyph is adjusted with font-size-adjust: from-font, so it should be the same size as the left one.
</div>
<div class="test">
<span>xx</span>
</div>
</div>
<div>
<div class="description">
2. Different glyphs 'x' and 'A' in the same span, with two fonts <em>without</em> font-size-adjust. As the primary font does not contain 'A' (U+0041), so the right glyph 'A' falls back to the secondary font. The right glyph should be smaller than the left one.
</div>
<div class="test"><span>xA</span></div>
</div>
<div>
<div class="description">
3. Different glyphs 'x' and 'A' in the same span, with two fonts and font-size-adjust: from-font. The right glyph 'A' cannot be rendered by the primary font, so it individually falls back to the secondary font. However, it should be the same size as the left glyph due to font-size-adjust: from-font.
</div>
<div class="test">
<!-- We are inserting a tall inline-block here to make the position of the baseline independent of the adjusted glyph since on the ref test we don't use font-size-adjust but font-size -->
<span>xx<span class="tall-inline-block"></span></span>
</div>
</div>
</html>
@@ -0,0 +1,62 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Test: font-size-adjust property</title>
<link rel="match" href="font-size-adjust-013-ref.html">
<link rel="help" href="https://www.w3.org/TR/css-fonts-5/#font-size-adjust-prop">
<meta name="assert" content="Test whether from-font automatically determines a font-size-adjust value based on the primary font.">
<style>
@font-face {
font-family: 'primary-font-ahem-ex-500';
src: url('./resources/ahem-ex-500.otf');
}
@font-face {
font-family: 'secondary-font-ahem-ex-250';
src: url('./resources/ahem-ex-250.otf');
}
.adjusted {
font-size-adjust: from-font;
}
.test {
font-family: 'primary-font-ahem-ex-500', 'secondary-font-ahem-ex-250';
font-size: 50px;
color: peru;
height: 50px;
margin-bottom: 24px;
}
.tall-inline-block {
display: inline-block;
height: 100px;
}
.description {
font-family: serif;
font-size: 16px;
}
</style>
</head>
<body>
<div>
<div class="description">
1. Same glyphs, two 'x' in different spans with two different fonts. The primary font (AhemEx500) has a double aspect value (i.e., x-height/size = 0.5) of the secondary font (AhemEx250). The right glyph is adjusted with font-size-adjust: from-font, so it should be the same size as the left one.
</div>
<div class="test">
<span>x</span><span class="adjusted">x</span>
</div>
</div>
<div>
<div class="description">
2. Different glyphs 'x' and 'A' in the same span, with two fonts <em>without</em> font-size-adjust. As the primary font does not contain 'A' (U+0041), so the right glyph 'A' falls back to the secondary font. The right glyph should be smaller than the left one.
</div>
<div class="test"><span>xA</span></div>
</div>
<div>
<div class="description">
3. Different glyphs 'x' and 'A' in the same span, with two fonts and font-size-adjust: from-font. The right glyph 'A' cannot be rendered by the primary font, so it individually falls back to the secondary font. However, it should be the same size as the left glyph due to font-size-adjust: from-font.
</div>
<div class="test">
<!-- We are inserting a tall inline-block here to make the position of the baseline independent of the adjusted glyph since on the ref test we don't use font-size-adjust but font-size -->
<span class="adjusted">xA<span class="tall-inline-block"></span></span>
</div>
</div>
</html>
Expand Up @@ -6,4 +6,10 @@ PASS Property font-size-adjust value 'cap-height 0.8'
PASS Property font-size-adjust value 'ch-width 0.4'
PASS Property font-size-adjust value 'ic-width 0.9'
PASS Property font-size-adjust value 'ic-height 1.1'
PASS Property font-size-adjust value 'from-font'
PASS Property font-size-adjust value 'ex-height from-font'
PASS Property font-size-adjust value 'cap-height from-font'
PASS Property font-size-adjust value 'ch-width from-font'
PASS Property font-size-adjust value 'ic-width from-font'
PASS Property font-size-adjust value 'ic-height from-font'

Expand Up @@ -2,8 +2,8 @@
<html>
<head>
<meta charset="utf-8">
<title>CSS Fonts Module Level 3: getComputedStyle().fontSizeAdjust</title>
<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-size-adjust-prop">
<title>CSS Fonts Module Level 5: getComputedStyle().fontSizeAdjust</title>
<link rel="help" href="https://www.w3.org/TR/css-fonts-5/#font-size-adjust-prop">
<meta name="assert" content="font-size-adjust computed value is as specified.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
Expand All @@ -13,12 +13,20 @@
<div id="target"></div>
<script>
test_computed_value('font-size-adjust', 'none');

test_computed_value('font-size-adjust', '0.5');
test_computed_value('font-size-adjust', 'ex-height 0.5', '0.5'); // default basis 'ex-height' omitted from serialization
test_computed_value('font-size-adjust', 'cap-height 0.8');
test_computed_value('font-size-adjust', 'ch-width 0.4');
test_computed_value('font-size-adjust', 'ic-width 0.9');
test_computed_value('font-size-adjust', 'ic-height 1.1');

test_computed_value('font-size-adjust', 'from-font');
test_computed_value('font-size-adjust', 'ex-height from-font', 'from-font'); // default basis 'ex-height' omitted from serialization
test_computed_value('font-size-adjust', 'cap-height from-font');
test_computed_value('font-size-adjust', 'ch-width from-font');
test_computed_value('font-size-adjust', 'ic-width from-font');
test_computed_value('font-size-adjust', 'ic-height from-font');
</script>
</body>
</html>
Expand Up @@ -5,4 +5,55 @@ PASS e.style['font-size-adjust'] = "0.5 ex-height" should not set the property v
PASS e.style['font-size-adjust'] = "em 1.0" should not set the property value
PASS e.style['font-size-adjust'] = "ch 0.5" should not set the property value
PASS e.style['font-size-adjust'] = "ic 1.0" should not set the property value
PASS e.style['font-size-adjust'] = "ex-height" should not set the property value
PASS e.style['font-size-adjust'] = "cap-height" should not set the property value
PASS e.style['font-size-adjust'] = "ic-height" should not set the property value
PASS e.style['font-size-adjust'] = "ic-width" should not set the property value
PASS e.style['font-size-adjust'] = "ch-width" should not set the property value
PASS e.style['font-size-adjust'] = "ex-height none" should not set the property value
PASS e.style['font-size-adjust'] = "cap-height none" should not set the property value
PASS e.style['font-size-adjust'] = "ic-height none" should not set the property value
PASS e.style['font-size-adjust'] = "ic-width none" should not set the property value
PASS e.style['font-size-adjust'] = "ch-width none" should not set the property value
PASS e.style['font-size-adjust'] = "ex-height ex-height" should not set the property value
PASS e.style['font-size-adjust'] = "cap-height cap-height" should not set the property value
PASS e.style['font-size-adjust'] = "ic-height ic-height" should not set the property value
PASS e.style['font-size-adjust'] = "ic-width ic-width" should not set the property value
PASS e.style['font-size-adjust'] = "ch-width ch-width" should not set the property value
PASS e.style['font-size-adjust'] = "none none" should not set the property value
PASS e.style['font-size-adjust'] = "none 0.5" should not set the property value
PASS e.style['font-size-adjust'] = "none from-font" should not set the property value
PASS e.style['font-size-adjust'] = "from-font none" should not set the property value
PASS e.style['font-size-adjust'] = "from-font 0.5" should not set the property value
PASS e.style['font-size-adjust'] = "from-font ex-height" should not set the property value
PASS e.style['font-size-adjust'] = "from-font cap-height" should not set the property value
PASS e.style['font-size-adjust'] = "from-font ic-height" should not set the property value
PASS e.style['font-size-adjust'] = "from-font ic-width" should not set the property value
PASS e.style['font-size-adjust'] = "from-font ch-width" should not set the property value
PASS e.style['font-size-adjust'] = "from-font from-font" should not set the property value
PASS e.style['font-size-adjust'] = "ex-height from-font from-font" should not set the property value
PASS e.style['font-size-adjust'] = "cap-height from-font from-font" should not set the property value
PASS e.style['font-size-adjust'] = "ic-height from-font from-font" should not set the property value
PASS e.style['font-size-adjust'] = "ic-width from-font from-font" should not set the property value
PASS e.style['font-size-adjust'] = "ch-width from-font from-font" should not set the property value
PASS e.style['font-size-adjust'] = "ex-height from-font 0.5" should not set the property value
PASS e.style['font-size-adjust'] = "cap-height from-font 0.5" should not set the property value
PASS e.style['font-size-adjust'] = "ic-height from-font 0.5" should not set the property value
PASS e.style['font-size-adjust'] = "ic-width from-font 0.5" should not set the property value
PASS e.style['font-size-adjust'] = "ch-width from-font 0.5" should not set the property value
PASS e.style['font-size-adjust'] = "ex-height 0.5 from-font" should not set the property value
PASS e.style['font-size-adjust'] = "cap-height 0.5 from-font" should not set the property value
PASS e.style['font-size-adjust'] = "ic-height 0.5 from-font" should not set the property value
PASS e.style['font-size-adjust'] = "ic-width 0.5 from-font" should not set the property value
PASS e.style['font-size-adjust'] = "ch-width 0.5 from-font" should not set the property value
PASS e.style['font-size-adjust'] = "ex-height from-font none" should not set the property value
PASS e.style['font-size-adjust'] = "cap-height from-font none" should not set the property value
PASS e.style['font-size-adjust'] = "ic-height from-font none" should not set the property value
PASS e.style['font-size-adjust'] = "ic-width from-font none" should not set the property value
PASS e.style['font-size-adjust'] = "ch-width from-font none" should not set the property value
PASS e.style['font-size-adjust'] = "ex-height none from-font" should not set the property value
PASS e.style['font-size-adjust'] = "cap-height none from-font" should not set the property value
PASS e.style['font-size-adjust'] = "ic-height none from-font" should not set the property value
PASS e.style['font-size-adjust'] = "ic-width none from-font" should not set the property value
PASS e.style['font-size-adjust'] = "ch-width none from-font" should not set the property value

Expand Up @@ -2,9 +2,9 @@
<html>
<head>
<meta charset="utf-8">
<title>CSS Fonts Module Level 3: parsing font-size-adjust with invalid values</title>
<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-size-adjust-prop">
<meta name="assert" content="font-size-adjust supports only the grammar 'none | [basis] <number>'.">
<title>CSS Fonts Module Level 5: parsing font-size-adjust with invalid values</title>
<link rel="help" href="https://www.w3.org/TR/css-fonts-5/#font-size-adjust-prop">
<meta name="assert" content="font-size-adjust supports only the grammar 'none | [metric]? [from-font | <number>]'.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/parsing-testcommon.js"></script>
Expand All @@ -17,6 +17,67 @@
test_invalid_value('font-size-adjust', 'em 1.0');
test_invalid_value('font-size-adjust', 'ch 0.5'); // it's 'ch-width', not 'ch'
test_invalid_value('font-size-adjust', 'ic 1.0'); // it's 'ic-width' or 'ic-height', not 'ic'

test_invalid_value('font-size-adjust', 'ex-height');
test_invalid_value('font-size-adjust', 'cap-height');
test_invalid_value('font-size-adjust', 'ic-height');
test_invalid_value('font-size-adjust', 'ic-width');
test_invalid_value('font-size-adjust', 'ch-width');

test_invalid_value('font-size-adjust', 'ex-height none');
test_invalid_value('font-size-adjust', 'cap-height none');
test_invalid_value('font-size-adjust', 'ic-height none');
test_invalid_value('font-size-adjust', 'ic-width none');
test_invalid_value('font-size-adjust', 'ch-width none');

test_invalid_value('font-size-adjust', 'ex-height ex-height');
test_invalid_value('font-size-adjust', 'cap-height cap-height');
test_invalid_value('font-size-adjust', 'ic-height ic-height');
test_invalid_value('font-size-adjust', 'ic-width ic-width');
test_invalid_value('font-size-adjust', 'ch-width ch-width');

test_invalid_value('font-size-adjust', 'none none');
test_invalid_value('font-size-adjust', 'none 0.5');
test_invalid_value('font-size-adjust', 'none from-font');

test_invalid_value('font-size-adjust', 'from-font none');
test_invalid_value('font-size-adjust', 'from-font 0.5');
test_invalid_value('font-size-adjust', 'from-font ex-height');
test_invalid_value('font-size-adjust', 'from-font cap-height');
test_invalid_value('font-size-adjust', 'from-font ic-height');
test_invalid_value('font-size-adjust', 'from-font ic-width');
test_invalid_value('font-size-adjust', 'from-font ch-width');
test_invalid_value('font-size-adjust', 'from-font from-font');

test_invalid_value('font-size-adjust', 'ex-height from-font from-font');
test_invalid_value('font-size-adjust', 'cap-height from-font from-font');
test_invalid_value('font-size-adjust', 'ic-height from-font from-font');
test_invalid_value('font-size-adjust', 'ic-width from-font from-font');
test_invalid_value('font-size-adjust', 'ch-width from-font from-font');

test_invalid_value('font-size-adjust', 'ex-height from-font 0.5');
test_invalid_value('font-size-adjust', 'cap-height from-font 0.5');
test_invalid_value('font-size-adjust', 'ic-height from-font 0.5');
test_invalid_value('font-size-adjust', 'ic-width from-font 0.5');
test_invalid_value('font-size-adjust', 'ch-width from-font 0.5');

test_invalid_value('font-size-adjust', 'ex-height 0.5 from-font');
test_invalid_value('font-size-adjust', 'cap-height 0.5 from-font');
test_invalid_value('font-size-adjust', 'ic-height 0.5 from-font');
test_invalid_value('font-size-adjust', 'ic-width 0.5 from-font');
test_invalid_value('font-size-adjust', 'ch-width 0.5 from-font');

test_invalid_value('font-size-adjust', 'ex-height from-font none');
test_invalid_value('font-size-adjust', 'cap-height from-font none');
test_invalid_value('font-size-adjust', 'ic-height from-font none');
test_invalid_value('font-size-adjust', 'ic-width from-font none');
test_invalid_value('font-size-adjust', 'ch-width from-font none');

test_invalid_value('font-size-adjust', 'ex-height none from-font');
test_invalid_value('font-size-adjust', 'cap-height none from-font');
test_invalid_value('font-size-adjust', 'ic-height none from-font');
test_invalid_value('font-size-adjust', 'ic-width none from-font');
test_invalid_value('font-size-adjust', 'ch-width none from-font');
</script>
</body>
</html>
Expand Up @@ -6,4 +6,10 @@ PASS e.style['font-size-adjust'] = "cap-height 0.8" should set the property valu
PASS e.style['font-size-adjust'] = "ch-width 0.4" should set the property value
PASS e.style['font-size-adjust'] = "ic-width 0.9" should set the property value
PASS e.style['font-size-adjust'] = "ic-height 0.9" should set the property value
PASS e.style['font-size-adjust'] = "from-font" should set the property value
PASS e.style['font-size-adjust'] = "ex-height from-font" should set the property value
PASS e.style['font-size-adjust'] = "cap-height from-font" should set the property value
PASS e.style['font-size-adjust'] = "ch-width from-font" should set the property value
PASS e.style['font-size-adjust'] = "ic-width from-font" should set the property value
PASS e.style['font-size-adjust'] = "ic-height from-font" should set the property value

Expand Up @@ -2,22 +2,30 @@
<html>
<head>
<meta charset="utf-8">
<title>CSS Fonts Module Level 3: parsing font-size-adjust with valid values</title>
<link rel="help" href="https://www.w3.org/TR/css-fonts-3/#font-size-adjust-prop">
<meta name="assert" content="font-size-adjust supports the full grammar 'none | [basis] <number>'.">
<title>CSS Fonts Module Level 5: parsing font-size-adjust with valid values</title>
<link rel="help" href="https://www.w3.org/TR/css-fonts-5/#font-size-adjust-prop">
<meta name="assert" content="font-size-adjust supports the full grammar 'none | [metric]? [from-font | <number>]'.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/parsing-testcommon.js"></script>
</head>
<body>
<script>
test_valid_value('font-size-adjust', 'none');

test_valid_value('font-size-adjust', '0.5');
test_valid_value('font-size-adjust', 'ex-height 0.5', '0.5'); // default basis 'ex' omitted from serialization
test_valid_value('font-size-adjust', 'cap-height 0.8');
test_valid_value('font-size-adjust', 'ch-width 0.4');
test_valid_value('font-size-adjust', 'ic-width 0.9');
test_valid_value('font-size-adjust', 'ic-height 0.9');

test_valid_value('font-size-adjust', 'from-font');
test_valid_value('font-size-adjust', 'ex-height from-font', 'from-font'); // default basis 'ex' omitted from serialization
test_valid_value('font-size-adjust', 'cap-height from-font');
test_valid_value('font-size-adjust', 'ch-width from-font');
test_valid_value('font-size-adjust', 'ic-width from-font');
test_valid_value('font-size-adjust', 'ic-height from-font');
</script>
</body>
</html>

0 comments on commit 0f2621d

Please sign in to comment.