Title: [101546] trunk/Source/WebCore
Revision
101546
Author
timothy_hor...@apple.com
Date
2011-11-30 13:20:12 -0800 (Wed, 30 Nov 2011)

Log Message

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):

Modified Paths

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
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to