From a2bc0bdcf3b0bfafdd848506605c93b97b8a5266 Mon Sep 17 00:00:00 2001 From: "shinyak@chromium.org" Date: Fri, 13 Apr 2012 08:39:58 +0000 Subject: [PATCH] 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. 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 | 12 +++++ .../css/zoom-background-repeat-x-expected.html | 18 +++++++ LayoutTests/fast/css/zoom-background-repeat-x.html | 19 ++++++++ .../css/zoom-background-repeat-y-expected.html | 17 +++++++ LayoutTests/fast/css/zoom-background-repeat-y.html | 18 +++++++ Source/WebCore/ChangeLog | 26 ++++++++++ Source/WebCore/loader/cache/CachedImage.cpp | 15 +++--- Source/WebCore/platform/graphics/IntSize.h | 19 ++++++-- Source/WebCore/rendering/RenderBoxModelObject.cpp | 56 ++++++++++------------ 9 files changed, 158 insertions(+), 42 deletions(-) create mode 100644 LayoutTests/fast/css/zoom-background-repeat-x-expected.html create mode 100644 LayoutTests/fast/css/zoom-background-repeat-x.html create mode 100644 LayoutTests/fast/css/zoom-background-repeat-y-expected.html create mode 100644 LayoutTests/fast/css/zoom-background-repeat-y.html diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog index 32bcf58..c6abfd2 100644 --- a/LayoutTests/ChangeLog +++ b/LayoutTests/ChangeLog @@ -1,3 +1,15 @@ +2012-04-13 Shinya Kawanaka + + 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 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 index 0000000..b0daf3c --- /dev/null +++ b/LayoutTests/fast/css/zoom-background-repeat-x-expected.html @@ -0,0 +1,18 @@ + + + + + + +
+ diff --git a/LayoutTests/fast/css/zoom-background-repeat-x.html b/LayoutTests/fast/css/zoom-background-repeat-x.html new file mode 100644 index 0000000..b408323 --- /dev/null +++ b/LayoutTests/fast/css/zoom-background-repeat-x.html @@ -0,0 +1,19 @@ + + + + + + +
+ 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 index 0000000..c5b285a --- /dev/null +++ b/LayoutTests/fast/css/zoom-background-repeat-y-expected.html @@ -0,0 +1,17 @@ + + + + + + +
+ diff --git a/LayoutTests/fast/css/zoom-background-repeat-y.html b/LayoutTests/fast/css/zoom-background-repeat-y.html new file mode 100644 index 0000000..053cded --- /dev/null +++ b/LayoutTests/fast/css/zoom-background-repeat-y.html @@ -0,0 +1,18 @@ + + + + + + +
+ diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index 67e9184..b24ebe1 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,29 @@ +2012-04-13 Shinya Kawanaka + + 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 Prepare submitForm for seamless navigation diff --git a/Source/WebCore/loader/cache/CachedImage.cpp b/Source/WebCore/loader/cache/CachedImage.cpp index 51f2f00..0af8404 100644 --- a/Source/WebCore/loader/cache/CachedImage.cpp +++ b/Source/WebCore/loader/cache/CachedImage.cpp @@ -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) diff --git a/Source/WebCore/platform/graphics/IntSize.h b/Source/WebCore/platform/graphics/IntSize.h index 8ec6539..c8a549d 100644 --- a/Source/WebCore/platform/graphics/IntSize.h +++ b/Source/WebCore/platform/graphics/IntSize.h @@ -80,13 +80,18 @@ public: m_width += width; m_height += height; } + + void scale(float widthScale, float heightScale) + { + m_width = static_cast(static_cast(m_width) * widthScale); + m_height = static_cast(static_cast(m_height) * heightScale); + } void scale(float scale) { - m_width = static_cast(static_cast(m_width) * scale); - m_height = static_cast(static_cast(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; diff --git a/Source/WebCore/rendering/RenderBoxModelObject.cpp b/Source/WebCore/rendering/RenderBoxModelObject.cpp index 4814d22..b7f29ba 100644 --- a/Source/WebCore/rendering/RenderBoxModelObject.cpp +++ b/Source/WebCore/rendering/RenderBoxModelObject.cpp @@ -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(round(positioningAreaSize.width() * intrinsicWidth.percent() / 100)); - resolvedHeight = static_cast(round(positioningAreaSize.height() * intrinsicHeight.percent() / 100)); - } else { - if (intrinsicWidth.isFixed()) - resolvedWidth = static_cast(intrinsicWidth.value() * style()->effectiveZoom()); - if (intrinsicHeight.isFixed()) - resolvedHeight = static_cast(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(round(positioningAreaSize.width() * intrinsicWidth.percent() / 100)); + int resolvedHeight = static_cast(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 -- 2.7.4