Background width (or height) is wrong if width (or height) * zoom < 1.
authorshinyak@chromium.org <shinyak@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Apr 2012 08:39:58 +0000 (08:39 +0000)
committershinyak@chromium.org <shinyak@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Apr 2012 08:39:58 +0000 (08:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=83350

Reviewed by Nikolas Zimmermann.

Source/WebCore:

calculateImageIntrinsicDimension will return wrong size if the calculated size is 0.
0 is used for expressing unspecfied, so the method returns the box width(height) instead.

Since CachedImage has already similar code, we moved it to IntSize and shared it.

Tests: fast/css/zoom-background-repeat-x-expected.html
       fast/css/zoom-background-repeat-x.html
       fast/css/zoom-background-repeat-y-expected.html
       fast/css/zoom-background-repeat-y.html

* loader/cache/CachedImage.cpp:
(WebCore::CachedImage::imageSizeForRenderer):
* platform/graphics/IntSize.h:
(IntSize):
(WebCore::IntSize::scale):
(WebCore::IntSize::clampToMinimumSize):
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::calculateImageIntrinsicDimensions):

LayoutTests:

* fast/css/zoom-background-repeat-x-expected.html: Added.
* fast/css/zoom-background-repeat-x.html: Added.
* fast/css/zoom-background-repeat-y-expected.html: Added.
* fast/css/zoom-background-repeat-y.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@114095 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/css/zoom-background-repeat-x-expected.html [new file with mode: 0644]
LayoutTests/fast/css/zoom-background-repeat-x.html [new file with mode: 0644]
LayoutTests/fast/css/zoom-background-repeat-y-expected.html [new file with mode: 0644]
LayoutTests/fast/css/zoom-background-repeat-y.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/loader/cache/CachedImage.cpp
Source/WebCore/platform/graphics/IntSize.h
Source/WebCore/rendering/RenderBoxModelObject.cpp

index 32bcf58..c6abfd2 100644 (file)
@@ -1,3 +1,15 @@
+2012-04-13  Shinya Kawanaka  <shinyak@chromium.org>
+
+        Background width (or height) is wrong if width (or height) * zoom < 1.
+        https://bugs.webkit.org/show_bug.cgi?id=83350
+
+        Reviewed by Nikolas Zimmermann.
+
+        * fast/css/zoom-background-repeat-x-expected.html: Added.
+        * fast/css/zoom-background-repeat-x.html: Added.
+        * fast/css/zoom-background-repeat-y-expected.html: Added.
+        * fast/css/zoom-background-repeat-y.html: Added.
+
 2012-04-13  Kent Tamura  <tkent@chromium.org>
 
         Should clear an invalid string in a date field on blur
diff --git a/LayoutTests/fast/css/zoom-background-repeat-x-expected.html b/LayoutTests/fast/css/zoom-background-repeat-x-expected.html
new file mode 100644 (file)
index 0000000..b0daf3c
--- /dev/null
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+      #content {
+        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABhJREFUeF4FwTEBAAAAgjD7FzESWfjYdgwEoAJ4lTsaxgAAAABJRU5ErkJggg==);
+        background-repeat: repeat-y;
+
+        background-color: green;
+
+        height: 1px;
+        width: 90px;
+      }
+</style>
+</head>
+<body>
+<div id="content"></div>
+</body></html>
diff --git a/LayoutTests/fast/css/zoom-background-repeat-x.html b/LayoutTests/fast/css/zoom-background-repeat-x.html
new file mode 100644 (file)
index 0000000..b408323
--- /dev/null
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+      #content {
+        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABhJREFUeF4FwTEBAAAAgjD7FzESWfjYdgwEoAJ4lTsaxgAAAABJRU5ErkJggg==);
+        background-repeat: repeat-y;
+
+        background-color: green;
+
+        height: 1px;
+        width: 100px;
+        zoom: 0.9;
+      }
+</style>
+</head>
+<body>
+<div id="content"></div>
+</body></html>
diff --git a/LayoutTests/fast/css/zoom-background-repeat-y-expected.html b/LayoutTests/fast/css/zoom-background-repeat-y-expected.html
new file mode 100644 (file)
index 0000000..c5b285a
--- /dev/null
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+      #content {
+        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABhJREFUeF4FwTEBAAAAgjD7FzESWfjYdgwEoAJ4lTsaxgAAAABJRU5ErkJggg==);
+        background-repeat: repeat-y;
+
+        background-color: green;
+
+        height: 90px;
+      }
+</style>
+</head>
+<body>
+<div id="content"></div>
+</body></html>
diff --git a/LayoutTests/fast/css/zoom-background-repeat-y.html b/LayoutTests/fast/css/zoom-background-repeat-y.html
new file mode 100644 (file)
index 0000000..053cded
--- /dev/null
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+      #content {
+        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABhJREFUeF4FwTEBAAAAgjD7FzESWfjYdgwEoAJ4lTsaxgAAAABJRU5ErkJggg==);
+        background-repeat: repeat-y;
+
+        background-color: green;
+
+        height: 100px;
+        zoom: 0.9;
+      }
+</style>
+</head>
+<body>
+<div id="content"></div>
+</body></html>
index 67e9184..b24ebe1 100644 (file)
@@ -1,3 +1,29 @@
+2012-04-13  Shinya Kawanaka  <shinyak@chromium.org>
+
+        Background width (or height) is wrong if width (or height) * zoom < 1.
+        https://bugs.webkit.org/show_bug.cgi?id=83350
+
+        Reviewed by Nikolas Zimmermann.
+
+        calculateImageIntrinsicDimension will return wrong size if the calculated size is 0.
+        0 is used for expressing unspecfied, so the method returns the box width(height) instead.
+
+        Since CachedImage has already similar code, we moved it to IntSize and shared it.
+
+        Tests: fast/css/zoom-background-repeat-x-expected.html
+               fast/css/zoom-background-repeat-x.html
+               fast/css/zoom-background-repeat-y-expected.html
+               fast/css/zoom-background-repeat-y.html
+
+        * loader/cache/CachedImage.cpp:
+        (WebCore::CachedImage::imageSizeForRenderer):
+        * platform/graphics/IntSize.h:
+        (IntSize):
+        (WebCore::IntSize::scale):
+        (WebCore::IntSize::clampToMinimumSize):
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::calculateImageIntrinsicDimensions):
+
 2012-04-13  Adam Barth  <abarth@webkit.org>
 
         Prepare submitForm for seamless navigation
