summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.cc
blob: 2cb44b83e61f4b1733b5f622045c1f1ef9291382 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h"

#include "third_party/blink/renderer/core/layout/ng/exclusions/ng_exclusion_space.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_item_result.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_logical_line_item.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_text_fragment_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h"
#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_positioned_float.h"

namespace blink {

void NGLineBoxFragmentBuilder::Reset() {
  children_.Shrink(0);
  child_break_tokens_.Shrink(0);
  inline_break_tokens_.Shrink(0);
  oof_positioned_candidates_.Shrink(0);
  unpositioned_list_marker_ = NGUnpositionedListMarker();

  size_.inline_size = LayoutUnit();
  metrics_ = NGLineHeightMetrics();
  line_box_type_ = NGPhysicalLineBoxFragment::kNormalLineBox;

  break_appeal_ = kBreakAppealPerfect;
  has_floating_descendants_for_paint_ = false;
  has_orthogonal_flow_roots_ = false;
  has_descendant_that_depends_on_percentage_block_size_ = false;
  has_block_fragmentation_ = false;
  may_have_descendant_above_block_start_ = false;
}

void NGLineBoxFragmentBuilder::SetIsEmptyLineBox() {
  line_box_type_ = NGPhysicalLineBoxFragment::kEmptyLineBox;
}

void NGLineBoxFragmentBuilder::AddChildren(NGLogicalLineItems& children) {
  children_.ReserveCapacity(children.size());

  for (auto& child : children) {
    if (child.layout_result) {
      DCHECK(!child.fragment);
      AddChild(child.layout_result->PhysicalFragment(), child.Offset());
      child.layout_result.reset();
    } else if (child.fragment) {
      AddChild(std::move(child.fragment), child.Offset());
      DCHECK(!child.fragment);
    } else if (child.out_of_flow_positioned_box) {
      AddOutOfFlowInlineChildCandidate(
          NGBlockNode(ToLayoutBox(child.out_of_flow_positioned_box)),
          child.Offset(), child.container_direction);
      child.out_of_flow_positioned_box = nullptr;
    }
  }
}

void NGLineBoxFragmentBuilder::PropagateChildrenData(
    NGLogicalLineItems& children) {
  for (unsigned index = 0; index < children.size(); ++index) {
    auto& child = children[index];
    if (child.layout_result) {
      DCHECK(!child.fragment);
      PropagateChildData(child.layout_result->PhysicalFragment(),
                         child.Offset());

      // Skip over any children, the information should have already been
      // propagated into this layout result.
      if (child.children_count)
        index += child.children_count - 1;

      continue;
    }
    if (child.out_of_flow_positioned_box) {
      AddOutOfFlowInlineChildCandidate(
          NGBlockNode(ToLayoutBox(child.out_of_flow_positioned_box)),
          child.Offset(), child.container_direction);
      child.out_of_flow_positioned_box = nullptr;
    }
  }

  DCHECK(oof_positioned_descendants_.IsEmpty());
  MoveOutOfFlowDescendantCandidatesToDescendants();
}

scoped_refptr<const NGLayoutResult>
NGLineBoxFragmentBuilder::ToLineBoxFragment() {
  writing_direction_.SetWritingMode(ToLineWritingMode(GetWritingMode()));

  if (!break_token_)
    break_token_ = NGInlineBreakToken::Create(node_);

  scoped_refptr<const NGPhysicalLineBoxFragment> fragment =
      NGPhysicalLineBoxFragment::Create(this);

  return base::AdoptRef(
      new NGLayoutResult(NGLayoutResult::NGLineBoxFragmentBuilderPassKey(),
                         std::move(fragment), this));
}

}  // namespace blink