1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-19 20:35:06 +00:00
serenity/Userland/Libraries/LibWeb/Layout/SVGSVGBox.cpp
Sam Atkins 84e7216603 LibWeb: Move "natural size" concept into Layout::Box
Having this here instead of in ReplacedBox means we can access it when
figuring out what the "preferred aspect ratio" is.

There's some inconsistency between specs about what this is called, but
they're moving towards referring to this as "natural width/height/
aspect-ratio", so let's copy that terminology.
2023-06-09 20:37:51 +02:00

83 lines
3.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org>
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/CSS/Parser/Parser.h>
#include <LibWeb/Layout/ReplacedBox.h>
#include <LibWeb/Layout/SVGGeometryBox.h>
#include <LibWeb/Painting/SVGSVGPaintable.h>
namespace Web::Layout {
SVGSVGBox::SVGSVGBox(DOM::Document& document, SVG::SVGSVGElement& element, NonnullRefPtr<CSS::StyleProperties> properties)
: ReplacedBox(document, element, move(properties))
{
}
JS::GCPtr<Painting::Paintable> SVGSVGBox::create_paintable() const
{
return Painting::SVGSVGPaintable::create(*this);
}
void SVGSVGBox::prepare_for_replaced_layout()
{
// https://www.w3.org/TR/SVG2/coords.html#SizingSVGInCSS
// The intrinsic dimensions must also be determined from the width and height sizing properties.
// If either width or height are not specified, the used value is the initial value 'auto'.
// 'auto' and percentage lengths must not be used to determine an intrinsic width or intrinsic height.
auto const& computed_width = computed_values().width();
if (computed_width.is_length() && !computed_width.contains_percentage()) {
set_natural_width(computed_width.to_px(*this, 0));
}
auto const& computed_height = computed_values().height();
if (computed_height.is_length() && !computed_height.contains_percentage()) {
set_natural_height(computed_height.to_px(*this, 0));
}
set_natural_aspect_ratio(calculate_intrinsic_aspect_ratio());
}
Optional<float> SVGSVGBox::calculate_intrinsic_aspect_ratio() const
{
// https://www.w3.org/TR/SVG2/coords.html#SizingSVGInCSS
// The intrinsic aspect ratio must be calculated using the following algorithm. If the algorithm returns null, then there is no intrinsic aspect ratio.
auto const& computed_width = computed_values().width();
auto const& computed_height = computed_values().height();
// 1. If the width and height sizing properties on the svg element are both absolute values:
if (computed_width.is_length() && !computed_width.contains_percentage() && computed_height.is_length() && !computed_height.contains_percentage()) {
auto width = computed_width.to_px(*this, 0);
auto height = computed_height.to_px(*this, 0);
if (width != 0 && height != 0) {
// 1. return width / height
return width.value() / height.value();
}
return {};
}
// FIXME: 2. If an SVG View is active:
// FIXME: 1. let viewbox be the viewbox defined by the active SVG View
// FIXME: 2. return viewbox.width / viewbox.height
// 3. If the viewBox on the svg element is correctly specified:
if (dom_node().view_box().has_value()) {
// 1. let viewbox be the viewbox defined by the viewBox attribute on the svg element
auto const& viewbox = dom_node().view_box().value();
// 2. return viewbox.width / viewbox.height
return viewbox.width / viewbox.height;
}
// 4. return null
return {};
}
}