Skip to content

Commit b10e156

Browse files
Ahmad-S792Ahmad Saleem
authored andcommitted
Fix negative shadow repaint issue
Fix negative shadow repaint issue https://bugs.webkit.org/show_bug.cgi?id=251176 Reviewed by Simon Fraser. Merge - https://src.chromium.org/viewvc/blink?view=revision&revision=164709 When a box with negative v-shadow changes height, the repaint rect is inadequate resulting some part of shadow is not repainted. Fix the issue by considering negative shadow-top/shadow-left. * Source/WebCore/rendering/RenderElement.cpp: (RenderElement::repaintAfterLayout): Add consideration for negative shadows * LayoutTests/fast/box-shadow/negative-shadow-box-shrink.html: Add Test Case * LayoutTests/fast/box-shadow/negative-shadow-box-shrink-expected.txt: Add Test Case Expectation * LayoutTests/fast/box-shadow/negative-shadow-box-expand.html: Add Test Case * LayoutTests/fast/box-shadow/negative-shadow-box-shrink-expand.txt: Add Test Case Expectation Canonical link: https://commits.webkit.org/259497@main
1 parent f325cba commit b10e156

File tree

5 files changed

+54
-8
lines changed

5 files changed

+54
-8
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
(repaint rects
2+
(rect 100 200 600 100)
3+
(rect 100 200 640 100)
4+
(rect 100 160 640 40)
5+
(rect 100 200 640 100)
6+
(rect 0 300 800 100)
7+
)
8+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<script src="../repaint/resources/text-based-repaint.js"></script>
3+
<script>
4+
function repaintTest()
5+
{
6+
document.getElementById('inner2').style.display = 'block';
7+
}
8+
</script>
9+
<body style="margin: 100px" onload="runRepaintTest()">
10+
<div id="outer" style="box-shadow: 40px -40px #F00;">
11+
<div id="inner1" style="height: 100px; background-color: blue"></div>
12+
<div id="inner2" style="display: none; height: 100px; background-color: green"></div>
13+
</div>
14+
</body>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
(repaint rects
2+
(rect 100 200 600 100)
3+
(rect 100 200 640 100)
4+
(rect 100 160 640 40)
5+
(rect 100 200 640 100)
6+
(rect 0 300 800 100)
7+
)
8+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<script src="../repaint/resources/text-based-repaint.js"></script>
3+
<script>
4+
function repaintTest()
5+
{
6+
document.getElementById('inner2').style.display = 'none';
7+
}
8+
</script>
9+
<body style="margin: 100px" onload="runRepaintTest()">
10+
<div id="outer" style="box-shadow: 40px -40px #F00;">
11+
<div id="inner1" style="height: 100px; background-color: blue"></div>
12+
<div id="inner2" style="height: 100px; background-color: green"></div>
13+
</div>
14+
</body>

Source/WebCore/rendering/RenderElement.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
* (C) 1999 Antti Koivisto ([email protected])
44
* (C) 2005 Allan Sandfeld Jensen ([email protected])
55
* (C) 2005, 2006 Samuel Weinig ([email protected])
6-
* Copyright (C) 2005-2021 Apple Inc. All rights reserved.
7-
* Copyright (C) 2010, 2012 Google Inc. All rights reserved.
6+
* Copyright (C) 2005-2023 Apple Inc. All rights reserved.
7+
* Copyright (C) 2010-2014 Google Inc. All rights reserved.
88
*
99
* This library is free software; you can redistribute it and/or
1010
* modify it under the terms of the GNU Library General Public
@@ -1284,10 +1284,11 @@ bool RenderElement::repaintAfterLayoutIfNeeded(const RenderLayerModelObject* rep
12841284
LayoutUnit boxWidth = is<RenderBox>(*this) ? downcast<RenderBox>(*this).width() : 0_lu;
12851285
LayoutUnit minInsetRightShadowExtent = std::min<LayoutUnit>(-insetShadowExtent.right(), std::min(newBounds.width(), oldBounds.width()));
12861286
LayoutUnit borderWidth = std::max(borderRight, std::max(valueForLength(style().borderTopRightRadius().width, boxWidth), valueForLength(style().borderBottomRightRadius().width, boxWidth)));
1287-
LayoutUnit decorationsWidth = std::max(LayoutUnit(-outlineStyle.outlineOffset()), borderWidth + minInsetRightShadowExtent) + std::max(outlineWidth, shadowRight);
1288-
LayoutRect rightRect(newOutlineBox.x() + std::min(newOutlineBox.width(), oldOutlineBox.width()) - decorationsWidth,
1287+
LayoutUnit decorationsLeftWidth = std::max(LayoutUnit(-outlineStyle.outlineOffset()), borderWidth + minInsetRightShadowExtent) + std::max(outlineWidth, -shadowLeft);
1288+
LayoutUnit decorationsRightWidth = std::max(LayoutUnit(-outlineStyle.outlineOffset()), borderWidth + minInsetRightShadowExtent) + std::max(outlineWidth, shadowRight);
1289+
LayoutRect rightRect(newOutlineBox.x() + std::min(newOutlineBox.width(), oldOutlineBox.width()) - decorationsLeftWidth,
12891290
newOutlineBox.y(),
1290-
width + decorationsWidth,
1291+
width + decorationsLeftWidth + decorationsRightWidth,
12911292
std::max(newOutlineBox.height(), oldOutlineBox.height()));
12921293
LayoutUnit right = std::min(newBounds.maxX(), oldBounds.maxX());
12931294
if (rightRect.x() < right) {
@@ -1305,11 +1306,12 @@ bool RenderElement::repaintAfterLayoutIfNeeded(const RenderLayerModelObject* rep
13051306
LayoutUnit minInsetBottomShadowExtent = std::min<LayoutUnit>(-insetShadowExtent.bottom(), std::min(newBounds.height(), oldBounds.height()));
13061307
LayoutUnit borderHeight = std::max(borderBottom, std::max(valueForLength(style().borderBottomLeftRadius().height, boxHeight),
13071308
valueForLength(style().borderBottomRightRadius().height, boxHeight)));
1308-
LayoutUnit decorationsHeight = std::max(LayoutUnit(-outlineStyle.outlineOffset()), borderHeight + minInsetBottomShadowExtent) + std::max(outlineWidth, shadowBottom);
1309+
LayoutUnit decorationsTopHeight = std::max(LayoutUnit(-outlineStyle.outlineOffset()), borderHeight + minInsetBottomShadowExtent) + std::max(outlineWidth, -shadowTop);
1310+
LayoutUnit decorationsBottomHeight = std::max(LayoutUnit(-outlineStyle.outlineOffset()), borderHeight + minInsetBottomShadowExtent) + std::max(outlineWidth, shadowBottom);
13091311
LayoutRect bottomRect(newOutlineBox.x(),
1310-
std::min(newOutlineBox.maxY(), oldOutlineBox.maxY()) - decorationsHeight,
1312+
std::min(newOutlineBox.maxY(), oldOutlineBox.maxY()) - decorationsTopHeight,
13111313
std::max(newOutlineBox.width(), oldOutlineBox.width()),
1312-
height + decorationsHeight);
1314+
height + decorationsTopHeight + decorationsBottomHeight);
13131315
LayoutUnit bottom = std::min(newBounds.maxY(), oldBounds.maxY());
13141316
if (bottomRect.y() < bottom) {
13151317
bottomRect.setHeight(std::min(bottomRect.height(), bottom - bottomRect.y()));

0 commit comments

Comments
 (0)