| Index: third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.cc
 | 
| diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.cc b/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.cc
 | 
| index dfcb0b331022510d3459f4b17726951b5d16e209..5eb1a7c78a601292445a6b44c4be74221492257c 100644
 | 
| --- a/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.cc
 | 
| +++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.cc
 | 
| @@ -43,18 +43,6 @@ bool IsOverlapping(const NGEdge& edge1, const NGEdge& edge2) {
 | 
|    return std::max(edge1.start, edge2.start) <= std::min(edge1.end, edge2.end);
 | 
|  }
 | 
|  
 | 
| -// Whether the exclusion is out of bounds of the LayoutNG constraint space.
 | 
| -bool IsExclusionWithinSpace(const NGLayoutOpportunity& opportunity,
 | 
| -                            const NGExclusion& exclusion) {
 | 
| -  LayoutUnit left = opportunity.offset.inline_offset;
 | 
| -  LayoutUnit top = opportunity.offset.block_offset;
 | 
| -  LayoutUnit right = left + opportunity.size.inline_size;
 | 
| -  LayoutUnit bottom = top + opportunity.size.block_size;
 | 
| -
 | 
| -  return !(exclusion.Right() <= left || exclusion.Bottom() <= top ||
 | 
| -           exclusion.Left() >= right || exclusion.Top() >= bottom);
 | 
| -}
 | 
| -
 | 
|  // Creates the *BOTTOM* positioned Layout Opportunity tree node by splitting
 | 
|  // the parent node with the exclusion.
 | 
|  //
 | 
