Commit 468c8890 authored by Mario Bianucci's avatar Mario Bianucci Committed by Commit Bot

Keep mask bounds expanded to edges of div to fully mask dest_rect.

Mask execution closely follows background execution, which results in the
size of the mask being reduced to the exact size requested, rather than
filling out the dest_rect in BackgroundImageGeography::SetNoRepeatX and
::SetNoRepeatY. This CL puts the mask in the correct location, then
when we are creating the shader in image.cc, if the mask doesn't fill
out the dest_rect, decal tilemode is used to fill the rest with
transparency, which allows the mask to fill the full area.

Regarding the change to the fast/backgrounds/mask-composite.html test:
This change results in the original test failing, displaying the same
thing that it displays when using source-out. Based on my understanding
of how the 'copy' Porter-Duff keyword works, I believe this is correct
and that the test previously had an incorrect baseline because of this
bug. My understanding is that, if mask-composite is 'copy', then regardless
of the number of masks, only the first one will be displayed. The PD
definition of copy is that only the source mask is displayed, and since
this would be applied starting from the last two masks listed, moving up
to the first two, the end result is that only the first mask is displayed.
And, since this matches what happens when mask-composite:source-out is
used (and matches Edge and Firefox using 'subtract'), I just changed it
to a likely more commonly used keyword.

