~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/css/CSSCrossfadeValue.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2011 Apple Inc.  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 APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. OR
 
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
18
 * EXEMPLARY, 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 THEORY
 
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
24
 */
 
25
 
 
26
#include "config.h"
 
27
#include "CSSCrossfadeValue.h"
 
28
 
 
29
#include "CSSImageValue.h"
 
30
#include "CachedImage.h"
 
31
#include "CachedResourceLoader.h"
 
32
#include "CrossfadeGeneratedImage.h"
 
33
#include "ImageBuffer.h"
 
34
#include "RenderObject.h"
 
35
#include "StyleCachedImage.h"
 
36
#include "StyleGeneratedImage.h"
 
37
#include "WebCoreMemoryInstrumentation.h"
 
38
#include <wtf/text/StringBuilder.h>
 
39
 
 
40
namespace WebCore {
 
41
 
 
42
static bool subimageIsPending(CSSValue* value)
 
43
{
 
44
    if (value->isImageValue())
 
45
        return static_cast<CSSImageValue*>(value)->cachedOrPendingImage()->isPendingImage();
 
46
    
 
47
    if (value->isImageGeneratorValue())
 
48
        return static_cast<CSSImageGeneratorValue*>(value)->isPending();
 
49
    
 
50
    ASSERT_NOT_REACHED();
 
51
    
 
52
    return false;
 
53
}
 
54
 
 
55
static bool subimageHasAlpha(CSSValue* value, const RenderObject* renderer)
 
56
{
 
57
    if (value->isImageValue())
 
58
        return static_cast<CSSImageValue*>(value)->hasAlpha(renderer);
 
59
 
 
60
    if (value->isImageGeneratorValue())
 
61
        return static_cast<CSSImageGeneratorValue*>(value)->hasAlpha(renderer);
 
62
 
 
63
    ASSERT_NOT_REACHED();
 
64
 
 
65
    return true;
 
66
}
 
67
 
 
68
static CachedImage* cachedImageForCSSValue(CSSValue* value, CachedResourceLoader* cachedResourceLoader)
 
69
{
 
70
    if (!value)
 
71
        return 0;
 
72
 
 
73
    if (value->isImageValue()) {
 
74
        StyleCachedImage* styleCachedImage = static_cast<CSSImageValue*>(value)->cachedImage(cachedResourceLoader);
 
75
        if (!styleCachedImage)
 
76
            return 0;
 
77
 
 
78
        return styleCachedImage->cachedImage();
 
79
    }
 
80
    
 
81
    if (value->isImageGeneratorValue()) {
 
82
        static_cast<CSSImageGeneratorValue*>(value)->loadSubimages(cachedResourceLoader);
 
83
        // FIXME: Handle CSSImageGeneratorValue (and thus cross-fades with gradients and canvas).
 
84
        return 0;
 
85
    }
 
86
    
 
87
    ASSERT_NOT_REACHED();
 
88
    
 
89
    return 0;
 
90
}
 
91
 
 
92
CSSCrossfadeValue::~CSSCrossfadeValue()
 
93
{
 
94
    if (m_cachedFromImage)
 
95
        m_cachedFromImage->removeClient(&m_crossfadeSubimageObserver);
 
96
    if (m_cachedToImage)
 
97
        m_cachedToImage->removeClient(&m_crossfadeSubimageObserver);
 
98
}
 
99
 
 
100
String CSSCrossfadeValue::customCssText() const
 
101
{
 
102
    StringBuilder result;
 
103
    result.appendLiteral("-webkit-cross-fade(");
 
104
    result.append(m_fromValue->cssText());
 
105
    result.appendLiteral(", ");
 
106
    result.append(m_toValue->cssText());
 
107
    result.appendLiteral(", ");
 
108
    result.append(m_percentageValue->cssText());
 
109
    result.append(')');
 
110
    return result.toString();
 
111
}
 
112
 
 
113
IntSize CSSCrossfadeValue::fixedSize(const RenderObject* renderer)
 
114
{
 
115
    float percentage = m_percentageValue->getFloatValue();
 
116
    float inversePercentage = 1 - percentage;
 
117
 
 
118
    CachedResourceLoader* cachedResourceLoader = renderer->document()->cachedResourceLoader();
 
119
    CachedImage* cachedFromImage = cachedImageForCSSValue(m_fromValue.get(), cachedResourceLoader);
 
120
    CachedImage* cachedToImage = cachedImageForCSSValue(m_toValue.get(), cachedResourceLoader);
 
121
 
 
122
    if (!cachedFromImage || !cachedToImage)
 
123
        return IntSize();
 
124
 
 
125
    IntSize fromImageSize = cachedFromImage->imageForRenderer(renderer)->size();
 
126
    IntSize toImageSize = cachedToImage->imageForRenderer(renderer)->size();
 
127
 
 
128
    // Rounding issues can cause transitions between images of equal size to return
 
129
    // a different fixed size; avoid performing the interpolation if the images are the same size.
 
130
    if (fromImageSize == toImageSize)
 
131
        return fromImageSize;
 
132
 
 
133
    return IntSize(fromImageSize.width() * inversePercentage + toImageSize.width() * percentage,
 
134
        fromImageSize.height() * inversePercentage + toImageSize.height() * percentage);
 
135
}
 
136
 
 
137
bool CSSCrossfadeValue::isPending() const
 
138
{
 
139
    return subimageIsPending(m_fromValue.get()) || subimageIsPending(m_toValue.get());
 
140
}
 
141
 
 
142
bool CSSCrossfadeValue::hasAlpha(const RenderObject* renderer) const
 
143
{
 
144
    return subimageHasAlpha(m_fromValue.get(), renderer) || subimageHasAlpha(m_toValue.get(), renderer);
 
145
}
 
146
 
 
147
void CSSCrossfadeValue::loadSubimages(CachedResourceLoader* cachedResourceLoader)
 
148
{
 
149
    m_cachedFromImage = cachedImageForCSSValue(m_fromValue.get(), cachedResourceLoader);
 
150
    m_cachedToImage = cachedImageForCSSValue(m_toValue.get(), cachedResourceLoader);
 
151
 
 
152
    if (m_cachedFromImage)
 
153
        m_cachedFromImage->addClient(&m_crossfadeSubimageObserver);
 
154
    if (m_cachedToImage)
 
155
        m_cachedToImage->addClient(&m_crossfadeSubimageObserver);
 
156
 
 
157
    m_crossfadeSubimageObserver.setReady(true);
 
158
}
 
159
 
 
160
void CSSCrossfadeValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 
161
{
 
162
    MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
 
163
    CSSImageGeneratorValue::reportBaseClassMemoryUsage(memoryObjectInfo);
 
164
    info.addMember(m_fromValue);
 
165
    info.addMember(m_toValue);
 
166
    info.addMember(m_percentageValue);
 
167
    // FIXME: add instrumentation for
 
168
    // m_cachedFromImage
 
169
    // m_cachedToImage
 
170
    // m_generatedImage
 
171
}
 
172
 
 
173
PassRefPtr<Image> CSSCrossfadeValue::image(RenderObject* renderer, const IntSize& size)
 
174
{
 
175
    if (size.isEmpty())
 
176
        return 0;
 
177
 
 
178
    CachedResourceLoader* cachedResourceLoader = renderer->document()->cachedResourceLoader();
 
179
    CachedImage* cachedFromImage = cachedImageForCSSValue(m_fromValue.get(), cachedResourceLoader);
 
180
    CachedImage* cachedToImage = cachedImageForCSSValue(m_toValue.get(), cachedResourceLoader);
 
181
 
 
182
    if (!cachedFromImage || !cachedToImage)
 
183
        return Image::nullImage();
 
184
 
 
185
    Image* fromImage = cachedFromImage->imageForRenderer(renderer);
 
186
    Image* toImage = cachedToImage->imageForRenderer(renderer);
 
187
 
 
188
    if (!fromImage || !toImage)
 
189
        return Image::nullImage();
 
190
 
 
191
    m_generatedImage = CrossfadeGeneratedImage::create(fromImage, toImage, m_percentageValue->getFloatValue(), fixedSize(renderer), size);
 
192
 
 
193
    return m_generatedImage.release();
 
194
}
 
195
 
 
196
void CSSCrossfadeValue::crossfadeChanged(const IntRect&)
 
197
{
 
198
    RenderObjectSizeCountMap::const_iterator end = clients().end();
 
199
    for (RenderObjectSizeCountMap::const_iterator curr = clients().begin(); curr != end; ++curr) {
 
200
        RenderObject* client = const_cast<RenderObject*>(curr->key);
 
201
        client->imageChanged(static_cast<WrappedImagePtr>(this));
 
202
    }
 
203
}
 
204
 
 
205
void CSSCrossfadeValue::CrossfadeSubimageObserverProxy::imageChanged(CachedImage*, const IntRect* rect)
 
206
{
 
207
    if (m_ready)
 
208
        m_ownerValue->crossfadeChanged(*rect);
 
209
}
 
210
 
 
211
bool CSSCrossfadeValue::hasFailedOrCanceledSubresources() const
 
212
{
 
213
    if (m_cachedFromImage && m_cachedFromImage->loadFailedOrCanceled())
 
214
        return true;
 
215
    if (m_cachedToImage && m_cachedToImage->loadFailedOrCanceled())
 
216
        return true;
 
217
    return false;
 
218
}
 
219
 
 
220
} // namespace WebCore