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

[LayoutNG] Add NGPhysicalLineBoxFragment::IsEmptyLineBox()

This patch adds IsEmptyLineBox() function that returns
whethe the line box is "empty", or "certain zero-height
line box" as defined in CSS2[1] or not, and change where
we used to determine it by checking if the number of children
is 0.

[1] https://drafts.csswg.org/css2/visuren.html#phantom-line-box

Bug: 636993, 903578
Change-Id: I2b9961e1ecb743063238b39a3a5be53f15ffce8c
Reviewed-on: https://chromium-review.googlesource.com/c/1332972Reviewed-by: default avatarAleks Totic <atotic@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#608419}
parent 47f35a31
...@@ -356,8 +356,10 @@ void NGInlineLayoutAlgorithm::CreateLine(NGLineInfo* line_info, ...@@ -356,8 +356,10 @@ void NGInlineLayoutAlgorithm::CreateLine(NGLineInfo* line_info,
// Even if we have something in-flow, it may just be empty items that // Even if we have something in-flow, it may just be empty items that
// shouldn't trigger creation of a line. Exit now if that's the case. // shouldn't trigger creation of a line. Exit now if that's the case.
if (line_info->IsEmptyLine()) if (line_info->IsEmptyLine()) {
container_builder_.SetIsEmptyLineBox();
return; return;
}
DCHECK(!line_box_metrics.IsEmpty()); DCHECK(!line_box_metrics.IsEmpty());
......
...@@ -17,10 +17,15 @@ namespace blink { ...@@ -17,10 +17,15 @@ namespace blink {
void NGLineBoxFragmentBuilder::Reset() { void NGLineBoxFragmentBuilder::Reset() {
children_.resize(0); children_.resize(0);
offsets_.resize(0); offsets_.resize(0);
line_box_type_ = NGPhysicalLineBoxFragment::kNormalLineBox;
metrics_ = NGLineHeightMetrics(); metrics_ = NGLineHeightMetrics();
size_.inline_size = LayoutUnit(); size_.inline_size = LayoutUnit();
} }
void NGLineBoxFragmentBuilder::SetIsEmptyLineBox() {
line_box_type_ = NGPhysicalLineBoxFragment::kEmptyLineBox;
}
NGLineBoxFragmentBuilder::Child* NGLineBoxFragmentBuilder::Child*
NGLineBoxFragmentBuilder::ChildList::FirstInFlowChild() { NGLineBoxFragmentBuilder::ChildList::FirstInFlowChild() {
for (auto& child : *this) { for (auto& child : *this) {
...@@ -78,6 +83,11 @@ void NGLineBoxFragmentBuilder::AddChildren(ChildList& children) { ...@@ -78,6 +83,11 @@ void NGLineBoxFragmentBuilder::AddChildren(ChildList& children) {
} }
scoped_refptr<NGLayoutResult> NGLineBoxFragmentBuilder::ToLineBoxFragment() { scoped_refptr<NGLayoutResult> NGLineBoxFragmentBuilder::ToLineBoxFragment() {
#if DCHECK_IS_ON()
if (line_box_type_ == NGPhysicalLineBoxFragment::kEmptyLineBox)
DCHECK_EQ(children_.size(), 0u);
#endif
writing_mode_ = ToLineWritingMode(writing_mode_); writing_mode_ = ToLineWritingMode(writing_mode_);
if (!break_token_) if (!break_token_)
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_line_height_metrics.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_line_height_metrics.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h" #include "third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h" #include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
#include "third_party/blink/renderer/core/layout/ng/ng_positioned_float.h" #include "third_party/blink/renderer/core/layout/ng/ng_positioned_float.h"
...@@ -32,6 +33,7 @@ class CORE_EXPORT NGLineBoxFragmentBuilder final ...@@ -32,6 +33,7 @@ class CORE_EXPORT NGLineBoxFragmentBuilder final
TextDirection) TextDirection)
: NGContainerFragmentBuilder(style, writing_mode, TextDirection::kLtr), : NGContainerFragmentBuilder(style, writing_mode, TextDirection::kLtr),
node_(node), node_(node),
line_box_type_(NGPhysicalLineBoxFragment::kNormalLineBox),
base_direction_(TextDirection::kLtr) {} base_direction_(TextDirection::kLtr) {}
void Reset(); void Reset();
...@@ -40,6 +42,9 @@ class CORE_EXPORT NGLineBoxFragmentBuilder final ...@@ -40,6 +42,9 @@ class CORE_EXPORT NGLineBoxFragmentBuilder final
return metrics_.LineHeight().ClampNegativeToZero(); return metrics_.LineHeight().ClampNegativeToZero();
} }
// Mark this line box is an "empty" line box. See NGLineBoxType.
void SetIsEmptyLineBox();
const NGLineHeightMetrics& Metrics() const { return metrics_; } const NGLineHeightMetrics& Metrics() const { return metrics_; }
void SetMetrics(const NGLineHeightMetrics& metrics) { metrics_ = metrics; } void SetMetrics(const NGLineHeightMetrics& metrics) { metrics_ = metrics; }
...@@ -204,6 +209,7 @@ class CORE_EXPORT NGLineBoxFragmentBuilder final ...@@ -204,6 +209,7 @@ class CORE_EXPORT NGLineBoxFragmentBuilder final
NGLineHeightMetrics metrics_; NGLineHeightMetrics metrics_;
Vector<NGPositionedFloat> positioned_floats_; Vector<NGPositionedFloat> positioned_floats_;
NGPhysicalLineBoxFragment::NGLineBoxType line_box_type_;
TextDirection base_direction_; TextDirection base_direction_;
friend class NGLayoutResult; friend class NGLayoutResult;
......
...@@ -45,7 +45,7 @@ NGPhysicalLineBoxFragment::NGPhysicalLineBoxFragment( ...@@ -45,7 +45,7 @@ NGPhysicalLineBoxFragment::NGPhysicalLineBoxFragment(
builder->GetWritingMode(), builder->GetWritingMode(),
children_, children_,
kFragmentLineBox, kFragmentLineBox,
0), builder->line_box_type_),
metrics_(builder->metrics_) { metrics_(builder->metrics_) {
style_ = std::move(builder->style_); style_ = std::move(builder->style_);
base_direction_ = static_cast<unsigned>(builder->base_direction_); base_direction_ = static_cast<unsigned>(builder->base_direction_);
......
...@@ -17,6 +17,16 @@ class NGLineBoxFragmentBuilder; ...@@ -17,6 +17,16 @@ class NGLineBoxFragmentBuilder;
class CORE_EXPORT NGPhysicalLineBoxFragment final class CORE_EXPORT NGPhysicalLineBoxFragment final
: public NGPhysicalContainerFragment { : public NGPhysicalContainerFragment {
public: public:
enum NGLineBoxType {
kNormalLineBox,
// This is an "empty" line box, or "certain zero-height line boxes":
// https://drafts.csswg.org/css2/visuren.html#phantom-line-box
// that are ignored for margin collapsing and for other purposes.
// https://drafts.csswg.org/css2/box.html#collapsing-margins
// Also see |NGInlineItem::IsEmptyItem|.
kEmptyLineBox
};
static scoped_refptr<const NGPhysicalLineBoxFragment> Create( static scoped_refptr<const NGPhysicalLineBoxFragment> Create(
NGLineBoxFragmentBuilder* builder); NGLineBoxFragmentBuilder* builder);
...@@ -25,6 +35,11 @@ class CORE_EXPORT NGPhysicalLineBoxFragment final ...@@ -25,6 +35,11 @@ class CORE_EXPORT NGPhysicalLineBoxFragment final
child.fragment->Release(); child.fragment->Release();
} }
NGLineBoxType LineBoxType() const {
return static_cast<NGLineBoxType>(sub_type_);
}
bool IsEmptyLineBox() const { return LineBoxType() == kEmptyLineBox; }
ChildLinkList Children() const final { ChildLinkList Children() const final {
return ChildLinkList(num_children_, &children_[0]); return ChildLinkList(num_children_, &children_[0]);
} }
......
...@@ -70,7 +70,7 @@ bool NGUnpositionedListMarker::AddToBox( ...@@ -70,7 +70,7 @@ bool NGUnpositionedListMarker::AddToBox(
// If this child is an empty line-box, the list marker should be aligned // If this child is an empty line-box, the list marker should be aligned
// with the next non-empty line box produced. (This can occur with floats // with the next non-empty line box produced. (This can occur with floats
// producing empty line-boxes). // producing empty line-boxes).
if (line_box.Children().IsEmpty() && !line_box.BreakToken()->IsFinished()) if (line_box.IsEmptyLineBox() && !line_box.BreakToken()->IsFinished())
return false; return false;
content_metrics = line_box.Metrics(); content_metrics = line_box.Metrics();
......
...@@ -2102,6 +2102,7 @@ LayoutUnit NGBlockLayoutAlgorithm::ComputeLineBoxBaselineOffset( ...@@ -2102,6 +2102,7 @@ LayoutUnit NGBlockLayoutAlgorithm::ComputeLineBoxBaselineOffset(
LayoutUnit line_box_block_offset) const { LayoutUnit line_box_block_offset) const {
NGLineHeightMetrics metrics = NGLineHeightMetrics metrics =
line_box.BaselineMetrics(request.BaselineType()); line_box.BaselineMetrics(request.BaselineType());
DCHECK(!metrics.IsEmpty());
// NGLineHeightMetrics is line-relative, which matches to the flow-relative // NGLineHeightMetrics is line-relative, which matches to the flow-relative
// unless this box is in flipped-lines writing-mode. // unless this box is in flipped-lines writing-mode.
...@@ -2133,9 +2134,9 @@ bool NGBlockLayoutAlgorithm::AddBaseline(const NGBaselineRequest& request, ...@@ -2133,9 +2134,9 @@ bool NGBlockLayoutAlgorithm::AddBaseline(const NGBaselineRequest& request,
const NGPhysicalLineBoxFragment* line_box = const NGPhysicalLineBoxFragment* line_box =
ToNGPhysicalLineBoxFragment(child); ToNGPhysicalLineBoxFragment(child);
// Skip over a line-box which is empty. These don't any baselines which // Skip over a line-box which is empty. These don't have any baselines which
// should be added. // should be added.
if (line_box->Children().IsEmpty()) if (line_box->IsEmptyLineBox())
return false; return false;
LayoutUnit offset = LayoutUnit offset =
......
...@@ -253,9 +253,9 @@ NGPhysicalFragment::NGPhysicalFragment(NGFragmentBuilder* builder, ...@@ -253,9 +253,9 @@ NGPhysicalFragment::NGPhysicalFragment(NGFragmentBuilder* builder,
break_token_(std::move(builder->break_token_)), break_token_(std::move(builder->break_token_)),
type_(type), type_(type),
sub_type_(sub_type), sub_type_(sub_type),
style_variant_((unsigned)builder->style_variant_),
is_fieldset_container_(false), is_fieldset_container_(false),
is_old_layout_root_(false), is_old_layout_root_(false) {}
style_variant_((unsigned)builder->style_variant_) {}
NGPhysicalFragment::NGPhysicalFragment(LayoutObject* layout_object, NGPhysicalFragment::NGPhysicalFragment(LayoutObject* layout_object,
NGStyleVariant style_variant, NGStyleVariant style_variant,
...@@ -268,9 +268,9 @@ NGPhysicalFragment::NGPhysicalFragment(LayoutObject* layout_object, ...@@ -268,9 +268,9 @@ NGPhysicalFragment::NGPhysicalFragment(LayoutObject* layout_object,
break_token_(std::move(break_token)), break_token_(std::move(break_token)),
type_(type), type_(type),
sub_type_(sub_type), sub_type_(sub_type),
style_variant_((unsigned)style_variant),
is_fieldset_container_(false), is_fieldset_container_(false),
is_old_layout_root_(false), is_old_layout_root_(false) {}
style_variant_((unsigned)style_variant) {}
// Keep the implementation of the destructor here, to avoid dependencies on // Keep the implementation of the destructor here, to avoid dependencies on
// ComputedStyle in the header file. // ComputedStyle in the header file.
......
...@@ -249,10 +249,7 @@ class CORE_EXPORT NGPhysicalFragment ...@@ -249,10 +249,7 @@ class CORE_EXPORT NGPhysicalFragment
scoped_refptr<NGBreakToken> break_token_; scoped_refptr<NGBreakToken> break_token_;
const unsigned type_ : 2; // NGFragmentType const unsigned type_ : 2; // NGFragmentType
const unsigned sub_type_ : 3; // Union of NGBoxType and NGTextType const unsigned sub_type_ : 3; // NGBoxType, NGTextType, or NGLineBoxType
unsigned is_fieldset_container_ : 1;
unsigned is_old_layout_root_ : 1;
unsigned border_edge_ : 4; // NGBorderEdges::Physical
const unsigned style_variant_ : 2; // NGStyleVariant const unsigned style_variant_ : 2; // NGStyleVariant
// The following bitfield is only to be used by NGPhysicalLineBoxFragment // The following bitfield is only to be used by NGPhysicalLineBoxFragment
...@@ -262,6 +259,9 @@ class CORE_EXPORT NGPhysicalFragment ...@@ -262,6 +259,9 @@ class CORE_EXPORT NGPhysicalFragment
// The following bitfield is only to be used by NGPhysicalBoxFragment (it's // The following bitfield is only to be used by NGPhysicalBoxFragment (it's
// defined here to save memory, since that class has no bitfields). // defined here to save memory, since that class has no bitfields).
unsigned children_inline_ : 1; unsigned children_inline_ : 1;
unsigned is_fieldset_container_ : 1;
unsigned is_old_layout_root_ : 1;
unsigned border_edge_ : 4; // NGBorderEdges::Physical
// The following bitfield is only to be used by NGPhysicalTextFragment (it's // The following bitfield is only to be used by NGPhysicalTextFragment (it's
// defined here to save memory, since that class has no bitfields). // defined here to save memory, since that class has no bitfields).
......
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