From 78e57096e25c495f9fa0580daa1f9e812789628a Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Tue, 19 Oct 2021 16:43:56 +0100 Subject: LibWeb: Distinguish between integer and float in NumericStyleValue We have this information when parsing, and some properties specifically only allow integers, so it makes sense to keep that around. --- Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp | 8 ++-- Userland/Libraries/LibWeb/CSS/Parser/Token.h | 4 +- .../LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp | 8 ++-- Userland/Libraries/LibWeb/CSS/StyleComputer.cpp | 4 +- Userland/Libraries/LibWeb/CSS/StyleProperties.cpp | 4 +- Userland/Libraries/LibWeb/CSS/StyleValue.h | 49 ++++++++++++++++------ 6 files changed, 51 insertions(+), 26 deletions(-) (limited to 'Userland/Libraries/LibWeb/CSS') diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index 2f3326d21e..5e4af2e804 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -2060,11 +2060,11 @@ RefPtr Parser::parse_numeric_value(ParsingContext const&, StyleCompo if (component_value.is(Token::Type::Number)) { auto number = component_value.token(); if (number.m_number_type == Token::NumberType::Integer) { - return NumericStyleValue::create(number.to_integer()); + return NumericStyleValue::create_integer(number.to_integer()); } else { auto float_value = try_parse_float(number.m_value.string_view()); if (float_value.has_value()) - return NumericStyleValue::create(float_value.value()); + return NumericStyleValue::create_float(float_value.value()); } } @@ -2626,11 +2626,11 @@ RefPtr Parser::parse_flex_value(ParsingContext const& context, Vecto switch (value->to_identifier()) { case ValueID::Auto: { - auto one = NumericStyleValue::create(1); + auto one = NumericStyleValue::create_integer(1); return FlexStyleValue::create(one, one, IdentifierStyleValue::create(ValueID::Auto)); } case ValueID::None: { - auto zero = NumericStyleValue::create(0); + auto zero = NumericStyleValue::create_integer(0); return FlexStyleValue::create(zero, zero, IdentifierStyleValue::create(ValueID::Auto)); } default: diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Token.h b/Userland/Libraries/LibWeb/CSS/Parser/Token.h index 61e1e58c8b..9c1d945b68 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Token.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Token.h @@ -105,7 +105,7 @@ public: VERIFY(m_type == Type::Number); return m_value.string_view(); } - int to_integer() const + i64 to_integer() const { VERIFY(m_type == Type::Number && m_number_type == NumberType::Integer); return number_string_value().to_int().value(); @@ -122,7 +122,7 @@ public: VERIFY(m_type == Type::Dimension); return m_value.string_view(); } - int dimension_value_int() const { return dimension_value().to_int().value(); } + i64 dimension_value_int() const { return dimension_value().to_int().value(); } NumberType number_type() const { diff --git a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp index ebed0d90aa..5f0a535b18 100644 --- a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp +++ b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp @@ -469,7 +469,7 @@ RefPtr ResolvedCSSStyleDeclaration::style_value_for_property(Layout: auto maybe_z_index = layout_node.computed_values().z_index(); if (!maybe_z_index.has_value()) return {}; - return NumericStyleValue::create(maybe_z_index.release_value()); + return NumericStyleValue::create_integer(maybe_z_index.release_value()); } case CSS::PropertyID::TextAlign: return IdentifierStyleValue::create(to_css_value_id(layout_node.computed_values().text_align())); @@ -501,19 +501,19 @@ RefPtr ResolvedCSSStyleDeclaration::style_value_for_property(Layout: auto maybe_grow_factor = layout_node.computed_values().flex_grow_factor(); if (!maybe_grow_factor.has_value()) return {}; - return NumericStyleValue::create(maybe_grow_factor.release_value()); + return NumericStyleValue::create_float(maybe_grow_factor.release_value()); } case CSS::PropertyID::FlexShrink: { auto maybe_shrink_factor = layout_node.computed_values().flex_shrink_factor(); if (!maybe_shrink_factor.has_value()) return {}; - return NumericStyleValue::create(maybe_shrink_factor.release_value()); + return NumericStyleValue::create_float(maybe_shrink_factor.release_value()); } case CSS::PropertyID::Opacity: { auto maybe_opacity = layout_node.computed_values().opacity(); if (!maybe_opacity.has_value()) return {}; - return NumericStyleValue::create(maybe_opacity.release_value()); + return NumericStyleValue::create_float(maybe_opacity.release_value()); } case CSS::PropertyID::JustifyContent: return IdentifierStyleValue::create(to_css_value_id(layout_node.computed_values().justify_content())); diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp index a8f6c39db4..f0c303b659 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -665,8 +665,8 @@ void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* ele default: break; } - } else if (font_weight->is_numeric()) { - int font_weight_integer = roundf(static_cast(*font_weight).value()); + } else if (font_weight->has_integer()) { + int font_weight_integer = font_weight->to_integer(); if (font_weight_integer <= Gfx::FontWeight::Regular) weight = Gfx::FontWeight::Regular; else if (font_weight_integer <= Gfx::FontWeight::Bold) diff --git a/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp b/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp index 02205a76f5..d767356dbd 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp @@ -116,8 +116,8 @@ Optional StyleProperties::z_index() const if (value->has_auto()) return 0; - if (value->is_numeric()) - return value->as_numeric().int_value(); + if (value->has_integer()) + return value->to_integer(); return {}; } diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValue.h index fc0f976315..55f44173b5 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.h @@ -333,11 +333,13 @@ public: virtual bool has_identifier() const { return false; } virtual bool has_length() const { return false; } virtual bool has_number() const { return false; } + virtual bool has_integer() const { return false; } virtual Color to_color(Layout::NodeWithStyle const&) const { return {}; } virtual CSS::ValueID to_identifier() const { return ValueID::Invalid; } virtual Length to_length() const { return {}; } - virtual float to_number() const { return {}; } + virtual float to_number() const { return 0; } + virtual float to_integer() const { return 0; } virtual String to_string() const = 0; bool operator==(StyleValue const& other) const { return equals(other); } @@ -1021,37 +1023,60 @@ private: class NumericStyleValue : public StyleValue { public: - static NonnullRefPtr create(float value) + static NonnullRefPtr create_float(float value) { return adopt_ref(*new NumericStyleValue(value)); } - virtual bool has_length() const override { return m_value == 0; } + static NonnullRefPtr create_integer(i64 value) + { + return adopt_ref(*new NumericStyleValue(value)); + } + + virtual bool has_length() const override { return to_number() == 0; } virtual Length to_length() const override { return Length(0, Length::Type::Px); } virtual bool has_number() const override { return true; } - virtual float to_number() const override { return m_value; } + virtual float to_number() const override + { + return m_value.visit( + [](float value) { return value; }, + [](i64 value) { return (float)value; }); + } - float value() const { return m_value; } - // FIXME: Store integer values separately - i64 int_value() const { return roundf(m_value); } - String to_string() const override { return String::formatted("{}", m_value); } + virtual bool has_integer() const override { return m_value.has(); } + virtual float to_integer() const override { return m_value.get(); } + + String to_string() const override + { + return m_value.visit( + [](float value) { + return String::formatted("{}", value); + }, + [](i64 value) { + return String::formatted("{}", value); + }); + } virtual bool equals(StyleValue const& other) const override { if (type() != other.type()) return false; - return m_value == static_cast(other).m_value; + if (has_integer() != other.has_integer()) + return false; + if (has_integer()) + return m_value.get() == static_cast(other).m_value.get(); + return m_value.get() == static_cast(other).m_value.get(); } private: - explicit NumericStyleValue(float value) + explicit NumericStyleValue(Variant value) : StyleValue(Type::Numeric) - , m_value(value) + , m_value(move(value)) { } - float m_value { 0 }; + Variant m_value { (i64)0 }; }; class OverflowStyleValue final : public StyleValue { -- cgit v1.2.3