diff options
author | Konstantin Tokarev <annulen@yandex.ru> | 2016-08-25 19:20:41 +0300 |
---|---|---|
committer | Konstantin Tokarev <annulen@yandex.ru> | 2017-02-02 12:30:55 +0000 |
commit | 6882a04fb36642862b11efe514251d32070c3d65 (patch) | |
tree | b7959826000b061fd5ccc7512035c7478742f7b0 /Source/WebCore/css/CSSCrossfadeValue.cpp | |
parent | ab6df191029eeeb0b0f16f127d553265659f739e (diff) | |
download | qtwebkit-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.cpp | 153 |
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 |