diff --git a/Libraries/LibWeb/CSS/CSSStyleValue.h b/Libraries/LibWeb/CSS/CSSStyleValue.h index bda98af5a53..44270280333 100644 --- a/Libraries/LibWeb/CSS/CSSStyleValue.h +++ b/Libraries/LibWeb/CSS/CSSStyleValue.h @@ -393,7 +393,7 @@ public: virtual ValueComparingNonnullRefPtr absolutized(CSSPixelRect const& viewport_rect, Length::FontMetrics const& font_metrics, Length::FontMetrics const& root_font_metrics) const; - virtual Color to_color(Optional, CalculationResolutionContext const&) const { return {}; } + virtual Optional to_color(Optional, CalculationResolutionContext const&) const { return {}; } Keyword to_keyword() const; virtual String to_string(SerializationMode) const = 0; diff --git a/Libraries/LibWeb/CSS/ComputedProperties.cpp b/Libraries/LibWeb/CSS/ComputedProperties.cpp index 89fcae0c53f..047c43c8450 100644 --- a/Libraries/LibWeb/CSS/ComputedProperties.cpp +++ b/Libraries/LibWeb/CSS/ComputedProperties.cpp @@ -226,7 +226,7 @@ Color ComputedProperties::color_or_fallback(PropertyID id, Layout::NodeWithStyle auto const& value = property(id); if (!value.has_color()) return fallback; - return value.to_color(node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(node) }); + return value.to_color(node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(node) }).value(); } // https://drafts.csswg.org/css-color-adjust-1/#determine-the-used-color-scheme @@ -447,7 +447,7 @@ Color ComputedProperties::flood_color(Layout::NodeWithStyle const& node) const { auto const& value = property(PropertyID::FloodColor); if (value.has_color()) { - return value.to_color(node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(node) }); + return value.to_color(node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(node) }).value(); } return InitialValues::flood_color(); @@ -940,7 +940,7 @@ Color ComputedProperties::caret_color(Layout::NodeWithStyle const& node) const return node.computed_values().color(); if (value.has_color()) - return value.to_color(node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(node) }); + return value.to_color(node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(node) }).value(); return InitialValues::caret_color(); } @@ -1203,7 +1203,7 @@ Vector ComputedProperties::shadow(PropertyID property_id, Layout::No maybe_offset_y.release_value(), maybe_blur_radius.release_value(), maybe_spread_distance.release_value(), - value.color()->to_color(as(layout_node), { .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }), + value.color()->to_color(as(layout_node), { .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value(), value.placement() }; }; @@ -1826,7 +1826,7 @@ Color ComputedProperties::stop_color() const // FIXME: This is used by the SVGStopElement, which does not participate in layout, so we can't pass a layout // node or CalculationResolutionContext. This means we don't support all valid colors (e.g. palette // colors, calculated values which depend on length resolution, etc) - return value->to_color({}, {}); + return value->to_color({}, {}).value_or(Color::Black); } return Color::Black; } @@ -1910,8 +1910,8 @@ ScrollbarColorData ComputedProperties::scrollbar_color(Layout::NodeWithStyle con if (value.is_scrollbar_color()) { auto& scrollbar_color_value = value.as_scrollbar_color(); - auto thumb_color = scrollbar_color_value.thumb_color()->to_color(layout_node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }); - auto track_color = scrollbar_color_value.track_color()->to_color(layout_node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }); + auto thumb_color = scrollbar_color_value.thumb_color()->to_color(layout_node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value(); + auto track_color = scrollbar_color_value.track_color()->to_color(layout_node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(layout_node) }).value(); return { thumb_color, track_color }; } diff --git a/Libraries/LibWeb/CSS/Interpolation.cpp b/Libraries/LibWeb/CSS/Interpolation.cpp index 4e16edda07d..568fd1e1021 100644 --- a/Libraries/LibWeb/CSS/Interpolation.cpp +++ b/Libraries/LibWeb/CSS/Interpolation.cpp @@ -688,13 +688,25 @@ RefPtr interpolate_box_shadow(DOM::Element& element, Calcul auto interpolated_spread_distance = interpolate_value(element, calculation_context, from_shadow.spread_distance(), to_shadow.spread_distance(), delta, allow_discrete); if (!interpolated_offset_x || !interpolated_offset_y || !interpolated_blur_radius || !interpolated_spread_distance) return {}; + auto color_syntax = ColorSyntax::Legacy; if ((!from_shadow.color()->is_keyword() && from_shadow.color()->as_color().color_syntax() == ColorSyntax::Modern) || (!to_shadow.color()->is_keyword() && to_shadow.color()->as_color().color_syntax() == ColorSyntax::Modern)) { color_syntax = ColorSyntax::Modern; } + + // FIXME: If we aren't able to resolve the colors here, we should postpone interpolation until we can (perhaps + // by creating something similar to a ColorMixStyleValue). + auto from_color = from_shadow.color()->to_color(layout_node, resolution_context); + auto to_color = to_shadow.color()->to_color(layout_node, resolution_context); + + Color interpolated_color = Color::Black; + + if (from_color.has_value() && to_color.has_value()) + interpolated_color = interpolate_color(from_color.value(), to_color.value(), delta, color_syntax); + auto result_shadow = ShadowStyleValue::create( - CSSColorValue::create_from_color(interpolate_color(from_shadow.color()->to_color(layout_node, resolution_context), to_shadow.color()->to_color(layout_node, resolution_context), delta, color_syntax), ColorSyntax::Modern), + CSSColorValue::create_from_color(interpolated_color, ColorSyntax::Modern), *interpolated_offset_x, *interpolated_offset_y, *interpolated_blur_radius, @@ -817,7 +829,18 @@ static RefPtr interpolate_value_impl(DOM::Element& element, || (!to.is_keyword() && to.as_color().color_syntax() == ColorSyntax::Modern)) { color_syntax = ColorSyntax::Modern; } - return CSSColorValue::create_from_color(interpolate_color(from.to_color(layout_node, resolution_context), to.to_color(layout_node, resolution_context), delta, color_syntax), ColorSyntax::Modern); + + // FIXME: If we aren't able to resolve the colors here, we should postpone interpolation until we can (perhaps + // by creating something similar to a ColorMixStyleValue). + auto from_color = from.to_color(layout_node, resolution_context); + auto to_color = to.to_color(layout_node, resolution_context); + + Color interpolated_color = Color::Black; + + if (from_color.has_value() && to_color.has_value()) + interpolated_color = interpolate_color(from_color.value(), to_color.value(), delta, color_syntax); + + return CSSColorValue::create_from_color(interpolated_color, ColorSyntax::Modern); } case CSSStyleValue::Type::Edge: { auto resolved_from = from.as_edge().resolved_value(calculation_context); diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSColorValue.cpp b/Libraries/LibWeb/CSS/StyleValues/CSSColorValue.cpp index 4822f04ffe5..a5e4048b0a5 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CSSColorValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/CSSColorValue.cpp @@ -52,16 +52,26 @@ Optional CSSColorValue::resolve_hue(CSSStyleValue const& style_value, Ca return normalized(style_value.as_angle().angle().to_degrees()); if (style_value.is_calculated()) { - if (style_value.as_calculated().resolves_to_number()) - return normalized(style_value.as_calculated().resolve_number_deprecated(resolution_context).value()); + if (style_value.as_calculated().resolves_to_number()) { + auto maybe_number = style_value.as_calculated().resolve_number(resolution_context); - if (style_value.as_calculated().resolves_to_angle()) - return normalized(style_value.as_calculated().resolve_angle_deprecated(resolution_context).value().to_degrees()); + if (!maybe_number.has_value()) + return {}; + + return normalized(maybe_number.value()); + } + + if (style_value.as_calculated().resolves_to_angle()) { + auto maybe_angle = style_value.as_calculated().resolve_angle(resolution_context); + + if (!maybe_angle.has_value()) + return {}; + + return normalized(maybe_angle.value().to_degrees()); + } } - if (style_value.is_keyword() && style_value.to_keyword() == Keyword::None) - return 0; - return {}; + return 0; } Optional CSSColorValue::resolve_with_reference_value(CSSStyleValue const& style_value, float one_hundred_percent_value, CalculationResolutionContext const& resolution_context) @@ -79,16 +89,26 @@ Optional CSSColorValue::resolve_with_reference_value(CSSStyleValue const if (style_value.is_calculated()) { auto const& calculated = style_value.as_calculated(); - if (calculated.resolves_to_number()) - return calculated.resolve_number_deprecated(resolution_context).value(); - if (calculated.resolves_to_percentage()) - return normalize_percentage(calculated.resolve_percentage_deprecated(resolution_context).value()); + if (calculated.resolves_to_number()) { + auto maybe_number = calculated.resolve_number(resolution_context); + + if (!maybe_number.has_value()) + return {}; + + return maybe_number.value(); + } + + if (calculated.resolves_to_percentage()) { + auto percentage = calculated.resolve_percentage(resolution_context); + + if (!percentage.has_value()) + return {}; + + return normalize_percentage(percentage.value()); + } } - if (style_value.is_keyword() && style_value.to_keyword() == Keyword::None) - return 0; - - return {}; + return 0; } Optional CSSColorValue::resolve_alpha(CSSStyleValue const& style_value, CalculationResolutionContext const& resolution_context) @@ -108,16 +128,29 @@ Optional CSSColorValue::resolve_alpha(CSSStyleValue const& style_value, if (style_value.is_calculated()) { auto const& calculated = style_value.as_calculated(); - if (calculated.resolves_to_number()) - return normalized(calculated.resolve_number_deprecated(resolution_context).value()); - if (calculated.resolves_to_percentage()) - return normalized(calculated.resolve_percentage_deprecated(resolution_context).value().as_fraction()); + if (calculated.resolves_to_number()) { + auto maybe_number = calculated.resolve_number(resolution_context); + + if (!maybe_number.has_value()) + return {}; + + return normalized(maybe_number.value()); + } + + if (calculated.resolves_to_percentage()) { + auto percentage = calculated.resolve_percentage(resolution_context); + + if (!percentage.has_value()) + return {}; + + return normalized(percentage.value().as_fraction()); + } } if (style_value.is_keyword() && style_value.to_keyword() == Keyword::None) return 0; - return {}; + return 1; } void CSSColorValue::serialize_color_component(StringBuilder& builder, SerializationMode mode, CSSStyleValue const& component, float one_hundred_percent_value, Optional clamp_min, Optional clamp_max) const @@ -130,7 +163,16 @@ void CSSColorValue::serialize_color_component(StringBuilder& builder, Serializat builder.append(component.to_string(mode)); return; } - auto resolved_value = resolve_with_reference_value(component, one_hundred_percent_value, {}).value_or(0); + + auto maybe_resolved_value = resolve_with_reference_value(component, one_hundred_percent_value, {}); + + if (!maybe_resolved_value.has_value()) { + builder.append(component.to_string(mode)); + return; + } + + auto resolved_value = maybe_resolved_value.value(); + if (clamp_min.has_value() && resolved_value < *clamp_min) resolved_value = *clamp_min; if (clamp_max.has_value() && resolved_value > *clamp_max) @@ -153,8 +195,15 @@ void CSSColorValue::serialize_alpha_component(StringBuilder& builder, Serializat builder.append(component.to_string(mode)); return; } - auto resolved_value = resolve_alpha(component, {}).value_or(0); - builder.appendff("{}", resolved_value); + + auto maybe_resolved_value = resolve_alpha(component, {}); + + if (!maybe_resolved_value.has_value()) { + builder.append(component.to_string(mode)); + return; + } + + builder.appendff("{}", maybe_resolved_value.value()); } void CSSColorValue::serialize_hue_component(StringBuilder& builder, SerializationMode mode, CSSStyleValue const& component) const @@ -167,7 +216,15 @@ void CSSColorValue::serialize_hue_component(StringBuilder& builder, Serializatio builder.append(component.to_string(mode)); return; } - builder.appendff("{:.4}", resolve_hue(component, {}).value_or(0)); + + auto maybe_resolved_value = resolve_hue(component, {}); + + if (!maybe_resolved_value.has_value()) { + builder.append(component.to_string(mode)); + return; + } + + builder.appendff("{:.4}", maybe_resolved_value.value()); } } diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSHSL.cpp b/Libraries/LibWeb/CSS/StyleValues/CSSHSL.cpp index 255d957fb93..8407592dc39 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CSSHSL.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/CSSHSL.cpp @@ -11,14 +11,17 @@ namespace Web::CSS { -Color CSSHSL::to_color(Optional, CalculationResolutionContext const& resolution_context) const +Optional CSSHSL::to_color(Optional, CalculationResolutionContext const& resolution_context) const { - auto const h_val = resolve_hue(m_properties.h, resolution_context).value_or(0); - auto const s_val = resolve_with_reference_value(m_properties.s, 100.0, resolution_context).value_or(0); - auto const l_val = resolve_with_reference_value(m_properties.l, 100.0, resolution_context).value_or(0); - auto const alpha_val = resolve_alpha(m_properties.alpha, resolution_context).value_or(1); + auto h_val = resolve_hue(m_properties.h, resolution_context); + auto s_val = resolve_with_reference_value(m_properties.s, 100.0, resolution_context); + auto l_val = resolve_with_reference_value(m_properties.l, 100.0, resolution_context); + auto alpha_val = resolve_alpha(m_properties.alpha, resolution_context); - return Color::from_hsla(h_val, s_val / 100.0f, l_val / 100.0f, alpha_val); + if (!h_val.has_value() || !s_val.has_value() || !l_val.has_value() || !alpha_val.has_value()) + return {}; + + return Color::from_hsla(h_val.value(), s_val.value() / 100.0f, l_val.value() / 100.0f, alpha_val.value()); } bool CSSHSL::equals(CSSStyleValue const& other) const @@ -35,8 +38,11 @@ bool CSSHSL::equals(CSSStyleValue const& other) const // https://www.w3.org/TR/css-color-4/#serializing-sRGB-values String CSSHSL::to_string(SerializationMode) const { + if (auto color = to_color({}, {}); color.has_value()) + return serialize_a_srgb_value(color.value()); + // FIXME: Do this properly, taking unresolved calculated values into account. - return serialize_a_srgb_value(to_color({}, {})); + return ""_string; } } diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSHSL.h b/Libraries/LibWeb/CSS/StyleValues/CSSHSL.h index ba39cd44a9f..2238ee1bce5 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CSSHSL.h +++ b/Libraries/LibWeb/CSS/StyleValues/CSSHSL.h @@ -29,7 +29,7 @@ public: CSSStyleValue const& l() const { return *m_properties.l; } CSSStyleValue const& alpha() const { return *m_properties.alpha; } - virtual Color to_color(Optional, CalculationResolutionContext const&) const override; + virtual Optional to_color(Optional, CalculationResolutionContext const&) const override; virtual String to_string(SerializationMode) const override; diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSHWB.cpp b/Libraries/LibWeb/CSS/StyleValues/CSSHWB.cpp index 8c4ea5fb62c..7dfb31d83ef 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CSSHWB.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/CSSHWB.cpp @@ -11,24 +11,30 @@ namespace Web::CSS { -Color CSSHWB::to_color(Optional, CalculationResolutionContext const& resolution_context) const +Optional CSSHWB::to_color(Optional, CalculationResolutionContext const& resolution_context) const { - auto const h_val = resolve_hue(m_properties.h, resolution_context).value_or(0); - auto const w_val = clamp(resolve_with_reference_value(m_properties.w, 100.0, resolution_context).value_or(0), 0, 100) / 100.0f; - auto const b_val = clamp(resolve_with_reference_value(m_properties.b, 100.0, resolution_context).value_or(0), 0, 100) / 100.0f; - auto const alpha_val = resolve_alpha(m_properties.alpha, resolution_context).value_or(1); + auto h_val = resolve_hue(m_properties.h, resolution_context); + auto raw_w_value = resolve_with_reference_value(m_properties.w, 100.0, resolution_context); + auto raw_b_value = resolve_with_reference_value(m_properties.b, 100.0, resolution_context); + auto alpha_val = resolve_alpha(m_properties.alpha, resolution_context); + + if (!h_val.has_value() || !raw_w_value.has_value() || !raw_b_value.has_value() || !alpha_val.has_value()) + return {}; + + auto w_val = clamp(raw_w_value.value(), 0, 100) / 100.0f; + auto b_val = clamp(raw_b_value.value(), 0, 100) / 100.0f; if (w_val + b_val >= 1.0f) { auto to_byte = [](float value) { return round_to(clamp(value * 255.0f, 0.0f, 255.0f)); }; u8 gray = to_byte(w_val / (w_val + b_val)); - return Color(gray, gray, gray, to_byte(alpha_val)); + return Color(gray, gray, gray, to_byte(alpha_val.value())); } auto value = 1 - b_val; auto saturation = 1 - (w_val / value); - return Color::from_hsv(h_val, saturation, value).with_opacity(alpha_val); + return Color::from_hsv(h_val.value(), saturation, value).with_opacity(alpha_val.value()); } bool CSSHWB::equals(CSSStyleValue const& other) const @@ -45,8 +51,11 @@ bool CSSHWB::equals(CSSStyleValue const& other) const // https://www.w3.org/TR/css-color-4/#serializing-sRGB-values String CSSHWB::to_string(SerializationMode) const { + if (auto color = to_color({}, {}); color.has_value()) + return serialize_a_srgb_value(color.value()); + // FIXME: Do this properly, taking unresolved calculated values into account. - return serialize_a_srgb_value(to_color({}, {})); + return ""_string; } } diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSHWB.h b/Libraries/LibWeb/CSS/StyleValues/CSSHWB.h index 16e4aaf5755..6561d54d9a5 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CSSHWB.h +++ b/Libraries/LibWeb/CSS/StyleValues/CSSHWB.h @@ -29,7 +29,7 @@ public: CSSStyleValue const& b() const { return *m_properties.b; } CSSStyleValue const& alpha() const { return *m_properties.alpha; } - virtual Color to_color(Optional, CalculationResolutionContext const&) const override; + virtual Optional to_color(Optional, CalculationResolutionContext const&) const override; virtual String to_string(SerializationMode) const override; diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSKeywordValue.cpp b/Libraries/LibWeb/CSS/StyleValues/CSSKeywordValue.cpp index e72405745fc..d31abe32497 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CSSKeywordValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/CSSKeywordValue.cpp @@ -135,7 +135,7 @@ bool CSSKeywordValue::has_color() const return is_color(keyword()); } -Color CSSKeywordValue::to_color(Optional node, CalculationResolutionContext const&) const +Optional CSSKeywordValue::to_color(Optional node, CalculationResolutionContext const&) const { if (keyword() == Keyword::Currentcolor) { if (!node.has_value() || !node->has_style()) diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSKeywordValue.h b/Libraries/LibWeb/CSS/StyleValues/CSSKeywordValue.h index 5a8ab43caba..6dc79386250 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CSSKeywordValue.h +++ b/Libraries/LibWeb/CSS/StyleValues/CSSKeywordValue.h @@ -51,7 +51,7 @@ public: static bool is_color(Keyword); virtual bool has_color() const override; - virtual Color to_color(Optional node, CalculationResolutionContext const&) const override; + virtual Optional to_color(Optional node, CalculationResolutionContext const&) const override; virtual String to_string(SerializationMode) const override; bool properties_equal(CSSKeywordValue const& other) const { return m_keyword == other.m_keyword; } diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSLCHLike.cpp b/Libraries/LibWeb/CSS/StyleValues/CSSLCHLike.cpp index b466473bc14..03f6fe5713f 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CSSLCHLike.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/CSSLCHLike.cpp @@ -27,14 +27,20 @@ bool CSSLCHLike::equals(CSSStyleValue const& other) const return m_properties == other_oklch_like.m_properties; } -Color CSSLCH::to_color(Optional, CalculationResolutionContext const& resolution_context) const +Optional CSSLCH::to_color(Optional, CalculationResolutionContext const& resolution_context) const { - auto const l_val = clamp(resolve_with_reference_value(m_properties.l, 100, resolution_context).value_or(0), 0, 100); - auto const c_val = resolve_with_reference_value(m_properties.c, 150, resolution_context).value_or(0); - auto const h_val = AK::to_radians(resolve_hue(m_properties.h, resolution_context).value_or(0)); - auto const alpha_val = resolve_alpha(m_properties.alpha, resolution_context).value_or(1); + auto raw_l_val = resolve_with_reference_value(m_properties.l, 100, resolution_context); + auto c_val = resolve_with_reference_value(m_properties.c, 150, resolution_context); + auto raw_h_val = resolve_hue(m_properties.h, resolution_context); + auto alpha_val = resolve_alpha(m_properties.alpha, resolution_context); - return Color::from_lab(l_val, c_val * cos(h_val), c_val * sin(h_val), alpha_val); + if (!raw_l_val.has_value() || !c_val.has_value() || !raw_h_val.has_value() || !alpha_val.has_value()) + return {}; + + auto l_val = clamp(raw_l_val.value(), 0, 100); + auto h_val = AK::to_radians(raw_h_val.value()); + + return Color::from_lab(l_val, c_val.value() * cos(h_val), c_val.value() * sin(h_val), alpha_val.value()); } // https://www.w3.org/TR/css-color-4/#serializing-lab-lch @@ -57,14 +63,21 @@ String CSSLCH::to_string(SerializationMode mode) const return MUST(builder.to_string()); } -Color CSSOKLCH::to_color(Optional, CalculationResolutionContext const& resolution_context) const +Optional CSSOKLCH::to_color(Optional, CalculationResolutionContext const& resolution_context) const { - auto const l_val = clamp(resolve_with_reference_value(m_properties.l, 1.0, resolution_context).value_or(0), 0, 1); - auto const c_val = max(resolve_with_reference_value(m_properties.c, 0.4, resolution_context).value_or(0), 0); - auto const h_val = AK::to_radians(resolve_hue(m_properties.h, resolution_context).value_or(0)); - auto const alpha_val = resolve_alpha(m_properties.alpha, resolution_context).value_or(1); + auto raw_l_val = resolve_with_reference_value(m_properties.l, 1.0, resolution_context); + auto raw_c_val = resolve_with_reference_value(m_properties.c, 0.4, resolution_context); + auto raw_h_val = resolve_hue(m_properties.h, resolution_context); + auto alpha_val = resolve_alpha(m_properties.alpha, resolution_context); - return Color::from_oklab(l_val, c_val * cos(h_val), c_val * sin(h_val), alpha_val); + if (!raw_l_val.has_value() || !raw_c_val.has_value() || !raw_h_val.has_value() || !alpha_val.has_value()) + return {}; + + auto l_val = clamp(raw_l_val.value(), 0, 1); + auto c_val = max(raw_c_val.value(), 0); + auto h_val = AK::to_radians(raw_h_val.value()); + + return Color::from_oklab(l_val, c_val * cos(h_val), c_val * sin(h_val), alpha_val.value()); } // https://www.w3.org/TR/css-color-4/#serializing-oklab-oklch diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSLCHLike.h b/Libraries/LibWeb/CSS/StyleValues/CSSLCHLike.h index a054846ba34..37acfcf616a 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CSSLCHLike.h +++ b/Libraries/LibWeb/CSS/StyleValues/CSSLCHLike.h @@ -56,7 +56,7 @@ public: } virtual ~CSSLCH() override = default; - virtual Color to_color(Optional, CalculationResolutionContext const&) const override; + virtual Optional to_color(Optional, CalculationResolutionContext const&) const override; virtual String to_string(SerializationMode) const override; }; @@ -70,7 +70,7 @@ public: } virtual ~CSSOKLCH() override = default; - virtual Color to_color(Optional, CalculationResolutionContext const&) const override; + virtual Optional to_color(Optional, CalculationResolutionContext const&) const override; virtual String to_string(SerializationMode) const override; }; diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSLabLike.cpp b/Libraries/LibWeb/CSS/StyleValues/CSSLabLike.cpp index 8e40560ec2c..918b72b8225 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CSSLabLike.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/CSSLabLike.cpp @@ -26,14 +26,17 @@ bool CSSLabLike::equals(CSSStyleValue const& other) const return m_properties == other_lab_like.m_properties; } -Color CSSOKLab::to_color(Optional, CalculationResolutionContext const& resolution_context) const +Optional CSSOKLab::to_color(Optional, CalculationResolutionContext const& resolution_context) const { - auto const l_val = clamp(resolve_with_reference_value(m_properties.l, 1.0, resolution_context).value_or(0), 0, 1); - auto const a_val = resolve_with_reference_value(m_properties.a, 0.4, resolution_context).value_or(0); - auto const b_val = resolve_with_reference_value(m_properties.b, 0.4, resolution_context).value_or(0); - auto const alpha_val = resolve_alpha(m_properties.alpha, resolution_context).value_or(1); + auto const l_val = resolve_with_reference_value(m_properties.l, 1.0, resolution_context); + auto const a_val = resolve_with_reference_value(m_properties.a, 0.4, resolution_context); + auto const b_val = resolve_with_reference_value(m_properties.b, 0.4, resolution_context); + auto const alpha_val = resolve_alpha(m_properties.alpha, resolution_context); - return Color::from_oklab(l_val, a_val, b_val, alpha_val); + if (!l_val.has_value() || !a_val.has_value() || !b_val.has_value() || !alpha_val.has_value()) + return {}; + + return Color::from_oklab(clamp(l_val.value(), 0, 1), a_val.value(), b_val.value(), alpha_val.value()); } // https://www.w3.org/TR/css-color-4/#serializing-oklab-oklch @@ -56,14 +59,17 @@ String CSSOKLab::to_string(SerializationMode mode) const return MUST(builder.to_string()); } -Color CSSLab::to_color(Optional, CalculationResolutionContext const& resolution_context) const +Optional CSSLab::to_color(Optional, CalculationResolutionContext const& resolution_context) const { - auto const l_val = clamp(resolve_with_reference_value(m_properties.l, 100, resolution_context).value_or(0), 0, 100); - auto const a_val = resolve_with_reference_value(m_properties.a, 125, resolution_context).value_or(0); - auto const b_val = resolve_with_reference_value(m_properties.b, 125, resolution_context).value_or(0); - auto const alpha_val = resolve_alpha(m_properties.alpha, resolution_context).value_or(1); + auto l_val = resolve_with_reference_value(m_properties.l, 100, resolution_context); + auto a_val = resolve_with_reference_value(m_properties.a, 125, resolution_context); + auto b_val = resolve_with_reference_value(m_properties.b, 125, resolution_context); + auto alpha_val = resolve_alpha(m_properties.alpha, resolution_context); - return Color::from_lab(l_val, a_val, b_val, alpha_val); + if (!l_val.has_value() || !a_val.has_value() || !b_val.has_value() || !alpha_val.has_value()) + return {}; + + return Color::from_lab(clamp(l_val.value(), 0, 100), a_val.value(), b_val.value(), alpha_val.value()); } // https://www.w3.org/TR/css-color-4/#serializing-lab-lch diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSLabLike.h b/Libraries/LibWeb/CSS/StyleValues/CSSLabLike.h index 4dde22cff55..ea476950df7 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CSSLabLike.h +++ b/Libraries/LibWeb/CSS/StyleValues/CSSLabLike.h @@ -51,7 +51,7 @@ protected: // https://drafts.css-houdini.org/css-typed-om-1/#cssoklab class CSSOKLab final : public CSSLabLike { public: - virtual Color to_color(Optional, CalculationResolutionContext const&) const override; + virtual Optional to_color(Optional, CalculationResolutionContext const&) const override; virtual String to_string(SerializationMode) const override; CSSOKLab(Badge, ValueComparingNonnullRefPtr l, ValueComparingNonnullRefPtr a, ValueComparingNonnullRefPtr b, ValueComparingNonnullRefPtr alpha) @@ -63,7 +63,7 @@ public: // https://drafts.css-houdini.org/css-typed-om-1/#csslab class CSSLab final : public CSSLabLike { public: - virtual Color to_color(Optional, CalculationResolutionContext const&) const override; + virtual Optional to_color(Optional, CalculationResolutionContext const&) const override; virtual String to_string(SerializationMode) const override; CSSLab(Badge, ValueComparingNonnullRefPtr l, ValueComparingNonnullRefPtr a, ValueComparingNonnullRefPtr b, ValueComparingNonnullRefPtr alpha) diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSLightDark.cpp b/Libraries/LibWeb/CSS/StyleValues/CSSLightDark.cpp index 4341c7689dc..faa4e86b5bb 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CSSLightDark.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/CSSLightDark.cpp @@ -9,7 +9,7 @@ namespace Web::CSS { -Color CSSLightDark::to_color(Optional node, CalculationResolutionContext const& resolution_context) const +Optional CSSLightDark::to_color(Optional node, CalculationResolutionContext const& resolution_context) const { if (node.has_value() && node.value().computed_values().color_scheme() == PreferredColorScheme::Dark) return m_properties.dark->to_color(node, resolution_context); diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSLightDark.h b/Libraries/LibWeb/CSS/StyleValues/CSSLightDark.h index 6477b429cea..090235cbe16 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CSSLightDark.h +++ b/Libraries/LibWeb/CSS/StyleValues/CSSLightDark.h @@ -21,7 +21,7 @@ public: } virtual bool equals(CSSStyleValue const&) const override; - virtual Color to_color(Optional, CalculationResolutionContext const&) const override; + virtual Optional to_color(Optional, CalculationResolutionContext const&) const override; virtual String to_string(SerializationMode) const override; private: diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSRGB.cpp b/Libraries/LibWeb/CSS/StyleValues/CSSRGB.cpp index 0b094cc8983..b7dd0f3928e 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CSSRGB.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/CSSRGB.cpp @@ -14,7 +14,7 @@ namespace Web::CSS { -Color CSSRGB::to_color(Optional, CalculationResolutionContext const& resolution_context) const +Optional CSSRGB::to_color(Optional, CalculationResolutionContext const& resolution_context) const { auto resolve_rgb_to_u8 = [&resolution_context](CSSStyleValue const& style_value) -> Optional { // | | none @@ -32,16 +32,26 @@ Color CSSRGB::to_color(Optional, CalculationResolu if (style_value.is_calculated()) { auto const& calculated = style_value.as_calculated(); - if (calculated.resolves_to_number()) - return normalized(calculated.resolve_number_deprecated(resolution_context).value()); - if (calculated.resolves_to_percentage()) - return normalized(calculated.resolve_percentage_deprecated(resolution_context).value().value() * 255 / 100); + if (calculated.resolves_to_number()) { + auto maybe_number = calculated.resolve_number(resolution_context); + + if (!maybe_number.has_value()) + return {}; + + return normalized(maybe_number.value()); + } + + if (calculated.resolves_to_percentage()) { + auto maybe_percentage = calculated.resolve_percentage(resolution_context); + + if (!maybe_percentage.has_value()) + return {}; + + return normalized(maybe_percentage.value().value() * 255 / 100); + } } - if (style_value.is_keyword() && style_value.to_keyword() == Keyword::None) - return 0; - - return {}; + return 0; }; auto resolve_alpha_to_u8 = [&resolution_context](CSSStyleValue const& style_value) -> Optional { @@ -51,12 +61,15 @@ Color CSSRGB::to_color(Optional, CalculationResolu return {}; }; - u8 const r_val = resolve_rgb_to_u8(m_properties.r).value_or(0); - u8 const g_val = resolve_rgb_to_u8(m_properties.g).value_or(0); - u8 const b_val = resolve_rgb_to_u8(m_properties.b).value_or(0); - u8 const alpha_val = resolve_alpha_to_u8(m_properties.alpha).value_or(255); + auto r_val = resolve_rgb_to_u8(m_properties.r); + auto g_val = resolve_rgb_to_u8(m_properties.g); + auto b_val = resolve_rgb_to_u8(m_properties.b); + auto alpha_val = resolve_alpha_to_u8(m_properties.alpha); - return Color(r_val, g_val, b_val, alpha_val); + if (!r_val.has_value() || !g_val.has_value() || !b_val.has_value() || !alpha_val.has_value()) + return {}; + + return Color(r_val.value(), g_val.value(), b_val.value(), alpha_val.value()); } bool CSSRGB::equals(CSSStyleValue const& other) const @@ -73,10 +86,14 @@ bool CSSRGB::equals(CSSStyleValue const& other) const // https://www.w3.org/TR/css-color-4/#serializing-sRGB-values String CSSRGB::to_string(SerializationMode mode) const { - // FIXME: Do this properly, taking unresolved calculated values into account. if (mode != SerializationMode::ResolvedValue && m_properties.name.has_value()) return m_properties.name.value().to_string().to_ascii_lowercase(); - return serialize_a_srgb_value(to_color({}, {})); + + if (auto color = to_color({}, {}); color.has_value()) + return serialize_a_srgb_value(color.value()); + + // FIXME: Do this properly, taking unresolved calculated values into account. + return ""_string; } } diff --git a/Libraries/LibWeb/CSS/StyleValues/CSSRGB.h b/Libraries/LibWeb/CSS/StyleValues/CSSRGB.h index 67d6892343b..e1ba07efa9f 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CSSRGB.h +++ b/Libraries/LibWeb/CSS/StyleValues/CSSRGB.h @@ -29,7 +29,7 @@ public: CSSStyleValue const& b() const { return *m_properties.b; } CSSStyleValue const& alpha() const { return *m_properties.alpha; } - virtual Color to_color(Optional, CalculationResolutionContext const&) const override; + virtual Optional to_color(Optional, CalculationResolutionContext const&) const override; virtual String to_string(SerializationMode) const override; diff --git a/Libraries/LibWeb/CSS/StyleValues/ColorFunctionStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/ColorFunctionStyleValue.cpp index 6c3a4475496..b95b0f2e260 100644 --- a/Libraries/LibWeb/CSS/StyleValues/ColorFunctionStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/ColorFunctionStyleValue.cpp @@ -82,13 +82,22 @@ bool ColorFunctionStyleValue::equals(CSSStyleValue const& other) const return m_properties == other_lab_like.m_properties; } -ColorFunctionStyleValue::Resolved ColorFunctionStyleValue::resolve_properties(CalculationResolutionContext const& resolution_context) const +Optional ColorFunctionStyleValue::resolve_properties(CalculationResolutionContext const& resolution_context) const { - float const c1 = resolve_with_reference_value(m_properties.channels[0], 1, resolution_context).value_or(0); - float const c2 = resolve_with_reference_value(m_properties.channels[1], 1, resolution_context).value_or(0); - float const c3 = resolve_with_reference_value(m_properties.channels[2], 1, resolution_context).value_or(0); - float const alpha_val = resolve_alpha(m_properties.alpha, resolution_context).value_or(1); - return { .channels = { c1, c2, c3 }, .alpha = alpha_val }; + auto c1 = resolve_with_reference_value(m_properties.channels[0], 1, resolution_context); + auto c2 = resolve_with_reference_value(m_properties.channels[1], 1, resolution_context); + auto c3 = resolve_with_reference_value(m_properties.channels[2], 1, resolution_context); + auto alpha = resolve_alpha(m_properties.alpha, resolution_context); + + if (!c1.has_value() || !c2.has_value() || !c3.has_value() || !alpha.has_value()) + return {}; + + float const c1_value = c1.value(); + float const c2_value = c2.value(); + float const c3_value = c3.value(); + float const alpha_value = alpha.value(); + + return ColorFunctionStyleValue::Resolved { .channels = { c1_value, c2_value, c3_value }, .alpha = alpha_value }; } // https://www.w3.org/TR/css-color-4/#serializing-color-function-values @@ -102,14 +111,14 @@ String ColorFunctionStyleValue::to_string(SerializationMode mode) const CalculationResolutionContext context {}; auto const& calculated = value->as_calculated(); if (calculated.resolves_to_percentage()) { - if (auto resolved_percentage = calculated.resolve_percentage_deprecated(context); resolved_percentage.has_value()) { + if (auto resolved_percentage = calculated.resolve_percentage(context); resolved_percentage.has_value()) { auto resolved_number = resolved_percentage->value() / 100; if (!isfinite(resolved_number)) resolved_number = 0; return NumberStyleValue::create(resolved_number); } } else if (calculated.resolves_to_number()) { - if (auto resolved_number = calculated.resolve_number_deprecated(context); resolved_number.has_value()) + if (auto resolved_number = calculated.resolve_number(context); resolved_number.has_value()) return NumberStyleValue::create(*resolved_number); } } @@ -144,9 +153,14 @@ String ColorFunctionStyleValue::to_string(SerializationMode mode) const convert_percentage(m_properties.channels[2])->to_string(mode))); } -Color ColorFunctionStyleValue::to_color(Optional, CalculationResolutionContext const& resolution_context) const +Optional ColorFunctionStyleValue::to_color(Optional, CalculationResolutionContext const& resolution_context) const { - auto [channels, alpha_val] = resolve_properties(resolution_context); + auto properties = resolve_properties(resolution_context); + + if (!properties.has_value()) + return {}; + + auto [channels, alpha_val] = properties.value(); auto c1 = channels[0]; auto c2 = channels[1]; auto c3 = channels[2]; diff --git a/Libraries/LibWeb/CSS/StyleValues/ColorFunctionStyleValue.h b/Libraries/LibWeb/CSS/StyleValues/ColorFunctionStyleValue.h index 7f1489a6833..7c6a1e22e68 100644 --- a/Libraries/LibWeb/CSS/StyleValues/ColorFunctionStyleValue.h +++ b/Libraries/LibWeb/CSS/StyleValues/ColorFunctionStyleValue.h @@ -18,7 +18,7 @@ public: static ValueComparingNonnullRefPtr create(StringView color_space, ValueComparingNonnullRefPtr c1, ValueComparingNonnullRefPtr c2, ValueComparingNonnullRefPtr c3, ValueComparingRefPtr alpha = {}); virtual bool equals(CSSStyleValue const&) const override; - virtual Color to_color(Optional, CalculationResolutionContext const& resolution_context) const override; + virtual Optional to_color(Optional, CalculationResolutionContext const& resolution_context) const override; virtual String to_string(SerializationMode) const override; virtual bool is_color_function() const override { return true; } @@ -43,7 +43,7 @@ private: float alpha {}; }; - Resolved resolve_properties(CalculationResolutionContext const& resolution_context) const; + Optional resolve_properties(CalculationResolutionContext const& resolution_context) const; Properties m_properties; }; diff --git a/Libraries/LibWeb/CSS/StyleValues/ColorMixStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/ColorMixStyleValue.cpp index a8f65d1d62e..05dfcbe67b0 100644 --- a/Libraries/LibWeb/CSS/StyleValues/ColorMixStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/ColorMixStyleValue.cpp @@ -175,15 +175,19 @@ ColorMixStyleValue::PercentageNormalizationResult ColorMixStyleValue::normalize_ } // https://drafts.csswg.org/css-color-5/#color-mix-result -Color ColorMixStyleValue::to_color(Optional node, CalculationResolutionContext const& resolution_context) const +Optional ColorMixStyleValue::to_color(Optional node, CalculationResolutionContext const& resolution_context) const { // FIXME: Take the color space and hue interpolation method into account. // The current implementation only uses oklab interpolation. auto normalized_percentages = normalize_percentages(); - auto from_color = m_properties.first_component.color; - auto to_color = m_properties.second_component.color; + auto from_color = m_properties.first_component.color->to_color(node, resolution_context); + auto to_color = m_properties.second_component.color->to_color(node, resolution_context); auto delta = normalized_percentages.p2.value() / 100; - return interpolate_color(from_color->to_color(node, resolution_context), to_color->to_color(node, resolution_context), delta, ColorSyntax::Modern); + + if (!from_color.has_value() || !to_color.has_value()) + return {}; + + return interpolate_color(from_color.value(), to_color.value(), delta, ColorSyntax::Modern); } } diff --git a/Libraries/LibWeb/CSS/StyleValues/ColorMixStyleValue.h b/Libraries/LibWeb/CSS/StyleValues/ColorMixStyleValue.h index 6ed7d495346..a540527c01c 100644 --- a/Libraries/LibWeb/CSS/StyleValues/ColorMixStyleValue.h +++ b/Libraries/LibWeb/CSS/StyleValues/ColorMixStyleValue.h @@ -30,7 +30,7 @@ public: static ValueComparingNonnullRefPtr create(ColorInterpolationMethod, ColorMixComponent first_component, ColorMixComponent second_component); virtual bool equals(CSSStyleValue const&) const override; - virtual Color to_color(Optional, CalculationResolutionContext const&) const override; + virtual Optional to_color(Optional, CalculationResolutionContext const&) const override; virtual String to_string(SerializationMode) const override; private: diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp index ec3e67991f0..0b8d767ceb3 100644 --- a/Libraries/LibWeb/DOM/Document.cpp +++ b/Libraries/LibWeb/DOM/Document.cpp @@ -1677,7 +1677,7 @@ void Document::obtain_theme_color() resolution_context.length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*html_element()->layout_node()); } - theme_color = css_value->to_color(root_node, resolution_context); + theme_color = css_value->to_color(root_node, resolution_context).value(); return TraversalDecision::Break; } } diff --git a/Libraries/LibWeb/Editing/Internal/Algorithms.cpp b/Libraries/LibWeb/Editing/Internal/Algorithms.cpp index 1f7e5619efd..cc8d165d5ab 100644 --- a/Libraries/LibWeb/Editing/Internal/Algorithms.cpp +++ b/Libraries/LibWeb/Editing/Internal/Algorithms.cpp @@ -1175,7 +1175,7 @@ Optional effective_command_value(GC::Ptr node, FlyString cons return NumericLimits::max(); VERIFY(is(node->layout_node())); auto& layout_node = *static_cast(node->layout_node()); - return background_color.value()->to_color(layout_node, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(layout_node) }).alpha(); + return background_color.value()->to_color(layout_node, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(layout_node) }).value().alpha(); }; while (resolved_background_alpha() == 0 && node->parent() && is(*node->parent())) node = node->parent(); diff --git a/Libraries/LibWeb/HTML/Canvas/CanvasFillStrokeStyles.h b/Libraries/LibWeb/HTML/Canvas/CanvasFillStrokeStyles.h index 4991abc51f7..315affbfab1 100644 --- a/Libraries/LibWeb/HTML/Canvas/CanvasFillStrokeStyles.h +++ b/Libraries/LibWeb/HTML/Canvas/CanvasFillStrokeStyles.h @@ -52,7 +52,7 @@ public: resolution_context.length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*context->layout_node()); } - auto parsedValue = style_value->to_color(layout_node, resolution_context); + auto parsedValue = style_value->to_color(layout_node, resolution_context).value_or(Color::Black); // 4. Set this's fill style to parsedValue. my_drawing_state().fill_style = parsedValue; @@ -105,7 +105,7 @@ public: resolution_context.length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*context->layout_node()); } - auto parsedValue = style_value->to_color(layout_node, resolution_context); + auto parsedValue = style_value->to_color(layout_node, resolution_context).value_or(Color::Black); // 4. Set this's stroke style to parsedValue. my_drawing_state().stroke_style = parsedValue; diff --git a/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp b/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp index 9add19b58fe..dde096c4fd1 100644 --- a/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp +++ b/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp @@ -950,7 +950,7 @@ void CanvasRenderingContext2D::set_shadow_color(String color) resolution_context.length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*node); } - auto parsedValue = style_value->to_color(layout_node, resolution_context); + auto parsedValue = style_value->to_color(layout_node, resolution_context).value_or(Color::Black); // 4. Set this's shadow color to parsedValue. drawing_state().shadow_color = parsedValue; diff --git a/Libraries/LibWeb/HTML/OffscreenCanvasRenderingContext2D.cpp b/Libraries/LibWeb/HTML/OffscreenCanvasRenderingContext2D.cpp index 2018f6e4f22..2a256ff34bd 100644 --- a/Libraries/LibWeb/HTML/OffscreenCanvasRenderingContext2D.cpp +++ b/Libraries/LibWeb/HTML/OffscreenCanvasRenderingContext2D.cpp @@ -288,7 +288,7 @@ void OffscreenCanvasRenderingContext2D::set_shadow_color(String color) // 2. Let parsedValue be the result of parsing the given value with context if non-null. auto style_value = parse_css_value(CSS::Parser::ParsingParams(), color, CSS::PropertyID::Color); if (style_value && style_value->has_color()) { - auto parsedValue = style_value->to_color({}, {}); + auto parsedValue = style_value->to_color({}, {}).value_or(Color::Black); // 4. Set this's shadow color to parsedValue. drawing_state().shadow_color = parsedValue; diff --git a/Libraries/LibWeb/Layout/Node.cpp b/Libraries/LibWeb/Layout/Node.cpp index 92879bdafb0..07820f08737 100644 --- a/Libraries/LibWeb/Layout/Node.cpp +++ b/Libraries/LibWeb/Layout/Node.cpp @@ -835,7 +835,7 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style) do_border_style(computed_values.border_bottom(), CSS::PropertyID::BorderBottomWidth, CSS::PropertyID::BorderBottomColor, CSS::PropertyID::BorderBottomStyle); if (auto const& outline_color = computed_style.property(CSS::PropertyID::OutlineColor); outline_color.has_color()) - computed_values.set_outline_color(outline_color.to_color(*this, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*this) })); + computed_values.set_outline_color(outline_color.to_color(*this, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*this) }).value()); if (auto const& outline_offset = computed_style.property(CSS::PropertyID::OutlineOffset); outline_offset.is_length()) computed_values.set_outline_offset(outline_offset.as_length().length()); computed_values.set_outline_style(computed_style.outline_style()); @@ -875,16 +875,16 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style) auto const& fill = computed_style.property(CSS::PropertyID::Fill); if (fill.has_color()) - computed_values.set_fill(fill.to_color(*this, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*this) })); + computed_values.set_fill(fill.to_color(*this, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*this) }).value()); else if (fill.is_url()) computed_values.set_fill(fill.as_url().url()); auto const& stroke = computed_style.property(CSS::PropertyID::Stroke); if (stroke.has_color()) - computed_values.set_stroke(stroke.to_color(*this, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*this) })); + computed_values.set_stroke(stroke.to_color(*this, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*this) }).value()); else if (stroke.is_url()) computed_values.set_stroke(stroke.as_url().url()); if (auto const& stop_color = computed_style.property(CSS::PropertyID::StopColor); stop_color.has_color()) - computed_values.set_stop_color(stop_color.to_color(*this, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*this) })); + computed_values.set_stop_color(stop_color.to_color(*this, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*this) }).value()); auto const& stroke_width = computed_style.property(CSS::PropertyID::StrokeWidth); // FIXME: Converting to pixels isn't really correct - values should be in "user units" // https://svgwg.org/svg2-draft/coords.html#TermUserUnits diff --git a/Libraries/LibWeb/Painting/BorderPainting.cpp b/Libraries/LibWeb/Painting/BorderPainting.cpp index 087ba2c33a5..70a307cc152 100644 --- a/Libraries/LibWeb/Painting/BorderPainting.cpp +++ b/Libraries/LibWeb/Painting/BorderPainting.cpp @@ -587,7 +587,7 @@ Optional borders_data_for_outline(Layout::Node const& layout_node, // `auto` lets us do whatever we want for the outline. 2px of the accent colour seems reasonable. line_style = CSS::LineStyle::Solid; // NOTE: CalculationResolutionContext is not required here as Accentcolor keyword value is guaranteed to not rely on it to resolve. - outline_color = CSS::CSSKeywordValue::create(CSS::Keyword::Accentcolor)->to_color(*static_cast(&layout_node), {}); + outline_color = CSS::CSSKeywordValue::create(CSS::Keyword::Accentcolor)->to_color(*static_cast(&layout_node), {}).value(); outline_width = 2; } else { line_style = CSS::keyword_to_line_style(CSS::to_keyword(outline_style)).value_or(CSS::LineStyle::None); diff --git a/Libraries/LibWeb/Painting/GradientPainting.cpp b/Libraries/LibWeb/Painting/GradientPainting.cpp index 8e92bb4bf5e..8febcea5809 100644 --- a/Libraries/LibWeb/Painting/GradientPainting.cpp +++ b/Libraries/LibWeb/Painting/GradientPainting.cpp @@ -30,7 +30,7 @@ static ColorStopData resolve_color_stop_positions(Layout::NodeWithStyle const& n resolved_color_stops.ensure_capacity(expanded_size); for (auto& stop : color_stop_list) { - auto resolved_stop = Gfx::ColorStop { .color = stop.color_stop.color->to_color(node, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(node) }) }; + auto resolved_stop = Gfx::ColorStop { .color = stop.color_stop.color->to_color(node, { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(node) }).value() }; for (int i = 0; i < color_stop_length(stop); i++) resolved_color_stops.append(resolved_stop); }