• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 blink {
35 
CSSImageGeneratorValue(ClassType classType)36 CSSImageGeneratorValue::CSSImageGeneratorValue(ClassType classType)
37     : CSSValue(classType)
38 {
39 }
40 
~CSSImageGeneratorValue()41 CSSImageGeneratorValue::~CSSImageGeneratorValue()
42 {
43 }
44 
addClient(RenderObject * renderer,const IntSize & size)45 void CSSImageGeneratorValue::addClient(RenderObject* renderer, const IntSize& size)
46 {
47     ASSERT(renderer);
48 #if !ENABLE(OILPAN)
49     ref();
50 #else
51     if (m_clients.isEmpty()) {
52         ASSERT(!m_keepAlive);
53         m_keepAlive = adoptPtr(new Persistent<CSSImageGeneratorValue>(this));
54     }
55 #endif
56 
57     if (!size.isEmpty())
58         m_sizes.add(size);
59 
60     RenderObjectSizeCountMap::iterator it = m_clients.find(renderer);
61     if (it == m_clients.end())
62         m_clients.add(renderer, SizeAndCount(size, 1));
63     else {
64         SizeAndCount& sizeCount = it->value;
65         ++sizeCount.count;
66     }
67 }
68 
removeClient(RenderObject * renderer)69 void CSSImageGeneratorValue::removeClient(RenderObject* renderer)
70 {
71     ASSERT(renderer);
72     RenderObjectSizeCountMap::iterator it = m_clients.find(renderer);
73     ASSERT_WITH_SECURITY_IMPLICATION(it != m_clients.end());
74 
75     IntSize removedImageSize;
76     SizeAndCount& sizeCount = it->value;
77     IntSize size = sizeCount.size;
78     if (!size.isEmpty()) {
79         m_sizes.remove(size);
80         if (!m_sizes.contains(size))
81             m_images.remove(size);
82     }
83 
84     if (!--sizeCount.count)
85         m_clients.remove(renderer);
86 
87 #if !ENABLE(OILPAN)
88     deref();
89 #else
90     if (m_clients.isEmpty()) {
91         ASSERT(m_keepAlive);
92         m_keepAlive = nullptr;
93     }
94 #endif
95 }
96 
getImage(RenderObject * renderer,const IntSize & size)97 Image* CSSImageGeneratorValue::getImage(RenderObject* renderer, const IntSize& size)
98 {
99     RenderObjectSizeCountMap::iterator it = m_clients.find(renderer);
100     if (it != m_clients.end()) {
101         SizeAndCount& sizeCount = it->value;
102         IntSize oldSize = sizeCount.size;
103         if (oldSize != size) {
104 #if !ENABLE_OILPAN
105             RefPtr<CSSImageGeneratorValue> protect(this);
106 #endif
107             removeClient(renderer);
108             addClient(renderer, size);
109         }
110     }
111 
112     // Don't generate an image for empty sizes.
113     if (size.isEmpty())
114         return 0;
115 
116     // Look up the image in our cache.
117     return m_images.get(size);
118 }
119 
putImage(const IntSize & size,PassRefPtr<Image> image)120 void CSSImageGeneratorValue::putImage(const IntSize& size, PassRefPtr<Image> image)
121 {
122     m_images.add(size, image);
123 }
124 
image(RenderObject * renderer,const IntSize & size)125 PassRefPtr<Image> CSSImageGeneratorValue::image(RenderObject* renderer, const IntSize& size)
126 {
127     switch (classType()) {
128     case CanvasClass:
129         return toCSSCanvasValue(this)->image(renderer, size);
130     case CrossfadeClass:
131         return toCSSCrossfadeValue(this)->image(renderer, size);
132     case LinearGradientClass:
133         return toCSSLinearGradientValue(this)->image(renderer, size);
134     case RadialGradientClass:
135         return toCSSRadialGradientValue(this)->image(renderer, size);
136     default:
137         ASSERT_NOT_REACHED();
138     }
139     return nullptr;
140 }
141 
isFixedSize() const142 bool CSSImageGeneratorValue::isFixedSize() const
143 {
144     switch (classType()) {
145     case CanvasClass:
146         return toCSSCanvasValue(this)->isFixedSize();
147     case CrossfadeClass:
148         return toCSSCrossfadeValue(this)->isFixedSize();
149     case LinearGradientClass:
150         return toCSSLinearGradientValue(this)->isFixedSize();
151     case RadialGradientClass:
152         return toCSSRadialGradientValue(this)->isFixedSize();
153     default:
154         ASSERT_NOT_REACHED();
155     }
156     return false;
157 }
158 
fixedSize(const RenderObject * renderer)159 IntSize CSSImageGeneratorValue::fixedSize(const RenderObject* renderer)
160 {
161     switch (classType()) {
162     case CanvasClass:
163         return toCSSCanvasValue(this)->fixedSize(renderer);
164     case CrossfadeClass:
165         return toCSSCrossfadeValue(this)->fixedSize(renderer);
166     case LinearGradientClass:
167         return toCSSLinearGradientValue(this)->fixedSize(renderer);
168     case RadialGradientClass:
169         return toCSSRadialGradientValue(this)->fixedSize(renderer);
170     default:
171         ASSERT_NOT_REACHED();
172     }
173     return IntSize();
174 }
175 
isPending() const176 bool CSSImageGeneratorValue::isPending() const
177 {
178     switch (classType()) {
179     case CrossfadeClass:
180         return toCSSCrossfadeValue(this)->isPending();
181     case CanvasClass:
182         return toCSSCanvasValue(this)->isPending();
183     case LinearGradientClass:
184         return toCSSLinearGradientValue(this)->isPending();
185     case RadialGradientClass:
186         return toCSSRadialGradientValue(this)->isPending();
187     default:
188         ASSERT_NOT_REACHED();
189     }
190     return false;
191 }
192 
knownToBeOpaque(const RenderObject * renderer) const193 bool CSSImageGeneratorValue::knownToBeOpaque(const RenderObject* renderer) const
194 {
195     switch (classType()) {
196     case CrossfadeClass:
197         return toCSSCrossfadeValue(this)->knownToBeOpaque(renderer);
198     case CanvasClass:
199         return false;
200     case LinearGradientClass:
201         return toCSSLinearGradientValue(this)->knownToBeOpaque(renderer);
202     case RadialGradientClass:
203         return toCSSRadialGradientValue(this)->knownToBeOpaque(renderer);
204     default:
205         ASSERT_NOT_REACHED();
206     }
207     return false;
208 }
209 
loadSubimages(ResourceFetcher * fetcher)210 void CSSImageGeneratorValue::loadSubimages(ResourceFetcher* fetcher)
211 {
212     switch (classType()) {
213     case CrossfadeClass:
214         toCSSCrossfadeValue(this)->loadSubimages(fetcher);
215         break;
216     case CanvasClass:
217         toCSSCanvasValue(this)->loadSubimages(fetcher);
218         break;
219     case LinearGradientClass:
220         toCSSLinearGradientValue(this)->loadSubimages(fetcher);
221         break;
222     case RadialGradientClass:
223         toCSSRadialGradientValue(this)->loadSubimages(fetcher);
224         break;
225     default:
226         ASSERT_NOT_REACHED();
227     }
228 }
229 
230 } // namespace blink
231