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( ...@@ -1141,8 +1141,8 @@ NGBoxFragmentPainter::MoveTo NGBoxFragmentPainter::PaintBoxItem(
return kDontSkipChildren; return kDontSkipChildren;
} }
// TODO(kojii): Implement. NGInlineBoxFragmentPainter(item, *child_fragment)
// NGInlineBoxFragmentPainter(*child).Paint(paint_info, paint_offset); .Paint(paint_info, paint_offset);
return kDontSkipChildren; return kDontSkipChildren;
} }
......
...@@ -209,8 +209,8 @@ inline NGBoxFragmentPainter::NGBoxFragmentPainter( ...@@ -209,8 +209,8 @@ inline NGBoxFragmentPainter::NGBoxFragmentPainter(
DCHECK(box.IsBox() || box.IsRenderedLegend()); DCHECK(box.IsBox() || box.IsRenderedLegend());
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
if (box.IsInlineBox()) { if (box.IsInlineBox()) {
DCHECK(paint_fragment); if (paint_fragment)
DCHECK_EQ(&paint_fragment->PhysicalFragment(), &box); DCHECK_EQ(&paint_fragment->PhysicalFragment(), &box);
} else if (box.ChildrenInline()) { } else if (box.ChildrenInline()) {
// If no children, there maybe or may not be NGPaintFragment. // If no children, there maybe or may not be NGPaintFragment.
// TODO(kojii): To be investigated if this correct or should be fixed. // TODO(kojii): To be investigated if this correct or should be fixed.
......
...@@ -19,6 +19,25 @@ ...@@ -19,6 +19,25 @@
namespace blink { 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 { const NGBorderEdges NGInlineBoxFragmentPainter::BorderEdges() const {
if (border_edges_.has_value()) if (border_edges_.has_value())
return *border_edges_; return *border_edges_;
...@@ -30,11 +49,14 @@ const NGBorderEdges NGInlineBoxFragmentPainter::BorderEdges() const { ...@@ -30,11 +49,14 @@ const NGBorderEdges NGInlineBoxFragmentPainter::BorderEdges() const {
void NGInlineBoxFragmentPainter::Paint(const PaintInfo& paint_info, void NGInlineBoxFragmentPainter::Paint(const PaintInfo& paint_info,
const PhysicalOffset& paint_offset) { const PhysicalOffset& paint_offset) {
const PhysicalOffset adjusted_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) if (paint_info.phase == PaintPhase::kForeground)
PaintBackgroundBorderShadow(paint_info, adjusted_paint_offset); 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; bool suppress_box_decoration_background = true;
box_painter.PaintObject(paint_info, adjusted_paint_offset, box_painter.PaintObject(paint_info, adjusted_paint_offset,
suppress_box_decoration_background); suppress_box_decoration_background);
...@@ -53,36 +75,38 @@ void NGInlineBoxFragmentPainterBase::PaintBackgroundBorderShadow( ...@@ -53,36 +75,38 @@ void NGInlineBoxFragmentPainterBase::PaintBackgroundBorderShadow(
// we do for LayoutObject. Querying Style each time is too costly. // we do for LayoutObject. Querying Style each time is too costly.
bool should_paint_box_decoration_background = bool should_paint_box_decoration_background =
inline_box_fragment_.GetLayoutObject()->HasBoxDecorationBackground() || inline_box_fragment_.GetLayoutObject()->HasBoxDecorationBackground() ||
inline_box_fragment_.PhysicalFragment().UsesFirstLineStyle(); inline_box_fragment_.UsesFirstLineStyle();
if (!should_paint_box_decoration_background) if (!should_paint_box_decoration_background)
return; return;
const DisplayItemClient& display_item_client = GetDisplayItemClient();
if (DrawingRecorder::UseCachedDrawingIfPossible( if (DrawingRecorder::UseCachedDrawingIfPossible(
paint_info.context, inline_box_fragment_, paint_info.context, display_item_client,
DisplayItem::kBoxDecorationBackground)) DisplayItem::kBoxDecorationBackground))
return; return;
DrawingRecorder recorder(paint_info.context, inline_box_fragment_, DrawingRecorder recorder(paint_info.context, display_item_client,
DisplayItem::kBoxDecorationBackground); DisplayItem::kBoxDecorationBackground);
PhysicalRect frame_rect = inline_box_fragment_.PhysicalFragment().LocalRect(); PhysicalRect frame_rect = inline_box_fragment_.LocalRect();
PhysicalOffset adjusted_paint_offset = paint_offset; PhysicalOffset adjusted_paint_offset = paint_offset;
PhysicalRect adjusted_frame_rect(adjusted_paint_offset, frame_rect.size); PhysicalRect adjusted_frame_rect(adjusted_paint_offset, frame_rect.size);
NGPaintFragment::FragmentRange fragments = DCHECK(inline_box_fragment_.GetLayoutObject());
inline_box_fragment_.InlineFragmentsFor( const LayoutObject& layout_object = *inline_box_fragment_.GetLayoutObject();
inline_box_fragment_.GetLayoutObject());
NGPaintFragment::FragmentRange::iterator iter = fragments.begin();
DCHECK(iter != fragments.end());
bool object_has_multiple_boxes = 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. // TODO(eae): Switch to LayoutNG version of BackgroundImageGeometry.
BackgroundImageGeometry geometry(*static_cast<const LayoutBoxModelObject*>( BackgroundImageGeometry geometry(*static_cast<const LayoutBoxModelObject*>(
inline_box_fragment_.GetLayoutObject())); 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(); const NGBorderEdges& border_edges = BorderEdges();
PaintBoxDecorationBackground(box_painter, paint_info, paint_offset, PaintBoxDecorationBackground(box_painter, paint_info, paint_offset,
adjusted_frame_rect, geometry, adjusted_frame_rect, geometry,
...@@ -94,20 +118,20 @@ void NGLineBoxFragmentPainter::PaintBackgroundBorderShadow( ...@@ -94,20 +118,20 @@ void NGLineBoxFragmentPainter::PaintBackgroundBorderShadow(
const PaintInfo& paint_info, const PaintInfo& paint_info,
const PhysicalOffset& paint_offset) { const PhysicalOffset& paint_offset) {
DCHECK_EQ(paint_info.phase, PaintPhase::kForeground); DCHECK_EQ(paint_info.phase, PaintPhase::kForeground);
DCHECK_EQ(inline_box_fragment_.PhysicalFragment().Type(), DCHECK_EQ(inline_box_fragment_.Type(), NGPhysicalFragment::kFragmentLineBox);
NGPhysicalFragment::kFragmentLineBox); DCHECK(NeedsPaint(inline_box_fragment_));
DCHECK(NeedsPaint(inline_box_fragment_.PhysicalFragment()));
if (line_style_ == style_ || if (line_style_ == style_ ||
line_style_.Visibility() != EVisibility::kVisible) line_style_.Visibility() != EVisibility::kVisible)
return; return;
const DisplayItemClient& display_item_client = GetDisplayItemClient();
if (DrawingRecorder::UseCachedDrawingIfPossible( if (DrawingRecorder::UseCachedDrawingIfPossible(
paint_info.context, inline_box_fragment_, paint_info.context, display_item_client,
DisplayItem::kBoxDecorationBackground)) DisplayItem::kBoxDecorationBackground))
return; return;
DrawingRecorder recorder(paint_info.context, inline_box_fragment_, DrawingRecorder recorder(paint_info.context, display_item_client,
DisplayItem::kBoxDecorationBackground); DisplayItem::kBoxDecorationBackground);
// Compute the content box for the `::first-line` box. It's different from // Compute the content box for the `::first-line` box. It's different from
...@@ -147,14 +171,14 @@ void NGInlineBoxFragmentPainterBase::ComputeFragmentOffsetOnLine( ...@@ -147,14 +171,14 @@ void NGInlineBoxFragmentPainterBase::ComputeFragmentOffsetOnLine(
LayoutUnit* total_width) const { LayoutUnit* total_width) const {
WritingMode writing_mode = inline_box_fragment_.Style().GetWritingMode(); WritingMode writing_mode = inline_box_fragment_.Style().GetWritingMode();
NGPaintFragment::FragmentRange fragments = NGPaintFragment::FragmentRange fragments =
inline_box_fragment_.InlineFragmentsFor( inline_box_paint_fragment_->InlineFragmentsFor(
inline_box_fragment_.GetLayoutObject()); inline_box_fragment_.GetLayoutObject());
LayoutUnit before; LayoutUnit before;
LayoutUnit after; LayoutUnit after;
bool before_self = true; bool before_self = true;
for (auto iter = fragments.begin(); iter != fragments.end(); ++iter) { for (auto iter = fragments.begin(); iter != fragments.end(); ++iter) {
if (*iter == &inline_box_fragment_) { if (*iter == inline_box_paint_fragment_) {
before_self = false; before_self = false;
continue; continue;
} }
...@@ -164,8 +188,7 @@ void NGInlineBoxFragmentPainterBase::ComputeFragmentOffsetOnLine( ...@@ -164,8 +188,7 @@ void NGInlineBoxFragmentPainterBase::ComputeFragmentOffsetOnLine(
after += NGFragment(writing_mode, iter->PhysicalFragment()).InlineSize(); after += NGFragment(writing_mode, iter->PhysicalFragment()).InlineSize();
} }
NGFragment logical_fragment(writing_mode, NGFragment logical_fragment(writing_mode, inline_box_fragment_);
inline_box_fragment_.PhysicalFragment());
*total_width = before + after + logical_fragment.InlineSize(); *total_width = before + after + logical_fragment.InlineSize();
// We're iterating over the fragments in physical order before so we need to // We're iterating over the fragments in physical order before so we need to
......
...@@ -28,6 +28,7 @@ class NGInlineBoxFragmentPainterBase : public InlineBoxPainterBase { ...@@ -28,6 +28,7 @@ class NGInlineBoxFragmentPainterBase : public InlineBoxPainterBase {
LayoutUnit* total_width) const; LayoutUnit* total_width) const;
protected: protected:
// Constructor for |NGPaintFragment|.
NGInlineBoxFragmentPainterBase(const NGPaintFragment& inline_box_fragment, NGInlineBoxFragmentPainterBase(const NGPaintFragment& inline_box_fragment,
const LayoutObject& layout_object, const LayoutObject& layout_object,
const ComputedStyle& style, const ComputedStyle& style,
...@@ -37,7 +38,32 @@ class NGInlineBoxFragmentPainterBase : public InlineBoxPainterBase { ...@@ -37,7 +38,32 @@ class NGInlineBoxFragmentPainterBase : public InlineBoxPainterBase {
layout_object.GeneratingNode(), layout_object.GeneratingNode(),
style, style,
line_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; const virtual NGBorderEdges BorderEdges() const = 0;
...@@ -58,7 +84,9 @@ class NGInlineBoxFragmentPainterBase : public InlineBoxPainterBase { ...@@ -58,7 +84,9 @@ class NGInlineBoxFragmentPainterBase : public InlineBoxPainterBase {
void PaintBackgroundBorderShadow(const PaintInfo&, void PaintBackgroundBorderShadow(const PaintInfo&,
const PhysicalOffset& paint_offset); 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 // Painter for LayoutNG inline box fragments. Delegates to NGBoxFragmentPainter
...@@ -67,6 +95,7 @@ class NGInlineBoxFragmentPainter : public NGInlineBoxFragmentPainterBase { ...@@ -67,6 +95,7 @@ class NGInlineBoxFragmentPainter : public NGInlineBoxFragmentPainterBase {
STACK_ALLOCATED(); STACK_ALLOCATED();
public: public:
// Constructor for |NGPaintFragment|.
NGInlineBoxFragmentPainter(const NGPaintFragment& inline_box_fragment) NGInlineBoxFragmentPainter(const NGPaintFragment& inline_box_fragment)
: NGInlineBoxFragmentPainterBase(inline_box_fragment, : NGInlineBoxFragmentPainterBase(inline_box_fragment,
*inline_box_fragment.GetLayoutObject(), *inline_box_fragment.GetLayoutObject(),
...@@ -78,12 +107,25 @@ class NGInlineBoxFragmentPainter : public NGInlineBoxFragmentPainterBase { ...@@ -78,12 +107,25 @@ class NGInlineBoxFragmentPainter : public NGInlineBoxFragmentPainterBase {
NGPhysicalFragment::NGBoxType::kInlineBox); 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); void Paint(const PaintInfo&, const PhysicalOffset& paint_offset);
private: private:
const NGPhysicalBoxFragment& PhysicalFragment() const { const NGPhysicalBoxFragment& PhysicalFragment() const {
return static_cast<const NGPhysicalBoxFragment&>( return static_cast<const NGPhysicalBoxFragment&>(inline_box_fragment_);
inline_box_fragment_.PhysicalFragment());
} }
const NGBorderEdges BorderEdges() const final; const NGBorderEdges BorderEdges() const final;
...@@ -136,8 +178,7 @@ class NGLineBoxFragmentPainter : public NGInlineBoxFragmentPainterBase { ...@@ -136,8 +178,7 @@ class NGLineBoxFragmentPainter : public NGInlineBoxFragmentPainterBase {
} }
const NGPhysicalLineBoxFragment& PhysicalFragment() const { const NGPhysicalLineBoxFragment& PhysicalFragment() const {
return static_cast<const NGPhysicalLineBoxFragment&>( return static_cast<const NGPhysicalLineBoxFragment&>(inline_box_fragment_);
inline_box_fragment_.PhysicalFragment());
} }
const NGBorderEdges BorderEdges() const final { return NGBorderEdges(); } 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