index 51f2f00..0af8404 100644 (file)
@@ -262,15 +262,12 @@ IntSize CachedImage::imageSizeForRenderer(const RenderObject* renderer, float mu
         return imageSize;
         
     // Don't let images that have a width/height >= 1 shrink below 1 when zoomed.
-    bool hasWidth = imageSize.width() > 0;
-    bool hasHeight = imageSize.height() > 0;
-    int width = imageSize.width() * (m_image->hasRelativeWidth() ? 1.0f : multiplier);
-    int height = imageSize.height() * (m_image->hasRelativeHeight() ? 1.0f : multiplier);
-    if (hasWidth)
-        width = max(1, width);
-    if (hasHeight)
-        height = max(1, height);
-    return IntSize(width, height);
+    float widthScale = m_image->hasRelativeWidth() ? 1.0f : multiplier;
+    float heightScale = m_image->hasRelativeHeight() ? 1.0f : multiplier;
+    IntSize minimumSize(imageSize.width() > 0 ? 1 : 0, imageSize.height() > 0 ? 1 : 0);
+    imageSize.scale(widthScale, heightScale);
+    imageSize.clampToMinimumSize(minimumSize);
+    return imageSize;
 }
 
 void CachedImage::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio, float scaleFactor)
index 8ec6539..c8a549d 100644 (file)
@@ -80,13 +80,18 @@ public:
         m_width += width;
         m_height += height;
     }
+
+    void scale(float widthScale, float heightScale)
+    {
+        m_width = static_cast<int>(static_cast<float>(m_width) * widthScale);
+        m_height = static_cast<int>(static_cast<float>(m_height) * heightScale);
+    }
     
     void scale(float scale)
     {
-        m_width = static_cast<int>(static_cast<float>(m_width) * scale);
-        m_height = static_cast<int>(static_cast<float>(m_height) * scale);
+        this->scale(scale, scale);
     }
