mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 23:38:12 +00:00
LibWeb: Support <svg> elements with display: block
There are a couple of things that went into this: - We now calculate the intrinsic width/height and aspect ratio of <svg> elements based on the spec algorithm instead of our previous ad-hoc guesswork solution. - Replaced elements with automatic size and intrinsic aspect ratio but no intrinsic dimensions are now sized with the stretch-fit width formula. - We take care to assign both used width and used height to <svg> elements before running their SVG formatting contexts. This ensures that the inside SVG content is laid out with knowledge of its viewport geometry. - We avoid infinite recursion in tentative_height_for_replaced_element() by using the already-calculated used width instead of calling the function that calculates the used width (since that may call us right back again).
This commit is contained in:
parent
28d2e26678
commit
f0560fd087
11 changed files with 107 additions and 74 deletions
|
@ -398,6 +398,9 @@ CSSPixels FormattingContext::tentative_width_for_replaced_element(LayoutState co
|
|||
// then the used value of 'width' is undefined in CSS 2.2. However, it is suggested that, if the containing block's width does not itself
|
||||
// depend on the replaced element's width, then the used value of 'width' is calculated from the constraint equation used for block-level,
|
||||
// non-replaced elements in normal flow.
|
||||
if (computed_height.is_auto() && computed_width.is_auto() && !box.has_intrinsic_width() && !box.has_intrinsic_height() && box.has_intrinsic_aspect_ratio()) {
|
||||
return calculate_stretch_fit_width(box, available_space.width, state);
|
||||
}
|
||||
|
||||
// Otherwise, if 'width' has a computed value of 'auto', and the element has an intrinsic width, then that intrinsic width is the used value of 'width'.
|
||||
if (computed_width.is_auto() && box.has_intrinsic_width())
|
||||
|
@ -483,7 +486,7 @@ CSSPixels FormattingContext::tentative_height_for_replaced_element(LayoutState c
|
|||
//
|
||||
// (used width) / (intrinsic ratio)
|
||||
if (computed_height.is_auto() && box.has_intrinsic_aspect_ratio())
|
||||
return compute_width_for_replaced_element(state, box, available_space) / box.intrinsic_aspect_ratio().value();
|
||||
return state.get(box).content_width() / box.intrinsic_aspect_ratio().value();
|
||||
|
||||
// Otherwise, if 'height' has a computed value of 'auto', and the element has an intrinsic height, then that intrinsic height is the used value of 'height'.
|
||||
if (computed_height.is_auto() && box.has_intrinsic_height())
|
||||
|
@ -1412,12 +1415,12 @@ CSSPixels FormattingContext::containing_block_height_for(Box const& box, LayoutS
|
|||
}
|
||||
|
||||
// https://drafts.csswg.org/css-sizing-3/#stretch-fit-size
|
||||
CSSPixels FormattingContext::calculate_stretch_fit_width(Box const& box, AvailableSize const& available_width) const
|
||||
CSSPixels FormattingContext::calculate_stretch_fit_width(Box const& box, AvailableSize const& available_width, LayoutState const& state)
|
||||
{
|
||||
// The size a box would take if its outer size filled the available space in the given axis;
|
||||
// in other words, the stretch fit into the available space, if that is definite.
|
||||
// Undefined if the available space is indefinite.
|
||||
auto const& box_state = m_state.get(box);
|
||||
auto const& box_state = state.get(box);
|
||||
return available_width.to_px()
|
||||
- box_state.margin_left
|
||||
- box_state.margin_right
|
||||
|
@ -1427,13 +1430,18 @@ CSSPixels FormattingContext::calculate_stretch_fit_width(Box const& box, Availab
|
|||
- box_state.border_right;
|
||||
}
|
||||
|
||||
CSSPixels FormattingContext::calculate_stretch_fit_width(Box const& box, AvailableSize const& available_width) const
|
||||
{
|
||||
return calculate_stretch_fit_width(box, available_width, m_state);
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-sizing-3/#stretch-fit-size
|
||||
CSSPixels FormattingContext::calculate_stretch_fit_height(Box const& box, AvailableSize const& available_height) const
|
||||
CSSPixels FormattingContext::calculate_stretch_fit_height(Box const& box, AvailableSize const& available_height, LayoutState const& state)
|
||||
{
|
||||
// The size a box would take if its outer size filled the available space in the given axis;
|
||||
// in other words, the stretch fit into the available space, if that is definite.
|
||||
// Undefined if the available space is indefinite.
|
||||
auto const& box_state = m_state.get(box);
|
||||
auto const& box_state = state.get(box);
|
||||
return available_height.to_px()
|
||||
- box_state.margin_top
|
||||
- box_state.margin_bottom
|
||||
|
@ -1443,6 +1451,11 @@ CSSPixels FormattingContext::calculate_stretch_fit_height(Box const& box, Availa
|
|||
- box_state.border_bottom;
|
||||
}
|
||||
|
||||
CSSPixels FormattingContext::calculate_stretch_fit_height(Box const& box, AvailableSize const& available_height) const
|
||||
{
|
||||
return calculate_stretch_fit_height(box, available_height, m_state);
|
||||
}
|
||||
|
||||
bool FormattingContext::should_treat_width_as_auto(Box const& box, AvailableSpace const& available_space)
|
||||
{
|
||||
return box.computed_values().width().is_auto()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue