summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorSimon Wanner <skyrising@pvpctutorials.de>2022-03-21 23:18:38 +0100
committerAndreas Kling <kling@serenityos.org>2022-03-22 02:06:21 +0100
commitdc94879b83f72e670773a8a05b2a547520c002d8 (patch)
tree9f89e59d77a85788312fc8455f94085b6cb0e983 /Userland
parentbc5d39493b9d13bae72fb5932bc218417fbea5a2 (diff)
downloadserenity-dc94879b83f72e670773a8a05b2a547520c002d8.zip
LibWeb: Support `transform: translate(...)` by percentage
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibWeb/CSS/ComputedValues.h2
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp5
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleProperties.cpp4
-rw-r--r--Userland/Libraries/LibWeb/Painting/StackingContext.cpp64
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;