OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com> | 2 * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com> |
3 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> | 3 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> |
4 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 4 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
5 * | 5 * |
6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
10 * | 10 * |
(...skipping 28 matching lines...) Expand all Loading... |
39 , m_hasWidth(false) | 39 , m_hasWidth(false) |
40 , m_hasHeight(false) | 40 , m_hasHeight(false) |
41 { | 41 { |
42 ASSERT(m_filter); | 42 ASSERT(m_filter); |
43 } | 43 } |
44 | 44 |
45 FilterEffect::~FilterEffect() | 45 FilterEffect::~FilterEffect() |
46 { | 46 { |
47 } | 47 } |
48 | 48 |
| 49 inline bool isFilterSizeValid(IntRect rect) |
| 50 { |
| 51 if (rect.width() < 0 || rect.width() > kMaxFilterSize |
| 52 || rect.height() < 0 || rect.height() > kMaxFilterSize) |
| 53 return false; |
| 54 return true; |
| 55 } |
| 56 |
49 void FilterEffect::determineAbsolutePaintRect() | 57 void FilterEffect::determineAbsolutePaintRect() |
50 { | 58 { |
51 m_absolutePaintRect = IntRect(); | 59 m_absolutePaintRect = IntRect(); |
52 unsigned size = m_inputEffects.size(); | 60 unsigned size = m_inputEffects.size(); |
53 for (unsigned i = 0; i < size; ++i) | 61 for (unsigned i = 0; i < size; ++i) |
54 m_absolutePaintRect.unite(m_inputEffects.at(i)->absolutePaintRect()); | 62 m_absolutePaintRect.unite(m_inputEffects.at(i)->absolutePaintRect()); |
55 | 63 |
56 // SVG specification wants us to clip to primitive subregion. | 64 // SVG specification wants us to clip to primitive subregion. |
57 m_absolutePaintRect.intersect(m_maxEffectRect); | 65 m_absolutePaintRect.intersect(enclosingIntRect(m_maxEffectRect)); |
58 } | 66 } |
59 | 67 |
60 IntRect FilterEffect::requestedRegionOfInputImageData(const IntRect& effectRect)
const | 68 IntRect FilterEffect::requestedRegionOfInputImageData(const IntRect& effectRect)
const |
61 { | 69 { |
62 ASSERT(hasResult()); | 70 ASSERT(hasResult()); |
63 IntPoint location = m_absolutePaintRect.location(); | 71 IntPoint location = m_absolutePaintRect.location(); |
64 location.move(-effectRect.x(), -effectRect.y()); | 72 location.move(-effectRect.x(), -effectRect.y()); |
65 return IntRect(location, m_absolutePaintRect.size()); | 73 return IntRect(location, m_absolutePaintRect.size()); |
66 } | 74 } |
67 | 75 |
(...skipping 29 matching lines...) Expand all Loading... |
97 IntRect destinationRect(IntPoint(), m_absolutePaintRect.size()); | 105 IntRect destinationRect(IntPoint(), m_absolutePaintRect.size()); |
98 if (m_premultipliedImageResult) | 106 if (m_premultipliedImageResult) |
99 m_imageBufferResult->putPremultipliedImageData(m_premultipliedImageResul
t.get(), destinationRect.size(), destinationRect, IntPoint()); | 107 m_imageBufferResult->putPremultipliedImageData(m_premultipliedImageResul
t.get(), destinationRect.size(), destinationRect, IntPoint()); |
100 else | 108 else |
101 m_imageBufferResult->putUnmultipliedImageData(m_unmultipliedImageResult.
get(), destinationRect.size(), destinationRect, IntPoint()); | 109 m_imageBufferResult->putUnmultipliedImageData(m_unmultipliedImageResult.
get(), destinationRect.size(), destinationRect, IntPoint()); |
102 return m_imageBufferResult.get(); | 110 return m_imageBufferResult.get(); |
103 } | 111 } |
104 | 112 |
105 PassRefPtr<ByteArray> FilterEffect::asUnmultipliedImage(const IntRect& rect) | 113 PassRefPtr<ByteArray> FilterEffect::asUnmultipliedImage(const IntRect& rect) |
106 { | 114 { |
| 115 ASSERT(isFilterSizeValid(rect)); |
107 RefPtr<ByteArray> imageData = ByteArray::create(rect.width() * rect.height()
* 4); | 116 RefPtr<ByteArray> imageData = ByteArray::create(rect.width() * rect.height()
* 4); |
108 copyUnmultipliedImage(imageData.get(), rect); | 117 copyUnmultipliedImage(imageData.get(), rect); |
109 return imageData.release(); | 118 return imageData.release(); |
110 } | 119 } |
111 | 120 |
112 PassRefPtr<ByteArray> FilterEffect::asPremultipliedImage(const IntRect& rect) | 121 PassRefPtr<ByteArray> FilterEffect::asPremultipliedImage(const IntRect& rect) |
113 { | 122 { |
| 123 ASSERT(isFilterSizeValid(rect)); |
114 RefPtr<ByteArray> imageData = ByteArray::create(rect.width() * rect.height()
* 4); | 124 RefPtr<ByteArray> imageData = ByteArray::create(rect.width() * rect.height()
* 4); |
115 copyPremultipliedImage(imageData.get(), rect); | 125 copyPremultipliedImage(imageData.get(), rect); |
116 return imageData.release(); | 126 return imageData.release(); |
117 } | 127 } |
118 | 128 |
119 inline void FilterEffect::copyImageBytes(ByteArray* source, ByteArray* destinati
on, const IntRect& rect) | 129 inline void FilterEffect::copyImageBytes(ByteArray* source, ByteArray* destinati
on, const IntRect& rect) |
120 { | 130 { |
121 // Initialize the destination to transparent black, if not entirely covered
by the source. | 131 // Initialize the destination to transparent black, if not entirely covered
by the source. |
122 if (rect.x() < 0 || rect.y() < 0 || rect.maxX() > m_absolutePaintRect.width(
) || rect.maxY() > m_absolutePaintRect.height()) | 132 if (rect.x() < 0 || rect.y() < 0 || rect.maxX() > m_absolutePaintRect.width(
) || rect.maxY() > m_absolutePaintRect.height()) |
123 memset(destination->data(), 0, destination->length()); | 133 memset(destination->data(), 0, destination->length()); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 | 172 |
163 void FilterEffect::copyUnmultipliedImage(ByteArray* destination, const IntRect&
rect) | 173 void FilterEffect::copyUnmultipliedImage(ByteArray* destination, const IntRect&
rect) |
164 { | 174 { |
165 ASSERT(hasResult()); | 175 ASSERT(hasResult()); |
166 | 176 |
167 if (!m_unmultipliedImageResult) { | 177 if (!m_unmultipliedImageResult) { |
168 // We prefer a conversion from the image buffer. | 178 // We prefer a conversion from the image buffer. |
169 if (m_imageBufferResult) | 179 if (m_imageBufferResult) |
170 m_unmultipliedImageResult = m_imageBufferResult->getUnmultipliedImag
eData(IntRect(IntPoint(), m_absolutePaintRect.size())); | 180 m_unmultipliedImageResult = m_imageBufferResult->getUnmultipliedImag
eData(IntRect(IntPoint(), m_absolutePaintRect.size())); |
171 else { | 181 else { |
| 182 ASSERT(isFilterSizeValid(m_absolutePaintRect)); |
172 m_unmultipliedImageResult = ByteArray::create(m_absolutePaintRect.wi
dth() * m_absolutePaintRect.height() * 4); | 183 m_unmultipliedImageResult = ByteArray::create(m_absolutePaintRect.wi
dth() * m_absolutePaintRect.height() * 4); |
173 unsigned char* sourceComponent = m_premultipliedImageResult->data(); | 184 unsigned char* sourceComponent = m_premultipliedImageResult->data(); |
174 unsigned char* destinationComponent = m_unmultipliedImageResult->dat
a(); | 185 unsigned char* destinationComponent = m_unmultipliedImageResult->dat
a(); |
175 unsigned char* end = sourceComponent + (m_absolutePaintRect.width()
* m_absolutePaintRect.height() * 4); | 186 unsigned char* end = sourceComponent + (m_absolutePaintRect.width()
* m_absolutePaintRect.height() * 4); |
176 while (sourceComponent < end) { | 187 while (sourceComponent < end) { |
177 int alpha = sourceComponent[3]; | 188 int alpha = sourceComponent[3]; |
178 if (alpha) { | 189 if (alpha) { |
179 destinationComponent[0] = static_cast<int>(sourceComponent[0
]) * 255 / alpha; | 190 destinationComponent[0] = static_cast<int>(sourceComponent[0
]) * 255 / alpha; |
180 destinationComponent[1] = static_cast<int>(sourceComponent[1
]) * 255 / alpha; | 191 destinationComponent[1] = static_cast<int>(sourceComponent[1
]) * 255 / alpha; |
181 destinationComponent[2] = static_cast<int>(sourceComponent[2
]) * 255 / alpha; | 192 destinationComponent[2] = static_cast<int>(sourceComponent[2
]) * 255 / alpha; |
(...skipping 13 matching lines...) Expand all Loading... |
195 | 206 |
196 void FilterEffect::copyPremultipliedImage(ByteArray* destination, const IntRect&
rect) | 207 void FilterEffect::copyPremultipliedImage(ByteArray* destination, const IntRect&
rect) |
197 { | 208 { |
198 ASSERT(hasResult()); | 209 ASSERT(hasResult()); |
199 | 210 |
200 if (!m_premultipliedImageResult) { | 211 if (!m_premultipliedImageResult) { |
201 // We prefer a conversion from the image buffer. | 212 // We prefer a conversion from the image buffer. |
202 if (m_imageBufferResult) | 213 if (m_imageBufferResult) |
203 m_premultipliedImageResult = m_imageBufferResult->getPremultipliedIm
ageData(IntRect(IntPoint(), m_absolutePaintRect.size())); | 214 m_premultipliedImageResult = m_imageBufferResult->getPremultipliedIm
ageData(IntRect(IntPoint(), m_absolutePaintRect.size())); |
204 else { | 215 else { |
| 216 ASSERT(isFilterSizeValid(m_absolutePaintRect)); |
205 m_premultipliedImageResult = ByteArray::create(m_absolutePaintRect.w
idth() * m_absolutePaintRect.height() * 4); | 217 m_premultipliedImageResult = ByteArray::create(m_absolutePaintRect.w
idth() * m_absolutePaintRect.height() * 4); |
206 unsigned char* sourceComponent = m_unmultipliedImageResult->data(); | 218 unsigned char* sourceComponent = m_unmultipliedImageResult->data(); |
207 unsigned char* destinationComponent = m_premultipliedImageResult->da
ta(); | 219 unsigned char* destinationComponent = m_premultipliedImageResult->da
ta(); |
208 unsigned char* end = sourceComponent + (m_absolutePaintRect.width()
* m_absolutePaintRect.height() * 4); | 220 unsigned char* end = sourceComponent + (m_absolutePaintRect.width()
* m_absolutePaintRect.height() * 4); |
209 while (sourceComponent < end) { | 221 while (sourceComponent < end) { |
210 int alpha = sourceComponent[3]; | 222 int alpha = sourceComponent[3]; |
211 destinationComponent[0] = static_cast<int>(sourceComponent[0]) *
alpha / 255; | 223 destinationComponent[0] = static_cast<int>(sourceComponent[0]) *
alpha / 255; |
212 destinationComponent[1] = static_cast<int>(sourceComponent[1]) *
alpha / 255; | 224 destinationComponent[1] = static_cast<int>(sourceComponent[1]) *
alpha / 255; |
213 destinationComponent[2] = static_cast<int>(sourceComponent[2]) *
alpha / 255; | 225 destinationComponent[2] = static_cast<int>(sourceComponent[2]) *
alpha / 255; |
214 destinationComponent[3] = alpha; | 226 destinationComponent[3] = alpha; |
(...skipping 16 matching lines...) Expand all Loading... |
231 if (!m_imageBufferResult) | 243 if (!m_imageBufferResult) |
232 return 0; | 244 return 0; |
233 ASSERT(m_imageBufferResult->context()); | 245 ASSERT(m_imageBufferResult->context()); |
234 return m_imageBufferResult.get(); | 246 return m_imageBufferResult.get(); |
235 } | 247 } |
236 | 248 |
237 ByteArray* FilterEffect::createUnmultipliedImageResult() | 249 ByteArray* FilterEffect::createUnmultipliedImageResult() |
238 { | 250 { |
239 // Only one result type is allowed. | 251 // Only one result type is allowed. |
240 ASSERT(!hasResult()); | 252 ASSERT(!hasResult()); |
| 253 ASSERT(isFilterSizeValid(m_absolutePaintRect)); |
| 254 |
241 determineAbsolutePaintRect(); | 255 determineAbsolutePaintRect(); |
242 if (m_absolutePaintRect.isEmpty()) | 256 if (m_absolutePaintRect.isEmpty()) |
243 return 0; | 257 return 0; |
244 m_unmultipliedImageResult = ByteArray::create(m_absolutePaintRect.width() *
m_absolutePaintRect.height() * 4); | 258 m_unmultipliedImageResult = ByteArray::create(m_absolutePaintRect.width() *
m_absolutePaintRect.height() * 4); |
245 return m_unmultipliedImageResult.get(); | 259 return m_unmultipliedImageResult.get(); |
246 } | 260 } |
247 | 261 |
248 ByteArray* FilterEffect::createPremultipliedImageResult() | 262 ByteArray* FilterEffect::createPremultipliedImageResult() |
249 { | 263 { |
250 // Only one result type is allowed. | 264 // Only one result type is allowed. |
251 ASSERT(!hasResult()); | 265 ASSERT(!hasResult()); |
| 266 ASSERT(isFilterSizeValid(m_absolutePaintRect)); |
| 267 |
252 determineAbsolutePaintRect(); | 268 determineAbsolutePaintRect(); |
253 if (m_absolutePaintRect.isEmpty()) | 269 if (m_absolutePaintRect.isEmpty()) |
254 return 0; | 270 return 0; |
255 m_premultipliedImageResult = ByteArray::create(m_absolutePaintRect.width() *
m_absolutePaintRect.height() * 4); | 271 m_premultipliedImageResult = ByteArray::create(m_absolutePaintRect.width() *
m_absolutePaintRect.height() * 4); |
256 return m_premultipliedImageResult.get(); | 272 return m_premultipliedImageResult.get(); |
257 } | 273 } |
258 | 274 |
259 TextStream& FilterEffect::externalRepresentation(TextStream& ts, int) const | 275 TextStream& FilterEffect::externalRepresentation(TextStream& ts, int) const |
260 { | 276 { |
261 // FIXME: We should dump the subRegions of the filter primitives here later.
This isn't | 277 // FIXME: We should dump the subRegions of the filter primitives here later.
This isn't |
262 // possible at the moment, because we need more detailed informations from t
he target object. | 278 // possible at the moment, because we need more detailed informations from t
he target object. |
263 return ts; | 279 return ts; |
264 } | 280 } |
265 | 281 |
266 } // namespace WebCore | 282 } // namespace WebCore |
267 | 283 |
268 #endif // ENABLE(FILTERS) | 284 #endif // ENABLE(FILTERS) |
OLD | NEW |