Diff
Modified: trunk/Source/WebCore/ChangeLog (101545 => 101546)
--- trunk/Source/WebCore/ChangeLog 2011-11-30 21:08:53 UTC (rev 101545)
+++ trunk/Source/WebCore/ChangeLog 2011-11-30 21:20:12 UTC (rev 101546)
@@ -1,3 +1,39 @@
+2011-11-30 Tim Horton <timothy_hor...@apple.com>
+
+ Implement CSS3 Images cross-fade() image function
+ https://bugs.webkit.org/show_bug.cgi?id=52162
+ <rdar://problem/10209254>
+
+ Reviewed by Simon Fraser.
+
+ Fix platform layering violation by moving CachedImage invalidation code into
+ CSSCrossfadeValue (instead of CrossfadeGeneratedImage).
+
+ No new tests.
+
+ * css/CSSCrossfadeValue.cpp:
+ (WebCore::loadSubimage):
+ (WebCore::CSSCrossfadeValue::~CSSCrossfadeValue):
+ (WebCore::CSSCrossfadeValue::customCssText):
+ (WebCore::CSSCrossfadeValue::fixedSize):
+ (WebCore::CSSCrossfadeValue::isPending):
+ (WebCore::CSSCrossfadeValue::loadSubimages):
+ (WebCore::CSSCrossfadeValue::image):
+ (WebCore::CSSCrossfadeValue::CrossfadeSubimageObserverProxy::imageChanged):
+ * css/CSSCrossfadeValue.h:
+ (WebCore::CSSCrossfadeValue::create):
+ (WebCore::CSSCrossfadeValue::setPercentage):
+ (WebCore::CSSCrossfadeValue::CSSCrossfadeValue):
+ (WebCore::CSSCrossfadeValue::CrossfadeSubimageObserverProxy::CrossfadeSubimageObserverProxy):
+ (WebCore::CSSCrossfadeValue::CrossfadeSubimageObserverProxy::~CrossfadeSubimageObserverProxy):
+ (WebCore::CSSCrossfadeValue::CrossfadeSubimageObserverProxy::setReady):
+ * platform/graphics/CrossfadeGeneratedImage.cpp:
+ (WebCore::CrossfadeGeneratedImage::CrossfadeGeneratedImage):
+ (WebCore::CrossfadeGeneratedImage::drawCrossfade):
+ (WebCore::CrossfadeGeneratedImage::drawPattern):
+ * platform/graphics/CrossfadeGeneratedImage.h:
+ (WebCore::CrossfadeGeneratedImage::create):
+
2011-11-30 Vsevolod Vlasov <vse...@chromium.org>
Web Inspector: [Regression] Successfully loaded XHRs are shown as canceled.
Modified: trunk/Source/WebCore/css/CSSCrossfadeValue.cpp (101545 => 101546)
--- trunk/Source/WebCore/css/CSSCrossfadeValue.cpp 2011-11-30 21:08:53 UTC (rev 101545)
+++ trunk/Source/WebCore/css/CSSCrossfadeValue.cpp 2011-11-30 21:20:12 UTC (rev 101546)
@@ -50,29 +50,18 @@
return false;
}
-static void loadSubimage(CSSValue* value, CachedResourceLoader* cachedResourceLoader)
+static CachedImage* cachedImageForCSSValue(CSSValue* value, CachedResourceLoader* cachedResourceLoader)
{
if (value->isImageValue()) {
- static_cast<CSSImageValue*>(value)->cachedImage(cachedResourceLoader);
- return;
+ StyleCachedImage* styleCachedImage = static_cast<CSSImageValue*>(value)->cachedImage(cachedResourceLoader);
+ if (!styleCachedImage)
+ return 0;
+
+ return styleCachedImage->cachedImage();
}
if (value->isImageGeneratorValue()) {
static_cast<CSSImageGeneratorValue*>(value)->loadSubimages(cachedResourceLoader);
- return;
- }
-
- ASSERT_NOT_REACHED();
-}
-
-static CachedImage* cachedImageForCSSValue(CSSValue* value, const RenderObject* renderer)
-{
- CachedResourceLoader* cachedResourceLoader = renderer->document()->cachedResourceLoader();
-
- if (value->isImageValue())
- return static_cast<CSSImageValue*>(value)->cachedImage(cachedResourceLoader)->cachedImage();
-
- if (value->isImageGeneratorValue()) {
// FIXME: Handle CSSImageGeneratorValue (and thus cross-fades with gradients and canvas).
return 0;
}
@@ -82,29 +71,38 @@
return 0;
}
+CSSCrossfadeValue::~CSSCrossfadeValue()
+{
+ if (m_cachedFromImage)
+ m_cachedFromImage->removeClient(&m_crossfadeSubimageObserver);
+ if (m_cachedToImage)
+ m_cachedToImage->removeClient(&m_crossfadeSubimageObserver);
+}
+
String CSSCrossfadeValue::customCssText() const
{
String result = "-webkit-cross-fade(";
- result += m_fromImage->cssText() + ", ";
- result += m_toImage->cssText() + ", ";
- result += m_percentage->cssText();
+ result += m_fromValue->cssText() + ", ";
+ result += m_toValue->cssText() + ", ";
+ result += m_percentageValue->cssText();
result += ")";
return result;
}
IntSize CSSCrossfadeValue::fixedSize(const RenderObject* renderer)
{
- float percentage = m_percentage->getFloatValue();
+ float percentage = m_percentageValue->getFloatValue();
float inversePercentage = 1 - percentage;
- CachedImage* fromImage = cachedImageForCSSValue(m_fromImage.get(), renderer);
- CachedImage* toImage = cachedImageForCSSValue(m_toImage.get(), renderer);
+ CachedResourceLoader* cachedResourceLoader = renderer->document()->cachedResourceLoader();
+ CachedImage* cachedFromImage = cachedImageForCSSValue(m_fromValue.get(), cachedResourceLoader);
+ CachedImage* cachedToImage = cachedImageForCSSValue(m_toValue.get(), cachedResourceLoader);
- if (!fromImage || !toImage)
+ if (!cachedFromImage || !cachedToImage)
return IntSize();
- IntSize fromImageSize = fromImage->image()->size();
- IntSize toImageSize = toImage->image()->size();
+ IntSize fromImageSize = cachedFromImage->imageForRenderer(renderer)->size();
+ IntSize toImageSize = cachedToImage->imageForRenderer(renderer)->size();
return IntSize(fromImageSize.width() * inversePercentage + toImageSize.width() * percentage,
fromImageSize.height() * inversePercentage + toImageSize.height() * percentage);
@@ -112,13 +110,20 @@
bool CSSCrossfadeValue::isPending() const
{
- return subimageIsPending(m_fromImage.get()) || subimageIsPending(m_toImage.get());
+ return subimageIsPending(m_fromValue.get()) || subimageIsPending(m_toValue.get());
}
void CSSCrossfadeValue::loadSubimages(CachedResourceLoader* cachedResourceLoader)
{
- loadSubimage(m_fromImage.get(), cachedResourceLoader);
- loadSubimage(m_toImage.get(), cachedResourceLoader);
+ m_cachedFromImage = cachedImageForCSSValue(m_fromValue.get(), cachedResourceLoader);
+ m_cachedToImage = cachedImageForCSSValue(m_toValue.get(), cachedResourceLoader);
+
+ if (m_cachedFromImage)
+ m_cachedFromImage->addClient(&m_crossfadeSubimageObserver);
+ if (m_cachedToImage)
+ m_cachedToImage->addClient(&m_crossfadeSubimageObserver);
+
+ m_crossfadeSubimageObserver.setReady(true);
}
PassRefPtr<Image> CSSCrossfadeValue::image(RenderObject* renderer, const IntSize& size)
@@ -126,21 +131,26 @@
if (size.isEmpty())
return 0;
- CachedImage* fromImage = cachedImageForCSSValue(m_fromImage.get(), renderer);
- CachedImage* toImage = cachedImageForCSSValue(m_toImage.get(), renderer);
+ CachedResourceLoader* cachedResourceLoader = renderer->document()->cachedResourceLoader();
+ CachedImage* cachedFromImage = cachedImageForCSSValue(m_fromValue.get(), cachedResourceLoader);
+ CachedImage* cachedToImage = cachedImageForCSSValue(m_toValue.get(), cachedResourceLoader);
+ if (!cachedFromImage || !cachedToImage)
+ return Image::nullImage();
+
+ Image* fromImage = cachedFromImage->imageForRenderer(renderer);
+ Image* toImage = cachedToImage->imageForRenderer(renderer);
+
if (!fromImage || !toImage)
return Image::nullImage();
- m_generatedImage = CrossfadeGeneratedImage::create(fromImage, toImage, m_percentage->getFloatValue(), &m_crossfadeObserver, fixedSize(renderer), size);
+ m_generatedImage = CrossfadeGeneratedImage::create(fromImage, toImage, m_percentageValue->getFloatValue(), fixedSize(renderer), size);
return m_generatedImage.get();
}
-void CSSCrossfadeValue::crossfadeChanged(const IntRect& rect)
+void CSSCrossfadeValue::crossfadeChanged(const IntRect&)
{
- UNUSED_PARAM(rect);
-
RenderObjectSizeCountMap::const_iterator end = clients().end();
for (RenderObjectSizeCountMap::const_iterator curr = clients().begin(); curr != end; ++curr) {
RenderObject* client = const_cast<RenderObject*>(curr->first);
@@ -148,4 +158,10 @@
}
}
+void CSSCrossfadeValue::CrossfadeSubimageObserverProxy::imageChanged(CachedImage*, const IntRect* rect)
+{
+ if (m_ready)
+ m_ownerValue->crossfadeChanged(*rect);
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/css/CSSCrossfadeValue.h (101545 => 101546)
--- trunk/Source/WebCore/css/CSSCrossfadeValue.h 2011-11-30 21:08:53 UTC (rev 101545)
+++ trunk/Source/WebCore/css/CSSCrossfadeValue.h 2011-11-30 21:20:12 UTC (rev 101546)
@@ -26,6 +26,7 @@
#ifndef CSSCrossfadeValue_h
#define CSSCrossfadeValue_h
+#include "CachedImage.h"
#include "CSSImageGeneratorValue.h"
#include "CSSPrimitiveValue.h"
#include "Image.h"
@@ -34,16 +35,20 @@
namespace WebCore {
class CachedImage;
+class CrossfadeSubimageObserverProxy;
class RenderObject;
class Document;
class CSSCrossfadeValue : public CSSImageGeneratorValue {
+ friend class CrossfadeSubimageObserverProxy;
public:
- static PassRefPtr<CSSCrossfadeValue> create(PassRefPtr<CSSValue> fromImage, PassRefPtr<CSSValue> toImage)
+ static PassRefPtr<CSSCrossfadeValue> create(PassRefPtr<CSSValue> fromValue, PassRefPtr<CSSValue> toValue)
{
- return adoptRef(new CSSCrossfadeValue(fromImage, toImage));
+ return adoptRef(new CSSCrossfadeValue(fromValue, toValue));
}
+ ~CSSCrossfadeValue();
+
String customCssText() const;
PassRefPtr<Image> image(RenderObject*, const IntSize&);
@@ -53,37 +58,43 @@
bool isPending() const;
void loadSubimages(CachedResourceLoader*);
- void setPercentage(PassRefPtr<CSSPrimitiveValue> percentage) { m_percentage = percentage; }
+ void setPercentage(PassRefPtr<CSSPrimitiveValue> percentageValue) { m_percentageValue = percentageValue; }
private:
- CSSCrossfadeValue(PassRefPtr<CSSValue> fromImage, PassRefPtr<CSSValue> toImage)
+ CSSCrossfadeValue(PassRefPtr<CSSValue> fromValue, PassRefPtr<CSSValue> toValue)
: CSSImageGeneratorValue(CrossfadeClass)
- , m_fromImage(fromImage)
- , m_toImage(toImage)
- , m_crossfadeObserver(this) { }
+ , m_fromValue(fromValue)
+ , m_toValue(toValue)
+ , m_cachedFromImage(0)
+ , m_cachedToImage(0)
+ , m_crossfadeSubimageObserver(this) { }
- class CrossfadeObserverProxy : public ImageObserver {
+ class CrossfadeSubimageObserverProxy : public CachedImageClient {
public:
- CrossfadeObserverProxy(CSSCrossfadeValue* ownerValue) : m_ownerValue(ownerValue) { }
- virtual ~CrossfadeObserverProxy() { }
- virtual void changedInRect(const Image*, const IntRect& rect) OVERRIDE { m_ownerValue->crossfadeChanged(rect); };
- virtual bool shouldPauseAnimation(const Image*) OVERRIDE { return false; }
- virtual void didDraw(const Image*) OVERRIDE { }
- virtual void animationAdvanced(const Image*) OVERRIDE { }
- virtual void decodedSizeChanged(const Image*, int) OVERRIDE { }
+ CrossfadeSubimageObserverProxy(CSSCrossfadeValue* ownerValue)
+ : m_ownerValue(ownerValue)
+ , m_ready(false) { }
+
+ virtual ~CrossfadeSubimageObserverProxy() { }
+ virtual void imageChanged(CachedImage*, const IntRect* = 0) OVERRIDE;
+ void setReady(bool ready) { m_ready = ready; }
private:
CSSCrossfadeValue* m_ownerValue;
+ bool m_ready;
};
void crossfadeChanged(const IntRect&);
- RefPtr<CSSValue> m_fromImage;
- RefPtr<CSSValue> m_toImage;
- RefPtr<CSSPrimitiveValue> m_percentage;
+ RefPtr<CSSValue> m_fromValue;
+ RefPtr<CSSValue> m_toValue;
+ RefPtr<CSSPrimitiveValue> m_percentageValue;
+ CachedImage* m_cachedFromImage;
+ CachedImage* m_cachedToImage;
+
RefPtr<Image> m_generatedImage;
- CrossfadeObserverProxy m_crossfadeObserver;
+ CrossfadeSubimageObserverProxy m_crossfadeSubimageObserver;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/CrossfadeGeneratedImage.cpp (101545 => 101546)
--- trunk/Source/WebCore/platform/graphics/CrossfadeGeneratedImage.cpp 2011-11-30 21:08:53 UTC (rev 101545)
+++ trunk/Source/WebCore/platform/graphics/CrossfadeGeneratedImage.cpp 2011-11-30 21:20:12 UTC (rev 101546)
@@ -26,7 +26,6 @@
#include "config.h"
#include "CrossfadeGeneratedImage.h"
-#include "CSSCrossfadeValue.h"
#include "FloatRect.h"
#include "GraphicsContext.h"
#include "ImageBuffer.h"
@@ -35,39 +34,24 @@
namespace WebCore {
-CrossfadeGeneratedImage::CrossfadeGeneratedImage(CachedImage* fromImage, CachedImage* toImage, float percentage, ImageObserver* observer, IntSize crossfadeSize, const IntSize& size)
+CrossfadeGeneratedImage::CrossfadeGeneratedImage(Image* fromImage, Image* toImage, float percentage, IntSize crossfadeSize, const IntSize& size)
: m_fromImage(fromImage)
, m_toImage(toImage)
, m_percentage(percentage)
, m_crossfadeSize(crossfadeSize)
- , m_observer(observer)
- , m_crossfadeSubimageObserver(adoptPtr(new CrossfadeSubimageObserverProxy(this)))
{
m_size = size;
-
- m_fromImage->addClient(m_crossfadeSubimageObserver.get());
- m_toImage->addClient(m_crossfadeSubimageObserver.get());
-
- m_crossfadeSubimageObserver->setReady(true);
}
-CrossfadeGeneratedImage::~CrossfadeGeneratedImage()
-{
- m_fromImage->removeClient(m_crossfadeSubimageObserver.get());
- m_toImage->removeClient(m_crossfadeSubimageObserver.get());
-}
-
void CrossfadeGeneratedImage::drawCrossfade(GraphicsContext* context, const FloatRect& srcRect)
{
float inversePercentage = 1 - m_percentage;
- Image* fromImage = m_fromImage->image();
- IntSize fromImageSize = fromImage->size();
- Image* toImage = m_toImage->image();
- IntSize toImageSize = toImage->size();
+ IntSize fromImageSize = m_fromImage->size();
+ IntSize toImageSize = m_toImage->size();
// Draw nothing if either of the images hasn't loaded yet.
- if (fromImage == Image::nullImage() || toImage == Image::nullImage())
+ if (m_fromImage == Image::nullImage() || m_toImage == Image::nullImage())
return;
GraphicsContextStateSaver stateSaver(*context);
@@ -83,7 +67,7 @@
context->translate(-srcRect.x() * fromImageSize.width() / static_cast<float>(m_crossfadeSize.width()),
-srcRect.y() * fromImageSize.height() / static_cast<float>(m_crossfadeSize.height()));
context->setAlpha(inversePercentage);
- context->drawImage(fromImage, ColorSpaceDeviceRGB, IntPoint());
+ context->drawImage(m_fromImage, ColorSpaceDeviceRGB, IntPoint());
context->restore();
// Draw the image we're fading towards.
@@ -94,7 +78,7 @@
context->translate(-srcRect.x() * toImageSize.width() / static_cast<float>(m_crossfadeSize.width()),
-srcRect.y() * toImageSize.height() / static_cast<float>(m_crossfadeSize.height()));
context->setAlpha(m_percentage);
- context->drawImage(toImage, ColorSpaceDeviceRGB, IntPoint(), CompositePlusLighter);
+ context->drawImage(m_toImage, ColorSpaceDeviceRGB, IntPoint(), CompositePlusLighter);
context->restore();
context->endTransparencyLayer();
@@ -124,17 +108,5 @@
// Tile the image buffer into the context.
imageBuffer->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, compositeOp, destRect);
}
-
-void CrossfadeSubimageObserverProxy::imageChanged(CachedImage* image, const IntRect* rect)
-{
- if (m_ready)
- m_ownerValue->imageChanged(image, rect);
-}
-void CrossfadeGeneratedImage::imageChanged(CachedImage* image, const IntRect* rect)
-{
- UNUSED_PARAM(image);
- m_observer->changedInRect(this, *rect);
}
-
-}
Modified: trunk/Source/WebCore/platform/graphics/CrossfadeGeneratedImage.h (101545 => 101546)
--- trunk/Source/WebCore/platform/graphics/CrossfadeGeneratedImage.h 2011-11-30 21:08:53 UTC (rev 101545)
+++ trunk/Source/WebCore/platform/graphics/CrossfadeGeneratedImage.h 2011-11-30 21:20:12 UTC (rev 101546)
@@ -26,7 +26,6 @@
#ifndef CrossfadeGeneratedImage_h
#define CrossfadeGeneratedImage_h
-#include "CachedImage.h"
#include "GeneratedImage.h"
#include "Image.h"
#include "ImageObserver.h"
@@ -36,53 +35,30 @@
namespace WebCore {
class CSSCrossfadeValue;
-class CrossfadeSubimageObserverProxy;
class CrossfadeGeneratedImage : public GeneratedImage {
- friend class CrossfadeSubimageObserverProxy;
public:
- static PassRefPtr<CrossfadeGeneratedImage> create(CachedImage* fromImage, CachedImage* toImage, float percentage, ImageObserver* observer, IntSize crossfadeSize, const IntSize& size)
+ static PassRefPtr<CrossfadeGeneratedImage> create(Image* fromImage, Image* toImage, float percentage, IntSize crossfadeSize, const IntSize& size)
{
- return adoptRef(new CrossfadeGeneratedImage(fromImage, toImage, percentage, observer, crossfadeSize, size));
+ return adoptRef(new CrossfadeGeneratedImage(fromImage, toImage, percentage, crossfadeSize, size));
}
- virtual ~CrossfadeGeneratedImage();
protected:
virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator);
virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator, const FloatRect& destRect);
- CrossfadeGeneratedImage(CachedImage* fromImage, CachedImage* toImage, float percentage, ImageObserver*, IntSize crossfadeSize, const IntSize&);
+ CrossfadeGeneratedImage(Image* fromImage, Image* toImage, float percentage, IntSize crossfadeSize, const IntSize&);
- void imageChanged(CachedImage*, const IntRect* = 0);
-
private:
void drawCrossfade(GraphicsContext*, const FloatRect& srcRect);
- // These are owned by the CSSCrossfadeValue that owns us.
- CachedImage* m_fromImage;
- CachedImage* m_toImage;
+ Image* m_fromImage;
+ Image* m_toImage;
float m_percentage;
IntSize m_crossfadeSize;
-
- ImageObserver* m_observer;
- OwnPtr<CrossfadeSubimageObserverProxy> m_crossfadeSubimageObserver;
};
-class CrossfadeSubimageObserverProxy : public CachedImageClient {
-public:
- CrossfadeSubimageObserverProxy(CrossfadeGeneratedImage* ownerValue)
- : m_ownerValue(ownerValue)
- , m_ready(false) { }
-
- virtual ~CrossfadeSubimageObserverProxy() { }
- virtual void imageChanged(CachedImage*, const IntRect* = 0) OVERRIDE;
- void setReady(bool ready) { m_ready = ready; }
-private:
- CrossfadeGeneratedImage* m_ownerValue;
- bool m_ready;
-};
-
}
#endif