https://bugs.webkit.org/show_bug.cgi?id=131623
Source/WebCore:
Compute correct repaint rect for decorated RenderSVGRoots.
The current implementation of clippedOverflowRectForRepaint() uses the
generic repaint-rect calculations in SVGRenderSupport. Those in turn make
use of repaintRectInLocalCoordinates(), which for RenderSVGRoot is the
union of the painted children (w/ some expansion). If there're no children,
or they do not fill the entire content box, then a repaint would not
repaint the correct parts.
Fix by calculating the union of the border-box and the SVG content
when the SVG root is decorated (has background/border/etc.)
Adapted from a Chromium patch by fs@opera.com
https://src.chromium.org/viewvc/blink?revision=170890&view=revision
Patch by Antoine Quint <graouts@apple.com> on 2015-10-09
Reviewed by Darin Adler.
Tests: svg/repaint/add-background-property-on-root.html
svg/repaint/add-border-property-on-root.html
svg/repaint/add-outline-property-on-root.html
svg/repaint/change-background-color.html
svg/repaint/remove-background-property-on-root.html
svg/repaint/remove-border-property-on-root.html
svg/repaint/remove-outline-property-on-root.html
* rendering/svg/RenderSVGRoot.cpp:
(WebCore::RenderSVGRoot::layout):
(WebCore::RenderSVGRoot::styleDidChange):
(WebCore::RenderSVGRoot::clippedOverflowRectForRepaint):
LayoutTests:
Add some new tests checking that dynamically updating the "background",
"border" and "outline" CSS properties repaint correctly and rebase a few
existing tests that yield the same rendered results but slightly different
DRT output.
Patch by Antoine Quint <graouts@apple.com> on 2015-10-09
Reviewed by Darin Adler.
* platform/mac/fast/repaint/moving-shadow-on-container-expected.txt:
* platform/mac/svg/custom/simple-text-double-shadow-expected.txt:
* svg/css/composite-shadow-example-expected.txt:
* svg/css/composite-shadow-with-opacity-expected.txt:
* svg/repaint/add-background-property-on-root-expected.html: Added.
* svg/repaint/add-background-property-on-root.html: Added.
* svg/repaint/add-border-property-on-root-expected.html: Added.
* svg/repaint/add-border-property-on-root.html: Added.
* svg/repaint/add-outline-property-on-root-expected.html: Added.
* svg/repaint/add-outline-property-on-root.html: Added.
* svg/repaint/change-background-color-expected.html: Added.
* svg/repaint/change-background-color.html: Added.
* svg/repaint/remove-background-property-on-root-expected.html: Added.
* svg/repaint/remove-background-property-on-root.html: Added.
* svg/repaint/remove-border-property-on-root-expected.html: Added.
* svg/repaint/remove-border-property-on-root.html: Added.
* svg/repaint/remove-outline-property-on-root-expected.html: Added.
* svg/repaint/remove-outline-property-on-root.html: Added.
* svg/repaint/repaint-webkit-svg-shadow-expected.txt:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190816
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2015-10-09 Antoine Quint <graouts@apple.com>
+
+ Dynamic background color changes do not update until a layout is forced
+ https://bugs.webkit.org/show_bug.cgi?id=131623
+
+ Add some new tests checking that dynamically updating the "background",
+ "border" and "outline" CSS properties repaint correctly and rebase a few
+ existing tests that yield the same rendered results but slightly different
+ DRT output.
+
+ Reviewed by Darin Adler.
+
+ * platform/mac/fast/repaint/moving-shadow-on-container-expected.txt:
+ * platform/mac/svg/custom/simple-text-double-shadow-expected.txt:
+ * svg/css/composite-shadow-example-expected.txt:
+ * svg/css/composite-shadow-with-opacity-expected.txt:
+ * svg/repaint/add-background-property-on-root-expected.html: Added.
+ * svg/repaint/add-background-property-on-root.html: Added.
+ * svg/repaint/add-border-property-on-root-expected.html: Added.
+ * svg/repaint/add-border-property-on-root.html: Added.
+ * svg/repaint/add-outline-property-on-root-expected.html: Added.
+ * svg/repaint/add-outline-property-on-root.html: Added.
+ * svg/repaint/change-background-color-expected.html: Added.
+ * svg/repaint/change-background-color.html: Added.
+ * svg/repaint/remove-background-property-on-root-expected.html: Added.
+ * svg/repaint/remove-background-property-on-root.html: Added.
+ * svg/repaint/remove-border-property-on-root-expected.html: Added.
+ * svg/repaint/remove-border-property-on-root.html: Added.
+ * svg/repaint/remove-outline-property-on-root-expected.html: Added.
+ * svg/repaint/remove-outline-property-on-root.html: Added.
+ * svg/repaint/repaint-webkit-svg-shadow-expected.txt:
+
2015-10-06 Simon Fraser <simon.fraser@apple.com>
Add some missing iOS results.
layer at (0,0) size 785x616
RenderBlock {HTML} at (0,0) size 785x616
RenderBody {BODY} at (8,8) size 769x600
- RenderSVGRoot {svg} at (8,8) size 496x201
+ RenderSVGRoot {svg} at (8,8) size 472x177
RenderSVGPath {path} at (8,8) size 80x70 [stroke={[type=SOLID] [color=#000000] [stroke width=10.00]}] [fill={[type=SOLID] [color=#999999]}] [data="M 1.83697e-15 30 L -35.2671 48.541 L -28.5317 9.27051 L -57.0634 -18.541 L -17.6336 -24.2705 L -1.10218e-14 -60 L 17.6336 -24.2705 L 57.0634 -18.541 L 28.5317 9.27051 L 35.2671 48.541 Z"]
RenderSVGPath {path} at (198,44) size 132x129 [transform={m=((1.00,0.00)(0.00,1.00)) t=(250.00,100.00)}] [stroke={[type=SOLID] [color=#000000] [stroke width=10.00] [dash array={20.00}]}] [fill={[type=SOLID] [color=#999999]}] [data="M 1.83697e-15 30 L -35.2671 48.541 L -28.5317 9.27051 L -57.0634 -18.541 L -17.6336 -24.2705 L -1.10218e-14 -60 L 17.6336 -24.2705 L 57.0634 -18.541 L 28.5317 9.27051 L 35.2671 48.541 Z"]
RenderSVGPath {path} at (347,44) size 121x126 [transform={m=((1.00,0.00)(0.00,1.00)) t=(400.00,100.00)}] [stroke={[type=SOLID] [color=#000000] [stroke width=10.00] [dash array={20.00}]}] [fill={[type=SOLID] [color=#999999]}] [data="M 1.53081e-15 25 L -29.3893 40.4509 L -23.7764 7.72542 L -47.5528 -15.4508 L -14.6946 -20.2254 L -9.18485e-15 -50 L 14.6946 -20.2254 L 47.5528 -15.4508 L 23.7764 7.72542 L 29.3893 40.4509 Z"]
layer at (0,0) size 800x600
RenderView at (0,0) size 800x600
layer at (0,0) size 800x600
- RenderSVGRoot {svg} at (20,26) size 480x294
+ RenderSVGRoot {svg} at (20,26) size 380x194
RenderSVGText {text} at (20,26) size 221x18 contains 1 chunk(s)
RenderSVGInlineText {#text} at (0,0) size 221x18
chunk 1 text run 1 at (20.00,40.00) startOffset 0 endOffset 34 width 220.84: "This text should appear only twice"
layer at (0,0) size 785x616
RenderBlock {HTML} at (0,0) size 785x616
RenderBody {BODY} at (8,8) size 769x600
- RenderSVGRoot {svg} at (32,28) size 472x186
+ RenderSVGRoot {svg} at (36,32) size 444x158
RenderSVGContainer {g} at (36,32) size 164x158
RenderSVGPath {path} at (38,34) size 150x144 [transform={m=((1.00,0.00)(0.00,1.00)) t=(100.00,100.00)}] [stroke={[type=SOLID] [color=#000000] [stroke width=10.00]}] [fill={[type=SOLID] [color=#999999]}] [data="M 1.83697e-15 30 L -35.2671 48.541 L -28.5317 9.27051 L -57.0634 -18.541 L -17.6336 -24.2705 L -1.10218e-14 -60 L 17.6336 -24.2705 L 57.0634 -18.541 L 28.5317 9.27051 L 35.2671 48.541 Z"]
RenderSVGContainer {g} at (196,42) size 146x143
RenderBlock {HTML} at (0,0) size 785x616
RenderBody {BODY} at (8,8) size 769x600
layer at (8,8) size 769x600
- RenderSVGRoot {svg} at (32,28) size 472x186 [opacity=0.50]
+ RenderSVGRoot {svg} at (36,32) size 444x158 [opacity=0.50]
RenderSVGContainer {g} at (36,32) size 164x158
RenderSVGPath {path} at (38,34) size 150x144 [transform={m=((1.00,0.00)(0.00,1.00)) t=(100.00,100.00)}] [stroke={[type=SOLID] [color=#000000] [stroke width=10.00]}] [fill={[type=SOLID] [color=#999999]}] [data="M 1.83697e-15 30 L -35.2671 48.541 L -28.5317 9.27051 L -57.0634 -18.541 L -17.6336 -24.2705 L -1.10218e-14 -60 L 17.6336 -24.2705 L 57.0634 -18.541 L 28.5317 9.27051 L 35.2671 48.541 Z"]
RenderSVGContainer {g} at (196,42) size 146x143
--- /dev/null
+<!DOCTYPE html>
+<div style="width: 100px; height: 100px; background: red">
+ <svg width="100" height="100" style="background: green"></svg>
+</div>
--- /dev/null
+<!DOCTYPE html>
+<script>
+if (window.testRunner)
+ testRunner.waitUntilDone();
+
+window.onload = function() {
+ requestAnimationFrame(function() {
+ document.querySelector("svg").style.background = "green";
+ if (window.testRunner)
+ window.testRunner.notifyDone();
+ });
+};
+</script>
+<div style="width: 100px; height: 100px; background: red">
+ <svg width="100" height="100"></svg>
+</div>
--- /dev/null
+<!DOCTYPE html>
+<svg width="100" height="100" style="position: absolute; border: 10px solid green"></svg>
--- /dev/null
+<!DOCTYPE html>
+<script>
+if (window.testRunner)
+ testRunner.waitUntilDone();
+
+window.onload = function() {
+ requestAnimationFrame(function() {
+ document.querySelector("svg").style.border = "10px solid green";
+ if (window.testRunner)
+ window.testRunner.notifyDone();
+ });
+};
+</script>
+<svg width="100" height="100" style="position: absolute"></svg>
--- /dev/null
+<!DOCTYPE html>
+<svg width="100" height="100" style="outline: 10px solid green"><rect width="100" height="100" fill="blue"/></svg>
--- /dev/null
+<!DOCTYPE html>
+<script>
+if (window.testRunner)
+ testRunner.waitUntilDone();
+
+window.onload = function() {
+ requestAnimationFrame(function() {
+ document.querySelector("svg").style.outline = "10px solid green";
+ if (window.testRunner)
+ window.testRunner.notifyDone();
+ });
+};
+</script>
+<svg width="100" height="100">
+ <rect width="100" height="100" fill="blue"/>
+</svg>
--- /dev/null
+<!DOCTYPE HTML>
+<svg width="200px" height="100px" viewBox="0 0 100 100" style="background-color: green"></svg>
--- /dev/null
+<!DOCTYPE HTML>
+<script>
+if (window.testRunner)
+ testRunner.waitUntilDone();
+
+window.onload = function() {
+ requestAnimationFrame(function() {
+ document.querySelector("svg").style.backgroundColor = "green";
+ if (window.testRunner)
+ window.testRunner.notifyDone();
+ });
+};
+</script>
+<svg width="200px" height="100px" viewBox="0 0 100 100" style="background-color: red"></svg>
--- /dev/null
+<!DOCTYPE html>
+<div style="width: 100px; height: 100px; background: green"></div>
--- /dev/null
+<!DOCTYPE html>
+<script>
+if (window.testRunner)
+ testRunner.waitUntilDone();
+
+window.onload = function() {
+ requestAnimationFrame(function() {
+ document.querySelector("svg").style.removeProperty("background");
+ if (window.testRunner)
+ window.testRunner.notifyDone();
+ });
+};
+</script>
+<div style="width: 100px; height: 100px; background: green">
+ <svg style="background: red" width="100" height="100"></svg>
+</div>
--- /dev/null
+<!DOCTYPE html>
+<svg style="position: absolute" width="100" height="100"></svg>
--- /dev/null
+<!DOCTYPE html>
+<script>
+if (window.testRunner)
+ testRunner.waitUntilDone();
+
+window.onload = function() {
+ requestAnimationFrame(function() {
+ document.querySelector("svg").style.removeProperty("border");
+ if (window.testRunner)
+ window.testRunner.notifyDone();
+ });
+};
+</script>
+<svg style="border: 10px solid red; position: absolute" width="100" height="100"></svg>
--- /dev/null
+<!DOCTYPE html>
+<svg width="100" height="100"><rect width="100" height="100" fill="green"/></svg>
--- /dev/null
+<!DOCTYPE html>
+<script>
+if (window.testRunner)
+ testRunner.waitUntilDone();
+
+window.onload = function() {
+ requestAnimationFrame(function() {
+ document.querySelector("svg").style.removeProperty("outline");
+ if (window.testRunner)
+ window.testRunner.notifyDone();
+ });
+};
+</script>
+<svg style="outline: 10px solid red" width="100" height="100">
+ <rect width="100" height="100" fill="green"/>
+</svg>
layer at (0,0) size 800x600
RenderView at (0,0) size 800x600
layer at (0,0) size 800x600
- RenderSVGRoot {svg} at (120,0) size 450x520
+ RenderSVGRoot {svg} at (120,0) size 250x320
RenderSVGRect {rect} at (150,100) size 120x120 [transform={m=((1.00,0.00)(0.00,1.00)) t=(150.00,50.00)}] [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=50.00] [width=20.00] [height=20.00]
RenderSVGRect {rect} at (120,0) size 120x120 [fill={[type=SOLID] [color=#000000]}] [x=120.00] [y=0.00] [width=20.00] [height=20.00]
+2015-10-09 Antoine Quint <graouts@apple.com>
+
+ Dynamic background color changes do not update until a layout is forced
+ https://bugs.webkit.org/show_bug.cgi?id=131623
+
+ Compute correct repaint rect for decorated RenderSVGRoots.
+
+ The current implementation of clippedOverflowRectForRepaint() uses the
+ generic repaint-rect calculations in SVGRenderSupport. Those in turn make
+ use of repaintRectInLocalCoordinates(), which for RenderSVGRoot is the
+ union of the painted children (w/ some expansion). If there're no children,
+ or they do not fill the entire content box, then a repaint would not
+ repaint the correct parts.
+ Fix by calculating the union of the border-box and the SVG content
+ when the SVG root is decorated (has background/border/etc.)
+
+ Adapted from a Chromium patch by fs@opera.com
+ https://src.chromium.org/viewvc/blink?revision=170890&view=revision
+
+ Reviewed by Darin Adler.
+
+ Tests: svg/repaint/add-background-property-on-root.html
+ svg/repaint/add-border-property-on-root.html
+ svg/repaint/add-outline-property-on-root.html
+ svg/repaint/change-background-color.html
+ svg/repaint/remove-background-property-on-root.html
+ svg/repaint/remove-border-property-on-root.html
+ svg/repaint/remove-outline-property-on-root.html
+
+ * rendering/svg/RenderSVGRoot.cpp:
+ (WebCore::RenderSVGRoot::layout):
+ (WebCore::RenderSVGRoot::styleDidChange):
+ (WebCore::RenderSVGRoot::clippedOverflowRectForRepaint):
+
2015-10-09 Simon Fraser <simon.fraser@apple.com>
[iOS WK2] Fix assertion in ViewportConfiguration::setDefaultConfiguration seen in testing
{
if (diff == StyleDifferenceLayout)
setNeedsBoundariesUpdate();
+
+ // Box decorations may have appeared/disappeared - recompute status.
+ if (diff == StyleDifferenceRepaint)
+ m_hasBoxDecorations = hasBoxDecorationStyle();
+
RenderReplaced::styleDidChange(diff, oldStyle);
SVGResourcesCache::clientStyleChanged(*this, diff, style());
}
LayoutRect RenderSVGRoot::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const
{
- return SVGRenderSupport::clippedOverflowRectForRepaint(*this, repaintContainer);
+ if (style().visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent())
+ return LayoutRect();
+
+ FloatRect contentRepaintRect = m_localToBorderBoxTransform.mapRect(repaintRectInLocalCoordinates());
+ contentRepaintRect.intersect(snappedIntRect(borderBoxRect()));
+
+ LayoutRect repaintRect = enclosingLayoutRect(contentRepaintRect);
+ if (m_hasBoxDecorations || hasRenderOverflow())
+ repaintRect.unite(unionRect(localSelectionRect(false), visualOverflowRect()));
+
+ return RenderReplaced::computeRectForRepaint(enclosingIntRect(repaintRect), repaintContainer);
}
FloatRect RenderSVGRoot::computeFloatRectForRepaint(const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed) const