-    
+
     IntSize expandedTo(const IntSize& other) const
     {
         return IntSize(m_width > other.m_width ? m_width : other.m_width,
@@ -104,6 +109,14 @@ public:
         *this = expandedTo(IntSize());
     }
 
+    void clampToMinimumSize(const IntSize& minimumSize)
+    {
+        if (m_width < minimumSize.width())
+            m_width = minimumSize.width();
+        if (m_height < minimumSize.height())
+            m_height = minimumSize.height();
+    }
+
     int area() const
     {
         return m_width * m_height;
index 4814d22..b7f29ba 100644 (file)
@@ -960,49 +960,45 @@ static inline IntSize resolveAgainstIntrinsicRatio(const IntSize& size, const Fl
 
 IntSize RenderBoxModelObject::calculateImageIntrinsicDimensions(StyleImage* image, const IntSize& positioningAreaSize) const
 {
-    int resolvedWidth = 0;
-    int resolvedHeight = 0;
+    // A generated image without a fixed size, will always return the container size as intrinsic size.
+    if (image->isGeneratedImage() && image->usesImageContainerSize())
+        return IntSize(positioningAreaSize.width(), positioningAreaSize.height());
+
+    Length intrinsicWidth;
+    Length intrinsicHeight;
     FloatSize intrinsicRatio;
+    image->computeIntrinsicDimensions(this, intrinsicWidth, intrinsicHeight, intrinsicRatio);
 
-    // A generated image without a fixed size, will always return the container size as intrinsic size.
-    if (image->isGeneratedImage() && image->usesImageContainerSize()) {
-        resolvedWidth = positioningAreaSize.width();
-        resolvedHeight = positioningAreaSize.height();
-    } else {
-        Length intrinsicWidth;
-        Length intrinsicHeight;
-        image->computeIntrinsicDimensions(this, intrinsicWidth, intrinsicHeight, intrinsicRatio);
-
-        // Intrinsic dimensions expressed as percentages must be resolved relative to the dimensions of the rectangle
-        // that establishes the coordinate system for the 'background-position' property. 
-
-        // FIXME: Remove unnecessary rounding when layout is off ints: webkit.org/b/63656
-        if (intrinsicWidth.isPercent() && intrinsicHeight.isPercent() && intrinsicRatio.isEmpty()) {
-            // Resolve width/height percentages against positioningAreaSize, only if no intrinsic ratio is provided.
-            resolvedWidth = static_cast<int>(round(positioningAreaSize.width() * intrinsicWidth.percent() / 100));
-            resolvedHeight = static_cast<int>(round(positioningAreaSize.height() * intrinsicHeight.percent() / 100));
-        } else {
-            if (intrinsicWidth.isFixed())
-                resolvedWidth = static_cast<int>(intrinsicWidth.value() * style()->effectiveZoom());
-            if (intrinsicHeight.isFixed())
-                resolvedHeight = static_cast<int>(intrinsicHeight.value() * style()->effectiveZoom());
-        }
+    // Intrinsic dimensions expressed as percentages must be resolved relative to the dimensions of the rectangle
+    // that establishes the coordinate system for the 'background-position' property. 
+    
+    // FIXME: Remove unnecessary rounding when layout is off ints: webkit.org/b/63656
+    if (intrinsicWidth.isPercent() && intrinsicHeight.isPercent() && intrinsicRatio.isEmpty()) {
+        // Resolve width/height percentages against positioningAreaSize, only if no intrinsic ratio is provided.
+        int resolvedWidth = static_cast<int>(round(positioningAreaSize.width() * intrinsicWidth.percent() / 100));
+        int resolvedHeight = static_cast<int>(round(positioningAreaSize.height() * intrinsicHeight.percent() / 100));
+        return IntSize(resolvedWidth, resolvedHeight);
     }
 
-    if (resolvedWidth > 0 && resolvedHeight > 0)
-        return IntSize(resolvedWidth, resolvedHeight);
+    IntSize resolvedSize(intrinsicWidth.isFixed() ? intrinsicWidth.value() : 0, intrinsicHeight.isFixed() ? intrinsicHeight.value() : 0);
+    IntSize minimumSize(resolvedSize.width() > 0 ? 1 : 0, resolvedSize.height() > 0 ? 1 : 0);
+    resolvedSize.scale(style()->effectiveZoom());
+    resolvedSize.clampToMinimumSize(minimumSize);
+
+    if (!resolvedSize.isEmpty())
+        return resolvedSize;
 
     // If the image has one of either an intrinsic width or an intrinsic height:
     // * and an intrinsic aspect ratio, then the missing dimension is calculated from the given dimension and the ratio.
     // * and no intrinsic aspect ratio, then the missing dimension is assumed to be the size of the rectangle that
     //   establishes the coordinate system for the 'background-position' property.
-    if ((resolvedWidth && !resolvedHeight) || (!resolvedWidth && resolvedHeight))
-        return resolveAgainstIntrinsicWidthOrHeightAndRatio(positioningAreaSize, intrinsicRatio, resolvedWidth, resolvedHeight);
+    if (resolvedSize.width() > 0 || resolvedSize.height() > 0)
+        return resolveAgainstIntrinsicWidthOrHeightAndRatio(positioningAreaSize, intrinsicRatio, resolvedSize.width(), resolvedSize.height());
 
     // If the image has no intrinsic dimensions and has an intrinsic ratio the dimensions must be assumed to be the
     // largest dimensions at that ratio such that neither dimension exceeds the dimensions of the rectangle that
     // establishes the coordinate system for the 'background-position' property.
-    if (!resolvedWidth && !resolvedHeight && !intrinsicRatio.isEmpty())
+    if (!intrinsicRatio.isEmpty())
         return resolveAgainstIntrinsicRatio(positioningAreaSize, intrinsicRatio);
 
     // If the image has no intrinsic ratio either, then the dimensions must be assumed to be the rectangle that