@@ -1535,6 +1535,35 @@ void PaintableBox::resolve_paint_properties()
15351535 matrix = matrix * transform.to_matrix (*this ).release_value ();
15361536 set_transform (matrix);
15371537
1538+ // https://drafts.csswg.org/css-transforms-2/#perspective
1539+ auto const & perspective = computed_values.perspective ();
1540+ if (perspective.has_value ()) {
1541+ // The perspective matrix is computed as follows:
1542+
1543+ // 1. Start with the identity matrix.
1544+ m_perspective_matrix = Gfx::FloatMatrix4x4::identity ();
1545+
1546+ // 2. Translate by the computed X and Y values of 'perspective-origin'
1547+ // FIXME: Implement this.
1548+
1549+ // 3. Multiply by the matrix that would be obtained from the 'perspective()' transform function, where the
1550+ // length is provided by the value of the perspective property
1551+ auto perspective_value = perspective.value ();
1552+
1553+ // https://drafts.csswg.org/css-transforms-2/#perspective-property
1554+ // As very small <length> values can produce bizarre rendering results and stress the numerical accuracy
1555+ // of transform calculations, values less than '1px' must be treated as '1px' for rendering purposes. (This
1556+ // clamping does not affect the underlying value, so 'perspective: 0;' in a stylesheet will still serialize back
1557+ // as '0'.)
1558+ if (perspective_value < 1 )
1559+ perspective_value = 1 ;
1560+
1561+ m_perspective_matrix = m_perspective_matrix * CSS::Transformation (CSS::TransformFunction::Perspective, Vector<CSS::TransformValue>({ CSS::TransformValue (CSS::Length::make_px (perspective_value)) })).to_matrix (*this ).release_value ();
1562+
1563+ // 4. Translate by the negated computed X and Y values of 'perspective-origin'
1564+ // FIXME: Implement this.
1565+ }
1566+
15381567 auto const & transform_origin = computed_values.transform_origin ();
15391568 auto reference_box = transform_box_rect ();
15401569 auto x = reference_box.left () + transform_origin.x .to_px (layout_node, reference_box.width ());
0 commit comments