mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 15:12:45 +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/Ratio.h> | ||||||
| #include <LibWeb/CSS/Size.h> | #include <LibWeb/CSS/Size.h> | ||||||
| #include <LibWeb/CSS/StyleValues/AbstractImageStyleValue.h> | #include <LibWeb/CSS/StyleValues/AbstractImageStyleValue.h> | ||||||
|  | #include <LibWeb/CSS/StyleValues/PositionStyleValue.h> | ||||||
| #include <LibWeb/CSS/StyleValues/ShadowStyleValue.h> | #include <LibWeb/CSS/StyleValues/ShadowStyleValue.h> | ||||||
| #include <LibWeb/CSS/Transformation.h> | #include <LibWeb/CSS/Transformation.h> | ||||||
| 
 | 
 | ||||||
|  | @ -76,6 +77,13 @@ struct ResolvedBackdropFilter { | ||||||
|     Vector<FilterFunction> filters; |     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 { | class InitialValues { | ||||||
| public: | public: | ||||||
|     static AspectRatio aspect_ratio() { return AspectRatio { true, {} }; } |     static AspectRatio aspect_ratio() { return AspectRatio { true, {} }; } | ||||||
|  | @ -154,6 +162,7 @@ public: | ||||||
|     static Vector<Vector<String>> grid_template_areas() { return {}; } |     static Vector<Vector<String>> grid_template_areas() { return {}; } | ||||||
|     static CSS::Time transition_delay() { return CSS::Time::make_seconds(0); } |     static CSS::Time transition_delay() { return CSS::Time::make_seconds(0); } | ||||||
|     static CSS::ObjectFit object_fit() { return CSS::ObjectFit::Fill; } |     static CSS::ObjectFit object_fit() { return CSS::ObjectFit::Fill; } | ||||||
|  |     static CSS::ObjectPosition object_position() { return {}; } | ||||||
|     static Color outline_color() { return Color::Black; } |     static Color outline_color() { return Color::Black; } | ||||||
|     static CSS::Length outline_offset() { return CSS::Length::make_px(0); } |     static CSS::Length outline_offset() { return CSS::Length::make_px(0); } | ||||||
|     static CSS::OutlineStyle outline_style() { return CSS::OutlineStyle::None; } |     static CSS::OutlineStyle outline_style() { return CSS::OutlineStyle::None; } | ||||||
|  | @ -359,6 +368,7 @@ public: | ||||||
|     CSS::BorderCollapse border_collapse() const { return m_inherited.border_collapse; } |     CSS::BorderCollapse border_collapse() const { return m_inherited.border_collapse; } | ||||||
|     Vector<Vector<String>> const& grid_template_areas() const { return m_noninherited.grid_template_areas; } |     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::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; } |     CSS::LengthBox const& inset() const { return m_noninherited.inset; } | ||||||
|     const CSS::LengthBox& margin() const { return m_noninherited.margin; } |     const CSS::LengthBox& margin() const { return m_noninherited.margin; } | ||||||
|  | @ -548,6 +558,7 @@ protected: | ||||||
|         CSS::Length outline_width { InitialValues::outline_width() }; |         CSS::Length outline_width { InitialValues::outline_width() }; | ||||||
|         CSS::TableLayout table_layout { InitialValues::table_layout() }; |         CSS::TableLayout table_layout { InitialValues::table_layout() }; | ||||||
|         CSS::ObjectFit object_fit { InitialValues::object_fit() }; |         CSS::ObjectFit object_fit { InitialValues::object_fit() }; | ||||||
|  |         CSS::ObjectPosition object_position { InitialValues::object_position() }; | ||||||
| 
 | 
 | ||||||
|         Optional<MaskReference> mask; |         Optional<MaskReference> mask; | ||||||
|         CSS::MaskType mask_type { InitialValues::mask_type() }; |         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_table_layout(CSS::TableLayout value) { m_noninherited.table_layout = value; } | ||||||
|     void set_quotes(CSS::QuotesData value) { m_inherited.quotes = 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_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_fill(SVGPaint value) { m_inherited.fill = value; } | ||||||
|     void set_stroke(SVGPaint value) { m_inherited.stroke = 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()); |     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); |     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 | Optional<CSS::TableLayout> StyleProperties::table_layout() const | ||||||
|  |  | ||||||
|  | @ -114,7 +114,7 @@ public: | ||||||
|     Vector<Vector<String>> grid_template_areas() const; |     Vector<Vector<String>> grid_template_areas() const; | ||||||
|     String grid_area() const; |     String grid_area() const; | ||||||
|     Optional<CSS::ObjectFit> object_fit() const; |     Optional<CSS::ObjectFit> object_fit() const; | ||||||
|     CSS::PositionStyleValue const& object_position() const; |     CSS::ObjectPosition object_position() const; | ||||||
|     Optional<CSS::TableLayout> table_layout() const; |     Optional<CSS::TableLayout> table_layout() const; | ||||||
| 
 | 
 | ||||||
|     static Vector<CSS::Transformation> transformations_for_style_value(StyleValue const& value); |     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()) |     if (auto object_fit = computed_style.object_fit(); object_fit.has_value()) | ||||||
|         computed_values.set_object_fit(object_fit.value()); |         computed_values.set_object_fit(object_fit.value()); | ||||||
| 
 | 
 | ||||||
|  |     computed_values.set_object_position(computed_style.object_position()); | ||||||
|  | 
 | ||||||
|     propagate_style_to_anonymous_wrappers(); |     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 image_int_rect = image_rect.to_type<int>(); | ||||||
|             auto bitmap_rect = bitmap->rect(); |             auto bitmap_rect = bitmap->rect(); | ||||||
|             auto scaling_mode = to_gfx_scaling_mode(computed_values().image_rendering(), bitmap_rect, image_int_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 bitmap_aspect_ratio = (float)bitmap_rect.height() / bitmap_rect.width(); | ||||||
|             auto image_aspect_ratio = (float)image_rect.height().value() / image_rect.width().value(); |             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_x((bitmap_rect.width() - bitmap_intersect.width()) / 2); | ||||||
|             bitmap_intersect.set_y((bitmap_rect.height() - bitmap_intersect.height()) / 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 offset_x = 0; | ||||||
|             auto const& horizontal = object_position.edge_x(); |             if (object_position.edge_x == CSS::PositionEdge::Left) { | ||||||
|             if (horizontal->is_edge()) { |                 offset_x = object_position.offset_x.to_px(layout_node(), residual_horizontal).to_int(); | ||||||
|                 auto const& horizontal_edge = horizontal->as_edge(); |                 bitmap_intersect.set_x(0); | ||||||
|                 auto const& offset = horizontal_edge.offset(); |             } else if (object_position.edge_x == CSS::PositionEdge::Right) { | ||||||
|                 if (horizontal_edge.edge() == CSS::PositionEdge::Left) { |                 offset_x = residual_horizontal.to_int() - object_position.offset_x.to_px(layout_node(), residual_horizontal).to_int(); | ||||||
|                     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 (image_int_rect.width() < scaled_bitmap_width) | ||||||
|  |                 bitmap_intersect.set_x(-(offset_x / scale_x)); | ||||||
| 
 | 
 | ||||||
|             auto offset_y = 0; |             auto offset_y = 0; | ||||||
|             auto const& vertical = object_position.edge_y(); |             if (object_position.edge_y == CSS::PositionEdge::Top) { | ||||||
|             if (vertical->is_edge()) { |                 offset_y = object_position.offset_y.to_px(layout_node(), residual_vertical).to_int(); | ||||||
|                 auto const& vertical_edge = vertical->as_edge(); |                 bitmap_intersect.set_y(0); | ||||||
|                 auto const& offset = vertical_edge.offset(); |             } else if (object_position.edge_y == CSS::PositionEdge::Bottom) { | ||||||
|                 if (vertical_edge.edge() == CSS::PositionEdge::Top) { |                 offset_y = residual_vertical.to_int() - object_position.offset_y.to_px(layout_node(), residual_vertical).to_int(); | ||||||
|                     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 (image_int_rect.height() < scaled_bitmap_height) | ||||||
|  |                 bitmap_intersect.set_y(-(offset_y / scale_y)); | ||||||
| 
 | 
 | ||||||
|             Gfx::IntRect draw_rect = { |             Gfx::IntRect draw_rect = { | ||||||
|                 image_int_rect.x() + offset_x, |                 image_int_rect.x() + offset_x, | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Aliaksandr Kalenik
						Aliaksandr Kalenik