LibWeb: Use transform-box for resolving percentage transform values
Some checks are pending
CI / Lagom (true, NO_FUZZ, ubuntu-22.04, Linux, Clang) (push) Waiting to run
CI / Lagom (false, FUZZ, ubuntu-22.04, Linux, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, macos-14, macOS, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, ubuntu-22.04, Linux, GNU) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-22.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Push notes / build (push) Waiting to run
Some checks are pending
CI / Lagom (true, NO_FUZZ, ubuntu-22.04, Linux, Clang) (push) Waiting to run
CI / Lagom (false, FUZZ, ubuntu-22.04, Linux, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, macos-14, macOS, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, ubuntu-22.04, Linux, GNU) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-22.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Push notes / build (push) Waiting to run
Factor out computing the transform box rect into its own method. Then use it when resolving the transformation matrix, to compute percentage values.
This commit is contained in:
parent
a9d5a99568
commit
7e38e12bb0
Notes:
github-actions[bot]
2024-09-05 23:35:41 +00:00
Author: https://github.com/BenJilks Commit: https://github.com/LadybirdBrowser/ladybird/commit/7e38e12bb05 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1289 Reviewed-by: https://github.com/kalenikaliaksandr
5 changed files with 92 additions and 65 deletions
13
Tests/LibWeb/Ref/reference/transform-box-ref.html
Normal file
13
Tests/LibWeb/Ref/reference/transform-box-ref.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<style>
|
||||
.a {
|
||||
border: 20px solid crimson;
|
||||
transform: translateY(0px);
|
||||
}
|
||||
.b {
|
||||
border: 20px solid crimson;
|
||||
transform: translateY(40px);
|
||||
}
|
||||
</style>
|
||||
<div class="a"></div>
|
||||
<div class="b"></div>
|
10
Tests/LibWeb/Ref/transform-box.html
Normal file
10
Tests/LibWeb/Ref/transform-box.html
Normal file
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="match" href="reference/transform-box-ref.html" />
|
||||
<style>
|
||||
div {
|
||||
border: 20px solid crimson;
|
||||
transform: translateY(100%);
|
||||
}
|
||||
</style>
|
||||
<div style="transform-box: fill-box"></div>
|
||||
<div></div>
|
|
@ -47,7 +47,7 @@ ErrorOr<Gfx::FloatMatrix4x4> Transformation::to_matrix(Optional<Painting::Painta
|
|||
CSSPixels width = 1;
|
||||
CSSPixels height = 1;
|
||||
if (paintable_box.has_value()) {
|
||||
auto reference_box = paintable_box->absolute_padding_box_rect();
|
||||
auto reference_box = paintable_box->transform_box_rect();
|
||||
width = reference_box.width();
|
||||
height = reference_box.height();
|
||||
}
|
||||
|
|
|
@ -969,6 +969,72 @@ Optional<CSSPixelRect> PaintableBox::get_masking_area() const
|
|||
return absolute_border_box_rect();
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/css-transforms-1/#transform-box
|
||||
CSSPixelRect PaintableBox::transform_box_rect() const
|
||||
{
|
||||
auto transform_box = computed_values().transform_box();
|
||||
// For SVG elements without associated CSS layout box, the used value for content-box is fill-box and for
|
||||
// border-box is stroke-box.
|
||||
// FIXME: This currently detects any SVG element except the <svg> one. Is that correct?
|
||||
// And is it correct to use `else` below?
|
||||
if (is<Painting::SVGPaintable>(*this)) {
|
||||
switch (transform_box) {
|
||||
case CSS::TransformBox::ContentBox:
|
||||
transform_box = CSS::TransformBox::FillBox;
|
||||
break;
|
||||
case CSS::TransformBox::BorderBox:
|
||||
transform_box = CSS::TransformBox::StrokeBox;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// For elements with associated CSS layout box, the used value for fill-box is content-box and for
|
||||
// stroke-box and view-box is border-box.
|
||||
else {
|
||||
switch (transform_box) {
|
||||
case CSS::TransformBox::FillBox:
|
||||
transform_box = CSS::TransformBox::ContentBox;
|
||||
break;
|
||||
case CSS::TransformBox::StrokeBox:
|
||||
case CSS::TransformBox::ViewBox:
|
||||
transform_box = CSS::TransformBox::BorderBox;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (transform_box) {
|
||||
case CSS::TransformBox::ContentBox:
|
||||
// Uses the content box as reference box.
|
||||
// FIXME: The reference box of a table is the border box of its table wrapper box, not its table box.
|
||||
return absolute_rect();
|
||||
case CSS::TransformBox::BorderBox:
|
||||
// Uses the border box as reference box.
|
||||
// FIXME: The reference box of a table is the border box of its table wrapper box, not its table box.
|
||||
return absolute_border_box_rect();
|
||||
case CSS::TransformBox::FillBox:
|
||||
// Uses the object bounding box as reference box.
|
||||
// FIXME: For now we're using the content rect as an approximation.
|
||||
return absolute_rect();
|
||||
case CSS::TransformBox::StrokeBox:
|
||||
// Uses the stroke bounding box as reference box.
|
||||
// FIXME: For now we're using the border rect as an approximation.
|
||||
return absolute_border_box_rect();
|
||||
case CSS::TransformBox::ViewBox:
|
||||
// Uses the nearest SVG viewport as reference box.
|
||||
// FIXME: If a viewBox attribute is specified for the SVG viewport creating element:
|
||||
// - The reference box is positioned at the origin of the coordinate system established by the viewBox attribute.
|
||||
// - The dimension of the reference box is set to the width and height values of the viewBox attribute.
|
||||
auto* svg_paintable = first_ancestor_of_type<Painting::SVGSVGPaintable>();
|
||||
if (!svg_paintable)
|
||||
return absolute_border_box_rect();
|
||||
return svg_paintable->absolute_rect();
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
void PaintableBox::resolve_paint_properties()
|
||||
{
|
||||
auto const& computed_values = this->computed_values();
|
||||
|
@ -1011,70 +1077,7 @@ void PaintableBox::resolve_paint_properties()
|
|||
}
|
||||
|
||||
auto const& transform_origin = computed_values.transform_origin();
|
||||
// https://www.w3.org/TR/css-transforms-1/#transform-box
|
||||
auto transform_box = computed_values.transform_box();
|
||||
// For SVG elements without associated CSS layout box, the used value for content-box is fill-box and for
|
||||
// border-box is stroke-box.
|
||||
// FIXME: This currently detects any SVG element except the <svg> one. Is that correct?
|
||||
// And is it correct to use `else` below?
|
||||
if (is<Painting::SVGPaintable>(*this)) {
|
||||
switch (transform_box) {
|
||||
case CSS::TransformBox::ContentBox:
|
||||
transform_box = CSS::TransformBox::FillBox;
|
||||
break;
|
||||
case CSS::TransformBox::BorderBox:
|
||||
transform_box = CSS::TransformBox::StrokeBox;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// For elements with associated CSS layout box, the used value for fill-box is content-box and for
|
||||
// stroke-box and view-box is border-box.
|
||||
else {
|
||||
switch (transform_box) {
|
||||
case CSS::TransformBox::FillBox:
|
||||
transform_box = CSS::TransformBox::ContentBox;
|
||||
break;
|
||||
case CSS::TransformBox::StrokeBox:
|
||||
case CSS::TransformBox::ViewBox:
|
||||
transform_box = CSS::TransformBox::BorderBox;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CSSPixelRect reference_box = [&]() {
|
||||
switch (transform_box) {
|
||||
case CSS::TransformBox::ContentBox:
|
||||
// Uses the content box as reference box.
|
||||
// FIXME: The reference box of a table is the border box of its table wrapper box, not its table box.
|
||||
return absolute_rect();
|
||||
case CSS::TransformBox::BorderBox:
|
||||
// Uses the border box as reference box.
|
||||
// FIXME: The reference box of a table is the border box of its table wrapper box, not its table box.
|
||||
return absolute_border_box_rect();
|
||||
case CSS::TransformBox::FillBox:
|
||||
// Uses the object bounding box as reference box.
|
||||
// FIXME: For now we're using the content rect as an approximation.
|
||||
return absolute_rect();
|
||||
case CSS::TransformBox::StrokeBox:
|
||||
// Uses the stroke bounding box as reference box.
|
||||
// FIXME: For now we're using the border rect as an approximation.
|
||||
return absolute_border_box_rect();
|
||||
case CSS::TransformBox::ViewBox:
|
||||
// Uses the nearest SVG viewport as reference box.
|
||||
// FIXME: If a viewBox attribute is specified for the SVG viewport creating element:
|
||||
// - The reference box is positioned at the origin of the coordinate system established by the viewBox attribute.
|
||||
// - The dimension of the reference box is set to the width and height values of the viewBox attribute.
|
||||
auto* svg_paintable = first_ancestor_of_type<Painting::SVGSVGPaintable>();
|
||||
if (!svg_paintable)
|
||||
return absolute_border_box_rect();
|
||||
return svg_paintable->absolute_rect();
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}();
|
||||
auto reference_box = transform_box_rect();
|
||||
auto x = reference_box.left() + transform_origin.x.to_px(layout_node, reference_box.width());
|
||||
auto y = reference_box.top() + transform_origin.y.to_px(layout_node, reference_box.height());
|
||||
set_transform_origin({ x, y });
|
||||
|
|
|
@ -208,6 +208,7 @@ public:
|
|||
|
||||
virtual bool wants_mouse_events() const override;
|
||||
|
||||
CSSPixelRect transform_box_rect() const;
|
||||
virtual void resolve_paint_properties() override;
|
||||
|
||||
RefPtr<ScrollFrame const> nearest_scroll_frame() const;
|
||||
|
|
Loading…
Add table
Reference in a new issue