mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-28 05:52:53 +00:00
LibWeb: Make use of transform-box when calculating transforms
We don't currently calculate the fill- or stroke-boxes of SVG elements, so for now we use the content- and border-boxes respectively, as those are the closest equivalents. The test will need updating when we do support them. Also, the test is a screenshot because of rendering differences when applying transforms: a 20px box does not get painted the same as a 10px box scaled up 2x. Otherwise that would be the more ideal form of test.
This commit is contained in:
parent
391cfdc085
commit
e025bcc4f9
Notes:
sideshowbarker
2024-07-17 03:25:24 +09:00
Author: https://github.com/AtkinsSJ
Commit: e025bcc4f9
Pull-request: https://github.com/SerenityOS/serenity/pull/22950
4 changed files with 117 additions and 2 deletions
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2022-2023, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2024, Sam Atkins <atkinssj@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -12,6 +13,7 @@
|
|||
#include <LibWeb/Layout/Viewport.h>
|
||||
#include <LibWeb/Painting/InlinePaintable.h>
|
||||
#include <LibWeb/Painting/SVGPathPaintable.h>
|
||||
#include <LibWeb/Painting/SVGSVGPaintable.h>
|
||||
#include <LibWeb/Painting/TextPaintable.h>
|
||||
|
||||
namespace Web::Layout {
|
||||
|
@ -369,8 +371,70 @@ void LayoutState::resolve_layout_dependent_properties()
|
|||
}
|
||||
|
||||
auto const& transform_origin = paintable_box.computed_values().transform_origin();
|
||||
// FIXME: respect transform-box property
|
||||
auto const& reference_box = paintable_box.absolute_border_box_rect();
|
||||
// https://www.w3.org/TR/css-transforms-1/#transform-box
|
||||
auto transform_box = paintable_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>(paintable_box)) {
|
||||
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 paintable_box.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 paintable_box.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 paintable_box.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 paintable_box.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 = paintable_box.first_ancestor_of_type<Painting::SVGSVGPaintable>();
|
||||
if (!svg_paintable)
|
||||
return paintable_box.absolute_border_box_rect();
|
||||
return svg_paintable->absolute_rect();
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
}();
|
||||
auto x = reference_box.left() + transform_origin.x.to_px(node, reference_box.width());
|
||||
auto y = reference_box.top() + transform_origin.y.to_px(node, reference_box.height());
|
||||
paintable_box.set_transform_origin({ x, y });
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue