LibWeb: Move our "default sizing algorithm" function into a public place

Specifically, this is used by the updated algorithm for parsing a sizes
attribute, so we need access to it there.

No behaviour changes.
This commit is contained in:
Sam Atkins 2024-09-09 17:16:25 +01:00 committed by Andreas Kling
parent 143c9581a2
commit 2671820ace
Notes: github-actions[bot] 2024-09-12 05:40:20 +00:00
5 changed files with 78 additions and 43 deletions

View file

@ -60,6 +60,7 @@ source_set("CSS") {
"SelectorEngine.cpp",
"Serialize.cpp",
"Size.cpp",
"Sizing.cpp",
"StyleComputer.cpp",
"StyleInvalidation.cpp",
"StyleProperties.cpp",

View file

@ -99,6 +99,7 @@ set(SOURCES
CSS/SelectorEngine.cpp
CSS/Serialize.cpp
CSS/Size.cpp
CSS/Sizing.cpp
CSS/StyleComputer.cpp
CSS/StyleInvalidation.cpp
CSS/StyleProperties.cpp

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2022, MacDue <macdue@dueutil.tech>
* Copyright (c) 2024, Sam Atkins <sam@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "Sizing.h"
namespace Web::CSS {
// https://drafts.csswg.org/css-images/#default-sizing
CSSPixelSize run_default_sizing_algorithm(
Optional<CSSPixels> specified_width, Optional<CSSPixels> specified_height,
Optional<CSSPixels> natural_width, Optional<CSSPixels> natural_height,
Optional<CSSPixelFraction> natural_aspect_ratio,
CSSPixelSize default_size)
{
// If the specified size is a definite width and height, the concrete object size is given that width and height.
if (specified_width.has_value() && specified_height.has_value())
return CSSPixelSize { specified_width.value(), specified_height.value() };
// If the specified size is only a width or height (but not both) then the concrete object size is given that specified width or height.
// The other dimension is calculated as follows:
if (specified_width.has_value() || specified_height.has_value()) {
// 1. If the object has a natural aspect ratio,
// the missing dimension of the concrete object size is calculated using that aspect ratio and the present dimension.
if (natural_aspect_ratio.has_value() && !natural_aspect_ratio->might_be_saturated()) {
if (specified_width.has_value())
return CSSPixelSize { specified_width.value(), (CSSPixels(1) / natural_aspect_ratio.value()) * specified_width.value() };
if (specified_height.has_value())
return CSSPixelSize { specified_height.value() * natural_aspect_ratio.value(), specified_height.value() };
}
// 2. Otherwise, if the missing dimension is present in the objects natural dimensions,
// the missing dimension is taken from the objects natural dimensions.
if (specified_height.has_value() && natural_width.has_value())
return CSSPixelSize { natural_width.value(), specified_height.value() };
if (specified_width.has_value() && natural_height.has_value())
return CSSPixelSize { specified_width.value(), natural_height.value() };
// 3. Otherwise, the missing dimension of the concrete object size is taken from the default object size.
if (specified_height.has_value())
return CSSPixelSize { default_size.width(), specified_height.value() };
if (specified_width.has_value())
return CSSPixelSize { specified_width.value(), default_size.height() };
VERIFY_NOT_REACHED();
}
// If the specified size has no constraints:
// 1. If the object has a natural height or width, its size is resolved as if its natural dimensions were given as the specified size.
if (natural_width.has_value() || natural_height.has_value())
return run_default_sizing_algorithm(natural_width, natural_height, natural_width, natural_height, natural_aspect_ratio, default_size);
// FIXME: 2. Otherwise, its size is resolved as a contain constraint against the default object size.
return default_size;
}
}

View file

@ -0,0 +1,20 @@
/*
* Copyright (c) 2024, Sam Atkins <sam@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibWeb/PixelUnits.h>
namespace Web::CSS {
// https://drafts.csswg.org/css-images/#default-sizing
CSSPixelSize run_default_sizing_algorithm(
Optional<CSSPixels> specified_width, Optional<CSSPixels> specified_height,
Optional<CSSPixels> natural_width, Optional<CSSPixels> natural_height,
Optional<CSSPixelFraction> natural_aspect_ratio,
CSSPixelSize default_size);
}

View file

@ -6,6 +6,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/CSS/Sizing.h>
#include <LibWeb/Layout/Node.h>
#include <LibWeb/Layout/Viewport.h>
#include <LibWeb/Painting/BackgroundPainting.h>
@ -14,48 +15,6 @@
namespace Web::Painting {
// https://drafts.csswg.org/css-images/#default-sizing
static CSSPixelSize run_default_sizing_algorithm(
Optional<CSSPixels> specified_width, Optional<CSSPixels> specified_height,
Optional<CSSPixels> natural_width, Optional<CSSPixels> natural_height,
Optional<CSSPixelFraction> natural_aspect_ratio,
CSSPixelSize default_size)
{
// If the specified size is a definite width and height, the concrete object size is given that width and height.
if (specified_width.has_value() && specified_height.has_value())
return CSSPixelSize { specified_width.value(), specified_height.value() };
// If the specified size is only a width or height (but not both) then the concrete object size is given that specified width or height.
// The other dimension is calculated as follows:
if (specified_width.has_value() || specified_height.has_value()) {
// 1. If the object has a natural aspect ratio,
// the missing dimension of the concrete object size is calculated using that aspect ratio and the present dimension.
if (natural_aspect_ratio.has_value() && !natural_aspect_ratio->might_be_saturated()) {
if (specified_width.has_value())
return CSSPixelSize { specified_width.value(), (CSSPixels(1) / natural_aspect_ratio.value()) * specified_width.value() };
if (specified_height.has_value())
return CSSPixelSize { specified_height.value() * natural_aspect_ratio.value(), specified_height.value() };
}
// 2. Otherwise, if the missing dimension is present in the objects natural dimensions,
// the missing dimension is taken from the objects natural dimensions.
if (specified_height.has_value() && natural_width.has_value())
return CSSPixelSize { natural_width.value(), specified_height.value() };
if (specified_width.has_value() && natural_height.has_value())
return CSSPixelSize { specified_width.value(), natural_height.value() };
// 3. Otherwise, the missing dimension of the concrete object size is taken from the default object size.
if (specified_height.has_value())
return CSSPixelSize { default_size.width(), specified_height.value() };
if (specified_width.has_value())
return CSSPixelSize { specified_width.value(), default_size.height() };
VERIFY_NOT_REACHED();
}
// If the specified size has no constraints:
// 1. If the object has a natural height or width, its size is resolved as if its natural dimensions were given as the specified size.
if (natural_width.has_value() || natural_height.has_value())
return run_default_sizing_algorithm(natural_width, natural_height, natural_width, natural_height, natural_aspect_ratio, default_size);
// FIXME: 2. Otherwise, its size is resolved as a contain constraint against the default object size.
return default_size;
}
static RefPtr<DisplayList> compute_text_clip_paths(PaintContext& context, Paintable const& paintable, CSSPixelPoint containing_block_location)
{
auto text_clip_paths = DisplayList::create();
@ -373,7 +332,7 @@ ResolvedBackground resolve_background_layers(Vector<CSS::BackgroundLayerData> co
if (!layer.size_y.is_auto())
specified_height = layer.size_y.to_px(layout_node, background_positioning_area.height());
}
auto concrete_image_size = run_default_sizing_algorithm(
auto concrete_image_size = CSS::run_default_sizing_algorithm(
specified_width, specified_height,
image.natural_width(), image.natural_height(), image.natural_aspect_ratio(),
background_positioning_area.size());