Coverage Report

Created: 2026-06-07 07:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibWeb/Layout/SVGSVGBox.cpp
Line
Count
Source
1
/*
2
 * Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org>
3
 * Copyright (c) 2022-2024, Andreas Kling <andreas@ladybird.org>
4
 *
5
 * SPDX-License-Identifier: BSD-2-Clause
6
 */
7
8
#include <LibWeb/CSS/Parser/Parser.h>
9
#include <LibWeb/CSS/StyleValues/LengthStyleValue.h>
10
#include <LibWeb/Layout/ReplacedBox.h>
11
#include <LibWeb/Layout/SVGGeometryBox.h>
12
#include <LibWeb/Painting/SVGSVGPaintable.h>
13
14
namespace Web::Layout {
15
16
JS_DEFINE_ALLOCATOR(SVGSVGBox);
17
18
SVGSVGBox::SVGSVGBox(DOM::Document& document, SVG::SVGSVGElement& element, NonnullRefPtr<CSS::StyleProperties> properties)
19
0
    : ReplacedBox(document, element, move(properties))
20
0
{
21
0
}
22
23
JS::GCPtr<Painting::Paintable> SVGSVGBox::create_paintable() const
24
0
{
25
0
    return Painting::SVGSVGPaintable::create(*this);
26
0
}
27
28
void SVGSVGBox::prepare_for_replaced_layout()
29
0
{
30
    // https://www.w3.org/TR/SVG2/coords.html#SizingSVGInCSS
31
32
    // The intrinsic dimensions must also be determined from the width and height sizing properties.
33
    // If either width or height are not specified, the used value is the initial value 'auto'.
34
    // 'auto' and percentage lengths must not be used to determine an intrinsic width or intrinsic height.
35
36
0
    Optional<CSSPixels> natural_width;
37
0
    if (auto width = dom_node().width_style_value_from_attribute(); width && width->is_length() && width->as_length().length().is_absolute()) {
38
0
        natural_width = width->as_length().length().absolute_length_to_px();
39
0
    }
40
41
0
    Optional<CSSPixels> natural_height;
42
0
    if (auto height = dom_node().height_style_value_from_attribute(); height && height->is_length() && height->as_length().length().is_absolute()) {
43
0
        natural_height = height->as_length().length().absolute_length_to_px();
44
0
    }
45
46
    // The intrinsic aspect ratio must be calculated using the following algorithm. If the algorithm returns null, then there is no intrinsic aspect ratio.
47
0
    auto natural_aspect_ratio = [&]() -> Optional<CSSPixelFraction> {
48
        // 1. If the width and height sizing properties on the ‘svg’ element are both absolute values:
49
0
        if (natural_width.has_value() && natural_height.has_value()) {
50
0
            if (natural_width != 0 && natural_height != 0) {
51
                // 1. return width / height
52
0
                return *natural_width / *natural_height;
53
0
            }
54
0
            return {};
55
0
        }
56
57
        // FIXME: 2. If an SVG View is active:
58
        // FIXME:    1. let viewbox be the viewbox defined by the active SVG View
59
        // FIXME:    2. return viewbox.width / viewbox.height
60
61
        // 3. If the ‘viewBox’ on the ‘svg’ element is correctly specified:
62
0
        if (dom_node().view_box().has_value()) {
63
            // 1. let viewbox be the viewbox defined by the ‘viewBox’ attribute on the ‘svg’ element
64
0
            auto const& viewbox = dom_node().view_box().value();
65
66
            // 2. return viewbox.width / viewbox.height
67
0
            auto viewbox_width = CSSPixels::nearest_value_for(viewbox.width);
68
0
            auto viewbox_height = CSSPixels::nearest_value_for(viewbox.height);
69
0
            if (viewbox_width != 0 && viewbox_height != 0)
70
0
                return viewbox_width / viewbox_height;
71
72
0
            return {};
73
0
        }
74
75
        // 4. return null
76
0
        return {};
77
0
    }();
78
79
0
    set_natural_width(natural_width);
80
0
    set_natural_height(natural_height);
81
0
    set_natural_aspect_ratio(natural_aspect_ratio);
82
0
}
83
84
}