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,
include_used_fonts = style.LineHeight().IsNegative();
}
void NGInlineBoxState::AccumulateUsedFonts(const NGInlineItem& item,
unsigned start,
unsigned end,
void NGInlineBoxState::AccumulateUsedFonts(const ShapeResult* shape_result,
FontBaseline baseline_type) {
HashSet<const SimpleFontData*> fallback_fonts;
item.GetFallbackFonts(&fallback_fonts, start, end);
shape_result->FallbackFonts(&fallback_fonts);
for (const auto& fallback_font : fallback_fonts) {
NGLineHeightMetrics fallback_metrics(fallback_font->GetFontMetrics(),
baseline_type);
......
......@@ -18,6 +18,7 @@ namespace blink {
class NGInlineItem;
struct NGInlineItemResult;
class NGLineBoxFragmentBuilder;
class ShapeResult;
// Fragments that require the layout position/size of ancestor are packed in
// this struct.
......@@ -65,10 +66,7 @@ struct NGInlineBoxState {
// Compute text metrics for a box. All text in a box share the same metrics.
void ComputeTextMetrics(const ComputedStyle& style, FontBaseline);
void AccumulateUsedFonts(const NGInlineItem&,
unsigned start,
unsigned end,
FontBaseline);
void AccumulateUsedFonts(const ShapeResult*, FontBaseline);
// Create a box fragment for this box.
void SetNeedsBoxFragment(bool when_empty);
......
......@@ -112,18 +112,6 @@ LayoutUnit NGInlineItem::InlineSize(unsigned start, unsigned end) const {
.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 {
DCHECK(Type() == kOpenTag || Type() == kCloseTag);
// TODO(kojii): Should use break token when NG has its own tree building.
......
......@@ -87,10 +87,6 @@ class NGInlineItem {
LayoutUnit InlineSize() const;
LayoutUnit InlineSize(unsigned start, unsigned end) const;
void GetFallbackFonts(HashSet<const SimpleFontData*>*,
unsigned start,
unsigned end) const;
bool HasStartEdge() const;
bool HasEndEdge() const;
......
......@@ -161,12 +161,16 @@ bool NGInlineLayoutAlgorithm::PlaceItems(
DCHECK(!box->text_metrics.IsEmpty());
text_builder.SetSize(
{item_result.inline_size, box->text_metrics.LineHeight()});
if (item_result.shape_result) {
// Take all used fonts into account if 'line-height: normal'.
if (box->include_used_fonts && item.Type() == NGInlineItem::kText) {
box->AccumulateUsedFonts(item, item_result.start_offset,
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.
}
RefPtr<NGPhysicalTextFragment> text_fragment =
text_builder.ToTextFragment(item_result.item_index,
item_result.start_offset,
......
......@@ -232,11 +232,11 @@ NGLineBreaker::LineBreakState NGLineBreaker::HandleText(
item_result->inline_size = item.InlineSize();
LayoutUnit next_position = position_ + item_result->inline_size;
if (!auto_wrap_ || next_position <= available_width) {
item_result->shape_result = item.TextShapeResult();
position_ = next_position;
MoveToNextOf(item);
if (auto_wrap_ && break_iterator_.IsBreakable(item.EndOffset()))
return LineBreakState::kIsBreakable;
item_result->shape_result = item.TextShapeResult();
item_result->prohibit_break_after = true;
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