1 // Copyright 2017 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 #include "third_party/blink/renderer/core/layout/grid_layout_utils.h"
6 
7 #include "third_party/blink/renderer/core/layout/layout_grid.h"
8 
9 namespace blink {
10 
MarginStartIsAuto(const LayoutBox & child,GridTrackSizingDirection direction)11 static inline bool MarginStartIsAuto(const LayoutBox& child,
12                                      GridTrackSizingDirection direction) {
13   return direction == kForColumns ? child.StyleRef().MarginStart().IsAuto()
14                                   : child.StyleRef().MarginBefore().IsAuto();
15 }
16 
MarginEndIsAuto(const LayoutBox & child,GridTrackSizingDirection direction)17 static inline bool MarginEndIsAuto(const LayoutBox& child,
18                                    GridTrackSizingDirection direction) {
19   return direction == kForColumns ? child.StyleRef().MarginEnd().IsAuto()
20                                   : child.StyleRef().MarginAfter().IsAuto();
21 }
22 
ChildHasMargin(const LayoutBox & child,GridTrackSizingDirection direction)23 static bool ChildHasMargin(const LayoutBox& child,
24                            GridTrackSizingDirection direction) {
25   // Length::IsZero returns true for 'auto' margins, which is aligned with the
26   // purpose of this function.
27   if (direction == kForColumns) {
28     return !child.StyleRef().MarginStart().IsZero() ||
29            !child.StyleRef().MarginEnd().IsZero();
30   }
31   return !child.StyleRef().MarginBefore().IsZero() ||
32          !child.StyleRef().MarginAfter().IsZero();
33 }
34 
ComputeMarginLogicalSizeForChild(const LayoutGrid & grid,MarginDirection for_direction,const LayoutBox & child)35 static LayoutUnit ComputeMarginLogicalSizeForChild(
36     const LayoutGrid& grid,
37     MarginDirection for_direction,
38     const LayoutBox& child) {
39   bool is_inline_direction = for_direction == kInlineDirection;
40   GridTrackSizingDirection direction =
41       is_inline_direction ? kForColumns : kForRows;
42   if (!ChildHasMargin(child, direction))
43     return LayoutUnit();
44 
45   LayoutUnit margin_start;
46   LayoutUnit margin_end;
47   LayoutUnit logical_size =
48       is_inline_direction ? child.LogicalWidth() : child.LogicalHeight();
49   const Length& margin_start_length = is_inline_direction
50                                           ? child.StyleRef().MarginStart()
51                                           : child.StyleRef().MarginBefore();
52   const Length& margin_end_length = is_inline_direction
53                                         ? child.StyleRef().MarginEnd()
54                                         : child.StyleRef().MarginAfter();
55   child.ComputeMarginsForDirection(
56       for_direction, &grid, child.ContainingBlockLogicalWidthForContent(),
57       logical_size, margin_start, margin_end, margin_start_length,
58       margin_end_length);
59 
60   return MarginStartIsAuto(child, direction)
61              ? margin_end
62              : MarginEndIsAuto(child, direction) ? margin_start
63                                                  : margin_start + margin_end;
64 }
65 
MarginLogicalWidthForChild(const LayoutGrid & grid,const LayoutBox & child)66 LayoutUnit GridLayoutUtils::MarginLogicalWidthForChild(const LayoutGrid& grid,
67                                                        const LayoutBox& child) {
68   if (child.NeedsLayout())
69     return ComputeMarginLogicalSizeForChild(grid, kInlineDirection, child);
70   // TODO(rego): Evaluate the possibility of using
71   // LayoutBlock::MarginIntrinsicLogicalWidthForChild() (note that this is
72   // protected so it cannot be directly used right now) or some similar method
73   // for this case.
74   LayoutUnit margin_start = child.StyleRef().MarginStart().IsAuto()
75                                 ? LayoutUnit()
76                                 : child.MarginStart();
77   LayoutUnit margin_end =
78       child.StyleRef().MarginEnd().IsAuto() ? LayoutUnit() : child.MarginEnd();
79   return margin_start + margin_end;
80 }
81 
MarginLogicalHeightForChild(const LayoutGrid & grid,const LayoutBox & child)82 LayoutUnit GridLayoutUtils::MarginLogicalHeightForChild(
83     const LayoutGrid& grid,
84     const LayoutBox& child) {
85   if (child.NeedsLayout())
86     return ComputeMarginLogicalSizeForChild(grid, kBlockDirection, child);
87   LayoutUnit margin_before = child.StyleRef().MarginBefore().IsAuto()
88                                  ? LayoutUnit()
89                                  : child.MarginBefore();
90   LayoutUnit margin_after = child.StyleRef().MarginAfter().IsAuto()
91                                 ? LayoutUnit()
92                                 : child.MarginAfter();
93   return margin_before + margin_after;
94 }
95 
IsOrthogonalChild(const LayoutGrid & grid,const LayoutBox & child)96 bool GridLayoutUtils::IsOrthogonalChild(const LayoutGrid& grid,
97                                         const LayoutBox& child) {
98   return child.IsHorizontalWritingMode() != grid.IsHorizontalWritingMode();
99 }
100 
FlowAwareDirectionForChild(const LayoutGrid & grid,const LayoutBox & child,GridTrackSizingDirection direction)101 GridTrackSizingDirection GridLayoutUtils::FlowAwareDirectionForChild(
102     const LayoutGrid& grid,
103     const LayoutBox& child,
104     GridTrackSizingDirection direction) {
105   return !IsOrthogonalChild(grid, child)
106              ? direction
107              : (direction == kForColumns ? kForRows : kForColumns);
108 }
109 
HasOverrideContainingBlockContentSizeForChild(const LayoutBox & child,GridTrackSizingDirection direction)110 bool GridLayoutUtils::HasOverrideContainingBlockContentSizeForChild(
111     const LayoutBox& child,
112     GridTrackSizingDirection direction) {
113   return direction == kForColumns
114              ? child.HasOverrideContainingBlockContentLogicalWidth()
115              : child.HasOverrideContainingBlockContentLogicalHeight();
116 }
117 
OverrideContainingBlockContentSizeForChild(const LayoutBox & child,GridTrackSizingDirection direction)118 LayoutUnit GridLayoutUtils::OverrideContainingBlockContentSizeForChild(
119     const LayoutBox& child,
120     GridTrackSizingDirection direction) {
121   return direction == kForColumns
122              ? child.OverrideContainingBlockContentLogicalWidth()
123              : child.OverrideContainingBlockContentLogicalHeight();
124 }
125 
126 }  // namespace blink
127