LibWeb: Pass 3D transforms to Skia

This commit is contained in:
Psychpsyo 2025-11-10 15:05:11 +01:00 committed by Jelle Raaijmakers
parent e0b5bd7894
commit e44a97e508
Notes: github-actions[bot] 2025-11-11 23:42:53 +00:00
3 changed files with 60 additions and 12 deletions

View file

@ -71,6 +71,26 @@ static SkMatrix to_skia_matrix(Gfx::AffineTransform const& affine_transform)
matrix.setAffine(affine);
return matrix;
}
static SkM44 to_skia_matrix4x4(Gfx::FloatMatrix4x4 const& matrix)
{
return SkM44(
matrix[0, 0],
matrix[0, 1],
matrix[0, 2],
matrix[0, 3],
matrix[1, 0],
matrix[1, 1],
matrix[1, 2],
matrix[1, 3],
matrix[2, 0],
matrix[2, 1],
matrix[2, 2],
matrix[2, 3],
matrix[3, 0],
matrix[3, 1],
matrix[3, 2],
matrix[3, 3]);
}
void DisplayListPlayerSkia::flush()
{
@ -204,12 +224,10 @@ void DisplayListPlayerSkia::push_stacking_context(PushStackingContext const& com
{
auto& canvas = surface().canvas();
auto affine_transform = Gfx::extract_2d_affine_transform(command.transform.matrix);
auto new_transform = Gfx::AffineTransform {}
.translate(command.transform.origin)
.multiply(affine_transform)
.translate(-command.transform.origin);
auto matrix = to_skia_matrix(new_transform);
auto new_transform = Gfx::translation_matrix(Vector3<float>(command.transform.origin.x(), command.transform.origin.y(), 0));
new_transform = new_transform * command.transform.matrix;
new_transform = new_transform * Gfx::translation_matrix(Vector3<float>(-command.transform.origin.x(), -command.transform.origin.y(), 0));
auto matrix = to_skia_matrix4x4(new_transform);
surface().canvas().save();
if (command.clip_path.has_value())
@ -959,12 +977,10 @@ void DisplayListPlayerSkia::apply_filters(ApplyFilter const& command)
void DisplayListPlayerSkia::apply_transform(ApplyTransform const& command)
{
auto affine_transform = Gfx::extract_2d_affine_transform(command.matrix);
auto new_transform = Gfx::AffineTransform {}
.translate(command.origin)
.multiply(affine_transform)
.translate(-command.origin);
auto matrix = to_skia_matrix(new_transform);
auto new_transform = Gfx::translation_matrix(Vector3<float>(command.origin.x(), command.origin.y(), 0));
new_transform = new_transform * command.matrix;
new_transform = new_transform * Gfx::translation_matrix(Vector3<float>(-command.origin.x(), -command.origin.y(), 0));
auto matrix = to_skia_matrix4x4(new_transform);
surface().canvas().concat(matrix);
}

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<title>CSS Reftest Reference</title>
<link rel="author" title="Matt Woodrow" href="mailto:mwoodrow@mozilla.com">
<link rel="author" title="Aryeh Gregor" href="mailto:ayg@aryeh.name">
<link rel="mismatch" href="transform-lime-square-ref.html">
</head>
<body>
<div style="transform: rotatex(45deg); width: 100px; height: 100px;
background: lime"></div>
</body>
</html>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<title>CSS Test (Transforms): perspective(1000px) rotatex(45deg)</title>
<link rel="author" title="Matt Woodrow" href="mailto:mwoodrow@mozilla.com">
<link rel="author" title="Aryeh Gregor" href="mailto:ayg@aryeh.name">
<link rel="help" href="http://www.w3.org/TR/css-transforms-2/#three-d-transform-functions">
<link rel="help" href="http://www.w3.org/TR/css-transforms-2/#funcdef-rotatex">
<link rel="help" href="http://www.w3.org/TR/css-transforms-2/#funcdef-perspective">
<meta name="assert" content="This tests that perspective() has some effect
when combined with rotatex() (i.e., is not equivalent to simply omitting
the perspective).">
<link rel="mismatch" href="../../../../expected/wpt-import/css/css-transforms/transform3d-rotatex-ref.html">
</head>
<body>
<div style="transform: perspective(1000px) rotatex(45deg); width: 100px;
height: 100px; background: lime"></div>
</body>
</html>