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); |
} |