| @@ -63,18 +51,18 @@ bool IsExclusionWithinSpace(const NGLayoutOpportunity& opportunity,
 | 
|  // @return New node or nullptr if the new block size == 0.
 | 
|  NGLayoutOpportunityTreeNode* CreateBottomNGLayoutOpportunityTreeNode(
 | 
|      const NGLayoutOpportunityTreeNode* parent_node,
 | 
| -    const NGExclusion& exclusion) {
 | 
| +    const NGLogicalRect& exclusion) {
 | 
|    const NGLayoutOpportunity& parent_opportunity = parent_node->opportunity;
 | 
| -  LayoutUnit left = parent_opportunity.offset.inline_offset;
 | 
| -  LayoutUnit top = exclusion.Bottom();
 | 
| -  LayoutUnit right = left + parent_opportunity.size.inline_size;
 | 
| -  LayoutUnit bottom = parent_opportunity.offset.block_offset +
 | 
| -                      parent_opportunity.size.block_size;
 | 
| -
 | 
| -  NGEdge exclusion_edge = {exclusion.Left(), exclusion.Right()};
 | 
| -  LayoutUnit block_size = bottom - top;
 | 
| -  if (block_size > 0) {
 | 
| -    NGLayoutOpportunity opportunity(left, top, right - left, block_size);
 | 
| +  LayoutUnit bottom_opportunity_block_size =
 | 
| +      parent_opportunity.BlockEndOffset() - exclusion.BlockEndOffset();
 | 
| +  if (bottom_opportunity_block_size > 0) {
 | 
| +    NGLayoutOpportunity opportunity;
 | 
| +    opportunity.offset.inline_offset = parent_opportunity.InlineStartOffset();
 | 
| +    opportunity.offset.block_offset = exclusion.BlockEndOffset();
 | 
| +    opportunity.size.inline_size = parent_opportunity.InlineSize();
 | 
| +    opportunity.size.block_size = bottom_opportunity_block_size;
 | 
| +    NGEdge exclusion_edge = {/* start */ exclusion.InlineStartOffset(),
 | 
| +                             /* end */ exclusion.InlineEndOffset()};
 | 
|      return new NGLayoutOpportunityTreeNode(opportunity, exclusion_edge);
 | 
|    }
 | 
|    return nullptr;
 | 
| @@ -89,18 +77,21 @@ NGLayoutOpportunityTreeNode* CreateBottomNGLayoutOpportunityTreeNode(
 | 
|  // exclusion edge doesn't limit the new node's constraint space.
 | 
|  NGLayoutOpportunityTreeNode* CreateLeftNGLayoutOpportunityTreeNode(
 | 
|      const NGLayoutOpportunityTreeNode* parent_node,
 | 
| -    const NGExclusion& exclusion) {
 | 
| +    const NGLogicalRect& exclusion) {
 | 
|    const NGLayoutOpportunity& parent_opportunity = parent_node->opportunity;
 | 
| -  LayoutUnit left = parent_opportunity.offset.inline_offset;
 | 
| -  LayoutUnit top = parent_opportunity.offset.block_offset;
 | 
| -  LayoutUnit right = exclusion.Left();
 | 
| -  LayoutUnit bottom = top + parent_opportunity.size.block_size;
 | 
| -
 | 
| -  NGEdge node_edge = {left, right};
 | 
| -  LayoutUnit inline_size = right - left;
 | 
| -  if (inline_size > 0 &&
 | 
| +
 | 
| +  LayoutUnit left_opportunity_inline_size =
 | 
| +      exclusion.InlineStartOffset() - parent_opportunity.InlineStartOffset();
 | 
| +  NGEdge node_edge = {/* start */ parent_opportunity.InlineStartOffset(),
 | 
| +                      /* end */ exclusion.InlineStartOffset()};
 | 
| +
 | 
| +  if (left_opportunity_inline_size > 0 &&
 | 
|        IsOverlapping(parent_node->exclusion_edge, node_edge)) {
 | 
| -    NGLayoutOpportunity opportunity(left, top, inline_size, bottom - top);
 | 
| +    NGLayoutOpportunity opportunity;
 | 
| +    opportunity.offset.inline_offset = parent_opportunity.InlineStartOffset();
 | 
| +    opportunity.offset.block_offset = parent_opportunity.BlockStartOffset();
 | 
| +    opportunity.size.inline_size = left_opportunity_inline_size;
 | 
| +    opportunity.size.block_size = parent_opportunity.BlockSize();
 | 
|      return new NGLayoutOpportunityTreeNode(opportunity);
 | 
|    }
 | 
|    return nullptr;
 | 
| @@ -115,19 +106,20 @@ NGLayoutOpportunityTreeNode* CreateLeftNGLayoutOpportunityTreeNode(
 | 
|  // exclusion edge doesn't limit the new node's constraint space.
 | 
|  NGLayoutOpportunityTreeNode* CreateRightNGLayoutOpportunityTreeNode(
 | 
|      const NGLayoutOpportunityTreeNode* parent_node,
 | 
| -    const NGExclusion& exclusion) {
 | 
| +    const NGLogicalRect& exclusion) {
 | 
|    const NGLayoutOpportunity& parent_opportunity = parent_node->opportunity;
 | 
| -  LayoutUnit left = exclusion.Right();
 | 
| -  LayoutUnit top = parent_opportunity.offset.block_offset;
 | 
| -  LayoutUnit right = parent_opportunity.offset.inline_offset +
 | 
| -                     parent_opportunity.size.inline_size;
 | 
| -  LayoutUnit bottom = top + parent_opportunity.size.block_size;
 | 
| -
 | 
| -  NGEdge node_edge = {left, right};
 | 
| -  LayoutUnit inline_size = right - left;
 | 
| -  if (inline_size > 0 &&
 | 
| +
 | 
| +  NGEdge node_edge = {/* start */ exclusion.InlineEndOffset(),
 | 
| +                      /* end */ parent_opportunity.InlineEndOffset()};
 | 
| +  LayoutUnit right_opportunity_inline_size =
 | 
| +      parent_opportunity.InlineEndOffset() - exclusion.InlineEndOffset();
 | 
| +  if (right_opportunity_inline_size > 0 &&
 | 
|        IsOverlapping(parent_node->exclusion_edge, node_edge)) {
 | 
| -    NGLayoutOpportunity opportunity(left, top, inline_size, bottom - top);
 | 
| +    NGLayoutOpportunity opportunity;
 | 
| +    opportunity.offset.inline_offset = exclusion.InlineEndOffset();
 | 
| +    opportunity.offset.block_offset = parent_opportunity.BlockStartOffset();
 | 
| +    opportunity.size.inline_size = right_opportunity_inline_size;
 | 
| +    opportunity.size.block_size = parent_opportunity.BlockSize();
 | 
|      return new NGLayoutOpportunityTreeNode(opportunity);
 | 
|    }
 | 
|    return nullptr;
 | 
| @@ -136,33 +128,34 @@ NGLayoutOpportunityTreeNode* CreateRightNGLayoutOpportunityTreeNode(
 | 
|  // Gets/Creates the "TOP" positioned constraint space by splitting
 | 
|  // the parent node with the exclusion.
 | 
|  //
 | 
| -// @param parent_node Node that needs to be split.
 | 
| +// @param parent_opportunity Parent opportunity that is being split.
 | 
|  // @param exclusion Exclusion existed in the parent node constraint space.
 | 
|  // @return New node or nullptr if the new block size == 0.
 | 
| -NGLayoutOpportunity GetTopSpace(const NGLayoutOpportunity& rect,
 | 
| -                                const NGExclusion& exclusion) {
 | 
| -  LayoutUnit left = rect.offset.inline_offset;
 | 
| -  LayoutUnit top = rect.offset.block_offset;
 | 
| -  LayoutUnit right = left + rect.size.inline_size;
 | 
| -  LayoutUnit bottom = exclusion.Top();
 | 
| -
 | 
| -  LayoutUnit block_size = bottom - top;
 | 
| -  if (block_size > 0)
 | 
| -    return NGLayoutOpportunity(left, top, right - left, block_size);
 | 
| -
 | 
| +NGLayoutOpportunity GetTopSpace(const NGLayoutOpportunity& parent_opportunity,
 | 
| +                                const NGLogicalRect& exclusion) {
 | 
| +  LayoutUnit top_opportunity_block_size =
 | 
| +      exclusion.BlockStartOffset() - parent_opportunity.BlockStartOffset();
 | 
| +  if (top_opportunity_block_size > 0) {
 | 
| +    NGLayoutOpportunity opportunity;
 | 
| +    opportunity.offset.inline_offset = parent_opportunity.InlineStartOffset();
 | 
| +    opportunity.offset.block_offset = parent_opportunity.BlockStartOffset();
 | 
| +    opportunity.size.inline_size = parent_opportunity.InlineSize();
 | 
| +    opportunity.size.block_size = top_opportunity_block_size;
 | 
| +    return opportunity;
 | 
| +  }
 | 
|    return NGLayoutOpportunity();
 | 
|  }
 | 
|  
 | 
|  // Inserts the exclusion into the Layout Opportunity tree.
 | 
|  void InsertExclusion(NGLayoutOpportunityTreeNode* node,
 | 
| -                     const NGExclusion* exclusion,
 | 
| +                     const NGLogicalRect* exclusion,
 | 
|                       NGLayoutOpportunities& opportunities) {
 | 
|    // Base case: there is no node.
 | 
|    if (!node)
 | 
|      return;
 | 
|  
 | 
|    // Base case: exclusion is not in the node's constraint space.
 | 
| -  if (!IsExclusionWithinSpace(node->opportunity, *exclusion))
 | 
| +  if (!exclusion->IsContained(node->opportunity))
 | 
|      return;
 | 
|  
 | 
|    if (node->exclusion) {
 | 
| @@ -186,9 +179,10 @@ void InsertExclusion(NGLayoutOpportunityTreeNode* node,
 | 
|  }
 | 
|  
 | 
|  // Compares exclusions by their top position.
 | 
| -bool CompareNGExclusionsByTopAsc(const Member<const NGExclusion>& lhs,
 | 
| -                                 const Member<const NGExclusion>& rhs) {
 | 
| -  return rhs->Top() > lhs->Top();
 | 
| +bool CompareNGExclusionsByTopAsc(
 | 
| +    const std::unique_ptr<const NGLogicalRect>& lhs,
 | 
| +    const std::unique_ptr<const NGLogicalRect>& rhs) {
 | 
| +  return rhs->offset.block_offset > lhs->offset.block_offset;
 | 
|  }
 | 
|  
 | 
|  // Compares Layout Opportunities by Start Point.
 | 
| @@ -224,7 +218,7 @@ NGLayoutOpportunityIterator::NGLayoutOpportunityIterator(
 | 
|      const NGLogicalOffset leader_point)
 | 
|      : constraint_space_(space), leader_point_(leader_point) {
 | 
|    // TODO(chrome-layout-team): Combine exclusions that shadow each other.
 | 
| -  auto exclusions = constraint_space_->PhysicalSpace()->Exclusions();
 | 
| +  auto& exclusions = constraint_space_->PhysicalSpace()->Exclusions();
 | 
|    DCHECK(std::is_sorted(exclusions.begin(), exclusions.end(),
 | 
|                          &CompareNGExclusionsByTopAsc))
 | 
|        << "Exclusions are expected to be sorted by TOP";
 | 
| @@ -233,8 +227,9 @@ NGLayoutOpportunityIterator::NGLayoutOpportunityIterator(
 | 
|        CreateLayoutOpportunityFromConstraintSpace(*space, origin_point);
 | 
|    opportunity_tree_root_ = new NGLayoutOpportunityTreeNode(initial_opportunity);
 | 
|  
 | 
| -  for (const auto exclusion : exclusions) {
 | 
| -    InsertExclusion(MutableOpportunityTreeRoot(), exclusion, opportunities_);
 | 
| +  for (const auto& exclusion : exclusions) {
 | 
| +    InsertExclusion(MutableOpportunityTreeRoot(), exclusion.get(),
 | 
| +                    opportunities_);
 | 
|    }
 | 
|    CollectAllOpportunities(OpportunityTreeRoot(), opportunities_);
 | 
|    std::sort(opportunities_.begin(), opportunities_.end(),
 | 
| 
 |