2021-01-18 19:33:46 +03:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
|
|
|
|
*
|
2021-04-22 11:24:48 +03:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2021-01-18 19:33:46 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2021-10-10 16:56:29 +03:00
|
|
|
#include <LibWeb/Layout/Box.h>
|
2021-01-18 19:33:46 +03:00
|
|
|
#include <LibWeb/Layout/FormattingContext.h>
|
|
|
|
|
|
|
|
namespace Web::Layout {
|
|
|
|
|
|
|
|
class FlexFormattingContext final : public FormattingContext {
|
|
|
|
public:
|
2022-02-20 17:51:24 +03:00
|
|
|
FlexFormattingContext(FormattingState&, Box const& flex_container, FormattingContext* parent);
|
2021-01-18 19:33:46 +03:00
|
|
|
~FlexFormattingContext();
|
|
|
|
|
2021-09-15 14:19:42 +03:00
|
|
|
virtual bool inhibits_floating() const override { return true; }
|
|
|
|
|
2022-02-20 17:51:24 +03:00
|
|
|
virtual void run(Box const&, LayoutMode) override;
|
2021-10-13 20:57:26 +03:00
|
|
|
|
2021-10-13 23:52:50 +03:00
|
|
|
Box const& flex_container() const { return context_box(); }
|
|
|
|
|
2021-10-13 20:57:26 +03:00
|
|
|
private:
|
2022-03-13 02:03:59 +03:00
|
|
|
void dump_items() const;
|
|
|
|
|
2021-10-13 23:44:54 +03:00
|
|
|
struct DirectionAgnosticMargins {
|
|
|
|
float main_before { 0 };
|
|
|
|
float main_after { 0 };
|
|
|
|
float cross_before { 0 };
|
|
|
|
float cross_after { 0 };
|
|
|
|
};
|
|
|
|
|
|
|
|
struct FlexItem {
|
|
|
|
Box& box;
|
|
|
|
float flex_base_size { 0 };
|
|
|
|
float hypothetical_main_size { 0 };
|
|
|
|
float hypothetical_cross_size { 0 };
|
2022-03-27 17:14:18 +03:00
|
|
|
float hypothetical_cross_size_with_margins() { return hypothetical_cross_size + margins.cross_before + margins.cross_after + borders.cross_after + borders.cross_before + padding.cross_after + padding.cross_before; }
|
2021-10-13 23:44:54 +03:00
|
|
|
float target_main_size { 0 };
|
|
|
|
bool frozen { false };
|
|
|
|
Optional<float> flex_factor {};
|
|
|
|
float scaled_flex_shrink_factor { 0 };
|
|
|
|
float max_content_flex_fraction { 0 };
|
|
|
|
float main_size { 0 };
|
|
|
|
float cross_size { 0 };
|
|
|
|
float main_offset { 0 };
|
|
|
|
float cross_offset { 0 };
|
|
|
|
DirectionAgnosticMargins margins {};
|
2022-03-27 17:14:18 +03:00
|
|
|
DirectionAgnosticMargins borders {};
|
|
|
|
DirectionAgnosticMargins padding {};
|
2021-10-13 23:44:54 +03:00
|
|
|
bool is_min_violation { false };
|
|
|
|
bool is_max_violation { false };
|
|
|
|
};
|
|
|
|
|
|
|
|
struct FlexLine {
|
|
|
|
Vector<FlexItem*> items;
|
|
|
|
float cross_size { 0 };
|
|
|
|
};
|
|
|
|
|
2021-10-13 22:24:00 +03:00
|
|
|
bool has_definite_main_size(Box const&) const;
|
|
|
|
bool has_definite_cross_size(Box const&) const;
|
|
|
|
float specified_main_size(Box const&) const;
|
|
|
|
float specified_cross_size(Box const&) const;
|
2022-03-12 16:11:55 +03:00
|
|
|
float resolved_definite_main_size(Box const&) const;
|
|
|
|
float resolved_definite_cross_size(Box const&) const;
|
2021-10-13 22:24:00 +03:00
|
|
|
bool has_main_min_size(Box const&) const;
|
|
|
|
bool has_cross_min_size(Box const&) const;
|
|
|
|
float specified_main_max_size(Box const&) const;
|
|
|
|
float specified_cross_max_size(Box const&) const;
|
|
|
|
float calculated_main_size(Box const&) const;
|
|
|
|
bool is_cross_auto(Box const&) const;
|
|
|
|
bool is_main_axis_margin_first_auto(Box const&) const;
|
|
|
|
bool is_main_axis_margin_second_auto(Box const&) const;
|
2021-10-13 23:52:50 +03:00
|
|
|
float specified_main_size_of_child_box(Box const& child_box) const;
|
2021-10-13 22:24:00 +03:00
|
|
|
float specified_main_min_size(Box const&) const;
|
|
|
|
float specified_cross_min_size(Box const&) const;
|
|
|
|
bool has_main_max_size(Box const&) const;
|
|
|
|
bool has_cross_max_size(Box const&) const;
|
|
|
|
float sum_of_margin_padding_border_in_main_axis(Box const&) const;
|
2022-03-30 20:50:57 +03:00
|
|
|
float determine_min_main_size_of_child(Box const& box);
|
2021-10-13 22:24:00 +03:00
|
|
|
|
2022-02-20 17:51:24 +03:00
|
|
|
void set_main_size(Box const&, float size);
|
|
|
|
void set_cross_size(Box const&, float size);
|
|
|
|
void set_offset(Box const&, float main_offset, float cross_offset);
|
|
|
|
void set_main_axis_first_margin(Box const&, float margin);
|
|
|
|
void set_main_axis_second_margin(Box const&, float margin);
|
2021-10-13 22:24:00 +03:00
|
|
|
|
2022-02-28 01:58:54 +03:00
|
|
|
void copy_dimensions_from_flex_items_to_boxes();
|
2022-02-27 11:50:09 +03:00
|
|
|
|
2021-10-13 23:52:50 +03:00
|
|
|
void generate_anonymous_flex_items();
|
2021-10-13 20:57:26 +03:00
|
|
|
|
2022-03-12 16:40:13 +03:00
|
|
|
void determine_available_main_and_cross_space(bool& main_is_constrained, bool& cross_is_constrained, float& main_min_size, float& main_max_size, float& cross_min_size, float& cross_max_size);
|
2021-10-13 22:41:35 +03:00
|
|
|
|
2022-03-12 16:40:13 +03:00
|
|
|
float calculate_indefinite_main_size(FlexItem const&);
|
2021-10-13 23:52:50 +03:00
|
|
|
void determine_flex_base_size_and_hypothetical_main_size(FlexItem&);
|
2021-10-13 22:49:28 +03:00
|
|
|
|
2022-03-12 16:40:13 +03:00
|
|
|
void determine_main_size_of_flex_container(bool main_is_constrained, float main_min_size, float main_max_size);
|
2021-10-13 23:03:39 +03:00
|
|
|
|
2022-03-12 16:40:13 +03:00
|
|
|
void collect_flex_items_into_flex_lines();
|
2021-10-13 23:07:55 +03:00
|
|
|
|
2022-03-12 16:40:13 +03:00
|
|
|
void resolve_flexible_lengths();
|
2021-10-13 23:11:50 +03:00
|
|
|
|
2022-02-27 15:39:38 +03:00
|
|
|
void determine_hypothetical_cross_size_of_item(FlexItem&);
|
2021-10-13 23:15:16 +03:00
|
|
|
|
2021-10-13 23:52:50 +03:00
|
|
|
void calculate_cross_size_of_each_flex_line(float cross_min_size, float cross_max_size);
|
2021-10-13 23:17:33 +03:00
|
|
|
|
2021-10-13 23:52:50 +03:00
|
|
|
void determine_used_cross_size_of_each_flex_item();
|
2021-10-13 23:19:17 +03:00
|
|
|
|
2022-03-12 16:40:13 +03:00
|
|
|
void distribute_any_remaining_free_space();
|
2021-10-13 23:20:55 +03:00
|
|
|
|
2021-10-13 23:52:50 +03:00
|
|
|
void align_all_flex_items_along_the_cross_axis();
|
2021-10-13 23:22:30 +03:00
|
|
|
|
2021-10-13 23:52:50 +03:00
|
|
|
void determine_flex_container_used_cross_size(float cross_min_size, float cross_max_size);
|
2021-10-13 23:24:09 +03:00
|
|
|
|
2021-10-13 23:44:54 +03:00
|
|
|
void align_all_flex_lines();
|
2021-10-13 23:25:39 +03:00
|
|
|
|
2021-10-13 20:57:26 +03:00
|
|
|
bool is_row_layout() const { return m_flex_direction == CSS::FlexDirection::Row || m_flex_direction == CSS::FlexDirection::RowReverse; }
|
2021-10-14 00:38:04 +03:00
|
|
|
bool is_single_line() const { return flex_container().computed_values().flex_wrap() == CSS::FlexWrap::Nowrap; }
|
2022-04-02 12:29:55 +03:00
|
|
|
bool is_direction_reverse() const { return m_flex_direction == CSS::FlexDirection::ColumnReverse || m_flex_direction == CSS::FlexDirection::RowReverse; }
|
2021-10-13 23:44:54 +03:00
|
|
|
void populate_specified_margins(FlexItem&, CSS::FlexDirection) const;
|
|
|
|
|
2022-04-06 02:20:20 +03:00
|
|
|
void determine_intrinsic_size_of_flex_container(LayoutMode);
|
|
|
|
[[nodiscard]] float calculate_intrinsic_main_size_of_flex_container(LayoutMode);
|
|
|
|
[[nodiscard]] float calculate_intrinsic_cross_size_of_flex_container(LayoutMode);
|
|
|
|
|
|
|
|
[[nodiscard]] float calculate_cross_min_content_contribution(FlexItem const&) const;
|
|
|
|
[[nodiscard]] float calculate_cross_max_content_contribution(FlexItem const&) const;
|
|
|
|
[[nodiscard]] float calculate_main_min_content_contribution(FlexItem const&) const;
|
|
|
|
[[nodiscard]] float calculate_main_max_content_contribution(FlexItem const&) const;
|
|
|
|
|
2022-02-20 17:51:24 +03:00
|
|
|
FormattingState::NodeState& m_flex_container_state;
|
|
|
|
|
2021-10-13 23:44:54 +03:00
|
|
|
Vector<FlexLine> m_flex_lines;
|
|
|
|
Vector<FlexItem> m_flex_items;
|
2021-10-13 20:57:26 +03:00
|
|
|
CSS::FlexDirection m_flex_direction {};
|
2022-02-27 14:19:58 +03:00
|
|
|
|
|
|
|
struct AvailableSpace {
|
2022-03-12 16:40:13 +03:00
|
|
|
Optional<float> main;
|
|
|
|
Optional<float> cross;
|
2022-02-27 14:19:58 +03:00
|
|
|
};
|
|
|
|
Optional<AvailableSpace> m_available_space;
|
2021-01-18 19:33:46 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|