1/*
2 * Copyright (C) 2017 Igalia S.L.
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 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#include "config.h"
27#include "GridLayoutFunctions.h"
28
29#include "LengthFunctions.h"
30#include "RenderGrid.h"
31
32namespace WebCore {
33
34namespace GridLayoutFunctions {
35
36static inline bool marginStartIsAuto(const RenderBox& child, GridTrackSizingDirection direction)
37{
38 return direction == ForColumns ? child.style().marginStart().isAuto() : child.style().marginBefore().isAuto();
39}
40
41static inline bool marginEndIsAuto(const RenderBox& child, GridTrackSizingDirection direction)
42{
43 return direction == ForColumns ? child.style().marginEnd().isAuto() : child.style().marginAfter().isAuto();
44}
45
46static bool childHasMargin(const RenderBox& child, GridTrackSizingDirection direction)
47{
48 // Length::IsZero returns true for 'auto' margins, which is aligned with the purpose of this function.
49 if (direction == ForColumns)
50 return !child.style().marginStart().isZero() || !child.style().marginEnd().isZero();
51 return !child.style().marginBefore().isZero() || !child.style().marginAfter().isZero();
52}
53
54LayoutUnit computeMarginLogicalSizeForChild(const RenderGrid& grid, GridTrackSizingDirection direction, const RenderBox& child)
55{
56 if (!childHasMargin(child, flowAwareDirectionForChild(grid, child, direction)))
57 return 0;
58
59 LayoutUnit marginStart;
60 LayoutUnit marginEnd;
61 if (direction == ForColumns)
62 child.computeInlineDirectionMargins(grid, child.containingBlockLogicalWidthForContentInFragment(nullptr), child.logicalWidth(), marginStart, marginEnd);
63 else
64 child.computeBlockDirectionMargins(grid, marginStart, marginEnd);
65 return marginStartIsAuto(child, direction) ? marginEnd : marginEndIsAuto(child, direction) ? marginStart : marginStart + marginEnd;
66}
67
68LayoutUnit marginLogicalSizeForChild(const RenderGrid& grid, GridTrackSizingDirection direction, const RenderBox& child)
69{
70 if (child.needsLayout())
71 return computeMarginLogicalSizeForChild(grid, direction, child);
72 bool isRowAxis = flowAwareDirectionForChild(grid, child, direction) == ForColumns;
73 LayoutUnit marginStart = marginStartIsAuto(child, direction) ? 0_lu : isRowAxis ? child.marginStart() : child.marginBefore();
74 LayoutUnit marginEnd = marginEndIsAuto(child, direction) ? 0_lu : isRowAxis ? child.marginEnd() : child.marginAfter();
75 return marginStart + marginEnd;
76}
77
78bool isOrthogonalChild(const RenderGrid& grid, const RenderBox& child)
79{
80 return child.isHorizontalWritingMode() != grid.isHorizontalWritingMode();
81}
82
83GridTrackSizingDirection flowAwareDirectionForChild(const RenderGrid& grid, const RenderBox& child, GridTrackSizingDirection direction)
84{
85 return !isOrthogonalChild(grid, child) ? direction : (direction == ForColumns ? ForRows : ForColumns);
86}
87
88bool hasOverrideContainingBlockContentSizeForChild(const RenderBox& child, GridTrackSizingDirection direction)
89{
90 return direction == ForColumns ? child.hasOverrideContainingBlockContentLogicalWidth() : child.hasOverrideContainingBlockContentLogicalHeight();
91}
92
93Optional<LayoutUnit> overrideContainingBlockContentSizeForChild(const RenderBox& child, GridTrackSizingDirection direction)
94{
95 return direction == ForColumns ? child.overrideContainingBlockContentLogicalWidth() : child.overrideContainingBlockContentLogicalHeight();
96}
97
98} // namespace GridLayoutFunctions
99
100} // namespace WebCore
101