Commit 6f165351 authored by ikilpatrick's avatar ikilpatrick Committed by Commit bot

[LayoutNG] Introduces NGPhysicalConstraintSpace and makes NGConstraintSpace a "view".

NGConstraintSpace now has a backing NGPhysicalConstaintSpace and
provides abstract coordinate system accessors for everything.

Makes NG*ConstraintSpace GarbagedCollected as well as we'll need
this once we move to a state machine / for caching fragment results.

BUG=635619

Review-Url: https://codereview.chromium.org/2267383003
Cr-Commit-Position: refs/heads/master@{#414745}
parent 64bae933
......@@ -553,7 +553,10 @@
'layout/ng/ng_box_iterator.h',
'layout/ng/ng_constraint_space.cc',
'layout/ng/ng_constraint_space.h',
'layout/ng/ng_derived_constraint_space.cc',
'layout/ng/ng_derived_constraint_space.h',
'layout/ng/ng_physical_constraint_space.cc',
'layout/ng/ng_physical_constraint_space.h',
'layout/ng/ng_fragment_base.cc',
'layout/ng/ng_fragment_base.h',
'layout/ng/ng_fragment_builder.cc',
......@@ -567,6 +570,8 @@
'layout/ng/ng_text_fragment.cc',
'layout/ng/ng_text_fragment.h',
'layout/ng/ng_units.h',
'layout/ng/ng_writing_mode.cc',
'layout/ng/ng_writing_mode.h',
'layout/BidiRun.h',
'layout/BidiRunForLine.cpp',
'layout/BidiRunForLine.h',
......@@ -4250,6 +4255,7 @@
'layout/VisualRectMappingTest.cpp',
'layout/compositing/CompositedLayerMappingTest.cpp',
'layout/ng/ng_block_layout_algorithm_test.cc',
'layout/ng/ng_constraint_space_test.cc',
'layout/ng/ng_length_utils_test.cc',
'layout/shapes/BoxShapeTest.cpp',
'layout/svg/LayoutSVGRootTest.cpp',
......
......@@ -3,7 +3,7 @@
// found in the LICENSE file.
#include "core/layout/ng/layout_ng_block_flow.h"
#include "core/layout/ng/ng_constraint_space.h"
#include "core/layout/ng/ng_derived_constraint_space.h"
#include "core/layout/ng/ng_block_layout_algorithm.h"
#include "core/layout/ng/ng_box_iterator.h"
#include "core/layout/ng/ng_fragment.h"
......@@ -21,7 +21,8 @@ bool LayoutNGBlockFlow::isOfType(LayoutObjectType type) const {
void LayoutNGBlockFlow::layoutBlock(bool relayoutChildren) {
LayoutAnalyzer::BlockScope analyzer(*this);
const auto& constraintSpace = NGConstraintSpace::fromLayoutObject(*this);
const auto* constraintSpace =
NGDerivedConstraintSpace::CreateFromLayoutObject(*this);
NGBox box(this);
box.layout(constraintSpace);
clearNeedsLayout();
......
......@@ -20,14 +20,14 @@ NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm(
: m_style(style), m_boxIterator(box_iterator) {}
NGFragment* NGBlockLayoutAlgorithm::layout(
const NGConstraintSpace& constraint_space) {
const NGConstraintSpace* constraint_space) {
LayoutUnit inline_size =
computeInlineSizeForFragment(constraint_space, *m_style);
computeInlineSizeForFragment(*constraint_space, *m_style);
// TODO(layout-ng): For quirks mode, should we pass blockSize instead of -1?
LayoutUnit block_size =
computeBlockSizeForFragment(constraint_space, *m_style, LayoutUnit(-1));
NGConstraintSpace constraint_space_for_children(
constraint_space, NGLogicalSize(inline_size, block_size));
computeBlockSizeForFragment(*constraint_space, *m_style, LayoutUnit(-1));
NGConstraintSpace* constraint_space_for_children = new NGConstraintSpace(
*constraint_space, NGLogicalSize(inline_size, block_size));
NGFragmentBuilder builder(NGFragmentBase::FragmentBox);
builder.SetInlineSize(inline_size).SetBlockSize(block_size);
......@@ -35,7 +35,7 @@ NGFragment* NGBlockLayoutAlgorithm::layout(
LayoutUnit content_size;
for (NGBox box : m_boxIterator) {
NGBoxStrut child_margins =
computeMargins(constraint_space_for_children, *box.style());
computeMargins(*constraint_space_for_children, *box.style());
NGFragment* fragment = box.layout(constraint_space_for_children);
// TODO(layout-ng): Support auto margins
fragment->SetOffset(child_margins.inline_start,
......@@ -47,7 +47,8 @@ NGFragment* NGBlockLayoutAlgorithm::layout(
// Recompute the block-axis size now that we know our content size.
block_size =
computeBlockSizeForFragment(constraint_space, *m_style, content_size);
computeBlockSizeForFragment(*constraint_space, *m_style, content_size);
// TODO(layout-ng): Compute correct inline overflow (block overflow should be
// correct)
builder.SetBlockSize(block_size)
......
......@@ -31,7 +31,7 @@ class CORE_EXPORT NGBlockLayoutAlgorithm : public NGLayoutAlgorithm {
// resulting layout information.
// This function can not be const because for interruptible layout, we have
// to be able to store state information.
NGFragment* layout(const NGConstraintSpace&) override;
NGFragment* layout(const NGConstraintSpace*) override;
private:
RefPtr<const ComputedStyle> m_style;
......
......@@ -25,10 +25,8 @@ TEST_F(NGBlockLayoutAlgorithmTest, FixedSize) {
style_->setWidth(Length(30, Fixed));
style_->setHeight(Length(40, Fixed));
NGLogicalSize container_size;
container_size.inline_size = LayoutUnit(100);
container_size.block_size = NGSizeIndefinite;
NGConstraintSpace space(container_size);
NGConstraintSpace* space = new NGConstraintSpace(
HorizontalTopBottom, NGLogicalSize(LayoutUnit(100), NGSizeIndefinite));
NGBlockLayoutAlgorithm algorithm(style_, NGBoxIterator(NGBox()));
NGFragment* frag = algorithm.layout(space);
......
......@@ -8,21 +8,28 @@
#include "core/layout/ng/layout_ng_block_flow.h"
#include "core/layout/ng/ng_block_layout_algorithm.h"
#include "core/layout/ng/ng_box_iterator.h"
#include "core/layout/ng/ng_constraint_space.h"
#include "core/layout/ng/ng_fragment.h"
#include "core/layout/ng/ng_fragment_builder.h"
#include "core/layout/ng/ng_writing_mode.h"
#include "core/layout/LayoutBlockFlow.h"
#include "core/layout/LayoutBox.h"
namespace blink {
NGFragment* NGBox::layout(const NGConstraintSpace& constraintSpace) {
NGFragment* NGBox::layout(const NGConstraintSpace* constraint_space) {
// We can either use the new layout code to do the layout and then copy the
// resulting size to the LayoutObject, or use the old layout code and
// synthesize a fragment.
NGFragment* fragment = nullptr;
if (canUseNewLayout()) {
NGBlockLayoutAlgorithm algorithm(style(), childIterator());
fragment = algorithm.layout(constraintSpace);
// Change the coordinate system of the constraint space.
NGConstraintSpace* child_constraint_space = new NGConstraintSpace(
FromPlatformWritingMode(style()->getWritingMode()), constraint_space);
fragment = algorithm.layout(child_constraint_space);
m_layoutBox->setLogicalWidth(fragment->InlineSize());
m_layoutBox->setLogicalHeight(fragment->BlockSize());
if (m_layoutBox->isLayoutBlock())
......@@ -30,11 +37,11 @@ NGFragment* NGBox::layout(const NGConstraintSpace& constraintSpace) {
m_layoutBox->clearNeedsLayout();
} else {
// TODO(layout-ng): If fixedSize is true, set the override width/height too
NGLogicalSize containerSize = constraintSpace.ContainerSize();
NGLogicalSize container_size = constraint_space->ContainerSize();
m_layoutBox->setOverrideContainingBlockContentLogicalWidth(
containerSize.inline_size);
container_size.inline_size);
m_layoutBox->setOverrideContainingBlockContentLogicalHeight(
containerSize.block_size);
container_size.block_size);
if (m_layoutBox->isLayoutNGBlockFlow() && m_layoutBox->needsLayout()) {
toLayoutNGBlockFlow(m_layoutBox)->LayoutBlockFlow::layoutBlock(true);
} else {
......
......@@ -29,7 +29,7 @@ class CORE_EXPORT NGBox final {
NGBoxIterator childIterator();
operator bool() const { return m_layoutBox; }
NGFragment* layout(const NGConstraintSpace&);
NGFragment* layout(const NGConstraintSpace*);
const ComputedStyle* style() const;
NGBox nextSibling() const;
......
......@@ -4,84 +4,116 @@
#include "core/layout/ng/ng_constraint_space.h"
#include "core/layout/LayoutBox.h"
#include "core/style/ComputedStyle.h"
#include "core/layout/ng/ng_units.h"
namespace blink {
NGConstraintSpace::NGConstraintSpace(NGLogicalSize container_size) {
container_size_ = container_size;
inline_triggers_scrollbar_ = 0;
block_triggers_scrollbar_ = 0;
fixed_inline_size_ = 0;
fixed_block_size_ = 0;
block_fragmentation_type_ = FragmentNone;
NGConstraintSpace::NGConstraintSpace(NGWritingMode writing_mode,
NGLogicalSize container_size)
: physical_space_(new NGPhysicalConstraintSpace()),
writing_mode_(writing_mode) {
SetContainerSize(container_size);
}
NGConstraintSpace::NGConstraintSpace(const NGConstraintSpace& other,
NGLogicalSize container_size)
: NGConstraintSpace(container_size) {
exclusions_ = other.exclusions_;
: physical_space_(new NGPhysicalConstraintSpace(*other.physical_space_)),
writing_mode_(other.writing_mode_) {
SetContainerSize(container_size);
}
NGConstraintSpace NGConstraintSpace::fromLayoutObject(const LayoutBox& child) {
bool fixedInline = false, fixedBlock = false;
// XXX for orthogonal writing mode this is not right
LayoutUnit container_logical_width =
std::max(LayoutUnit(), child.containingBlockLogicalWidthForContent());
// XXX Make sure this height is correct
LayoutUnit container_logical_height =
child.containingBlockLogicalHeightForContent(ExcludeMarginBorderPadding);
if (child.hasOverrideLogicalContentWidth()) {
container_logical_width = child.overrideLogicalContentWidth();
fixedInline = true;
}
if (child.hasOverrideLogicalContentHeight()) {
container_logical_width = child.overrideLogicalContentHeight();
fixedBlock = true;
}
NGLogicalSize size;
size.inline_size = container_logical_width;
size.block_size = container_logical_height;
NGConstraintSpace space(size);
space.setOverflowTriggersScrollbar(
child.styleRef().overflowInlineDirection() == OverflowAuto,
child.styleRef().overflowBlockDirection() == OverflowAuto);
space.setFixedSize(fixedInline, fixedBlock);
return space;
NGLogicalSize NGConstraintSpace::ContainerSize() const {
return writing_mode_ == HorizontalTopBottom
? NGLogicalSize(physical_space_->container_size_.width,
physical_space_->container_size_.height)
: NGLogicalSize(physical_space_->container_size_.height,
physical_space_->container_size_.width);
}
void NGConstraintSpace::addExclusion(const NGExclusion exclusion,
unsigned options) {}
bool NGConstraintSpace::InlineTriggersScrollbar() const {
return writing_mode_ == HorizontalTopBottom
? physical_space_->width_direction_triggers_scrollbar_
: physical_space_->height_direction_triggers_scrollbar_;
}
void NGConstraintSpace::setOverflowTriggersScrollbar(bool inline_triggers,
bool block_triggers) {
inline_triggers_scrollbar_ = inline_triggers;
block_triggers_scrollbar_ = block_triggers;
bool NGConstraintSpace::BlockTriggersScrollbar() const {
return writing_mode_ == HorizontalTopBottom
? physical_space_->height_direction_triggers_scrollbar_
: physical_space_->width_direction_triggers_scrollbar_;
}
void NGConstraintSpace::setFixedSize(bool inline_fixed, bool block_fixed) {
fixed_inline_size_ = inline_fixed;
fixed_block_size_ = block_fixed;
bool NGConstraintSpace::FixedInlineSize() const {
return writing_mode_ == HorizontalTopBottom ? physical_space_->fixed_width_
: physical_space_->fixed_height_;
}
void NGConstraintSpace::setFragmentationType(NGFragmentationType type) {
block_fragmentation_type_ = type;
bool NGConstraintSpace::FixedBlockSize() const {
return writing_mode_ == HorizontalTopBottom ? physical_space_->fixed_height_
: physical_space_->fixed_width_;
}
DoublyLinkedList<const NGExclusion> NGConstraintSpace::exclusions(
unsigned options) const {
DoublyLinkedList<const NGExclusion> exclusions;
// TODO(eae): Implement.
return exclusions;
NGFragmentationType NGConstraintSpace::BlockFragmentationType() const {
return static_cast<NGFragmentationType>(
writing_mode_ == HorizontalTopBottom
? physical_space_->height_direction_fragmentation_type_
: physical_space_->width_direction_fragmentation_type_);
}
NGLayoutOpportunityIterator NGConstraintSpace::layoutOpportunities(
void NGConstraintSpace::Subtract(const NGFragment*) {
// TODO(layout-ng): Implement.
}
NGLayoutOpportunityIterator NGConstraintSpace::LayoutOpportunities(
unsigned clear,
bool for_inline_or_bfc) const {
// TODO(eae): Implement.
bool for_inline_or_bfc) {
// TODO(layout-ng): Implement.
NGLayoutOpportunityIterator iterator(this, clear, for_inline_or_bfc);
return iterator;
}
void NGConstraintSpace::SetContainerSize(NGLogicalSize container_size) {
if (writing_mode_ == HorizontalTopBottom) {
physical_space_->container_size_.width = container_size.inline_size;
physical_space_->container_size_.height = container_size.block_size;
} else {
physical_space_->container_size_.width = container_size.block_size;
physical_space_->container_size_.height = container_size.inline_size;
}
}
void NGConstraintSpace::SetOverflowTriggersScrollbar(bool inline_triggers,
bool block_triggers) {
if (writing_mode_ == HorizontalTopBottom) {
physical_space_->width_direction_triggers_scrollbar_ = inline_triggers;
physical_space_->height_direction_triggers_scrollbar_ = block_triggers;
} else {
physical_space_->width_direction_triggers_scrollbar_ = block_triggers;
physical_space_->height_direction_triggers_scrollbar_ = inline_triggers;
}
}
void NGConstraintSpace::SetFixedSize(bool inline_fixed, bool block_fixed) {
if (writing_mode_ == HorizontalTopBottom) {
physical_space_->fixed_width_ = inline_fixed;
physical_space_->fixed_height_ = block_fixed;
} else {
physical_space_->fixed_width_ = block_fixed;
physical_space_->fixed_height_ = inline_fixed;
}
}
void NGConstraintSpace::SetFragmentationType(NGFragmentationType type) {
if (writing_mode_ == HorizontalTopBottom) {
DCHECK_EQ(static_cast<NGFragmentationType>(
physical_space_->width_direction_fragmentation_type_),
FragmentNone);
physical_space_->height_direction_fragmentation_type_ = type;
} else {
DCHECK_EQ(static_cast<NGFragmentationType>(
physical_space_->height_direction_fragmentation_type_),
FragmentNone);
physical_space_->width_direction_triggers_scrollbar_ = type;
}
}
} // namespace blink
......@@ -6,64 +6,35 @@
#define NGConstraintSpace_h
#include "core/CoreExport.h"
#include "core/layout/ng/ng_units.h"
#include "wtf/DoublyLinkedList.h"
#include "core/layout/ng/ng_physical_constraint_space.h"
#include "core/layout/ng/ng_writing_mode.h"
#include "platform/heap/Handle.h"
namespace blink {
class NGConstraintSpace;
class LayoutBox;
class NGDerivedConstraintSpace;
class NGExclusion;
class NGFragment;
class NGLayoutOpportunityIterator;
class LayoutBox;
enum NGExclusionType {
NGClearNone = 0,
NGClearFloatLeft = 1,
NGClearFloatRight = 2,
NGClearFragment = 4
};
enum NGFragmentationType {
FragmentNone,
FragmentPage,
FragmentColumn,
FragmentRegion
};
enum NGWritingMode {
HorizontalTopBottom = 0,
VerticalRightLeft = 1,
VerticalLeftRight = 2,
SidewaysRightLeft = 3,
SidewaysLeftRight = 4
};
enum NGDirection { LeftToRight = 0, RightToLeft = 1 };
class NGExclusion {
public:
NGExclusion();
~NGExclusion() {}
};
class CORE_EXPORT NGConstraintSpace {
// The NGConstraintSpace represents a set of constraints and available space
// which a layout algorithm may produce a NGFragment within. It is a view on
// top of a NGPhysicalConstraintSpace and provides accessor methods in the
// logical coordinate system defined by the writing mode given.
class CORE_EXPORT NGConstraintSpace
: public GarbageCollected<NGConstraintSpace> {
public:
NGConstraintSpace(NGLogicalSize container_size);
virtual ~NGConstraintSpace() {}
// Constructs a new constraint space based on an old one with a new size but
// the same exclusions.
NGConstraintSpace(const NGConstraintSpace&, NGLogicalSize container_size);
// Constructs a constraint space with a new backing NGPhysicalConstraintSpace.
NGConstraintSpace(NGWritingMode writing_mode, NGLogicalSize container_size);
// Constructs Layout NG constraint space from legacy layout object.
static NGConstraintSpace fromLayoutObject(const LayoutBox&);
// Constructs a constraint space with a different NGWritingMode.
NGConstraintSpace(NGWritingMode writing_mode,
const NGConstraintSpace* constraint_space)
: physical_space_(constraint_space->physical_space_),
writing_mode_(writing_mode) {}
void addExclusion(const NGExclusion, unsigned options = 0);
void setOverflowTriggersScrollbar(bool inlineTriggers, bool blockTriggers);
void setFixedSize(bool inlineFixed, bool blockFixed);
void setFragmentationType(NGFragmentationType);
NGConstraintSpace(const NGConstraintSpace& other,
NGLogicalSize container_size);
// Size of the container. Used for the following three cases:
// 1) Percentage resolution.
......@@ -71,7 +42,7 @@ class CORE_EXPORT NGConstraintSpace {
// 3) Defining the threashold that triggers the presence of a scrollbar. Only
// applies if the corresponding scrollbarTrigger flag has been set for the
// direction.
NGLogicalSize ContainerSize() const { return container_size_; }
NGLogicalSize ContainerSize() const;
// Returns the effective size of the constraint space. Defaults to
// ContainerSize() for the root constraint space but derived constraint spaces
......@@ -82,48 +53,47 @@ class CORE_EXPORT NGConstraintSpace {
// for the indicated direction.
// If exceeded the current layout should be aborted and invoked again with a
// constraint space modified to reserve space for a scrollbar.
bool inlineTriggersScrollbar() const { return inline_triggers_scrollbar_; }
bool blockTriggersScrollbar() const { return block_triggers_scrollbar_; }
bool InlineTriggersScrollbar() const;
bool BlockTriggersScrollbar() const;
// Some layout modes “stretch” their children to a fixed size (e.g. flex,
// grid). These flags represented whether a layout needs to produce a
// fragment that satisfies a fixed constraint in the inline and block
// direction respectively.
bool fixedInlineSize() const { return fixed_inline_size_; }
bool fixedBlockSize() const { return fixed_block_size_; }
bool FixedInlineSize() const;
bool FixedBlockSize() const;
// If specified a layout should produce a Fragment which fragments at the
// blockSize if possible.
NGFragmentationType blockFragmentationType() const {
return static_cast<NGFragmentationType>(block_fragmentation_type_);
}
DoublyLinkedList<const NGExclusion> exclusions(unsigned options = 0) const;
NGLayoutOpportunityIterator layoutOpportunities(
unsigned clear = NGClearNone,
bool for_inline_or_bfc = false) const;
NGFragmentationType BlockFragmentationType() const;
// Modifies constraint space to account for a placed fragment. Depending on
// the shape of the fragment this will either modify the inline or block
// size, or add an exclusion.
void subtract(const NGFragment);
void Subtract(const NGFragment*);
private:
NGLogicalSize container_size_;
NGLayoutOpportunityIterator LayoutOpportunities(
unsigned clear = NGClearNone,
bool for_inline_or_bfc = false);
unsigned fixed_inline_size_ : 1;
unsigned fixed_block_size_ : 1;
unsigned inline_triggers_scrollbar_ : 1;
unsigned block_triggers_scrollbar_ : 1;
unsigned block_fragmentation_type_ : 2;
DEFINE_INLINE_VIRTUAL_TRACE() { visitor->trace(physical_space_); }
DoublyLinkedList<const NGExclusion> exclusions_;
protected:
// The setters for the NGConstraintSpace should only be used when constructing
// via the NGDerivedConstraintSpace.
void SetContainerSize(NGLogicalSize);
void SetOverflowTriggersScrollbar(bool inlineTriggers, bool blockTriggers);
void SetFixedSize(bool inlineFixed, bool blockFixed);
void SetFragmentationType(NGFragmentationType);
private:
Member<NGPhysicalConstraintSpace> physical_space_;
unsigned writing_mode_ : 3;
};
class CORE_EXPORT NGLayoutOpportunityIterator final {
public:
NGLayoutOpportunityIterator(const NGConstraintSpace* space,
NGLayoutOpportunityIterator(NGConstraintSpace* space,
unsigned clear,
bool for_inline_or_bfc)
: constraint_space_(space),
......@@ -131,10 +101,10 @@ class CORE_EXPORT NGLayoutOpportunityIterator final {
for_inline_or_bfc_(for_inline_or_bfc) {}
~NGLayoutOpportunityIterator() {}
const NGDerivedConstraintSpace* next();
const NGDerivedConstraintSpace* Next();
private:
const NGConstraintSpace* constraint_space_;
Persistent<NGConstraintSpace> constraint_space_;
unsigned clear_;
bool for_inline_or_bfc_;
};
......
// Copyright 2016 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/ng/ng_constraint_space.h"
#include "core/layout/ng/ng_derived_constraint_space.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace blink {
namespace {
TEST(NGConstraintSpaceTest, WritingMode) {
NGConstraintSpace* horz_space = new NGDerivedConstraintSpace(
HorizontalTopBottom, NGLogicalSize(LayoutUnit(200), LayoutUnit(100)),
true, false, true, false, FragmentColumn);
NGConstraintSpace* vert_space =
new NGConstraintSpace(VerticalRightLeft, horz_space);
EXPECT_EQ(LayoutUnit(200), horz_space->ContainerSize().inline_size);
EXPECT_EQ(LayoutUnit(200), vert_space->ContainerSize().block_size);
EXPECT_EQ(LayoutUnit(100), horz_space->ContainerSize().block_size);
EXPECT_EQ(LayoutUnit(100), vert_space->ContainerSize().inline_size);
EXPECT_TRUE(horz_space->InlineTriggersScrollbar());
EXPECT_TRUE(vert_space->BlockTriggersScrollbar());
EXPECT_FALSE(horz_space->BlockTriggersScrollbar());
EXPECT_FALSE(vert_space->InlineTriggersScrollbar());
EXPECT_TRUE(horz_space->FixedInlineSize());
EXPECT_TRUE(vert_space->FixedBlockSize());
EXPECT_FALSE(horz_space->FixedBlockSize());
EXPECT_FALSE(vert_space->FixedInlineSize());
EXPECT_EQ(FragmentColumn, horz_space->BlockFragmentationType());
EXPECT_EQ(FragmentNone, vert_space->BlockFragmentationType());
}
} // namespace
} // namespace blink
// Copyright 2016 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/ng/ng_derived_constraint_space.h"
#include "core/layout/LayoutBox.h"
#include "core/style/ComputedStyle.h"
namespace blink {
NGDerivedConstraintSpace* NGDerivedConstraintSpace::CreateFromLayoutObject(
const LayoutBox& box) {
bool fixed_inline = false, fixed_block = false;
// XXX for orthogonal writing mode this is not right
LayoutUnit container_logical_width =
std::max(LayoutUnit(), box.containingBlockLogicalWidthForContent());
// XXX Make sure this height is correct
LayoutUnit container_logical_height =
box.containingBlockLogicalHeightForContent(ExcludeMarginBorderPadding);
if (box.hasOverrideLogicalContentWidth()) {
container_logical_width = box.overrideLogicalContentWidth();
fixed_inline = true;
}
if (box.hasOverrideLogicalContentHeight()) {
container_logical_width = box.overrideLogicalContentHeight();
fixed_block = true;
}
return new NGDerivedConstraintSpace(
FromPlatformWritingMode(box.styleRef().getWritingMode()),
NGLogicalSize(container_logical_width, container_logical_height),
box.styleRef().overflowInlineDirection() == OverflowAuto,
box.styleRef().overflowBlockDirection() == OverflowAuto, fixed_inline,
fixed_block, FragmentNone);
}
NGDerivedConstraintSpace::NGDerivedConstraintSpace(NGWritingMode writing_mode,
NGLogicalSize container_size,
bool inline_triggers,
bool block_triggers,
bool fixed_inline,
bool fixed_block,
NGFragmentationType type)
: NGConstraintSpace(writing_mode, container_size), direction_(LeftToRight) {
SetOverflowTriggersScrollbar(inline_triggers, block_triggers);
SetFixedSize(fixed_inline, fixed_block);
SetFragmentationType(type);
}
} // namespace blink
......@@ -15,27 +15,40 @@ namespace blink {
class CORE_EXPORT NGDerivedConstraintSpace final : public NGConstraintSpace {
public:
~NGDerivedConstraintSpace();
// Constructs a NGConstraintSpace from legacy layout object.
static NGDerivedConstraintSpace* CreateFromLayoutObject(const LayoutBox&);
NGDerivedConstraintSpace(NGWritingMode,
NGLogicalSize container_size,
bool inline_triggers,
bool block_triggers,
bool fixed_inline,
bool fixed_block,
NGFragmentationType);
NGLogicalOffset Offset() const { return offset_; }
NGLogicalSize Size() const override { return size_; }
NGDirection Direction() const { return direction_; }
// TODO(layout-ng): All exclusion operations on a NGDerivedConstraintSpace
// should be performed on it's parent if it exists. This is so that if a float
// is added by a child an arbitary sibling can avoid/clear that float.
// Alternatively the list of exclusions could be shared between constraint
// spaces.
DEFINE_INLINE_VIRTUAL_TRACE() {
visitor->trace(parent_);
NGConstraintSpace::trace(visitor);
}
private:
NGDerivedConstraintSpace(const NGConstraintSpace* original,
NGLogicalOffset offset,
NGLogicalSize size,
NGWritingMode writingMode,
NGDirection direction)
: original_(original),
offset_(offset),
size_(size),
writingMode_(writingMode),
direction_(direction) {}
const NGConstraintSpace* original_;
Member<NGConstraintSpace> parent_;
NGLogicalOffset offset_;
// TODO(layout-ng) move to NGPhysicalConstraintSpace?
NGLogicalSize size_;
NGWritingMode writingMode_;
// TODO(layout-ng) move to NGConstraintSpace?
NGDirection direction_;
};
......
......@@ -9,6 +9,7 @@
#include "core/layout/ng/ng_fragment_base.h"
#include "core/layout/ng/ng_constraint_space.h"
#include "core/layout/ng/ng_units.h"
#include "core/layout/ng/ng_writing_mode.h"
#include "platform/LayoutUnit.h"
#include "platform/heap/Handle.h"
#include "wtf/Vector.h"
......
......@@ -6,7 +6,8 @@
#define NGFragmentBase_h
#include "core/CoreExport.h"
#include "core/layout/ng/ng_constraint_space.h"
#include "core/layout/ng/ng_physical_constraint_space.h"
#include "core/layout/ng/ng_writing_mode.h"
#include "platform/LayoutUnit.h"
#include "platform/heap/Handle.h"
#include "wtf/Vector.h"
......
......@@ -27,7 +27,7 @@ class CORE_EXPORT NGLayoutAlgorithm {
// resulting layout information.
// This function can not be const because for interruptible layout, we have
// to be able to store state information.
virtual NGFragment* layout(const NGConstraintSpace&) = 0;
virtual NGFragment* layout(const NGConstraintSpace*) = 0;
};
} // namespace blink
......
......@@ -59,7 +59,7 @@ LayoutUnit resolveBlockLength(const NGConstraintSpace& constraintSpace,
LayoutUnit computeInlineSizeForFragment(
const NGConstraintSpace& constraintSpace,
const ComputedStyle& style) {
if (constraintSpace.fixedInlineSize())
if (constraintSpace.FixedInlineSize())
return constraintSpace.ContainerSize().inline_size;
LayoutUnit extent = resolveInlineLength(constraintSpace, style.logicalWidth(),
......@@ -86,7 +86,7 @@ LayoutUnit computeInlineSizeForFragment(
LayoutUnit computeBlockSizeForFragment(const NGConstraintSpace& constraintSpace,
const ComputedStyle& style,
LayoutUnit contentSize) {
if (constraintSpace.fixedBlockSize())
if (constraintSpace.FixedBlockSize())
return constraintSpace.ContainerSize().block_size;
LayoutUnit extent =
......
......@@ -5,6 +5,8 @@
#include "core/layout/ng/ng_length_utils.h"
#include "core/layout/ng/ng_constraint_space.h"
#include "core/layout/ng/ng_derived_constraint_space.h"
#include "core/layout/ng/ng_margin_strut.h"
#include "core/style/ComputedStyle.h"
#include "platform/CalculationValue.h"
#include "platform/LayoutUnit.h"
......@@ -19,41 +21,43 @@ class NGLengthUtilsTest : public ::testing::Test {
protected:
void SetUp() override { style_ = ComputedStyle::create(); }
static NGConstraintSpace constructConstraintSpace(int inline_size,
int block_size) {
NGLogicalSize container_size;
container_size.inline_size = LayoutUnit(inline_size);
container_size.block_size = LayoutUnit(block_size);
return NGConstraintSpace(container_size);
static NGConstraintSpace* ConstructConstraintSpace(int inline_size,
int block_size,
bool fixed_inline = false,
bool fixed_block = false) {
return new NGDerivedConstraintSpace(
HorizontalTopBottom,
NGLogicalSize(LayoutUnit(inline_size), LayoutUnit(block_size)), false,
false, fixed_inline, fixed_block, FragmentNone);
}
LayoutUnit resolveInlineLength(
const Length& length,
LengthResolveType type = LengthResolveType::ContentSize) {
NGConstraintSpace constraintSpace = constructConstraintSpace(200, 300);
return ::blink::resolveInlineLength(constraintSpace, length, type);
NGConstraintSpace* constraintSpace = ConstructConstraintSpace(200, 300);
return ::blink::resolveInlineLength(*constraintSpace, length, type);
}
LayoutUnit resolveBlockLength(
const Length& length,
LengthResolveType type = LengthResolveType::ContentSize,
LayoutUnit contentSize = LayoutUnit()) {
NGConstraintSpace constraintSpace = constructConstraintSpace(200, 300);
return ::blink::resolveBlockLength(constraintSpace, length, contentSize,
NGConstraintSpace* constraintSpace = ConstructConstraintSpace(200, 300);
return ::blink::resolveBlockLength(*constraintSpace, length, contentSize,
type);
}
LayoutUnit computeInlineSizeForFragment(
const NGConstraintSpace constraintSpace = constructConstraintSpace(200,
300)) {
return ::blink::computeInlineSizeForFragment(constraintSpace, *style_);
const NGConstraintSpace* constraintSpace =
ConstructConstraintSpace(200, 300)) {
return ::blink::computeInlineSizeForFragment(*constraintSpace, *style_);
}
LayoutUnit computeBlockSizeForFragment(
const NGConstraintSpace constraintSpace = constructConstraintSpace(200,
300),
const NGConstraintSpace* constraintSpace = ConstructConstraintSpace(200,
300),
LayoutUnit contentSize = LayoutUnit()) {
return ::blink::computeBlockSizeForFragment(constraintSpace, *style_,
return ::blink::computeBlockSizeForFragment(*constraintSpace, *style_,
contentSize);
}
......@@ -104,8 +108,8 @@ TEST_F(NGLengthUtilsTest, testComputeInlineSizeForFragment) {
PixelsAndPercent(100, -10), ValueRangeNonNegative)));
EXPECT_EQ(LayoutUnit(80), computeInlineSizeForFragment());
NGConstraintSpace constraintSpace = constructConstraintSpace(120, 120);
constraintSpace.setFixedSize(true, true);
NGConstraintSpace* constraintSpace =
ConstructConstraintSpace(120, 120, true, true);
style_->setLogicalWidth(Length(150, Fixed));
EXPECT_EQ(LayoutUnit(120), computeInlineSizeForFragment(constraintSpace));
......@@ -132,7 +136,7 @@ TEST_F(NGLengthUtilsTest, testComputeBlockSizeForFragment) {
style_->setLogicalHeight(Length(Auto));
EXPECT_EQ(LayoutUnit(120),
computeBlockSizeForFragment(constructConstraintSpace(200, 300),
computeBlockSizeForFragment(ConstructConstraintSpace(200, 300),
LayoutUnit(120)));
style_->setLogicalHeight(Length(FillAvailable));
......@@ -142,8 +146,8 @@ TEST_F(NGLengthUtilsTest, testComputeBlockSizeForFragment) {
PixelsAndPercent(100, -10), ValueRangeNonNegative)));
EXPECT_EQ(LayoutUnit(70), computeBlockSizeForFragment());
NGConstraintSpace constraintSpace = constructConstraintSpace(200, 200);
constraintSpace.setFixedSize(true, true);
NGConstraintSpace* constraintSpace =
ConstructConstraintSpace(200, 200, true, true);
style_->setLogicalHeight(Length(150, Fixed));
EXPECT_EQ(LayoutUnit(200), computeBlockSizeForFragment(constraintSpace));
......@@ -163,13 +167,13 @@ TEST_F(NGLengthUtilsTest, testIndefinitePercentages) {
style_->setHeight(Length(20, Percent));
EXPECT_EQ(NGSizeIndefinite,
computeBlockSizeForFragment(constructConstraintSpace(200, -1),
computeBlockSizeForFragment(ConstructConstraintSpace(200, -1),
LayoutUnit(-1)));
EXPECT_EQ(LayoutUnit(20),
computeBlockSizeForFragment(constructConstraintSpace(200, -1),
computeBlockSizeForFragment(ConstructConstraintSpace(200, -1),
LayoutUnit(10)));
EXPECT_EQ(LayoutUnit(120),
computeBlockSizeForFragment(constructConstraintSpace(200, -1),
computeBlockSizeForFragment(ConstructConstraintSpace(200, -1),
LayoutUnit(120)));
}
......@@ -179,9 +183,9 @@ TEST_F(NGLengthUtilsTest, testMargins) {
style_->setMarginBottom(Length(Auto));
style_->setMarginLeft(Length(11, Percent));
NGConstraintSpace constraintSpace(constructConstraintSpace(200, 300));
NGConstraintSpace* constraintSpace(ConstructConstraintSpace(200, 300));
NGBoxStrut margins = computeMargins(constraintSpace, *style_);
NGBoxStrut margins = computeMargins(*constraintSpace, *style_);
EXPECT_EQ(LayoutUnit(20), margins.block_start);
EXPECT_EQ(LayoutUnit(52), margins.inline_end);
......
// Copyright 2016 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/ng/ng_physical_constraint_space.h"
#include "core/layout/LayoutBox.h"
#include "core/style/ComputedStyle.h"
namespace blink {
NGPhysicalConstraintSpace::NGPhysicalConstraintSpace()
: fixed_width_(0),
fixed_height_(0),
width_direction_triggers_scrollbar_(0),
height_direction_triggers_scrollbar_(0),
width_direction_fragmentation_type_(FragmentNone),
height_direction_fragmentation_type_(FragmentNone) {}
NGPhysicalConstraintSpace::NGPhysicalConstraintSpace(
const NGPhysicalConstraintSpace& other)
: fixed_width_(other.fixed_width_),
fixed_height_(other.fixed_height_),
width_direction_triggers_scrollbar_(
other.width_direction_triggers_scrollbar_),
height_direction_triggers_scrollbar_(
other.height_direction_triggers_scrollbar_),
width_direction_fragmentation_type_(
other.width_direction_fragmentation_type_),
height_direction_fragmentation_type_(
other.height_direction_fragmentation_type_) {}
void NGPhysicalConstraintSpace::AddExclusion(const NGExclusion,
unsigned options) {
// TODO(layout-ng): Implement.
}
DoublyLinkedList<const NGExclusion> NGPhysicalConstraintSpace::Exclusions(
unsigned options) const {
DoublyLinkedList<const NGExclusion> exclusions;
// TODO(layout-ng): Implement.
return exclusions;
}
} // namespace blink
// Copyright 2016 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.
#ifndef NGPhysicalConstraintSpace_h
#define NGPhysicalConstraintSpace_h
#include "core/CoreExport.h"
#include "core/layout/ng/ng_units.h"
#include "platform/heap/Handle.h"
#include "wtf/DoublyLinkedList.h"
namespace blink {
enum NGExclusionType {
NGClearNone = 0,
NGClearFloatLeft = 1,
NGClearFloatRight = 2,
NGClearFragment = 4
};
enum NGFragmentationType {
FragmentNone,
FragmentPage,
FragmentColumn,
FragmentRegion
};
enum NGDirection { LeftToRight = 0, RightToLeft = 1 };
class NGExclusion {
public:
NGExclusion();
~NGExclusion() {}
};
// The NGPhysicalConstraintSpace contains the underlying data for the
// NGConstraintSpace. It is not meant to be used directly as all members are in
// the physical coordinate space. Instead NGConstraintSpace should be used.
class CORE_EXPORT NGPhysicalConstraintSpace final
: public GarbageCollected<NGPhysicalConstraintSpace> {
public:
NGPhysicalConstraintSpace();
NGPhysicalConstraintSpace(const NGPhysicalConstraintSpace&);
void AddExclusion(const NGExclusion, unsigned options = 0);
DoublyLinkedList<const NGExclusion> Exclusions(unsigned options = 0) const;
DEFINE_INLINE_TRACE() {}
private:
friend class NGConstraintSpace;
NGPhysicalSize container_size_;
unsigned fixed_width_ : 1;
unsigned fixed_height_ : 1;
unsigned width_direction_triggers_scrollbar_ : 1;
unsigned height_direction_triggers_scrollbar_ : 1;
unsigned width_direction_fragmentation_type_ : 2;
unsigned height_direction_fragmentation_type_ : 2;
DoublyLinkedList<const NGExclusion> exclusions_;
};
} // namespace blink
#endif // NGPhysicalConstraintSpace_h
......@@ -26,6 +26,10 @@ struct NGLogicalOffset {
};
struct NGPhysicalSize {
NGPhysicalSize() {}
NGPhysicalSize(LayoutUnit width, LayoutUnit height)
: width(width), height(height) {}
LayoutUnit width;
LayoutUnit height;
};
......
// Copyright 2016 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/ng/ng_writing_mode.h"
#include "platform/text/WritingMode.h"
#include "wtf/Assertions.h"
namespace blink {
NGWritingMode FromPlatformWritingMode(WritingMode mode) {
switch (mode) {
case TopToBottomWritingMode:
return HorizontalTopBottom;
case RightToLeftWritingMode:
return VerticalRightLeft;
case LeftToRightWritingMode:
return VerticalLeftRight;
default:
NOTREACHED();
return HorizontalTopBottom;
}
}
} // namespace blink
// Copyright 2016 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.
#ifndef NGWritingMode_h
#define NGWritingMode_h
#include "core/CoreExport.h"
#include "platform/text/WritingMode.h"
namespace blink {
enum NGWritingMode {
HorizontalTopBottom = 0,
VerticalRightLeft = 1,
VerticalLeftRight = 2,
SidewaysRightLeft = 3,
SidewaysLeftRight = 4
};
CORE_EXPORT NGWritingMode FromPlatformWritingMode(WritingMode);
} // namespace blink
#endif // NGWritingMode_h
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