LibWeb/CSS: Add the text-rendering property

This commit is contained in:
Tim Ledbetter 2025-06-27 07:03:05 +01:00 committed by Sam Atkins
commit 68035a2b8d
Notes: github-actions[bot] 2025-06-27 15:53:08 +00:00
19 changed files with 106 additions and 10 deletions

View file

@ -792,6 +792,12 @@ TextOverflow ComputedProperties::text_overflow() const
return keyword_to_text_overflow(value.to_keyword()).release_value();
}
TextRendering ComputedProperties::text_rendering() const
{
auto const& value = property(PropertyID::TextRendering);
return keyword_to_text_rendering(value.to_keyword()).release_value();
}
PointerEvents ComputedProperties::pointer_events() const
{
auto const& value = property(PropertyID::PointerEvents);

View file

@ -83,6 +83,7 @@ public:
TextAlign text_align() const;
TextJustify text_justify() const;
TextOverflow text_overflow() const;
TextRendering text_rendering() const;
Length border_spacing_horizontal(Layout::Node const&) const;
Length border_spacing_vertical(Layout::Node const&) const;
CaptionSide caption_side() const;

View file

@ -121,6 +121,7 @@ public:
static CSS::TextOverflow text_overflow() { return CSS::TextOverflow::Clip; }
static CSS::LengthPercentage text_indent() { return CSS::Length::make_px(0); }
static CSS::TextWrapMode text_wrap_mode() { return CSS::TextWrapMode::Wrap; }
static CSS::TextRendering text_rendering() { return CSS::TextRendering::Auto; }
static CSS::Display display() { return CSS::Display { CSS::DisplayOutside::Inline, CSS::DisplayInside::Flow }; }
static Color color() { return Color::Black; }
static Color stop_color() { return Color::Black; }
@ -437,6 +438,7 @@ public:
CSS::TextJustify text_justify() const { return m_inherited.text_justify; }
CSS::LengthPercentage const& text_indent() const { return m_inherited.text_indent; }
CSS::TextWrapMode text_wrap_mode() const { return m_inherited.text_wrap_mode; }
CSS::TextRendering text_rendering() const { return m_inherited.text_rendering; }
Vector<CSS::TextDecorationLine> const& text_decoration_line() const { return m_noninherited.text_decoration_line; }
CSS::LengthPercentage const& text_decoration_thickness() const { return m_noninherited.text_decoration_thickness; }
CSS::TextDecorationStyle text_decoration_style() const { return m_noninherited.text_decoration_style; }
@ -645,6 +647,7 @@ protected:
CSS::TextTransform text_transform { InitialValues::text_transform() };
CSS::LengthPercentage text_indent { InitialValues::text_indent() };
CSS::TextWrapMode text_wrap_mode { InitialValues::text_wrap_mode() };
CSS::TextRendering text_rendering { InitialValues::text_rendering() };
CSS::WhiteSpaceCollapse white_space_collapse { InitialValues::white_space_collapse() };
CSS::WordBreak word_break { InitialValues::word_break() };
CSS::LengthOrCalculated word_spacing { InitialValues::word_spacing() };
@ -851,6 +854,7 @@ public:
void set_text_indent(CSS::LengthPercentage value) { m_inherited.text_indent = move(value); }
void set_text_wrap_mode(CSS::TextWrapMode value) { m_inherited.text_wrap_mode = value; }
void set_text_overflow(CSS::TextOverflow value) { m_noninherited.text_overflow = value; }
void set_text_rendering(CSS::TextRendering value) { m_inherited.text_rendering = value; }
void set_webkit_text_fill_color(Color value) { m_inherited.webkit_text_fill_color = value; }
void set_position(CSS::Positioning position) { m_noninherited.position = position; }
void set_white_space_collapse(CSS::WhiteSpaceCollapse value) { m_inherited.white_space_collapse = value; }

View file

@ -633,6 +633,12 @@
"clip",
"ellipsis"
],
"text-rendering": [
"auto",
"optimizespeed",
"optimizelegibility",
"geometricprecision"
],
"text-transform": [
"capitalize",
"full-size-kana",

View file

@ -216,6 +216,7 @@
"full-size-kana",
"full-width",
"fullscreen",
"geometricprecision",
"grab",
"grabbing",
"grammar-error",
@ -360,6 +361,7 @@
"on",
"opaque",
"open-quote",
"optimizelegibility",
"optimizequality",
"optimizespeed",
"optional",

View file

@ -3003,6 +3003,15 @@
"text-overflow"
]
},
"text-rendering": {
"affects-layout": false,
"animation-type": "discrete",
"inherited": true,
"initial": "auto",
"valid-types": [
"text-rendering"
]
},
"text-shadow": {
"affects-layout": false,
"animation-type": "custom",

View file

@ -651,6 +651,7 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style)
computed_values.set_text_align(computed_style.text_align());
computed_values.set_text_justify(computed_style.text_justify());
computed_values.set_text_overflow(computed_style.text_overflow());
computed_values.set_text_rendering(computed_style.text_rendering());
if (auto text_indent = computed_style.length_percentage(CSS::PropertyID::TextIndent); text_indent.has_value())
computed_values.set_text_indent(text_indent.release_value());

