summaryrefslogtreecommitdiff
path: root/Source/WebCore/css/CSSCrossfadeValue.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-01-06 14:44:00 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-01-06 14:44:00 +0100
commit40736c5763bf61337c8c14e16d8587db021a87d4 (patch)
treeb17a9c00042ad89cb1308e2484491799aa14e9f8 /Source/WebCore/css/CSSCrossfadeValue.cpp
downloadqtwebkit-40736c5763bf61337c8c14e16d8587db021a87d4.tar.gz
Imported WebKit commit 2ea9d364d0f6efa8fa64acf19f451504c59be0e4 (http://svn.webkit.org/repository/webkit/trunk@104285)
Diffstat (limited to 'Source/WebCore/css/CSSCrossfadeValue.cpp')
-rw-r--r--Source/WebCore/css/CSSCrossfadeValue.cpp175
1 files changed, 175 insertions, 0 deletions
diff --git a/Source/WebCore/css/CSSCrossfadeValue.cpp b/Source/WebCore/css/CSSCrossfadeValue.cpp
new file mode 100644
index 000000000..4ff08afca
--- /dev/null
+++ b/Source/WebCore/css/CSSCrossfadeValue.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#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 CachedImage* cachedImageForCSSValue(CSSValue* value, CachedResourceLoader* cachedResourceLoader)
+{
+ if (!value)
+ return 0;
+
+ if (value->isImageValue()) {
+ StyleCachedImage* styleCachedImage = static_cast<CSSImageValue*>(value)->cachedImage(cachedResourceLoader);
+ if (!styleCachedImage)
+ return 0;
+
+ return styleCachedImage->cachedImage();
+ }
+
+ if (value->isImageGeneratorValue()) {
+ static_cast<CSSImageGeneratorValue*>(value)->loadSubimages(cachedResourceLoader);
+ // FIXME: Handle CSSImageGeneratorValue (and thus cross-fades with gradients and canvas).
+ return 0;
+ }
+
+ ASSERT_NOT_REACHED();
+
+ 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_fromValue->cssText() + ", ";
+ result += m_toValue->cssText() + ", ";
+ result += m_percentageValue->cssText();
+ result += ")";
+ return result;
+}
+
+IntSize CSSCrossfadeValue::fixedSize(const RenderObject* renderer)
+{
+ float percentage = m_percentageValue->getFloatValue();
+ float inversePercentage = 1 - percentage;
+
+ CachedResourceLoader* cachedResourceLoader = renderer->document()->cachedResourceLoader();
+ CachedImage* cachedFromImage = cachedImageForCSSValue(m_fromValue.get(), cachedResourceLoader);
+ CachedImage* cachedToImage = cachedImageForCSSValue(m_toValue.get(), cachedResourceLoader);
+
+ if (!cachedFromImage || !cachedToImage)
+ return IntSize();
+
+ IntSize fromImageSize = cachedFromImage->imageForRenderer(renderer)->size();
+ IntSize toImageSize = cachedToImage->imageForRenderer(renderer)->size();
+
+ // Rounding issues can cause transitions between images of equal size to return
+ // a different fixed size; avoid performing the interpolation if the images are the same size.
+ if (fromImageSize == toImageSize)
+ return fromImageSize;
+
+ return IntSize(fromImageSize.width() * inversePercentage + toImageSize.width() * percentage,
+ fromImageSize.height() * inversePercentage + toImageSize.height() * percentage);
+}
+
+bool CSSCrossfadeValue::isPending() const
+{
+ return subimageIsPending(m_fromValue.get()) || subimageIsPending(m_toValue.get());
+}
+
+void CSSCrossfadeValue::loadSubimages(CachedResourceLoader* 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)
+{
+ if (size.isEmpty())
+ return 0;
+
+ 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_percentageValue->getFloatValue(), fixedSize(renderer), size);
+
+ return m_generatedImage.release();
+}
+
+void CSSCrossfadeValue::crossfadeChanged(const IntRect&)
+{
+ 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));
+ }
+}
+
+void CSSCrossfadeValue::CrossfadeSubimageObserverProxy::imageChanged(CachedImage*, const IntRect* rect)
+{
+ if (m_ready)
+ m_ownerValue->crossfadeChanged(*rect);
+}
+
+} // namespace WebCore