Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(389)

Unified Diff: third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc

Issue 2772503004: [LayoutNG] Add NGInlineBreakToken and back of NGInlineLayoutAlgorithm (Closed)
Patch Set: Rename Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc
similarity index 83%
rename from third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc
rename to third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc
index be639f41da13b93bc0d9f8a3458f3f0f5cd322c5..d7b22d08960f76145277b364f8e77a87a5b2f346 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "core/layout/ng/ng_line_builder.h"
+#include "core/layout/ng/ng_inline_layout_algorithm.h"
#include "core/layout/BidiRun.h"
#include "core/layout/LayoutBlockFlow.h"
@@ -17,10 +17,12 @@
#include "core/layout/ng/ng_floating_object.h"
#include "core/layout/ng/ng_floats_utils.h"
#include "core/layout/ng/ng_fragment_builder.h"
+#include "core/layout/ng/ng_inline_break_token.h"
#include "core/layout/ng/ng_inline_node.h"
#include "core/layout/ng/ng_length_utils.h"
#include "core/layout/ng/ng_line_box_fragment.h"
#include "core/layout/ng/ng_line_box_fragment_builder.h"
+#include "core/layout/ng/ng_line_breaker.h"
#include "core/layout/ng/ng_space_utils.h"
#include "core/layout/ng/ng_text_fragment.h"
#include "core/layout/ng/ng_text_fragment_builder.h"
@@ -65,12 +67,13 @@ void PositionPendingFloats(const NGLogicalOffset& origin_point,
} // namespace
-NGLineBuilder::NGLineBuilder(NGInlineNode* inline_box,
- NGConstraintSpace* constraint_space)
+NGInlineLayoutAlgorithm::NGInlineLayoutAlgorithm(
+ NGInlineNode* inline_box,
+ NGConstraintSpace* constraint_space,
+ NGInlineBreakToken* break_token)
: inline_box_(inline_box),
constraint_space_(constraint_space),
container_builder_(NGPhysicalFragment::kFragmentBox, inline_box_),
- container_layout_result_(nullptr),
is_horizontal_writing_mode_(
blink::IsHorizontalWritingMode(constraint_space->WritingMode())),
space_builder_(constraint_space)
@@ -81,29 +84,34 @@ NGLineBuilder::NGLineBuilder(NGInlineNode* inline_box,
{
if (!is_horizontal_writing_mode_)
baseline_type_ = FontBaseline::IdeographicBaseline;
+ if (break_token)
+ Initialize(break_token->ItemIndex(), break_token->TextOffset());
+ else
+ Initialize(0, 0);
}
-bool NGLineBuilder::CanFitOnLine() const {
+bool NGInlineLayoutAlgorithm::CanFitOnLine() const {
LayoutUnit available_size = current_opportunity_.InlineSize();
if (available_size == NGSizeIndefinite)
return true;
return end_position_ <= available_size;
}
-bool NGLineBuilder::HasItems() const {
+bool NGInlineLayoutAlgorithm::HasItems() const {
return start_offset_ != end_offset_;
}
-bool NGLineBuilder::HasBreakOpportunity() const {
+bool NGInlineLayoutAlgorithm::HasBreakOpportunity() const {
return start_offset_ != last_break_opportunity_offset_;
}
-bool NGLineBuilder::HasItemsAfterLastBreakOpportunity() const {
+bool NGInlineLayoutAlgorithm::HasItemsAfterLastBreakOpportunity() const {
return last_break_opportunity_offset_ != end_offset_;
}
-void NGLineBuilder::SetStart(unsigned index, unsigned offset) {
- inline_box_->AssertOffset(index, offset);
+void NGInlineLayoutAlgorithm::Initialize(unsigned index, unsigned offset) {
+ if (index || offset)
+ inline_box_->AssertOffset(index, offset);
start_index_ = last_index_ = last_break_opportunity_index_ = index;
start_offset_ = end_offset_ = last_break_opportunity_offset_ = offset;
@@ -112,7 +120,7 @@ void NGLineBuilder::SetStart(unsigned index, unsigned offset) {
FindNextLayoutOpportunity();
}
-void NGLineBuilder::SetEnd(unsigned new_end_offset) {
+void NGInlineLayoutAlgorithm::SetEnd(unsigned new_end_offset) {
DCHECK_GT(new_end_offset, end_offset_);
const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
DCHECK_LE(new_end_offset, items.back().EndOffset());
@@ -144,9 +152,9 @@ void NGLineBuilder::SetEnd(unsigned new_end_offset) {
}
}
-void NGLineBuilder::SetEnd(unsigned index,
- unsigned new_end_offset,
- LayoutUnit inline_size_since_current_end) {
+void NGInlineLayoutAlgorithm::SetEnd(unsigned index,
+ unsigned new_end_offset,
+ LayoutUnit inline_size_since_current_end) {
const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
DCHECK_LE(new_end_offset, items.back().EndOffset());
@@ -169,38 +177,39 @@ void NGLineBuilder::SetEnd(unsigned index,
end_position_ += inline_size_since_current_end;
}
-void NGLineBuilder::SetBreakOpportunity() {
+void NGInlineLayoutAlgorithm::SetBreakOpportunity() {
last_break_opportunity_index_ = last_index_;
last_break_opportunity_offset_ = end_offset_;
last_break_opportunity_position_ = end_position_;
}
-void NGLineBuilder::SetStartOfHangables(unsigned offset) {
+void NGInlineLayoutAlgorithm::SetStartOfHangables(unsigned offset) {
// TODO(kojii): Implement.
}
-LayoutUnit NGLineBuilder::InlineSize(const NGLayoutInlineItem& item) {
+LayoutUnit NGInlineLayoutAlgorithm::InlineSize(const NGLayoutInlineItem& item) {
if (item.Type() == NGLayoutInlineItem::kAtomicInline)
return InlineSizeFromLayout(item);
return item.InlineSize();
}
-LayoutUnit NGLineBuilder::InlineSize(const NGLayoutInlineItem& item,
- unsigned start_offset,
- unsigned end_offset) {
+LayoutUnit NGInlineLayoutAlgorithm::InlineSize(const NGLayoutInlineItem& item,
+ unsigned start_offset,
+ unsigned end_offset) {
if (item.StartOffset() == start_offset && item.EndOffset() == end_offset)
return InlineSize(item);
return item.InlineSize(start_offset, end_offset);
}
-LayoutUnit NGLineBuilder::InlineSizeFromLayout(const NGLayoutInlineItem& item) {
+LayoutUnit NGInlineLayoutAlgorithm::InlineSizeFromLayout(
+ const NGLayoutInlineItem& item) {
return NGBoxFragment(ConstraintSpace().WritingMode(),
toNGPhysicalBoxFragment(
LayoutItem(item)->PhysicalFragment().get()))
.InlineSize();
}
-const NGLayoutResult* NGLineBuilder::LayoutItem(
+const NGLayoutResult* NGInlineLayoutAlgorithm::LayoutItem(
const NGLayoutInlineItem& item) {
// Returns the cached NGLayoutResult if available.
const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
@@ -225,13 +234,13 @@ const NGLayoutResult* NGLineBuilder::LayoutItem(
return layout_result->get();
}
-void NGLineBuilder::CreateLine() {
+bool NGInlineLayoutAlgorithm::CreateLine() {
if (HasItemsAfterLastBreakOpportunity())
SetBreakOpportunity();
- CreateLineUpToLastBreakOpportunity();
+ return CreateLineUpToLastBreakOpportunity();
}
-void NGLineBuilder::CreateLineUpToLastBreakOpportunity() {
+bool NGInlineLayoutAlgorithm::CreateLineUpToLastBreakOpportunity() {
const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
// Create a list of LineItemChunk from |start| and |last_break_opportunity|.
@@ -252,7 +261,8 @@ void NGLineBuilder::CreateLineUpToLastBreakOpportunity() {
if (inline_box_->IsBidiEnabled())
BidiReorder(&line_item_chunks);
- PlaceItems(line_item_chunks);
+ if (!PlaceItems(line_item_chunks))
+ return false;
// Prepare for the next line.
// Move |start| to |last_break_opportunity|, keeping items after
@@ -270,9 +280,11 @@ void NGLineBuilder::CreateLineUpToLastBreakOpportunity() {
GetOriginPointForFloats(ConstraintSpace(), content_size_);
PositionPendingFloats(origin_point, constraint_space_, &container_builder_);
FindNextLayoutOpportunity();
+ return true;
}
-void NGLineBuilder::BidiReorder(Vector<LineItemChunk, 32>* line_item_chunks) {
+void NGInlineLayoutAlgorithm::BidiReorder(
+ Vector<LineItemChunk, 32>* line_item_chunks) {
#if DCHECK_IS_ON()
DCHECK(!is_bidi_reordered_);
is_bidi_reordered_ = true;
@@ -307,10 +319,10 @@ void NGLineBuilder::BidiReorder(Vector<LineItemChunk, 32>* line_item_chunks) {
}
// TODO(glebl): Add the support of clearance for inline floats.
-void NGLineBuilder::LayoutAndPositionFloat(LayoutUnit end_position,
- LayoutObject* layout_object) {
- LayoutNGBlockFlow* block_flow = toLayoutNGBlockFlow(layout_object);
- NGBlockNode* node = new NGBlockNode(block_flow);
+void NGInlineLayoutAlgorithm::LayoutAndPositionFloat(
+ LayoutUnit end_position,
+ LayoutObject* layout_object) {
+ NGBlockNode* node = new NGBlockNode(layout_object);
RefPtr<NGConstraintSpace> float_space = CreateConstraintSpaceForFloat(
node->Style(), ConstraintSpace(), &space_builder_);
@@ -347,7 +359,7 @@ void NGLineBuilder::LayoutAndPositionFloat(LayoutUnit end_position,
}
}
-void NGLineBuilder::PlaceItems(
+bool NGInlineLayoutAlgorithm::PlaceItems(
const Vector<LineItemChunk, 32>& line_item_chunks) {
const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
@@ -425,8 +437,15 @@ void NGLineBuilder::PlaceItems(
}
if (line_box.Children().isEmpty()) {
- // The line was empty.
- return;
+ return true; // The line was empty.
+ }
+
+ // Check if the line fits into the constraint space in block direction.
+ LayoutUnit block_end = content_size_ + line_box.Metrics().LineHeight();
+ if (!container_builder_.Children().isEmpty() &&
+ ConstraintSpace().AvailableSize().block_size != NGSizeIndefinite &&
+ block_end > ConstraintSpace().AvailableSize().block_size) {
+ return false;
}
// If the estimated baseline position was not the actual position, move all
@@ -436,16 +455,27 @@ void NGLineBuilder::PlaceItems(
if (adjust_baseline)
line_box.MoveChildrenInBlockDirection(adjust_baseline);
+ // If there are more content to consume, create an unfinished break token.
+ if (last_break_opportunity_index_ != items.size() - 1 ||
+ last_break_opportunity_offset_ != inline_box_->Text().length()) {
+ line_box.SetBreakToken(
+ NGInlineBreakToken::create(inline_box_, last_break_opportunity_index_,
+ last_break_opportunity_offset_));
+ }
+
line_box.SetInlineSize(inline_size);
- NGLogicalOffset offset(LayoutUnit(), content_size_);
- container_builder_.AddChild(line_box.ToLineBoxFragment(), offset);
+ container_builder_.AddChild(line_box.ToLineBoxFragment(),
+ {LayoutUnit(), content_size_});
+
max_inline_size_ = std::max(max_inline_size_, inline_size);
- content_size_ += line_box.Metrics().LineHeight();
+ content_size_ = block_end;
+ return true;
}
-void NGLineBuilder::AccumulateUsedFonts(const NGLayoutInlineItem& item,
- const LineItemChunk& line_item_chunk,
- NGLineBoxFragmentBuilder* line_box) {
+void NGInlineLayoutAlgorithm::AccumulateUsedFonts(
+ const NGLayoutInlineItem& item,
+ const LineItemChunk& line_item_chunk,
+ NGLineBoxFragmentBuilder* line_box) {
HashSet<const SimpleFontData*> fallback_fonts;
item.GetFallbackFonts(&fallback_fonts, line_item_chunk.start_offset,
line_item_chunk.end_offset);
@@ -456,7 +486,7 @@ void NGLineBuilder::AccumulateUsedFonts(const NGLayoutInlineItem& item,
}
}
-LayoutUnit NGLineBuilder::PlaceAtomicInline(
+LayoutUnit NGInlineLayoutAlgorithm::PlaceAtomicInline(
const NGLayoutInlineItem& item,
LayoutUnit estimated_baseline,
NGLineBoxFragmentBuilder* line_box,
@@ -493,7 +523,7 @@ LayoutUnit NGLineBuilder::PlaceAtomicInline(
return block_start;
}
-void NGLineBuilder::FindNextLayoutOpportunity() {
+void NGInlineLayoutAlgorithm::FindNextLayoutOpportunity() {
NGLogicalOffset iter_offset = constraint_space_->BfcOffset();
iter_offset.block_offset += content_size_;
auto* iter = constraint_space_->LayoutOpportunityIterator(iter_offset);
@@ -502,9 +532,7 @@ void NGLineBuilder::FindNextLayoutOpportunity() {
current_opportunity_ = opportunity;
}
-RefPtr<NGLayoutResult> NGLineBuilder::CreateFragments() {
- DCHECK(!HasItems()) << "Must call CreateLine()";
-
+RefPtr<NGLayoutResult> NGInlineLayoutAlgorithm::CreateFragments() {
// TODO(kojii): Check if the line box width should be content or available.
// TODO(kojii): Need to take constraint_space into account.
container_builder_.SetInlineSize(max_inline_size_)
@@ -512,11 +540,33 @@ RefPtr<NGLayoutResult> NGLineBuilder::CreateFragments() {
.SetBlockSize(content_size_)
.SetBlockOverflow(content_size_);
- container_layout_result_ = container_builder_.ToBoxFragment();
- return container_layout_result_;
+ return container_builder_.ToBoxFragment();
+}
+
+RefPtr<NGLayoutResult> NGInlineLayoutAlgorithm::Layout() {
+ if (!inline_box_->Text().isEmpty())
+ NGLineBreaker().BreakLines(this, inline_box_->Text(), start_offset_);
+ return CreateFragments();
ikilpatrick 2017/03/24 20:58:05 can just inline this function now?
+}
+
+MinMaxContentSize NGInlineLayoutAlgorithm::ComputeMinMaxContentSizeByLayout() {
+ DCHECK(ConstraintSpace().AvailableSize().inline_size == LayoutUnit() &&
+ ConstraintSpace().AvailableSize().block_size == NGSizeIndefinite);
+ if (!inline_box_->Text().isEmpty())
+ NGLineBreaker().BreakLines(this, inline_box_->Text(), start_offset_);
+ MinMaxContentSize sizes;
+ sizes.min_content = MaxInlineSize();
+
+ // max-content is the width without any line wrapping.
+ // TODO(kojii): Implement hard breaks (<br> etc.) to break.
+ for (const auto& item : inline_box_->Items())
+ sizes.max_content += InlineSize(item);
+
+ return sizes;
}
-void NGLineBuilder::CopyFragmentDataToLayoutBlockFlow() {
+void NGInlineLayoutAlgorithm::CopyFragmentDataToLayoutBlockFlow(
+ NGLayoutResult* layout_result) {
LayoutBlockFlow* block = inline_box_->GetLayoutBlockFlow();
block->deleteLineBoxTree();
@@ -528,8 +578,8 @@ void NGLineBuilder::CopyFragmentDataToLayoutBlockFlow() {
fragments_for_bidi_runs.reserveInitialCapacity(items.size());
BidiRunList<BidiRun> bidi_runs;
LineInfo line_info;
- NGPhysicalBoxFragment* box_fragment = toNGPhysicalBoxFragment(
- container_layout_result_->PhysicalFragment().get());
+ NGPhysicalBoxFragment* box_fragment =
+ toNGPhysicalBoxFragment(layout_result->PhysicalFragment().get());
for (const auto& container_child : box_fragment->Children()) {
NGPhysicalLineBoxFragment* physical_line_box =
toNGPhysicalLineBoxFragment(container_child.get());

Powered by Google App Engine
This is Rietveld 408576698