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(
return base::AdoptRef(new NGLayoutResult(status, this));
}
// Finds FragmentPairs that define inline containing blocks.
// inline_container_fragments is a map whose keys specify which
// Finds InlineContainingBlockGeometry that define inline containing blocks.
// inline_containing_block_map is a map whose keys specify which
// inline containing blocks are required.
// Not finding a required block is an unexpected behavior (DCHECK).
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,
// and will break if this changes.
DCHECK_GE(InlineSize(), 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++) {
if (children_[i]->IsLineBox()) {
const NGPhysicalLineBoxFragment* linebox =
......@@ -227,29 +236,38 @@ void NGBoxFragmentBuilder::ComputeInlineContainerFragments(
continue;
LayoutObject* key = descendant.fragment->GetLayoutObject();
auto it = inline_container_fragments->find(key);
if (it != inline_container_fragments->end()) {
NGBoxFragmentBuilder::FragmentPair& value = it->value;
auto it = inline_containing_block_map->find(key);
if (it == inline_containing_block_map->end())
continue;
base::Optional<NGBoxFragmentBuilder::InlineContainingBlockGeometry>&
containing_block_geometry = it->value;
LineBoxPair* containing_lineboxes =
&containing_linebox_map.insert(key, LineBoxPair{nullptr, nullptr})
.stored_value->value;
// |DescendantsOf| returns the offset from the given fragment. Since
// we give it the line box, need to add the |linebox_offset|.
NGPhysicalOffsetRect fragment_rect(
linebox_offset + descendant.offset_to_container_box,
descendant.fragment->Size());
if (value.start_linebox_fragment == linebox) {
value.start_fragment_union_rect.Unite(fragment_rect);
} else if (!value.start_fragment) {
value.start_fragment = descendant.fragment.get();
value.start_fragment_union_rect = fragment_rect;
value.start_linebox_fragment = linebox;
if (containing_lineboxes->first == linebox) {
containing_block_geometry.value().start_fragment_union_rect.Unite(
fragment_rect);
} else if (!containing_lineboxes->first) {
containing_lineboxes->first = linebox;
containing_block_geometry = InlineContainingBlockGeometry{
fragment_rect, NGPhysicalOffsetRect()};
}
// Skip fragments within an empty line boxes for the end fragment.
if (value.end_linebox_fragment == linebox) {
value.end_fragment_union_rect.Unite(fragment_rect);
} else if (!value.end_fragment || !linebox->IsEmptyLineBox()) {
value.end_fragment = descendant.fragment.get();
value.end_fragment_union_rect = fragment_rect;
value.end_linebox_fragment = linebox;
}
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 @@
namespace blink {
class NGPhysicalFragment;
class NGPhysicalLineBoxFragment;
class CORE_EXPORT NGBoxFragmentBuilder final
: public NGContainerFragmentBuilder {
......@@ -206,26 +205,21 @@ class CORE_EXPORT NGBoxFragmentBuilder final
// type pair.
void AddBaseline(NGBaselineRequest, LayoutUnit);
// Inline containing block geometry is defined by two fragments:
// start and end. FragmentPair holds the information needed to compute
// inline containing block geometry wrt enclosing container block.
struct FragmentPair {
// Inline containing block geometry is defined by two rectangles defined
// by fragments generated by LayoutInline.
struct InlineContainingBlockGeometry {
DISALLOW_NEW();
// Linebox that contains start_fragment.
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.
// Union of fragments generated on the first line.
NGPhysicalOffsetRect start_fragment_union_rect;
// end_** variables are end fragment counterparts to start fragment.
const NGPhysicalLineBoxFragment* end_linebox_fragment;
const NGPhysicalFragment* end_fragment;
// Union of fragments generated on the last line.
NGPhysicalOffsetRect end_fragment_union_rect;
};
using InlineContainingBlockMap =
HashMap<const LayoutObject*,
base::Optional<InlineContainingBlockGeometry>>;
void ComputeInlineContainerFragments(
HashMap<const LayoutObject*, FragmentPair>* inline_container_fragments);
InlineContainingBlockMap* inline_container_fragments);
private:
scoped_refptr<NGLayoutResult> ToBoxFragment(WritingMode);
......
......@@ -102,15 +102,14 @@ NGOutOfFlowLayoutPart::GetContainingBlockInfo(
void NGOutOfFlowLayoutPart::ComputeInlineContainingBlocks(
Vector<NGOutOfFlowPositionedDescendant> descendants) {
HashMap<const LayoutObject*, NGBoxFragmentBuilder::FragmentPair>
inline_container_fragments;
NGBoxFragmentBuilder::InlineContainingBlockMap inline_container_fragments;
for (auto& descendant : descendants) {
if (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,
fragment_pair);
inline_geometry);
}
}
// Fetch start/end fragment info.
......@@ -128,7 +127,7 @@ void NGOutOfFlowLayoutPart::ComputeInlineContainingBlocks(
NGLogicalOffset 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.
// In this case, container builder does not have any fragments because
// ng layout algorithm did not run.
......@@ -211,7 +210,7 @@ void NGOutOfFlowLayoutPart::ComputeInlineContainingBlocks(
// Step 1 - determine the start_offset.
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(
container_writing_mode, container_direction,
container_builder_physical_size, start_rect.size);
......@@ -224,7 +223,7 @@ void NGOutOfFlowLayoutPart::ComputeInlineContainingBlocks(
// Step 2 - determine the end_offset.
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(
container_writing_mode, container_direction,
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