Implement CSS3 Images cross-fade() image function
https://bugs.webkit.org/show_bug.cgi?id=52162
<rdar://problem/10209254>
Reviewed by Simon Fraser.
Render -webkit-cross-fade. Only cross-fades entirely composed of images will render for now,
cross-fades involving generated images are not yet implemented.
Reorganize GeneratedImage to be the base class for GeneratorGeneratedImage and CrossfadeGeneratedImage.
Add a pending state to CSSImageGeneratorValue, which is used to enable the pending-images loading
mechanism for -webkit-cross-fade's sub-images. Rework the logic in CSSStyleSelector to support pending
generated images.
Support parsing fractional values for the cross-fade amount (for example, 0.5 = 50%). Clamp cross-fade
amount to 0-1 range.
Tests: css3/images/cross-fade-invalidation.html
css3/images/cross-fade-simple.html
css3/images/cross-fade-sizing.html
css3/images/cross-fade-tiled.html
* CMakeLists.txt:
* GNUmakefile.list.am:
* Target.pri:
* WebCore.gypi:
* WebCore.xcodeproj/project.pbxproj:
* css/CSSCanvasValue.h:
(WebCore::CSSCanvasValue::isPending):
(WebCore::CSSCanvasValue::loadSubimages):
* css/CSSCrossfadeValue.cpp:
(WebCore::CSSCrossfadeValue::isPending):
(WebCore::CSSCrossfadeValue::loadSubimages):
(WebCore::subimageIsPending):
(WebCore::loadSubimage):
(WebCore::cachedImageForCSSValue):
(WebCore::CSSCrossfadeValue::image):
(WebCore::CSSCrossfadeValue::crossfadeChanged):
* css/CSSCrossfadeValue.h:
(WebCore::CSSCrossfadeValue::create):
(WebCore::CSSCrossfadeValue::~CSSCrossfadeValue):
(WebCore::CSSCrossfadeValue::fixedSize):
(WebCore::CSSCrossfadeValue::CSSCrossfadeValue):
(WebCore::CSSCrossfadeValue::CrossfadeObserverProxy::CrossfadeObserverProxy):
* css/CSSGradientValue.cpp:
(WebCore::CSSGradientValue::image):
* css/CSSGradientValue.h:
(WebCore::CSSGradientValue::isPending):
(WebCore::CSSGradientValue::loadSubimages):
* css/CSSImageGeneratorValue.cpp:
(WebCore::CSSImageGeneratorValue::generatedOrPendingImage):
(WebCore::CSSImageGeneratorValue::generatedImage):
(WebCore::CSSImageGeneratorValue::isPending):
(WebCore::CSSImageGeneratorValue::loadSubimages):
* css/CSSImageGeneratorValue.h:
* css/CSSParser.cpp:
(WebCore::CSSParser::parseCrossfade):
* css/CSSStyleSelector.cpp:
(WebCore::CSSStyleSelector::styleImage):
(WebCore::CSSStyleSelector::generatedOrPendingFromValue):
(WebCore::CSSStyleSelector::loadPendingImage):
(WebCore::CSSStyleSelector::loadPendingImages):
* css/CSSStyleSelector.h:
* platform/graphics/BitmapImage.h:
* platform/graphics/CrossfadeGeneratedImage.cpp: Added.
(WebCore::CrossfadeGeneratedImage::CrossfadeGeneratedImage):
(WebCore::CrossfadeGeneratedImage::~CrossfadeGeneratedImage):
(WebCore::CrossfadeGeneratedImage::drawCrossfade):
(WebCore::CrossfadeGeneratedImage::draw):
(WebCore::CrossfadeGeneratedImage::drawPattern):
(WebCore::CrossfadeGeneratedImage::imageChanged):
* platform/graphics/CrossfadeGeneratedImage.h: Added.
(WebCore::CrossfadeGeneratedImage::create):
(WebCore::CrossfadeSubimageObserverProxy::CrossfadeSubimageObserverProxy):
(WebCore::CrossfadeSubimageObserverProxy::setReady):
* platform/graphics/GeneratedImage.h:
(WebCore::GeneratedImage::GeneratedImage):
* platform/graphics/GeneratorGeneratedImage.cpp: Renamed from Source/WebCore/platform/graphics/GeneratedImage.cpp.
(WebCore::GeneratorGeneratedImage::draw):
(WebCore::GeneratorGeneratedImage::drawPattern):
(WebCore::GeneratedImage::computeIntrinsicDimensions):
* platform/graphics/GeneratorGeneratedImage.h: Copied from Source/WebCore/platform/graphics/GeneratedImage.h.
(WebCore::GeneratorGeneratedImage::create):
(WebCore::GeneratorGeneratedImage::~GeneratorGeneratedImage):
(WebCore::GeneratorGeneratedImage::GeneratorGeneratedImage):
* platform/graphics/Image.h:
* platform/graphics/ImageBuffer.h:
* rendering/style/StylePendingImage.h:
(WebCore::StylePendingImage::create):
(WebCore::StylePendingImage::data):
(WebCore::StylePendingImage::cssImageValue):
(WebCore::StylePendingImage::cssImageGeneratorValue):
(WebCore::StylePendingImage::StylePendingImage):
Add tests of -webkit-cross-fade, ensuring that simple cross-fades between
two images work correctly.
Adjust fast/css/getComputedStyle/computed-style-cross-fade.html to test
fractional and out-of-range cross-fade percentage values.
* css3/images/cross-fade-invalidation.html: Added.
* css3/images/cross-fade-simple.html: Added.
* css3/images/cross-fade-sizing.html: Added.
* css3/images/cross-fade-tiled.html: Added.
* css3/images/resources/blue-10.png: Added.
* css3/images/resources/blue-100.png: Added.
* css3/images/resources/green-10.png: Added.
* css3/images/resources/green-100.png: Added.
* css3/images/resources/green-circle.svg: Added.
* css3/images/resources/red-10.png: Added.
* css3/images/resources/red-100.png: Added.
* fast/css/getComputedStyle/computed-style-cross-fade-expected.txt:
* fast/css/getComputedStyle/computed-style-cross-fade.html:
* platform/mac/css3/images/cross-fade-invalidation-expected.png: Added.
* platform/mac/css3/images/cross-fade-invalidation-expected.txt: Added.
* platform/mac/css3/images/cross-fade-simple-expected.png: Added.
* platform/mac/css3/images/cross-fade-simple-expected.txt: Added.
* platform/mac/css3/images/cross-fade-sizing-expected.png: Added.
* platform/mac/css3/images/cross-fade-sizing-expected.txt: Added.
* platform/mac/css3/images/cross-fade-tiled-expected.png: Added.
* platform/mac/css3/images/cross-fade-tiled-expected.txt: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@100535 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/css/CSSCanvasValue.h b/Source/WebCore/css/CSSCanvasValue.h
index 232a525..efad7e6 100644
--- a/Source/WebCore/css/CSSCanvasValue.h
+++ b/Source/WebCore/css/CSSCanvasValue.h
@@ -44,6 +44,9 @@
bool isFixedSize() const { return true; }
IntSize fixedSize(const RenderObject*);
+ bool isPending() const { return false; }
+ void loadSubimages(CachedResourceLoader*) { }
+
void setName(const String& name) { m_name = name; }
private:
diff --git a/Source/WebCore/css/CSSCrossfadeValue.cpp b/Source/WebCore/css/CSSCrossfadeValue.cpp
index b77069f..acbca87 100644
--- a/Source/WebCore/css/CSSCrossfadeValue.cpp
+++ b/Source/WebCore/css/CSSCrossfadeValue.cpp
@@ -26,8 +26,62 @@
#include "config.h"
#include "CSSCrossfadeValue.h"
+#include "CSSImageValue.h"
+#include "CachedImage.h"
+#include "CachedResourceLoader.h"
+#include "CrossfadeGeneratedImage.h"
+#include "ImageBuffer.h"
+#include "RenderObject.h"
+#include "StyleCachedImage.h"
+#include "StyleGeneratedImage.h"
+
namespace WebCore {
+static bool subimageIsPending(CSSValue* value)
+{
+ if (value->isImageValue())
+ return static_cast<CSSImageValue*>(value)->cachedOrPendingImage()->isPendingImage();
+
+ if (value->isImageGeneratorValue())
+ return static_cast<CSSImageGeneratorValue*>(value)->isPending();
+
+ ASSERT_NOT_REACHED();
+
+ return false;
+}
+
+static void loadSubimage(CSSValue* value, CachedResourceLoader* cachedResourceLoader)
+{
+ if (value->isImageValue()) {
+ static_cast<CSSImageValue*>(value)->cachedImage(cachedResourceLoader);
+ return;
+ }
+
+ 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;
+ }
+
+ ASSERT_NOT_REACHED();
+
+ return 0;
+}
+
String CSSCrossfadeValue::customCssText() const
{
String result = "-webkit-cross-fade(";
@@ -40,17 +94,58 @@
IntSize CSSCrossfadeValue::fixedSize(const RenderObject* renderer)
{
- UNUSED_PARAM(renderer);
+ float percentage = m_percentage->getFloatValue();
+ float inversePercentage = 1 - percentage;
- return IntSize();
+ CachedImage* fromImage = cachedImageForCSSValue(m_fromImage.get(), renderer);
+ CachedImage* toImage = cachedImageForCSSValue(m_toImage.get(), renderer);
+
+ if (!fromImage || !toImage)
+ return IntSize();
+
+ IntSize fromImageSize = fromImage->image()->size();
+ IntSize toImageSize = toImage->image()->size();
+
+ return IntSize(fromImageSize.width() * inversePercentage + toImageSize.width() * percentage,
+ fromImageSize.height() * inversePercentage + toImageSize.height() * percentage);
+}
+
+bool CSSCrossfadeValue::isPending() const
+{
+ return subimageIsPending(m_fromImage.get()) || subimageIsPending(m_toImage.get());
+}
+
+void CSSCrossfadeValue::loadSubimages(CachedResourceLoader* cachedResourceLoader)
+{
+ loadSubimage(m_fromImage.get(), cachedResourceLoader);
+ loadSubimage(m_toImage.get(), cachedResourceLoader);
}
PassRefPtr<Image> CSSCrossfadeValue::image(RenderObject* renderer, const IntSize& size)
{
- UNUSED_PARAM(renderer);
- UNUSED_PARAM(size);
+ if (size.isEmpty())
+ return 0;
- return 0;
+ CachedImage* fromImage = cachedImageForCSSValue(m_fromImage.get(), renderer);
+ CachedImage* toImage = cachedImageForCSSValue(m_toImage.get(), renderer);
+
+ if (!fromImage || !toImage)
+ return Image::nullImage();
+
+ m_generatedImage = CrossfadeGeneratedImage::create(fromImage, toImage, m_percentage->getFloatValue(), &m_crossfadeObserver, fixedSize(renderer), size);
+
+ return m_generatedImage.get();
+}
+
+void CSSCrossfadeValue::crossfadeChanged(const IntRect& rect)
+{
+ 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);
+ client->imageChanged(static_cast<WrappedImagePtr>(this));
+ }
}
} // namespace WebCore
diff --git a/Source/WebCore/css/CSSCrossfadeValue.h b/Source/WebCore/css/CSSCrossfadeValue.h
index d549fbe..233a80a 100644
--- a/Source/WebCore/css/CSSCrossfadeValue.h
+++ b/Source/WebCore/css/CSSCrossfadeValue.h
@@ -27,37 +27,63 @@
#define CSSCrossfadeValue_h
#include "CSSImageGeneratorValue.h"
-#include "CSSImageValue.h"
+#include "CSSPrimitiveValue.h"
#include "Image.h"
#include "ImageObserver.h"
namespace WebCore {
+class CachedImage;
class RenderObject;
+class Document;
class CSSCrossfadeValue : public CSSImageGeneratorValue {
public:
- static PassRefPtr<CSSCrossfadeValue> create(PassRefPtr<CSSImageValue> fromImage, PassRefPtr<CSSImageValue> toImage) { return adoptRef(new CSSCrossfadeValue(fromImage, toImage)); }
+ static PassRefPtr<CSSCrossfadeValue> create(PassRefPtr<CSSValue> fromImage, PassRefPtr<CSSValue> toImage)
+ {
+ return adoptRef(new CSSCrossfadeValue(fromImage, toImage));
+ }
String customCssText() const;
PassRefPtr<Image> image(RenderObject*, const IntSize&);
- bool isFixedSize() const { return false; }
+ bool isFixedSize() const { return true; }
IntSize fixedSize(const RenderObject*);
+ bool isPending() const;
+ void loadSubimages(CachedResourceLoader*);
+
void setPercentage(PassRefPtr<CSSPrimitiveValue> percentage) { m_percentage = percentage; }
private:
- CSSCrossfadeValue(PassRefPtr<CSSImageValue> fromImage, PassRefPtr<CSSImageValue> toImage)
+ CSSCrossfadeValue(PassRefPtr<CSSValue> fromImage, PassRefPtr<CSSValue> toImage)
: CSSImageGeneratorValue(CrossfadeClass)
, m_fromImage(fromImage)
, m_toImage(toImage)
- {
- }
+ , m_crossfadeObserver(this) { }
- RefPtr<CSSImageValue> m_fromImage;
- RefPtr<CSSImageValue> m_toImage;
+ class CrossfadeObserverProxy : public ImageObserver {
+ 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 { }
+ private:
+ CSSCrossfadeValue* m_ownerValue;
+ };
+
+ void crossfadeChanged(const IntRect&);
+
+ RefPtr<CSSValue> m_fromImage;
+ RefPtr<CSSValue> m_toImage;
RefPtr<CSSPrimitiveValue> m_percentage;
+
+ RefPtr<Image> m_generatedImage;
+
+ CrossfadeObserverProxy m_crossfadeObserver;
};
} // namespace WebCore
diff --git a/Source/WebCore/css/CSSGradientValue.cpp b/Source/WebCore/css/CSSGradientValue.cpp
index feb01f4..b55b475 100644
--- a/Source/WebCore/css/CSSGradientValue.cpp
+++ b/Source/WebCore/css/CSSGradientValue.cpp
@@ -26,9 +26,9 @@
#include "config.h"
#include "CSSGradientValue.h"
-#include "CSSValueKeywords.h"
#include "CSSStyleSelector.h"
-#include "GeneratedImage.h"
+#include "CSSValueKeywords.h"
+#include "GeneratorGeneratedImage.h"
#include "Gradient.h"
#include "Image.h"
#include "IntSize.h"
@@ -67,7 +67,7 @@
gradient = static_cast<CSSRadialGradientValue*>(this)->createGradient(renderer, size);
}
- RefPtr<Image> newImage = GeneratedImage::create(gradient, size);
+ RefPtr<Image> newImage = GeneratorGeneratedImage::create(gradient, size);
if (cacheable)
putImage(size, newImage);
diff --git a/Source/WebCore/css/CSSGradientValue.h b/Source/WebCore/css/CSSGradientValue.h
index f13ac98..ea10eb8 100644
--- a/Source/WebCore/css/CSSGradientValue.h
+++ b/Source/WebCore/css/CSSGradientValue.h
@@ -69,6 +69,9 @@
bool isFixedSize() const { return false; }
IntSize fixedSize(const RenderObject*) const { return IntSize(); }
+ bool isPending() const { return false; }
+ void loadSubimages(CachedResourceLoader*) { }
+
protected:
CSSGradientValue(ClassType classType, CSSGradientRepeat repeat, bool deprecatedType = false)
: CSSImageGeneratorValue(classType)
diff --git a/Source/WebCore/css/CSSImageGeneratorValue.cpp b/Source/WebCore/css/CSSImageGeneratorValue.cpp
index 1c3c652..41b464c 100644
--- a/Source/WebCore/css/CSSImageGeneratorValue.cpp
+++ b/Source/WebCore/css/CSSImageGeneratorValue.cpp
@@ -32,6 +32,7 @@
#include "Image.h"
#include "RenderObject.h"
#include "StyleGeneratedImage.h"
+#include "StylePendingImage.h"
#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -110,13 +111,26 @@
m_images.add(size, image);
}
+StyleImage* CSSImageGeneratorValue::generatedOrPendingImage()
+{
+ if (isPending())
+ m_image = StylePendingImage::create(this).get();
+ else if (!m_accessedImage) {
+ m_accessedImage = true;
+ m_image = StyleGeneratedImage::create(this, isFixedSize());
+ }
+
+ return m_image.get();
+}
+
StyleGeneratedImage* CSSImageGeneratorValue::generatedImage()
{
if (!m_accessedImage) {
m_accessedImage = true;
m_image = StyleGeneratedImage::create(this, isFixedSize());
}
- return m_image.get();
+
+ return static_cast<StyleGeneratedImage*>(m_image.get());
}
PassRefPtr<Image> CSSImageGeneratorValue::image(RenderObject* renderer, const IntSize& size)
@@ -170,4 +184,41 @@
return IntSize();
}
+bool CSSImageGeneratorValue::isPending() const
+{
+ switch (classType()) {
+ case CrossfadeClass:
+ return static_cast<const CSSCrossfadeValue*>(this)->isPending();
+ case CanvasClass:
+ return static_cast<const CSSCanvasValue*>(this)->isPending();
+ case LinearGradientClass:
+ return static_cast<const CSSLinearGradientValue*>(this)->isPending();
+ case RadialGradientClass:
+ return static_cast<const CSSRadialGradientValue*>(this)->isPending();
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ return false;
+}
+
+void CSSImageGeneratorValue::loadSubimages(CachedResourceLoader* cachedResourceLoader)
+{
+ switch (classType()) {
+ case CrossfadeClass:
+ static_cast<CSSCrossfadeValue*>(this)->loadSubimages(cachedResourceLoader);
+ break;
+ case CanvasClass:
+ static_cast<CSSCanvasValue*>(this)->loadSubimages(cachedResourceLoader);
+ break;
+ case LinearGradientClass:
+ static_cast<CSSLinearGradientValue*>(this)->loadSubimages(cachedResourceLoader);
+ break;
+ case RadialGradientClass:
+ static_cast<CSSRadialGradientValue*>(this)->loadSubimages(cachedResourceLoader);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/css/CSSImageGeneratorValue.h b/Source/WebCore/css/CSSImageGeneratorValue.h
index d0eb65b..1ab4474 100644
--- a/Source/WebCore/css/CSSImageGeneratorValue.h
+++ b/Source/WebCore/css/CSSImageGeneratorValue.h
@@ -33,9 +33,11 @@
namespace WebCore {
+class CachedResourceLoader;
class Image;
class RenderObject;
class StyleGeneratedImage;
+class StyleImage;
struct SizeAndCount {
SizeAndCount(IntSize newSize = IntSize(), int newCount = 0)
@@ -58,11 +60,16 @@
void removeClient(RenderObject*);
PassRefPtr<Image> image(RenderObject*, const IntSize&);
+ StyleImage* generatedOrPendingImage();
StyleGeneratedImage* generatedImage();
bool isFixedSize() const;
IntSize fixedSize(const RenderObject*);
+ bool isPending() const;
+
+ void loadSubimages(CachedResourceLoader*);
+
protected:
CSSImageGeneratorValue(ClassType);
@@ -70,7 +77,7 @@
void putImage(const IntSize&, PassRefPtr<Image>);
const RenderObjectSizeCountMap& clients() const { return m_clients; }
- RefPtr<StyleGeneratedImage> m_image;
+ RefPtr<StyleImage> m_image;
bool m_accessedImage;
HashCountedSet<IntSize> m_sizes; // A count of how many times a given image size is in use.
diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp
index 93a0ad8..b6b0b28 100644
--- a/Source/WebCore/css/CSSParser.cpp
+++ b/Source/WebCore/css/CSSParser.cpp
@@ -6313,12 +6313,20 @@
return false;
a = args->next();
- // The third argument is the crossfade value. It is a percentage.
- if (!a || a->unit != CSSPrimitiveValue::CSS_PERCENTAGE)
+ // The third argument is the crossfade value. It is a percentage or a fractional number.
+ RefPtr<CSSPrimitiveValue> percentage;
+ if (!a)
+ return false;
+
+ if (a->unit == CSSPrimitiveValue::CSS_PERCENTAGE)
+ percentage = primitiveValueCache()->createValue(clampTo<double>(a->fValue / 100, 0, 1), CSSPrimitiveValue::CSS_NUMBER);
+ else if (a->unit == CSSPrimitiveValue::CSS_NUMBER)
+ percentage = primitiveValueCache()->createValue(clampTo<double>(a->fValue, 0, 1), CSSPrimitiveValue::CSS_NUMBER);
+ else
return false;
- result = CSSCrossfadeValue::create(static_cast<CSSImageValue*>(fromImageValue.get()), static_cast<CSSImageValue*>(toImageValue.get()));
- result->setPercentage(createPrimitiveNumericValue(a));
+ result = CSSCrossfadeValue::create(fromImageValue, toImageValue);
+ result->setPercentage(percentage);
crossfade = result;
diff --git a/Source/WebCore/css/CSSStyleSelector.cpp b/Source/WebCore/css/CSSStyleSelector.cpp
index 7527d73..4d459e0 100644
--- a/Source/WebCore/css/CSSStyleSelector.cpp
+++ b/Source/WebCore/css/CSSStyleSelector.cpp
@@ -4279,7 +4279,7 @@
return cachedOrPendingFromValue(property, static_cast<CSSImageValue*>(value));
if (value->isImageGeneratorValue())
- return static_cast<CSSImageGeneratorValue*>(value)->generatedImage();
+ return generatedOrPendingFromValue(property, static_cast<CSSImageGeneratorValue*>(value));
return 0;
}
@@ -4292,6 +4292,14 @@
return image;
}
+StyleImage* CSSStyleSelector::generatedOrPendingFromValue(CSSPropertyID property, CSSImageGeneratorValue* value)
+{
+ StyleImage* image = value->generatedOrPendingImage();
+ if (image && image->isPendingImage())
+ m_pendingImageProperties.add(property);
+ return image;
+}
+
void CSSStyleSelector::mapFillImage(CSSPropertyID property, FillLayer* layer, CSSValue* value)
{
if (value->isInitialValue()) {
@@ -5667,6 +5675,24 @@
#endif
+StyleImage* CSSStyleSelector::loadPendingImage(StylePendingImage* pendingImage)
+{
+ CachedResourceLoader* cachedResourceLoader = m_element->document()->cachedResourceLoader();
+
+ if (pendingImage->cssImageValue()) {
+ CSSImageValue* imageValue = pendingImage->cssImageValue();
+ return imageValue->cachedImage(cachedResourceLoader);
+ }
+
+ if (pendingImage->cssImageGeneratorValue()) {
+ CSSImageGeneratorValue* imageGeneratorValue = pendingImage->cssImageGeneratorValue();
+ imageGeneratorValue->loadSubimages(cachedResourceLoader);
+ return imageGeneratorValue->generatedImage();
+ }
+
+ return 0;
+}
+
void CSSStyleSelector::loadPendingImages()
{
if (m_pendingImageProperties.isEmpty())
@@ -5676,14 +5702,12 @@
for (HashSet<int>::const_iterator it = m_pendingImageProperties.begin(); it != end; ++it) {
CSSPropertyID currentProperty = static_cast<CSSPropertyID>(*it);
- CachedResourceLoader* cachedResourceLoader = m_element->document()->cachedResourceLoader();
-
switch (currentProperty) {
case CSSPropertyBackgroundImage: {
for (FillLayer* backgroundLayer = m_style->accessBackgroundLayers(); backgroundLayer; backgroundLayer = backgroundLayer->next()) {
if (backgroundLayer->image() && backgroundLayer->image()->isPendingImage()) {
- CSSImageValue* imageValue = static_cast<StylePendingImage*>(backgroundLayer->image())->cssImageValue();
- backgroundLayer->setImage(imageValue->cachedImage(cachedResourceLoader));
+ StyleImage* loadedImage = loadPendingImage(static_cast<StylePendingImage*>(backgroundLayer->image()));
+ backgroundLayer->setImage(loadedImage);
}
}
break;
@@ -5692,11 +5716,11 @@
case CSSPropertyContent: {
for (ContentData* contentData = const_cast<ContentData*>(m_style->contentData()); contentData; contentData = contentData->next()) {
if (contentData->isImage()) {
- const StyleImage* image = static_cast<ImageContentData*>(contentData)->image();
+ StyleImage* image = static_cast<ImageContentData*>(contentData)->image();
if (image->isPendingImage()) {
- CSSImageValue* imageValue = static_cast<const StylePendingImage*>(image)->cssImageValue();
- if (StyleCachedImage* cachedImage = imageValue->cachedImage(cachedResourceLoader))
- static_cast<ImageContentData*>(contentData)->setImage(cachedImage);
+ StyleImage* loadedImage = loadPendingImage(static_cast<StylePendingImage*>(image));
+ if (loadedImage)
+ static_cast<ImageContentData*>(contentData)->setImage(loadedImage);
}
}
}
@@ -5709,8 +5733,8 @@
CursorData& currentCursor = cursorList->at(i);
if (StyleImage* image = currentCursor.image()) {
if (image->isPendingImage()) {
- CSSImageValue* imageValue = static_cast<StylePendingImage*>(image)->cssImageValue();
- currentCursor.setImage(imageValue->cachedImage(cachedResourceLoader));
+ StyleImage* loadedImage = loadPendingImage(static_cast<StylePendingImage*>(image));
+ currentCursor.setImage(loadedImage);
}
}
}
@@ -5720,16 +5744,16 @@
case CSSPropertyListStyleImage: {
if (m_style->listStyleImage() && m_style->listStyleImage()->isPendingImage()) {
- CSSImageValue* imageValue = static_cast<StylePendingImage*>(m_style->listStyleImage())->cssImageValue();
- m_style->setListStyleImage(imageValue->cachedImage(cachedResourceLoader));
+ StyleImage* loadedImage = loadPendingImage(static_cast<StylePendingImage*>(m_style->listStyleImage()));
+ m_style->setListStyleImage(loadedImage);
}
break;
}
case CSSPropertyBorderImageSource: {
if (m_style->borderImageSource() && m_style->borderImageSource()->isPendingImage()) {
- CSSImageValue* imageValue = static_cast<StylePendingImage*>(m_style->borderImageSource())->cssImageValue();
- m_style->setBorderImageSource(imageValue->cachedImage(cachedResourceLoader));
+ StyleImage* loadedImage = loadPendingImage(static_cast<StylePendingImage*>(m_style->borderImageSource()));
+ m_style->setBorderImageSource(loadedImage);
}
break;
}
@@ -5738,8 +5762,8 @@
if (StyleReflection* reflection = m_style->boxReflect()) {
const NinePieceImage& maskImage = reflection->mask();
if (maskImage.image() && maskImage.image()->isPendingImage()) {
- CSSImageValue* imageValue = static_cast<StylePendingImage*>(maskImage.image())->cssImageValue();
- reflection->setMask(NinePieceImage(imageValue->cachedImage(cachedResourceLoader), maskImage.imageSlices(), maskImage.fill(), maskImage.borderSlices(), maskImage.outset(), maskImage.horizontalRule(), maskImage.verticalRule()));
+ StyleImage* loadedImage = loadPendingImage(static_cast<StylePendingImage*>(maskImage.image()));
+ reflection->setMask(NinePieceImage(loadedImage, maskImage.imageSlices(), maskImage.fill(), maskImage.borderSlices(), maskImage.outset(), maskImage.horizontalRule(), maskImage.verticalRule()));
}
}
break;
@@ -5747,8 +5771,8 @@
case CSSPropertyWebkitMaskBoxImageSource: {
if (m_style->maskBoxImageSource() && m_style->maskBoxImageSource()->isPendingImage()) {
- CSSImageValue* imageValue = static_cast<StylePendingImage*>(m_style->maskBoxImageSource())->cssImageValue();
- m_style->setMaskBoxImageSource(imageValue->cachedImage(cachedResourceLoader));
+ StyleImage* loadedImage = loadPendingImage(static_cast<StylePendingImage*>(m_style->maskBoxImageSource()));
+ m_style->setMaskBoxImageSource(loadedImage);
}
break;
}
@@ -5756,8 +5780,8 @@
case CSSPropertyWebkitMaskImage: {
for (FillLayer* maskLayer = m_style->accessMaskLayers(); maskLayer; maskLayer = maskLayer->next()) {
if (maskLayer->image() && maskLayer->image()->isPendingImage()) {
- CSSImageValue* imageValue = static_cast<StylePendingImage*>(maskLayer->image())->cssImageValue();
- maskLayer->setImage(imageValue->cachedImage(cachedResourceLoader));
+ StyleImage* loadedImage = loadPendingImage(static_cast<StylePendingImage*>(maskLayer->image()));
+ maskLayer->setImage(loadedImage);
}
}
break;
diff --git a/Source/WebCore/css/CSSStyleSelector.h b/Source/WebCore/css/CSSStyleSelector.h
index 979fc99..b48939c 100644
--- a/Source/WebCore/css/CSSStyleSelector.h
+++ b/Source/WebCore/css/CSSStyleSelector.h
@@ -44,6 +44,7 @@
class CSSProperty;
class CSSFontFace;
class CSSFontFaceRule;
+class CSSImageGeneratorValue;
class CSSImageValue;
class CSSRegionStyleRule;
class CSSRuleList;
@@ -67,6 +68,7 @@
class RuleSet;
class Settings;
class StyleImage;
+class StylePendingImage;
class StyleShader;
class StyleSheet;
class StyleSheetList;
@@ -294,6 +296,7 @@
StyleImage* styleImage(CSSPropertyID, CSSValue*);
StyleImage* cachedOrPendingFromValue(CSSPropertyID, CSSImageValue*);
+ StyleImage* generatedOrPendingFromValue(CSSPropertyID, CSSImageGeneratorValue*);
bool applyPropertyToRegularStyle() const { return m_applyPropertyToRegularStyle; }
bool applyPropertyToVisitedLinkStyle() const { return m_applyPropertyToVisitedLinkStyle; }
@@ -340,6 +343,7 @@
void applySVGProperty(int id, CSSValue*);
#endif
+ StyleImage* loadPendingImage(StylePendingImage*);
void loadPendingImages();
struct MatchedStyleDeclaration {