blob: 16042e39c4308f26cddb1333724cb308e9376a36 [file] [log] [blame]
// Copyright 2017 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.
#include "core/layout/GridLayoutUtils.h"
#include "platform/LengthFunctions.h"
namespace blink {
static inline bool MarginStartIsAuto(const LayoutBox& child,
GridTrackSizingDirection direction) {
return direction == kForColumns ? child.StyleRef().MarginStart().IsAuto()
: child.StyleRef().MarginBefore().IsAuto();
}
static inline bool MarginEndIsAuto(const LayoutBox& child,
GridTrackSizingDirection direction) {
return direction == kForColumns ? child.StyleRef().MarginEnd().IsAuto()
: child.StyleRef().MarginAfter().IsAuto();
}
static bool ChildHasMargin(const LayoutBox& child,
GridTrackSizingDirection direction) {
// Length::IsZero returns true for 'auto' margins, which is aligned with the
// purpose of this function.
if (direction == kForColumns) {
return !child.StyleRef().MarginStart().IsZero() ||
!child.StyleRef().MarginEnd().IsZero();
}
return !child.StyleRef().MarginBefore().IsZero() ||
!child.StyleRef().MarginAfter().IsZero();
}
static LayoutUnit ComputeMarginLogicalSizeForChild(
const LayoutGrid& grid,
MarginDirection for_direction,
const LayoutBox& child) {
bool is_inline_direction = for_direction == kInlineDirection;
GridTrackSizingDirection direction =
is_inline_direction ? kForColumns : kForRows;
if (!ChildHasMargin(child, direction))
return LayoutUnit();
LayoutUnit margin_start;
LayoutUnit margin_end;
LayoutUnit logical_size =
is_inline_direction ? child.LogicalWidth() : child.LogicalHeight();
Length margin_start_length = is_inline_direction
? child.StyleRef().MarginStart()
: child.StyleRef().MarginBefore();
Length margin_end_length = is_inline_direction
? child.StyleRef().MarginEnd()
: child.StyleRef().MarginAfter();
child.ComputeMarginsForDirection(
for_direction, &grid, child.ContainingBlockLogicalWidthForContent(),
logical_size, margin_start, margin_end, margin_start_length,
margin_end_length);
return MarginStartIsAuto(child, direction)
? margin_end
: MarginEndIsAuto(child, direction) ? margin_start
: margin_start + margin_end;
}
LayoutUnit GridLayoutUtils::MarginLogicalWidthForChild(const LayoutGrid& grid,
const LayoutBox& child) {
if (child.NeedsLayout())
return ComputeMarginLogicalSizeForChild(grid, kInlineDirection, child);
LayoutUnit margin_start = child.StyleRef().MarginStart().IsAuto()
? LayoutUnit()
: child.MarginStart();
LayoutUnit margin_end =
child.StyleRef().MarginEnd().IsAuto() ? LayoutUnit() : child.MarginEnd();
return margin_start + margin_end;
}
LayoutUnit GridLayoutUtils::MarginLogicalHeightForChild(
const LayoutGrid& grid,
const LayoutBox& child) {
if (child.NeedsLayout())
return ComputeMarginLogicalSizeForChild(grid, kBlockDirection, child);
LayoutUnit margin_before = child.StyleRef().MarginBefore().IsAuto()
? LayoutUnit()
: child.MarginBefore();
LayoutUnit margin_after = child.StyleRef().MarginAfter().IsAuto()
? LayoutUnit()
: child.MarginAfter();
return margin_before + margin_after;
}
bool GridLayoutUtils::IsOrthogonalChild(const LayoutGrid& grid,
const LayoutBox& child) {
return child.IsHorizontalWritingMode() != grid.IsHorizontalWritingMode();
}
GridTrackSizingDirection GridLayoutUtils::FlowAwareDirectionForChild(
const LayoutGrid& grid,
const LayoutBox& child,
GridTrackSizingDirection direction) {
return !IsOrthogonalChild(grid, child)
? direction
: (direction == kForColumns ? kForRows : kForColumns);
}
bool GridLayoutUtils::HasOverrideContainingBlockContentSizeForChild(
const LayoutBox& child,
GridTrackSizingDirection direction) {
return direction == kForColumns
? child.HasOverrideContainingBlockLogicalWidth()
: child.HasOverrideContainingBlockLogicalHeight();
}
LayoutUnit GridLayoutUtils::OverrideContainingBlockContentSizeForChild(
const LayoutBox& child,
GridTrackSizingDirection direction) {
return direction == kForColumns
? child.OverrideContainingBlockContentLogicalWidth()
: child.OverrideContainingBlockContentLogicalHeight();
}
} // namespace blink