blob: 402f5bbe61530d2af4642b2a025f2e30ed162851 [file] [log] [blame]
// Copyright 2019 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 "third_party/blink/renderer/core/layout/ng/layout_box_utils.h"
#include "third_party/blink/renderer/core/layout/layout_block.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_static_position.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h"
namespace blink {
LayoutUnit LayoutBoxUtils::AvailableLogicalWidth(const LayoutBox& box,
const LayoutBlock* cb) {
auto writing_mode = box.StyleRef().GetWritingMode();
bool parallel_containing_block = IsParallelWritingMode(
cb ? cb->StyleRef().GetWritingMode() : writing_mode, writing_mode);
// Grid layout sets OverrideContainingBlockContentLogicalWidth|Height
if (parallel_containing_block &&
box.HasOverrideContainingBlockContentLogicalWidth()) {
return box.OverrideContainingBlockContentLogicalWidth()
.ClampNegativeToZero();
}
if (!parallel_containing_block &&
box.HasOverrideContainingBlockContentLogicalHeight()) {
return box.OverrideContainingBlockContentLogicalHeight()
.ClampNegativeToZero();
}
if (parallel_containing_block)
return box.ContainingBlockLogicalWidthForContent().ClampNegativeToZero();
return box.PerpendicularContainingBlockLogicalHeight().ClampNegativeToZero();
}
LayoutUnit LayoutBoxUtils::AvailableLogicalHeight(const LayoutBox& box,
const LayoutBlock* cb) {
auto writing_mode = box.StyleRef().GetWritingMode();
bool parallel_containing_block = IsParallelWritingMode(
cb ? cb->StyleRef().GetWritingMode() : writing_mode, writing_mode);
// Grid layout sets OverrideContainingBlockContentLogicalWidth|Height
if (parallel_containing_block &&
box.HasOverrideContainingBlockContentLogicalHeight())
return box.OverrideContainingBlockContentLogicalHeight();
if (!parallel_containing_block &&
box.HasOverrideContainingBlockContentLogicalWidth())
return box.OverrideContainingBlockContentLogicalWidth();
if (!box.Parent())
return box.View()->ViewLogicalHeightForPercentages();
DCHECK(cb);
if (parallel_containing_block)
return box.ContainingBlockLogicalHeightForPercentageResolution();
return box.ContainingBlockLogicalWidthForContent();
}
NGLogicalStaticPosition LayoutBoxUtils::ComputeStaticPositionFromLegacy(
const LayoutBox& box,
const NGBoxStrut& container_border_scrollbar,
const NGBoxFragmentBuilder* container_builder) {
const LayoutBoxModelObject* css_container =
ToLayoutBoxModelObject(box.Container());
const TextDirection parent_direction = box.Parent()->StyleRef().Direction();
// These two values represent the available-size for the OOF-positioned
// descandant, in the *descendant's* writing mode.
LayoutUnit containing_block_logical_width =
box.ContainingBlockLogicalWidthForPositioned(css_container);
LayoutUnit containing_block_logical_height =
box.ContainingBlockLogicalHeightForPositioned(css_container);
Length logical_left;
Length logical_right;
Length logical_top;
Length logical_bottom;
box.ComputeInlineStaticDistance(logical_left, logical_right, &box,
css_container, containing_block_logical_width,
container_builder);
box.ComputeBlockStaticDistance(logical_top, logical_bottom, &box,
css_container, container_builder);
// Determine the static-position.
LayoutUnit static_line;
LayoutUnit static_block;
if (IsLtr(parent_direction)) {
if (!logical_left.IsAuto()) {
static_line =
MinimumValueForLength(logical_left, containing_block_logical_width);
}
} else {
if (!logical_right.IsAuto()) {
static_line =
MinimumValueForLength(logical_right, containing_block_logical_width);
}
// |logical_right| is an adjustment from the right edge, to keep this
// relative to the line-left edge account for the
// |containing_block_logical_width|.
static_line = containing_block_logical_width - static_line;
}
if (!logical_top.IsAuto()) {
static_block =
MinimumValueForLength(logical_top, containing_block_logical_height);
}
NGLogicalStaticPosition logical_static_position{
{static_line, static_block},
IsLtr(parent_direction)
? NGLogicalStaticPosition::InlineEdge::kInlineStart
: NGLogicalStaticPosition::InlineEdge::kInlineEnd,
NGLogicalStaticPosition::BlockEdge::kBlockStart};
// Determine the physical available-size, remember that the available-size is
// currently in the *descendant's* writing-mode.
PhysicalSize container_size =
ToPhysicalSize(LogicalSize(containing_block_logical_width,
containing_block_logical_height),
box.StyleRef().GetWritingMode());
const LayoutBox* container = css_container->IsBox()
? ToLayoutBox(css_container)
: box.ContainingBlock();
const WritingMode container_writing_mode =
container->StyleRef().GetWritingMode();
const TextDirection container_direction = container->StyleRef().Direction();
// We perform a logical-physical-logical conversion to convert the
// static-position into the correct writing-mode, and direction combination.
//
// At the moment the static-position is in line-relative coordinates which is
// why we use |TextDirection::kLtr| for the first conversion.
logical_static_position =
logical_static_position
.ConvertToPhysical(container_writing_mode, TextDirection::kLtr,
container_size)
.ConvertToLogical(container_writing_mode, container_direction,
container_size);
// Finally we shift the static-position from being relative to the
// padding-box, to the border-box.
logical_static_position.offset +=
LogicalOffset{container_border_scrollbar.inline_start,
container_border_scrollbar.block_start};
return logical_static_position;
}
bool LayoutBoxUtils::SkipContainingBlockForPercentHeightCalculation(
const LayoutBlock* cb) {
return LayoutBox::SkipContainingBlockForPercentHeightCalculation(cb);
}
} // namespace blink