summaryrefslogtreecommitdiff
path: root/Source/WebCore/css/CSSCrossfadeValue.cpp
diff options
context:
space:
mode:
authorKonstantin Tokarev <annulen@yandex.ru>2016-08-25 19:20:41 +0300
committerKonstantin Tokarev <annulen@yandex.ru>2017-02-02 12:30:55 +0000
commit6882a04fb36642862b11efe514251d32070c3d65 (patch)
treeb7959826000b061fd5ccc7512035c7478742f7b0 /Source/WebCore/css/CSSCrossfadeValue.cpp
parentab6df191029eeeb0b0f16f127d553265659f739e (diff)
downloadqtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/WebCore/css/CSSCrossfadeValue.cpp')
-rw-r--r--Source/WebCore/css/CSSCrossfadeValue.cpp153
1 files changed, 79 insertions, 74 deletions
diff --git a/Source/WebCore/css/CSSCrossfadeValue.cpp b/Source/WebCore/css/CSSCrossfadeValue.cpp
index 736c0c4fd..9d58f8e79 100644
--- a/Source/WebCore/css/CSSCrossfadeValue.cpp
+++ b/Source/WebCore/css/CSSCrossfadeValue.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +11,10 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY APPLE 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
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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
@@ -26,68 +27,37 @@
#include "config.h"
#include "CSSCrossfadeValue.h"
+#include "AnimationUtilities.h"
#include "CSSImageValue.h"
#include "CachedImage.h"
#include "CachedResourceLoader.h"
#include "CrossfadeGeneratedImage.h"
#include "ImageBuffer.h"
-#include "RenderObject.h"
+#include "RenderElement.h"
#include "StyleCachedImage.h"
#include "StyleGeneratedImage.h"
#include <wtf/text/StringBuilder.h>
namespace WebCore {
-static bool subimageIsPending(CSSValue* value)
+static inline double blendFunc(double from, double to, double progress)
{
- if (value->isImageValue())
- return static_cast<CSSImageValue*>(value)->cachedOrPendingImage()->isPendingImage();
-
- if (value->isImageGeneratorValue())
- return static_cast<CSSImageGeneratorValue*>(value)->isPending();
-
- ASSERT_NOT_REACHED();
-
- return false;
+ return blend(from, to, progress);
}
-static bool subimageKnownToBeOpaque(CSSValue* value, const RenderObject* renderer)
+static bool subimageKnownToBeOpaque(CSSValue& value, const RenderElement* renderer)
{
- if (value->isImageValue())
- return static_cast<CSSImageValue*>(value)->knownToBeOpaque(renderer);
+ if (is<CSSImageValue>(value))
+ return downcast<CSSImageValue>(value).knownToBeOpaque(renderer);
- if (value->isImageGeneratorValue())
- return static_cast<CSSImageGeneratorValue*>(value)->knownToBeOpaque(renderer);
+ if (is<CSSImageGeneratorValue>(value))
+ return downcast<CSSImageGeneratorValue>(value).knownToBeOpaque(renderer);
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)
@@ -96,7 +66,7 @@ CSSCrossfadeValue::~CSSCrossfadeValue()
m_cachedToImage->removeClient(&m_crossfadeSubimageObserver);
}
-String CSSCrossfadeValue::customCssText() const
+String CSSCrossfadeValue::customCSSText() const
{
StringBuilder result;
result.appendLiteral("-webkit-cross-fade(");
@@ -109,47 +79,52 @@ String CSSCrossfadeValue::customCssText() const
return result.toString();
}
-IntSize CSSCrossfadeValue::fixedSize(const RenderObject* renderer)
+FloatSize CSSCrossfadeValue::fixedSize(const RenderElement* 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);
+ // FIXME: Skip Content Security Policy check when cross fade is applied to an element in a user agent shadow tree.
+ // See <https://bugs.webkit.org/show_bug.cgi?id=146663>.
+ ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions();
+
+ CachedResourceLoader& cachedResourceLoader = renderer->document().cachedResourceLoader();
+ CachedImage* cachedFromImage = cachedImageForCSSValue(m_fromValue.get(), cachedResourceLoader, options);
+ CachedImage* cachedToImage = cachedImageForCSSValue(m_toValue.get(), cachedResourceLoader, options);
if (!cachedFromImage || !cachedToImage)
- return IntSize();
+ return FloatSize();
- IntSize fromImageSize = cachedFromImage->imageForRenderer(renderer)->size();
- IntSize toImageSize = cachedToImage->imageForRenderer(renderer)->size();
+ FloatSize fromImageSize = cachedFromImage->imageForRenderer(renderer)->size();
+ FloatSize 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,
+ return FloatSize(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());
+ return CSSImageGeneratorValue::subimageIsPending(m_fromValue.get())
+ || CSSImageGeneratorValue::subimageIsPending(m_toValue.get());
}
-bool CSSCrossfadeValue::knownToBeOpaque(const RenderObject* renderer) const
+bool CSSCrossfadeValue::knownToBeOpaque(const RenderElement* renderer) const
{
- return subimageKnownToBeOpaque(m_fromValue.get(), renderer) && subimageKnownToBeOpaque(m_toValue.get(), renderer);
+ return subimageKnownToBeOpaque(*m_fromValue, renderer) && subimageKnownToBeOpaque(*m_toValue, renderer);
}
-void CSSCrossfadeValue::loadSubimages(CachedResourceLoader* cachedResourceLoader)
+void CSSCrossfadeValue::loadSubimages(CachedResourceLoader& cachedResourceLoader, const ResourceLoaderOptions& options)
{
CachedResourceHandle<CachedImage> oldCachedFromImage = m_cachedFromImage;
CachedResourceHandle<CachedImage> oldCachedToImage = m_cachedToImage;
- m_cachedFromImage = cachedImageForCSSValue(m_fromValue.get(), cachedResourceLoader);
- m_cachedToImage = cachedImageForCSSValue(m_toValue.get(), cachedResourceLoader);
+ m_cachedFromImage = CSSImageGeneratorValue::cachedImageForCSSValue(m_fromValue.get(), cachedResourceLoader, options);
+ m_cachedToImage = CSSImageGeneratorValue::cachedImageForCSSValue(m_toValue.get(), cachedResourceLoader, options);
if (m_cachedFromImage != oldCachedFromImage) {
if (oldCachedFromImage)
@@ -168,14 +143,18 @@ void CSSCrossfadeValue::loadSubimages(CachedResourceLoader* cachedResourceLoader
m_crossfadeSubimageObserver.setReady(true);
}
-PassRefPtr<Image> CSSCrossfadeValue::image(RenderObject* renderer, const IntSize& size)
+RefPtr<Image> CSSCrossfadeValue::image(RenderElement* renderer, const FloatSize& size)
{
if (size.isEmpty())
- return 0;
+ return nullptr;
- CachedResourceLoader* cachedResourceLoader = renderer->document()->cachedResourceLoader();
- CachedImage* cachedFromImage = cachedImageForCSSValue(m_fromValue.get(), cachedResourceLoader);
- CachedImage* cachedToImage = cachedImageForCSSValue(m_toValue.get(), cachedResourceLoader);
+ // FIXME: Skip Content Security Policy check when cross fade is applied to an element in a user agent shadow tree.
+ // See <https://bugs.webkit.org/show_bug.cgi?id=146663>.
+ ResourceLoaderOptions options = CachedResourceLoader::defaultCachedResourceOptions();
+
+ CachedResourceLoader& cachedResourceLoader = renderer->document().cachedResourceLoader();
+ CachedImage* cachedFromImage = cachedImageForCSSValue(m_fromValue.get(), cachedResourceLoader, options);
+ CachedImage* cachedToImage = cachedImageForCSSValue(m_toValue.get(), cachedResourceLoader, options);
if (!cachedFromImage || !cachedToImage)
return Image::nullImage();
@@ -186,18 +165,15 @@ PassRefPtr<Image> CSSCrossfadeValue::image(RenderObject* renderer, const IntSize
if (!fromImage || !toImage)
return Image::nullImage();
- m_generatedImage = CrossfadeGeneratedImage::create(fromImage, toImage, m_percentageValue->getFloatValue(), fixedSize(renderer), size);
+ m_generatedImage = CrossfadeGeneratedImage::create(*fromImage, *toImage, m_percentageValue->getFloatValue(), fixedSize(renderer), size);
- return m_generatedImage.release();
+ return m_generatedImage;
}
void CSSCrossfadeValue::crossfadeChanged(const IntRect&)
{
- HashCountedSet<RenderObject*>::const_iterator end = clients().end();
- for (HashCountedSet<RenderObject*>::const_iterator curr = clients().begin(); curr != end; ++curr) {
- RenderObject* client = const_cast<RenderObject*>(curr->key);
- client->imageChanged(static_cast<WrappedImagePtr>(this));
- }
+ for (auto it = clients().begin(), end = clients().end(); it != end; ++it)
+ it->key->imageChanged(static_cast<WrappedImagePtr>(this));
}
void CSSCrossfadeValue::CrossfadeSubimageObserverProxy::imageChanged(CachedImage*, const IntRect* rect)
@@ -206,20 +182,49 @@ void CSSCrossfadeValue::CrossfadeSubimageObserverProxy::imageChanged(CachedImage
m_ownerValue->crossfadeChanged(*rect);
}
-bool CSSCrossfadeValue::hasFailedOrCanceledSubresources() const
+bool CSSCrossfadeValue::traverseSubresources(const std::function<bool (const CachedResource&)>& handler) const
{
- if (m_cachedFromImage && m_cachedFromImage->loadFailedOrCanceled())
+ if (m_cachedFromImage && handler(*m_cachedFromImage))
return true;
- if (m_cachedToImage && m_cachedToImage->loadFailedOrCanceled())
+ if (m_cachedToImage && handler(*m_cachedToImage))
return true;
return false;
}
+RefPtr<CSSCrossfadeValue> CSSCrossfadeValue::blend(const CSSCrossfadeValue& from, double progress) const
+{
+ ASSERT(equalInputImages(from));
+ if (!m_cachedToImage || !m_cachedFromImage)
+ return nullptr;
+ RefPtr<StyleCachedImage> toStyledImage = StyleCachedImage::create(m_cachedToImage.get());
+ RefPtr<StyleCachedImage> fromStyledImage = StyleCachedImage::create(m_cachedFromImage.get());
+
+ auto fromImageValue = CSSImageValue::create(m_cachedFromImage->url(), fromStyledImage.get());
+ auto toImageValue = CSSImageValue::create(m_cachedToImage->url(), toStyledImage.get());
+
+ RefPtr<CSSCrossfadeValue> crossfadeValue = CSSCrossfadeValue::create(WTFMove(fromImageValue), WTFMove(toImageValue));
+
+ double fromPercentage = from.m_percentageValue->getDoubleValue();
+ if (from.m_percentageValue->isPercentage())
+ fromPercentage /= 100.0;
+ double toPercentage = m_percentageValue->getDoubleValue();
+ if (m_percentageValue->isPercentage())
+ toPercentage /= 100.0;
+ crossfadeValue->setPercentage(CSSPrimitiveValue::create(blendFunc(fromPercentage, toPercentage, progress), CSSPrimitiveValue::CSS_NUMBER));
+ return crossfadeValue;
+}
+
bool CSSCrossfadeValue::equals(const CSSCrossfadeValue& other) const
{
- return compareCSSValuePtr(m_fromValue, other.m_fromValue)
- && compareCSSValuePtr(m_toValue, other.m_toValue)
+ return equalInputImages(other)
&& compareCSSValuePtr(m_percentageValue, other.m_percentageValue);
}
+
+bool CSSCrossfadeValue::equalInputImages(const CSSCrossfadeValue& other) const
+{
+ return compareCSSValuePtr(m_fromValue, other.m_fromValue)
+ && compareCSSValuePtr(m_toValue, other.m_toValue);
+}
+
} // namespace WebCore