Commit eb0fe177 authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

[LayoutNG] Implement line height from font metrics when elements wraps

When elements wraps, 'line-height: normal' should take used fonts of
each line into account, but it was talking used fonts of the element
instead. This patch implements this case using the ShapeResult from
ShapingLineBreaker.

This patch also fixes a case where ShapeResult was not set.

BUG=636993
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_layout_tests_layout_ng

Change-Id: Idf11e7b4676ec0639aa3ffa94890619502064070
Reviewed-on: https://chromium-review.googlesource.com/572603Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Commit-Queue: Emil A Eklund <eae@chromium.org>
Cr-Commit-Position: refs/heads/master@{#487110}
parent 8f09df8b
...@@ -24,12 +24,10 @@ void NGInlineBoxState::ComputeTextMetrics(const ComputedStyle& style, ...@@ -24,12 +24,10 @@ void NGInlineBoxState::ComputeTextMetrics(const ComputedStyle& style,
include_used_fonts = style.LineHeight().IsNegative(); include_used_fonts = style.LineHeight().IsNegative();
} }
void NGInlineBoxState::AccumulateUsedFonts(const NGInlineItem& item, void NGInlineBoxState::AccumulateUsedFonts(const ShapeResult* shape_result,
unsigned start,
unsigned end,
FontBaseline baseline_type) { FontBaseline baseline_type) {
HashSet<const SimpleFontData*> fallback_fonts; HashSet<const SimpleFontData*> fallback_fonts;
item.GetFallbackFonts(&fallback_fonts, start, end); shape_result->FallbackFonts(&fallback_fonts);
for (const auto& fallback_font : fallback_fonts) { for (const auto& fallback_font : fallback_fonts) {
NGLineHeightMetrics fallback_metrics(fallback_font->GetFontMetrics(), NGLineHeightMetrics fallback_metrics(fallback_font->GetFontMetrics(),
baseline_type); baseline_type);
......
...@@ -18,6 +18,7 @@ namespace blink { ...@@ -18,6 +18,7 @@ namespace blink {
class NGInlineItem; class NGInlineItem;
struct NGInlineItemResult; struct NGInlineItemResult;
class NGLineBoxFragmentBuilder; class NGLineBoxFragmentBuilder;
class ShapeResult;
// Fragments that require the layout position/size of ancestor are packed in // Fragments that require the layout position/size of ancestor are packed in
// this struct. // this struct.
...@@ -65,10 +66,7 @@ struct NGInlineBoxState { ...@@ -65,10 +66,7 @@ struct NGInlineBoxState {
// Compute text metrics for a box. All text in a box share the same metrics. // Compute text metrics for a box. All text in a box share the same metrics.
void ComputeTextMetrics(const ComputedStyle& style, FontBaseline); void ComputeTextMetrics(const ComputedStyle& style, FontBaseline);
void AccumulateUsedFonts(const NGInlineItem&, void AccumulateUsedFonts(const ShapeResult*, FontBaseline);
unsigned start,
unsigned end,
FontBaseline);
// Create a box fragment for this box. // Create a box fragment for this box.
void SetNeedsBoxFragment(bool when_empty); void SetNeedsBoxFragment(bool when_empty);
......
...@@ -112,18 +112,6 @@ LayoutUnit NGInlineItem::InlineSize(unsigned start, unsigned end) const { ...@@ -112,18 +112,6 @@ LayoutUnit NGInlineItem::InlineSize(unsigned start, unsigned end) const {
.Width()); .Width());
} }
void NGInlineItem::GetFallbackFonts(
HashSet<const SimpleFontData*>* fallback_fonts,
unsigned start,
unsigned end) const {
DCHECK_GE(start, StartOffset());
DCHECK_LE(start, end);
DCHECK_LE(end, EndOffset());
// TODO(kojii): Implement |start| and |end|.
shape_result_->FallbackFonts(fallback_fonts);
}
bool NGInlineItem::HasStartEdge() const { bool NGInlineItem::HasStartEdge() const {
DCHECK(Type() == kOpenTag || Type() == kCloseTag); DCHECK(Type() == kOpenTag || Type() == kCloseTag);
// TODO(kojii): Should use break token when NG has its own tree building. // TODO(kojii): Should use break token when NG has its own tree building.
......
...@@ -87,10 +87,6 @@ class NGInlineItem { ...@@ -87,10 +87,6 @@ class NGInlineItem {
LayoutUnit InlineSize() const; LayoutUnit InlineSize() const;
LayoutUnit InlineSize(unsigned start, unsigned end) const; LayoutUnit InlineSize(unsigned start, unsigned end) const;
void GetFallbackFonts(HashSet<const SimpleFontData*>*,
unsigned start,
unsigned end) const;
bool HasStartEdge() const; bool HasStartEdge() const;
bool HasEndEdge() const; bool HasEndEdge() const;
......
...@@ -161,12 +161,16 @@ bool NGInlineLayoutAlgorithm::PlaceItems( ...@@ -161,12 +161,16 @@ bool NGInlineLayoutAlgorithm::PlaceItems(
DCHECK(!box->text_metrics.IsEmpty()); DCHECK(!box->text_metrics.IsEmpty());
text_builder.SetSize( text_builder.SetSize(
{item_result.inline_size, box->text_metrics.LineHeight()}); {item_result.inline_size, box->text_metrics.LineHeight()});
// Take all used fonts into account if 'line-height: normal'. if (item_result.shape_result) {
if (box->include_used_fonts && item.Type() == NGInlineItem::kText) { // Take all used fonts into account if 'line-height: normal'.
box->AccumulateUsedFonts(item, item_result.start_offset, if (box->include_used_fonts && item.Type() == NGInlineItem::kText) {
item_result.end_offset, baseline_type_); box->AccumulateUsedFonts(item_result.shape_result.Get(),
baseline_type_);
}
text_builder.SetShapeResult(std::move(item_result.shape_result));
} else {
DCHECK(!item.TextShapeResult()); // kControl or unit tests.
} }
text_builder.SetShapeResult(std::move(item_result.shape_result));
RefPtr<NGPhysicalTextFragment> text_fragment = RefPtr<NGPhysicalTextFragment> text_fragment =
text_builder.ToTextFragment(item_result.item_index, text_builder.ToTextFragment(item_result.item_index,
item_result.start_offset, item_result.start_offset,
......
...@@ -232,11 +232,11 @@ NGLineBreaker::LineBreakState NGLineBreaker::HandleText( ...@@ -232,11 +232,11 @@ NGLineBreaker::LineBreakState NGLineBreaker::HandleText(
item_result->inline_size = item.InlineSize(); item_result->inline_size = item.InlineSize();
LayoutUnit next_position = position_ + item_result->inline_size; LayoutUnit next_position = position_ + item_result->inline_size;
if (!auto_wrap_ || next_position <= available_width) { if (!auto_wrap_ || next_position <= available_width) {
item_result->shape_result = item.TextShapeResult();
position_ = next_position; position_ = next_position;
MoveToNextOf(item); MoveToNextOf(item);
if (auto_wrap_ && break_iterator_.IsBreakable(item.EndOffset())) if (auto_wrap_ && break_iterator_.IsBreakable(item.EndOffset()))
return LineBreakState::kIsBreakable; return LineBreakState::kIsBreakable;
item_result->shape_result = item.TextShapeResult();
item_result->prohibit_break_after = true; item_result->prohibit_break_after = true;
return LineBreakState::kNotBreakable; return LineBreakState::kNotBreakable;
} }
......
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