diff options
author | Simon Wanner <skyrising@pvpctutorials.de> | 2022-03-21 23:18:38 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-03-22 02:06:21 +0100 |
commit | dc94879b83f72e670773a8a05b2a547520c002d8 (patch) | |
tree | 9f89e59d77a85788312fc8455f94085b6cb0e983 /Userland | |
parent | bc5d39493b9d13bae72fb5932bc218417fbea5a2 (diff) | |
download | serenity-dc94879b83f72e670773a8a05b2a547520c002d8.zip |
LibWeb: Support `transform: translate(...)` by percentage
Diffstat (limited to 'Userland')
4 files changed, 43 insertions, 32 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/ComputedValues.h b/Userland/Libraries/LibWeb/CSS/ComputedValues.h index d1bb3e1131..191e387f9a 100644 --- a/Userland/Libraries/LibWeb/CSS/ComputedValues.h +++ b/Userland/Libraries/LibWeb/CSS/ComputedValues.h @@ -72,7 +72,7 @@ public: struct Transformation { CSS::TransformFunction function; - Vector<Variant<CSS::Length, float>> values; + Vector<Variant<CSS::LengthPercentage, float>> values; }; struct TransformOrigin { diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index d9c6ca7beb..dfbdb0509d 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -3976,6 +3976,11 @@ RefPtr<StyleValue> Parser::parse_transform_value(Vector<StyleComponentValueRule> } else if (value.is(Token::Type::Number)) { auto number = parse_numeric_value(value); values.append(number.release_nonnull()); + } else if (value.is(Token::Type::Percentage)) { + auto percentage = parse_dimension_value(value); + if (!percentage || !percentage->is_percentage()) + return nullptr; + values.append(percentage.release_nonnull()); } else { dbgln_if(CSS_PARSER_DEBUG, "FIXME: Unsupported value type for transformation!"); return nullptr; diff --git a/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp b/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp index d9fdb39dcd..1e9d4e1f44 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp @@ -329,10 +329,12 @@ Vector<CSS::Transformation> StyleProperties::transformations() const auto& transformation_style_value = it.as_transformation(); CSS::Transformation transformation; transformation.function = transformation_style_value.transform_function(); - Vector<Variant<CSS::Length, float>> values; + Vector<Variant<CSS::LengthPercentage, float>> values; for (auto& transformation_value : transformation_style_value.values()) { if (transformation_value.is_length()) { values.append({ transformation_value.to_length() }); + } else if (transformation_value.is_percentage()) { + values.append({ transformation_value.as_percentage().percentage() }); } else if (transformation_value.is_numeric()) { values.append({ transformation_value.to_number() }); } else if (transformation_value.is_angle()) { diff --git a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp index db5c947101..ab85977616 100644 --- a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp +++ b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp @@ -143,74 +143,78 @@ void StackingContext::paint_internal(PaintContext& context) const Gfx::FloatMatrix4x4 StackingContext::get_transformation_matrix(CSS::Transformation const& transformation) const { - Vector<float> float_values; - for (auto const& value : transformation.values) { - value.visit( - [&](CSS::Length const& value) { - float_values.append(value.to_px(m_box)); + auto count = transformation.values.size(); + auto value = [this, transformation](size_t index, CSS::Length& reference) -> float { + return transformation.values[index].visit( + [this, reference](CSS::LengthPercentage const& value) { + return value.resolved(m_box, reference).to_px(m_box); }, - [&](float value) { - float_values.append(value); + [](float value) { + return value; }); - } + }; + + auto reference_box = m_box.paint_box()->absolute_rect(); + auto width = CSS::Length::make_px(reference_box.width()); + auto height = CSS::Length::make_px(reference_box.height()); switch (transformation.function) { case CSS::TransformFunction::Matrix: - if (float_values.size() == 6) - return Gfx::FloatMatrix4x4(float_values[0], float_values[2], 0, float_values[4], - float_values[1], float_values[3], 0, float_values[5], + if (count == 6) + return Gfx::FloatMatrix4x4(value(0, width), value(2, width), 0, value(4, width), + value(1, height), value(3, height), 0, value(5, height), 0, 0, 1, 0, 0, 0, 0, 1); break; case CSS::TransformFunction::Translate: - if (float_values.size() == 1) - return Gfx::FloatMatrix4x4(1, 0, 0, float_values[0], + if (count == 1) + return Gfx::FloatMatrix4x4(1, 0, 0, value(0, width), 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - if (float_values.size() == 2) - return Gfx::FloatMatrix4x4(1, 0, 0, float_values[0], - 0, 1, 0, float_values[1], + if (count == 2) + return Gfx::FloatMatrix4x4(1, 0, 0, value(0, width), + 0, 1, 0, value(1, height), 0, 0, 1, 0, 0, 0, 0, 1); break; case CSS::TransformFunction::TranslateX: - if (float_values.size() == 1) - return Gfx::FloatMatrix4x4(1, 0, 0, float_values[0], + if (count == 1) + return Gfx::FloatMatrix4x4(1, 0, 0, value(0, width), 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); break; case CSS::TransformFunction::TranslateY: - if (float_values.size() == 1) + if (count == 1) return Gfx::FloatMatrix4x4(1, 0, 0, 0, - 0, 1, 0, float_values[0], + 0, 1, 0, value(0, height), 0, 0, 1, 0, 0, 0, 0, 1); break; case CSS::TransformFunction::Scale: - if (float_values.size() == 1) - return Gfx::FloatMatrix4x4(float_values[0], 0, 0, 0, - 0, float_values[0], 0, 0, + if (count == 1) + return Gfx::FloatMatrix4x4(value(0, width), 0, 0, 0, + 0, value(0, height), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - if (float_values.size() == 2) - return Gfx::FloatMatrix4x4(float_values[0], 0, 0, 0, - 0, float_values[1], 0, 0, + if (count == 2) + return Gfx::FloatMatrix4x4(value(0, width), 0, 0, 0, + 0, value(0, height), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); break; case CSS::TransformFunction::ScaleX: - if (float_values.size() == 1) - return Gfx::FloatMatrix4x4(float_values[0], 0, 0, 0, + if (count == 1) + return Gfx::FloatMatrix4x4(value(0, width), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); break; case CSS::TransformFunction::ScaleY: - if (float_values.size() == 1) + if (count == 1) return Gfx::FloatMatrix4x4(1, 0, 0, 0, - 0, float_values[0], 0, 0, + 0, value(0, height), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); break; |