| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_OUT_OF_FLOW_LAYOUT_PART_H_ |
| #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_OUT_OF_FLOW_LAYOUT_PART_H_ |
| |
| #include "third_party/blink/renderer/core/core_export.h" |
| |
| #include "base/optional.h" |
| #include "third_party/blink/renderer/core/layout/geometry/logical_rect.h" |
| #include "third_party/blink/renderer/core/layout/geometry/physical_offset.h" |
| #include "third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h" |
| #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h" |
| #include "third_party/blink/renderer/core/style/computed_style_base_constants.h" |
| #include "third_party/blink/renderer/platform/wtf/hash_map.h" |
| #include "third_party/blink/renderer/platform/wtf/hash_set.h" |
| |
| namespace blink { |
| |
| class ComputedStyle; |
| class LayoutBox; |
| class LayoutObject; |
| class NGBlockBreakToken; |
| class NGBlockNode; |
| class NGBoxFragmentBuilder; |
| class NGLayoutResult; |
| class NGPhysicalContainerFragment; |
| struct NGLink; |
| struct NGLogicalOutOfFlowPositionedNode; |
| |
| // Helper class for positioning of out-of-flow blocks. |
| // It should be used together with NGBoxFragmentBuilder. |
| // See NGBoxFragmentBuilder::AddOutOfFlowChildCandidate documentation |
| // for example of using these classes together. |
| class CORE_EXPORT NGOutOfFlowLayoutPart { |
| STACK_ALLOCATED(); |
| |
| public: |
| NGOutOfFlowLayoutPart(const NGBlockNode& container_node, |
| const NGConstraintSpace& container_space, |
| NGBoxFragmentBuilder* container_builder); |
| |
| // The |container_builder|, |container_space|, and |container_style| |
| // parameters are all with respect to the containing block of the relevant |
| // out-of-flow positioned descendants. If the CSS "containing block" of such |
| // an out-of-flow positioned descendant isn't a true block (e.g. a relatively |
| // positioned inline instead), the containing block here is the containing |
| // block of said non-block. |
| NGOutOfFlowLayoutPart( |
| bool is_absolute_container, |
| bool is_fixed_container, |
| const ComputedStyle& container_style, |
| const NGConstraintSpace& container_space, |
| NGBoxFragmentBuilder* container_builder, |
| base::Optional<LogicalSize> initial_containing_block_fixed_size = |
| base::nullopt); |
| |
| // Normally this function lays out and positions all out-of-flow objects from |
| // the container_builder and additional ones it discovers through laying out |
| // those objects. However, if only_layout is specified, only that object will |
| // get laid out; any additional ones will be stored as out-of-flow |
| // descendants in the builder for use via |
| // LayoutResult::OutOfFlowPositionedDescendants. |
| void Run(const LayoutBox* only_layout = nullptr); |
| |
| private: |
| // Information needed to position descendant within a containing block. |
| // Geometry expressed here is complicated: |
| // There are two types of containing blocks: |
| // 1) Default containing block (DCB) |
| // Containing block passed in NGOutOfFlowLayoutPart constructor. |
| // It is the block element inside which this algorighm runs. |
| // All OOF descendants not in inline containing block are placed in DCB. |
| // 2) Inline containing block |
| // OOF descendants might be positioned wrt inline containing block. |
| // Inline containing block is positioned wrt default containing block. |
| struct ContainingBlockInfo { |
| STACK_ALLOCATED(); |
| |
| public: |
| // The writing direction of the container. |
| WritingDirectionMode writing_direction = {WritingMode::kHorizontalTb, |
| TextDirection::kLtr}; |
| // Size and offset of the container. |
| LogicalRect rect; |
| }; |
| |
| // TODO(almaher): Move this to the multicol algorithm in upcoming refactor. |
| // This stores the information needed to update a multicol child inside an |
| // existing multicol fragment. This is used during nested fragmentation of an |
| // OOF positioned element. |
| struct MulticolChildInfo { |
| // The mutable link of a multicol child. |
| NGLink* mutable_link; |
| |
| // The multicol break token that stores a reference to |mutable_link|'s |
| // break token in its list of child break tokens. |
| const NGBlockBreakToken* parent_break_token; |
| |
| explicit MulticolChildInfo(NGLink* mutable_link, |
| NGBlockBreakToken* parent_break_token = nullptr) |
| : mutable_link(mutable_link), parent_break_token(parent_break_token) {} |
| }; |
| |
| bool SweepLegacyCandidates(HashSet<const LayoutObject*>* placed_objects); |
| |
| const ContainingBlockInfo GetContainingBlockInfo( |
| const NGLogicalOutOfFlowPositionedNode&, |
| const NGPhysicalContainerFragment* = nullptr); |
| |
| void ComputeInlineContainingBlocks( |
| const Vector<NGLogicalOutOfFlowPositionedNode>&); |
| |
| void LayoutCandidates(Vector<NGLogicalOutOfFlowPositionedNode>* candidates, |
| const LayoutBox* only_layout, |
| HashSet<const LayoutObject*>* placed_objects); |
| |
| scoped_refptr<const NGLayoutResult> LayoutCandidate( |
| const NGLogicalOutOfFlowPositionedNode&, |
| const LayoutBox* only_layout); |
| |
| void LayoutOOFsInMulticol(const NGBlockNode& multicol); |
| |
| // Layout the OOF nodes that are descendants of a fragmentation context root. |
| // |multicol_children| holds the children of an inner multicol if |
| // we are laying out OOF elements inside a nested fragmentation context. |
| void LayoutFragmentainerDescendants( |
| Vector<NGLogicalOutOfFlowPositionedNode>* descendants, |
| LayoutUnit column_inline_progression, |
| Vector<MulticolChildInfo>* multicol_children = nullptr); |
| |
| scoped_refptr<const NGLayoutResult> LayoutFragmentainerDescendant( |
| const NGLogicalOutOfFlowPositionedNode&); |
| |
| scoped_refptr<const NGLayoutResult> Layout( |
| NGBlockNode, |
| const NGConstraintSpace&, |
| const NGLogicalStaticPosition&, |
| PhysicalSize container_physical_content_size, |
| const ContainingBlockInfo&, |
| const WritingDirectionMode, |
| const LayoutBox* only_layout, |
| bool is_fragmentainer_descendant = false); |
| |
| bool IsContainingBlockForCandidate(const NGLogicalOutOfFlowPositionedNode&); |
| |
| scoped_refptr<const NGLayoutResult> GenerateFragment( |
| NGBlockNode node, |
| const LogicalSize& container_content_size_in_child_writing_mode, |
| const base::Optional<LayoutUnit>& block_estimate, |
| const NGLogicalOutOfFlowDimensions& node_dimensions, |
| const LayoutUnit block_offset, |
| const NGBlockBreakToken* break_token, |
| const NGConstraintSpace* fragmentainer_constraint_space, |
| bool should_use_fixed_block_size); |
| void AddOOFResultsToFragmentainer( |
| const Vector<scoped_refptr<const NGLayoutResult>>& results, |
| wtf_size_t index, |
| LayoutUnit column_inline_progression, |
| Vector<MulticolChildInfo>* multicol_children = nullptr); |
| const NGConstraintSpace& GetFragmentainerConstraintSpace(wtf_size_t index); |
| void AddOOFResultToFragmentainerResults( |
| const scoped_refptr<const NGLayoutResult> result, |
| wtf_size_t index); |
| void ComputeStartFragmentIndexAndRelativeOffset( |
| const ContainingBlockInfo& container_info, |
| WritingMode default_writing_mode, |
| LayoutUnit block_estimate, |
| wtf_size_t* start_index, |
| LogicalOffset* offset) const; |
| |
| NGBoxFragmentBuilder* container_builder_; |
| ContainingBlockInfo default_containing_block_info_for_absolute_; |
| ContainingBlockInfo default_containing_block_info_for_fixed_; |
| HashMap<const LayoutObject*, ContainingBlockInfo> containing_blocks_map_; |
| HashMap<wtf_size_t, NGConstraintSpace> fragmentainer_constraint_space_map_; |
| // Map of fragmentainer indexes to a list of descendant layout results to |
| // be added as children. |
| HashMap<wtf_size_t, Vector<scoped_refptr<const NGLayoutResult>>> |
| fragmentainer_descendant_results_; |
| const WritingMode writing_mode_; |
| const WritingDirectionMode default_writing_direction_; |
| // The block size of the multi-column (before adjustment for spanners, etc.) |
| // This is used to calculate the column size of any newly added proxy |
| // fragments when handling fragmentation for abspos elements. |
| LayoutUnit original_column_block_size_ = kIndefiniteSize; |
| bool is_absolute_container_; |
| bool is_fixed_container_; |
| bool allow_first_tier_oof_cache_; |
| bool has_block_fragmentation_; |
| bool can_traverse_fragments_ = false; |
| bool nested_fragmentation_context_ = false; |
| }; |
| |
| } // namespace blink |
| |
| #endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_OUT_OF_FLOW_LAYOUT_PART_H_ |