Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(276)

Unified Diff: third_party/WebKit/Source/core/paint/NGBoxFragmentPainter.cpp

Issue 2842983002: [LayoutNG] Paint inlines from the fragment tree
Patch Set: Basic box painting support Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/paint/NGBoxFragmentPainter.cpp
diff --git a/third_party/WebKit/Source/core/paint/NGBoxFragmentPainter.cpp b/third_party/WebKit/Source/core/paint/NGBoxFragmentPainter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c84796e6398249f1020620abcd002bda92dabe20
--- /dev/null
+++ b/third_party/WebKit/Source/core/paint/NGBoxFragmentPainter.cpp
@@ -0,0 +1,620 @@
+// 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 "core/paint/NGBoxFragmentPainter.h"
+
+#include "core/layout/BackgroundBleedAvoidance.h"
+#include "core/layout/ng/inline/ng_physical_line_box_fragment.h"
+#include "core/layout/ng/inline/ng_physical_text_fragment.h"
+#include "core/layout/ng/ng_physical_box_fragment.h"
+#include "core/paint/BoxBorderPainter.h"
+#include "core/paint/BoxDecorationData.h"
+#include "core/paint/NGTextFragmentPainter.h"
+#include "core/paint/PaintInfo.h"
+#include "core/paint/PaintLayer.h"
+#include "core/paint/RoundedInnerRectClipper.h"
+#include "core/style/FillLayer.h"
+#include "platform/geometry/LayoutRectOutsets.h"
+#include "platform/graphics/GraphicsContextStateSaver.h"
+#include "platform/graphics/paint/DrawingRecorder.h"
+
+namespace blink {
+
+void NGBoxFragmentPainter::Paint(const PaintInfo& paint_info,
+ const LayoutPoint& paint_offset) {
+ PaintChildren(paint_info, paint_offset);
+}
+
+void NGBoxFragmentPainter::PaintChildren(const PaintInfo& paint_info,
+ const LayoutPoint& paint_offset) {
+ PaintInfo child_info(paint_info);
+ for (const auto& child : box_fragment_->Children()) {
+ if (child->Type() == NGPhysicalBoxFragment::kFragmentLineBox) {
+ const NGPhysicalLineBoxFragment* line_box_fragment =
+ ToNGPhysicalLineBoxFragment(child.Get());
+ PaintLineBox(line_box_fragment, child_info, paint_offset);
+ }
+ }
+}
+
+void NGBoxFragmentPainter::PaintLineBox(
+ const NGPhysicalLineBoxFragment* fragment,
+ const PaintInfo& paint_info,
+ const LayoutPoint& paint_offset) {
+ // TODO: Should this check if the line boxes intersects with the dirty rect
+ // like legacy layout or do we want to change the invalidation logic?
+
+ LayoutRect overflow_rect(box_fragment_->VisualOverflowRect());
+ overflow_rect.MoveBy(paint_offset);
+
+ // TODO(eae): Should this go here, in ::Paint or in the NGTextFragmentPainter
+ // class?
+ DrawingRecorder recorder(
+ paint_info.context, *fragment,
+ DisplayItem::PaintPhaseToDrawingType(paint_info.phase),
+ PixelSnappedIntRect(overflow_rect));
+
+ for (const auto& child : fragment->Children()) {
+ if (child->Type() == NGPhysicalBoxFragment::kFragmentLineBox) {
+ CHECK(false);
+ } else if (child->Type() == NGPhysicalBoxFragment::kFragmentText) {
+ const NGPhysicalTextFragment* text_fragment =
+ ToNGPhysicalTextFragment(child.Get());
+ NGTextFragmentPainter(text_fragment)
+ .Paint(GetDocument(), paint_info, paint_offset);
+ }
+ }
+}
+
+bool IsPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
+ const NGPhysicalFragment* fragment,
+ const PaintInfo& paint_info) {
+ // TODO(eae): Implement. Will require changing the type of
+ // PaintInfo::paint_container_ or using the NGBoxFragment container object.
+ return false;
+}
+
+void NGBoxFragmentPainter::PaintBoxDecorationBackground(
+ const PaintInfo& paint_info,
+ const LayoutPoint& paint_offset) {
+ LayoutRect paint_rect;
+ if (IsPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
+ box_fragment_, paint_info)) {
+ // For the case where we are painting the background into the scrolling
+ // contents layer of a composited scroller we need to include the entire
+ // overflow rect.
+
+ // The background painting code assumes that the borders are part of the
+ // paintRect so we expand the paintRect by the border size when painting the
+ // background into the scrolling contents layer.
+ } else {
+ // TODO(eae): We need better converters for ng geometry types. Long term we
+ // probably want to change the paint code to take NGPhysical* but that is a
+ // much bigger change.
+ NGPhysicalSize size = box_fragment_->Size();
+ paint_rect = LayoutRect(LayoutPoint(), LayoutSize(size.width, size.height));
+ }
+
+ paint_rect.MoveBy(paint_offset);
+ PaintBoxDecorationBackgroundWithRect(paint_info, paint_offset, paint_rect);
+}
+
+void NGBoxFragmentPainter::PaintBoxDecorationBackgroundWithRect(
+ const PaintInfo& paint_info,
+ const LayoutPoint& paint_offset,
+ const LayoutRect& paint_rect) {
+ bool painting_overflow_contents =
+ IsPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
+ box_fragment_, paint_info);
+ const ComputedStyle& style = box_fragment_->Style();
+
+ // TODO(eae): Implement support for painting overflow contents.
+ const DisplayItemClient& display_item_client = *box_fragment_;
+ if (DrawingRecorder::UseCachedDrawingIfPossible(
+ paint_info.context, display_item_client,
+ DisplayItem::kBoxDecorationBackground))
+ return;
+
+ DrawingRecorder recorder(
+ paint_info.context, display_item_client,
+ DisplayItem::kBoxDecorationBackground,
+ FloatRect(BoundsForDrawingRecorder(paint_info, paint_offset)));
+ BoxDecorationData box_decoration_data(box_fragment_);
+ GraphicsContextStateSaver state_saver(paint_info.context, false);
+
+ if (!painting_overflow_contents) {
+ // FIXME: Should eventually give the theme control over whether the box
+ // shadow should paint, since controls could have custom shadows of their
+ // own.
+ PaintNormalBoxShadow(paint_info, paint_rect, style);
+
+ if (BleedAvoidanceIsClipping(box_decoration_data.bleed_avoidance)) {
+ state_saver.Save();
+ FloatRoundedRect border = style.GetRoundedBorderFor(paint_rect);
+ paint_info.context.ClipRoundedRect(border);
+
+ if (box_decoration_data.bleed_avoidance == kBackgroundBleedClipLayer)
+ paint_info.context.BeginLayer();
+ }
+ }
+
+ // TODO(layout-dev): Support theme painting.
+
+ // TODO(eae): Support SkipRootBackground painting.
+ bool should_paint_background = true;
+ if (should_paint_background) {
+ PaintBackground(paint_info, paint_rect,
+ box_decoration_data.background_color,
+ box_decoration_data.bleed_avoidance);
+ }
+
+ if (!painting_overflow_contents) {
+ PaintInsetBoxShadow(paint_info, paint_rect, style);
+
+ if (box_decoration_data.has_border_decoration) {
+ PaintBorder(box_fragment_, paint_info, paint_rect, style,
+ box_decoration_data.bleed_avoidance);
+ }
+ }
+
+ if (box_decoration_data.bleed_avoidance == kBackgroundBleedClipLayer)
+ paint_info.context.EndLayer();
+}
+
+void NGBoxFragmentPainter::PaintBackground(
+ const PaintInfo& paint_info,
+ const LayoutRect& paint_rect,
+ const Color& background_color,
+ BackgroundBleedAvoidance bleed_avoidance) {
+ // if (layout_box_.IsDocumentElement())
+ // return;
+ // if (layout_box_.BackgroundStolenForBeingBody())
+ // return;
+ // if (layout_box_.BackgroundIsKnownToBeObscured())
+ // return;
+ PaintFillLayers(paint_info, background_color,
+ box_fragment_->Style().BackgroundLayers(), paint_rect,
+ bleed_avoidance);
+}
+
+void NGBoxFragmentPainter::PaintFillLayers(
+ const PaintInfo& paint_info,
+ const Color& c,
+ const FillLayer& fill_layer,
+ const LayoutRect& rect,
+ BackgroundBleedAvoidance avoidance,
+ SkBlendMode op,
+ const NGPhysicalFragment* bg_fragment) {
+ FillLayerOcclusionOutputList reversed_paint_list;
+ bool should_draw_background_in_separate_buffer =
+ CalculateFillLayerOcclusionCulling(reversed_paint_list, fill_layer,
+ GetDocument(), box_fragment_->Style());
+
+ // TODO(trchen): We can optimize out isolation group if we have a
+ // non-transparent background color and the bottom layer encloses all other
+ // layers.
+
+ GraphicsContext& context = paint_info.context;
+
+ if (should_draw_background_in_separate_buffer)
+ context.BeginLayer();
+
+ for (auto it = reversed_paint_list.rbegin(); it != reversed_paint_list.rend();
+ ++it) {
+ PaintFillLayer(box_fragment_, paint_info, c, **it, rect, avoidance, 0,
+ LayoutSize(), op, bg_fragment);
+ }
+
+ if (should_draw_background_in_separate_buffer)
+ context.EndLayer();
+}
+
+namespace {
+
+FloatRoundedRect GetBackgroundRoundedRect(const ComputedStyle& style,
+ const LayoutRect& border_rect,
+ bool has_line_box_sibling,
+ const LayoutSize& inline_box_size,
+ bool include_logical_left_edge,
+ bool include_logical_right_edge) {
+ FloatRoundedRect border = style.GetRoundedBorderFor(
+ border_rect, include_logical_left_edge, include_logical_right_edge);
+ if (has_line_box_sibling) {
+ FloatRoundedRect segment_border = style.GetRoundedBorderFor(
+ LayoutRect(LayoutPoint(), LayoutSize(FlooredIntSize(inline_box_size))),
+ include_logical_left_edge, include_logical_right_edge);
+ border.SetRadii(segment_border.GetRadii());
+ }
+ return border;
+}
+
+FloatRoundedRect BackgroundRoundedRectAdjustedForBleedAvoidance(
+ const ComputedStyle& style,
+ const LayoutRect& border_rect,
+ BackgroundBleedAvoidance bleed_avoidance,
+ bool has_line_box_sibling,
+ const LayoutSize& box_size,
+ bool include_logical_left_edge,
+ bool include_logical_right_edge) {
+ if (bleed_avoidance == kBackgroundBleedShrinkBackground) {
+ // Inset the background rect by a "safe" amount: 1/2 border-width for opaque
+ // border styles, 1/6 border-width for double borders.
+
+ // TODO(fmalita): we should be able to fold these parameters into
+ // BoxBorderInfo or BoxDecorationData and avoid calling getBorderEdgeInfo
+ // redundantly here.
+ BorderEdge edges[4];
+ style.GetBorderEdgeInfo(edges, include_logical_left_edge,
+ include_logical_right_edge);
+
+ // Use the most conservative inset to avoid mixed-style corner issues.
+ float fractional_inset = 1.0f / 2;
+ for (auto& edge : edges) {
+ if (edge.BorderStyle() == kBorderStyleDouble) {
+ fractional_inset = 1.0f / 6;
+ break;
+ }
+ }
+
+ FloatRectOutsets insets(-fractional_inset * edges[kBSTop].Width(),
+ -fractional_inset * edges[kBSRight].Width(),
+ -fractional_inset * edges[kBSBottom].Width(),
+ -fractional_inset * edges[kBSLeft].Width());
+
+ FloatRoundedRect background_rounded_rect = GetBackgroundRoundedRect(
+ style, border_rect, has_line_box_sibling, box_size,
+ include_logical_left_edge, include_logical_right_edge);
+ FloatRect inset_rect(background_rounded_rect.Rect());
+ inset_rect.Expand(insets);
+ FloatRoundedRect::Radii inset_radii(background_rounded_rect.GetRadii());
+ inset_radii.Shrink(-insets.Top(), -insets.Bottom(), -insets.Left(),
+ -insets.Right());
+ return FloatRoundedRect(inset_rect, inset_radii);
+ }
+
+ return GetBackgroundRoundedRect(style, border_rect, has_line_box_sibling,
+ box_size, include_logical_left_edge,
+ include_logical_right_edge);
+}
+
+struct FillLayerInfo {
+ STACK_ALLOCATED();
+
+ FillLayerInfo(const Document& doc,
+ const ComputedStyle& style,
+ bool has_overflow_clip,
+ Color bg_color,
+ const FillLayer& layer,
+ BackgroundBleedAvoidance bleed_avoidance,
+ const NGPhysicalFragment* box)
+ : image(layer.GetImage()),
+ color(bg_color),
+ include_left_edge(
+ box ? (box->BorderEdges() & NGPhysicalTextFragment::kLeftBorder)
+ : true),
+ include_right_edge(
+ box ? (box->BorderEdges() & NGPhysicalTextFragment::kRightBorder)
+ : true),
+ is_bottom_layer(!layer.Next()),
+ is_border_fill(layer.Clip() == kBorderFillBox),
+ is_clipped_with_local_scrolling(has_overflow_clip &&
+ layer.Attachment() ==
+ kLocalBackgroundAttachment) {
+ // When printing backgrounds is disabled or using economy mode,
+ // change existing background colors and images to a solid white background.
+ // If there's no bg color or image, leave it untouched to avoid affecting
+ // transparency. We don't try to avoid loading the background images,
+ // because this style flag is only set when printing, and at that point
+ // we've already loaded the background images anyway. (To avoid loading the
+ // background images we'd have to do this check when applying styles rather
+ // than while layout.)
+ if (BoxPainterBase::ShouldForceWhiteBackgroundForPrintEconomy(doc, style)) {
+ // Note that we can't reuse this variable below because the bgColor might
+ // be changed.
+ bool should_paint_background_color = is_bottom_layer && color.Alpha();
+ if (image || should_paint_background_color) {
+ color = Color::kWhite;
+ image = nullptr;
+ }
+ }
+
+ const bool has_rounded_border =
+ style.HasBorderRadius() && (include_left_edge || include_right_edge);
+ // BorderFillBox radius clipping is taken care of by
+ // BackgroundBleedClip{Only,Layer}
+ is_rounded_fill =
+ has_rounded_border &&
+ !(is_border_fill && BleedAvoidanceIsClipping(bleed_avoidance));
+
+ should_paint_image = image && image->CanRender();
+ should_paint_color =
+ is_bottom_layer && color.Alpha() &&
+ (!should_paint_image || !layer.ImageOccludesNextLayers(doc, style));
+ }
+
+ // FillLayerInfo is a temporary, stack-allocated container which cannot
+ // outlive the StyleImage. This would normally be a raw pointer, if not for
+ // the Oilpan tooling complaints.
+ Member<StyleImage> image;
+ Color color;
+
+ bool include_left_edge;
+ bool include_right_edge;
+ bool is_bottom_layer;
+ bool is_border_fill;
+ bool is_clipped_with_local_scrolling;
+ bool is_rounded_fill;
+
+ bool should_paint_image;
+ bool should_paint_color;
+};
+
+inline bool PaintFastBottomLayer(
+ const NGPhysicalBoxFragment* fragment,
+ const PaintInfo& paint_info,
+ const FillLayerInfo& info,
+ const FillLayer& layer,
+ const LayoutRect& rect,
+ BackgroundBleedAvoidance bleed_avoidance,
+ bool has_line_box_sibling,
+ const LayoutSize& box_size,
+ SkBlendMode op,
+ const NGPhysicalFragment* background_fragment
+ /*Optional<BackgroundImageGeometry>& geometry*/) {
+ // Painting a background image from an ancestor onto a cell is a complex case.
+ // if (obj.IsTableCell() && bg_fragment &&
+ // !bg_fragment->IsTableCell())
+ // return false;
+ // Complex cases not handled on the fast path.
+ // if (!info.is_bottom_layer || !info.is_border_fill ||
+ // info.is_clipped_with_local_scrolling)
+ // return false;
+
+ // Transparent layer, nothing to paint.
+ if (!info.should_paint_color && !info.should_paint_image)
+ return true;
+
+ // When the layer has an image, figure out whether it is covered by a single
+ // tile.
+ FloatRect image_tile;
+ if (info.should_paint_image) {
+ // TODO(layout-dev): Add support for background images.
+ return false;
+ }
+
+ // At this point we're committed to the fast path: the destination (r)rect
+ // fits within a single tile, and we can paint it using direct draw(R)Rect()
+ // calls.
+ GraphicsContext& context = paint_info.context;
+ FloatRoundedRect border =
+ info.is_rounded_fill
+ ? BackgroundRoundedRectAdjustedForBleedAvoidance(
+ fragment->Style(), rect, bleed_avoidance, has_line_box_sibling,
+ box_size, info.include_left_edge, info.include_right_edge)
+ : FloatRoundedRect(PixelSnappedIntRect(rect));
+
+ // Optional<RoundedInnerRectClipper> clipper;
+ // if (info.is_rounded_fill && !border.IsRenderable()) {
+ // When the rrect is not renderable, we resort to clipping.
+ // RoundedInnerRectClipper handles this case via discrete, corner-wise
+ // clipping.
+ // clipper.emplace(obj, paint_info, rect, border, kApplyToContext);
+ // border.SetRadii(FloatRoundedRect::Radii());
+ //}
+
+ // Paint the color if needed.
+ if (info.should_paint_color)
+ context.FillRoundedRect(border, info.color);
+
+ return true;
+}
+
+} // anonymous namespace
+
+void NGBoxFragmentPainter::PaintFillLayer(
+ const NGPhysicalBoxFragment* fragment,
+ const PaintInfo& paint_info,
+ const Color& color,
+ const FillLayer& bg_layer,
+ const LayoutRect& rect,
+ BackgroundBleedAvoidance avoidance,
+ const NGPhysicalFragment* box,
+ const LayoutSize& box_size,
+ SkBlendMode op,
+ const NGPhysicalFragment* bg_fragment) {
+ GraphicsContext& context = paint_info.context;
+ const ComputedStyle& style = fragment->Style();
+ if (rect.IsEmpty())
+ return;
+
+ const FillLayerInfo info(fragment->GetLayoutObject()->GetDocument(), style,
+ fragment->HasOverflowClip(), color, bg_layer,
+ avoidance, box);
+ // Optional<BackgroundImageGeometry> geometry;
+ // bool has_line_box_sibling = box && (box->NextLineBox() ||
+ // box->PrevLineBox());
+ bool has_line_box_sibling = false;
+
+ // Fast path for drawing simple color backgrounds.
+ if (PaintFastBottomLayer(fragment, paint_info, info, bg_layer, rect,
+ avoidance, has_line_box_sibling, box_size, op,
+ bg_fragment)) {
+ return;
+ }
+
+ NGPixelSnappedPhysicalBoxStrut borders = fragment->BorderWidths();
+ NGPhysicalBoxStrut paddings; // TODO(layout-dev): Implement
+
+ Optional<RoundedInnerRectClipper> clip_to_border;
+ if (info.is_rounded_fill) {
+ FloatRoundedRect border =
+ info.is_border_fill
+ ? BackgroundRoundedRectAdjustedForBleedAvoidance(
+ style, rect, avoidance, has_line_box_sibling, box_size,
+ info.include_left_edge, info.include_right_edge)
+ : GetBackgroundRoundedRect(style, rect, has_line_box_sibling,
+ box_size, info.include_left_edge,
+ info.include_right_edge);
+
+ // Clip to the padding or content boxes as necessary.
+ if (bg_layer.Clip() == kContentFillBox) {
+ // TODO(layout-dev): Do we need to include the padding here?
+ LayoutRectOutsets border_inset(
+ LayoutUnit(borders.top), LayoutUnit(borders.right),
+ LayoutUnit(borders.bottom), LayoutUnit(borders.left));
+ border = style.GetRoundedInnerBorderFor(
+ LayoutRect(border.Rect()), border_inset, info.include_left_edge,
+ info.include_right_edge);
+ } else if (bg_layer.Clip() == kPaddingFillBox) {
+ border = style.GetRoundedInnerBorderFor(LayoutRect(border.Rect()),
+ info.include_left_edge,
+ info.include_right_edge);
+ }
+
+ clip_to_border.emplace(*fragment, paint_info, rect, border,
+ kApplyToContext);
+ }
+
+ GraphicsContextStateSaver clip_with_scrolling_state_saver(
+ context, info.is_clipped_with_local_scrolling);
+ LayoutRect scrolled_paint_rect = rect;
+ if (info.is_clipped_with_local_scrolling &&
+ !IsPaintingBackgroundOfPaintContainerIntoScrollingContentsLayer(
+ fragment, paint_info)) {
+ // Clip to the overflow area.
+ // TODO(chrishtr): this should be pixel-snapped.
+ // TODO(layout-dev): We don't know the location...
+ // context.Clip(FloatRect(this_box.OverflowClipRect(rect.Location())));
+
+ // Adjust the paint rect to reflect a scrolled content box with borders at
+ // the ends.
+ // TODO(layout_dev): Support scrolling
+ // IntSize offset = this_box.ScrolledContentOffset();
+ // scrolled_paint_rect.Move(-offset);
+ // scrolled_paint_rect.SetWidth(borders.left + this_box.ScrollWidth() +
+ // borders.right); scrolled_paint_rect.SetHeight(this_box.BorderTop() +
+ // this_box.ScrollHeight() +
+ // this_box.BorderBottom());
+ }
+
+ GraphicsContextStateSaver background_clip_state_saver(context, false);
+ IntRect mask_rect;
+
+ switch (bg_layer.Clip()) {
+ case kPaddingFillBox:
+ case kContentFillBox: {
+ if (info.is_rounded_fill)
+ break;
+
+ // Clip to the padding or content boxes as necessary.
+ bool include_padding = bg_layer.Clip() == kContentFillBox;
+ LayoutRect clip_rect(
+ scrolled_paint_rect.X() + borders.left,
+ scrolled_paint_rect.Y() + borders.top,
+ scrolled_paint_rect.Width() - borders.left - borders.right,
+ scrolled_paint_rect.Height() - borders.top - borders.bottom);
+
+ if (include_padding) {
+ clip_rect.ContractEdges(paddings.top, paddings.right, paddings.bottom,
+ paddings.left);
+ }
+
+ background_clip_state_saver.Save();
+ // TODO(chrishtr): this should be pixel-snapped.
+ context.Clip(FloatRect(clip_rect));
+
+ break;
+ }
+ case kTextFillBox: {
+ // First figure out how big the mask has to be. It should be no bigger
+ // than what we need to actually render, so we should intersect the dirty
+ // rect with the border box of the background.
+ mask_rect = PixelSnappedIntRect(rect);
+
+ // We draw the background into a separate layer, to be later masked with
+ // yet another layer holding the text content.
+ background_clip_state_saver.Save();
+ context.Clip(mask_rect);
+ context.BeginLayer();
+
+ break;
+ }
+ case kBorderFillBox:
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+
+ // Paint the color first underneath all images, culled if background image
+ // occludes it.
+ // TODO(trchen): In the !bgLayer.hasRepeatXY() case, we could improve the
+ // culling test by verifying whether the background image covers the entire
+ // painting area.
+ if (info.is_bottom_layer && info.color.Alpha() && info.should_paint_color) {
+ IntRect background_rect(PixelSnappedIntRect(scrolled_paint_rect));
+ context.FillRect(background_rect, info.color);
+ }
+
+ // No progressive loading of the background image.
+ if (info.should_paint_image) {
+ // TODO(layout-dev): Add support for image painting.
+ DCHECK(false);
+ }
+
+ if (bg_layer.Clip() == kTextFillBox) {
+ // Create the text mask layer.
+ context.BeginLayer(1, SkBlendMode::kDstIn);
+
+ // Now draw the text into the mask. We do this by painting using a special
+ // paint phase that signals to
+ // InlineTextBoxes that they should just add their contents to the clip.
+ PaintInfo info(context, mask_rect, kPaintPhaseTextClip,
+ kGlobalPaintNormalPhase, 0);
+ // if (box) {
+ // const RootInlineBox& root = box->Root();
+ // box->Paint(info,
+ // LayoutPoint(scrolled_paint_rect.X() - box->X(),
+ // scrolled_paint_rect.Y() - box->Y()),
+ // root.LineTop(), root.LineBottom());
+ //} else {
+ // // FIXME: this should only have an effect for the line box list within
+ // // |obj|. Change this to create a LineBoxListPainter directly.
+ // LayoutSize local_offset =
+ // obj.IsBox() ? ToLayoutBox(&obj)->LocationOffset() : LayoutSize();
+ // obj.Paint(info, scrolled_paint_rect.Location() - local_offset);
+ //}
+
+ context.EndLayer();
+ context.EndLayer();
+ }
+}
+
+LayoutRect NGBoxFragmentPainter::BoundsForDrawingRecorder(
+ const PaintInfo& paint_info,
+ const LayoutPoint& adjusted_paint_offset) {
+ LayoutRect bounds = box_fragment_->VisualOverflowRect();
+ bounds.MoveBy(adjusted_paint_offset);
+ return bounds;
+}
+
+void NGBoxFragmentPainter::PaintBorder(const NGPhysicalBoxFragment* fragment,
+ const PaintInfo& info,
+ const LayoutRect& rect,
+ const ComputedStyle& style,
+ BackgroundBleedAvoidance bleed_avoidance,
+ bool include_logical_left_edge,
+ bool include_logical_right_edge) {
+ // TODO(layout-dev): Add support for image border painting.
+ const BoxBorderPainter border_painter(rect, style, bleed_avoidance,
+ include_logical_left_edge,
+ include_logical_right_edge);
+ border_painter.PaintBorder(info, rect);
+}
+
+const Document& NGBoxFragmentPainter::GetDocument() const {
+ return box_fragment_->GetLayoutObject()->GetDocument();
+}
+
+} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698