Bug: 917067
Change-Id: Ic9174ea67d92abe6b78acf9b7f2640796d30d249
Reviewed-on: https://chromium-review.googlesource.com/c/1447261
Commit-Queue: Mario Bianucci <mabian@microsoft.com>
Reviewed-by: default avatarFlorin Malita <fmalita@chromium.org>
Reviewed-by: default avatarFredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#630004}
parent fbeb44e0
......@@ -83,8 +83,26 @@ IntPoint AccumulatedScrollOffsetForFixedBackground(
} // anonymous namespace
void BackgroundImageGeometry::SetNoRepeatX(LayoutUnit x_offset,
bool NeedsFullSizeDestination(const FillLayer& fill_layer) {
// When dealing with a mask, the dest rect needs to maintain the full size
// and the mask should be expanded to fill it out. This allows the mask to
// correctly mask the entire area it is meant to. This is unnecessary on the
// last layer, so the normal background path is taken for efficiency when
// creating the paint shader later on.
return fill_layer.GetType() == EFillLayerType::kMask && fill_layer.Next() &&
fill_layer.Composite() != kCompositeSourceOver;
}
void BackgroundImageGeometry::SetNoRepeatX(const FillLayer& fill_layer,
LayoutUnit x_offset,
LayoutUnit snapped_x_offset) {
if (NeedsFullSizeDestination(fill_layer)) {
SetPhaseX(-x_offset.ToFloat());
SetSpaceSize(
LayoutSize(unsnapped_dest_rect_.Width(), SpaceSize().Height()));
return;
}
// The snapped offset may not yet be snapped, so make sure it is an integer.
snapped_x_offset = LayoutUnit(RoundToInt(snapped_x_offset));
......@@ -120,8 +138,16 @@ void BackgroundImageGeometry::SetNoRepeatX(LayoutUnit x_offset,
SetSpaceSize(LayoutSize(LayoutUnit(), SpaceSize().Height()));
}
void BackgroundImageGeometry::SetNoRepeatY(LayoutUnit y_offset,
void BackgroundImageGeometry::SetNoRepeatY(const FillLayer& fill_layer,
LayoutUnit y_offset,
LayoutUnit snapped_y_offset) {
if (NeedsFullSizeDestination(fill_layer)) {
SetPhaseY(-y_offset.ToFloat());
SetSpaceSize(
LayoutSize(SpaceSize().Width(), unsnapped_dest_rect_.Height()));
return;
}
// The snapped offset may not yet be snapped, so make sure it is an integer.
snapped_y_offset = LayoutUnit(RoundToInt(snapped_y_offset));
......@@ -978,7 +1004,7 @@ void BackgroundImageGeometry::Calculate(const LayoutBoxModelObject* container,
fill_layer.BackgroundXOrigin() == BackgroundEdgeOrigin::kRight
? snapped_available_width - computed_x_position
: computed_x_position;
SetNoRepeatX(unsnapped_box_offset.X() + x_offset,
SetNoRepeatX(fill_layer, unsnapped_box_offset.X() + x_offset,
snapped_box_offset.X() + snapped_x_offset);
if (offset_in_background_.X() > tile_size_.Width())
unsnapped_dest_rect_ = snapped_dest_rect_ = LayoutRect();
......@@ -1009,7 +1035,7 @@ void BackgroundImageGeometry::Calculate(const LayoutBoxModelObject* container,
fill_layer.BackgroundYOrigin() == BackgroundEdgeOrigin::kBottom
? snapped_available_height - computed_y_position
: computed_y_position;
SetNoRepeatY(unsnapped_box_offset.Y() + y_offset,
SetNoRepeatY(fill_layer, unsnapped_box_offset.Y() + y_offset,
snapped_box_offset.Y() + snapped_y_offset);
if (offset_in_background_.Y() > tile_size_.Height())
unsnapped_dest_rect_ = snapped_dest_rect_ = LayoutRect();
......
......@@ -97,8 +97,12 @@ class BackgroundImageGeometry {
void SetPhaseX(float x) { phase_.SetX(x); }
void SetPhaseY(float y) { phase_.SetY(y); }
void SetNoRepeatX(LayoutUnit x_offset, LayoutUnit snapped_x_offset);
void SetNoRepeatY(LayoutUnit y_offset, LayoutUnit snapped_y_offset);
void SetNoRepeatX(const FillLayer&,
LayoutUnit x_offset,
LayoutUnit snapped_x_offset);
void SetNoRepeatY(const FillLayer&,
LayoutUnit y_offset,
LayoutUnit snapped_y_offset);
void SetRepeatX(const FillLayer&,
LayoutUnit available_width,
LayoutUnit extra_offset);
......
<!DOCTYPE html>
<style>
#cover {
width: 100px;
height: 100px;
background-color: green;
position: absolute;
left: 0;
top: 0;
}
div {
display: inline-block;
}
</style>
<p>There should be 2 green squares and a green rectangle below and no red.</p>
<div style="position: absolute">
<div id="cover"></div>
<div id="cover" style="left: 204px; top: 100px;"></div>
<div id="cover" style="left: 558px; top: 0px; height: 200px; width: 50px;"></div>
</div>
\ No newline at end of file
<!DOCTYPE html>
<style>
#mask {
width: 200px;
height: 200px;
background-color: red;
-webkit-mask-image: linear-gradient(black, black), linear-gradient(90deg, black, black);
-webkit-mask-size: 50% 100%, 100% 50%;
-webkit-mask-repeat: no-repeat;
}
#cover {
width: 100px;
height: 100px;
background-color: green;
position: absolute;
left: 0;
top: 0;
}
div {
display: inline-block;
}
</style>
<p>There should be 2 green squares and a green rectangle below and no red.</p>
<div style="position: absolute">
<div>
<div id="mask" style="-webkit-mask-composite: source-in;"></div>
<div id="cover"></div>
</div>
<div>
<div id="mask" style="-webkit-mask-composite: source-out;"></div>
<div id="cover" style="left: 204px;top:100px;"></div>
</div>
<div>
<div id="mask" style="-webkit-mask-composite: source-out; -webkit-mask-size: 50px; -webkit-mask-position: bottom right, top left;"></div>
<div id="cover" style="left: 558px; top:0px; height: 200px; width: 50px;"></div>
</div>
</div>
\ No newline at end of file
......@@ -9,11 +9,11 @@
-webkit-mask-position: top left, top right, bottom left, bottom right, top center, center right, bottom center, center left, center;
-webkit-mask-origin: border;
-webkit-mask-repeat: no-repeat, no-repeat, no-repeat, no-repeat, repeat-x, repeat-y, repeat-x, repeat-y, repeat;
-webkit-mask-composite: copy;
-webkit-mask-composite: xor;
}
</style>
The lime div below should have a soft glow effect.
The lime div below should have a soft glow effect on some edges.
<div class="test"></div>
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