| 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 |