Commit 72bf334e authored by Fredrik Söderqvist's avatar Fredrik Söderqvist Committed by Chromium LUCI CQ

Refactor/share more 'image strip' painting code

Move NGClipRectForNinePieceImageStrip() to InlineBoxPainterBase
(dropping the 'NG' prefix) and switch InlineFlowBoxPainter to using it.

Clean up InlineFlowBoxPainter::PaintMask() to use the various member
fields from the base class. Also straighten out the mask-box-image
painting code a bit.

Restructure InlineFlowBoxPainter::GetBorderPaintType() to more closely
resemble the NG variant.

Change-Id: Ia09be7a2c43b31a12e5538364fa0292a2246b291
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2585088Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#836179}
parent 28ceb847
......@@ -13,6 +13,28 @@
namespace blink {
PhysicalRect InlineBoxPainterBase::ClipRectForNinePieceImageStrip(
const ComputedStyle& style,
PhysicalBoxSides sides_to_include,
const NinePieceImage& image,
const PhysicalRect& paint_rect) {
PhysicalRect clip_rect(paint_rect);
LayoutRectOutsets outsets = style.ImageOutsets(image);
if (sides_to_include.left) {
clip_rect.SetX(paint_rect.X() - outsets.Left());
clip_rect.SetWidth(paint_rect.Width() + outsets.Left());
}
if (sides_to_include.right)
clip_rect.SetWidth(clip_rect.Width() + outsets.Right());
if (sides_to_include.top) {
clip_rect.SetY(paint_rect.Y() - outsets.Top());
clip_rect.SetHeight(paint_rect.Height() + outsets.Top());
}
if (sides_to_include.bottom)
clip_rect.SetHeight(clip_rect.Height() + outsets.Bottom());
return clip_rect;
}
void InlineBoxPainterBase::PaintBoxDecorationBackground(
BoxPainterBase& box_painter,
const PaintInfo& paint_info,
......
......@@ -18,6 +18,7 @@ class Color;
class ComputedStyle;
class FillLayer;
class IntRect;
class NinePieceImage;
struct PaintInfo;
struct PhysicalOffset;
struct PhysicalRect;
......@@ -69,6 +70,11 @@ class InlineBoxPainterBase {
const ComputedStyle&,
const PhysicalRect& paint_rect) = 0;
static PhysicalRect ClipRectForNinePieceImageStrip(
const ComputedStyle& style,
PhysicalBoxSides sides_to_include,
const NinePieceImage& image,
const PhysicalRect& paint_rect);
virtual PhysicalRect PaintRectForImageStrip(
const PhysicalRect&,
TextDirection direction) const = 0;
......
......@@ -77,35 +77,6 @@ void InlineFlowBoxPainter::Paint(const PaintInfo& paint_info,
}
}
static PhysicalRect ClipRectForNinePieceImageStrip(
const InlineFlowBox& box,
const NinePieceImage& image,
const PhysicalRect& paint_rect) {
PhysicalRect clip_rect = paint_rect;
const ComputedStyle& style = box.GetLineLayoutItem().StyleRef();
LayoutRectOutsets outsets = style.ImageOutsets(image);
if (box.IsHorizontal()) {
clip_rect.SetY(paint_rect.Y() - outsets.Top());
clip_rect.SetHeight(paint_rect.Height() + outsets.Top() + outsets.Bottom());
if (box.IncludeLogicalLeftEdge()) {
clip_rect.SetX(paint_rect.X() - outsets.Left());
clip_rect.SetWidth(paint_rect.Width() + outsets.Left());
}
if (box.IncludeLogicalRightEdge())
clip_rect.SetWidth(clip_rect.Width() + outsets.Right());
} else {
clip_rect.SetX(paint_rect.X() - outsets.Left());
clip_rect.SetWidth(paint_rect.Width() + outsets.Left() + outsets.Right());
if (box.IncludeLogicalLeftEdge()) {
clip_rect.SetY(paint_rect.Y() - outsets.Top());
clip_rect.SetHeight(paint_rect.Height() + outsets.Top());
}
if (box.IncludeLogicalRightEdge())
clip_rect.SetHeight(clip_rect.Height() + outsets.Bottom());
}
return clip_rect;
}
PhysicalRect InlineFlowBoxPainter::PaintRectForImageStrip(
const PhysicalRect& paint_rect,
TextDirection direction) const {
......@@ -155,10 +126,9 @@ InlineFlowBoxPainter::GetBorderPaintType(
IntRect& adjusted_clip_rect,
bool object_has_multiple_boxes) const {
adjusted_clip_rect = PixelSnappedIntRect(adjusted_frame_rect);
if (inline_flow_box_.Parent() &&
inline_flow_box_.GetLineLayoutItem().StyleRef().HasBorderDecoration()) {
const NinePieceImage& border_image =
inline_flow_box_.GetLineLayoutItem().StyleRef().BorderImage();
if (!inline_flow_box_.Parent() || !style_.HasBorderDecoration())
return kDontPaintBorders;
const NinePieceImage& border_image = style_.BorderImage();
StyleImage* border_image_source = border_image.GetImage();
bool has_border_image =
border_image_source && border_image_source->CanRender();
......@@ -172,11 +142,10 @@ InlineFlowBoxPainter::GetBorderPaintType(
return kPaintBordersWithoutClip;
// We have a border image that spans multiple lines.
adjusted_clip_rect = PixelSnappedIntRect(ClipRectForNinePieceImageStrip(
inline_flow_box_, border_image, adjusted_frame_rect));
adjusted_clip_rect = PixelSnappedIntRect(
ClipRectForNinePieceImageStrip(style_, inline_flow_box_.SidesToInclude(),
border_image, adjusted_frame_rect));
return kPaintBordersWithClip;
}
return kDontPaintBorders;
}
void InlineFlowBoxPainter::PaintBackgroundBorderShadow(
......@@ -229,10 +198,7 @@ void InlineFlowBoxPainter::PaintBackgroundBorderShadow(
void InlineFlowBoxPainter::PaintMask(const PaintInfo& paint_info,
const PhysicalOffset& paint_offset) {
DCHECK_EQ(PaintPhase::kMask, paint_info.phase);
const auto& box_model = *To<LayoutBoxModelObject>(
LineLayoutAPIShim::LayoutObjectFrom(inline_flow_box_.BoxModelObject()));
if (!box_model.HasMask() ||
box_model.StyleRef().Visibility() != EVisibility::kVisible)
if (!style_.HasMask() || style_.Visibility() != EVisibility::kVisible)
return;
if (DrawingRecorder::UseCachedDrawingIfPossible(
......@@ -242,19 +208,20 @@ void InlineFlowBoxPainter::PaintMask(const PaintInfo& paint_info,
PhysicalRect paint_rect = AdjustedFrameRect(paint_offset);
DrawingRecorder recorder(paint_info.context, inline_flow_box_,
paint_info.phase, VisualRect(paint_rect));
const auto& mask_nine_piece_image = box_model.StyleRef().MaskBoxImage();
const auto* mask_box_image = mask_nine_piece_image.GetImage();
bool object_has_multiple_boxes = inline_flow_box_.PrevForSameLayoutObject() ||
inline_flow_box_.NextForSameLayoutObject();
const auto& box_model = *To<LayoutBoxModelObject>(
LineLayoutAPIShim::LayoutObjectFrom(inline_flow_box_.BoxModelObject()));
// Figure out if we need to push a transparency layer to render our mask.
BackgroundImageGeometry geometry(box_model);
BoxModelObjectPainter box_painter(box_model, &inline_flow_box_);
PaintFillLayers(box_painter, paint_info, Color::kTransparent,
box_model.StyleRef().MaskLayers(), paint_rect, geometry,
style_.MaskLayers(), paint_rect, geometry,
object_has_multiple_boxes);
const auto& mask_nine_piece_image = style_.MaskBoxImage();
const auto* mask_box_image = mask_nine_piece_image.GetImage();
bool has_box_image = mask_box_image && mask_box_image->CanRender();
if (!has_box_image || !mask_box_image->IsLoaded()) {
// Don't paint anything while we wait for the image to load.
......@@ -263,27 +230,24 @@ void InlineFlowBoxPainter::PaintMask(const PaintInfo& paint_info,
// The simple case is where we are the only box for this object. In those
// cases only a single call to draw is required.
if (!object_has_multiple_boxes) {
NinePieceImagePainter::Paint(paint_info.context, box_model,
box_model.GetDocument(), GetNode(&box_model),
paint_rect, box_model.StyleRef(),
mask_nine_piece_image);
} else {
PhysicalRect mask_image_paint_rect = paint_rect;
GraphicsContextStateSaver state_saver(paint_info.context, false);
if (object_has_multiple_boxes) {
// We have a mask image that spans multiple lines.
state_saver.Save();
// FIXME: What the heck do we do with RTL here? The math we're using is
// obviously not right, but it isn't even clear how this should work at all.
PhysicalRect image_strip_paint_rect =
mask_image_paint_rect =
PaintRectForImageStrip(paint_rect, TextDirection::kLtr);
FloatRect clip_rect(ClipRectForNinePieceImageStrip(
inline_flow_box_, mask_nine_piece_image, paint_rect));
GraphicsContextStateSaver state_saver(paint_info.context);
style_, inline_flow_box_.SidesToInclude(), mask_nine_piece_image,
paint_rect));
// TODO(chrishtr): this should be pixel-snapped.
paint_info.context.Clip(clip_rect);
NinePieceImagePainter::Paint(paint_info.context, box_model,
box_model.GetDocument(), GetNode(&box_model),
image_strip_paint_rect, box_model.StyleRef(),
mask_nine_piece_image);
}
NinePieceImagePainter::Paint(paint_info.context, image_observer_, *document_,
node_, mask_image_paint_rect, style_,
mask_nine_piece_image);
}
// This method should not be needed. See crbug.com/530659.
......
......@@ -281,28 +281,6 @@ PhysicalRect NGInlineBoxFragmentPainterBase::PaintRectForImageStrip(
paint_rect.Width(), total_width);
}
static PhysicalRect NGClipRectForNinePieceImageStrip(
const ComputedStyle& style,
PhysicalBoxSides sides_to_include,
const NinePieceImage& image,
const PhysicalRect& paint_rect) {
PhysicalRect clip_rect(paint_rect);
LayoutRectOutsets outsets = style.ImageOutsets(image);
if (sides_to_include.left) {
clip_rect.SetX(paint_rect.X() - outsets.Left());
clip_rect.SetWidth(paint_rect.Width() + outsets.Left());
}
if (sides_to_include.right)
clip_rect.SetWidth(clip_rect.Width() + outsets.Right());
if (sides_to_include.top) {
clip_rect.SetY(paint_rect.Y() - outsets.Top());
clip_rect.SetHeight(paint_rect.Height() + outsets.Top());
}
if (sides_to_include.bottom)
clip_rect.SetHeight(clip_rect.Height() + outsets.Bottom());
return clip_rect;
}
InlineBoxPainterBase::BorderPaintingType
NGInlineBoxFragmentPainterBase::GetBorderPaintType(
const PhysicalRect& adjusted_frame_rect,
......@@ -328,7 +306,7 @@ NGInlineBoxFragmentPainterBase::GetBorderPaintType(
}
// We have a border image that spans multiple lines.
adjusted_clip_rect = PixelSnappedIntRect(NGClipRectForNinePieceImageStrip(
adjusted_clip_rect = PixelSnappedIntRect(ClipRectForNinePieceImageStrip(
style, SidesToInclude(), border_image, adjusted_frame_rect));
return kPaintBordersWithClip;
}
......
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