1 // Copyright 2016 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_OUT_OF_FLOW_LAYOUT_PART_H_ 6 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_OUT_OF_FLOW_LAYOUT_PART_H_ 7 8 #include "third_party/blink/renderer/core/core_export.h" 9 10 #include "base/optional.h" 11 #include "third_party/blink/renderer/core/layout/geometry/physical_offset.h" 12 #include "third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h" 13 #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h" 14 #include "third_party/blink/renderer/core/style/computed_style_base_constants.h" 15 #include "third_party/blink/renderer/platform/wtf/hash_map.h" 16 #include "third_party/blink/renderer/platform/wtf/hash_set.h" 17 18 namespace blink { 19 20 class ComputedStyle; 21 class LayoutBox; 22 class LayoutObject; 23 class NGBlockBreakToken; 24 class NGBlockNode; 25 class NGBoxFragmentBuilder; 26 class NGLayoutResult; 27 class NGPhysicalContainerFragment; 28 struct NGLogicalOutOfFlowPositionedNode; 29 30 // Helper class for positioning of out-of-flow blocks. 31 // It should be used together with NGBoxFragmentBuilder. 32 // See NGBoxFragmentBuilder::AddOutOfFlowChildCandidate documentation 33 // for example of using these classes together. 34 class CORE_EXPORT NGOutOfFlowLayoutPart { 35 STACK_ALLOCATED(); 36 37 public: 38 NGOutOfFlowLayoutPart(const NGBlockNode& container_node, 39 const NGConstraintSpace& container_space, 40 NGBoxFragmentBuilder* container_builder); 41 42 // The |container_builder|, |container_space|, and |container_style| 43 // parameters are all with respect to the containing block of the relevant 44 // out-of-flow positioned descendants. If the CSS "containing block" of such 45 // an out-of-flow positioned descendant isn't a true block (e.g. a relatively 46 // positioned inline instead), the containing block here is the containing 47 // block of said non-block. 48 NGOutOfFlowLayoutPart( 49 bool is_absolute_container, 50 bool is_fixed_container, 51 const ComputedStyle& container_style, 52 const NGConstraintSpace& container_space, 53 NGBoxFragmentBuilder* container_builder, 54 base::Optional<LogicalSize> initial_containing_block_fixed_size = 55 base::nullopt); 56 57 // Normally this function lays out and positions all out-of-flow objects from 58 // the container_builder and additional ones it discovers through laying out 59 // those objects. However, if only_layout is specified, only that object will 60 // get laid out; any additional ones will be stored as out-of-flow 61 // descendants in the builder for use via 62 // LayoutResult::OutOfFlowPositionedDescendants. 63 void Run(const LayoutBox* only_layout = nullptr); 64 65 private: 66 // Information needed to position descendant within a containing block. 67 // Geometry expressed here is complicated: 68 // There are two types of containing blocks: 69 // 1) Default containing block (DCB) 70 // Containing block passed in NGOutOfFlowLayoutPart constructor. 71 // It is the block element inside which this algorighm runs. 72 // All OOF descendants not in inline containing block are placed in DCB. 73 // 2) Inline containing block 74 // OOF descendants might be positioned wrt inline containing block. 75 // Inline containing block is positioned wrt default containing block. 76 struct ContainingBlockInfo { 77 STACK_ALLOCATED(); 78 79 public: 80 // The writing direction of the container. 81 WritingDirectionMode writing_direction = {WritingMode::kHorizontalTb, 82 TextDirection::kLtr}; 83 // Logical in containing block coordinates. 84 LogicalSize content_size_for_absolute; 85 // Content size for fixed is different for the ICB. 86 LogicalSize content_size_for_fixed; 87 88 // Offset of the container's padding-box. 89 LogicalOffset container_offset; 90 ContentSizeContainingBlockInfo91 LogicalSize ContentSize(EPosition position) const { 92 return position == EPosition::kAbsolute ? content_size_for_absolute 93 : content_size_for_fixed; 94 } 95 }; 96 97 bool SweepLegacyCandidates(HashSet<const LayoutObject*>* placed_objects); 98 99 const ContainingBlockInfo& GetContainingBlockInfo( 100 const NGLogicalOutOfFlowPositionedNode&, 101 const NGPhysicalContainerFragment* = nullptr); 102 103 void ComputeInlineContainingBlocks( 104 const Vector<NGLogicalOutOfFlowPositionedNode>&); 105 106 void LayoutCandidates(Vector<NGLogicalOutOfFlowPositionedNode>* candidates, 107 const LayoutBox* only_layout, 108 HashSet<const LayoutObject*>* placed_objects); 109 110 scoped_refptr<const NGLayoutResult> LayoutCandidate( 111 const NGLogicalOutOfFlowPositionedNode&, 112 const LayoutBox* only_layout); 113 114 void LayoutFragmentainerDescendants( 115 Vector<NGLogicalOutOfFlowPositionedNode>* descendants); 116 117 void LayoutFragmentainerDescendant(const NGLogicalOutOfFlowPositionedNode&); 118 119 scoped_refptr<const NGLayoutResult> Layout( 120 NGBlockNode, 121 const NGConstraintSpace&, 122 const NGLogicalStaticPosition&, 123 PhysicalSize container_physical_content_size, 124 const ContainingBlockInfo&, 125 const WritingDirectionMode, 126 const LayoutBox* only_layout, 127 bool is_fragmentainer_descendant = false); 128 129 bool IsContainingBlockForCandidate(const NGLogicalOutOfFlowPositionedNode&); 130 131 scoped_refptr<const NGLayoutResult> GenerateFragment( 132 NGBlockNode node, 133 const LogicalSize& container_content_size_in_child_writing_mode, 134 const base::Optional<LayoutUnit>& block_estimate, 135 const NGLogicalOutOfFlowDimensions& node_dimensions, 136 const LayoutUnit block_offset, 137 const NGBlockBreakToken* break_token, 138 const NGConstraintSpace* fragmentainer_constraint_space); 139 void AddOOFResultsToFragmentainer( 140 const Vector<scoped_refptr<const NGLayoutResult>>& results, 141 wtf_size_t index); 142 const NGConstraintSpace& GetFragmentainerConstraintSpace(wtf_size_t index); 143 void AddOOFResultToFragmentainerResults( 144 const scoped_refptr<const NGLayoutResult> result, 145 wtf_size_t index); 146 void ComputeStartFragmentIndexAndRelativeOffset( 147 const ContainingBlockInfo& container_info, 148 WritingMode default_writing_mode, 149 wtf_size_t* start_index, 150 LogicalOffset* offset) const; 151 152 NGBoxFragmentBuilder* container_builder_; 153 ContainingBlockInfo default_containing_block_; 154 HashMap<const LayoutObject*, ContainingBlockInfo> containing_blocks_map_; 155 HashMap<wtf_size_t, NGConstraintSpace> fragmentainer_constraint_space_map_; 156 // Map of fragmentainer indexes to a list of descendant layout results to 157 // be added as children. 158 HashMap<wtf_size_t, Vector<scoped_refptr<const NGLayoutResult>>> 159 fragmentainer_descendant_results_; 160 const WritingMode writing_mode_; 161 LayoutUnit column_inline_progression_ = kIndefiniteSize; 162 // The block size of the multi-column (before adjustment for spanners, etc.) 163 // This is used to calculate the column size of any newly added proxy 164 // fragments when handling fragmentation for abspos elements. 165 LayoutUnit original_column_block_size_ = kIndefiniteSize; 166 bool is_absolute_container_; 167 bool is_fixed_container_; 168 bool allow_first_tier_oof_cache_; 169 bool has_block_fragmentation_; 170 }; 171 172 } // namespace blink 173 174 #endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_OUT_OF_FLOW_LAYOUT_PART_H_ 175