fa3f22a05e657f4ec001d551380eaf7b2040fec1
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / css / CSSImageGeneratorValue.cpp
1 /*
2  * Copyright (C) 2008 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 "core/css/CSSImageGeneratorValue.h"
28
29 #include "core/css/CSSCanvasValue.h"
30 #include "core/css/CSSCrossfadeValue.h"
31 #include "core/css/CSSGradientValue.h"
32 #include "platform/graphics/Image.h"
33
34 namespace WebCore {
35
36 CSSImageGeneratorValue::CSSImageGeneratorValue(ClassType classType)
37     : CSSValue(classType)
38 {
39 }
40
41 CSSImageGeneratorValue::~CSSImageGeneratorValue()
42 {
43 }
44
45 void CSSImageGeneratorValue::addClient(RenderObject* renderer, const IntSize& size)
46 {
47     ref();
48
49     ASSERT(renderer);
50     if (!size.isEmpty())
51         m_sizes.add(size);
52
53     RenderObjectSizeCountMap::iterator it = m_clients.find(renderer);
54     if (it == m_clients.end())
55         m_clients.add(renderer, SizeAndCount(size, 1));
56     else {
57         SizeAndCount& sizeCount = it->value;
58         ++sizeCount.count;
59     }
60 }
61
62 void CSSImageGeneratorValue::removeClient(RenderObject* renderer)
63 {
64     ASSERT(renderer);
65     RenderObjectSizeCountMap::iterator it = m_clients.find(renderer);
66     ASSERT_WITH_SECURITY_IMPLICATION(it != m_clients.end());
67
68     IntSize removedImageSize;
69     SizeAndCount& sizeCount = it->value;
70     IntSize size = sizeCount.size;
71     if (!size.isEmpty()) {
72         m_sizes.remove(size);
73         if (!m_sizes.contains(size))
74             m_images.remove(size);
75     }
76
77     if (!--sizeCount.count)
78         m_clients.remove(renderer);
79
80     deref();
81 }
82
83 Image* CSSImageGeneratorValue::getImage(RenderObject* renderer, const IntSize& size)
84 {
85     RenderObjectSizeCountMap::iterator it = m_clients.find(renderer);
86     if (it != m_clients.end()) {
87         SizeAndCount& sizeCount = it->value;
88         IntSize oldSize = sizeCount.size;
89         if (oldSize != size) {
90             RefPtr<CSSImageGeneratorValue> protect(this);
91             removeClient(renderer);
92             addClient(renderer, size);
93         }
94     }
95
96     // Don't generate an image for empty sizes.
97     if (size.isEmpty())
98         return 0;
99
100     // Look up the image in our cache.
101     return m_images.get(size);
102 }
103
104 void CSSImageGeneratorValue::putImage(const IntSize& size, PassRefPtr<Image> image)
105 {
106     m_images.add(size, image);
107 }
108
109 PassRefPtr<Image> CSSImageGeneratorValue::image(RenderObject* renderer, const IntSize& size)
110 {
111     switch (classType()) {
112     case CanvasClass:
113         return toCSSCanvasValue(this)->image(renderer, size);
114     case CrossfadeClass:
115         return toCSSCrossfadeValue(this)->image(renderer, size);
116     case LinearGradientClass:
117         return toCSSLinearGradientValue(this)->image(renderer, size);
118     case RadialGradientClass:
119         return toCSSRadialGradientValue(this)->image(renderer, size);
120     default:
121         ASSERT_NOT_REACHED();
122     }
123     return 0;
124 }
125
126 bool CSSImageGeneratorValue::isFixedSize() const
127 {
128     switch (classType()) {
129     case CanvasClass:
130         return toCSSCanvasValue(this)->isFixedSize();
131     case CrossfadeClass:
132         return toCSSCrossfadeValue(this)->isFixedSize();
133     case LinearGradientClass:
134         return toCSSLinearGradientValue(this)->isFixedSize();
135     case RadialGradientClass:
136         return toCSSRadialGradientValue(this)->isFixedSize();
137     default:
138         ASSERT_NOT_REACHED();
139     }
140     return false;
141 }
142
143 IntSize CSSImageGeneratorValue::fixedSize(const RenderObject* renderer)
144 {
145     switch (classType()) {
146     case CanvasClass:
147         return toCSSCanvasValue(this)->fixedSize(renderer);
148     case CrossfadeClass:
149         return toCSSCrossfadeValue(this)->fixedSize(renderer);
150     case LinearGradientClass:
151         return toCSSLinearGradientValue(this)->fixedSize(renderer);
152     case RadialGradientClass:
153         return toCSSRadialGradientValue(this)->fixedSize(renderer);
154     default:
155         ASSERT_NOT_REACHED();
156     }
157     return IntSize();
158 }
159
160 bool CSSImageGeneratorValue::isPending() const
161 {
162     switch (classType()) {
163     case CrossfadeClass:
164         return toCSSCrossfadeValue(this)->isPending();
165     case CanvasClass:
166         return toCSSCanvasValue(this)->isPending();
167     case LinearGradientClass:
168         return toCSSLinearGradientValue(this)->isPending();
169     case RadialGradientClass:
170         return toCSSRadialGradientValue(this)->isPending();
171     default:
172         ASSERT_NOT_REACHED();
173     }
174     return false;
175 }
176
177 bool CSSImageGeneratorValue::knownToBeOpaque(const RenderObject* renderer) const
178 {
179     switch (classType()) {
180     case CrossfadeClass:
181         return toCSSCrossfadeValue(this)->knownToBeOpaque(renderer);
182     case CanvasClass:
183         return false;
184     case LinearGradientClass:
185         return toCSSLinearGradientValue(this)->knownToBeOpaque(renderer);
186     case RadialGradientClass:
187         return toCSSRadialGradientValue(this)->knownToBeOpaque(renderer);
188     default:
189         ASSERT_NOT_REACHED();
190     }
191     return false;
192 }
193
194 void CSSImageGeneratorValue::loadSubimages(ResourceFetcher* fetcher)
195 {
196     switch (classType()) {
197     case CrossfadeClass:
198         toCSSCrossfadeValue(this)->loadSubimages(fetcher);
199         break;
200     case CanvasClass:
201         toCSSCanvasValue(this)->loadSubimages(fetcher);
202         break;
203     case LinearGradientClass:
204         toCSSLinearGradientValue(this)->loadSubimages(fetcher);
205         break;
206     case RadialGradientClass:
207         toCSSRadialGradientValue(this)->loadSubimages(fetcher);
208         break;
209     default:
210         ASSERT_NOT_REACHED();
211     }
212 }
213
214 } // namespace WebCore