Commit e639e0c8 authored by Emil A Eklund's avatar Emil A Eklund Committed by Commit Bot

[LayoutNG] Fix inline mask painting for multi-line

In legacy layout multi-line image mask painting is handled by giving the
entire width of the element to the painting code and then clipping it to
ensure the left edge is omitted for all but the first line and the right
edge is for all but the last. This is inefficient and different from how
the logic to omit edges is implement for other border/image paint calls.

This change adds include_logical_left_edge/include_logical_right_edge to
the NinePieceImageGrid constructor and uses these new parameters to size
the left and right edges respectively. Matching existing painting logic.

Bug: 714962
Test: fast/borders/inline-mask-overlay-image.html
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.linux:linux_layout_tests_layout_ng;master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Change-Id: I4bcefcc91115a9601632d9e1a0bce70b591cd0a6
Reviewed-on: https://chromium-review.googlesource.com/1048844
Commit-Queue: Koji Ishii <kojii@chromium.org>
Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#556671}
parent 967e1009
...@@ -921,8 +921,6 @@ crbug.com/591099 fast/borders/border-radius-mask-canvas-with-mask.html [ Failure ...@@ -921,8 +921,6 @@ crbug.com/591099 fast/borders/border-radius-mask-canvas-with-mask.html [ Failure
crbug.com/591099 fast/borders/border-radius-mask-canvas-with-shadow.html [ Failure ] crbug.com/591099 fast/borders/border-radius-mask-canvas-with-shadow.html [ Failure ]
crbug.com/714962 fast/borders/border-styles-split.html [ Failure ] crbug.com/714962 fast/borders/border-styles-split.html [ Failure ]
crbug.com/591099 fast/borders/inline-mask-overlay-image-outset-vertical-rl.html [ Failure ] crbug.com/591099 fast/borders/inline-mask-overlay-image-outset-vertical-rl.html [ Failure ]
crbug.com/591099 fast/borders/inline-mask-overlay-image-outset.html [ Failure ]
crbug.com/591099 fast/borders/inline-mask-overlay-image.html [ Failure ]
crbug.com/591099 fast/box-decoration-break/box-decoration-break-rendering.html [ Failure ] crbug.com/591099 fast/box-decoration-break/box-decoration-break-rendering.html [ Failure ]
crbug.com/591099 fast/box-shadow/basic-shadows.html [ Failure ] crbug.com/591099 fast/box-shadow/basic-shadows.html [ Failure ]
crbug.com/591099 fast/box-shadow/box-shadow.html [ Failure ] crbug.com/591099 fast/box-shadow/box-shadow.html [ Failure ]
......
layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 1880
LayoutView at (0,0) size 800x600
layer at (0,0) size 785x1880 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
LayoutNGBlockFlow {HTML} at (0,0) size 785x1880
LayoutNGBlockFlow {BODY} at (8,8) size 769x1864
LayoutText {#text} at (0,0) size 0x0
layer at (8,8) size 612x1856 backgroundClip at (8,12) size 612x588 clip at (8,12) size 612x588 transparent
LayoutInline {SPAN} at (0,0) size 612x1856 [bgcolor=#800000]
LayoutText {#text} at (0,4) size 612x1856
text run at (0,4) width 356: "This"
text run at (0,237) width 590: "content"
text run at (0,470) width 534: "should"
text run at (0,703) width 189: "be"
text run at (0,936) width 612: "masked"
text run at (0,1169) width 495: "with a"
text run at (0,1402) width 301: "soft"
text run at (0,1635) width 437: "glow."
layer at (0,0) size 800x600
LayoutView at (0,0) size 800x600
layer at (0,0) size 800x600
LayoutNGBlockFlow {HTML} at (0,0) size 800x600
LayoutNGBlockFlow {BODY} at (8,8) size 784x584
LayoutText {#text} at (0,0) size 0x0
layer at (8,8) size 375x119 backgroundClip at (0,10) size 393x139 clip at (0,10) size 393x139 transparent
LayoutInline {SPAN} at (0,0) size 375x119 [bgcolor=#808080]
LayoutText {#text} at (75,22) size 300x27
text run at (75,22) width 300: "This content should be masked"
LayoutBR {BR} at (375,22) size 0x0
LayoutText {#text} at (0,94) size 160x27
text run at (0,94) width 160: "with a soft glow."
...@@ -245,9 +245,17 @@ void BoxPainter::PaintMask(const PaintInfo& paint_info, ...@@ -245,9 +245,17 @@ void BoxPainter::PaintMask(const PaintInfo& paint_info,
void BoxPainter::PaintMaskImages(const PaintInfo& paint_info, void BoxPainter::PaintMaskImages(const PaintInfo& paint_info,
const LayoutRect& paint_rect) { const LayoutRect& paint_rect) {
// For mask images legacy layout painting handles multi-line boxes by giving
// the full width of the element, not the current line box, thereby clipping
// the offending edges.
bool include_logical_left_edge = true;
bool include_logical_right_edge = true;
BackgroundImageGeometry geometry(layout_box_); BackgroundImageGeometry geometry(layout_box_);
BoxModelObjectPainter painter(layout_box_); BoxModelObjectPainter painter(layout_box_);
painter.PaintMaskImages(paint_info, paint_rect, layout_box_, geometry); painter.PaintMaskImages(paint_info, paint_rect, layout_box_, geometry,
include_logical_left_edge,
include_logical_right_edge);
} }
void BoxPainter::PaintClippingMask(const PaintInfo& paint_info, void BoxPainter::PaintClippingMask(const PaintInfo& paint_info,
......
...@@ -700,7 +700,9 @@ void BoxPainterBase::PaintBorder(const ImageResourceObserver& obj, ...@@ -700,7 +700,9 @@ void BoxPainterBase::PaintBorder(const ImageResourceObserver& obj,
void BoxPainterBase::PaintMaskImages(const PaintInfo& paint_info, void BoxPainterBase::PaintMaskImages(const PaintInfo& paint_info,
const LayoutRect& paint_rect, const LayoutRect& paint_rect,
const ImageResourceObserver& obj, const ImageResourceObserver& obj,
BackgroundImageGeometry& geometry) { BackgroundImageGeometry& geometry,
bool include_logical_left_edge,
bool include_logical_right_edge) {
// Figure out if we need to push a transparency layer to render our mask. // Figure out if we need to push a transparency layer to render our mask.
bool push_transparency_layer = false; bool push_transparency_layer = false;
bool all_mask_images_loaded = true; bool all_mask_images_loaded = true;
...@@ -728,7 +730,9 @@ void BoxPainterBase::PaintMaskImages(const PaintInfo& paint_info, ...@@ -728,7 +730,9 @@ void BoxPainterBase::PaintMaskImages(const PaintInfo& paint_info,
PaintFillLayers(paint_info, Color::kTransparent, style_.MaskLayers(), PaintFillLayers(paint_info, Color::kTransparent, style_.MaskLayers(),
paint_rect, geometry); paint_rect, geometry);
NinePieceImagePainter::Paint(paint_info.context, obj, *document_, node_, NinePieceImagePainter::Paint(paint_info.context, obj, *document_, node_,
paint_rect, style_, style_.MaskBoxImage()); paint_rect, style_, style_.MaskBoxImage(),
include_logical_left_edge,
include_logical_right_edge);
} }
if (push_transparency_layer) if (push_transparency_layer)
......
...@@ -67,7 +67,9 @@ class BoxPainterBase { ...@@ -67,7 +67,9 @@ class BoxPainterBase {
void PaintMaskImages(const PaintInfo&, void PaintMaskImages(const PaintInfo&,
const LayoutRect&, const LayoutRect&,
const ImageResourceObserver&, const ImageResourceObserver&,
BackgroundImageGeometry&); BackgroundImageGeometry&,
bool include_logical_left_edge,
bool include_logical_right_edge);
static void PaintNormalBoxShadow(const PaintInfo&, static void PaintNormalBoxShadow(const PaintInfo&,
const LayoutRect&, const LayoutRect&,
......
...@@ -386,7 +386,8 @@ void NGBoxFragmentPainter::PaintMask(const PaintInfo& paint_info, ...@@ -386,7 +386,8 @@ void NGBoxFragmentPainter::PaintMask(const PaintInfo& paint_info,
DrawingRecorder recorder(paint_info.context, box_fragment_, paint_info.phase); DrawingRecorder recorder(paint_info.context, box_fragment_, paint_info.phase);
LayoutRect paint_rect = LayoutRect paint_rect =
LayoutRect(paint_offset, box_fragment_.Size().ToLayoutSize()); LayoutRect(paint_offset, box_fragment_.Size().ToLayoutSize());
PaintMaskImages(paint_info, paint_rect, box_fragment_, geometry); PaintMaskImages(paint_info, paint_rect, box_fragment_, geometry,
border_edges_.line_left, border_edges_.line_right);
} }
void NGBoxFragmentPainter::PaintClippingMask(const PaintInfo&, void NGBoxFragmentPainter::PaintClippingMask(const PaintInfo&,
......
...@@ -30,7 +30,9 @@ static int ComputeEdgeSlice(const Length& slice, int maximum) { ...@@ -30,7 +30,9 @@ static int ComputeEdgeSlice(const Length& slice, int maximum) {
NinePieceImageGrid::NinePieceImageGrid(const NinePieceImage& nine_piece_image, NinePieceImageGrid::NinePieceImageGrid(const NinePieceImage& nine_piece_image,
IntSize image_size, IntSize image_size,
IntRect border_image_area, IntRect border_image_area,
const IntRectOutsets& border_widths) const IntRectOutsets& border_widths,
bool include_left_edge,
bool include_rigt_edge)
: border_image_area_(border_image_area), : border_image_area_(border_image_area),
image_size_(image_size), image_size_(image_size),
horizontal_tile_rule_((Image::TileRule)nine_piece_image.HorizontalRule()), horizontal_tile_rule_((Image::TileRule)nine_piece_image.HorizontalRule()),
...@@ -48,15 +50,19 @@ NinePieceImageGrid::NinePieceImageGrid(const NinePieceImage& nine_piece_image, ...@@ -48,15 +50,19 @@ NinePieceImageGrid::NinePieceImageGrid(const NinePieceImage& nine_piece_image,
top_.width = ComputeEdgeWidth(nine_piece_image.BorderSlices().Top(), top_.width = ComputeEdgeWidth(nine_piece_image.BorderSlices().Top(),
border_widths.Top(), top_.slice, border_widths.Top(), top_.slice,
border_image_area.Height()); border_image_area.Height());
right_.width = ComputeEdgeWidth(nine_piece_image.BorderSlices().Right(), right_.width = include_rigt_edge
border_widths.Right(), right_.slice, ? ComputeEdgeWidth(nine_piece_image.BorderSlices().Right(),
border_image_area.Width()); border_widths.Right(), right_.slice,
border_image_area.Width())
: 0;
bottom_.width = ComputeEdgeWidth(nine_piece_image.BorderSlices().Bottom(), bottom_.width = ComputeEdgeWidth(nine_piece_image.BorderSlices().Bottom(),
border_widths.Bottom(), bottom_.slice, border_widths.Bottom(), bottom_.slice,
border_image_area.Height()); border_image_area.Height());
left_.width = ComputeEdgeWidth(nine_piece_image.BorderSlices().Left(), left_.width = include_left_edge
border_widths.Left(), left_.slice, ? ComputeEdgeWidth(nine_piece_image.BorderSlices().Left(),
border_image_area.Width()); border_widths.Left(), left_.slice,
border_image_area.Width())
: 0;
// The spec says: Given Lwidth as the width of the border image area, Lheight // The spec says: Given Lwidth as the width of the border image area, Lheight
// as its height, and Wside as the border image width offset for the side, let // as its height, and Wside as the border image width offset for the side, let
......
...@@ -65,7 +65,9 @@ class CORE_EXPORT NinePieceImageGrid { ...@@ -65,7 +65,9 @@ class CORE_EXPORT NinePieceImageGrid {
NinePieceImageGrid(const NinePieceImage&, NinePieceImageGrid(const NinePieceImage&,
IntSize image_size, IntSize image_size,
IntRect border_image_area, IntRect border_image_area,
const IntRectOutsets& border_widths); const IntRectOutsets& border_widths,
bool include_left_edge = true,
bool include_rigt_edge = true);
struct CORE_EXPORT NinePieceDrawInfo { struct CORE_EXPORT NinePieceDrawInfo {
STACK_ALLOCATED(); STACK_ALLOCATED();
......
...@@ -24,13 +24,15 @@ void PaintPieces(GraphicsContext& context, ...@@ -24,13 +24,15 @@ void PaintPieces(GraphicsContext& context,
const ComputedStyle& style, const ComputedStyle& style,
const NinePieceImage& nine_piece_image, const NinePieceImage& nine_piece_image,
Image* image, Image* image,
IntSize image_size) { IntSize image_size,
bool include_logical_left_edge,
bool include_logical_right_edge) {
IntRectOutsets border_widths(style.BorderTopWidth(), style.BorderRightWidth(), IntRectOutsets border_widths(style.BorderTopWidth(), style.BorderRightWidth(),
style.BorderBottomWidth(), style.BorderBottomWidth(),
style.BorderLeftWidth()); style.BorderLeftWidth());
NinePieceImageGrid grid(nine_piece_image, image_size, NinePieceImageGrid grid(
PixelSnappedIntRect(border_image_rect), nine_piece_image, image_size, PixelSnappedIntRect(border_image_rect),
border_widths); border_widths, include_logical_left_edge, include_logical_right_edge);
for (NinePiece piece = kMinPiece; piece < kMaxPiece; ++piece) { for (NinePiece piece = kMinPiece; piece < kMaxPiece; ++piece) {
NinePieceImageGrid::NinePieceDrawInfo draw_info = grid.GetNinePieceDrawInfo( NinePieceImageGrid::NinePieceDrawInfo draw_info = grid.GetNinePieceDrawInfo(
...@@ -60,7 +62,9 @@ bool NinePieceImagePainter::Paint(GraphicsContext& graphics_context, ...@@ -60,7 +62,9 @@ bool NinePieceImagePainter::Paint(GraphicsContext& graphics_context,
Node* node, Node* node,
const LayoutRect& rect, const LayoutRect& rect,
const ComputedStyle& style, const ComputedStyle& style,
const NinePieceImage& nine_piece_image) { const NinePieceImage& nine_piece_image,
bool include_logical_left_edge,
bool include_logical_right_edge) {
StyleImage* style_image = nine_piece_image.GetImage(); StyleImage* style_image = nine_piece_image.GetImage();
if (!style_image) if (!style_image)
return false; return false;
...@@ -102,7 +106,8 @@ bool NinePieceImagePainter::Paint(GraphicsContext& graphics_context, ...@@ -102,7 +106,8 @@ bool NinePieceImagePainter::Paint(GraphicsContext& graphics_context,
ScopedInterpolationQuality interpolation_quality_scope( ScopedInterpolationQuality interpolation_quality_scope(
graphics_context, style.GetInterpolationQuality()); graphics_context, style.GetInterpolationQuality());
PaintPieces(graphics_context, border_image_rect, style, nine_piece_image, PaintPieces(graphics_context, border_image_rect, style, nine_piece_image,
image.get(), image_size); image.get(), image_size, include_logical_left_edge,
include_logical_right_edge);
return true; return true;
} }
......
...@@ -27,7 +27,9 @@ class NinePieceImagePainter { ...@@ -27,7 +27,9 @@ class NinePieceImagePainter {
Node*, Node*,
const LayoutRect&, const LayoutRect&,
const ComputedStyle&, const ComputedStyle&,
const NinePieceImage&); const NinePieceImage&,
bool include_logical_left_edge = true,
bool include_logical_right_edge = true);
private: private:
NinePieceImagePainter() = default; NinePieceImagePainter() = default;
......
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