View file

@ -76,6 +76,7 @@ static Array const attribute_style_properties {
NamedPropertyID(CSS::PropertyID::StrokeOpacity),
NamedPropertyID(CSS::PropertyID::StrokeWidth),
NamedPropertyID(CSS::PropertyID::TextAnchor),
NamedPropertyID(CSS::PropertyID::TextRendering),
NamedPropertyID(CSS::PropertyID::TextOverflow),
NamedPropertyID(CSS::PropertyID::TransformOrigin),
NamedPropertyID(CSS::PropertyID::UnicodeBidi),

View file

@ -56,6 +56,7 @@ All properties associated with getComputedStyle(document.body):
"text-decoration-line",
"text-indent",
"text-justify",
"text-rendering",
"text-shadow",
"text-transform",
"text-wrap-mode",

View file

@ -618,6 +618,8 @@ All supported properties and their default values exposed from CSSStylePropertie
'text-justify': 'auto'
'textOverflow': 'clip'
'text-overflow': 'clip'
'textRendering': 'auto'
'text-rendering': 'auto'
'textShadow': 'none'
'text-shadow': 'none'
'textTransform': 'none'

View file

@ -54,6 +54,7 @@ text-anchor: start
text-decoration-line: none
text-indent: 0px
text-justify: auto
text-rendering: auto
text-shadow: none
text-transform: none
text-wrap-mode: wrap
@ -88,7 +89,7 @@ background-position-x: 0%
background-position-y: 0%
background-repeat: repeat
background-size: auto auto
block-size: 1350px
block-size: 1365px
border-block-end-color: rgb(0, 0, 0)
border-block-end-style: none
border-block-end-width: 0px
@ -153,7 +154,7 @@ grid-row-start: auto
grid-template-areas: none
grid-template-columns: none
grid-template-rows: none
height: 2325px
height: 2340px
inline-size: 784px
inset-block-end: auto
inset-block-start: auto

View file

@ -1,8 +1,8 @@
Harness status: OK
Found 236 tests
Found 237 tests
230 Pass
231 Pass
6 Fail
Pass accent-color
Pass border-collapse
@ -58,6 +58,7 @@ Pass text-anchor
Pass text-decoration-line
Pass text-indent
Pass text-justify
Pass text-rendering
Pass text-shadow
Pass text-transform
Pass text-wrap-mode

View file

@ -0,0 +1,7 @@
Harness status: OK
Found 2 tests
2 Pass
Pass e.style['text-rendering'] = "crispedges" should not set the property value
Pass e.style['text-rendering'] = "auto optimizespeed" should not set the property value

View file

@ -0,0 +1,9 @@
Harness status: OK
Found 4 tests
4 Pass
Pass e.style['text-rendering'] = "auto" should set the property value
Pass e.style['text-rendering'] = "optimizespeed" should set the property value
Pass e.style['text-rendering'] = "optimizelegibility" should set the property value
Pass e.style['text-rendering'] = "geometricprecision" should set the property value

View file

@ -1,8 +1,8 @@
Harness status: OK
Found 42 tests
Found 43 tests
38 Pass
39 Pass
4 Fail
Pass clip-path presentation attribute supported on an irrelevant element
Pass clip-rule presentation attribute supported on an irrelevant element
@ -40,6 +40,7 @@ Pass stroke-width presentation attribute supported on an irrelevant element
Pass text-anchor presentation attribute supported on an irrelevant element
Fail text-decoration presentation attribute supported on an irrelevant element
Pass text-overflow presentation attribute supported on an irrelevant element
Pass text-rendering presentation attribute supported on an irrelevant element
Pass transform-origin presentation attribute supported on an irrelevant element
Pass unicode-bidi presentation attribute supported on an irrelevant element
Pass visibility presentation attribute supported on an irrelevant element

View file

@ -1,8 +1,8 @@
Harness status: OK
Found 52 tests
Found 53 tests
41 Pass
42 Pass
11 Fail
Pass clip-path presentation attribute supported on a relevant element
Pass clip-rule presentation attribute supported on a relevant element
@ -46,6 +46,7 @@ Pass stroke-width presentation attribute supported on a relevant element
Pass text-anchor presentation attribute supported on a relevant element
Fail text-decoration presentation attribute supported on a relevant element
Pass text-overflow presentation attribute supported on a relevant element
Pass text-rendering presentation attribute supported on a relevant element
Pass transform-origin presentation attribute supported on a relevant element
Fail transform presentation attribute supported on a relevant element
Pass unicode-bidi presentation attribute supported on a relevant element

View file

@ -1,8 +1,8 @@
Harness status: OK
Found 42 tests
Found 43 tests
38 Pass
39 Pass
4 Fail
Pass clip-path presentation attribute supported on an unknown SVG element
Pass clip-rule presentation attribute supported on an unknown SVG element
@ -40,6 +40,7 @@ Pass stroke-width presentation attribute supported on an unknown SVG element
Pass text-anchor presentation attribute supported on an unknown SVG element
Fail text-decoration presentation attribute supported on an unknown SVG element
Pass text-overflow presentation attribute supported on an unknown SVG element
Pass text-rendering presentation attribute supported on an unknown SVG element
Pass transform-origin presentation attribute supported on an unknown SVG element
Pass unicode-bidi presentation attribute supported on an unknown SVG element
Pass visibility presentation attribute supported on an unknown SVG element

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:h="http://www.w3.org/1999/xhtml"
width="800px" height="800px">
<title>SVG Painting: parsing text-rendering with invalid values</title>
<metadata>
<h:link rel="help" href="https://svgwg.org/svg2-draft/painting.html#TextRenderingProperty"/>
<h:meta name="assert" content="text-rendering supports only the grammar 'auto | optimizeSpeed | optimizeLegibility | geometricPrecision'."/>
</metadata>
<g id="target"></g>
<h:script src="../../../resources/testharness.js"/>
<h:script src="../../../resources/testharnessreport.js"/>
<h:script src="../../../css/support/parsing-testcommon.js"/>
<script><![CDATA[
test_invalid_value("text-rendering", "crispedges");
test_invalid_value("text-rendering", "auto optimizespeed");
]]></script>
</svg>

After

Width:  |  Height:  |  Size: 856 B

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:h="http://www.w3.org/1999/xhtml"
width="800px" height="800px">
<title>SVG Painting: parsing text-rendering with valid values</title>
<metadata>
<h:link rel="help" href="https://svgwg.org/svg2-draft/painting.html#TextRenderingProperty"/>
<h:meta name="assert" content="text-rendering supports the full grammar 'auto | optimizeSpeed | optimizeLegibility | geometricPrecision'."/>
</metadata>
<g id="target"></g>
<h:script src="../../../resources/testharness.js"/>
<h:script src="../../../resources/testharnessreport.js"/>
<h:script src="../../../css/support/parsing-testcommon.js"/>
<script><![CDATA[
test_valid_value("text-rendering", "auto");
test_valid_value("text-rendering", "optimizespeed");
test_valid_value("text-rendering", "optimizelegibility");
test_valid_value("text-rendering", "geometricprecision");
]]></script>
</svg>

After

Width:  |  Height:  |  Size: 955 B