Commit 8fab3ddc authored by Aleks Totic's avatar Aleks Totic Committed by Commit Bot

[NGLayout] Cleanup computation of InlineContainingBlock

Bug: 740993
Change-Id: I8253d80703333beb4d252b585df910c71af43ab6
Reviewed-on: https://chromium-review.googlesource.com/c/1371019
Commit-Queue: Aleks Totic <atotic@chromium.org>
Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#616017}
parent 4f25d671
...@@ -202,17 +202,26 @@ scoped_refptr<NGLayoutResult> NGBoxFragmentBuilder::Abort( ...@@ -202,17 +202,26 @@ scoped_refptr<NGLayoutResult> NGBoxFragmentBuilder::Abort(
return base::AdoptRef(new NGLayoutResult(status, this)); return base::AdoptRef(new NGLayoutResult(status, this));
} }
// Finds FragmentPairs that define inline containing blocks. // Finds InlineContainingBlockGeometry that define inline containing blocks.
// inline_container_fragments is a map whose keys specify which // inline_containing_block_map is a map whose keys specify which
// inline containing blocks are required. // inline containing blocks are required.
// Not finding a required block is an unexpected behavior (DCHECK). // Not finding a required block is an unexpected behavior (DCHECK).
void NGBoxFragmentBuilder::ComputeInlineContainerFragments( void NGBoxFragmentBuilder::ComputeInlineContainerFragments(
HashMap<const LayoutObject*, FragmentPair>* inline_container_fragments) { InlineContainingBlockMap* inline_containing_block_map) {
if (!inline_containing_block_map->size())
return;
// This function has detailed knowledge of inline fragment tree structure, // This function has detailed knowledge of inline fragment tree structure,
// and will break if this changes. // and will break if this changes.
DCHECK_GE(InlineSize(), LayoutUnit()); DCHECK_GE(InlineSize(), LayoutUnit());
DCHECK_GE(BlockSize(), LayoutUnit()); DCHECK_GE(BlockSize(), LayoutUnit());
// std::pair.first points to start linebox fragment.
// std::pair.second points to ending linebox fragment.
using LineBoxPair = std::pair<const NGPhysicalLineBoxFragment*,
const NGPhysicalLineBoxFragment*>;
HashMap<const LayoutObject*, LineBoxPair> containing_linebox_map;
for (wtf_size_t i = 0; i < children_.size(); i++) { for (wtf_size_t i = 0; i < children_.size(); i++) {
if (children_[i]->IsLineBox()) { if (children_[i]->IsLineBox()) {
const NGPhysicalLineBoxFragment* linebox = const NGPhysicalLineBoxFragment* linebox =
...@@ -227,29 +236,38 @@ void NGBoxFragmentBuilder::ComputeInlineContainerFragments( ...@@ -227,29 +236,38 @@ void NGBoxFragmentBuilder::ComputeInlineContainerFragments(
continue; continue;
LayoutObject* key = descendant.fragment->GetLayoutObject(); LayoutObject* key = descendant.fragment->GetLayoutObject();
auto it = inline_container_fragments->find(key); auto it = inline_containing_block_map->find(key);
if (it != inline_container_fragments->end()) { if (it == inline_containing_block_map->end())
NGBoxFragmentBuilder::FragmentPair& value = it->value; continue;
// |DescendantsOf| returns the offset from the given fragment. Since base::Optional<NGBoxFragmentBuilder::InlineContainingBlockGeometry>&
// we give it the line box, need to add the |linebox_offset|. containing_block_geometry = it->value;
NGPhysicalOffsetRect fragment_rect(
linebox_offset + descendant.offset_to_container_box, LineBoxPair* containing_lineboxes =
descendant.fragment->Size()); &containing_linebox_map.insert(key, LineBoxPair{nullptr, nullptr})
if (value.start_linebox_fragment == linebox) { .stored_value->value;
value.start_fragment_union_rect.Unite(fragment_rect);
} else if (!value.start_fragment) { // |DescendantsOf| returns the offset from the given fragment. Since
value.start_fragment = descendant.fragment.get(); // we give it the line box, need to add the |linebox_offset|.
value.start_fragment_union_rect = fragment_rect; NGPhysicalOffsetRect fragment_rect(
value.start_linebox_fragment = linebox; linebox_offset + descendant.offset_to_container_box,
} descendant.fragment->Size());
// Skip fragments within an empty line boxes for the end fragment. if (containing_lineboxes->first == linebox) {
if (value.end_linebox_fragment == linebox) { containing_block_geometry.value().start_fragment_union_rect.Unite(
value.end_fragment_union_rect.Unite(fragment_rect); fragment_rect);
} else if (!value.end_fragment || !linebox->IsEmptyLineBox()) { } else if (!containing_lineboxes->first) {
value.end_fragment = descendant.fragment.get(); containing_lineboxes->first = linebox;
value.end_fragment_union_rect = fragment_rect; containing_block_geometry = InlineContainingBlockGeometry{
value.end_linebox_fragment = linebox; fragment_rect, NGPhysicalOffsetRect()};
} }
// Skip fragments within an empty line boxes for the end fragment.
if (containing_lineboxes->second == linebox) {
containing_block_geometry.value().end_fragment_union_rect.Unite(
fragment_rect);
} else if (!containing_lineboxes->second ||
!linebox->IsEmptyLineBox()) {
containing_lineboxes->second = linebox;
containing_block_geometry.value().end_fragment_union_rect =
fragment_rect;
} }
} }
} }
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
namespace blink { namespace blink {
class NGPhysicalFragment; class NGPhysicalFragment;
class NGPhysicalLineBoxFragment;
class CORE_EXPORT NGBoxFragmentBuilder final class CORE_EXPORT NGBoxFragmentBuilder final
: public NGContainerFragmentBuilder { : public NGContainerFragmentBuilder {
...@@ -206,26 +205,21 @@ class CORE_EXPORT NGBoxFragmentBuilder final ...@@ -206,26 +205,21 @@ class CORE_EXPORT NGBoxFragmentBuilder final
// type pair. // type pair.
void AddBaseline(NGBaselineRequest, LayoutUnit); void AddBaseline(NGBaselineRequest, LayoutUnit);
// Inline containing block geometry is defined by two fragments: // Inline containing block geometry is defined by two rectangles defined
// start and end. FragmentPair holds the information needed to compute // by fragments generated by LayoutInline.
// inline containing block geometry wrt enclosing container block. struct InlineContainingBlockGeometry {
struct FragmentPair {
DISALLOW_NEW(); DISALLOW_NEW();
// Linebox that contains start_fragment. // Union of fragments generated on the first line.
const NGPhysicalLineBoxFragment* start_linebox_fragment;
// Start fragment of inline containing block.
const NGPhysicalFragment* start_fragment;
// Start fragment rect combined with rectangles of all fragments
// generated by same Element as start_fragment.
NGPhysicalOffsetRect start_fragment_union_rect; NGPhysicalOffsetRect start_fragment_union_rect;
// end_** variables are end fragment counterparts to start fragment. // Union of fragments generated on the last line.
const NGPhysicalLineBoxFragment* end_linebox_fragment;
const NGPhysicalFragment* end_fragment;
NGPhysicalOffsetRect end_fragment_union_rect; NGPhysicalOffsetRect end_fragment_union_rect;
}; };
using InlineContainingBlockMap =
HashMap<const LayoutObject*,
base::Optional<InlineContainingBlockGeometry>>;
void ComputeInlineContainerFragments( void ComputeInlineContainerFragments(
HashMap<const LayoutObject*, FragmentPair>* inline_container_fragments); InlineContainingBlockMap* inline_container_fragments);
private: private:
scoped_refptr<NGLayoutResult> ToBoxFragment(WritingMode); scoped_refptr<NGLayoutResult> ToBoxFragment(WritingMode);
......
...@@ -102,15 +102,14 @@ NGOutOfFlowLayoutPart::GetContainingBlockInfo( ...@@ -102,15 +102,14 @@ NGOutOfFlowLayoutPart::GetContainingBlockInfo(
void NGOutOfFlowLayoutPart::ComputeInlineContainingBlocks( void NGOutOfFlowLayoutPart::ComputeInlineContainingBlocks(
Vector<NGOutOfFlowPositionedDescendant> descendants) { Vector<NGOutOfFlowPositionedDescendant> descendants) {
HashMap<const LayoutObject*, NGBoxFragmentBuilder::FragmentPair> NGBoxFragmentBuilder::InlineContainingBlockMap inline_container_fragments;
inline_container_fragments;
for (auto& descendant : descendants) { for (auto& descendant : descendants) {
if (descendant.inline_container && if (descendant.inline_container &&
!inline_container_fragments.Contains(descendant.inline_container)) { !inline_container_fragments.Contains(descendant.inline_container)) {
NGBoxFragmentBuilder::FragmentPair fragment_pair = {}; NGBoxFragmentBuilder::InlineContainingBlockGeometry inline_geometry = {};
inline_container_fragments.insert(descendant.inline_container, inline_container_fragments.insert(descendant.inline_container,
fragment_pair); inline_geometry);
} }
} }
// Fetch start/end fragment info. // Fetch start/end fragment info.
...@@ -128,7 +127,7 @@ void NGOutOfFlowLayoutPart::ComputeInlineContainingBlocks( ...@@ -128,7 +127,7 @@ void NGOutOfFlowLayoutPart::ComputeInlineContainingBlocks(
NGLogicalOffset container_offset; NGLogicalOffset container_offset;
NGPhysicalOffset physical_container_offset; NGPhysicalOffset physical_container_offset;
if (!block_info.value.start_fragment) { if (!block_info.value.has_value()) {
// This happens when Legacy block is the default container. // This happens when Legacy block is the default container.
// In this case, container builder does not have any fragments because // In this case, container builder does not have any fragments because
// ng layout algorithm did not run. // ng layout algorithm did not run.
...@@ -211,7 +210,7 @@ void NGOutOfFlowLayoutPart::ComputeInlineContainingBlocks( ...@@ -211,7 +210,7 @@ void NGOutOfFlowLayoutPart::ComputeInlineContainingBlocks(
// Step 1 - determine the start_offset. // Step 1 - determine the start_offset.
const NGPhysicalOffsetRect& start_rect = const NGPhysicalOffsetRect& start_rect =
block_info.value.start_fragment_union_rect; block_info.value.value().start_fragment_union_rect;
NGLogicalOffset start_offset = start_rect.offset.ConvertToLogical( NGLogicalOffset start_offset = start_rect.offset.ConvertToLogical(
container_writing_mode, container_direction, container_writing_mode, container_direction,
container_builder_physical_size, start_rect.size); container_builder_physical_size, start_rect.size);
...@@ -224,7 +223,7 @@ void NGOutOfFlowLayoutPart::ComputeInlineContainingBlocks( ...@@ -224,7 +223,7 @@ void NGOutOfFlowLayoutPart::ComputeInlineContainingBlocks(
// Step 2 - determine the end_offset. // Step 2 - determine the end_offset.
const NGPhysicalOffsetRect& end_rect = const NGPhysicalOffsetRect& end_rect =
block_info.value.end_fragment_union_rect; block_info.value.value().end_fragment_union_rect;
NGLogicalOffset end_offset = end_rect.offset.ConvertToLogical( NGLogicalOffset end_offset = end_rect.offset.ConvertToLogical(
container_writing_mode, container_direction, container_writing_mode, container_direction,
container_builder_physical_size, end_rect.size); container_builder_physical_size, end_rect.size);
......
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