Commit 2d526f29 authored by Xianzhu Wang's avatar Xianzhu Wang

[PE] Let visual rect cover sub-pixel visual effect outsets

If an overflowing visual effect has sub-pixel geometry and is painted
with anti-aliasing along pixel-snapped border box, the pixel-snapping
may cause the anti-aliased edge overflow the calculated visual rect.

Let LayoutBox::VisualRectOutsetForRasterEffects() return 1 if there are
any sub-pixel visual effect outsets to ensure the visual rect covers
all pixels.

Bug: 827516
Change-Id: I48f8350fb2124d002333a4cc76486c63ca55f8c9
Reviewed-on: https://chromium-review.googlesource.com/1003492Reviewed-by: default avatarChris Harrelson <chrishtr@chromium.org>
Reviewed-by: default avatarFlorin Malita <fmalita@chromium.org>
Cr-Commit-Position: refs/heads/master@{#550014}
parent 83bd0327
<!DOCTYPE html>
Passes if there is no residue when the black bar moving up.
<div id="target"
style="position: relative; top: 40px; width: 100px; height: 100px; box-shadow: 0 8.2px 0 0 black"></div>
<!DOCTYPE html>
Passes if there is no residue when the black bar moving up.
<div id="target"
style="position: relative; top: 50px; width: 100px; height: 100px; box-shadow: 0 8.2px 0 0 black"></div>
<script src="../../resources/run-after-layout-and-paint.js"></script>
<script>
if (window.testRunner)
testRunner.waitUntilDone();
var target_top = 50;
function test() {
target_top -= 0.25;
console.log(target_top);
target.style.top = target_top + 'px';
if (window.testRunner && target_top <= 40) {
testRunner.notifyDone();
} else {
runAfterLayoutAndPaint(test);
}
}
onload = test;
</script>
...@@ -5061,8 +5061,17 @@ void LayoutBox::AddVisualEffectOverflow() { ...@@ -5061,8 +5061,17 @@ void LayoutBox::AddVisualEffectOverflow() {
// Add in the final overflow with shadows, outsets and outline combined. // Add in the final overflow with shadows, outsets and outline combined.
LayoutRect visual_effect_overflow = BorderBoxRect(); LayoutRect visual_effect_overflow = BorderBoxRect();
visual_effect_overflow.Expand(ComputeVisualEffectOverflowOutsets()); LayoutRectOutsets outsets = ComputeVisualEffectOverflowOutsets();
visual_effect_overflow.Expand(outsets);
AddSelfVisualOverflow(visual_effect_overflow); AddSelfVisualOverflow(visual_effect_overflow);
if (!IsIntegerValue(outsets.Top()) || !IsIntegerValue(outsets.Right()) ||
!IsIntegerValue(outsets.Bottom()) || !IsIntegerValue(outsets.Left())) {
DCHECK(overflow_);
overflow_->SetHasSubpixelVisualEffectOutsets(true);
} else if (overflow_) {
overflow_->SetHasSubpixelVisualEffectOutsets(false);
}
} }
LayoutRectOutsets LayoutBox::ComputeVisualEffectOverflowOutsets() { LayoutRectOutsets LayoutBox::ComputeVisualEffectOverflowOutsets() {
...@@ -5991,4 +6000,12 @@ void LayoutBox::MutableForPainting:: ...@@ -5991,4 +6000,12 @@ void LayoutBox::MutableForPainting::
GetLayoutBox().PhysicalLayoutOverflowRect(); GetLayoutBox().PhysicalLayoutOverflowRect();
} }
float LayoutBox::VisualRectOutsetForRasterEffects() const {
// If the box has subpixel visual effect outsets, as the visual effect may be
// painted along the pixel-snapped border box, the pixels on the anti-aliased
// edge of the effect may overflow the calculated visual rect. Expand visual
// rect by one pixel in the case.
return overflow_ && overflow_->HasSubpixelVisualEffectOutsets() ? 1 : 0;
}
} // namespace blink } // namespace blink
...@@ -1626,6 +1626,8 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject { ...@@ -1626,6 +1626,8 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
LayoutRect DebugRect() const override; LayoutRect DebugRect() const override;
float VisualRectOutsetForRasterEffects() const override;
// The CSS border box rect for this box. // The CSS border box rect for this box.
// //
// The rectangle is in this box's physical coordinates but with a // The rectangle is in this box's physical coordinates but with a
......
...@@ -181,11 +181,19 @@ class BoxOverflowModel { ...@@ -181,11 +181,19 @@ class BoxOverflowModel {
layout_client_after_edge_ = client_after_edge; layout_client_after_edge_ = client_after_edge;
} }
void SetHasSubpixelVisualEffectOutsets(bool b) {
has_subpixel_visual_effect_outsets_ = b;
}
bool HasSubpixelVisualEffectOutsets() const {
return has_subpixel_visual_effect_outsets_;
}
private: private:
LayoutRect layout_overflow_; LayoutRect layout_overflow_;
LayoutRect self_visual_overflow_; LayoutRect self_visual_overflow_;
LayoutRect contents_visual_overflow_; LayoutRect contents_visual_overflow_;
LayoutUnit layout_client_after_edge_; LayoutUnit layout_client_after_edge_;
bool has_subpixel_visual_effect_outsets_ = false;
DISALLOW_COPY_AND_ASSIGN(BoxOverflowModel); DISALLOW_COPY_AND_ASSIGN(BoxOverflowModel);
}; };
......
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