 Chromium Code Reviews
 Chromium Code Reviews Issue 2745973002:
  [LayoutNG] Implement atomic inlines for LayoutNGInline  (Closed)
    
  
    Issue 2745973002:
  [LayoutNG] Implement atomic inlines for LayoutNGInline  (Closed) 
  | Index: third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc | 
| diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc | 
| index 3c2b40b086519549eb63076fe12e1d79029772f6..120359897cfda94cf09b310a22a6cb2d982f4b9e 100644 | 
| --- a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc | 
| +++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc | 
| @@ -30,7 +30,9 @@ namespace blink { | 
| NGInlineNode::NGInlineNode(LayoutObject* start_inline, LayoutBlockFlow* block) | 
| : NGLayoutInputNode(NGLayoutInputNodeType::kLegacyInline), | 
| start_inline_(start_inline), | 
| - block_(block) { | 
| + block_(block), | 
| + has_atomic_inlines_(false), | 
| + is_bidi_enabled_(false) { | 
| DCHECK(start_inline); | 
| DCHECK(block); | 
| } | 
| @@ -38,7 +40,9 @@ NGInlineNode::NGInlineNode(LayoutObject* start_inline, LayoutBlockFlow* block) | 
| NGInlineNode::NGInlineNode() | 
| : NGLayoutInputNode(NGLayoutInputNodeType::kLegacyInline), | 
| start_inline_(nullptr), | 
| - block_(nullptr) {} | 
| + block_(nullptr), | 
| + has_atomic_inlines_(false), | 
| + is_bidi_enabled_(false) {} | 
| NGInlineNode::~NGInlineNode() {} | 
| @@ -49,6 +53,7 @@ NGLayoutInlineItemRange NGInlineNode::Items(unsigned start, unsigned end) { | 
| void NGInlineNode::InvalidatePrepareLayout() { | 
| text_content_ = String(); | 
| items_.clear(); | 
| + has_atomic_inlines_ = false; | 
| } | 
| void NGInlineNode::PrepareLayout() { | 
| @@ -107,6 +112,7 @@ LayoutObject* NGInlineNode::CollectInlines( | 
| // signal the presence of a non-text object to the unicode bidi algorithm. | 
| if (node->isAtomicInlineLevel()) { | 
| builder->Append(objectReplacementCharacter, nullptr, node); | 
| + has_atomic_inlines_ = true; | 
| } | 
| // Otherwise traverse to children if they exist. | 
| @@ -219,8 +225,20 @@ LayoutUnit NGLayoutInlineItem::InlineSize(unsigned start, unsigned end) const { | 
| return LayoutUnit(); | 
| if (!style_ || !shape_result_) { | 
| - // Bidi controls do not have widths. | 
| - // TODO(kojii): Atomic inline not supported yet. | 
| + DCHECK(start == start_offset_ && end == end_offset_); | 
| + if (layout_result_) { | 
| + DCHECK(layout_object_ && layout_object_->isAtomicInlineLevel() && | 
| + !layout_object_->isFloatingOrOutOfFlowPositioned()); | 
| + // TODO(kojii): Store parent's isHorizontalWritingMode in | 
| + // NGLayoutInlineItem. | 
| + if (!isHorizontalWritingMode( | 
| + layout_object_->parent()->styleRef().getWritingMode())) | 
| + return layout_result_->PhysicalFragment()->Height(); | 
| + return layout_result_->PhysicalFragment()->Width(); | 
| + } | 
| + DCHECK(!layout_object_ || | 
| + layout_object_->isFloatingOrOutOfFlowPositioned()); | 
| + // Bidi controls and out-of-flow objects do not have in-flow widths. | 
| return LayoutUnit(); | 
| } | 
| @@ -250,7 +268,8 @@ void NGInlineNode::ShapeText() { | 
| // Shape each item with the full context of the entire node. | 
| HarfBuzzShaper shaper(text_content_.characters16(), text_content_.length()); | 
| for (auto& item : items_) { | 
| - // Skip object replacement characters and bidi control characters. | 
| + // Skip non-text items; e.g., bidi controls, atomic inlines, out-of-flow | 
| + // objects. | 
| if (!item.style_) | 
| continue; | 
| @@ -264,6 +283,31 @@ RefPtr<NGLayoutResult> NGInlineNode::Layout(NGConstraintSpace*, NGBreakToken*) { | 
| return nullptr; | 
| } | 
| +void NGInlineNode::LayoutAtomicInlines( | 
| + const NGConstraintSpace& parent_constraint_space) { | 
| + NGConstraintSpaceBuilder constraint_space_builder(&parent_constraint_space); | 
| + constraint_space_builder.SetIsNewFormattingContext(true).SetIsShrinkToFit( | 
| + true); | 
| + for (auto& item : items_) { | 
| + if (item.style_) | 
| + continue; | 
| + LayoutObject* layout_object = item.layout_object_; | 
| + if (layout_object && layout_object->isAtomicInlineLevel() && | 
| + !layout_object->isFloatingOrOutOfFlowPositioned() && | 
| + (!item.layout_result_ || layout_object->needsLayout())) { | 
| + NGBlockNode* node = new NGBlockNode(layout_object); | 
| + const ComputedStyle& style = node->Style(); | 
| + RefPtr<NGConstraintSpace> constraint_space = | 
| + constraint_space_builder.SetTextDirection(style.direction()) | 
| + .ToConstraintSpace( | 
| + FromPlatformWritingMode(style.getWritingMode())); | 
| + item.layout_result_ = node->Layout(constraint_space.get()); | 
| + DCHECK(!layout_object->needsLayout()); | 
| + // TODO(kojii): Figure out what to do with OOF and unpositioned floats. | 
| + } | 
| + } | 
| +} | 
| + | 
| void NGInlineNode::LayoutInline(NGConstraintSpace* constraint_space, | 
| NGLineBuilder* line_builder) { | 
| if (!IsPrepareLayoutFinished()) | 
| @@ -272,6 +316,9 @@ void NGInlineNode::LayoutInline(NGConstraintSpace* constraint_space, | 
| if (text_content_.isEmpty()) | 
| return; | 
| + if (has_atomic_inlines_) | 
| + LayoutAtomicInlines(*constraint_space); | 
| 
ikilpatrick
2017/03/15 16:39:41
We need to decide if we are going to support fragm
 
kojii
2017/03/15 17:30:28
It'd be great if we can, though I acknowledge it's
 
mstensho (USE GERRIT)
2017/03/16 09:20:14
Lines are monolithic, which means that we shouldn'
 | 
| + | 
| NGTextLayoutAlgorithm(this, constraint_space).LayoutInline(line_builder); | 
| } |