#include "third_party/blink/renderer/core/layout/block_layout_algorithm.h"
#include <algorithm>
#include <memory>
#include <optional>
#include <utility>
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/layout/block_child_iterator.h"
#include "third_party/blink/renderer/core/layout/block_layout_algorithm_utils.h"
#include "third_party/blink/renderer/core/layout/box_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/column_spanner_path.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/early_break.h"
#include "third_party/blink/renderer/core/layout/floats_utils.h"
#include "third_party/blink/renderer/core/layout/fragmentation_utils.h"
#include "third_party/blink/renderer/core/layout/inline/inline_cursor.h"
#include "third_party/blink/renderer/core/layout/inline/inline_node.h"
#include "third_party/blink/renderer/core/layout/inline/physical_line_box_fragment.h"
#include "third_party/blink/renderer/core/layout/inline/ruby_utils.h"
#include "third_party/blink/renderer/core/layout/layout_multi_column_flow_thread.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_result.h"
#include "third_party/blink/renderer/core/layout/legacy_layout_tree_walking.h"
#include "third_party/blink/renderer/core/layout/length_utils.h"
#include "third_party/blink/renderer/core/layout/list/unpositioned_list_marker.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/positioned_float.h"
#include "third_party/blink/renderer/core/layout/space_utils.h"
#include "third_party/blink/renderer/core/layout/table/table_layout_utils.h"
#include "third_party/blink/renderer/core/layout/unpositioned_float.h"
#include "third_party/blink/renderer/core/mathml/mathml_element.h"
#include "third_party/blink/renderer/core/mathml/mathml_table_cell_element.h"
#include "third_party/blink/renderer/core/mathml_names.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
namespace blink {
namespace {
bool HasLineEvenIfEmpty(LayoutBox* box) { … }
inline bool IsLastInflowChild(const LayoutBox& box) { … }
inline const LayoutResult* LayoutBlockChild(
const ConstraintSpace& space,
const BreakToken* break_token,
const EarlyBreak* early_break,
const ColumnSpannerPath* column_spanner_path,
BlockNode* node) { … }
inline const LayoutResult* LayoutInflow(
const ConstraintSpace& space,
const BreakToken* break_token,
const EarlyBreak* early_break,
const ColumnSpannerPath* column_spanner_path,
LayoutInputNode* node,
InlineChildLayoutContext* context) { … }
AdjoiningObjectTypes ToAdjoiningObjectTypes(EClear clear) { … }
inline bool HasClearancePastAdjoiningFloats(
AdjoiningObjectTypes adjoining_object_types,
const ComputedStyle& child_style,
const ComputedStyle& cb_style) { … }
bool ApplyClearance(const ConstraintSpace& constraint_space,
LayoutUnit* bfc_block_offset) { … }
LayoutUnit LogicalFromBfcLineOffset(LayoutUnit child_bfc_line_offset,
LayoutUnit parent_bfc_line_offset,
LayoutUnit child_inline_size,
LayoutUnit parent_inline_size,
TextDirection direction) { … }
LogicalOffset LogicalFromBfcOffsets(const BfcOffset& child_bfc_offset,
const BfcOffset& parent_bfc_offset,
LayoutUnit child_inline_size,
LayoutUnit parent_inline_size,
TextDirection direction) { … }
ItemPosition WebkitTextToItemPosition(ETextAlign text_align) { … }
template <typename ChildInlineSizeFunc>
LayoutUnit WebkitTextAlignAndJustifySelfOffset(
const ComputedStyle& child_style,
const ComputedStyle& style,
LayoutUnit available_space,
const BoxStrut& margins,
const ChildInlineSizeFunc& child_inline_size_func) { … }
}
BlockLayoutAlgorithm::BlockLayoutAlgorithm(const LayoutAlgorithmParams& params)
: … { … }
BlockLayoutAlgorithm::~BlockLayoutAlgorithm() = default;
void BlockLayoutAlgorithm::SetBoxType(PhysicalFragment::BoxType type) { … }
MinMaxSizesResult BlockLayoutAlgorithm::ComputeMinMaxSizes(
const MinMaxSizesFloatInput& float_input) { … }
LogicalOffset BlockLayoutAlgorithm::CalculateLogicalOffset(
const LogicalFragment& fragment,
LayoutUnit child_bfc_line_offset,
const std::optional<LayoutUnit>& child_bfc_block_offset) { … }
const LayoutResult* BlockLayoutAlgorithm::Layout() { … }
NOINLINE const LayoutResult*
BlockLayoutAlgorithm::HandleNonsuccessfulLayoutResult(
const LayoutResult* result) { … }
const LayoutResult* BlockLayoutAlgorithm::LayoutInlineChild(
const InlineNode& node) { … }
NOINLINE const LayoutResult*
BlockLayoutAlgorithm::LayoutWithSimpleInlineChildLayoutContext(
const InlineNode& child) { … }
template <wtf_size_t capacity>
NOINLINE const LayoutResult*
BlockLayoutAlgorithm::LayoutWithOptimalInlineChildLayoutContext(
const InlineNode& child) { … }
NOINLINE const LayoutResult* BlockLayoutAlgorithm::RelayoutIgnoringLineClamp() { … }
NOINLINE const LayoutResult*
BlockLayoutAlgorithm::RelayoutWithLineClampBlockSize() { … }
NOINLINE const LayoutResult* BlockLayoutAlgorithm::RelayoutForTextBoxTrimEnd() { … }
inline const LayoutResult* BlockLayoutAlgorithm::Layout(
InlineChildLayoutContext* inline_child_layout_context) { … }
const LayoutResult* BlockLayoutAlgorithm::FinishLayout(
PreviousInflowPosition* previous_inflow_position,
InlineChildLayoutContext* inline_child_layout_context) { … }
bool BlockLayoutAlgorithm::TryReuseFragmentsFromCache(
InlineNode inline_node,
PreviousInflowPosition* previous_inflow_position,
const InlineBreakToken** inline_break_token_out) { … }
void BlockLayoutAlgorithm::HandleOutOfFlowPositioned(
const PreviousInflowPosition& previous_inflow_position,
BlockNode child) { … }
void BlockLayoutAlgorithm::HandleFloat(
const PreviousInflowPosition& previous_inflow_position,
BlockNode child,
const BlockBreakToken* child_break_token) { … }
LayoutResult::EStatus BlockLayoutAlgorithm::HandleNewFormattingContext(
LayoutInputNode child,
const BlockBreakToken* child_break_token,
PreviousInflowPosition* previous_inflow_position) { … }
const LayoutResult* BlockLayoutAlgorithm::LayoutNewFormattingContext(
LayoutInputNode child,
const BlockBreakToken* child_break_token,
const InflowChildData& child_data,
BfcOffset origin_offset,
bool abort_if_cleared,
BfcOffset* out_child_bfc_offset,
BoxStrut* out_resolved_margins) { … }
LayoutResult::EStatus BlockLayoutAlgorithm::HandleInflow(
LayoutInputNode child,
const BreakToken* child_break_token,
PreviousInflowPosition* previous_inflow_position,
InlineChildLayoutContext* inline_child_layout_context,
const InlineBreakToken** previous_inline_break_token) { … }
LayoutResult::EStatus BlockLayoutAlgorithm::FinishInflow(
LayoutInputNode child,
const BreakToken* child_break_token,
const ConstraintSpace& child_space,
bool has_clearance_past_adjoining_floats,
const LayoutResult* layout_result,
InflowChildData* child_data,
PreviousInflowPosition* previous_inflow_position,
InlineChildLayoutContext* inline_child_layout_context,
const InlineBreakToken** previous_inline_break_token) { … }
InflowChildData BlockLayoutAlgorithm::ComputeChildData(
const PreviousInflowPosition& previous_inflow_position,
LayoutInputNode child,
const BreakToken* child_break_token,
bool is_new_fc) { … }
PreviousInflowPosition BlockLayoutAlgorithm::ComputeInflowPosition(
const PreviousInflowPosition& previous_inflow_position,
const LayoutInputNode child,
const InflowChildData& child_data,
const std::optional<LayoutUnit>& child_bfc_block_offset,
const LogicalOffset& logical_offset,
const LayoutResult& layout_result,
const LogicalFragment& fragment,
bool self_collapsing_child_had_clearance) { … }
LayoutUnit BlockLayoutAlgorithm::PositionSelfCollapsingChildWithParentBfc(
const LayoutInputNode& child,
const ConstraintSpace& child_space,
const InflowChildData& child_data,
const LayoutResult& layout_result) const { … }
void BlockLayoutAlgorithm::ConsumeRemainingFragmentainerSpace(
PreviousInflowPosition* previous_inflow_position) { … }
BreakStatus BlockLayoutAlgorithm::FinalizeForFragmentation() { … }
BreakStatus BlockLayoutAlgorithm::BreakBeforeChildIfNeeded(
LayoutInputNode child,
const LayoutResult& layout_result,
PreviousInflowPosition* previous_inflow_position,
LayoutUnit bfc_block_offset,
bool has_container_separation) { … }
void BlockLayoutAlgorithm::UpdateEarlyBreakBetweenLines() { … }
BoxStrut BlockLayoutAlgorithm::CalculateMargins(
LayoutInputNode child,
bool is_new_fc,
LayoutUnit* additional_line_offset) { … }
ConstraintSpace BlockLayoutAlgorithm::CreateConstraintSpaceForChild(
const LayoutInputNode child,
const BreakToken* child_break_token,
const InflowChildData& child_data,
const LogicalSize child_available_size,
bool is_new_fc,
const std::optional<LayoutUnit> child_bfc_block_offset,
bool has_clearance_past_adjoining_floats,
LayoutUnit block_start_annotation_space) { … }
void BlockLayoutAlgorithm::PropagateBaselineFromLineBox(
const PhysicalFragment& child,
LayoutUnit block_offset) { … }
void BlockLayoutAlgorithm::PropagateBaselineFromBlockChild(
const PhysicalFragment& child,
const BoxStrut& margins,
LayoutUnit block_offset) { … }
bool BlockLayoutAlgorithm::ResolveBfcBlockOffset(
PreviousInflowPosition* previous_inflow_position,
LayoutUnit bfc_block_offset,
std::optional<LayoutUnit> forced_bfc_block_offset) { … }
bool BlockLayoutAlgorithm::NeedsAbortOnBfcBlockOffsetChange() const { … }
std::optional<LayoutUnit>
BlockLayoutAlgorithm::CalculateQuirkyBodyMarginBlockSum(
const MarginStrut& end_margin_strut) { … }
bool BlockLayoutAlgorithm::PositionOrPropagateListMarker(
const LayoutResult& layout_result,
LogicalOffset* content_offset,
PreviousInflowPosition* previous_inflow_position) { … }
bool BlockLayoutAlgorithm::PositionListMarkerWithoutLineBoxes(
PreviousInflowPosition* previous_inflow_position) { … }
bool BlockLayoutAlgorithm::IsRubyText(const LayoutInputNode& child) const { … }
void BlockLayoutAlgorithm::HandleRubyText(BlockNode ruby_text_child) { … }
LayoutUnit BlockLayoutAlgorithm::HandleTextControlPlaceholder(
BlockNode placeholder,
const PreviousInflowPosition& previous_inflow_position) { … }
LayoutUnit BlockLayoutAlgorithm::FinishTextControlPlaceholder(
const LayoutResult* result,
const LogicalOffset& offset,
bool apply_fixed_size,
const PreviousInflowPosition& previous_inflow_position) { … }
LogicalOffset BlockLayoutAlgorithm::AdjustSliderThumbInlineOffset(
const LogicalFragment& fragment,
const LogicalOffset& logical_offset) { … }
}