#include "third_party/blink/renderer/core/layout/flex/flex_layout_algorithm.h"
#include <memory>
#include <optional>
#include "base/not_fatal_until.h"
#include "base/types/optional_util.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/layout/baseline_utils.h"
#include "third_party/blink/renderer/core/layout/block_break_token.h"
#include "third_party/blink/renderer/core/layout/constraint_space.h"
#include "third_party/blink/renderer/core/layout/constraint_space_builder.h"
#include "third_party/blink/renderer/core/layout/disable_layout_side_effects_scope.h"
#include "third_party/blink/renderer/core/layout/flex/devtools_flex_info.h"
#include "third_party/blink/renderer/core/layout/flex/flex_child_iterator.h"
#include "third_party/blink/renderer/core/layout/flex/flex_item_iterator.h"
#include "third_party/blink/renderer/core/layout/flex/flexible_box_algorithm.h"
#include "third_party/blink/renderer/core/layout/flex/layout_flexible_box.h"
#include "third_party/blink/renderer/core/layout/flex/ng_flex_line.h"
#include "third_party/blink/renderer/core/layout/geometry/box_strut.h"
#include "third_party/blink/renderer/core/layout/geometry/logical_size.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/layout_input_node.h"
#include "third_party/blink/renderer/core/layout/length_utils.h"
#include "third_party/blink/renderer/core/layout/logical_box_fragment.h"
#include "third_party/blink/renderer/core/layout/logical_fragment.h"
#include "third_party/blink/renderer/core/layout/physical_box_fragment.h"
#include "third_party/blink/renderer/core/layout/space_utils.h"
#include "third_party/blink/renderer/core/layout/table/table_node.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style/computed_style_base_constants.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
#include "third_party/blink/renderer/platform/geometry/layout_unit.h"
#include "third_party/blink/renderer/platform/heap/collection_support/clear_collection_scope.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/text/writing_mode.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
namespace {
class BaselineAccumulator { … };
}
FlexLayoutAlgorithm::FlexLayoutAlgorithm(
const LayoutAlgorithmParams& params,
const HashMap<wtf_size_t, LayoutUnit>* cross_size_adjustments)
: … { … }
LayoutUnit FlexLayoutAlgorithm::MainAxisContentExtent(
LayoutUnit sum_hypothetical_main_size) const { … }
namespace {
enum AxisEdge { … };
AxisEdge MainAxisStaticPositionEdge(const ComputedStyle& style,
bool is_column) { … }
AxisEdge CrossAxisStaticPositionEdge(const ComputedStyle& style,
const ComputedStyle& child_style) { … }
}
void FlexLayoutAlgorithm::HandleOutOfFlowPositionedItems(
HeapVector<Member<LayoutBox>>& oof_children) { … }
void FlexLayoutAlgorithm::SetReadingFlowElements(
const HeapVector<NGFlexLine>& flex_line_outputs) { … }
bool FlexLayoutAlgorithm::IsContainerCrossSizeDefinite() const { … }
bool FlexLayoutAlgorithm::DoesItemStretch(const BlockNode& child) const { … }
bool FlexLayoutAlgorithm::DoesItemComputedCrossSizeHaveAuto(
const BlockNode& child) const { … }
bool FlexLayoutAlgorithm::WillChildCrossSizeBeContainerCrossSize(
const BlockNode& child) const { … }
ConstraintSpace FlexLayoutAlgorithm::BuildSpaceForIntrinsicInlineSize(
const BlockNode& child) const { … }
ConstraintSpace FlexLayoutAlgorithm::BuildSpaceForIntrinsicBlockSize(
const BlockNode& flex_item,
std::optional<LayoutUnit> override_inline_size) const { … }
ConstraintSpace FlexLayoutAlgorithm::BuildSpaceForFlexBasis(
const BlockNode& flex_item) const { … }
ConstraintSpace FlexLayoutAlgorithm::BuildSpaceForLayout(
const BlockNode& flex_item_node,
LayoutUnit item_main_axis_final_size,
bool is_initial_block_size_indefinite,
std::optional<LayoutUnit> override_inline_size,
std::optional<LayoutUnit> line_cross_size_for_stretch,
std::optional<LayoutUnit> block_offset_for_fragmentation,
bool min_block_size_should_encompass_intrinsic_size) const { … }
void FlexLayoutAlgorithm::ConstructAndAppendFlexItems(
Phase phase,
HeapVector<Member<LayoutBox>>* oof_children) { … }
const LayoutResult* FlexLayoutAlgorithm::Layout() { … }
const LayoutResult*
FlexLayoutAlgorithm::RelayoutIgnoringChildScrollbarChanges() { … }
const LayoutResult* FlexLayoutAlgorithm::RelayoutAndBreakEarlierForFlex(
const LayoutResult* previous_result) { … }
const LayoutResult* FlexLayoutAlgorithm::LayoutInternal() { … }
void FlexLayoutAlgorithm::PlaceFlexItems(
HeapVector<NGFlexLine>* flex_line_outputs,
HeapVector<Member<LayoutBox>>* oof_children,
bool is_computing_multiline_column_intrinsic_size) { … }
void FlexLayoutAlgorithm::CalculateTotalIntrinsicBlockSize(
bool use_empty_line_block_size) { … }
void FlexLayoutAlgorithm::ApplyFinalAlignmentAndReversals(
HeapVector<NGFlexLine>* flex_line_outputs) { … }
LayoutResult::EStatus FlexLayoutAlgorithm::GiveItemsFinalPositionAndSize(
HeapVector<NGFlexLine>* flex_line_outputs,
Vector<EBreakBetween>* row_break_between_outputs) { … }
LayoutResult::EStatus
FlexLayoutAlgorithm::GiveItemsFinalPositionAndSizeForFragmentation(
HeapVector<NGFlexLine>* flex_line_outputs,
Vector<EBreakBetween>* row_break_between_outputs,
FlexBreakTokenData::FlexBreakBeforeRow* break_before_row) { … }
LayoutResult::EStatus FlexLayoutAlgorithm::PropagateFlexItemInfo(
FlexItem* flex_item,
wtf_size_t flex_line_idx,
LogicalOffset offset,
PhysicalSize fragment_size) { … }
MinMaxSizesResult
FlexLayoutAlgorithm::ComputeMinMaxSizeOfMultilineColumnContainer() { … }
MinMaxSizesResult FlexLayoutAlgorithm::ComputeMinMaxSizeOfRowContainerV3() { … }
MinMaxSizesResult FlexLayoutAlgorithm::ComputeMinMaxSizes(
const MinMaxSizesFloatInput&) { … }
LayoutUnit FlexLayoutAlgorithm::FragmentainerSpaceAvailable(
LayoutUnit block_offset) const { … }
void FlexLayoutAlgorithm::ConsumeRemainingFragmentainerSpace(
LayoutUnit offset_in_stitched_container,
NGFlexLine* flex_line,
const FlexColumnBreakInfo* column_break_info) { … }
BreakStatus FlexLayoutAlgorithm::BreakBeforeRowIfNeeded(
const NGFlexLine& row,
LayoutUnit row_block_offset,
EBreakBetween row_break_between,
wtf_size_t row_index,
LayoutInputNode child,
bool has_container_separation,
bool is_first_for_row) { … }
bool FlexLayoutAlgorithm::MovePastRowBreakPoint(
BreakAppeal appeal_before,
LayoutUnit fragmentainer_block_offset,
LayoutUnit row_block_size,
wtf_size_t row_index,
bool has_container_separation,
bool breakable_at_start_of_container) { … }
void FlexLayoutAlgorithm::AddColumnEarlyBreak(EarlyBreak* breakpoint,
wtf_size_t index) { … }
void FlexLayoutAlgorithm::AdjustOffsetForNextLine(
HeapVector<NGFlexLine>* flex_line_outputs,
wtf_size_t flex_line_idx,
LayoutUnit item_expansion) const { … }
const LayoutResult* FlexLayoutAlgorithm::RelayoutWithNewRowSizes() { … }
bool FlexLayoutAlgorithm::MinBlockSizeShouldEncompassIntrinsicSize(
const NGFlexItem& item) const { … }
#if DCHECK_IS_ON()
void FlexLayoutAlgorithm::CheckFlexLines(
HeapVector<NGFlexLine>& flex_line_outputs) const { … }
#endif
}