1 /* 2 * Copyright (C) 2011 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_GRID_H_ 27 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_GRID_H_ 28 29 #include <memory> 30 #include "third_party/blink/renderer/core/layout/grid.h" 31 #include "third_party/blink/renderer/core/layout/grid_layout_utils.h" 32 #include "third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h" 33 #include "third_party/blink/renderer/core/layout/layout_block.h" 34 #include "third_party/blink/renderer/core/layout/order_iterator.h" 35 #include "third_party/blink/renderer/core/style/grid_positions_resolver.h" 36 37 namespace blink { 38 39 struct GridArea; 40 struct GridSpan; 41 42 struct ContentAlignmentData { 43 public: 44 ContentAlignmentData() = default; 45 ContentAlignmentData(const ContentAlignmentData&) = delete; 46 ContentAlignmentData& operator=(const ContentAlignmentData&) = delete; IsValidContentAlignmentData47 bool IsValid() { return position_offset >= 0 && distribution_offset >= 0; } 48 49 LayoutUnit position_offset = LayoutUnit(-1); 50 LayoutUnit distribution_offset = LayoutUnit(-1); 51 }; 52 53 enum GridAxisPosition { kGridAxisStart, kGridAxisEnd, kGridAxisCenter }; 54 55 class LayoutGrid final : public LayoutBlock { 56 public: 57 explicit LayoutGrid(Element*); 58 ~LayoutGrid() override; 59 60 static LayoutGrid* CreateAnonymous(Document*); GetName()61 const char* GetName() const override { 62 NOT_DESTROYED(); 63 return "LayoutGrid"; 64 } 65 66 void UpdateBlockLayout(bool relayout_children) override; 67 68 void DirtyGrid(); 69 70 Vector<LayoutUnit> TrackSizesForComputedStyle(GridTrackSizingDirection) const; 71 ColumnPositions()72 const Vector<LayoutUnit>& ColumnPositions() const { 73 NOT_DESTROYED(); 74 DCHECK(!grid_->NeedsItemsPlacement()); 75 return column_positions_; 76 } 77 RowPositions()78 const Vector<LayoutUnit>& RowPositions() const { 79 NOT_DESTROYED(); 80 DCHECK(!grid_->NeedsItemsPlacement()); 81 return row_positions_; 82 } 83 84 // TODO(svillar): rename this method as this does not return a 85 // GridCell but its contents. GetGridCell(int row,int column)86 const GridItemList& GetGridCell(int row, int column) const { 87 NOT_DESTROYED(); 88 SECURITY_DCHECK(!grid_->NeedsItemsPlacement()); 89 return grid_->Cell(row, column); 90 } 91 AutoRepeatCountForDirection(GridTrackSizingDirection direction)92 size_t AutoRepeatCountForDirection(GridTrackSizingDirection direction) const { 93 return grid_->AutoRepeatTracks(direction); 94 } 95 ExplicitGridStartForDirection(GridTrackSizingDirection direction)96 size_t ExplicitGridStartForDirection( 97 GridTrackSizingDirection direction) const { 98 return grid_->ExplicitGridStart(direction); 99 } 100 101 LayoutUnit TranslateRTLCoordinate(LayoutUnit) const; 102 103 LayoutUnit TranslateOutOfFlowRTLCoordinate(const LayoutBox&, 104 LayoutUnit) const; 105 106 // TODO(svillar): We need these for the GridTrackSizingAlgorithm. Let's figure 107 // it out how to remove this dependency. 108 LayoutUnit GuttersSize(const Grid&, 109 GridTrackSizingDirection, 110 size_t start_line, 111 size_t span, 112 base::Optional<LayoutUnit> available_size) const; 113 bool CachedHasDefiniteLogicalHeight() const; 114 bool IsBaselineAlignmentForChild(const LayoutBox& child) const; 115 bool IsBaselineAlignmentForChild(const LayoutBox& child, GridAxis) const; 116 117 StyleSelfAlignmentData SelfAlignmentForChild( 118 GridAxis, 119 const LayoutBox& child, 120 const ComputedStyle* = nullptr) const; 121 122 LayoutUnit GridGap(GridTrackSizingDirection) const; 123 LayoutUnit GridItemOffset(GridTrackSizingDirection) const; 124 125 void UpdateGridAreaLogicalSize(LayoutBox&, LayoutSize) const; 126 127 StyleContentAlignmentData ContentAlignment(GridTrackSizingDirection) const; 128 129 size_t ExplicitGridEndForDirection(GridTrackSizingDirection) const; 130 131 // Exposed for testing *ONLY*. InternalGrid()132 Grid* InternalGrid() const { 133 NOT_DESTROYED(); 134 return grid_.get(); 135 } 136 137 protected: 138 ItemPosition SelfAlignmentNormalBehavior( 139 const LayoutBox* child = nullptr) const override { 140 NOT_DESTROYED(); 141 DCHECK(child); 142 return child->IsLayoutReplaced() ? ItemPosition::kStart 143 : ItemPosition::kStretch; 144 } 145 146 private: IsOfType(LayoutObjectType type)147 bool IsOfType(LayoutObjectType type) const override { 148 NOT_DESTROYED(); 149 return type == kLayoutObjectGrid || LayoutBlock::IsOfType(type); 150 } 151 MinMaxSizes ComputeIntrinsicLogicalWidths() const override; 152 153 void AddChild(LayoutObject* new_child, 154 LayoutObject* before_child = nullptr) override; 155 void RemoveChild(LayoutObject*) override; 156 157 bool SelfAlignmentChangedSize(GridAxis, 158 const ComputedStyle& old_style, 159 const ComputedStyle& new_style, 160 const LayoutBox&) const; 161 bool DefaultAlignmentChangedSize(GridAxis, 162 const ComputedStyle& old_style, 163 const ComputedStyle& new_style) const; 164 void StyleDidChange(StyleDifference, const ComputedStyle*) override; 165 166 bool ExplicitGridDidResize(const ComputedStyle&) const; 167 bool NamedGridLinesDefinitionDidChange(const ComputedStyle&) const; 168 169 size_t ComputeAutoRepeatTracksCount( 170 GridTrackSizingDirection, 171 base::Optional<LayoutUnit> available_size) const; 172 size_t ClampAutoRepeatTracks(GridTrackSizingDirection, 173 size_t auto_repeat_tracks) const; 174 175 std::unique_ptr<OrderedTrackIndexSet> ComputeEmptyTracksForAutoRepeat( 176 Grid&, 177 GridTrackSizingDirection) const; 178 179 void PerformGridItemsPreLayout(const GridTrackSizingAlgorithm&) const; 180 181 void PlaceItemsOnGrid( 182 GridTrackSizingAlgorithm&, 183 base::Optional<LayoutUnit> available_logical_width) const; 184 void PopulateExplicitGridAndOrderIterator(Grid&) const; 185 std::unique_ptr<GridArea> CreateEmptyGridAreaAtSpecifiedPositionsOutsideGrid( 186 const Grid&, 187 const LayoutBox&, 188 GridTrackSizingDirection, 189 const GridSpan& specified_positions) const; 190 void PlaceSpecifiedMajorAxisItemsOnGrid(Grid&, 191 const Vector<LayoutBox*>&) const; 192 void PlaceAutoMajorAxisItemsOnGrid(Grid&, const Vector<LayoutBox*>&) const; 193 void PlaceAutoMajorAxisItemOnGrid( 194 Grid&, 195 LayoutBox&, 196 std::pair<size_t, size_t>& auto_placement_cursor) const; 197 GridTrackSizingDirection AutoPlacementMajorAxisDirection() const; 198 GridTrackSizingDirection AutoPlacementMinorAxisDirection() const; 199 200 base::Optional<LayoutUnit> OverrideIntrinsicContentLogicalSize( 201 GridTrackSizingDirection) const; 202 203 void ComputeTrackSizesForIndefiniteSize(GridTrackSizingAlgorithm&, 204 GridTrackSizingDirection) const; 205 void ComputeTrackSizesForDefiniteSize(GridTrackSizingDirection, 206 LayoutUnit free_space); 207 208 void RepeatTracksSizingIfNeeded(LayoutUnit available_space_for_columns, 209 LayoutUnit available_space_for_rows); 210 211 void LayoutGridItems(); 212 void PrepareChildForPositionedLayout(LayoutBox&); 213 bool HasStaticPositionForChild(const LayoutBox&, 214 GridTrackSizingDirection) const; 215 void LayoutPositionedObjects( 216 bool relayout_children, 217 PositionedLayoutBehavior = kDefaultLayout) override; 218 void PopulateGridPositionsForDirection(GridTrackSizingDirection); 219 220 LayoutUnit ResolveAutoStartGridPosition(GridTrackSizingDirection) const; 221 LayoutUnit ResolveAutoEndGridPosition(GridTrackSizingDirection) const; 222 LayoutUnit LogicalOffsetForOutOfFlowChild(const LayoutBox&, 223 GridTrackSizingDirection, 224 LayoutUnit) const; 225 LayoutUnit GridAreaBreadthForOutOfFlowChild(const LayoutBox&, 226 GridTrackSizingDirection); 227 void GridAreaPositionForOutOfFlowChild(const LayoutBox&, 228 GridTrackSizingDirection, 229 LayoutUnit& start, 230 LayoutUnit& end) const; 231 void GridAreaPositionForInFlowChild(const LayoutBox&, 232 GridTrackSizingDirection, 233 LayoutUnit& start, 234 LayoutUnit& end) const; 235 void GridAreaPositionForChild(const LayoutBox&, 236 GridTrackSizingDirection, 237 LayoutUnit& start, 238 LayoutUnit& end) const; 239 240 GridAxisPosition ColumnAxisPositionForChild(const LayoutBox&) const; 241 GridAxisPosition RowAxisPositionForChild(const LayoutBox&) const; 242 LayoutUnit RowAxisOffsetForChild(const LayoutBox&) const; 243 LayoutUnit ColumnAxisOffsetForChild(const LayoutBox&) const; 244 void ComputeContentPositionAndDistributionOffset( 245 GridTrackSizingDirection, 246 const LayoutUnit& available_free_space, 247 unsigned number_of_grid_tracks); 248 LayoutPoint GridAreaLogicalPosition(const GridArea&) const; 249 void SetLogicalPositionForChild(LayoutBox&) const; 250 void SetLogicalOffsetForChild(LayoutBox&, GridTrackSizingDirection) const; 251 LayoutUnit LogicalOffsetForChild(const LayoutBox&, 252 GridTrackSizingDirection) const; 253 254 LayoutUnit GridAreaBreadthForChildIncludingAlignmentOffsets( 255 const LayoutBox&, 256 GridTrackSizingDirection) const; 257 258 void PaintChildren(const PaintInfo&, 259 const PhysicalOffset& paint_offset) const override; 260 261 LayoutUnit AvailableAlignmentSpaceForChildBeforeStretching( 262 LayoutUnit grid_area_breadth_for_child, 263 const LayoutBox&) const; 264 StyleSelfAlignmentData JustifySelfForChild( 265 const LayoutBox&, 266 const ComputedStyle* = nullptr) const; 267 StyleSelfAlignmentData AlignSelfForChild( 268 const LayoutBox&, 269 const ComputedStyle* = nullptr) const; 270 StyleSelfAlignmentData DefaultAlignment(GridAxis, const ComputedStyle&) const; 271 bool DefaultAlignmentIsStretchOrNormal(GridAxis, const ComputedStyle&) const; 272 void ApplyStretchAlignmentToChildIfNeeded(LayoutBox&); 273 bool HasAutoSizeInColumnAxis(const LayoutBox& child) const; 274 bool HasAutoSizeInRowAxis(const LayoutBox& child) const; AllowedToStretchChildAlongColumnAxis(const LayoutBox & child)275 bool AllowedToStretchChildAlongColumnAxis(const LayoutBox& child) const { 276 NOT_DESTROYED(); 277 return AlignSelfForChild(child).GetPosition() == ItemPosition::kStretch && 278 HasAutoSizeInColumnAxis(child) && !HasAutoMarginsInColumnAxis(child); 279 } AllowedToStretchChildAlongRowAxis(const LayoutBox & child)280 bool AllowedToStretchChildAlongRowAxis(const LayoutBox& child) const { 281 NOT_DESTROYED(); 282 return JustifySelfForChild(child).GetPosition() == ItemPosition::kStretch && 283 HasAutoSizeInRowAxis(child) && !HasAutoMarginsInRowAxis(child); 284 } 285 bool HasAutoMarginsInColumnAxis(const LayoutBox&) const; 286 bool HasAutoMarginsInRowAxis(const LayoutBox&) const; 287 void UpdateAutoMarginsInColumnAxisIfNeeded(LayoutBox&); 288 void UpdateAutoMarginsInRowAxisIfNeeded(LayoutBox&); 289 290 LayoutUnit BaselinePosition( 291 FontBaseline, 292 bool first_line, 293 LineDirectionMode, 294 LinePositionMode = kPositionOnContainingLine) const override; 295 LayoutUnit FirstLineBoxBaseline() const override; 296 LayoutUnit InlineBlockBaseline(LineDirectionMode) const override; 297 298 LayoutUnit ColumnAxisBaselineOffsetForChild(const LayoutBox&) const; 299 LayoutUnit RowAxisBaselineOffsetForChild(const LayoutBox&) const; 300 301 LayoutUnit GridGap(GridTrackSizingDirection, 302 base::Optional<LayoutUnit> available_size) const; 303 304 size_t GridItemSpan(const LayoutBox&, GridTrackSizingDirection); 305 306 size_t NonCollapsedTracks(GridTrackSizingDirection) const; 307 size_t NumTracks(GridTrackSizingDirection, const Grid&) const; 308 309 static LayoutUnit OverrideContainingBlockContentSizeForChild( 310 const LayoutBox& child, 311 GridTrackSizingDirection); 312 static LayoutUnit SynthesizedBaselineFromBorderBox(const LayoutBox&, 313 LineDirectionMode); 314 static const StyleContentAlignmentData& ContentAlignmentNormalBehavior(); 315 316 std::unique_ptr<Grid> grid_; 317 GridTrackSizingAlgorithm track_sizing_algorithm_; 318 319 Vector<LayoutUnit> row_positions_; 320 Vector<LayoutUnit> column_positions_; 321 ContentAlignmentData offset_between_columns_; 322 ContentAlignmentData offset_between_rows_; 323 324 typedef HashMap<const LayoutBox*, base::Optional<size_t>> 325 OutOfFlowPositionsMap; 326 OutOfFlowPositionsMap column_of_positioned_item_; 327 OutOfFlowPositionsMap row_of_positioned_item_; 328 329 bool has_any_orthogonal_item_{false}; 330 bool baseline_items_cached_{false}; 331 base::Optional<bool> has_definite_logical_height_; 332 }; 333 334 DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutGrid, IsLayoutGrid()); 335 336 } // namespace blink 337 338 #endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_GRID_H_ 339