Add WTF::move()
[WebKit-https.git] / Source / WebCore / css / CSSFilterImageValue.cpp
1 /*
2  * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
17  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
18  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
22  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
23  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 #include "config.h"
28 #include "CSSFilterImageValue.h"
29
30 #if ENABLE(CSS_FILTERS)
31
32 #include "CSSImageValue.h"
33 #include "CachedImage.h"
34 #include "CachedResourceLoader.h"
35 #include "CrossfadeGeneratedImage.h"
36 #include "FilterEffectRenderer.h"
37 #include "ImageBuffer.h"
38 #include "RenderElement.h"
39 #include "StyleCachedImage.h"
40 #include "StyleGeneratedImage.h"
41 #include "StyleResolver.h"
42 #include <wtf/text/StringBuilder.h>
43
44 namespace WebCore {
45
46 CSSFilterImageValue::~CSSFilterImageValue()
47 {
48     if (m_cachedImage)
49         m_cachedImage->removeClient(&m_filterSubimageObserver);
50 }
51
52 String CSSFilterImageValue::customCSSText() const
53 {
54     StringBuilder result;
55     result.appendLiteral("-webkit-filter(");
56     result.append(m_imageValue->cssText());
57     result.appendLiteral(", ");
58     result.append(m_filterValue->cssText());
59     result.append(')');
60     return result.toString();
61 }
62
63 FloatSize CSSFilterImageValue::fixedSize(const RenderElement* renderer)
64 {
65     CachedResourceLoader* cachedResourceLoader = renderer->document().cachedResourceLoader();
66     CachedImage* cachedImage = cachedImageForCSSValue(m_imageValue.get(), cachedResourceLoader);
67
68     if (!cachedImage)
69         return FloatSize();
70
71     return cachedImage->imageForRenderer(renderer)->size();
72 }
73
74 bool CSSFilterImageValue::isPending() const
75 {
76     return CSSImageGeneratorValue::subimageIsPending(m_imageValue.get());
77 }
78
79 bool CSSFilterImageValue::knownToBeOpaque(const RenderElement*) const
80 {
81     return false;
82 }
83
84 void CSSFilterImageValue::loadSubimages(CachedResourceLoader* cachedResourceLoader)
85 {
86     CachedResourceHandle<CachedImage> oldCachedImage = m_cachedImage;
87
88     m_cachedImage = CSSImageGeneratorValue::cachedImageForCSSValue(m_imageValue.get(), cachedResourceLoader);
89
90     if (m_cachedImage != oldCachedImage) {
91         if (oldCachedImage)
92             oldCachedImage->removeClient(&m_filterSubimageObserver);
93         if (m_cachedImage)
94             m_cachedImage->addClient(&m_filterSubimageObserver);
95     }
96
97     m_filterSubimageObserver.setReady(true);
98 }
99
100 PassRefPtr<Image> CSSFilterImageValue::image(RenderElement* renderer, const FloatSize& size)
101 {
102     if (size.isEmpty())
103         return 0;
104
105     CachedResourceLoader* cachedResourceLoader = renderer->document().cachedResourceLoader();
106     CachedImage* cachedImage = cachedImageForCSSValue(m_imageValue.get(), cachedResourceLoader);
107
108     if (!cachedImage)
109         return Image::nullImage();
110
111     Image* image = cachedImage->imageForRenderer(renderer);
112
113     if (!image)
114         return Image::nullImage();
115
116     // Transform Image into ImageBuffer.
117     std::unique_ptr<ImageBuffer> texture = ImageBuffer::create(size);
118     if (!texture)
119         return Image::nullImage();
120     texture->context()->drawImage(image, ColorSpaceDeviceRGB, IntPoint());
121
122     RefPtr<FilterEffectRenderer> filterRenderer = FilterEffectRenderer::create();
123     filterRenderer->setSourceImage(WTF::move(texture));
124     filterRenderer->setSourceImageRect(FloatRect(FloatPoint(), size));
125     filterRenderer->setFilterRegion(FloatRect(FloatPoint(), size));
126     if (!filterRenderer->build(renderer, m_filterOperations, FilterFunction))
127         return Image::nullImage();
128     filterRenderer->apply();
129
130     m_generatedImage = filterRenderer->output()->copyImage();
131
132     return m_generatedImage.release();
133 }
134
135 void CSSFilterImageValue::filterImageChanged(const IntRect&)
136 {
137     for (auto it = clients().begin(), end = clients().end(); it != end; ++it)
138         it->key->imageChanged(static_cast<WrappedImagePtr>(this));
139 }
140
141 void CSSFilterImageValue::createFilterOperations(StyleResolver* resolver)
142 {
143     m_filterOperations.clear();
144     resolver->createFilterOperations(m_filterValue.get(), m_filterOperations);
145 }
146
147 void CSSFilterImageValue::FilterSubimageObserverProxy::imageChanged(CachedImage*, const IntRect* rect)
148 {
149     if (m_ready)
150         m_ownerValue->filterImageChanged(*rect);
151 }
152
153 bool CSSFilterImageValue::hasFailedOrCanceledSubresources() const
154 {
155     if (m_cachedImage && m_cachedImage->loadFailedOrCanceled())
156         return true;
157     return false;
158 }
159
160 bool CSSFilterImageValue::equals(const CSSFilterImageValue& other) const
161 {
162     return equalInputImages(other) && compareCSSValuePtr(m_filterValue, other.m_filterValue);
163 }
164
165 bool CSSFilterImageValue::equalInputImages(const CSSFilterImageValue& other) const
166 {
167     return compareCSSValuePtr(m_imageValue, other.m_imageValue);
168 }
169
170 } // namespace WebCore
171
172 #endif // ENABLE(CSS_FILTERS)