Title: [109104] trunk
Revision
109104
Author
[email protected]
Date
2012-02-28 08:01:19 -0800 (Tue, 28 Feb 2012)

Log Message

Percent width/height SVG not always scaled on window resize
https://bugs.webkit.org/show_bug.cgi?id=79490

Patch by Florin Malita <[email protected]> on 2012-02-28
Reviewed by Nikolas Zimmermann.

Source/WebCore:

Tests: fast/repaint/percent-minheight-resize-expected.html
       fast/repaint/percent-minheight-resize.html
       svg/custom/svg-percent-scale-expected.html
       svg/custom/svg-percent-scale-vonly-expected.html
       svg/custom/svg-percent-scale-vonly.html
       svg/custom/svg-percent-scale.html

Fix a couple of problems preventing correct SVG scaling on window resize:

- RenderReplaced::computePreferredLogicalWidths is not SVG attribute aware and computes
a non-zero m_minPreferredLogicalWidth even when the SVG widh/height are percentages.

- RenderBlock::layoutInlineChildren is also not SVG attribute aware and does not trigger
percent height child layouts on vertical-only resizes.

* rendering/RenderBlockLineLayout.cpp:
(WebCore::RenderBlock::layoutInlineChildren):
Use hasRelativeDimensions() instead of direct width/height->isPercent tests. This also fixes
an HTML issue where percent {min,max}Height inline elements are not updated on vertical-only resizes.

* rendering/RenderBox.cpp:
(WebCore::RenderBox::hasRelativeDimensions):
(WebCore):
* rendering/RenderBox.h:
(RenderBox):
Add virtual hasRelativeDimensions() method.

* rendering/RenderReplaced.cpp:
(WebCore::RenderReplaced::computePreferredLogicalWidths):
Use hasRelativeDimensions() instead of direct width/height->isPercent tests.

* rendering/svg/RenderSVGRoot.cpp:
(WebCore::RenderSVGRoot::computeReplacedLogicalHeight):
(WebCore::RenderSVGRoot::willBeDestroyed):
Register percent-height SVG elements with the gPercentHeightDescendantsMap, and clean-up on destruction
or height unit change.

(WebCore::RenderSVGRoot::hasRelativeDimensions):
(WebCore):
* rendering/svg/RenderSVGRoot.h:
(RenderSVGRoot):
SVG-aware hasRelativeDimensions() override.

LayoutTests:

* fast/repaint/percent-minheight-resize-expected.html: Added.
* fast/repaint/percent-minheight-resize.html: Added.
* svg/custom/svg-percent-scale-expected.html: Added.
* svg/custom/svg-percent-scale-vonly-expected.html: Added.
* svg/custom/svg-percent-scale-vonly.html: Added.
* svg/custom/svg-percent-scale.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (109103 => 109104)


--- trunk/LayoutTests/ChangeLog	2012-02-28 14:43:58 UTC (rev 109103)
+++ trunk/LayoutTests/ChangeLog	2012-02-28 16:01:19 UTC (rev 109104)
@@ -1,3 +1,17 @@
+2012-02-28  Florin Malita  <[email protected]>
+
+        Percent width/height SVG not always scaled on window resize
+        https://bugs.webkit.org/show_bug.cgi?id=79490
+
+        Reviewed by Nikolas Zimmermann.
+
+        * fast/repaint/percent-minheight-resize-expected.html: Added.
+        * fast/repaint/percent-minheight-resize.html: Added.
+        * svg/custom/svg-percent-scale-expected.html: Added.
+        * svg/custom/svg-percent-scale-vonly-expected.html: Added.
+        * svg/custom/svg-percent-scale-vonly.html: Added.
+        * svg/custom/svg-percent-scale.html: Added.
+
 2012-02-28  Nikolas Zimmermann  <[email protected]>
 
         Rebaseline Gtk results after r109097.

Added: trunk/LayoutTests/fast/repaint/percent-minheight-resize-expected.html (0 => 109104)


--- trunk/LayoutTests/fast/repaint/percent-minheight-resize-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/repaint/percent-minheight-resize-expected.html	2012-02-28 16:01:19 UTC (rev 109104)
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+
+<body style="margin: 0; padding: 0; overflow: hidden;" _onload_="runRepaintTest()">
+<div style="width: 100px; height: 100px; background-color: green; position: absolute;"></div>
+
+<script>
+  function repaintTest() {
+    window.resizeBy(0, -window.innerHeight / 2);
+  }
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/fast/repaint/percent-minheight-resize.html (0 => 109104)


--- trunk/LayoutTests/fast/repaint/percent-minheight-resize.html	                        (rev 0)
+++ trunk/LayoutTests/fast/repaint/percent-minheight-resize.html	2012-02-28 16:01:19 UTC (rev 109104)
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+
+<body style="margin: 0; padding: 0; overflow: hidden;" _onload_="runRepaintTest()">
+<div style="width: 100%; height: 100%; position: absolute;">
+  <!-- After window resizing, this DIV element should not be visible -->
+  <div style="width: 100px; min-height: 33%; background-color: red; display: inline-block;"></div>
+</div>
+
+<div style="width: 100px; height: 100px; background-color: green; position: absolute;"></div>
+
+<script>
+  function repaintTest() {
+    window.resizeBy(0, -window.innerHeight / 2);
+  }
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/svg/custom/svg-percent-scale-expected.html (0 => 109104)


--- trunk/LayoutTests/svg/custom/svg-percent-scale-expected.html	                        (rev 0)
+++ trunk/LayoutTests/svg/custom/svg-percent-scale-expected.html	2012-02-28 16:01:19 UTC (rev 109104)
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+
+<body style="margin: 0; padding: 0; overflow: hidden;" _onload_="runRepaintTest()">
+<div style="width: 100%; height: 100%; position: absolute;">
+<svg width="200" height="150" xmlns="http://www.w3.org/2000/svg">
+  <rect fill="green" width="100%" height="100%"/>
+</svg>
+</div>
+
+<script>
+  function repaintTest() {
+    window.resizeTo(window.innerWidth / 2, window.innerHeight / 2);
+  }
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/svg/custom/svg-percent-scale-vonly-expected.html (0 => 109104)


--- trunk/LayoutTests/svg/custom/svg-percent-scale-vonly-expected.html	                        (rev 0)
+++ trunk/LayoutTests/svg/custom/svg-percent-scale-vonly-expected.html	2012-02-28 16:01:19 UTC (rev 109104)
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+
+<body style="margin: 0; padding: 0; overflow: hidden;" _onload_="runRepaintTest()">
+<div style="width: 100px; height: 100px; position: absolute; background-color: green;"></div>
+
+<script>
+  function repaintTest() {
+    window.resizeBy(0, -window.innerHeight / 2);
+  }
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/svg/custom/svg-percent-scale-vonly.html (0 => 109104)


--- trunk/LayoutTests/svg/custom/svg-percent-scale-vonly.html	                        (rev 0)
+++ trunk/LayoutTests/svg/custom/svg-percent-scale-vonly.html	2012-02-28 16:01:19 UTC (rev 109104)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+
+<body style="margin: 0; padding: 0; overflow: hidden;" _onload_="runRepaintTest()">
+
+<div style="width: 100%; height: 100%; position: absolute; align: left;">
+<!-- After vertical window resizing, this SVG element should not be visible -->
+<svg width="50%" height="100%" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 600">
+  <rect fill="red" width="200" height="200"></rect>
+</svg>
+
+<!-- force an anonymous block creation to exercise the percent-height descendants map -->
+<div></div>
+</div>
+
+<div style="width: 100px; height: 100px; position: absolute; background-color: green;"></div>
+
+<script>
+  function repaintTest() {
+    window.resizeBy(0, -window.innerHeight / 2);
+  }
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/svg/custom/svg-percent-scale.html (0 => 109104)


--- trunk/LayoutTests/svg/custom/svg-percent-scale.html	                        (rev 0)
+++ trunk/LayoutTests/svg/custom/svg-percent-scale.html	2012-02-28 16:01:19 UTC (rev 109104)
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+
+<body style="margin: 0; padding: 0; overflow: hidden;" _onload_="runRepaintTest()">
+
+<div style="width: 100%; height: 100%; position: absolute;">
+<!-- After window resizing, this SVG element should not be visible -->
+<svg width="50%" height="50%" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 600">
+  <rect fill="red" width="800" height="600"></rect>
+</svg>
+</div>
+
+<div style="width: 100%; height: 100%; position: absolute;">
+<svg width="200" height="150" xmlns="http://www.w3.org/2000/svg">
+  <rect fill="green" width="100%" height="100%"/>
+</svg>
+</div>
+
+<script>
+  function repaintTest() {
+    window.resizeTo(window.innerWidth / 2, window.innerHeight / 2);
+  }
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (109103 => 109104)


--- trunk/Source/WebCore/ChangeLog	2012-02-28 14:43:58 UTC (rev 109103)
+++ trunk/Source/WebCore/ChangeLog	2012-02-28 16:01:19 UTC (rev 109104)
@@ -1,3 +1,53 @@
+2012-02-28  Florin Malita  <[email protected]>
+
+        Percent width/height SVG not always scaled on window resize
+        https://bugs.webkit.org/show_bug.cgi?id=79490
+
+        Reviewed by Nikolas Zimmermann.
+
+        Tests: fast/repaint/percent-minheight-resize-expected.html
+               fast/repaint/percent-minheight-resize.html
+               svg/custom/svg-percent-scale-expected.html
+               svg/custom/svg-percent-scale-vonly-expected.html
+               svg/custom/svg-percent-scale-vonly.html
+               svg/custom/svg-percent-scale.html
+
+        Fix a couple of problems preventing correct SVG scaling on window resize:
+
+        - RenderReplaced::computePreferredLogicalWidths is not SVG attribute aware and computes
+        a non-zero m_minPreferredLogicalWidth even when the SVG widh/height are percentages.
+
+        - RenderBlock::layoutInlineChildren is also not SVG attribute aware and does not trigger
+        percent height child layouts on vertical-only resizes.
+
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::RenderBlock::layoutInlineChildren):
+        Use hasRelativeDimensions() instead of direct width/height->isPercent tests. This also fixes
+        an HTML issue where percent {min,max}Height inline elements are not updated on vertical-only resizes.
+
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::hasRelativeDimensions):
+        (WebCore):
+        * rendering/RenderBox.h:
+        (RenderBox):
+        Add virtual hasRelativeDimensions() method.
+
+        * rendering/RenderReplaced.cpp:
+        (WebCore::RenderReplaced::computePreferredLogicalWidths):
+        Use hasRelativeDimensions() instead of direct width/height->isPercent tests.
+
+        * rendering/svg/RenderSVGRoot.cpp:
+        (WebCore::RenderSVGRoot::computeReplacedLogicalHeight):
+        (WebCore::RenderSVGRoot::willBeDestroyed):
+        Register percent-height SVG elements with the gPercentHeightDescendantsMap, and clean-up on destruction
+        or height unit change.
+
+        (WebCore::RenderSVGRoot::hasRelativeDimensions):
+        (WebCore):
+        * rendering/svg/RenderSVGRoot.h:
+        (RenderSVGRoot):
+        SVG-aware hasRelativeDimensions() override.
+
 2012-02-28  Yury Semikhatsky  <[email protected]>
 
         Web Inspector: show resource dividers on memory counter graphs

Modified: trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp (109103 => 109104)


--- trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2012-02-28 14:43:58 UTC (rev 109103)
+++ trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2012-02-28 16:01:19 UTC (rev 109104)
@@ -1486,7 +1486,7 @@
             if (o->isReplaced() || o->isFloating() || o->isPositioned()) {
                 RenderBox* box = toRenderBox(o);
 
-                if (relayoutChildren || o->style()->width().isPercent() || o->style()->height().isPercent())
+                if (relayoutChildren || box->hasRelativeDimensions())
                     o->setChildNeedsLayout(true, false);
 
                 // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.

Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (109103 => 109104)


--- trunk/Source/WebCore/rendering/RenderBox.cpp	2012-02-28 14:43:58 UTC (rev 109103)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp	2012-02-28 16:01:19 UTC (rev 109104)
@@ -3960,4 +3960,11 @@
     return LayoutSize(rect.x(), rect.y());
 }
 
+bool RenderBox::hasRelativeDimensions() const
+{
+    return style()->height().isPercent() || style()->width().isPercent()
+            || style()->maxHeight().isPercent() || style()->maxWidth().isPercent()
+            || style()->minHeight().isPercent() || style()->minWidth().isPercent();
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/RenderBox.h (109103 => 109104)


--- trunk/Source/WebCore/rendering/RenderBox.h	2012-02-28 14:43:58 UTC (rev 109103)
+++ trunk/Source/WebCore/rendering/RenderBox.h	2012-02-28 16:01:19 UTC (rev 109104)
@@ -449,6 +449,8 @@
 
     IntSize scrolledContentOffset() const;
 
+    virtual bool hasRelativeDimensions() const;
+
 protected:
     virtual void willBeDestroyed();
 

Modified: trunk/Source/WebCore/rendering/RenderReplaced.cpp (109103 => 109104)


--- trunk/Source/WebCore/rendering/RenderReplaced.cpp	2012-02-28 14:43:58 UTC (rev 109103)
+++ trunk/Source/WebCore/rendering/RenderReplaced.cpp	2012-02-28 16:01:19 UTC (rev 109104)
@@ -440,9 +440,7 @@
     if (style()->maxWidth().isFixed())
         m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, style()->maxWidth().value() + (style()->boxSizing() == CONTENT_BOX ? borderAndPadding : zeroLayoutUnit));
 
-    if (style()->width().isPercent() || style()->height().isPercent()
-        || style()->maxWidth().isPercent() || style()->maxHeight().isPercent()
-        || style()->minWidth().isPercent() || style()->minHeight().isPercent())
+    if (hasRelativeDimensions())
         m_minPreferredLogicalWidth = 0;
     else
         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth;

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp (109103 => 109104)


--- trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp	2012-02-28 14:43:58 UTC (rev 109103)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp	2012-02-28 16:01:19 UTC (rev 109104)
@@ -188,9 +188,21 @@
     if (hasReplacedLogicalHeight())
         return RenderReplaced::computeReplacedLogicalHeight();
 
-    if (svg->heightAttributeEstablishesViewport())
-        return resolveLengthAttributeForSVG(svg->intrinsicHeight(SVGSVGElement::IgnoreCSSProperties), style()->effectiveZoom(), containingBlock()->availableLogicalHeight());
+    if (svg->heightAttributeEstablishesViewport()) {
+        Length height = svg->intrinsicHeight(SVGSVGElement::IgnoreCSSProperties);
+        if (height.isPercent()) {
+            RenderBlock* cb = containingBlock();
+            ASSERT(cb);
+            while (cb->isAnonymous()) {
+                cb = cb->containingBlock();
+                cb->addPercentHeightDescendant(const_cast<RenderSVGRoot*>(this));
+            }
+        } else
+            RenderBlock::removePercentHeightDescendant(const_cast<RenderSVGRoot*>(this));
 
+        return resolveLengthAttributeForSVG(height, style()->effectiveZoom(), containingBlock()->availableLogicalHeight());
+    }
+
     // Only SVGs embedded in <object> reach this point.
     ASSERT(isEmbeddedThroughFrameContainingSVGDocument());
     return document()->frame()->ownerRenderer()->availableLogicalHeight();
@@ -275,6 +287,8 @@
 
 void RenderSVGRoot::willBeDestroyed()
 {
+    RenderBlock::removePercentHeightDescendant(const_cast<RenderSVGRoot*>(this));
+
     SVGResourcesCache::clientDestroyed(this);
     RenderReplaced::willBeDestroyed();
 }
@@ -401,6 +415,14 @@
     return false;
 }
 
+bool RenderSVGRoot::hasRelativeDimensions() const
+{
+    SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
+    ASSERT(svg);
+
+    return svg->intrinsicHeight(SVGSVGElement::IgnoreCSSProperties).isPercent() || svg->intrinsicWidth(SVGSVGElement::IgnoreCSSProperties).isPercent();
 }
 
+}
+
 #endif // ENABLE(SVG)

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGRoot.h (109103 => 109104)


--- trunk/Source/WebCore/rendering/svg/RenderSVGRoot.h	2012-02-28 14:43:58 UTC (rev 109103)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGRoot.h	2012-02-28 16:01:19 UTC (rev 109104)
@@ -53,6 +53,8 @@
     IntSize containerSize() const { return m_containerSize; }
     void setContainerSize(const IntSize& containerSize) { m_containerSize = containerSize; }
 
+    virtual bool hasRelativeDimensions() const;
+
 private:
     virtual RenderObjectChildList* virtualChildren() { return children(); }
     virtual const RenderObjectChildList* virtualChildren() const { return children(); }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to