Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Percent width/height SVG not always scaled on window resize
https://bugs.webkit.org/show_bug.cgi?id=79490

Patch by Florin Malita <fmalita@google.com> 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.

Canonical link: https://commits.webkit.org/96865@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@109104 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
fmalita authored and webkit-commit-queue committed Feb 28, 2012
1 parent 19a9f05 commit 32f5e81
Show file tree
Hide file tree
Showing 14 changed files with 229 additions and 6 deletions.
14 changes: 14 additions & 0 deletions LayoutTests/ChangeLog
@@ -1,3 +1,17 @@
2012-02-28 Florin Malita <fmalita@google.com>

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 <nzimmermann@rim.com>

Rebaseline Gtk results after r109097.
Expand Down
16 changes: 16 additions & 0 deletions LayoutTests/fast/repaint/percent-minheight-resize-expected.html
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<script src="resources/repaint.js"></script>
</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>
21 changes: 21 additions & 0 deletions LayoutTests/fast/repaint/percent-minheight-resize.html
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<script src="resources/repaint.js"></script>
</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>
20 changes: 20 additions & 0 deletions LayoutTests/svg/custom/svg-percent-scale-expected.html
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<script src="../../fast/repaint/resources/repaint.js"></script>
</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>
16 changes: 16 additions & 0 deletions LayoutTests/svg/custom/svg-percent-scale-vonly-expected.html
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<script src="../../fast/repaint/resources/repaint.js"></script>
</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>
27 changes: 27 additions & 0 deletions LayoutTests/svg/custom/svg-percent-scale-vonly.html
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<script src="../../fast/repaint/resources/repaint.js"></script>
</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>
28 changes: 28 additions & 0 deletions LayoutTests/svg/custom/svg-percent-scale.html
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>
<script src="../../fast/repaint/resources/repaint.js"></script>
</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>
50 changes: 50 additions & 0 deletions Source/WebCore/ChangeLog
@@ -1,3 +1,53 @@
2012-02-28 Florin Malita <fmalita@google.com>

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 <yurys@chromium.org>

Web Inspector: show resource dividers on memory counter graphs
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/rendering/RenderBlockLineLayout.cpp
Expand Up @@ -1486,7 +1486,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, LayoutUnit& repain
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.
Expand Down
7 changes: 7 additions & 0 deletions Source/WebCore/rendering/RenderBox.cpp
Expand Up @@ -3960,4 +3960,11 @@ LayoutSize RenderBox::topLeftLocationOffset() const
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
2 changes: 2 additions & 0 deletions Source/WebCore/rendering/RenderBox.h
Expand Up @@ -449,6 +449,8 @@ class RenderBox : public RenderBoxModelObject {

IntSize scrolledContentOffset() const;

virtual bool hasRelativeDimensions() const;

protected:
virtual void willBeDestroyed();

Expand Down
4 changes: 1 addition & 3 deletions Source/WebCore/rendering/RenderReplaced.cpp
Expand Up @@ -440,9 +440,7 @@ void RenderReplaced::computePreferredLogicalWidths()
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;
Expand Down
26 changes: 24 additions & 2 deletions Source/WebCore/rendering/svg/RenderSVGRoot.cpp
Expand Up @@ -188,8 +188,20 @@ LayoutUnit RenderSVGRoot::computeReplacedLogicalHeight() const
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());
Expand Down Expand Up @@ -275,6 +287,8 @@ void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& adjus

void RenderSVGRoot::willBeDestroyed()
{
RenderBlock::removePercentHeightDescendant(const_cast<RenderSVGRoot*>(this));

SVGResourcesCache::clientDestroyed(this);
RenderReplaced::willBeDestroyed();
}
Expand Down Expand Up @@ -401,6 +415,14 @@ bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
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)
2 changes: 2 additions & 0 deletions Source/WebCore/rendering/svg/RenderSVGRoot.h
Expand Up @@ -53,6 +53,8 @@ class RenderSVGRoot : public RenderReplaced {
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(); }
Expand Down

0 comments on commit 32f5e81

Please sign in to comment.