Commit 835274ca authored by cbiesinger's avatar cbiesinger Committed by Commit bot

[layoutng] Bidirectional interoperability between layoutng and legacy layout

Adds a function canUseNewLayout that determines whether to
use the new code, or fall back to the old layout()
implementation.

This mostly works for now. The main thing that still needs
to be done is to correctly pass down the constraints from
the constraint space. I am planning to use
setOverrideContainingBlockLogical{Width,Height} for that,
but I first have to fix it to not be grid-specific.

Complex constraint spaces will need more thought.

BUG=636993

Review-Url: https://codereview.chromium.org/2244463003
Cr-Commit-Position: refs/heads/master@{#412815}
parent 229561e7
...@@ -414,6 +414,10 @@ protected: ...@@ -414,6 +414,10 @@ protected:
// FIXME: This is temporary as we move code that accesses block flow // FIXME: This is temporary as we move code that accesses block flow
// member variables out of LayoutBlock and into LayoutBlockFlow. // member variables out of LayoutBlock and into LayoutBlockFlow.
friend class LayoutBlockFlow; friend class LayoutBlockFlow;
// This is necessary for now for interoperability between the old and new
// layout code. Primarily for calling layoutPositionedObjects at the moment.
friend class NGBox;
}; };
DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutBlock, isLayoutBlock()); DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutBlock, isLayoutBlock());
......
...@@ -29,6 +29,7 @@ NGFragment* NGBlockLayoutAlgorithm::layout( ...@@ -29,6 +29,7 @@ NGFragment* NGBlockLayoutAlgorithm::layout(
NGFragment* fragment = box.layout(constraintSpace); NGFragment* fragment = box.layout(constraintSpace);
// TODO(layout-ng): Take margins into account // TODO(layout-ng): Take margins into account
fragment->setOffset(LayoutUnit(), contentSize); fragment->setOffset(LayoutUnit(), contentSize);
box.positionUpdated(*fragment);
contentSize += fragment->blockSize(); contentSize += fragment->blockSize();
childFragments.append(fragment); childFragments.append(fragment);
} }
......
...@@ -5,19 +5,40 @@ ...@@ -5,19 +5,40 @@
#include "core/layout/ng/ng_box.h" #include "core/layout/ng/ng_box.h"
#include "core/layout/LayoutObject.h" #include "core/layout/LayoutObject.h"
#include "core/layout/ng/layout_ng_block_flow.h"
#include "core/layout/ng/ng_block_layout_algorithm.h" #include "core/layout/ng/ng_block_layout_algorithm.h"
#include "core/layout/ng/ng_box_iterator.h" #include "core/layout/ng/ng_box_iterator.h"
#include "core/layout/ng/ng_fragment.h" #include "core/layout/ng/ng_fragment.h"
#include "core/layout/LayoutBlockFlow.h"
#include "core/layout/LayoutBox.h" #include "core/layout/LayoutBox.h"
namespace blink { namespace blink {
NGFragment* NGBox::layout(const NGConstraintSpace& constraintSpace) { NGFragment* NGBox::layout(const NGConstraintSpace& constraintSpace) {
NGBlockLayoutAlgorithm algorithm(style(), childIterator()); // We can either use the new layout code to do the layout and then copy the
m_layoutBox->clearNeedsLayout(); // resulting size to the LayoutObject, or use the old layout code and
NGFragment* fragment = algorithm.layout(constraintSpace); // synthesize a fragment.
m_layoutBox->setLogicalWidth(fragment->inlineSize()); NGFragment* fragment = nullptr;
m_layoutBox->setLogicalHeight(fragment->blockSize()); if (canUseNewLayout()) {
NGBlockLayoutAlgorithm algorithm(style(), childIterator());
fragment = algorithm.layout(constraintSpace);
m_layoutBox->setLogicalWidth(fragment->inlineSize());
m_layoutBox->setLogicalHeight(fragment->blockSize());
if (m_layoutBox->isLayoutBlock())
toLayoutBlock(m_layoutBox)->layoutPositionedObjects(true);
m_layoutBox->clearNeedsLayout();
} else {
if (m_layoutBox->isLayoutNGBlockFlow() && m_layoutBox->needsLayout()) {
toLayoutNGBlockFlow(m_layoutBox)->LayoutBlockFlow::layoutBlock(true);
} else {
m_layoutBox->layoutIfNeeded();
}
LayoutRect overflow = m_layoutBox->layoutOverflowRect();
// This does not handle writing modes correctly (for overflow & the enums)
fragment = new NGFragment(
m_layoutBox->logicalWidth(), m_layoutBox->logicalHeight(),
overflow.width(), overflow.height(), HorizontalTopBottom, LeftToRight);
}
return fragment; return fragment;
} }
...@@ -36,4 +57,17 @@ NGBox NGBox::nextSibling() const { ...@@ -36,4 +57,17 @@ NGBox NGBox::nextSibling() const {
NGBox NGBox::firstChild() const { NGBox NGBox::firstChild() const {
return m_layoutBox ? NGBox(m_layoutBox->slowFirstChild()) : NGBox(); return m_layoutBox ? NGBox(m_layoutBox->slowFirstChild()) : NGBox();
} }
void NGBox::positionUpdated(const NGFragment& fragment) {
m_layoutBox->setLogicalLeft(fragment.inlineOffset());
m_layoutBox->setLogicalTop(fragment.blockOffset());
}
bool NGBox::canUseNewLayout() {
if (!m_layoutBox)
return true;
if (m_layoutBox->isLayoutBlockFlow() && !m_layoutBox->childrenInline())
return true;
return false;
}
} // namespace blink } // namespace blink
...@@ -36,7 +36,14 @@ class CORE_EXPORT NGBox final { ...@@ -36,7 +36,14 @@ class CORE_EXPORT NGBox final {
NGBox firstChild() const; NGBox firstChild() const;
// This is necessary for interop between old and new trees -- after our parent
// positions us, it calls this function so we can store the position on the
// underlying LayoutBox.
void positionUpdated(const NGFragment&);
private: private:
bool canUseNewLayout();
LayoutBox* m_layoutBox; LayoutBox* m_layoutBox;
}; };
......
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