mirror of
https://github.com/RGBCube/serenity
synced 2025-05-14 09:34:59 +00:00
LibWeb: Add "object-position" CSS property into ComputedValues
This commit is contained in:
parent
677a00ed92
commit
a0dc9584de
5 changed files with 46 additions and 29 deletions
|
@ -21,6 +21,7 @@
|
|||
#include <LibWeb/CSS/Ratio.h>
|
||||
#include <LibWeb/CSS/Size.h>
|
||||
#include <LibWeb/CSS/StyleValues/AbstractImageStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/PositionStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/ShadowStyleValue.h>
|
||||
#include <LibWeb/CSS/Transformation.h>
|
||||
|
||||
|
@ -76,6 +77,13 @@ struct ResolvedBackdropFilter {
|
|||
Vector<FilterFunction> filters;
|
||||
};
|
||||
|
||||
struct ObjectPosition {
|
||||
PositionEdge edge_x { PositionEdge::Left };
|
||||
CSS::LengthPercentage offset_x { Percentage(50) };
|
||||
PositionEdge edge_y { PositionEdge::Top };
|
||||
CSS::LengthPercentage offset_y { Percentage(50) };
|
||||
};
|
||||
|
||||
class InitialValues {
|
||||
public:
|
||||
static AspectRatio aspect_ratio() { return AspectRatio { true, {} }; }
|
||||
|
@ -154,6 +162,7 @@ public:
|
|||
static Vector<Vector<String>> grid_template_areas() { return {}; }
|
||||
static CSS::Time transition_delay() { return CSS::Time::make_seconds(0); }
|
||||
static CSS::ObjectFit object_fit() { return CSS::ObjectFit::Fill; }
|
||||
static CSS::ObjectPosition object_position() { return {}; }
|
||||
static Color outline_color() { return Color::Black; }
|
||||
static CSS::Length outline_offset() { return CSS::Length::make_px(0); }
|
||||
static CSS::OutlineStyle outline_style() { return CSS::OutlineStyle::None; }
|
||||
|
@ -359,6 +368,7 @@ public:
|
|||
CSS::BorderCollapse border_collapse() const { return m_inherited.border_collapse; }
|
||||
Vector<Vector<String>> const& grid_template_areas() const { return m_noninherited.grid_template_areas; }
|
||||
CSS::ObjectFit object_fit() const { return m_noninherited.object_fit; }
|
||||
CSS::ObjectPosition object_position() const { return m_noninherited.object_position; }
|
||||
|
||||
CSS::LengthBox const& inset() const { return m_noninherited.inset; }
|
||||
const CSS::LengthBox& margin() const { return m_noninherited.margin; }
|
||||
|
@ -548,6 +558,7 @@ protected:
|
|||
CSS::Length outline_width { InitialValues::outline_width() };
|
||||
CSS::TableLayout table_layout { InitialValues::table_layout() };
|
||||
CSS::ObjectFit object_fit { InitialValues::object_fit() };
|
||||
CSS::ObjectPosition object_position { InitialValues::object_position() };
|
||||
|
||||
Optional<MaskReference> mask;
|
||||
CSS::MaskType mask_type { InitialValues::mask_type() };
|
||||
|
@ -660,6 +671,7 @@ public:
|
|||
void set_table_layout(CSS::TableLayout value) { m_noninherited.table_layout = value; }
|
||||
void set_quotes(CSS::QuotesData value) { m_inherited.quotes = value; }
|
||||
void set_object_fit(CSS::ObjectFit value) { m_noninherited.object_fit = value; }
|
||||
void set_object_position(CSS::ObjectPosition value) { m_noninherited.object_position = value; }
|
||||
|
||||
void set_fill(SVGPaint value) { m_inherited.fill = value; }
|
||||
void set_stroke(SVGPaint value) { m_inherited.stroke = value; }
|
||||
|
|
|
@ -1026,10 +1026,24 @@ Optional<CSS::ObjectFit> StyleProperties::object_fit() const
|
|||
return value_id_to_object_fit(value->to_identifier());
|
||||
}
|
||||
|
||||
CSS::PositionStyleValue const& StyleProperties::object_position() const
|
||||
CSS::ObjectPosition StyleProperties::object_position() const
|
||||
{
|
||||
auto value = property(CSS::PropertyID::ObjectPosition);
|
||||
return value->as_position();
|
||||
auto const& position = value->as_position();
|
||||
CSS::ObjectPosition object_position;
|
||||
auto const& edge_x = position.edge_x();
|
||||
auto const& edge_y = position.edge_y();
|
||||
if (edge_x->is_edge()) {
|
||||
auto const& edge = edge_x->as_edge();
|
||||
object_position.edge_x = edge.edge();
|
||||
object_position.offset_x = edge.offset();
|
||||
}
|
||||
if (edge_y->is_edge()) {
|
||||
auto const& edge = edge_y->as_edge();
|
||||
object_position.edge_y = edge.edge();
|
||||
object_position.offset_y = edge.offset();
|
||||
}
|
||||
return object_position;
|
||||
}
|
||||
|
||||
Optional<CSS::TableLayout> StyleProperties::table_layout() const
|
||||
|
|
|
@ -114,7 +114,7 @@ public:
|
|||
Vector<Vector<String>> grid_template_areas() const;
|
||||
String grid_area() const;
|
||||
Optional<CSS::ObjectFit> object_fit() const;
|
||||
CSS::PositionStyleValue const& object_position() const;
|
||||
CSS::ObjectPosition object_position() const;
|
||||
Optional<CSS::TableLayout> table_layout() const;
|
||||
|
||||
static Vector<CSS::Transformation> transformations_for_style_value(StyleValue const& value);
|
||||
|
|
|
@ -833,6 +833,8 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& computed_style)
|
|||
if (auto object_fit = computed_style.object_fit(); object_fit.has_value())
|
||||
computed_values.set_object_fit(object_fit.value());
|
||||
|
||||
computed_values.set_object_position(computed_style.object_position());
|
||||
|
||||
propagate_style_to_anonymous_wrappers();
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,6 @@ void ImagePaintable::paint(PaintContext& context, PaintPhase phase) const
|
|||
auto image_int_rect = image_rect.to_type<int>();
|
||||
auto bitmap_rect = bitmap->rect();
|
||||
auto scaling_mode = to_gfx_scaling_mode(computed_values().image_rendering(), bitmap_rect, image_int_rect);
|
||||
auto& dom_element = verify_cast<DOM::Element>(*dom_node());
|
||||
auto bitmap_aspect_ratio = (float)bitmap_rect.height() / bitmap_rect.width();
|
||||
auto image_aspect_ratio = (float)image_rect.height().value() / image_rect.width().value();
|
||||
|
||||
|
@ -121,37 +120,27 @@ void ImagePaintable::paint(PaintContext& context, PaintPhase phase) const
|
|||
bitmap_intersect.set_x((bitmap_rect.width() - bitmap_intersect.width()) / 2);
|
||||
bitmap_intersect.set_y((bitmap_rect.height() - bitmap_intersect.height()) / 2);
|
||||
|
||||
CSS::PositionStyleValue const& object_position = dom_element.computed_css_values()->object_position();
|
||||
auto const& object_position = computed_values().object_position();
|
||||
|
||||
auto offset_x = 0;
|
||||
auto const& horizontal = object_position.edge_x();
|
||||
if (horizontal->is_edge()) {
|
||||
auto const& horizontal_edge = horizontal->as_edge();
|
||||
auto const& offset = horizontal_edge.offset();
|
||||
if (horizontal_edge.edge() == CSS::PositionEdge::Left) {
|
||||
offset_x = offset.to_px(layout_node(), residual_horizontal).to_int();
|
||||
bitmap_intersect.set_x(0);
|
||||
} else if (horizontal_edge.edge() == CSS::PositionEdge::Right) {
|
||||
offset_x = residual_horizontal.to_int() - offset.to_px(layout_node(), residual_horizontal).to_int();
|
||||
}
|
||||
if (image_int_rect.width() < scaled_bitmap_width)
|
||||
bitmap_intersect.set_x(-(offset_x / scale_x));
|
||||
if (object_position.edge_x == CSS::PositionEdge::Left) {
|
||||
offset_x = object_position.offset_x.to_px(layout_node(), residual_horizontal).to_int();
|
||||
bitmap_intersect.set_x(0);
|
||||
} else if (object_position.edge_x == CSS::PositionEdge::Right) {
|
||||
offset_x = residual_horizontal.to_int() - object_position.offset_x.to_px(layout_node(), residual_horizontal).to_int();
|
||||
}
|
||||
if (image_int_rect.width() < scaled_bitmap_width)
|
||||
bitmap_intersect.set_x(-(offset_x / scale_x));
|
||||
|
||||
auto offset_y = 0;
|
||||
auto const& vertical = object_position.edge_y();
|
||||
if (vertical->is_edge()) {
|
||||
auto const& vertical_edge = vertical->as_edge();
|
||||
auto const& offset = vertical_edge.offset();
|
||||
if (vertical_edge.edge() == CSS::PositionEdge::Top) {
|
||||
offset_y = offset.to_px(layout_node(), residual_vertical).to_int();
|
||||
bitmap_intersect.set_y(0);
|
||||
} else if (vertical_edge.edge() == CSS::PositionEdge::Bottom) {
|
||||
offset_y = residual_vertical.to_int() - offset.to_px(layout_node(), residual_vertical).to_int();
|
||||
}
|
||||
if (image_int_rect.height() < scaled_bitmap_height)
|
||||
bitmap_intersect.set_y(-(offset_y / scale_y));
|
||||
if (object_position.edge_y == CSS::PositionEdge::Top) {
|
||||
offset_y = object_position.offset_y.to_px(layout_node(), residual_vertical).to_int();
|
||||
bitmap_intersect.set_y(0);
|
||||
} else if (object_position.edge_y == CSS::PositionEdge::Bottom) {
|
||||
offset_y = residual_vertical.to_int() - object_position.offset_y.to_px(layout_node(), residual_vertical).to_int();
|
||||
}
|
||||
if (image_int_rect.height() < scaled_bitmap_height)
|
||||
bitmap_intersect.set_y(-(offset_y / scale_y));
|
||||
|
||||
Gfx::IntRect draw_rect = {
|
||||
image_int_rect.x() + offset_x,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue