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> values; + Vector> 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 Parser::parse_transform_value(Vector } 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 StyleProperties::transformations() const auto& transformation_style_value = it.as_transformation(); CSS::Transformation transformation; transformation.function = transformation_style_value.transform_function(); - Vector> values; + Vector> 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_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;