Index: third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc |
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc |
index 070fa6a6f2bee865e8a17c4e8d63e789a8ecddc1..de846ef179f1766d1e78db0945a24c4e63c80361 100644 |
--- a/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc |
+++ b/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc |
@@ -218,19 +218,28 @@ void NGLineBuilder::PlaceItems( |
if (!item.GetLayoutObject()) |
continue; |
- LayoutUnit top, height; |
+ LayoutUnit top; |
const ComputedStyle* style = item.Style(); |
if (style) { |
+ DCHECK(item.GetLayoutObject()->isText()); |
// |InlineTextBoxPainter| sets the baseline at |top + |
// ascent-of-primary-font|. Compute |top| to match. |
InlineItemMetrics metrics(*style, baseline_type_); |
top = estimated_baseline - LayoutUnit(metrics.ascent); |
- height = LayoutUnit(metrics.ascent + metrics.descent); |
+ LayoutUnit height = LayoutUnit(metrics.ascent + metrics.descent); |
line_box_data.UpdateMaxAscentAndDescent(metrics); |
// Take all used fonts into account if 'line-height: normal'. |
if (style->lineHeight().isNegative()) |
AccumulateUsedFonts(item, line_item_chunk, &line_box_data); |
+ |
+ // The direction of a fragment is the CSS direction to resolve logical |
+ // properties, not the resolved bidi direction. |
+ text_builder.SetDirection(style->direction()) |
+ .SetInlineSize(line_item_chunk.inline_size) |
+ .SetInlineOverflow(line_item_chunk.inline_size) |
+ .SetBlockSize(height) |
+ .SetBlockOverflow(height); |
} else { |
LayoutObject* layout_object = item.GetLayoutObject(); |
if (layout_object->isOutOfFlowPositioned()) { |
@@ -249,19 +258,10 @@ void NGLineBuilder::PlaceItems( |
layout_object->clearNeedsLayout(); |
continue; |
} |
- DCHECK(layout_object->isAtomicInlineLevel()); |
- // TODO(kojii): Implement atomic inline. |
- style = layout_object->style(); |
- top = content_size_; |
+ top = PlaceAtomicInline(item, estimated_baseline, &line_box_data, |
+ &text_builder); |
} |
- // The direction of a fragment is the CSS direction to resolve logical |
- // properties, not the resolved bidi direction. |
- text_builder.SetDirection(style->direction()) |
- .SetInlineSize(line_item_chunk.inline_size) |
- .SetInlineOverflow(line_item_chunk.inline_size) |
- .SetBlockSize(height) |
- .SetBlockOverflow(height); |
RefPtr<NGPhysicalTextFragment> text_fragment = text_builder.ToTextFragment( |
line_item_chunk.index, line_item_chunk.start_offset, |
line_item_chunk.end_offset); |
@@ -352,6 +352,54 @@ void NGLineBuilder::AccumulateUsedFonts(const NGLayoutInlineItem& item, |
} |
} |
+LayoutUnit NGLineBuilder::PlaceAtomicInline(const NGLayoutInlineItem& item, |
+ LayoutUnit estimated_baseline, |
+ LineBoxData* line_box_data, |
+ NGFragmentBuilder* text_builder) { |
+ LayoutObject* layout_object = item.GetLayoutObject(); |
+ DCHECK(layout_object && layout_object->isAtomicInlineLevel()); |
+ const NGLayoutResult* layout_result = item.GetLayoutResult(); |
+ DCHECK(layout_result); |
+ RefPtr<NGPhysicalFragment> fragment = layout_result->PhysicalFragment(); |
+ bool is_horizontal_writing_mode = |
+ IsHorizontalWritingMode(ConstraintSpace().WritingMode()); |
+ LayoutUnit height; |
+ // TODO(kojii): Try to eliminate the text fragment and use the |fragment| |
+ // directly. Currently |CopyFragmentDataToLayoutBlockFlow| requires a text |
+ // fragment. |
+ // TODO(kojii): Margin and border in block progression not implemented yet. |
+ if (is_horizontal_writing_mode) { |
+ height = fragment->Height(); |
+ text_builder->SetInlineSize(fragment->Width()) |
+ .SetInlineOverflow(fragment->WidthOverflow()) |
+ .SetBlockSize(height) |
+ .SetBlockOverflow(fragment->HeightOverflow()); |
+ } else { |
+ height = fragment->Width(); |
+ text_builder->SetInlineSize(fragment->Height()) |
+ .SetInlineOverflow(fragment->HeightOverflow()) |
+ .SetBlockSize(height) |
+ .SetBlockOverflow(fragment->WidthOverflow()); |
+ } |
+ |
+ // TODO(kojii): Add baseline position to NGPhysicalFragment. |
+ LayoutBox* box = toLayoutBox(layout_object); |
+ LineDirectionMode line_direction_mode = |
+ is_horizontal_writing_mode ? LineDirectionMode::HorizontalLine |
+ : LineDirectionMode::VerticalLine; |
+ bool is_first_line = line_box_data_list_.size() == 1; |
+ int baseline_offset = |
+ box->baselinePosition(baseline_type_, is_first_line, line_direction_mode); |
+ LayoutUnit top = estimated_baseline - baseline_offset; |
+ |
+ line_box_data->max_ascent_and_leading = |
+ std::max<float>(baseline_offset, line_box_data->max_ascent_and_leading); |
+ line_box_data->max_descent_and_leading = std::max<float>( |
+ height - baseline_offset, line_box_data->max_descent_and_leading); |
+ |
+ return top; |
+} |
+ |
void NGLineBuilder::FindNextLayoutOpportunity() { |
NGLogicalOffset iter_offset = constraint_space_->BfcOffset(); |
iter_offset.block_offset += content_size_; |
@@ -417,8 +465,6 @@ void NGLineBuilder::CopyFragmentDataToLayoutBlockFlow() { |
DCHECK(layout_object->isAtomicInlineLevel()); |
run = |
new BidiRun(0, 1, item.BidiLevel(), LineLayoutItem(layout_object)); |
- // TODO(kojii): Temporarily clearNeedsLayout() for not to assert. |
- layout_object->clearNeedsLayout(); |
} |
bidi_runs.addRun(run); |
fragments_for_bidi_runs.push_back(text_fragment); |
@@ -443,12 +489,17 @@ void NGLineBuilder::CopyFragmentDataToLayoutBlockFlow() { |
inline_box->setLogicalWidth(fragment.InlineSize()); |
inline_box->setLogicalLeft(fragment.InlineOffset()); |
inline_box->setLogicalTop(fragment.BlockOffset()); |
+ if (inline_box->getLineLayoutItem().isBox()) { |
+ LineLayoutBox box(inline_box->getLineLayoutItem()); |
+ box.setLocation(inline_box->location()); |
+ } |
run = run->next(); |
} |
DCHECK(!run); |
// Copy LineBoxData to RootInlineBox. |
line_box->setLogicalWidth(line_box_data.inline_size); |
+ line_box->setLogicalTop(line_box_data.top_with_leading); |
LayoutUnit baseline_position = |
line_box_data.top_with_leading + |
LayoutUnit(line_box_data.max_ascent_and_leading); |