Commit f2e5768a authored by cbiesinger's avatar cbiesinger Committed by Commit bot

[layoutng] Allow testing NGBox without a LayoutObject

And use that to add a test for ng_block_layout_algorithm that tests layout
with children.

BUG=635619
R=eae@chromium.org,glebl@chromium.org,ikilpatrick@chromium.org

Review-Url: https://codereview.chromium.org/2291273002
Cr-Commit-Position: refs/heads/master@{#415762}
parent 5a1a9aae
......@@ -18,7 +18,9 @@ namespace blink {
NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm(
PassRefPtr<const ComputedStyle> style,
NGBox* first_child)
: style_(style), first_child_(first_child), state_(kStateInit) {}
: style_(style), first_child_(first_child), state_(kStateInit) {
DCHECK(style_);
}
bool NGBlockLayoutAlgorithm::Layout(const NGConstraintSpace* constraint_space,
NGPhysicalFragment** out) {
......
......@@ -35,5 +35,48 @@ TEST_F(NGBlockLayoutAlgorithmTest, FixedSize) {
EXPECT_EQ(frag->Height(), LayoutUnit(40));
}
// Verifies that two children are laid out with the correct size and position.
TEST_F(NGBlockLayoutAlgorithmTest, LayoutBlockChildren) {
const int kWidth = 30;
const int kHeight1 = 20;
const int kHeight2 = 30;
const int kMarginTop = 5;
const int kMarginBottom = 20;
style_->setWidth(Length(kWidth, Fixed));
NGConstraintSpace* space = new NGConstraintSpace(
HorizontalTopBottom, NGLogicalSize(LayoutUnit(100), NGSizeIndefinite));
RefPtr<ComputedStyle> first_style = ComputedStyle::create();
first_style->setHeight(Length(kHeight1, Fixed));
NGBox* first_child = new NGBox(first_style.get());
RefPtr<ComputedStyle> second_style = ComputedStyle::create();
second_style->setHeight(Length(kHeight2, Fixed));
second_style->setMarginTop(Length(kMarginTop, Fixed));
second_style->setMarginBottom(Length(kMarginBottom, Fixed));
NGBox* second_child = new NGBox(second_style.get());
first_child->SetNextSibling(second_child);
NGBlockLayoutAlgorithm algorithm(style_, first_child);
NGPhysicalFragment* frag;
while (!algorithm.Layout(space, &frag))
;
EXPECT_EQ(frag->Width(), LayoutUnit(kWidth));
EXPECT_EQ(frag->Height(),
LayoutUnit(kHeight1 + kHeight2 + kMarginTop + kMarginBottom));
EXPECT_EQ(frag->Type(), NGPhysicalFragmentBase::FragmentBox);
ASSERT_EQ(frag->Children().size(), 2UL);
const NGPhysicalFragmentBase* child = frag->Children()[0];
EXPECT_EQ(child->Height(), kHeight1);
EXPECT_EQ(child->TopOffset(), 0);
child = frag->Children()[1];
EXPECT_EQ(child->Height(), kHeight2);
EXPECT_EQ(child->TopOffset(), kHeight1 + kMarginTop);
}
} // namespace
} // namespace blink
......@@ -21,6 +21,10 @@ NGBox::NGBox(LayoutObject* layout_object)
DCHECK(layout_box_);
}
NGBox::NGBox(ComputedStyle* style) : style_(style) {
DCHECK(style_);
}
bool NGBox::Layout(const NGConstraintSpace* constraint_space,
NGFragment** out) {
// We can either use the new layout code to do the layout and then copy the
......@@ -38,20 +42,23 @@ bool NGBox::Layout(const NGConstraintSpace* constraint_space,
return false;
fragment_ = fragment;
layout_box_->setWidth(fragment_->Width());
layout_box_->setHeight(fragment_->Height());
if (layout_box_) {
layout_box_->setWidth(fragment_->Width());
layout_box_->setHeight(fragment_->Height());
// Ensure the position of the children are copied across to the
// LayoutObject tree.
for (NGBox* box = FirstChild(); box; box = box->NextSibling()) {
if (box->fragment_)
box->PositionUpdated();
}
// Ensure the position of the children are copied across to the
// LayoutObject tree.
for (NGBox* box = FirstChild(); box; box = box->NextSibling()) {
if (box->fragment_)
box->PositionUpdated();
}
if (layout_box_->isLayoutBlock())
toLayoutBlock(layout_box_)->layoutPositionedObjects(true);
layout_box_->clearNeedsLayout();
if (layout_box_->isLayoutBlock())
toLayoutBlock(layout_box_)->layoutPositionedObjects(true);
layout_box_->clearNeedsLayout();
}
} else {
DCHECK(layout_box_);
// TODO(layout-ng): If fixedSize is true, set the override width/height too
NGLogicalSize container_size = constraint_space->ContainerSize();
layout_box_->setOverrideContainingBlockContentLogicalWidth(
......@@ -82,23 +89,45 @@ bool NGBox::Layout(const NGConstraintSpace* constraint_space,
}
const ComputedStyle* NGBox::Style() const {
if (style_)
return style_.get();
DCHECK(layout_box_);
return layout_box_->style();
}
NGBox* NGBox::NextSibling() const {
if (style_)
return next_sibling_;
DCHECK(layout_box_);
LayoutObject* next_sibling = layout_box_->nextSibling();
return next_sibling ? new NGBox(next_sibling) : nullptr;
}
NGBox* NGBox::FirstChild() const {
if (style_)
return first_child_;
DCHECK(layout_box_);
LayoutObject* child = layout_box_->slowFirstChild();
return child ? new NGBox(child) : nullptr;
}
void NGBox::SetNextSibling(NGBox* sibling) {
DCHECK(!layout_box_);
DCHECK(style_);
next_sibling_ = sibling;
}
void NGBox::SetFirstChild(NGBox* child) {
DCHECK(!layout_box_);
DCHECK(style_);
first_child_ = child;
}
void NGBox::PositionUpdated() {
DCHECK(fragment_);
layout_box_->setX(fragment_->LeftOffset());
layout_box_->setY(fragment_->TopOffset());
if (layout_box_) {
layout_box_->setX(fragment_->LeftOffset());
layout_box_->setY(fragment_->TopOffset());
}
}
bool NGBox::CanUseNewLayout() {
......
......@@ -19,9 +19,10 @@ class NGFragment;
class NGPhysicalFragment;
// Represents a node to be laid out.
class CORE_EXPORT NGBox final : public GarbageCollected<NGBox> {
class CORE_EXPORT NGBox final : public GarbageCollectedFinalized<NGBox> {
public:
explicit NGBox(LayoutObject*);
explicit NGBox(ComputedStyle*);
// Returns true when done; when this function returns false, it has to be
// called again. The out parameter will only be set when this function
......@@ -35,9 +36,14 @@ class CORE_EXPORT NGBox final : public GarbageCollected<NGBox> {
NGBox* FirstChild() const;
void SetNextSibling(NGBox*);
void SetFirstChild(NGBox*);
DEFINE_INLINE_VIRTUAL_TRACE() {
visitor->trace(algorithm_);
visitor->trace(fragment_);
visitor->trace(next_sibling_);
visitor->trace(first_child_);
}
private:
......@@ -45,9 +51,15 @@ class CORE_EXPORT NGBox final : public GarbageCollected<NGBox> {
// positions us, it calls this function so we can store the position on the
// underlying LayoutBox.
void PositionUpdated();
bool CanUseNewLayout();
// We can either wrap a layout_box_ or a style_/next_sibling_/first_child_
// combination.
LayoutBox* layout_box_;
RefPtr<ComputedStyle> style_;
Member<NGBox> next_sibling_;
Member<NGBox> first_child_;
Member<NGBlockLayoutAlgorithm> algorithm_;
Member<NGPhysicalFragment> fragment_;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment