Changeset 101546 in webkit


Ignore:
Timestamp:
Nov 30, 2011 1:20:12 PM (12 years ago)
Author:
timothy_horton@apple.com
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):

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r101545 r101546  
     12011-11-30  Tim Horton  <timothy_horton@apple.com>
     2
     3        Implement CSS3 Images cross-fade() image function
     4        https://bugs.webkit.org/show_bug.cgi?id=52162
     5        <rdar://problem/10209254>
     6
     7        Reviewed by Simon Fraser.
     8
     9        Fix platform layering violation by moving CachedImage invalidation code into
     10        CSSCrossfadeValue (instead of CrossfadeGeneratedImage).
     11
     12        No new tests.
     13
     14        * css/CSSCrossfadeValue.cpp:
     15        (WebCore::loadSubimage):
     16        (WebCore::CSSCrossfadeValue::~CSSCrossfadeValue):
     17        (WebCore::CSSCrossfadeValue::customCssText):
     18        (WebCore::CSSCrossfadeValue::fixedSize):
     19        (WebCore::CSSCrossfadeValue::isPending):
     20        (WebCore::CSSCrossfadeValue::loadSubimages):
     21        (WebCore::CSSCrossfadeValue::image):
     22        (WebCore::CSSCrossfadeValue::CrossfadeSubimageObserverProxy::imageChanged):
     23        * css/CSSCrossfadeValue.h:
     24        (WebCore::CSSCrossfadeValue::create):
     25        (WebCore::CSSCrossfadeValue::setPercentage):
     26        (WebCore::CSSCrossfadeValue::CSSCrossfadeValue):
     27        (WebCore::CSSCrossfadeValue::CrossfadeSubimageObserverProxy::CrossfadeSubimageObserverProxy):
     28        (WebCore::CSSCrossfadeValue::CrossfadeSubimageObserverProxy::~CrossfadeSubimageObserverProxy):
     29        (WebCore::CSSCrossfadeValue::CrossfadeSubimageObserverProxy::setReady):
     30        * platform/graphics/CrossfadeGeneratedImage.cpp:
     31        (WebCore::CrossfadeGeneratedImage::CrossfadeGeneratedImage):
     32        (WebCore::CrossfadeGeneratedImage::drawCrossfade):
     33        (WebCore::CrossfadeGeneratedImage::drawPattern):
     34        * platform/graphics/CrossfadeGeneratedImage.h:
     35        (WebCore::CrossfadeGeneratedImage::create):
     36
    1372011-11-30  Vsevolod Vlasov  <vsevik@chromium.org>
    238
  • trunk/Source/WebCore/css/CSSCrossfadeValue.cpp

    r100535 r101546  
    5151}
    5252
    53 static void loadSubimage(CSSValue* value, CachedResourceLoader* cachedResourceLoader)
     53static CachedImage* cachedImageForCSSValue(CSSValue* value, CachedResourceLoader* cachedResourceLoader)
    5454{
    5555    if (value->isImageValue()) {
    56         static_cast<CSSImageValue*>(value)->cachedImage(cachedResourceLoader);
    57         return;
     56        StyleCachedImage* styleCachedImage = static_cast<CSSImageValue*>(value)->cachedImage(cachedResourceLoader);
     57        if (!styleCachedImage)
     58            return 0;
     59
     60        return styleCachedImage->cachedImage();
    5861    }
    5962   
    6063    if (value->isImageGeneratorValue()) {
    6164        static_cast<CSSImageGeneratorValue*>(value)->loadSubimages(cachedResourceLoader);
    62         return;
    63     }
    64    
    65     ASSERT_NOT_REACHED();
    66 }
    67 
    68 static CachedImage* cachedImageForCSSValue(CSSValue* value, const RenderObject* renderer)
    69 {
    70     CachedResourceLoader* cachedResourceLoader = renderer->document()->cachedResourceLoader();
    71    
    72     if (value->isImageValue())
    73         return static_cast<CSSImageValue*>(value)->cachedImage(cachedResourceLoader)->cachedImage();
    74    
    75     if (value->isImageGeneratorValue()) {
    7665        // FIXME: Handle CSSImageGeneratorValue (and thus cross-fades with gradients and canvas).
    7766        return 0;
     
    8372}
    8473
     74CSSCrossfadeValue::~CSSCrossfadeValue()
     75{
     76    if (m_cachedFromImage)
     77        m_cachedFromImage->removeClient(&m_crossfadeSubimageObserver);
     78    if (m_cachedToImage)
     79        m_cachedToImage->removeClient(&m_crossfadeSubimageObserver);
     80}
     81
    8582String CSSCrossfadeValue::customCssText() const
    8683{
    8784    String result = "-webkit-cross-fade(";
    88     result += m_fromImage->cssText() + ", ";
    89     result += m_toImage->cssText() + ", ";
    90     result += m_percentage->cssText();
     85    result += m_fromValue->cssText() + ", ";
     86    result += m_toValue->cssText() + ", ";
     87    result += m_percentageValue->cssText();
    9188    result += ")";
    9289    return result;
     
    9592IntSize CSSCrossfadeValue::fixedSize(const RenderObject* renderer)
    9693{
    97     float percentage = m_percentage->getFloatValue();
     94    float percentage = m_percentageValue->getFloatValue();
    9895    float inversePercentage = 1 - percentage;
    9996
    100     CachedImage* fromImage = cachedImageForCSSValue(m_fromImage.get(), renderer);
    101     CachedImage* toImage = cachedImageForCSSValue(m_toImage.get(), renderer);
     97    CachedResourceLoader* cachedResourceLoader = renderer->document()->cachedResourceLoader();
     98    CachedImage* cachedFromImage = cachedImageForCSSValue(m_fromValue.get(), cachedResourceLoader);
     99    CachedImage* cachedToImage = cachedImageForCSSValue(m_toValue.get(), cachedResourceLoader);
    102100
    103     if (!fromImage || !toImage)
     101    if (!cachedFromImage || !cachedToImage)
    104102        return IntSize();
    105103
    106     IntSize fromImageSize = fromImage->image()->size();
    107     IntSize toImageSize = toImage->image()->size();
     104    IntSize fromImageSize = cachedFromImage->imageForRenderer(renderer)->size();
     105    IntSize toImageSize = cachedToImage->imageForRenderer(renderer)->size();
    108106
    109107    return IntSize(fromImageSize.width() * inversePercentage + toImageSize.width() * percentage,
     
    113111bool CSSCrossfadeValue::isPending() const
    114112{
    115     return subimageIsPending(m_fromImage.get()) || subimageIsPending(m_toImage.get());
     113    return subimageIsPending(m_fromValue.get()) || subimageIsPending(m_toValue.get());
    116114}
    117115
    118116void CSSCrossfadeValue::loadSubimages(CachedResourceLoader* cachedResourceLoader)
    119117{
    120     loadSubimage(m_fromImage.get(), cachedResourceLoader);
    121     loadSubimage(m_toImage.get(), cachedResourceLoader);
     118    m_cachedFromImage = cachedImageForCSSValue(m_fromValue.get(), cachedResourceLoader);
     119    m_cachedToImage = cachedImageForCSSValue(m_toValue.get(), cachedResourceLoader);
     120
     121    if (m_cachedFromImage)
     122        m_cachedFromImage->addClient(&m_crossfadeSubimageObserver);
     123    if (m_cachedToImage)
     124        m_cachedToImage->addClient(&m_crossfadeSubimageObserver);
     125
     126    m_crossfadeSubimageObserver.setReady(true);
    122127}
    123128
     
    127132        return 0;
    128133
    129     CachedImage* fromImage = cachedImageForCSSValue(m_fromImage.get(), renderer);
    130     CachedImage* toImage = cachedImageForCSSValue(m_toImage.get(), renderer);
     134    CachedResourceLoader* cachedResourceLoader = renderer->document()->cachedResourceLoader();
     135    CachedImage* cachedFromImage = cachedImageForCSSValue(m_fromValue.get(), cachedResourceLoader);
     136    CachedImage* cachedToImage = cachedImageForCSSValue(m_toValue.get(), cachedResourceLoader);
     137
     138    if (!cachedFromImage || !cachedToImage)
     139        return Image::nullImage();
     140
     141    Image* fromImage = cachedFromImage->imageForRenderer(renderer);
     142    Image* toImage = cachedToImage->imageForRenderer(renderer);
    131143
    132144    if (!fromImage || !toImage)
    133145        return Image::nullImage();
    134146
    135     m_generatedImage = CrossfadeGeneratedImage::create(fromImage, toImage, m_percentage->getFloatValue(), &m_crossfadeObserver, fixedSize(renderer), size);
     147    m_generatedImage = CrossfadeGeneratedImage::create(fromImage, toImage, m_percentageValue->getFloatValue(), fixedSize(renderer), size);
    136148
    137149    return m_generatedImage.get();
    138150}
    139151
    140 void CSSCrossfadeValue::crossfadeChanged(const IntRect& rect)
     152void CSSCrossfadeValue::crossfadeChanged(const IntRect&)
    141153{
    142     UNUSED_PARAM(rect);
    143 
    144154    RenderObjectSizeCountMap::const_iterator end = clients().end();
    145155    for (RenderObjectSizeCountMap::const_iterator curr = clients().begin(); curr != end; ++curr) {
     
    149159}
    150160
     161void CSSCrossfadeValue::CrossfadeSubimageObserverProxy::imageChanged(CachedImage*, const IntRect* rect)
     162{
     163    if (m_ready)
     164        m_ownerValue->crossfadeChanged(*rect);
     165}
     166
    151167} // namespace WebCore
  • trunk/Source/WebCore/css/CSSCrossfadeValue.h

    r100535 r101546  
    2727#define CSSCrossfadeValue_h
    2828
     29#include "CachedImage.h"
    2930#include "CSSImageGeneratorValue.h"
    3031#include "CSSPrimitiveValue.h"
     
    3536
    3637class CachedImage;
     38class CrossfadeSubimageObserverProxy;
    3739class RenderObject;
    3840class Document;
    3941
    4042class CSSCrossfadeValue : public CSSImageGeneratorValue {
     43    friend class CrossfadeSubimageObserverProxy;
    4144public:
    42     static PassRefPtr<CSSCrossfadeValue> create(PassRefPtr<CSSValue> fromImage, PassRefPtr<CSSValue> toImage)
     45    static PassRefPtr<CSSCrossfadeValue> create(PassRefPtr<CSSValue> fromValue, PassRefPtr<CSSValue> toValue)
    4346    {
    44         return adoptRef(new CSSCrossfadeValue(fromImage, toImage));
     47        return adoptRef(new CSSCrossfadeValue(fromValue, toValue));
    4548    }
     49
     50    ~CSSCrossfadeValue();
    4651
    4752    String customCssText() const;
     
    5459    void loadSubimages(CachedResourceLoader*);
    5560
    56     void setPercentage(PassRefPtr<CSSPrimitiveValue> percentage) { m_percentage = percentage; }
     61    void setPercentage(PassRefPtr<CSSPrimitiveValue> percentageValue) { m_percentageValue = percentageValue; }
    5762
    5863private:
    59     CSSCrossfadeValue(PassRefPtr<CSSValue> fromImage, PassRefPtr<CSSValue> toImage)
     64    CSSCrossfadeValue(PassRefPtr<CSSValue> fromValue, PassRefPtr<CSSValue> toValue)
    6065        : CSSImageGeneratorValue(CrossfadeClass)
    61         , m_fromImage(fromImage)
    62         , m_toImage(toImage)
    63         , m_crossfadeObserver(this) { }
     66        , m_fromValue(fromValue)
     67        , m_toValue(toValue)
     68        , m_cachedFromImage(0)
     69        , m_cachedToImage(0)
     70        , m_crossfadeSubimageObserver(this) { }
    6471
    65     class CrossfadeObserverProxy : public ImageObserver {
     72    class CrossfadeSubimageObserverProxy : public CachedImageClient {
    6673    public:
    67         CrossfadeObserverProxy(CSSCrossfadeValue* ownerValue) : m_ownerValue(ownerValue) { }
    68         virtual ~CrossfadeObserverProxy() { }
    69         virtual void changedInRect(const Image*, const IntRect& rect) OVERRIDE { m_ownerValue->crossfadeChanged(rect); };
    70         virtual bool shouldPauseAnimation(const Image*) OVERRIDE { return false; }
    71         virtual void didDraw(const Image*) OVERRIDE { }
    72         virtual void animationAdvanced(const Image*) OVERRIDE { }
    73         virtual void decodedSizeChanged(const Image*, int) OVERRIDE { }
     74        CrossfadeSubimageObserverProxy(CSSCrossfadeValue* ownerValue)
     75        : m_ownerValue(ownerValue)
     76        , m_ready(false) { }
     77
     78        virtual ~CrossfadeSubimageObserverProxy() { }
     79        virtual void imageChanged(CachedImage*, const IntRect* = 0) OVERRIDE;
     80        void setReady(bool ready) { m_ready = ready; }
    7481    private:
    7582        CSSCrossfadeValue* m_ownerValue;
     83        bool m_ready;
    7684    };
    7785
    7886    void crossfadeChanged(const IntRect&);
    7987
    80     RefPtr<CSSValue> m_fromImage;
    81     RefPtr<CSSValue> m_toImage;
    82     RefPtr<CSSPrimitiveValue> m_percentage;
     88    RefPtr<CSSValue> m_fromValue;
     89    RefPtr<CSSValue> m_toValue;
     90    RefPtr<CSSPrimitiveValue> m_percentageValue;
     91
     92    CachedImage* m_cachedFromImage;
     93    CachedImage* m_cachedToImage;
    8394
    8495    RefPtr<Image> m_generatedImage;
    8596
    86     CrossfadeObserverProxy m_crossfadeObserver;
     97    CrossfadeSubimageObserverProxy m_crossfadeSubimageObserver;
    8798};
    8899
  • trunk/Source/WebCore/platform/graphics/CrossfadeGeneratedImage.cpp

    r100786 r101546  
    2727#include "CrossfadeGeneratedImage.h"
    2828
    29 #include "CSSCrossfadeValue.h"
    3029#include "FloatRect.h"
    3130#include "GraphicsContext.h"
     
    3635namespace WebCore {
    3736
    38 CrossfadeGeneratedImage::CrossfadeGeneratedImage(CachedImage* fromImage, CachedImage* toImage, float percentage, ImageObserver* observer, IntSize crossfadeSize, const IntSize& size)
     37CrossfadeGeneratedImage::CrossfadeGeneratedImage(Image* fromImage, Image* toImage, float percentage, IntSize crossfadeSize, const IntSize& size)
    3938    : m_fromImage(fromImage)
    4039    , m_toImage(toImage)
    4140    , m_percentage(percentage)
    4241    , m_crossfadeSize(crossfadeSize)
    43     , m_observer(observer)
    44     , m_crossfadeSubimageObserver(adoptPtr(new CrossfadeSubimageObserverProxy(this)))
    4542{
    4643    m_size = size;
    47 
    48     m_fromImage->addClient(m_crossfadeSubimageObserver.get());
    49     m_toImage->addClient(m_crossfadeSubimageObserver.get());
    50 
    51     m_crossfadeSubimageObserver->setReady(true);
    52 }
    53 
    54 CrossfadeGeneratedImage::~CrossfadeGeneratedImage()
    55 {
    56     m_fromImage->removeClient(m_crossfadeSubimageObserver.get());
    57     m_toImage->removeClient(m_crossfadeSubimageObserver.get());
    5844}
    5945
     
    6248    float inversePercentage = 1 - m_percentage;
    6349
    64     Image* fromImage = m_fromImage->image();
    65     IntSize fromImageSize = fromImage->size();
    66     Image* toImage = m_toImage->image();
    67     IntSize toImageSize = toImage->size();
     50    IntSize fromImageSize = m_fromImage->size();
     51    IntSize toImageSize = m_toImage->size();
    6852
    6953    // Draw nothing if either of the images hasn't loaded yet.
    70     if (fromImage == Image::nullImage() || toImage == Image::nullImage())
     54    if (m_fromImage == Image::nullImage() || m_toImage == Image::nullImage())
    7155        return;
    7256
     
    8468                       -srcRect.y() * fromImageSize.height() / static_cast<float>(m_crossfadeSize.height()));
    8569    context->setAlpha(inversePercentage);
    86     context->drawImage(fromImage, ColorSpaceDeviceRGB, IntPoint());
     70    context->drawImage(m_fromImage, ColorSpaceDeviceRGB, IntPoint());
    8771    context->restore();
    8872
     
    9579                       -srcRect.y() * toImageSize.height() / static_cast<float>(m_crossfadeSize.height()));
    9680    context->setAlpha(m_percentage);
    97     context->drawImage(toImage, ColorSpaceDeviceRGB, IntPoint(), CompositePlusLighter);
     81    context->drawImage(m_toImage, ColorSpaceDeviceRGB, IntPoint(), CompositePlusLighter);
    9882    context->restore();
    9983
     
    125109    imageBuffer->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, compositeOp, destRect);
    126110}
    127    
    128 void CrossfadeSubimageObserverProxy::imageChanged(CachedImage* image, const IntRect* rect)
    129 {
    130     if (m_ready)
    131         m_ownerValue->imageChanged(image, rect);
    132 }
    133 
    134 void CrossfadeGeneratedImage::imageChanged(CachedImage* image, const IntRect* rect)
    135 {
    136     UNUSED_PARAM(image);
    137     m_observer->changedInRect(this, *rect);
    138 }
    139111
    140112}
  • trunk/Source/WebCore/platform/graphics/CrossfadeGeneratedImage.h

    r100786 r101546  
    2727#define CrossfadeGeneratedImage_h
    2828
    29 #include "CachedImage.h"
    3029#include "GeneratedImage.h"
    3130#include "Image.h"
     
    3736
    3837class CSSCrossfadeValue;
    39 class CrossfadeSubimageObserverProxy;
    4038
    4139class CrossfadeGeneratedImage : public GeneratedImage {
    42     friend class CrossfadeSubimageObserverProxy;
    4340public:
    44     static PassRefPtr<CrossfadeGeneratedImage> create(CachedImage* fromImage, CachedImage* toImage, float percentage, ImageObserver* observer, IntSize crossfadeSize, const IntSize& size)
     41    static PassRefPtr<CrossfadeGeneratedImage> create(Image* fromImage, Image* toImage, float percentage, IntSize crossfadeSize, const IntSize& size)
    4542    {
    46         return adoptRef(new CrossfadeGeneratedImage(fromImage, toImage, percentage, observer, crossfadeSize, size));
     43        return adoptRef(new CrossfadeGeneratedImage(fromImage, toImage, percentage, crossfadeSize, size));
    4744    }
    48     virtual ~CrossfadeGeneratedImage();
    4945
    5046protected:
     
    5248    virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator, const FloatRect& destRect);
    5349
    54     CrossfadeGeneratedImage(CachedImage* fromImage, CachedImage* toImage, float percentage, ImageObserver*, IntSize crossfadeSize, const IntSize&);
    55 
    56     void imageChanged(CachedImage*, const IntRect* = 0);
     50    CrossfadeGeneratedImage(Image* fromImage, Image* toImage, float percentage, IntSize crossfadeSize, const IntSize&);
    5751
    5852private:
    5953    void drawCrossfade(GraphicsContext*, const FloatRect& srcRect);
    6054
    61     // These are owned by the CSSCrossfadeValue that owns us.
    62     CachedImage* m_fromImage;
    63     CachedImage* m_toImage;
     55    Image* m_fromImage;
     56    Image* m_toImage;
    6457
    6558    float m_percentage;
    6659    IntSize m_crossfadeSize;
    67 
    68     ImageObserver* m_observer;
    69     OwnPtr<CrossfadeSubimageObserverProxy> m_crossfadeSubimageObserver;
    70 };
    71 
    72 class CrossfadeSubimageObserverProxy : public CachedImageClient {
    73 public:
    74     CrossfadeSubimageObserverProxy(CrossfadeGeneratedImage* ownerValue)
    75         : m_ownerValue(ownerValue)
    76         , m_ready(false) { }
    77 
    78     virtual ~CrossfadeSubimageObserverProxy() { }
    79     virtual void imageChanged(CachedImage*, const IntRect* = 0) OVERRIDE;
    80     void setReady(bool ready) { m_ready = ready; }
    81 private:
    82     CrossfadeGeneratedImage* m_ownerValue;
    83     bool m_ready;
    8460};
    8561
Note: See TracChangeset for help on using the changeset viewer.