LibWeb: Convert background-size from Length to LengthPercentage
Checking these for `auto` is awkward, but separating that will come later. :^)
This commit is contained in:
parent
f75e796909
commit
f602249ae9
Notes:
sideshowbarker
2024-07-17 20:36:47 +09:00
Author: https://github.com/AtkinsSJ Commit: https://github.com/SerenityOS/serenity/commit/f602249ae95 Pull-request: https://github.com/SerenityOS/serenity/pull/12007
4 changed files with 46 additions and 21 deletions
|
@ -49,8 +49,8 @@ struct BackgroundLayerData {
|
|||
CSS::PositionEdge position_edge_y { CSS::PositionEdge::Top };
|
||||
CSS::Length position_offset_y { CSS::Length::make_px(0) };
|
||||
CSS::BackgroundSize size_type { CSS::BackgroundSize::LengthPercentage };
|
||||
CSS::Length size_x { CSS::Length::make_auto() };
|
||||
CSS::Length size_y { CSS::Length::make_auto() };
|
||||
CSS::LengthPercentage size_x { CSS::Length::make_auto() };
|
||||
CSS::LengthPercentage size_y { CSS::Length::make_auto() };
|
||||
CSS::Repeat repeat_x { CSS::Repeat::Repeat };
|
||||
CSS::Repeat repeat_y { CSS::Repeat::Repeat };
|
||||
};
|
||||
|
|
|
@ -2940,6 +2940,14 @@ RefPtr<StyleValue> Parser::parse_single_background_size_value(TokenStream<StyleC
|
|||
return nullptr;
|
||||
};
|
||||
|
||||
auto get_length_percentage = [](StyleValue& style_value) -> Optional<LengthPercentage> {
|
||||
if (style_value.is_percentage())
|
||||
return LengthPercentage { style_value.as_percentage().percentage() };
|
||||
if (style_value.has_length())
|
||||
return LengthPercentage { style_value.to_length() };
|
||||
return {};
|
||||
};
|
||||
|
||||
auto maybe_x_value = parse_css_value(tokens.next_token());
|
||||
if (!maybe_x_value || !property_accepts_value(PropertyID::BackgroundSize, *maybe_x_value))
|
||||
return error();
|
||||
|
@ -2949,13 +2957,20 @@ RefPtr<StyleValue> Parser::parse_single_background_size_value(TokenStream<StyleC
|
|||
return x_value;
|
||||
|
||||
auto maybe_y_value = parse_css_value(tokens.peek_token());
|
||||
if (!maybe_y_value || !property_accepts_value(PropertyID::BackgroundSize, *maybe_y_value))
|
||||
return BackgroundSizeStyleValue::create(x_value->to_length(), x_value->to_length());
|
||||
if (!maybe_y_value || !property_accepts_value(PropertyID::BackgroundSize, *maybe_y_value)) {
|
||||
auto x_size = get_length_percentage(*x_value);
|
||||
if (!x_size.has_value())
|
||||
return error();
|
||||
return BackgroundSizeStyleValue::create(x_size.value(), x_size.value());
|
||||
}
|
||||
|
||||
tokens.next_token();
|
||||
auto y_value = maybe_y_value.release_nonnull();
|
||||
auto x_size = get_length_percentage(*x_value);
|
||||
auto y_size = get_length_percentage(*y_value);
|
||||
|
||||
if (x_value->has_length() && y_value->has_length())
|
||||
return BackgroundSizeStyleValue::create(x_value->to_length(), y_value->to_length());
|
||||
if (x_size.has_value() && y_size.has_value())
|
||||
return BackgroundSizeStyleValue::create(x_size.release_value(), y_size.release_value());
|
||||
|
||||
return error();
|
||||
}
|
||||
|
|
|
@ -499,14 +499,14 @@ private:
|
|||
// NOTE: This is not used for identifier sizes, like `cover` and `contain`.
|
||||
class BackgroundSizeStyleValue final : public StyleValue {
|
||||
public:
|
||||
static NonnullRefPtr<BackgroundSizeStyleValue> create(Length size_x, Length size_y)
|
||||
static NonnullRefPtr<BackgroundSizeStyleValue> create(LengthPercentage size_x, LengthPercentage size_y)
|
||||
{
|
||||
return adopt_ref(*new BackgroundSizeStyleValue(size_x, size_y));
|
||||
}
|
||||
virtual ~BackgroundSizeStyleValue() override { }
|
||||
|
||||
Length size_x() const { return m_size_x; }
|
||||
Length size_y() const { return m_size_y; }
|
||||
LengthPercentage size_x() const { return m_size_x; }
|
||||
LengthPercentage size_y() const { return m_size_y; }
|
||||
|
||||
virtual String to_string() const override
|
||||
{
|
||||
|
@ -514,15 +514,15 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
BackgroundSizeStyleValue(Length size_x, Length size_y)
|
||||
BackgroundSizeStyleValue(LengthPercentage size_x, LengthPercentage size_y)
|
||||
: StyleValue(Type::BackgroundSize)
|
||||
, m_size_x(size_x)
|
||||
, m_size_y(size_y)
|
||||
{
|
||||
}
|
||||
|
||||
Length m_size_x;
|
||||
Length m_size_y;
|
||||
LengthPercentage m_size_x;
|
||||
LengthPercentage m_size_y;
|
||||
};
|
||||
|
||||
class BorderStyleValue final : public StyleValue {
|
||||
|
|
|
@ -82,18 +82,28 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
|
|||
case CSS::BackgroundSize::LengthPercentage: {
|
||||
int width;
|
||||
int height;
|
||||
if (layer.size_x.is_auto() && layer.size_y.is_auto()) {
|
||||
bool x_is_auto = layer.size_x.is_length() && layer.size_x.length().is_auto();
|
||||
bool y_is_auto = layer.size_y.is_length() && layer.size_y.length().is_auto();
|
||||
if (x_is_auto && y_is_auto) {
|
||||
width = image.width();
|
||||
height = image.height();
|
||||
} else if (layer.size_x.is_auto()) {
|
||||
height = layer.size_y.resolved_or_zero(layout_node, background_positioning_area.height()).to_px(layout_node);
|
||||
} else if (x_is_auto) {
|
||||
height = layer.size_y.resolved(CSS::Length::make_px(background_positioning_area.height()))
|
||||
.resolved_or_zero(layout_node, background_positioning_area.height())
|
||||
.to_px(layout_node);
|
||||
width = roundf(image.width() * ((float)height / (float)image.height()));
|
||||
} else if (layer.size_y.is_auto()) {
|
||||
width = layer.size_x.resolved_or_zero(layout_node, background_positioning_area.width()).to_px(layout_node);
|
||||
} else if (y_is_auto) {
|
||||
width = layer.size_x.resolved(CSS::Length::make_px(background_positioning_area.width()))
|
||||
.resolved_or_zero(layout_node, background_positioning_area.width())
|
||||
.to_px(layout_node);
|
||||
height = roundf(image.height() * ((float)width / (float)image.width()));
|
||||
} else {
|
||||
width = layer.size_x.resolved_or_zero(layout_node, background_positioning_area.width()).to_px(layout_node);
|
||||
height = layer.size_y.resolved_or_zero(layout_node, background_positioning_area.height()).to_px(layout_node);
|
||||
width = layer.size_x.resolved(CSS::Length::make_px(background_positioning_area.width()))
|
||||
.resolved_or_zero(layout_node, background_positioning_area.width())
|
||||
.to_px(layout_node);
|
||||
height = layer.size_y.resolved(CSS::Length::make_px(background_positioning_area.height()))
|
||||
.resolved_or_zero(layout_node, background_positioning_area.height())
|
||||
.to_px(layout_node);
|
||||
}
|
||||
|
||||
image_rect.set_size(width, height);
|
||||
|
@ -120,10 +130,10 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
|
|||
// for the other dimension, then there is a third step: that other dimension is scaled
|
||||
// so that the original aspect ratio is restored.
|
||||
if (layer.repeat_x != layer.repeat_y) {
|
||||
if (layer.size_x.is_auto()) {
|
||||
if (layer.size_x.is_length() && layer.size_x.length().is_auto()) {
|
||||
image_rect.set_width((float)image.width() * ((float)image_rect.height() / (float)image.height()));
|
||||
}
|
||||
if (layer.size_y.is_auto()) {
|
||||
if (layer.size_y.is_length() && layer.size_y.length().is_auto()) {
|
||||
image_rect.set_height((float)image.height() * ((float)image_rect.width() / (float)image.width()));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue