Commit 87f2e0fd authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

[NGFragmentItem] Paint inline boxes from NGFragmentItem

This is the initial patch to paint inline boxes from
|NGFragmentItem|. Not complete yet, and can't paint
line boxes yet, but supports simple cases.

Bug: 982194, 988015
Change-Id: I14da083edf0a839f57d7de8b28810f8d31d8b994
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1788427
Commit-Queue: Koji Ishii <kojii@chromium.org>
Reviewed-by: default avatarYoshifumi Inoue <yosin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#702992}
parent 3d54f3a1
......@@ -1141,8 +1141,8 @@ NGBoxFragmentPainter::MoveTo NGBoxFragmentPainter::PaintBoxItem(
return kDontSkipChildren;
}
// TODO(kojii): Implement.
// NGInlineBoxFragmentPainter(*child).Paint(paint_info, paint_offset);
NGInlineBoxFragmentPainter(item, *child_fragment)
.Paint(paint_info, paint_offset);
return kDontSkipChildren;
}
......
......@@ -209,7 +209,7 @@ inline NGBoxFragmentPainter::NGBoxFragmentPainter(
DCHECK(box.IsBox() || box.IsRenderedLegend());
#if DCHECK_IS_ON()
if (box.IsInlineBox()) {
DCHECK(paint_fragment);
if (paint_fragment)
DCHECK_EQ(&paint_fragment->PhysicalFragment(), &box);
} else if (box.ChildrenInline()) {
// If no children, there maybe or may not be NGPaintFragment.
......
......@@ -19,6 +19,25 @@
namespace blink {
namespace {
template <class Items>
bool HasMultipleItems(const Items items) {
auto iter = items.begin();
DCHECK(iter != items.end());
return iter != items.end() && ++iter != items.end();
}
inline bool HasMultiplePaintFragments(const LayoutObject& layout_object) {
return HasMultipleItems(NGPaintFragment::InlineFragmentsFor(&layout_object));
}
inline bool HasMultipleFragmentItems(const LayoutObject& layout_object) {
return HasMultipleItems(NGFragmentItem::ItemsFor(layout_object));
}
} // namespace
const NGBorderEdges NGInlineBoxFragmentPainter::BorderEdges() const {
if (border_edges_.has_value())
return *border_edges_;
......@@ -30,11 +49,14 @@ const NGBorderEdges NGInlineBoxFragmentPainter::BorderEdges() const {
void NGInlineBoxFragmentPainter::Paint(const PaintInfo& paint_info,
const PhysicalOffset& paint_offset) {
const PhysicalOffset adjusted_paint_offset =
paint_offset + inline_box_fragment_.Offset();
paint_offset + (inline_box_paint_fragment_
? inline_box_paint_fragment_->Offset()
: inline_box_item_->Offset());
if (paint_info.phase == PaintPhase::kForeground)
PaintBackgroundBorderShadow(paint_info, adjusted_paint_offset);
NGBoxFragmentPainter box_painter(inline_box_fragment_);
NGBoxFragmentPainter box_painter(PhysicalFragment(),
inline_box_paint_fragment_);
bool suppress_box_decoration_background = true;
box_painter.PaintObject(paint_info, adjusted_paint_offset,
suppress_box_decoration_background);
......@@ -53,36 +75,38 @@ void NGInlineBoxFragmentPainterBase::PaintBackgroundBorderShadow(
// we do for LayoutObject. Querying Style each time is too costly.
bool should_paint_box_decoration_background =
inline_box_fragment_.GetLayoutObject()->HasBoxDecorationBackground() ||
inline_box_fragment_.PhysicalFragment().UsesFirstLineStyle();
inline_box_fragment_.UsesFirstLineStyle();
if (!should_paint_box_decoration_background)
return;
const DisplayItemClient& display_item_client = GetDisplayItemClient();
if (DrawingRecorder::UseCachedDrawingIfPossible(
paint_info.context, inline_box_fragment_,
paint_info.context, display_item_client,
DisplayItem::kBoxDecorationBackground))
return;
DrawingRecorder recorder(paint_info.context, inline_box_fragment_,
DrawingRecorder recorder(paint_info.context, display_item_client,
DisplayItem::kBoxDecorationBackground);
PhysicalRect frame_rect = inline_box_fragment_.PhysicalFragment().LocalRect();
PhysicalRect frame_rect = inline_box_fragment_.LocalRect();
PhysicalOffset adjusted_paint_offset = paint_offset;
PhysicalRect adjusted_frame_rect(adjusted_paint_offset, frame_rect.size);
NGPaintFragment::FragmentRange fragments =
inline_box_fragment_.InlineFragmentsFor(
inline_box_fragment_.GetLayoutObject());
NGPaintFragment::FragmentRange::iterator iter = fragments.begin();
DCHECK(iter != fragments.end());
DCHECK(inline_box_fragment_.GetLayoutObject());
const LayoutObject& layout_object = *inline_box_fragment_.GetLayoutObject();
bool object_has_multiple_boxes =
iter != fragments.end() && ++iter != fragments.end();
inline_box_paint_fragment_ ? HasMultiplePaintFragments(layout_object)
: HasMultipleFragmentItems(layout_object);
// TODO(eae): Switch to LayoutNG version of BackgroundImageGeometry.
BackgroundImageGeometry geometry(*static_cast<const LayoutBoxModelObject*>(
inline_box_fragment_.GetLayoutObject()));
NGBoxFragmentPainter box_painter(inline_box_fragment_);
// TODO(kojii): not applicable for line box
NGBoxFragmentPainter box_painter(
To<NGPhysicalBoxFragment>(inline_box_fragment_),
inline_box_paint_fragment_);
const NGBorderEdges& border_edges = BorderEdges();
PaintBoxDecorationBackground(box_painter, paint_info, paint_offset,
adjusted_frame_rect, geometry,
......@@ -94,20 +118,20 @@ void NGLineBoxFragmentPainter::PaintBackgroundBorderShadow(
const PaintInfo& paint_info,
const PhysicalOffset& paint_offset) {
DCHECK_EQ(paint_info.phase, PaintPhase::kForeground);
DCHECK_EQ(inline_box_fragment_.PhysicalFragment().Type(),
NGPhysicalFragment::kFragmentLineBox);
DCHECK(NeedsPaint(inline_box_fragment_.PhysicalFragment()));
DCHECK_EQ(inline_box_fragment_.Type(), NGPhysicalFragment::kFragmentLineBox);
DCHECK(NeedsPaint(inline_box_fragment_));
if (line_style_ == style_ ||
line_style_.Visibility() != EVisibility::kVisible)
return;
const DisplayItemClient& display_item_client = GetDisplayItemClient();
if (DrawingRecorder::UseCachedDrawingIfPossible(
paint_info.context, inline_box_fragment_,
paint_info.context, display_item_client,
DisplayItem::kBoxDecorationBackground))
return;
DrawingRecorder recorder(paint_info.context, inline_box_fragment_,
DrawingRecorder recorder(paint_info.context, display_item_client,
DisplayItem::kBoxDecorationBackground);
// Compute the content box for the `::first-line` box. It's different from
......@@ -147,14 +171,14 @@ void NGInlineBoxFragmentPainterBase::ComputeFragmentOffsetOnLine(
LayoutUnit* total_width) const {
WritingMode writing_mode = inline_box_fragment_.Style().GetWritingMode();
NGPaintFragment::FragmentRange fragments =
inline_box_fragment_.InlineFragmentsFor(
inline_box_paint_fragment_->InlineFragmentsFor(
inline_box_fragment_.GetLayoutObject());
LayoutUnit before;
LayoutUnit after;
bool before_self = true;
for (auto iter = fragments.begin(); iter != fragments.end(); ++iter) {
if (*iter == &inline_box_fragment_) {
if (*iter == inline_box_paint_fragment_) {
before_self = false;
continue;
}
......@@ -164,8 +188,7 @@ void NGInlineBoxFragmentPainterBase::ComputeFragmentOffsetOnLine(
after += NGFragment(writing_mode, iter->PhysicalFragment()).InlineSize();
}
NGFragment logical_fragment(writing_mode,
inline_box_fragment_.PhysicalFragment());
NGFragment logical_fragment(writing_mode, inline_box_fragment_);
*total_width = before + after + logical_fragment.InlineSize();
// We're iterating over the fragments in physical order before so we need to
......
......@@ -28,6 +28,7 @@ class NGInlineBoxFragmentPainterBase : public InlineBoxPainterBase {
LayoutUnit* total_width) const;
protected:
// Constructor for |NGPaintFragment|.
NGInlineBoxFragmentPainterBase(const NGPaintFragment& inline_box_fragment,
const LayoutObject& layout_object,
const ComputedStyle& style,
......@@ -37,7 +38,32 @@ class NGInlineBoxFragmentPainterBase : public InlineBoxPainterBase {
layout_object.GeneratingNode(),
style,
line_style),
inline_box_fragment_(inline_box_fragment) {}
inline_box_fragment_(inline_box_fragment.PhysicalFragment()),
inline_box_paint_fragment_(&inline_box_fragment) {}
// Constructor for |NGFragmentItem|.
NGInlineBoxFragmentPainterBase(
const NGFragmentItem& inline_box_item,
const NGPhysicalBoxFragment& inline_box_fragment,
const LayoutObject& layout_object,
const ComputedStyle& style,
const ComputedStyle& line_style)
: InlineBoxPainterBase(layout_object,
&layout_object.GetDocument(),
layout_object.GeneratingNode(),
style,
line_style),
inline_box_fragment_(inline_box_fragment),
inline_box_item_(&inline_box_item) {
DCHECK_EQ(inline_box_item.BoxFragment(), &inline_box_fragment);
}
const DisplayItemClient& GetDisplayItemClient() const {
if (inline_box_paint_fragment_)
return *inline_box_paint_fragment_;
DCHECK(inline_box_item_);
return *inline_box_item_;
}
const virtual NGBorderEdges BorderEdges() const = 0;
......@@ -58,7 +84,9 @@ class NGInlineBoxFragmentPainterBase : public InlineBoxPainterBase {
void PaintBackgroundBorderShadow(const PaintInfo&,
const PhysicalOffset& paint_offset);
const NGPaintFragment& inline_box_fragment_;
const NGPhysicalFragment& inline_box_fragment_;
const NGPaintFragment* inline_box_paint_fragment_ = nullptr;
const NGFragmentItem* inline_box_item_ = nullptr;
};
// Painter for LayoutNG inline box fragments. Delegates to NGBoxFragmentPainter
......@@ -67,6 +95,7 @@ class NGInlineBoxFragmentPainter : public NGInlineBoxFragmentPainterBase {
STACK_ALLOCATED();
public:
// Constructor for |NGPaintFragment|.
NGInlineBoxFragmentPainter(const NGPaintFragment& inline_box_fragment)
: NGInlineBoxFragmentPainterBase(inline_box_fragment,
*inline_box_fragment.GetLayoutObject(),
......@@ -78,12 +107,25 @@ class NGInlineBoxFragmentPainter : public NGInlineBoxFragmentPainterBase {
NGPhysicalFragment::NGBoxType::kInlineBox);
}
// Constructor for |NGFragmentItem|.
NGInlineBoxFragmentPainter(const NGFragmentItem& inline_box_item,
const NGPhysicalBoxFragment& inline_box_fragment)
: NGInlineBoxFragmentPainterBase(inline_box_item,
inline_box_fragment,
*inline_box_fragment.GetLayoutObject(),
inline_box_fragment.Style(),
inline_box_fragment.Style()) {
DCHECK_EQ(inline_box_fragment.Type(),
NGPhysicalFragment::NGFragmentType::kFragmentBox);
DCHECK_EQ(inline_box_fragment.BoxType(),
NGPhysicalFragment::NGBoxType::kInlineBox);
}
void Paint(const PaintInfo&, const PhysicalOffset& paint_offset);
private:
const NGPhysicalBoxFragment& PhysicalFragment() const {
return static_cast<const NGPhysicalBoxFragment&>(
inline_box_fragment_.PhysicalFragment());
return static_cast<const NGPhysicalBoxFragment&>(inline_box_fragment_);
}
const NGBorderEdges BorderEdges() const final;
......@@ -136,8 +178,7 @@ class NGLineBoxFragmentPainter : public NGInlineBoxFragmentPainterBase {
}
const NGPhysicalLineBoxFragment& PhysicalFragment() const {
return static_cast<const NGPhysicalLineBoxFragment&>(
inline_box_fragment_.PhysicalFragment());
return static_cast<const NGPhysicalLineBoxFragment&>(inline_box_fragment_);
}
const NGBorderEdges BorderEdges() const final { return NGBorderEdges(); }
......
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