summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics/filters
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-05-06 11:45:16 +0100
committerSteve Block <steveblock@google.com>2011-05-12 13:44:10 +0100
commitcad810f21b803229eb11403f9209855525a25d57 (patch)
tree29a6fd0279be608e0fe9ffe9841f722f0f4e4269 /Source/WebCore/platform/graphics/filters
parent121b0cf4517156d0ac5111caf9830c51b69bae8f (diff)
downloadexternal_webkit-cad810f21b803229eb11403f9209855525a25d57.zip
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.gz
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.bz2
Merge WebKit at r75315: Initial merge by git.
Change-Id: I570314b346ce101c935ed22a626b48c2af266b84
Diffstat (limited to 'Source/WebCore/platform/graphics/filters')
-rw-r--r--Source/WebCore/platform/graphics/filters/DistantLightSource.h62
-rw-r--r--Source/WebCore/platform/graphics/filters/FEBlend.cpp175
-rw-r--r--Source/WebCore/platform/graphics/filters/FEBlend.h63
-rw-r--r--Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp241
-rw-r--r--Source/WebCore/platform/graphics/filters/FEColorMatrix.h67
-rw-r--r--Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp245
-rw-r--r--Source/WebCore/platform/graphics/filters/FEComponentTransfer.h100
-rw-r--r--Source/WebCore/platform/graphics/filters/FEComposite.cpp290
-rw-r--r--Source/WebCore/platform/graphics/filters/FEComposite.h83
-rw-r--r--Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp471
-rw-r--r--Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h120
-rw-r--r--Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp126
-rw-r--r--Source/WebCore/platform/graphics/filters/FEDiffuseLighting.h68
-rw-r--r--Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp172
-rw-r--r--Source/WebCore/platform/graphics/filters/FEDisplacementMap.h72
-rw-r--r--Source/WebCore/platform/graphics/filters/FEFlood.cpp93
-rw-r--r--Source/WebCore/platform/graphics/filters/FEFlood.h60
-rw-r--r--Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp242
-rw-r--r--Source/WebCore/platform/graphics/filters/FEGaussianBlur.h61
-rw-r--r--Source/WebCore/platform/graphics/filters/FELighting.cpp359
-rw-r--r--Source/WebCore/platform/graphics/filters/FELighting.h98
-rw-r--r--Source/WebCore/platform/graphics/filters/FEMerge.cpp85
-rw-r--r--Source/WebCore/platform/graphics/filters/FEMerge.h49
-rw-r--r--Source/WebCore/platform/graphics/filters/FEMorphology.cpp199
-rw-r--r--Source/WebCore/platform/graphics/filters/FEMorphology.h68
-rw-r--r--Source/WebCore/platform/graphics/filters/FEOffset.cpp112
-rw-r--r--Source/WebCore/platform/graphics/filters/FEOffset.h59
-rw-r--r--Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp138
-rw-r--r--Source/WebCore/platform/graphics/filters/FESpecularLighting.h69
-rw-r--r--Source/WebCore/platform/graphics/filters/FETile.cpp108
-rw-r--r--Source/WebCore/platform/graphics/filters/FETile.h52
-rw-r--r--Source/WebCore/platform/graphics/filters/FETurbulence.cpp385
-rw-r--r--Source/WebCore/platform/graphics/filters/FETurbulence.h105
-rw-r--r--Source/WebCore/platform/graphics/filters/Filter.h68
-rw-r--r--Source/WebCore/platform/graphics/filters/FilterEffect.cpp251
-rw-r--r--Source/WebCore/platform/graphics/filters/FilterEffect.h154
-rw-r--r--Source/WebCore/platform/graphics/filters/LightSource.cpp170
-rw-r--r--Source/WebCore/platform/graphics/filters/LightSource.h85
-rw-r--r--Source/WebCore/platform/graphics/filters/PointLightSource.h59
-rw-r--r--Source/WebCore/platform/graphics/filters/SourceAlpha.cpp85
-rw-r--r--Source/WebCore/platform/graphics/filters/SourceAlpha.h57
-rw-r--r--Source/WebCore/platform/graphics/filters/SourceGraphic.cpp77
-rw-r--r--Source/WebCore/platform/graphics/filters/SourceGraphic.h58
-rw-r--r--Source/WebCore/platform/graphics/filters/SpotLightSource.h72
44 files changed, 5833 insertions, 0 deletions
diff --git a/Source/WebCore/platform/graphics/filters/DistantLightSource.h b/Source/WebCore/platform/graphics/filters/DistantLightSource.h
new file mode 100644
index 0000000..d5d474f
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/DistantLightSource.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef DistantLightSource_h
+#define DistantLightSource_h
+
+#if ENABLE(FILTERS)
+#include "LightSource.h"
+
+namespace WebCore {
+
+class DistantLightSource : public LightSource {
+public:
+ static PassRefPtr<DistantLightSource> create(float azimuth, float elevation)
+ {
+ return adoptRef(new DistantLightSource(azimuth, elevation));
+ }
+
+ float azimuth() const { return m_azimuth; }
+ float elevation() const { return m_elevation; }
+
+ virtual void initPaintingData(PaintingData&);
+ virtual void updatePaintingData(PaintingData&, int x, int y, float z);
+
+ virtual TextStream& externalRepresentation(TextStream&) const;
+
+private:
+ DistantLightSource(float azimuth, float elevation)
+ : LightSource(LS_DISTANT)
+ , m_azimuth(azimuth)
+ , m_elevation(elevation)
+ {
+ }
+
+ float m_azimuth;
+ float m_elevation;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // DistantLightSource_h
diff --git a/Source/WebCore/platform/graphics/filters/FEBlend.cpp b/Source/WebCore/platform/graphics/filters/FEBlend.cpp
new file mode 100644
index 0000000..7eeb128
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEBlend.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FEBlend.h"
+
+#include "Filter.h"
+#include "FloatPoint.h"
+#include "GraphicsContext.h"
+
+#include <wtf/ByteArray.h>
+
+typedef unsigned char (*BlendType)(unsigned char colorA, unsigned char colorB, unsigned char alphaA, unsigned char alphaB);
+
+namespace WebCore {
+
+FEBlend::FEBlend(Filter* filter, BlendModeType mode)
+ : FilterEffect(filter)
+ , m_mode(mode)
+{
+}
+
+PassRefPtr<FEBlend> FEBlend::create(Filter* filter, BlendModeType mode)
+{
+ return adoptRef(new FEBlend(filter, mode));
+}
+
+BlendModeType FEBlend::blendMode() const
+{
+ return m_mode;
+}
+
+void FEBlend::setBlendMode(BlendModeType mode)
+{
+ m_mode = mode;
+}
+
+static unsigned char unknown(unsigned char, unsigned char, unsigned char, unsigned char)
+{
+ return 0;
+}
+
+static unsigned char normal(unsigned char colorA, unsigned char colorB, unsigned char alphaA, unsigned char)
+{
+ return (((255 - alphaA) * colorB + colorA * 255) / 255);
+}
+
+static unsigned char multiply(unsigned char colorA, unsigned char colorB, unsigned char alphaA, unsigned char alphaB)
+{
+ return (((255 - alphaA) * colorB + (255 - alphaB + colorB) * colorA) / 255);
+}
+
+static unsigned char screen(unsigned char colorA, unsigned char colorB, unsigned char, unsigned char)
+{
+ return (((colorB + colorA) * 255 - colorA * colorB) / 255);
+}
+
+static unsigned char darken(unsigned char colorA, unsigned char colorB, unsigned char alphaA, unsigned char alphaB)
+{
+ return ((std::min((255 - alphaA) * colorB + colorA * 255, (255 - alphaB) * colorA + colorB * 255)) / 255);
+}
+
+static unsigned char lighten(unsigned char colorA, unsigned char colorB, unsigned char alphaA, unsigned char alphaB)
+{
+ return ((std::max((255 - alphaA) * colorB + colorA * 255, (255 - alphaB) * colorA + colorB * 255)) / 255);
+}
+
+void FEBlend::apply()
+{
+ if (hasResult())
+ return;
+ FilterEffect* in = inputEffect(0);
+ FilterEffect* in2 = inputEffect(1);
+ in->apply();
+ in2->apply();
+ if (!in->hasResult() || !in2->hasResult())
+ return;
+
+ if (m_mode <= FEBLEND_MODE_UNKNOWN || m_mode > FEBLEND_MODE_LIGHTEN)
+ return;
+
+ ByteArray* dstPixelArray = createPremultipliedImageResult();
+ if (!dstPixelArray)
+ return;
+
+ IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
+ RefPtr<ByteArray> srcPixelArrayA = in->asPremultipliedImage(effectADrawingRect);
+
+ IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect());
+ RefPtr<ByteArray> srcPixelArrayB = in2->asPremultipliedImage(effectBDrawingRect);
+
+ // Keep synchronized with BlendModeType
+ static const BlendType callEffect[] = {unknown, normal, multiply, screen, darken, lighten};
+
+ unsigned pixelArrayLength = srcPixelArrayA->length();
+ ASSERT(pixelArrayLength == srcPixelArrayB->length());
+ for (unsigned pixelOffset = 0; pixelOffset < pixelArrayLength; pixelOffset += 4) {
+ unsigned char alphaA = srcPixelArrayA->get(pixelOffset + 3);
+ unsigned char alphaB = srcPixelArrayB->get(pixelOffset + 3);
+ for (unsigned channel = 0; channel < 3; ++channel) {
+ unsigned char colorA = srcPixelArrayA->get(pixelOffset + channel);
+ unsigned char colorB = srcPixelArrayB->get(pixelOffset + channel);
+
+ unsigned char result = (*callEffect[m_mode])(colorA, colorB, alphaA, alphaB);
+ dstPixelArray->set(pixelOffset + channel, result);
+ }
+ unsigned char alphaR = 255 - ((255 - alphaA) * (255 - alphaB)) / 255;
+ dstPixelArray->set(pixelOffset + 3, alphaR);
+ }
+}
+
+void FEBlend::dump()
+{
+}
+
+static TextStream& operator<<(TextStream& ts, const BlendModeType& type)
+{
+ switch (type) {
+ case FEBLEND_MODE_UNKNOWN:
+ ts << "UNKNOWN";
+ break;
+ case FEBLEND_MODE_NORMAL:
+ ts << "NORMAL";
+ break;
+ case FEBLEND_MODE_MULTIPLY:
+ ts << "MULTIPLY";
+ break;
+ case FEBLEND_MODE_SCREEN:
+ ts << "SCREEN";
+ break;
+ case FEBLEND_MODE_DARKEN:
+ ts << "DARKEN";
+ break;
+ case FEBLEND_MODE_LIGHTEN:
+ ts << "LIGHTEN";
+ break;
+ }
+ return ts;
+}
+
+TextStream& FEBlend::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feBlend";
+ FilterEffect::externalRepresentation(ts);
+ ts << " mode=\"" << m_mode << "\"]\n";
+ inputEffect(0)->externalRepresentation(ts, indent + 1);
+ inputEffect(1)->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/FEBlend.h b/Source/WebCore/platform/graphics/filters/FEBlend.h
new file mode 100644
index 0000000..4c59578
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEBlend.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FEBlend_h
+#define FEBlend_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+
+#include "Filter.h"
+
+namespace WebCore {
+
+enum BlendModeType {
+ FEBLEND_MODE_UNKNOWN = 0,
+ FEBLEND_MODE_NORMAL = 1,
+ FEBLEND_MODE_MULTIPLY = 2,
+ FEBLEND_MODE_SCREEN = 3,
+ FEBLEND_MODE_DARKEN = 4,
+ FEBLEND_MODE_LIGHTEN = 5
+};
+
+class FEBlend : public FilterEffect {
+public:
+ static PassRefPtr<FEBlend> create(Filter*, BlendModeType);
+
+ BlendModeType blendMode() const;
+ void setBlendMode(BlendModeType);
+
+ virtual void apply();
+ virtual void dump();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FEBlend(Filter*, BlendModeType);
+
+ BlendModeType m_mode;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FEBlend_h
diff --git a/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp
new file mode 100644
index 0000000..e0b15d1
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FEColorMatrix.h"
+
+#include "Filter.h"
+#include "GraphicsContext.h"
+
+#include <wtf/ByteArray.h>
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+FEColorMatrix::FEColorMatrix(Filter* filter, ColorMatrixType type, const Vector<float>& values)
+ : FilterEffect(filter)
+ , m_type(type)
+ , m_values(values)
+{
+}
+
+PassRefPtr<FEColorMatrix> FEColorMatrix::create(Filter* filter, ColorMatrixType type, const Vector<float>& values)
+{
+ return adoptRef(new FEColorMatrix(filter, type, values));
+}
+
+ColorMatrixType FEColorMatrix::type() const
+{
+ return m_type;
+}
+
+void FEColorMatrix::setType(ColorMatrixType type)
+{
+ m_type = type;
+}
+
+const Vector<float>& FEColorMatrix::values() const
+{
+ return m_values;
+}
+
+void FEColorMatrix::setValues(const Vector<float> &values)
+{
+ m_values = values;
+}
+
+inline void matrix(double& red, double& green, double& blue, double& alpha, const Vector<float>& values)
+{
+ double r = values[0] * red + values[1] * green + values[2] * blue + values[3] * alpha + values[4] * 255;
+ double g = values[5] * red + values[6] * green + values[7] * blue + values[8] * alpha + values[9] * 255;
+ double b = values[10] * red + values[11] * green + values[12] * blue + values[13] * alpha + values[14] * 255;
+ double a = values[15] * red + values[16] * green + values[17] * blue + values[18] * alpha + values[19] * 255;
+
+ red = r;
+ green = g;
+ blue = b;
+ alpha = a;
+}
+
+inline void saturate(double& red, double& green, double& blue, const float& s)
+{
+ double r = (0.213 + 0.787 * s) * red + (0.715 - 0.715 * s) * green + (0.072 - 0.072 * s) * blue;
+ double g = (0.213 - 0.213 * s) * red + (0.715 + 0.285 * s) * green + (0.072 - 0.072 * s) * blue;
+ double b = (0.213 - 0.213 * s) * red + (0.715 - 0.715 * s) * green + (0.072 + 0.928 * s) * blue;
+
+ red = r;
+ green = g;
+ blue = b;
+}
+
+inline void huerotate(double& red, double& green, double& blue, const float& hue)
+{
+ double cosHue = cos(hue * piDouble / 180);
+ double sinHue = sin(hue * piDouble / 180);
+ double r = red * (0.213 + cosHue * 0.787 - sinHue * 0.213) +
+ green * (0.715 - cosHue * 0.715 - sinHue * 0.715) +
+ blue * (0.072 - cosHue * 0.072 + sinHue * 0.928);
+ double g = red * (0.213 - cosHue * 0.213 + sinHue * 0.143) +
+ green * (0.715 + cosHue * 0.285 + sinHue * 0.140) +
+ blue * (0.072 - cosHue * 0.072 - sinHue * 0.283);
+ double b = red * (0.213 - cosHue * 0.213 - sinHue * 0.787) +
+ green * (0.715 - cosHue * 0.715 + sinHue * 0.715) +
+ blue * (0.072 + cosHue * 0.928 + sinHue * 0.072);
+
+ red = r;
+ green = g;
+ blue = b;
+}
+
+inline void luminance(double& red, double& green, double& blue, double& alpha)
+{
+ alpha = 0.2125 * red + 0.7154 * green + 0.0721 * blue;
+ red = 0;
+ green = 0;
+ blue = 0;
+}
+
+template<ColorMatrixType filterType>
+void effectType(ByteArray* pixelArray, const Vector<float>& values)
+{
+ unsigned pixelArrayLength = pixelArray->length();
+ for (unsigned pixelByteOffset = 0; pixelByteOffset < pixelArrayLength; pixelByteOffset += 4) {
+ double red = pixelArray->get(pixelByteOffset);
+ double green = pixelArray->get(pixelByteOffset + 1);
+ double blue = pixelArray->get(pixelByteOffset + 2);
+ double alpha = pixelArray->get(pixelByteOffset + 3);
+
+ switch (filterType) {
+ case FECOLORMATRIX_TYPE_MATRIX:
+ matrix(red, green, blue, alpha, values);
+ break;
+ case FECOLORMATRIX_TYPE_SATURATE:
+ saturate(red, green, blue, values[0]);
+ break;
+ case FECOLORMATRIX_TYPE_HUEROTATE:
+ huerotate(red, green, blue, values[0]);
+ break;
+ case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
+ luminance(red, green, blue, alpha);
+ break;
+ }
+
+ pixelArray->set(pixelByteOffset, red);
+ pixelArray->set(pixelByteOffset + 1, green);
+ pixelArray->set(pixelByteOffset + 2, blue);
+ pixelArray->set(pixelByteOffset + 3, alpha);
+ }
+}
+
+void FEColorMatrix::apply()
+{
+ if (hasResult())
+ return;
+ FilterEffect* in = inputEffect(0);
+ in->apply();
+ if (!in->hasResult())
+ return;
+
+ ImageBuffer* resultImage = createImageBufferResult();
+ if (!resultImage)
+ return;
+
+ resultImage->context()->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()));
+
+ IntRect imageRect(IntPoint(), absolutePaintRect().size());
+ RefPtr<ByteArray> pixelArray = resultImage->getUnmultipliedImageData(imageRect);
+
+ switch (m_type) {
+ case FECOLORMATRIX_TYPE_UNKNOWN:
+ break;
+ case FECOLORMATRIX_TYPE_MATRIX:
+ effectType<FECOLORMATRIX_TYPE_MATRIX>(pixelArray.get(), m_values);
+ break;
+ case FECOLORMATRIX_TYPE_SATURATE:
+ effectType<FECOLORMATRIX_TYPE_SATURATE>(pixelArray.get(), m_values);
+ break;
+ case FECOLORMATRIX_TYPE_HUEROTATE:
+ effectType<FECOLORMATRIX_TYPE_HUEROTATE>(pixelArray.get(), m_values);
+ break;
+ case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
+ effectType<FECOLORMATRIX_TYPE_LUMINANCETOALPHA>(pixelArray.get(), m_values);
+ setIsAlphaImage(true);
+ break;
+ }
+
+ resultImage->putUnmultipliedImageData(pixelArray.get(), imageRect.size(), imageRect, IntPoint());
+}
+
+void FEColorMatrix::dump()
+{
+}
+
+static TextStream& operator<<(TextStream& ts, const ColorMatrixType& type)
+{
+ switch (type) {
+ case FECOLORMATRIX_TYPE_UNKNOWN:
+ ts << "UNKNOWN";
+ break;
+ case FECOLORMATRIX_TYPE_MATRIX:
+ ts << "MATRIX";
+ break;
+ case FECOLORMATRIX_TYPE_SATURATE:
+ ts << "SATURATE";
+ break;
+ case FECOLORMATRIX_TYPE_HUEROTATE:
+ ts << "HUEROTATE";
+ break;
+ case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
+ ts << "LUMINANCETOALPHA";
+ break;
+ }
+ return ts;
+}
+
+TextStream& FEColorMatrix::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feColorMatrix";
+ FilterEffect::externalRepresentation(ts);
+ ts << " type=\"" << m_type << "\"";
+ if (!m_values.isEmpty()) {
+ ts << " values=\"";
+ Vector<float>::const_iterator ptr = m_values.begin();
+ const Vector<float>::const_iterator end = m_values.end();
+ while (ptr < end) {
+ ts << *ptr;
+ ++ptr;
+ if (ptr < end)
+ ts << " ";
+ }
+ ts << "\"";
+ }
+ ts << "]\n";
+ inputEffect(0)->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/FEColorMatrix.h b/Source/WebCore/platform/graphics/filters/FEColorMatrix.h
new file mode 100644
index 0000000..a3ced7e
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEColorMatrix.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FEColorMatrix_h
+#define FEColorMatrix_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+
+#include "Filter.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+enum ColorMatrixType {
+ FECOLORMATRIX_TYPE_UNKNOWN = 0,
+ FECOLORMATRIX_TYPE_MATRIX = 1,
+ FECOLORMATRIX_TYPE_SATURATE = 2,
+ FECOLORMATRIX_TYPE_HUEROTATE = 3,
+ FECOLORMATRIX_TYPE_LUMINANCETOALPHA = 4
+};
+
+class FEColorMatrix : public FilterEffect {
+public:
+ static PassRefPtr<FEColorMatrix> create(Filter*, ColorMatrixType, const Vector<float>&);
+
+ ColorMatrixType type() const;
+ void setType(ColorMatrixType);
+
+ const Vector<float>& values() const;
+ void setValues(const Vector<float>&);
+
+ virtual void apply();
+ virtual void dump();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FEColorMatrix(Filter*, ColorMatrixType, const Vector<float>&);
+
+ ColorMatrixType m_type;
+ Vector<float> m_values;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FEColorMatrix_h
diff --git a/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp b/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
new file mode 100644
index 0000000..ca8e5d3
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FEComponentTransfer.h"
+
+#include "Filter.h"
+#include "GraphicsContext.h"
+
+#include <wtf/ByteArray.h>
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+typedef void (*TransferType)(unsigned char*, const ComponentTransferFunction&);
+
+FEComponentTransfer::FEComponentTransfer(Filter* filter, const ComponentTransferFunction& redFunc, const ComponentTransferFunction& greenFunc,
+ const ComponentTransferFunction& blueFunc, const ComponentTransferFunction& alphaFunc)
+ : FilterEffect(filter)
+ , m_redFunc(redFunc)
+ , m_greenFunc(greenFunc)
+ , m_blueFunc(blueFunc)
+ , m_alphaFunc(alphaFunc)
+{
+}
+
+PassRefPtr<FEComponentTransfer> FEComponentTransfer::create(Filter* filter, const ComponentTransferFunction& redFunc,
+ const ComponentTransferFunction& greenFunc, const ComponentTransferFunction& blueFunc, const ComponentTransferFunction& alphaFunc)
+{
+ return adoptRef(new FEComponentTransfer(filter, redFunc, greenFunc, blueFunc, alphaFunc));
+}
+
+ComponentTransferFunction FEComponentTransfer::redFunction() const
+{
+ return m_redFunc;
+}
+
+void FEComponentTransfer::setRedFunction(const ComponentTransferFunction& func)
+{
+ m_redFunc = func;
+}
+
+ComponentTransferFunction FEComponentTransfer::greenFunction() const
+{
+ return m_greenFunc;
+}
+
+void FEComponentTransfer::setGreenFunction(const ComponentTransferFunction& func)
+{
+ m_greenFunc = func;
+}
+
+ComponentTransferFunction FEComponentTransfer::blueFunction() const
+{
+ return m_blueFunc;
+}
+
+void FEComponentTransfer::setBlueFunction(const ComponentTransferFunction& func)
+{
+ m_blueFunc = func;
+}
+
+ComponentTransferFunction FEComponentTransfer::alphaFunction() const
+{
+ return m_alphaFunc;
+}
+
+void FEComponentTransfer::setAlphaFunction(const ComponentTransferFunction& func)
+{
+ m_alphaFunc = func;
+}
+
+static void identity(unsigned char*, const ComponentTransferFunction&)
+{
+}
+
+static void table(unsigned char* values, const ComponentTransferFunction& transferFunction)
+{
+ const Vector<float>& tableValues = transferFunction.tableValues;
+ unsigned n = tableValues.size();
+ if (n < 1)
+ return;
+ for (unsigned i = 0; i < 256; ++i) {
+ double c = i / 255.0;
+ unsigned k = static_cast<unsigned>(c * (n - 1));
+ double v1 = tableValues[k];
+ double v2 = tableValues[std::min((k + 1), (n - 1))];
+ double val = 255.0 * (v1 + (c * (n - 1) - k) * (v2 - v1));
+ val = std::max(0.0, std::min(255.0, val));
+ values[i] = static_cast<unsigned char>(val);
+ }
+}
+
+static void discrete(unsigned char* values, const ComponentTransferFunction& transferFunction)
+{
+ const Vector<float>& tableValues = transferFunction.tableValues;
+ unsigned n = tableValues.size();
+ if (n < 1)
+ return;
+ for (unsigned i = 0; i < 256; ++i) {
+ unsigned k = static_cast<unsigned>((i * n) / 255.0);
+ k = std::min(k, n - 1);
+ double val = 255 * tableValues[k];
+ val = std::max(0.0, std::min(255.0, val));
+ values[i] = static_cast<unsigned char>(val);
+ }
+}
+
+static void linear(unsigned char* values, const ComponentTransferFunction& transferFunction)
+{
+ for (unsigned i = 0; i < 256; ++i) {
+ double val = transferFunction.slope * i + 255 * transferFunction.intercept;
+ val = std::max(0.0, std::min(255.0, val));
+ values[i] = static_cast<unsigned char>(val);
+ }
+}
+
+static void gamma(unsigned char* values, const ComponentTransferFunction& transferFunction)
+{
+ for (unsigned i = 0; i < 256; ++i) {
+ double exponent = transferFunction.exponent; // RCVT doesn't like passing a double and a float to pow, so promote this to double
+ double val = 255.0 * (transferFunction.amplitude * pow((i / 255.0), exponent) + transferFunction.offset);
+ val = std::max(0.0, std::min(255.0, val));
+ values[i] = static_cast<unsigned char>(val);
+ }
+}
+
+void FEComponentTransfer::apply()
+{
+ if (hasResult())
+ return;
+ FilterEffect* in = inputEffect(0);
+ in->apply();
+ if (!in->hasResult())
+ return;
+
+ ByteArray* pixelArray = createUnmultipliedImageResult();
+ if (!pixelArray)
+ return;
+
+ unsigned char rValues[256], gValues[256], bValues[256], aValues[256];
+ for (unsigned i = 0; i < 256; ++i)
+ rValues[i] = gValues[i] = bValues[i] = aValues[i] = i;
+ unsigned char* tables[] = { rValues, gValues, bValues, aValues };
+ ComponentTransferFunction transferFunction[] = {m_redFunc, m_greenFunc, m_blueFunc, m_alphaFunc};
+ TransferType callEffect[] = {identity, identity, table, discrete, linear, gamma};
+
+ for (unsigned channel = 0; channel < 4; channel++)
+ (*callEffect[transferFunction[channel].type])(tables[channel], transferFunction[channel]);
+
+ IntRect drawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
+ in->copyUnmultipliedImage(pixelArray, drawingRect);
+
+ unsigned pixelArrayLength = pixelArray->length();
+ for (unsigned pixelOffset = 0; pixelOffset < pixelArrayLength; pixelOffset += 4) {
+ for (unsigned channel = 0; channel < 4; ++channel) {
+ unsigned char c = pixelArray->get(pixelOffset + channel);
+ pixelArray->set(pixelOffset + channel, tables[channel][c]);
+ }
+ }
+}
+
+void FEComponentTransfer::dump()
+{
+}
+
+static TextStream& operator<<(TextStream& ts, const ComponentTransferType& type)
+{
+ switch (type) {
+ case FECOMPONENTTRANSFER_TYPE_UNKNOWN:
+ ts << "UNKNOWN";
+ break;
+ case FECOMPONENTTRANSFER_TYPE_IDENTITY:
+ ts << "IDENTITY";
+ break;
+ case FECOMPONENTTRANSFER_TYPE_TABLE:
+ ts << "TABLE";
+ break;
+ case FECOMPONENTTRANSFER_TYPE_DISCRETE:
+ ts << "DISCRETE";
+ break;
+ case FECOMPONENTTRANSFER_TYPE_LINEAR:
+ ts << "LINEAR";
+ break;
+ case FECOMPONENTTRANSFER_TYPE_GAMMA:
+ ts << "GAMMA";
+ break;
+ }
+ return ts;
+}
+
+static TextStream& operator<<(TextStream& ts, const ComponentTransferFunction& function)
+{
+ ts << "type=\"" << function.type
+ << "\" slope=\"" << function.slope
+ << "\" intercept=\"" << function.intercept
+ << "\" amplitude=\"" << function.amplitude
+ << "\" exponent=\"" << function.exponent
+ << "\" offset=\"" << function.offset << "\"";
+ return ts;
+}
+
+TextStream& FEComponentTransfer::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feComponentTransfer";
+ FilterEffect::externalRepresentation(ts);
+ ts << " \n";
+ writeIndent(ts, indent + 2);
+ ts << "{red: " << m_redFunc << "}\n";
+ writeIndent(ts, indent + 2);
+ ts << "{green: " << m_greenFunc << "}\n";
+ writeIndent(ts, indent + 2);
+ ts << "{blue: " << m_blueFunc << "}\n";
+ writeIndent(ts, indent + 2);
+ ts << "{alpha: " << m_alphaFunc << "}]\n";
+ inputEffect(0)->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/FEComponentTransfer.h b/Source/WebCore/platform/graphics/filters/FEComponentTransfer.h
new file mode 100644
index 0000000..bbe3ebb
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEComponentTransfer.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FEComponentTransfer_h
+#define FEComponentTransfer_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+
+#include "Filter.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+enum ComponentTransferType {
+ FECOMPONENTTRANSFER_TYPE_UNKNOWN = 0,
+ FECOMPONENTTRANSFER_TYPE_IDENTITY = 1,
+ FECOMPONENTTRANSFER_TYPE_TABLE = 2,
+ FECOMPONENTTRANSFER_TYPE_DISCRETE = 3,
+ FECOMPONENTTRANSFER_TYPE_LINEAR = 4,
+ FECOMPONENTTRANSFER_TYPE_GAMMA = 5
+};
+
+struct ComponentTransferFunction {
+ ComponentTransferFunction()
+ : type(FECOMPONENTTRANSFER_TYPE_UNKNOWN)
+ , slope(0)
+ , intercept(0)
+ , amplitude(0)
+ , exponent(0)
+ , offset(0)
+ {
+ }
+
+ ComponentTransferType type;
+
+ float slope;
+ float intercept;
+ float amplitude;
+ float exponent;
+ float offset;
+
+ Vector<float> tableValues;
+};
+
+class FEComponentTransfer : public FilterEffect {
+public:
+ static PassRefPtr<FEComponentTransfer> create(Filter*, const ComponentTransferFunction& redFunc, const ComponentTransferFunction& greenFunc,
+ const ComponentTransferFunction& blueFunc, const ComponentTransferFunction& alphaFunc);
+
+ ComponentTransferFunction redFunction() const;
+ void setRedFunction(const ComponentTransferFunction&);
+
+ ComponentTransferFunction greenFunction() const;
+ void setGreenFunction(const ComponentTransferFunction&);
+
+ ComponentTransferFunction blueFunction() const;
+ void setBlueFunction(const ComponentTransferFunction&);
+
+ ComponentTransferFunction alphaFunction() const;
+ void setAlphaFunction(const ComponentTransferFunction&);
+
+ virtual void apply();
+ virtual void dump();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FEComponentTransfer(Filter*, const ComponentTransferFunction& redFunc, const ComponentTransferFunction& greenFunc,
+ const ComponentTransferFunction& blueFunc, const ComponentTransferFunction& alphaFunc);
+
+ ComponentTransferFunction m_redFunc;
+ ComponentTransferFunction m_greenFunc;
+ ComponentTransferFunction m_blueFunc;
+ ComponentTransferFunction m_alphaFunc;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FEComponentTransfer_h
diff --git a/Source/WebCore/platform/graphics/filters/FEComposite.cpp b/Source/WebCore/platform/graphics/filters/FEComposite.cpp
new file mode 100644
index 0000000..80cb2b2
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEComposite.cpp
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FEComposite.h"
+
+#include "Filter.h"
+#include "GraphicsContext.h"
+
+#include <wtf/ByteArray.h>
+
+namespace WebCore {
+
+FEComposite::FEComposite(Filter* filter, const CompositeOperationType& type, float k1, float k2, float k3, float k4)
+ : FilterEffect(filter)
+ , m_type(type)
+ , m_k1(k1)
+ , m_k2(k2)
+ , m_k3(k3)
+ , m_k4(k4)
+{
+}
+
+PassRefPtr<FEComposite> FEComposite::create(Filter* filter, const CompositeOperationType& type, float k1, float k2, float k3, float k4)
+{
+ return adoptRef(new FEComposite(filter, type, k1, k2, k3, k4));
+}
+
+CompositeOperationType FEComposite::operation() const
+{
+ return m_type;
+}
+
+void FEComposite::setOperation(CompositeOperationType type)
+{
+ m_type = type;
+}
+
+float FEComposite::k1() const
+{
+ return m_k1;
+}
+
+void FEComposite::setK1(float k1)
+{
+ m_k1 = k1;
+}
+
+float FEComposite::k2() const
+{
+ return m_k2;
+}
+
+void FEComposite::setK2(float k2)
+{
+ m_k2 = k2;
+}
+
+float FEComposite::k3() const
+{
+ return m_k3;
+}
+
+void FEComposite::setK3(float k3)
+{
+ m_k3 = k3;
+}
+
+float FEComposite::k4() const
+{
+ return m_k4;
+}
+
+void FEComposite::setK4(float k4)
+{
+ m_k4 = k4;
+}
+
+template <int b1, int b2, int b3, int b4>
+inline void computeArithmeticPixels(unsigned char* source, unsigned char* destination, int pixelArrayLength,
+ float k1, float k2, float k3, float k4)
+{
+ float scaledK4;
+ float scaledK1;
+ if (b1)
+ scaledK1 = k1 / 255.f;
+ if (b4)
+ scaledK4 = k4 * 255.f;
+
+ while (--pixelArrayLength >= 0) {
+ unsigned char i1 = *source;
+ unsigned char i2 = *destination;
+ float result = 0;
+ if (b1)
+ result += scaledK1 * i1 * i2;
+ if (b2)
+ result += k2 * i1;
+ if (b3)
+ result += k3 * i2;
+ if (b4)
+ result += scaledK4;
+
+ if (result <= 0)
+ *destination = 0;
+ else if (result >= 255)
+ *destination = 255;
+ else
+ *destination = result;
+ ++source;
+ ++destination;
+ }
+}
+
+inline void arithmetic(ByteArray* srcPixelArrayA, ByteArray* srcPixelArrayB,
+ float k1, float k2, float k3, float k4)
+{
+ int pixelArrayLength = srcPixelArrayA->length();
+ ASSERT(pixelArrayLength == static_cast<int>(srcPixelArrayB->length()));
+ unsigned char* source = srcPixelArrayA->data();
+ unsigned char* destination = srcPixelArrayB->data();
+
+ if (!k4) {
+ if (!k1) {
+ computeArithmeticPixels<0, 1, 1, 0>(source, destination, pixelArrayLength, k1, k2, k3, k4);
+ return;
+ }
+
+ computeArithmeticPixels<1, 1, 1, 0>(source, destination, pixelArrayLength, k1, k2, k3, k4);
+ return;
+ }
+
+ if (!k1) {
+ computeArithmeticPixels<0, 1, 1, 1>(source, destination, pixelArrayLength, k1, k2, k3, k4);
+ return;
+ }
+ computeArithmeticPixels<1, 1, 1, 1>(source, destination, pixelArrayLength, k1, k2, k3, k4);
+}
+
+void FEComposite::determineAbsolutePaintRect()
+{
+ switch (m_type) {
+ case FECOMPOSITE_OPERATOR_IN:
+ case FECOMPOSITE_OPERATOR_ATOP:
+ // For In and Atop the first effect just influences the result of
+ // the second effect. So just use the absolute paint rect of the second effect here.
+ setAbsolutePaintRect(inputEffect(1)->absolutePaintRect());
+ return;
+ case FECOMPOSITE_OPERATOR_ARITHMETIC:
+ // Arithmetic may influnce the compele filter primitive region. So we can't
+ // optimize the paint region here.
+ setAbsolutePaintRect(maxEffectRect());
+ return;
+ default:
+ // Take the union of both input effects.
+ FilterEffect::determineAbsolutePaintRect();
+ return;
+ }
+}
+
+void FEComposite::apply()
+{
+ if (hasResult())
+ return;
+ FilterEffect* in = inputEffect(0);
+ FilterEffect* in2 = inputEffect(1);
+ in->apply();
+ in2->apply();
+ if (!in->hasResult() || !in2->hasResult())
+ return;
+
+ if (m_type == FECOMPOSITE_OPERATOR_ARITHMETIC) {
+ ByteArray* dstPixelArray = createPremultipliedImageResult();
+ if (!dstPixelArray)
+ return;
+
+ IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
+ RefPtr<ByteArray> srcPixelArray = in->asPremultipliedImage(effectADrawingRect);
+
+ IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect());
+ in2->copyPremultipliedImage(dstPixelArray, effectBDrawingRect);
+
+ arithmetic(srcPixelArray.get(), dstPixelArray, m_k1, m_k2, m_k3, m_k4);
+ return;
+ }
+
+ ImageBuffer* resultImage = createImageBufferResult();
+ if (!resultImage)
+ return;
+ GraphicsContext* filterContext = resultImage->context();
+
+ FloatRect srcRect = FloatRect(0, 0, -1, -1);
+ switch (m_type) {
+ case FECOMPOSITE_OPERATOR_OVER:
+ filterContext->drawImageBuffer(in2->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect()));
+ filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()));
+ break;
+ case FECOMPOSITE_OPERATOR_IN:
+ filterContext->save();
+ filterContext->clipToImageBuffer(in2->asImageBuffer(), drawingRegionOfInputImage(in2->absolutePaintRect()));
+ filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()));
+ filterContext->restore();
+ break;
+ case FECOMPOSITE_OPERATOR_OUT:
+ filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()));
+ filterContext->drawImageBuffer(in2->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect()), srcRect, CompositeDestinationOut);
+ break;
+ case FECOMPOSITE_OPERATOR_ATOP:
+ filterContext->drawImageBuffer(in2->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect()));
+ filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()), srcRect, CompositeSourceAtop);
+ break;
+ case FECOMPOSITE_OPERATOR_XOR:
+ filterContext->drawImageBuffer(in2->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect()));
+ filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()), srcRect, CompositeXOR);
+ break;
+ default:
+ break;
+ }
+}
+
+void FEComposite::dump()
+{
+}
+
+static TextStream& operator<<(TextStream& ts, const CompositeOperationType& type)
+{
+ switch (type) {
+ case FECOMPOSITE_OPERATOR_UNKNOWN:
+ ts << "UNKNOWN";
+ break;
+ case FECOMPOSITE_OPERATOR_OVER:
+ ts << "OVER";
+ break;
+ case FECOMPOSITE_OPERATOR_IN:
+ ts << "IN";
+ break;
+ case FECOMPOSITE_OPERATOR_OUT:
+ ts << "OUT";
+ break;
+ case FECOMPOSITE_OPERATOR_ATOP:
+ ts << "ATOP";
+ break;
+ case FECOMPOSITE_OPERATOR_XOR:
+ ts << "XOR";
+ break;
+ case FECOMPOSITE_OPERATOR_ARITHMETIC:
+ ts << "ARITHMETIC";
+ break;
+ }
+ return ts;
+}
+
+TextStream& FEComposite::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feComposite";
+ FilterEffect::externalRepresentation(ts);
+ ts << " operation=\"" << m_type << "\"";
+ if (m_type == FECOMPOSITE_OPERATOR_ARITHMETIC)
+ ts << " k1=\"" << m_k1 << "\" k2=\"" << m_k2 << "\" k3=\"" << m_k3 << "\" k4=\"" << m_k4 << "\"";
+ ts << "]\n";
+ inputEffect(0)->externalRepresentation(ts, indent + 1);
+ inputEffect(1)->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/FEComposite.h b/Source/WebCore/platform/graphics/filters/FEComposite.h
new file mode 100644
index 0000000..b846902
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEComposite.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FEComposite_h
+#define FEComposite_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+
+#include "PlatformString.h"
+#include "Filter.h"
+
+namespace WebCore {
+
+enum CompositeOperationType {
+ FECOMPOSITE_OPERATOR_UNKNOWN = 0,
+ FECOMPOSITE_OPERATOR_OVER = 1,
+ FECOMPOSITE_OPERATOR_IN = 2,
+ FECOMPOSITE_OPERATOR_OUT = 3,
+ FECOMPOSITE_OPERATOR_ATOP = 4,
+ FECOMPOSITE_OPERATOR_XOR = 5,
+ FECOMPOSITE_OPERATOR_ARITHMETIC = 6
+};
+
+class FEComposite : public FilterEffect {
+public:
+ static PassRefPtr<FEComposite> create(Filter*, const CompositeOperationType&, float, float, float, float);
+
+ CompositeOperationType operation() const;
+ void setOperation(CompositeOperationType);
+
+ float k1() const;
+ void setK1(float);
+
+ float k2() const;
+ void setK2(float);
+
+ float k3() const;
+ void setK3(float);
+
+ float k4() const;
+ void setK4(float);
+
+ virtual void apply();
+ virtual void dump();
+
+ virtual void determineAbsolutePaintRect();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FEComposite(Filter*, const CompositeOperationType&, float, float, float, float);
+
+ CompositeOperationType m_type;
+ float m_k1;
+ float m_k2;
+ float m_k3;
+ float m_k4;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FEComposite_h
diff --git a/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp b/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp
new file mode 100644
index 0000000..b8f8aea
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp
@@ -0,0 +1,471 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2010 Zoltan Herczeg <zherczeg@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FEConvolveMatrix.h"
+
+#include "Filter.h"
+
+#include <wtf/ByteArray.h>
+
+namespace WebCore {
+
+FEConvolveMatrix::FEConvolveMatrix(Filter* filter, const IntSize& kernelSize,
+ float divisor, float bias, const IntPoint& targetOffset, EdgeModeType edgeMode,
+ const FloatPoint& kernelUnitLength, bool preserveAlpha, const Vector<float>& kernelMatrix)
+ : FilterEffect(filter)
+ , m_kernelSize(kernelSize)
+ , m_divisor(divisor)
+ , m_bias(bias)
+ , m_targetOffset(targetOffset)
+ , m_edgeMode(edgeMode)
+ , m_kernelUnitLength(kernelUnitLength)
+ , m_preserveAlpha(preserveAlpha)
+ , m_kernelMatrix(kernelMatrix)
+{
+}
+
+PassRefPtr<FEConvolveMatrix> FEConvolveMatrix::create(Filter* filter, const IntSize& kernelSize,
+ float divisor, float bias, const IntPoint& targetOffset, EdgeModeType edgeMode,
+ const FloatPoint& kernelUnitLength, bool preserveAlpha, const Vector<float>& kernelMatrix)
+{
+ return adoptRef(new FEConvolveMatrix(filter, kernelSize, divisor, bias, targetOffset, edgeMode, kernelUnitLength,
+ preserveAlpha, kernelMatrix));
+}
+
+
+IntSize FEConvolveMatrix::kernelSize() const
+{
+ return m_kernelSize;
+}
+
+void FEConvolveMatrix::setKernelSize(IntSize kernelSize)
+{
+ m_kernelSize = kernelSize;
+}
+
+const Vector<float>& FEConvolveMatrix::kernel() const
+{
+ return m_kernelMatrix;
+}
+
+void FEConvolveMatrix::setKernel(const Vector<float>& kernel)
+{
+ m_kernelMatrix = kernel;
+}
+
+float FEConvolveMatrix::divisor() const
+{
+ return m_divisor;
+}
+
+void FEConvolveMatrix::setDivisor(float divisor)
+{
+ m_divisor = divisor;
+}
+
+float FEConvolveMatrix::bias() const
+{
+ return m_bias;
+}
+
+void FEConvolveMatrix::setBias(float bias)
+{
+ m_bias = bias;
+}
+
+IntPoint FEConvolveMatrix::targetOffset() const
+{
+ return m_targetOffset;
+}
+
+void FEConvolveMatrix::setTargetOffset(IntPoint targetOffset)
+{
+ m_targetOffset = targetOffset;
+}
+
+EdgeModeType FEConvolveMatrix::edgeMode() const
+{
+ return m_edgeMode;
+}
+
+void FEConvolveMatrix::setEdgeMode(EdgeModeType edgeMode)
+{
+ m_edgeMode = edgeMode;
+}
+
+FloatPoint FEConvolveMatrix::kernelUnitLength() const
+{
+ return m_kernelUnitLength;
+}
+
+void FEConvolveMatrix::setKernelUnitLength(FloatPoint kernelUnitLength)
+{
+ m_kernelUnitLength = kernelUnitLength;
+}
+
+bool FEConvolveMatrix::preserveAlpha() const
+{
+ return m_preserveAlpha;
+}
+
+void FEConvolveMatrix::setPreserveAlpha(bool preserveAlpha)
+{
+ m_preserveAlpha = preserveAlpha;
+}
+
+/*
+ -----------------------------------
+ ConvolveMatrix implementation
+ -----------------------------------
+
+ The image rectangle is split in the following way:
+
+ +---------------------+
+ | A |
+ +---------------------+
+ | | | |
+ | B | C | D |
+ | | | |
+ +---------------------+
+ | E |
+ +---------------------+
+
+ Where region C contains those pixels, whose values
+ can be calculated without crossing the edge of the rectangle.
+
+ Example:
+ Image size: width: 10, height: 10
+
+ Order (kernel matrix size): width: 3, height 4
+ Target: x:1, y:3
+
+ The following figure shows the target inside the kernel matrix:
+
+ ...
+ ...
+ ...
+ .X.
+
+ The regions in this case are the following:
+ Note: (x1, y1) top-left and (x2, y2) is the bottom-right corner
+ Note: row x2 and column y2 is not part of the region
+ only those (x, y) pixels, where x1 <= x < x2 and y1 <= y < y2
+
+ Region A: x1: 0, y1: 0, x2: 10, y2: 3
+ Region B: x1: 0, y1: 3, x2: 1, y2: 10
+ Region C: x1: 1, y1: 3, x2: 9, y2: 10
+ Region D: x1: 9, y1: 3, x2: 10, y2: 10
+ Region E: x1: 0, y1: 10, x2: 10, y2: 10 (empty region)
+
+ Since region C (often) contains most of the pixels, we implemented
+ a fast algoritm to calculate these values, called fastSetInteriorPixels.
+ For other regions, fastSetOuterPixels is used, which calls getPixelValue,
+ to handle pixels outside of the image. In a rare situations, when
+ kernel matrix is bigger than the image, all pixels are calculated by this
+ function.
+
+ Although these two functions have lot in common, I decided not to make
+ common a template for them, since there are key differences as well,
+ and would make it really hard to understand.
+*/
+
+static ALWAYS_INLINE unsigned char clampRGBAValue(float channel, unsigned char max = 255)
+{
+ if (channel <= 0)
+ return 0;
+ if (channel >= max)
+ return max;
+ return channel;
+}
+
+template<bool preserveAlphaValues>
+ALWAYS_INLINE void setDestinationPixels(ByteArray* image, int& pixel, float* totals, float divisor, float bias, ByteArray* src)
+{
+ unsigned char maxAlpha = preserveAlphaValues ? 255 : clampRGBAValue(totals[3] / divisor + bias);
+ for (int i = 0; i < 3; ++i)
+ image->set(pixel++, clampRGBAValue(totals[i] / divisor + bias, maxAlpha));
+
+ if (preserveAlphaValues) {
+ image->set(pixel, src->get(pixel));
+ ++pixel;
+ } else
+ image->set(pixel++, maxAlpha);
+}
+
+// Only for region C
+template<bool preserveAlphaValues>
+ALWAYS_INLINE void FEConvolveMatrix::fastSetInteriorPixels(PaintingData& paintingData, int clipRight, int clipBottom)
+{
+ // edge mode does not affect these pixels
+ int pixel = (m_targetOffset.y() * paintingData.width + m_targetOffset.x()) * 4;
+ int startKernelPixel = 0;
+ int kernelIncrease = clipRight * 4;
+ int xIncrease = (m_kernelSize.width() - 1) * 4;
+ // Contains the sum of rgb(a) components
+ float totals[3 + (preserveAlphaValues ? 0 : 1)];
+
+ // m_divisor cannot be 0, SVGFEConvolveMatrixElement ensures this
+ ASSERT(m_divisor);
+
+ for (int y = clipBottom + 1; y > 0; --y) {
+ for (int x = clipRight + 1; x > 0; --x) {
+ int kernelValue = m_kernelMatrix.size() - 1;
+ int kernelPixel = startKernelPixel;
+ int width = m_kernelSize.width();
+
+ totals[0] = 0;
+ totals[1] = 0;
+ totals[2] = 0;
+ if (!preserveAlphaValues)
+ totals[3] = 0;
+
+ while (kernelValue >= 0) {
+ totals[0] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->get(kernelPixel++));
+ totals[1] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->get(kernelPixel++));
+ totals[2] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->get(kernelPixel++));
+ if (!preserveAlphaValues)
+ totals[3] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->get(kernelPixel));
+ ++kernelPixel;
+ --kernelValue;
+ if (!--width) {
+ kernelPixel += kernelIncrease;
+ width = m_kernelSize.width();
+ }
+ }
+
+ setDestinationPixels<preserveAlphaValues>(paintingData.dstPixelArray, pixel, totals, m_divisor, paintingData.bias, paintingData.srcPixelArray);
+ startKernelPixel += 4;
+ }
+ pixel += xIncrease;
+ startKernelPixel += xIncrease;
+ }
+}
+
+ALWAYS_INLINE int FEConvolveMatrix::getPixelValue(PaintingData& paintingData, int x, int y)
+{
+ if (x >= 0 && x < paintingData.width && x >= 0 && y < paintingData.height)
+ return (y * paintingData.width + x) << 2;
+
+ switch (m_edgeMode) {
+ default: // EDGEMODE_NONE
+ return -1;
+ case EDGEMODE_DUPLICATE:
+ if (x < 0)
+ x = 0;
+ else if (x >= paintingData.width)
+ x = paintingData.width - 1;
+ if (y < 0)
+ y = 0;
+ else if (y >= paintingData.height)
+ y = paintingData.height - 1;
+ return (y * paintingData.width + x) << 2;
+ case EDGEMODE_WRAP:
+ while (x < 0)
+ x += paintingData.width;
+ x %= paintingData.width;
+ while (y < 0)
+ y += paintingData.height;
+ y %= paintingData.height;
+ return (y * paintingData.width + x) << 2;
+ }
+}
+
+// For other regions than C
+template<bool preserveAlphaValues>
+void FEConvolveMatrix::fastSetOuterPixels(PaintingData& paintingData, int x1, int y1, int x2, int y2)
+{
+ int pixel = (y1 * paintingData.width + x1) * 4;
+ int height = y2 - y1;
+ int width = x2 - x1;
+ int beginKernelPixelX = x1 - m_targetOffset.x();
+ int startKernelPixelX = beginKernelPixelX;
+ int startKernelPixelY = y1 - m_targetOffset.y();
+ int xIncrease = (paintingData.width - width) * 4;
+ // Contains the sum of rgb(a) components
+ float totals[3 + (preserveAlphaValues ? 0 : 1)];
+
+ // m_divisor cannot be 0, SVGFEConvolveMatrixElement ensures this
+ ASSERT(m_divisor);
+
+ for (int y = height; y > 0; --y) {
+ for (int x = width; x > 0; --x) {
+ int kernelValue = m_kernelMatrix.size() - 1;
+ int kernelPixelX = startKernelPixelX;
+ int kernelPixelY = startKernelPixelY;
+ int width = m_kernelSize.width();
+
+ totals[0] = 0;
+ totals[1] = 0;
+ totals[2] = 0;
+ if (!preserveAlphaValues)
+ totals[3] = 0;
+
+ while (kernelValue >= 0) {
+ int pixelIndex = getPixelValue(paintingData, kernelPixelX, kernelPixelY);
+ if (pixelIndex >= 0) {
+ totals[0] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->get(pixelIndex));
+ totals[1] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->get(pixelIndex + 1));
+ totals[2] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->get(pixelIndex + 2));
+ }
+ if (!preserveAlphaValues && pixelIndex >= 0)
+ totals[3] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->get(pixelIndex + 3));
+ ++kernelPixelX;
+ --kernelValue;
+ if (!--width) {
+ kernelPixelX = startKernelPixelX;
+ ++kernelPixelY;
+ width = m_kernelSize.width();
+ }
+ }
+
+ setDestinationPixels<preserveAlphaValues>(paintingData.dstPixelArray, pixel, totals, m_divisor, paintingData.bias, paintingData.srcPixelArray);
+ ++startKernelPixelX;
+ }
+ pixel += xIncrease;
+ startKernelPixelX = beginKernelPixelX;
+ ++startKernelPixelY;
+ }
+}
+
+ALWAYS_INLINE void FEConvolveMatrix::setInteriorPixels(PaintingData& paintingData, int clipRight, int clipBottom)
+{
+ // Must be implemented here, since it refers another ALWAYS_INLINE
+ // function, which defined in this C++ source file as well
+ if (m_preserveAlpha)
+ fastSetInteriorPixels<true>(paintingData, clipRight, clipBottom);
+ else
+ fastSetInteriorPixels<false>(paintingData, clipRight, clipBottom);
+}
+
+ALWAYS_INLINE void FEConvolveMatrix::setOuterPixels(PaintingData& paintingData, int x1, int y1, int x2, int y2)
+{
+ // Although this function can be moved to the header, it is implemented here
+ // because setInteriorPixels is also implemented here
+ if (m_preserveAlpha)
+ fastSetOuterPixels<true>(paintingData, x1, y1, x2, y2);
+ else
+ fastSetOuterPixels<false>(paintingData, x1, y1, x2, y2);
+}
+
+void FEConvolveMatrix::apply()
+{
+ if (hasResult())
+ return;
+ FilterEffect* in = inputEffect(0);
+ in->apply();
+ if (!in->hasResult())
+ return;
+
+ ByteArray* resultImage;
+ if (m_preserveAlpha)
+ resultImage = createUnmultipliedImageResult();
+ else
+ resultImage = createPremultipliedImageResult();
+ if (!resultImage)
+ return;
+
+ IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
+
+ RefPtr<ByteArray> srcPixelArray;
+ if (m_preserveAlpha)
+ srcPixelArray = in->asUnmultipliedImage(effectDrawingRect);
+ else
+ srcPixelArray = in->asPremultipliedImage(effectDrawingRect);
+
+ IntSize paintSize = absolutePaintRect().size();
+ PaintingData paintingData;
+ paintingData.srcPixelArray = srcPixelArray.get();
+ paintingData.dstPixelArray = resultImage;
+ paintingData.width = paintSize.width();
+ paintingData.height = paintSize.height();
+ paintingData.bias = m_bias * 255;
+
+ // Drawing fully covered pixels
+ int clipRight = paintSize.width() - m_kernelSize.width();
+ int clipBottom = paintSize.height() - m_kernelSize.height();
+
+ if (clipRight >= 0 && clipBottom >= 0) {
+ setInteriorPixels(paintingData, clipRight, clipBottom);
+
+ clipRight += m_targetOffset.x() + 1;
+ clipBottom += m_targetOffset.y() + 1;
+ if (m_targetOffset.y() > 0)
+ setOuterPixels(paintingData, 0, 0, paintSize.width(), m_targetOffset.y());
+ if (clipBottom < paintSize.height())
+ setOuterPixels(paintingData, 0, clipBottom, paintSize.width(), paintSize.height());
+ if (m_targetOffset.x() > 0)
+ setOuterPixels(paintingData, 0, m_targetOffset.y(), m_targetOffset.x(), clipBottom);
+ if (clipRight < paintSize.width())
+ setOuterPixels(paintingData, clipRight, m_targetOffset.y(), paintSize.width(), clipBottom);
+ } else {
+ // Rare situation, not optimizied for speed
+ setOuterPixels(paintingData, 0, 0, paintSize.width(), paintSize.height());
+ }
+}
+
+void FEConvolveMatrix::dump()
+{
+}
+
+static TextStream& operator<<(TextStream& ts, const EdgeModeType& type)
+{
+ switch (type) {
+ case EDGEMODE_UNKNOWN:
+ ts << "UNKNOWN";
+ break;
+ case EDGEMODE_DUPLICATE:
+ ts << "DUPLICATE";
+ break;
+ case EDGEMODE_WRAP:
+ ts << "WRAP";
+ break;
+ case EDGEMODE_NONE:
+ ts << "NONE";
+ break;
+ }
+ return ts;
+}
+
+TextStream& FEConvolveMatrix::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feConvolveMatrix";
+ FilterEffect::externalRepresentation(ts);
+ ts << " order=\"" << m_kernelSize << "\" "
+ << "kernelMatrix=\"" << m_kernelMatrix << "\" "
+ << "divisor=\"" << m_divisor << "\" "
+ << "bias=\"" << m_bias << "\" "
+ << "target=\"" << m_targetOffset << "\" "
+ << "edgeMode=\"" << m_edgeMode << "\" "
+ << "kernelUnitLength=\"" << m_kernelUnitLength << "\" "
+ << "preserveAlpha=\"" << m_preserveAlpha << "\"]\n";
+ inputEffect(0)->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
+}; // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h b/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h
new file mode 100644
index 0000000..05d1199
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2010 Zoltan Herczeg <zherczeg@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FEConvolveMatrix_h
+#define FEConvolveMatrix_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+#include "FloatPoint.h"
+#include "FloatSize.h"
+#include "Filter.h"
+#include <wtf/AlwaysInline.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+enum EdgeModeType {
+ EDGEMODE_UNKNOWN = 0,
+ EDGEMODE_DUPLICATE = 1,
+ EDGEMODE_WRAP = 2,
+ EDGEMODE_NONE = 3
+};
+
+class CanvasPixelArray;
+
+class FEConvolveMatrix : public FilterEffect {
+public:
+ static PassRefPtr<FEConvolveMatrix> create(Filter*, const IntSize&,
+ float, float, const IntPoint&, EdgeModeType, const FloatPoint&,
+ bool, const Vector<float>&);
+
+ IntSize kernelSize() const;
+ void setKernelSize(IntSize);
+
+ const Vector<float>& kernel() const;
+ void setKernel(const Vector<float>&);
+
+ float divisor() const;
+ void setDivisor(float);
+
+ float bias() const;
+ void setBias(float);
+
+ IntPoint targetOffset() const;
+ void setTargetOffset(IntPoint);
+
+ EdgeModeType edgeMode() const;
+ void setEdgeMode(EdgeModeType);
+
+ FloatPoint kernelUnitLength() const;
+ void setKernelUnitLength(FloatPoint);
+
+ bool preserveAlpha() const;
+ void setPreserveAlpha(bool);
+
+ virtual void apply();
+ virtual void dump();
+
+ virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(maxEffectRect()); }
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FEConvolveMatrix(Filter*, const IntSize&, float, float,
+ const IntPoint&, EdgeModeType, const FloatPoint&, bool, const Vector<float>&);
+
+ struct PaintingData {
+ ByteArray* srcPixelArray;
+ ByteArray* dstPixelArray;
+ int width;
+ int height;
+ float bias;
+ };
+
+ template<bool preserveAlphaValues>
+ ALWAYS_INLINE void fastSetInteriorPixels(PaintingData&, int clipRight, int clipBottom);
+
+ ALWAYS_INLINE int getPixelValue(PaintingData&, int x, int y);
+
+ template<bool preserveAlphaValues>
+ void fastSetOuterPixels(PaintingData&, int x1, int y1, int x2, int y2);
+
+ // Wrapper functions
+ ALWAYS_INLINE void setInteriorPixels(PaintingData& paintingData, int clipRight, int clipBottom);
+ ALWAYS_INLINE void setOuterPixels(PaintingData& paintingData, int x1, int y1, int x2, int y2);
+
+ IntSize m_kernelSize;
+ float m_divisor;
+ float m_bias;
+ IntPoint m_targetOffset;
+ EdgeModeType m_edgeMode;
+ FloatPoint m_kernelUnitLength;
+ bool m_preserveAlpha;
+ Vector<float> m_kernelMatrix;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FEConvolveMatrix_h
diff --git a/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp b/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp
new file mode 100644
index 0000000..14d57f4
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FEDiffuseLighting.h"
+
+#include "LightSource.h"
+
+namespace WebCore {
+
+FEDiffuseLighting::FEDiffuseLighting(Filter* filter, const Color& lightingColor, float surfaceScale,
+ float diffuseConstant, float kernelUnitLengthX, float kernelUnitLengthY, PassRefPtr<LightSource> lightSource)
+ : FELighting(filter, DiffuseLighting, lightingColor, surfaceScale, diffuseConstant, 0, 0, kernelUnitLengthX, kernelUnitLengthY, lightSource)
+{
+}
+
+PassRefPtr<FEDiffuseLighting> FEDiffuseLighting::create(Filter* filter, const Color& lightingColor,
+ float surfaceScale, float diffuseConstant, float kernelUnitLengthX,
+ float kernelUnitLengthY, PassRefPtr<LightSource> lightSource)
+{
+ return adoptRef(new FEDiffuseLighting(filter, lightingColor, surfaceScale, diffuseConstant, kernelUnitLengthX, kernelUnitLengthY, lightSource));
+}
+
+FEDiffuseLighting::~FEDiffuseLighting()
+{
+}
+
+Color FEDiffuseLighting::lightingColor() const
+{
+ return m_lightingColor;
+}
+
+void FEDiffuseLighting::setLightingColor(const Color& lightingColor)
+{
+ m_lightingColor = lightingColor;
+}
+
+float FEDiffuseLighting::surfaceScale() const
+{
+ return m_surfaceScale;
+}
+
+void FEDiffuseLighting::setSurfaceScale(float surfaceScale)
+{
+ m_surfaceScale = surfaceScale;
+}
+
+float FEDiffuseLighting::diffuseConstant() const
+{
+ return m_diffuseConstant;
+}
+
+void FEDiffuseLighting::setDiffuseConstant(float diffuseConstant)
+{
+ m_diffuseConstant = diffuseConstant;
+}
+
+float FEDiffuseLighting::kernelUnitLengthX() const
+{
+ return m_kernelUnitLengthX;
+}
+
+void FEDiffuseLighting::setKernelUnitLengthX(float kernelUnitLengthX)
+{
+ m_kernelUnitLengthX = kernelUnitLengthX;
+}
+
+float FEDiffuseLighting::kernelUnitLengthY() const
+{
+ return m_kernelUnitLengthY;
+}
+
+void FEDiffuseLighting::setKernelUnitLengthY(float kernelUnitLengthY)
+{
+ m_kernelUnitLengthY = kernelUnitLengthY;
+}
+
+const LightSource* FEDiffuseLighting::lightSource() const
+{
+ return m_lightSource.get();
+}
+
+void FEDiffuseLighting::setLightSource(PassRefPtr<LightSource> lightSource)
+{
+ m_lightSource = lightSource;
+}
+
+void FEDiffuseLighting::dump()
+{
+}
+
+TextStream& FEDiffuseLighting::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feDiffuseLighting";
+ FilterEffect::externalRepresentation(ts);
+ ts << " surfaceScale=\"" << m_surfaceScale << "\" "
+ << "diffuseConstant=\"" << m_diffuseConstant << "\" "
+ << "kernelUnitLength=\"" << m_kernelUnitLengthX << ", " << m_kernelUnitLengthY << "\"]\n";
+ inputEffect(0)->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.h b/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.h
new file mode 100644
index 0000000..b58b47a
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FEDiffuseLighting_h
+#define FEDiffuseLighting_h
+
+#if ENABLE(FILTERS)
+#include "FELighting.h"
+
+namespace WebCore {
+
+class LightSource;
+
+class FEDiffuseLighting : public FELighting {
+public:
+ static PassRefPtr<FEDiffuseLighting> create(Filter*, const Color&, float, float,
+ float, float, PassRefPtr<LightSource>);
+ virtual ~FEDiffuseLighting();
+
+ Color lightingColor() const;
+ void setLightingColor(const Color&);
+
+ float surfaceScale() const;
+ void setSurfaceScale(float);
+
+ float diffuseConstant() const;
+ void setDiffuseConstant(float);
+
+ float kernelUnitLengthX() const;
+ void setKernelUnitLengthX(float);
+
+ float kernelUnitLengthY() const;
+ void setKernelUnitLengthY(float);
+
+ const LightSource* lightSource() const;
+ void setLightSource(PassRefPtr<LightSource>);
+
+ virtual void dump();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FEDiffuseLighting(Filter*, const Color&, float, float, float, float, PassRefPtr<LightSource>);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FEDiffuseLighting_h
diff --git a/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp b/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp
new file mode 100644
index 0000000..b5151bf
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FEDisplacementMap.h"
+
+#include "Filter.h"
+#include "GraphicsContext.h"
+
+#include <wtf/ByteArray.h>
+
+namespace WebCore {
+
+FEDisplacementMap::FEDisplacementMap(Filter* filter, ChannelSelectorType xChannelSelector, ChannelSelectorType yChannelSelector, float scale)
+ : FilterEffect(filter)
+ , m_xChannelSelector(xChannelSelector)
+ , m_yChannelSelector(yChannelSelector)
+ , m_scale(scale)
+{
+}
+
+PassRefPtr<FEDisplacementMap> FEDisplacementMap::create(Filter* filter, ChannelSelectorType xChannelSelector,
+ ChannelSelectorType yChannelSelector, float scale)
+{
+ return adoptRef(new FEDisplacementMap(filter, xChannelSelector, yChannelSelector, scale));
+}
+
+ChannelSelectorType FEDisplacementMap::xChannelSelector() const
+{
+ return m_xChannelSelector;
+}
+
+void FEDisplacementMap::setXChannelSelector(const ChannelSelectorType xChannelSelector)
+{
+ m_xChannelSelector = xChannelSelector;
+}
+
+ChannelSelectorType FEDisplacementMap::yChannelSelector() const
+{
+ return m_yChannelSelector;
+}
+
+void FEDisplacementMap::setYChannelSelector(const ChannelSelectorType yChannelSelector)
+{
+ m_yChannelSelector = yChannelSelector;
+}
+
+float FEDisplacementMap::scale() const
+{
+ return m_scale;
+}
+
+void FEDisplacementMap::setScale(float scale)
+{
+ m_scale = scale;
+}
+
+void FEDisplacementMap::apply()
+{
+ if (hasResult())
+ return;
+ FilterEffect* in = inputEffect(0);
+ FilterEffect* in2 = inputEffect(1);
+ in->apply();
+ in2->apply();
+ if (!in->hasResult() || !in2->hasResult())
+ return;
+
+ if (m_xChannelSelector == CHANNEL_UNKNOWN || m_yChannelSelector == CHANNEL_UNKNOWN)
+ return;
+
+ ByteArray* dstPixelArray = createPremultipliedImageResult();
+ if (!dstPixelArray)
+ return;
+
+ IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
+ RefPtr<ByteArray> srcPixelArrayA = in->asPremultipliedImage(effectADrawingRect);
+
+ IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect());
+ RefPtr<ByteArray> srcPixelArrayB = in2->asUnmultipliedImage(effectBDrawingRect);
+
+ ASSERT(srcPixelArrayA->length() == srcPixelArrayB->length());
+
+ Filter* filter = this->filter();
+ IntSize paintSize = absolutePaintRect().size();
+ float scaleX = filter->applyHorizontalScale(m_scale / 255);
+ float scaleY = filter->applyVerticalScale(m_scale / 255);
+ float scaleAdjustmentX = filter->applyHorizontalScale(0.5f - 0.5f * m_scale);
+ float scaleAdjustmentY = filter->applyVerticalScale(0.5f - 0.5f * m_scale);
+ int stride = paintSize.width() * 4;
+ for (int y = 0; y < paintSize.height(); ++y) {
+ int line = y * stride;
+ for (int x = 0; x < paintSize.width(); ++x) {
+ int dstIndex = line + x * 4;
+ int srcX = x + static_cast<int>(scaleX * srcPixelArrayB->get(dstIndex + m_xChannelSelector - 1) + scaleAdjustmentX);
+ int srcY = y + static_cast<int>(scaleY * srcPixelArrayB->get(dstIndex + m_yChannelSelector - 1) + scaleAdjustmentY);
+ for (unsigned channel = 0; channel < 4; ++channel) {
+ if (srcX < 0 || srcX >= paintSize.width() || srcY < 0 || srcY >= paintSize.height())
+ dstPixelArray->set(dstIndex + channel, static_cast<unsigned char>(0));
+ else {
+ unsigned char pixelValue = srcPixelArrayA->get(srcY * stride + srcX * 4 + channel);
+ dstPixelArray->set(dstIndex + channel, pixelValue);
+ }
+ }
+ }
+ }
+}
+
+void FEDisplacementMap::dump()
+{
+}
+
+static TextStream& operator<<(TextStream& ts, const ChannelSelectorType& type)
+{
+ switch (type) {
+ case CHANNEL_UNKNOWN:
+ ts << "UNKNOWN";
+ break;
+ case CHANNEL_R:
+ ts << "RED";
+ break;
+ case CHANNEL_G:
+ ts << "GREEN";
+ break;
+ case CHANNEL_B:
+ ts << "BLUE";
+ break;
+ case CHANNEL_A:
+ ts << "ALPHA";
+ break;
+ }
+ return ts;
+}
+
+TextStream& FEDisplacementMap::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feDisplacementMap";
+ FilterEffect::externalRepresentation(ts);
+ ts << " scale=\"" << m_scale << "\" "
+ << "xChannelSelector=\"" << m_xChannelSelector << "\" "
+ << "yChannelSelector=\"" << m_yChannelSelector << "\"]\n";
+ inputEffect(0)->externalRepresentation(ts, indent + 1);
+ inputEffect(1)->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h b/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h
new file mode 100644
index 0000000..ffb8f0e
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FEDisplacementMap_h
+#define FEDisplacementMap_h
+
+#if ENABLE(FILTERS)
+#include "PlatformString.h"
+#include "FilterEffect.h"
+#include "Filter.h"
+
+namespace WebCore {
+
+enum ChannelSelectorType {
+ CHANNEL_UNKNOWN = 0,
+ CHANNEL_R = 1,
+ CHANNEL_G = 2,
+ CHANNEL_B = 3,
+ CHANNEL_A = 4
+};
+
+class FEDisplacementMap : public FilterEffect {
+public:
+ static PassRefPtr<FEDisplacementMap> create(Filter*, ChannelSelectorType xChannelSelector, ChannelSelectorType yChannelSelector, float);
+
+ ChannelSelectorType xChannelSelector() const;
+ void setXChannelSelector(const ChannelSelectorType);
+
+ ChannelSelectorType yChannelSelector() const;
+ void setYChannelSelector(const ChannelSelectorType);
+
+ float scale() const;
+ void setScale(float scale);
+
+ virtual void apply();
+ virtual void dump();
+
+ virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(maxEffectRect()); }
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FEDisplacementMap(Filter*, ChannelSelectorType xChannelSelector, ChannelSelectorType yChannelSelector, float);
+
+ ChannelSelectorType m_xChannelSelector;
+ ChannelSelectorType m_yChannelSelector;
+ float m_scale;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FEDisplacementMap_h
diff --git a/Source/WebCore/platform/graphics/filters/FEFlood.cpp b/Source/WebCore/platform/graphics/filters/FEFlood.cpp
new file mode 100644
index 0000000..8bfdef8
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEFlood.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FEFlood.h"
+
+#include "Filter.h"
+#include "GraphicsContext.h"
+
+namespace WebCore {
+
+FEFlood::FEFlood(Filter* filter, const Color& floodColor, float floodOpacity)
+ : FilterEffect(filter)
+ , m_floodColor(floodColor)
+ , m_floodOpacity(floodOpacity)
+{
+}
+
+PassRefPtr<FEFlood> FEFlood::create(Filter* filter, const Color& floodColor, float floodOpacity)
+{
+ return adoptRef(new FEFlood(filter, floodColor, floodOpacity));
+}
+
+Color FEFlood::floodColor() const
+{
+ return m_floodColor;
+}
+
+void FEFlood::setFloodColor(const Color& color)
+{
+ m_floodColor = color;
+}
+
+float FEFlood::floodOpacity() const
+{
+ return m_floodOpacity;
+}
+
+void FEFlood::setFloodOpacity(float floodOpacity)
+{
+ m_floodOpacity = floodOpacity;
+}
+
+void FEFlood::apply()
+{
+ if (hasResult())
+ return;
+ ImageBuffer* resultImage = createImageBufferResult();
+ if (!resultImage)
+ return;
+
+ Color color = colorWithOverrideAlpha(floodColor().rgb(), floodOpacity());
+ resultImage->context()->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()), color, ColorSpaceDeviceRGB);
+}
+
+void FEFlood::dump()
+{
+}
+
+TextStream& FEFlood::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feFlood";
+ FilterEffect::externalRepresentation(ts);
+ ts << " flood-color=\"" << floodColor().name() << "\" "
+ << "flood-opacity=\"" << floodOpacity() << "\"]\n";
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/FEFlood.h b/Source/WebCore/platform/graphics/filters/FEFlood.h
new file mode 100644
index 0000000..2e8824f
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEFlood.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FEFlood_h
+#define FEFlood_h
+
+#if ENABLE(FILTERS)
+#include "Color.h"
+#include "Filter.h"
+#include "FilterEffect.h"
+
+namespace WebCore {
+
+class FEFlood : public FilterEffect {
+public:
+ static PassRefPtr<FEFlood> create(Filter* filter, const Color&, float);
+
+ Color floodColor() const;
+ void setFloodColor(const Color &);
+
+ float floodOpacity() const;
+ void setFloodOpacity(float);
+
+ virtual void apply();
+ virtual void dump();
+
+ virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(maxEffectRect()); }
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FEFlood(Filter*, const Color&, float);
+
+ Color m_floodColor;
+ float m_floodOpacity;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FEFlood_h
diff --git a/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp b/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
new file mode 100644
index 0000000..37b5992
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2010 Igalia, S.L.
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FEGaussianBlur.h"
+
+#include "Filter.h"
+#include "GraphicsContext.h"
+
+#include <wtf/ByteArray.h>
+#include <wtf/MathExtras.h>
+
+using std::max;
+
+static const float gGaussianKernelFactor = 3 / 4.f * sqrtf(2 * piFloat);
+static const unsigned gMaxKernelSize = 1000;
+
+namespace WebCore {
+
+FEGaussianBlur::FEGaussianBlur(Filter* filter, float x, float y)
+ : FilterEffect(filter)
+ , m_stdX(x)
+ , m_stdY(y)
+{
+}
+
+PassRefPtr<FEGaussianBlur> FEGaussianBlur::create(Filter* filter, float x, float y)
+{
+ return adoptRef(new FEGaussianBlur(filter, x, y));
+}
+
+float FEGaussianBlur::stdDeviationX() const
+{
+ return m_stdX;
+}
+
+void FEGaussianBlur::setStdDeviationX(float x)
+{
+ m_stdX = x;
+}
+
+float FEGaussianBlur::stdDeviationY() const
+{
+ return m_stdY;
+}
+
+void FEGaussianBlur::setStdDeviationY(float y)
+{
+ m_stdY = y;
+}
+
+inline void boxBlur(ByteArray* srcPixelArray, ByteArray* dstPixelArray,
+ unsigned dx, int dxLeft, int dxRight, int stride, int strideLine, int effectWidth, int effectHeight, bool alphaImage)
+{
+ for (int y = 0; y < effectHeight; ++y) {
+ int line = y * strideLine;
+ for (int channel = 3; channel >= 0; --channel) {
+ int sum = 0;
+ // Fill the kernel
+ int maxKernelSize = std::min(dxRight, effectWidth);
+ for (int i = 0; i < maxKernelSize; ++i)
+ sum += srcPixelArray->get(line + i * stride + channel);
+
+ // Blurring
+ for (int x = 0; x < effectWidth; ++x) {
+ int pixelByteOffset = line + x * stride + channel;
+ dstPixelArray->set(pixelByteOffset, static_cast<unsigned char>(sum / dx));
+ if (x >= dxLeft)
+ sum -= srcPixelArray->get(pixelByteOffset - dxLeft * stride);
+ if (x + dxRight < effectWidth)
+ sum += srcPixelArray->get(pixelByteOffset + dxRight * stride);
+ }
+ if (alphaImage) // Source image is black, it just has different alpha values
+ break;
+ }
+ }
+}
+
+inline void kernelPosition(int boxBlur, unsigned& std, int& dLeft, int& dRight)
+{
+ // check http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement for details
+ switch (boxBlur) {
+ case 0:
+ if (!(std % 2)) {
+ dLeft = std / 2 - 1;
+ dRight = std - dLeft;
+ } else {
+ dLeft = std / 2;
+ dRight = std - dLeft;
+ }
+ break;
+ case 1:
+ if (!(std % 2)) {
+ dLeft++;
+ dRight--;
+ }
+ break;
+ case 2:
+ if (!(std % 2)) {
+ dRight++;
+ std++;
+ }
+ break;
+ }
+}
+
+inline void calculateKernelSize(Filter* filter, unsigned& kernelSizeX, unsigned& kernelSizeY, float stdX, float stdY)
+{
+ stdX = filter->applyHorizontalScale(stdX);
+ stdY = filter->applyVerticalScale(stdY);
+
+ kernelSizeX = 0;
+ if (stdX)
+ kernelSizeX = max<unsigned>(2, static_cast<unsigned>(floorf(stdX * gGaussianKernelFactor + 0.5f)));
+ kernelSizeY = 0;
+ if (stdY)
+ kernelSizeY = max<unsigned>(2, static_cast<unsigned>(floorf(stdY * gGaussianKernelFactor + 0.5f)));
+
+ // Limit the kernel size to 1000. A bigger radius won't make a big difference for the result image but
+ // inflates the absolute paint rect to much. This is compatible with Firefox' behavior.
+ if (kernelSizeX > gMaxKernelSize)
+ kernelSizeX = gMaxKernelSize;
+ if (kernelSizeY > gMaxKernelSize)
+ kernelSizeY = gMaxKernelSize;
+}
+
+void FEGaussianBlur::determineAbsolutePaintRect()
+{
+ FloatRect absolutePaintRect = inputEffect(0)->absolutePaintRect();
+ absolutePaintRect.intersect(maxEffectRect());
+
+ unsigned kernelSizeX = 0;
+ unsigned kernelSizeY = 0;
+ calculateKernelSize(filter(), kernelSizeX, kernelSizeY, m_stdX, m_stdY);
+
+ // We take the half kernel size and multiply it with three, because we run box blur three times.
+ absolutePaintRect.inflateX(3 * kernelSizeX * 0.5f);
+ absolutePaintRect.inflateY(3 * kernelSizeY * 0.5f);
+ setAbsolutePaintRect(enclosingIntRect(absolutePaintRect));
+}
+
+void FEGaussianBlur::apply()
+{
+ if (hasResult())
+ return;
+ FilterEffect* in = inputEffect(0);
+ in->apply();
+ if (!in->hasResult())
+ return;
+
+ ByteArray* srcPixelArray = createPremultipliedImageResult();
+ if (!srcPixelArray)
+ return;
+
+ setIsAlphaImage(in->isAlphaImage());
+
+ IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
+ in->copyPremultipliedImage(srcPixelArray, effectDrawingRect);
+
+ if (!m_stdX && !m_stdY)
+ return;
+
+ unsigned kernelSizeX = 0;
+ unsigned kernelSizeY = 0;
+ calculateKernelSize(filter(), kernelSizeX, kernelSizeY, m_stdX, m_stdY);
+
+ IntSize paintSize = absolutePaintRect().size();
+ RefPtr<ByteArray> tmpImageData = ByteArray::create(paintSize.width() * paintSize.height() * 4);
+ ByteArray* tmpPixelArray = tmpImageData.get();
+
+ int stride = 4 * paintSize.width();
+ int dxLeft = 0;
+ int dxRight = 0;
+ int dyLeft = 0;
+ int dyRight = 0;
+ for (int i = 0; i < 3; ++i) {
+ if (kernelSizeX) {
+ kernelPosition(i, kernelSizeX, dxLeft, dxRight);
+ boxBlur(srcPixelArray, tmpPixelArray, kernelSizeX, dxLeft, dxRight, 4, stride, paintSize.width(), paintSize.height(), isAlphaImage());
+ } else {
+ ByteArray* auxPixelArray = tmpPixelArray;
+ tmpPixelArray = srcPixelArray;
+ srcPixelArray = auxPixelArray;
+ }
+
+ if (kernelSizeY) {
+ kernelPosition(i, kernelSizeY, dyLeft, dyRight);
+ boxBlur(tmpPixelArray, srcPixelArray, kernelSizeY, dyLeft, dyRight, stride, 4, paintSize.height(), paintSize.width(), isAlphaImage());
+ } else {
+ ByteArray* auxPixelArray = tmpPixelArray;
+ tmpPixelArray = srcPixelArray;
+ srcPixelArray = auxPixelArray;
+ }
+ }
+}
+
+void FEGaussianBlur::dump()
+{
+}
+
+TextStream& FEGaussianBlur::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feGaussianBlur";
+ FilterEffect::externalRepresentation(ts);
+ ts << " stdDeviation=\"" << m_stdX << ", " << m_stdY << "\"]\n";
+ inputEffect(0)->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
+float FEGaussianBlur::calculateStdDeviation(float radius)
+{
+ // Blur radius represents 2/3 times the kernel size, the dest pixel is half of the radius applied 3 times
+ return max((radius * 2 / 3.f - 0.5f) / gGaussianKernelFactor, 0.f);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h b/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h
new file mode 100644
index 0000000..79f9a45
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEGaussianBlur.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FEGaussianBlur_h
+#define FEGaussianBlur_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+#include "Filter.h"
+
+namespace WebCore {
+
+class FEGaussianBlur : public FilterEffect {
+public:
+ static PassRefPtr<FEGaussianBlur> create(Filter*, float, float);
+
+ float stdDeviationX() const;
+ void setStdDeviationX(float);
+
+ float stdDeviationY() const;
+ void setStdDeviationY(float);
+
+ static float calculateStdDeviation(float);
+
+ virtual void apply();
+ virtual void dump();
+
+ virtual void determineAbsolutePaintRect();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FEGaussianBlur(Filter*, float, float);
+
+ float m_stdX;
+ float m_stdY;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FEGaussianBlur_h
diff --git a/Source/WebCore/platform/graphics/filters/FELighting.cpp b/Source/WebCore/platform/graphics/filters/FELighting.cpp
new file mode 100644
index 0000000..ec1ca88
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FELighting.cpp
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) 2010 University of Szeged
+ * Copyright (C) 2010 Zoltan Herczeg
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FELighting.h"
+
+#include "LightSource.h"
+
+namespace WebCore {
+
+FELighting::FELighting(Filter* filter, LightingType lightingType, const Color& lightingColor, float surfaceScale,
+ float diffuseConstant, float specularConstant, float specularExponent,
+ float kernelUnitLengthX, float kernelUnitLengthY, PassRefPtr<LightSource> lightSource)
+ : FilterEffect(filter)
+ , m_lightingType(lightingType)
+ , m_lightSource(lightSource)
+ , m_lightingColor(lightingColor)
+ , m_surfaceScale(surfaceScale)
+ , m_diffuseConstant(diffuseConstant)
+ , m_specularConstant(specularConstant)
+ , m_specularExponent(specularExponent)
+ , m_kernelUnitLengthX(kernelUnitLengthX)
+ , m_kernelUnitLengthY(kernelUnitLengthY)
+{
+}
+
+const static int cPixelSize = 4;
+const static int cAlphaChannelOffset = 3;
+const static unsigned char cOpaqueAlpha = static_cast<unsigned char>(0xff);
+const static float cFactor1div2 = -1 / 2.f;
+const static float cFactor1div3 = -1 / 3.f;
+const static float cFactor1div4 = -1 / 4.f;
+const static float cFactor2div3 = -2 / 3.f;
+
+// << 1 is signed multiply by 2
+inline void FELighting::LightingData::topLeft(int offset, IntPoint& normalVector)
+{
+ int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int right = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ offset += widthMultipliedByPixelSize;
+ int bottom = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int bottomRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ normalVector.setX(-(center << 1) + (right << 1) - bottom + bottomRight);
+ normalVector.setY(-(center << 1) - right + (bottom << 1) + bottomRight);
+}
+
+inline void FELighting::LightingData::topRow(int offset, IntPoint& normalVector)
+{
+ int left = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int right = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ offset += widthMultipliedByPixelSize;
+ int bottomLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int bottom = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int bottomRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ normalVector.setX(-(left << 1) + (right << 1) - bottomLeft + bottomRight);
+ normalVector.setY(-left - (center << 1) - right + bottomLeft + (bottom << 1) + bottomRight);
+}
+
+inline void FELighting::LightingData::topRight(int offset, IntPoint& normalVector)
+{
+ int left = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ offset += widthMultipliedByPixelSize;
+ int bottomLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int bottom = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ normalVector.setX(-(left << 1) + (center << 1) - bottomLeft + bottom);
+ normalVector.setY(-left - (center << 1) + bottomLeft + (bottom << 1));
+}
+
+inline void FELighting::LightingData::leftColumn(int offset, IntPoint& normalVector)
+{
+ int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int right = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ offset -= widthMultipliedByPixelSize;
+ int top = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int topRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ offset += widthMultipliedByPixelSize << 1;
+ int bottom = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int bottomRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ normalVector.setX(-top + topRight - (center << 1) + (right << 1) - bottom + bottomRight);
+ normalVector.setY(-(top << 1) - topRight + (bottom << 1) + bottomRight);
+}
+
+inline void FELighting::LightingData::interior(int offset, IntPoint& normalVector)
+{
+ int left = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int right = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ offset -= widthMultipliedByPixelSize;
+ int topLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int top = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int topRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ offset += widthMultipliedByPixelSize << 1;
+ int bottomLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int bottom = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int bottomRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ normalVector.setX(-topLeft + topRight - (left << 1) + (right << 1) - bottomLeft + bottomRight);
+ normalVector.setY(-topLeft - (top << 1) - topRight + bottomLeft + (bottom << 1) + bottomRight);
+}
+
+inline void FELighting::LightingData::rightColumn(int offset, IntPoint& normalVector)
+{
+ int left = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ offset -= widthMultipliedByPixelSize;
+ int topLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int top = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ offset += widthMultipliedByPixelSize << 1;
+ int bottomLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int bottom = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ normalVector.setX(-topLeft + top - (left << 1) + (center << 1) - bottomLeft + bottom);
+ normalVector.setY(-topLeft - (top << 1) + bottomLeft + (bottom << 1));
+}
+
+inline void FELighting::LightingData::bottomLeft(int offset, IntPoint& normalVector)
+{
+ int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int right = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ offset -= widthMultipliedByPixelSize;
+ int top = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int topRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ normalVector.setX(-top + topRight - (center << 1) + (right << 1));
+ normalVector.setY(-(top << 1) - topRight + (center << 1) + right);
+}
+
+inline void FELighting::LightingData::bottomRow(int offset, IntPoint& normalVector)
+{
+ int left = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int right = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ offset -= widthMultipliedByPixelSize;
+ int topLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int top = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ int topRight = static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+ normalVector.setX(-topLeft + topRight - (left << 1) + (right << 1));
+ normalVector.setY(-topLeft - (top << 1) - topRight + left + (center << 1) + right);
+}
+
+inline void FELighting::LightingData::bottomRight(int offset, IntPoint& normalVector)
+{
+ int left = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int center = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ offset -= widthMultipliedByPixelSize;
+ int topLeft = static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+ int top = static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+ normalVector.setX(-topLeft + top - (left << 1) + (center << 1));
+ normalVector.setY(-topLeft - (top << 1) + left + (center << 1));
+}
+
+inline void FELighting::inlineSetPixel(int offset, LightingData& data, LightSource::PaintingData& paintingData,
+ int lightX, int lightY, float factorX, float factorY, IntPoint& normal2DVector)
+{
+ m_lightSource->updatePaintingData(paintingData, lightX, lightY, static_cast<float>(data.pixels->get(offset + cAlphaChannelOffset)) * data.surfaceScale);
+
+ float lightStrength;
+ if (!normal2DVector.x() && !normal2DVector.y()) {
+ // Normal vector is (0, 0, 1). This is a quite frequent case.
+ if (m_lightingType == FELighting::DiffuseLighting)
+ lightStrength = m_diffuseConstant * paintingData.lightVector.z() / paintingData.lightVectorLength;
+ else {
+ FloatPoint3D halfwayVector = paintingData.lightVector;
+ halfwayVector.setZ(halfwayVector.z() + paintingData.lightVectorLength);
+ float halfwayVectorLength = halfwayVector.length();
+ if (m_specularExponent == 1)
+ lightStrength = m_specularConstant * halfwayVector.z() / halfwayVectorLength;
+ else
+ lightStrength = m_specularConstant * powf(halfwayVector.z() / halfwayVectorLength, m_specularExponent);
+ }
+ } else {
+ FloatPoint3D normalVector;
+ normalVector.setX(factorX * static_cast<float>(normal2DVector.x()) * data.surfaceScale);
+ normalVector.setY(factorY * static_cast<float>(normal2DVector.y()) * data.surfaceScale);
+ normalVector.setZ(1);
+ float normalVectorLength = normalVector.length();
+
+ if (m_lightingType == FELighting::DiffuseLighting)
+ lightStrength = m_diffuseConstant * (normalVector * paintingData.lightVector) / (normalVectorLength * paintingData.lightVectorLength);
+ else {
+ FloatPoint3D halfwayVector = paintingData.lightVector;
+ halfwayVector.setZ(halfwayVector.z() + paintingData.lightVectorLength);
+ float halfwayVectorLength = halfwayVector.length();
+ if (m_specularExponent == 1)
+ lightStrength = m_specularConstant * (normalVector * halfwayVector) / (normalVectorLength * halfwayVectorLength);
+ else
+ lightStrength = m_specularConstant * powf((normalVector * halfwayVector) / (normalVectorLength * halfwayVectorLength), m_specularExponent);
+ }
+ }
+
+ if (lightStrength > 1)
+ lightStrength = 1;
+ if (lightStrength < 0)
+ lightStrength = 0;
+
+ data.pixels->set(offset, static_cast<unsigned char>(lightStrength * paintingData.colorVector.x()));
+ data.pixels->set(offset + 1, static_cast<unsigned char>(lightStrength * paintingData.colorVector.y()));
+ data.pixels->set(offset + 2, static_cast<unsigned char>(lightStrength * paintingData.colorVector.z()));
+}
+
+void FELighting::setPixel(int offset, LightingData& data, LightSource::PaintingData& paintingData,
+ int lightX, int lightY, float factorX, float factorY, IntPoint& normalVector)
+{
+ inlineSetPixel(offset, data, paintingData, lightX, lightY, factorX, factorY, normalVector);
+}
+
+bool FELighting::drawLighting(ByteArray* pixels, int width, int height)
+{
+ LightSource::PaintingData paintingData;
+ LightingData data;
+
+ if (!m_lightSource)
+ return false;
+
+ // FIXME: do something if width or height (or both) is 1 pixel.
+ // The W3 spec does not define this case. Now the filter just returns.
+ if (width <= 2 || height <= 2)
+ return false;
+
+ data.pixels = pixels;
+ data.surfaceScale = m_surfaceScale / 255.0f;
+ data.widthMultipliedByPixelSize = width * cPixelSize;
+ data.widthDecreasedByOne = width - 1;
+ data.heightDecreasedByOne = height - 1;
+ paintingData.colorVector = FloatPoint3D(m_lightingColor.red(), m_lightingColor.green(), m_lightingColor.blue());
+ m_lightSource->initPaintingData(paintingData);
+
+ // Top/Left corner
+ IntPoint normalVector;
+ int offset = 0;
+ data.topLeft(offset, normalVector);
+ setPixel(offset, data, paintingData, 0, 0, cFactor2div3, cFactor2div3, normalVector);
+
+ // Top/Right pixel
+ offset = data.widthMultipliedByPixelSize - cPixelSize;
+ data.topRight(offset, normalVector);
+ setPixel(offset, data, paintingData, data.widthDecreasedByOne, 0, cFactor2div3, cFactor2div3, normalVector);
+
+ // Bottom/Left pixel
+ offset = data.heightDecreasedByOne * data.widthMultipliedByPixelSize;
+ data.bottomLeft(offset, normalVector);
+ setPixel(offset, data, paintingData, 0, data.heightDecreasedByOne, cFactor2div3, cFactor2div3, normalVector);
+
+ // Bottom/Right pixel
+ offset = height * data.widthMultipliedByPixelSize - cPixelSize;
+ data.bottomRight(offset, normalVector);
+ setPixel(offset, data, paintingData, data.widthDecreasedByOne, data.heightDecreasedByOne, cFactor2div3, cFactor2div3, normalVector);
+
+ if (width >= 3) {
+ // Top row
+ offset = cPixelSize;
+ for (int x = 1; x < data.widthDecreasedByOne; ++x, offset += cPixelSize) {
+ data.topRow(offset, normalVector);
+ inlineSetPixel(offset, data, paintingData, x, 0, cFactor1div3, cFactor1div2, normalVector);
+ }
+ // Bottom row
+ offset = data.heightDecreasedByOne * data.widthMultipliedByPixelSize + cPixelSize;
+ for (int x = 1; x < data.widthDecreasedByOne; ++x, offset += cPixelSize) {
+ data.bottomRow(offset, normalVector);
+ inlineSetPixel(offset, data, paintingData, x, data.heightDecreasedByOne, cFactor1div3, cFactor1div2, normalVector);
+ }
+ }
+
+ if (height >= 3) {
+ // Left column
+ offset = data.widthMultipliedByPixelSize;
+ for (int y = 1; y < data.heightDecreasedByOne; ++y, offset += data.widthMultipliedByPixelSize) {
+ data.leftColumn(offset, normalVector);
+ inlineSetPixel(offset, data, paintingData, 0, y, cFactor1div2, cFactor1div3, normalVector);
+ }
+ // Right column
+ offset = (data.widthMultipliedByPixelSize << 1) - cPixelSize;
+ for (int y = 1; y < data.heightDecreasedByOne; ++y, offset += data.widthMultipliedByPixelSize) {
+ data.rightColumn(offset, normalVector);
+ inlineSetPixel(offset, data, paintingData, data.widthDecreasedByOne, y, cFactor1div2, cFactor1div3, normalVector);
+ }
+ }
+
+ if (width >= 3 && height >= 3) {
+ // Interior pixels
+ for (int y = 1; y < data.heightDecreasedByOne; ++y) {
+ offset = y * data.widthMultipliedByPixelSize + cPixelSize;
+ for (int x = 1; x < data.widthDecreasedByOne; ++x, offset += cPixelSize) {
+ data.interior(offset, normalVector);
+ inlineSetPixel(offset, data, paintingData, x, y, cFactor1div4, cFactor1div4, normalVector);
+ }
+ }
+ }
+
+ int lastPixel = data.widthMultipliedByPixelSize * height;
+ if (m_lightingType == DiffuseLighting) {
+ for (int i = cAlphaChannelOffset; i < lastPixel; i += cPixelSize)
+ data.pixels->set(i, cOpaqueAlpha);
+ } else {
+ for (int i = 0; i < lastPixel; i += cPixelSize) {
+ unsigned char a1 = data.pixels->get(i);
+ unsigned char a2 = data.pixels->get(i + 1);
+ unsigned char a3 = data.pixels->get(i + 2);
+ // alpha set to set to max(a1, a2, a3)
+ data.pixels->set(i + 3, a1 >= a2 ? (a1 >= a3 ? a1 : a3) : (a2 >= a3 ? a2 : a3));
+ }
+ }
+
+ return true;
+}
+
+void FELighting::apply()
+{
+ if (hasResult())
+ return;
+ FilterEffect* in = inputEffect(0);
+ in->apply();
+ if (!in->hasResult())
+ return;
+
+ ByteArray* srcPixelArray = createUnmultipliedImageResult();
+ if (!srcPixelArray)
+ return;
+
+ setIsAlphaImage(false);
+
+ IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
+ in->copyUnmultipliedImage(srcPixelArray, effectDrawingRect);
+
+ // FIXME: support kernelUnitLengths other than (1,1). The issue here is that the W3
+ // standard has no test case for them, and other browsers (like Firefox) has strange
+ // output for various kernelUnitLengths, and I am not sure they are reliable.
+ // Anyway, feConvolveMatrix should also use the implementation
+
+ IntSize absolutePaintSize = absolutePaintRect().size();
+ drawLighting(srcPixelArray, absolutePaintSize.width(), absolutePaintSize.height());
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/FELighting.h b/Source/WebCore/platform/graphics/filters/FELighting.h
new file mode 100644
index 0000000..fa1c0aa
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FELighting.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2010 University of Szeged
+ * Copyright (C) 2010 Zoltan Herczeg
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FELighting_h
+#define FELighting_h
+
+#if ENABLE(FILTERS)
+#include "Color.h"
+#include "Filter.h"
+#include "FilterEffect.h"
+#include "LightSource.h"
+#include <wtf/ByteArray.h>
+
+// Common base class for FEDiffuseLighting and FESpecularLighting
+
+namespace WebCore {
+
+class FELighting : public FilterEffect {
+public:
+ virtual void apply();
+
+ virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(maxEffectRect()); }
+
+protected:
+ enum LightingType {
+ DiffuseLighting,
+ SpecularLighting
+ };
+
+ struct LightingData {
+ // This structure contains only read-only (SMP safe) data
+ ByteArray* pixels;
+ float surfaceScale;
+ int widthMultipliedByPixelSize;
+ int widthDecreasedByOne;
+ int heightDecreasedByOne;
+
+ inline void topLeft(int offset, IntPoint& normalVector);
+ inline void topRow(int offset, IntPoint& normalVector);
+ inline void topRight(int offset, IntPoint& normalVector);
+ inline void leftColumn(int offset, IntPoint& normalVector);
+ inline void interior(int offset, IntPoint& normalVector);
+ inline void rightColumn(int offset, IntPoint& normalVector);
+ inline void bottomLeft(int offset, IntPoint& normalVector);
+ inline void bottomRow(int offset, IntPoint& normalVector);
+ inline void bottomRight(int offset, IntPoint& normalVector);
+ };
+
+ FELighting(Filter*, LightingType, const Color&, float, float, float, float, float, float, PassRefPtr<LightSource>);
+
+ bool drawLighting(ByteArray*, int, int);
+ inline void inlineSetPixel(int offset, LightingData&, LightSource::PaintingData&,
+ int lightX, int lightY, float factorX, float factorY, IntPoint& normalVector);
+
+ // Not worth to inline every occurence of setPixel.
+ void setPixel(int offset, LightingData&, LightSource::PaintingData&,
+ int lightX, int lightY, float factorX, float factorY, IntPoint& normalVector);
+
+ LightingType m_lightingType;
+ RefPtr<LightSource> m_lightSource;
+
+ Color m_lightingColor;
+ float m_surfaceScale;
+ float m_diffuseConstant;
+ float m_specularConstant;
+ float m_specularExponent;
+ float m_kernelUnitLengthX;
+ float m_kernelUnitLengthY;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FELighting_h
diff --git a/Source/WebCore/platform/graphics/filters/FEMerge.cpp b/Source/WebCore/platform/graphics/filters/FEMerge.cpp
new file mode 100644
index 0000000..4395321
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEMerge.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FEMerge.h"
+
+#include "Filter.h"
+#include "GraphicsContext.h"
+
+namespace WebCore {
+
+FEMerge::FEMerge(Filter* filter)
+ : FilterEffect(filter)
+{
+}
+
+PassRefPtr<FEMerge> FEMerge::create(Filter* filter)
+{
+ return adoptRef(new FEMerge(filter));
+}
+
+void FEMerge::apply()
+{
+ if (hasResult())
+ return;
+ unsigned size = numberOfEffectInputs();
+ ASSERT(size > 0);
+ for (unsigned i = 0; i < size; ++i) {
+ FilterEffect* in = inputEffect(i);
+ in->apply();
+ if (!in->hasResult())
+ return;
+ }
+
+ ImageBuffer* resultImage = createImageBufferResult();
+ if (!resultImage)
+ return;
+
+ GraphicsContext* filterContext = resultImage->context();
+ for (unsigned i = 0; i < size; ++i) {
+ FilterEffect* in = inputEffect(i);
+ filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()));
+ }
+}
+
+void FEMerge::dump()
+{
+}
+
+TextStream& FEMerge::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feMerge";
+ FilterEffect::externalRepresentation(ts);
+ unsigned size = numberOfEffectInputs();
+ ASSERT(size > 0);
+ ts << " mergeNodes=\"" << size << "\"]\n";
+ for (unsigned i = 0; i < size; ++i)
+ inputEffect(i)->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/FEMerge.h b/Source/WebCore/platform/graphics/filters/FEMerge.h
new file mode 100644
index 0000000..dbee610
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEMerge.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FEMerge_h
+#define FEMerge_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+#include "Filter.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class FEMerge : public FilterEffect {
+public:
+ static PassRefPtr<FEMerge> create(Filter*);
+
+ virtual void apply();
+ virtual void dump();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FEMerge(Filter*);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FEMerge_h
diff --git a/Source/WebCore/platform/graphics/filters/FEMorphology.cpp b/Source/WebCore/platform/graphics/filters/FEMorphology.cpp
new file mode 100644
index 0000000..45c7edb
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEMorphology.cpp
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FEMorphology.h"
+
+#include "Filter.h"
+
+#include <wtf/ByteArray.h>
+#include <wtf/Vector.h>
+
+using std::min;
+using std::max;
+
+namespace WebCore {
+
+FEMorphology::FEMorphology(Filter* filter, MorphologyOperatorType type, float radiusX, float radiusY)
+ : FilterEffect(filter)
+ , m_type(type)
+ , m_radiusX(radiusX)
+ , m_radiusY(radiusY)
+{
+}
+
+PassRefPtr<FEMorphology> FEMorphology::create(Filter* filter, MorphologyOperatorType type, float radiusX, float radiusY)
+{
+ return adoptRef(new FEMorphology(filter, type, radiusX, radiusY));
+}
+
+MorphologyOperatorType FEMorphology::morphologyOperator() const
+{
+ return m_type;
+}
+
+void FEMorphology::setMorphologyOperator(MorphologyOperatorType type)
+{
+ m_type = type;
+}
+
+float FEMorphology::radiusX() const
+{
+ return m_radiusX;
+}
+
+void FEMorphology::setRadiusX(float radiusX)
+{
+ m_radiusX = radiusX;
+}
+
+float FEMorphology::radiusY() const
+{
+ return m_radiusY;
+}
+
+void FEMorphology::determineAbsolutePaintRect()
+{
+ FloatRect paintRect = inputEffect(0)->absolutePaintRect();
+ Filter* filter = this->filter();
+ paintRect.inflateX(filter->applyHorizontalScale(m_radiusX));
+ paintRect.inflateY(filter->applyVerticalScale(m_radiusY));
+ paintRect.intersect(maxEffectRect());
+ setAbsolutePaintRect(enclosingIntRect(paintRect));
+}
+
+void FEMorphology::setRadiusY(float radiusY)
+{
+ m_radiusY = radiusY;
+}
+
+void FEMorphology::apply()
+{
+ if (hasResult())
+ return;
+ FilterEffect* in = inputEffect(0);
+ in->apply();
+ if (!in->hasResult())
+ return;
+
+ ByteArray* dstPixelArray = createPremultipliedImageResult();
+ if (!dstPixelArray)
+ return;
+
+ setIsAlphaImage(in->isAlphaImage());
+ if (m_radiusX <= 0 || m_radiusY <= 0)
+ return;
+
+ Filter* filter = this->filter();
+ int radiusX = static_cast<int>(floorf(filter->applyHorizontalScale(m_radiusX)));
+ int radiusY = static_cast<int>(floorf(filter->applyVerticalScale(m_radiusY)));
+
+ IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
+ RefPtr<ByteArray> srcPixelArray = in->asPremultipliedImage(effectDrawingRect);
+
+ int effectWidth = effectDrawingRect.width() * 4;
+
+ // Limit the radius size to effect dimensions
+ radiusX = min(effectDrawingRect.width() - 1, radiusX);
+ radiusY = min(effectDrawingRect.height() - 1, radiusY);
+
+ Vector<unsigned char> extrema;
+ for (int y = 0; y < effectDrawingRect.height(); ++y) {
+ int startY = max(0, y - radiusY);
+ int endY = min(effectDrawingRect.height() - 1, y + radiusY);
+ for (unsigned channel = 0; channel < 4; ++channel) {
+ // Fill the kernel
+ extrema.clear();
+ for (int j = 0; j <= radiusX; ++j) {
+ unsigned char columnExtrema = srcPixelArray->get(startY * effectWidth + 4 * j + channel);
+ for (int i = startY; i <= endY; ++i) {
+ unsigned char pixel = srcPixelArray->get(i * effectWidth + 4 * j + channel);
+ if ((m_type == FEMORPHOLOGY_OPERATOR_ERODE && pixel <= columnExtrema) ||
+ (m_type == FEMORPHOLOGY_OPERATOR_DILATE && pixel >= columnExtrema))
+ columnExtrema = pixel;
+ }
+ extrema.append(columnExtrema);
+ }
+
+ // Kernel is filled, get extrema of next column
+ for (int x = 0; x < effectDrawingRect.width(); ++x) {
+ unsigned endX = min(x + radiusX, effectDrawingRect.width() - 1);
+ unsigned char columnExtrema = srcPixelArray->get(startY * effectWidth + endX * 4 + channel);
+ for (int i = startY; i <= endY; ++i) {
+ unsigned char pixel = srcPixelArray->get(i * effectWidth + endX * 4 + channel);
+ if ((m_type == FEMORPHOLOGY_OPERATOR_ERODE && pixel <= columnExtrema) ||
+ (m_type == FEMORPHOLOGY_OPERATOR_DILATE && pixel >= columnExtrema))
+ columnExtrema = pixel;
+ }
+ if (x - radiusX >= 0)
+ extrema.remove(0);
+ if (x + radiusX <= effectDrawingRect.width())
+ extrema.append(columnExtrema);
+ unsigned char entireExtrema = extrema[0];
+ for (unsigned kernelIndex = 0; kernelIndex < extrema.size(); ++kernelIndex) {
+ if ((m_type == FEMORPHOLOGY_OPERATOR_ERODE && extrema[kernelIndex] <= entireExtrema) ||
+ (m_type == FEMORPHOLOGY_OPERATOR_DILATE && extrema[kernelIndex] >= entireExtrema))
+ entireExtrema = extrema[kernelIndex];
+ }
+ dstPixelArray->set(y * effectWidth + 4 * x + channel, entireExtrema);
+ }
+ }
+ }
+}
+
+void FEMorphology::dump()
+{
+}
+
+static TextStream& operator<<(TextStream& ts, const MorphologyOperatorType& type)
+{
+ switch (type) {
+ case FEMORPHOLOGY_OPERATOR_UNKNOWN:
+ ts << "UNKNOWN";
+ break;
+ case FEMORPHOLOGY_OPERATOR_ERODE:
+ ts << "ERODE";
+ break;
+ case FEMORPHOLOGY_OPERATOR_DILATE:
+ ts << "DILATE";
+ break;
+ }
+ return ts;
+}
+
+TextStream& FEMorphology::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feMorphology";
+ FilterEffect::externalRepresentation(ts);
+ ts << " operator=\"" << morphologyOperator() << "\" "
+ << "radius=\"" << radiusX() << ", " << radiusY() << "\"]\n";
+ inputEffect(0)->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/FEMorphology.h b/Source/WebCore/platform/graphics/filters/FEMorphology.h
new file mode 100644
index 0000000..683e7d0
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEMorphology.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FEMorphology_h
+#define FEMorphology_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+#include "Filter.h"
+
+namespace WebCore {
+
+enum MorphologyOperatorType {
+ FEMORPHOLOGY_OPERATOR_UNKNOWN = 0,
+ FEMORPHOLOGY_OPERATOR_ERODE = 1,
+ FEMORPHOLOGY_OPERATOR_DILATE = 2
+};
+
+class FEMorphology : public FilterEffect {
+public:
+ static PassRefPtr<FEMorphology> create(Filter*, MorphologyOperatorType, float radiusX, float radiusY);
+ MorphologyOperatorType morphologyOperator() const;
+ void setMorphologyOperator(MorphologyOperatorType);
+
+ float radiusX() const;
+ void setRadiusX(float);
+
+ float radiusY() const;
+ void setRadiusY(float);
+
+ virtual void apply();
+ virtual void dump();
+
+ virtual void determineAbsolutePaintRect();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FEMorphology(Filter*, MorphologyOperatorType, float radiusX, float radiusY);
+
+ MorphologyOperatorType m_type;
+ float m_radiusX;
+ float m_radiusY;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FEMorphology_h
diff --git a/Source/WebCore/platform/graphics/filters/FEOffset.cpp b/Source/WebCore/platform/graphics/filters/FEOffset.cpp
new file mode 100644
index 0000000..f1d5914
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEOffset.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FEOffset.h"
+
+#include "Filter.h"
+#include "GraphicsContext.h"
+
+namespace WebCore {
+
+FEOffset::FEOffset(Filter* filter, float dx, float dy)
+ : FilterEffect(filter)
+ , m_dx(dx)
+ , m_dy(dy)
+{
+}
+
+PassRefPtr<FEOffset> FEOffset::create(Filter* filter, float dx, float dy)
+{
+ return adoptRef(new FEOffset(filter, dx, dy));
+}
+
+float FEOffset::dx() const
+{
+ return m_dx;
+}
+
+void FEOffset::setDx(float dx)
+{
+ m_dx = dx;
+}
+
+float FEOffset::dy() const
+{
+ return m_dy;
+}
+
+void FEOffset::setDy(float dy)
+{
+ m_dy = dy;
+}
+
+void FEOffset::determineAbsolutePaintRect()
+{
+ FloatRect paintRect = inputEffect(0)->absolutePaintRect();
+ Filter* filter = this->filter();
+ paintRect.move(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy));
+ paintRect.intersect(maxEffectRect());
+ setAbsolutePaintRect(enclosingIntRect(paintRect));
+}
+
+void FEOffset::apply()
+{
+ if (hasResult())
+ return;
+ FilterEffect* in = inputEffect(0);
+ in->apply();
+ if (!in->hasResult())
+ return;
+
+ ImageBuffer* resultImage = createImageBufferResult();
+ if (!resultImage)
+ return;
+
+ setIsAlphaImage(in->isAlphaImage());
+
+ FloatRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect());
+ Filter* filter = this->filter();
+ drawingRegion.move(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy));
+ resultImage->context()->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegion);
+}
+
+void FEOffset::dump()
+{
+}
+
+TextStream& FEOffset::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feOffset";
+ FilterEffect::externalRepresentation(ts);
+ ts << " dx=\"" << dx() << "\" dy=\"" << dy() << "\"]\n";
+ inputEffect(0)->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/FEOffset.h b/Source/WebCore/platform/graphics/filters/FEOffset.h
new file mode 100644
index 0000000..5aa5c38
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FEOffset.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FEOffset_h
+#define FEOffset_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+#include "Filter.h"
+
+namespace WebCore {
+
+class FEOffset : public FilterEffect {
+public:
+ static PassRefPtr<FEOffset> create(Filter*, float dx, float dy);
+
+ float dx() const;
+ void setDx(float);
+
+ float dy() const;
+ void setDy(float);
+
+ virtual void apply();
+ virtual void dump();
+
+ virtual void determineAbsolutePaintRect();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FEOffset(Filter*, float dx, float dy);
+
+ float m_dx;
+ float m_dy;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FEOffset_h
diff --git a/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp b/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp
new file mode 100644
index 0000000..d21dafd
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FESpecularLighting.h"
+
+#include "LightSource.h"
+
+namespace WebCore {
+
+FESpecularLighting::FESpecularLighting(Filter* filter, const Color& lightingColor, float surfaceScale,
+ float specularConstant, float specularExponent, float kernelUnitLengthX,
+ float kernelUnitLengthY, PassRefPtr<LightSource> lightSource)
+ : FELighting(filter, SpecularLighting, lightingColor, surfaceScale, 0, specularConstant, specularExponent, kernelUnitLengthX, kernelUnitLengthY, lightSource)
+{
+}
+
+PassRefPtr<FESpecularLighting> FESpecularLighting::create(Filter* filter, const Color& lightingColor,
+ float surfaceScale, float specularConstant, float specularExponent,
+ float kernelUnitLengthX, float kernelUnitLengthY, PassRefPtr<LightSource> lightSource)
+{
+ return adoptRef(new FESpecularLighting(filter, lightingColor, surfaceScale, specularConstant, specularExponent,
+ kernelUnitLengthX, kernelUnitLengthY, lightSource));
+}
+
+FESpecularLighting::~FESpecularLighting()
+{
+}
+
+Color FESpecularLighting::lightingColor() const
+{
+ return m_lightingColor;
+}
+
+void FESpecularLighting::setLightingColor(const Color& lightingColor)
+{
+ m_lightingColor = lightingColor;
+}
+
+float FESpecularLighting::surfaceScale() const
+{
+ return m_surfaceScale;
+}
+
+void FESpecularLighting::setSurfaceScale(float surfaceScale)
+{
+ m_surfaceScale = surfaceScale;
+}
+
+float FESpecularLighting::specularConstant() const
+{
+ return m_specularConstant;
+}
+
+void FESpecularLighting::setSpecularConstant(float specularConstant)
+{
+ m_specularConstant = specularConstant;
+}
+
+float FESpecularLighting::specularExponent() const
+{
+ return m_specularExponent;
+}
+
+void FESpecularLighting::setSpecularExponent(float specularExponent)
+{
+ m_specularExponent = specularExponent;
+}
+
+float FESpecularLighting::kernelUnitLengthX() const
+{
+ return m_kernelUnitLengthX;
+}
+
+void FESpecularLighting::setKernelUnitLengthX(float kernelUnitLengthX)
+{
+ m_kernelUnitLengthX = kernelUnitLengthX;
+}
+
+float FESpecularLighting::kernelUnitLengthY() const
+{
+ return m_kernelUnitLengthY;
+}
+
+void FESpecularLighting::setKernelUnitLengthY(float kernelUnitLengthY)
+{
+ m_kernelUnitLengthY = kernelUnitLengthY;
+}
+
+const LightSource* FESpecularLighting::lightSource() const
+{
+ return m_lightSource.get();
+}
+
+void FESpecularLighting::setLightSource(PassRefPtr<LightSource> lightSource)
+{
+ m_lightSource = lightSource;
+}
+
+void FESpecularLighting::dump()
+{
+}
+
+TextStream& FESpecularLighting::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feSpecularLighting";
+ FilterEffect::externalRepresentation(ts);
+ ts << " surfaceScale=\"" << m_surfaceScale << "\" "
+ << "specualConstant=\"" << m_specularConstant << "\" "
+ << "specularExponent=\"" << m_specularExponent << "\"]\n";
+ inputEffect(0)->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/FESpecularLighting.h b/Source/WebCore/platform/graphics/filters/FESpecularLighting.h
new file mode 100644
index 0000000..b3ccfbc
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FESpecularLighting.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FESpecularLighting_h
+#define FESpecularLighting_h
+
+#if ENABLE(FILTERS)
+#include "FELighting.h"
+
+namespace WebCore {
+
+class FESpecularLighting : public FELighting {
+public:
+ static PassRefPtr<FESpecularLighting> create(Filter*, const Color&, float, float,
+ float, float, float, PassRefPtr<LightSource>);
+ virtual ~FESpecularLighting();
+
+ Color lightingColor() const;
+ void setLightingColor(const Color&);
+
+ float surfaceScale() const;
+ void setSurfaceScale(float);
+
+ float specularConstant() const;
+ void setSpecularConstant(float);
+
+ float specularExponent() const;
+ void setSpecularExponent(float);
+
+ float kernelUnitLengthX() const;
+ void setKernelUnitLengthX(float);
+
+ float kernelUnitLengthY() const;
+ void setKernelUnitLengthY(float);
+
+ const LightSource* lightSource() const;
+ void setLightSource(PassRefPtr<LightSource>);
+
+ virtual void dump();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FESpecularLighting(Filter*, const Color&, float, float, float, float, float, PassRefPtr<LightSource>);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FESpecularLighting_h
diff --git a/Source/WebCore/platform/graphics/filters/FETile.cpp b/Source/WebCore/platform/graphics/filters/FETile.cpp
new file mode 100644
index 0000000..e516c7e
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FETile.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FETile.h"
+
+#include "AffineTransform.h"
+#include "Filter.h"
+#include "GraphicsContext.h"
+#include "Pattern.h"
+#include "SVGImageBufferTools.h"
+
+namespace WebCore {
+
+FETile::FETile(Filter* filter)
+ : FilterEffect(filter)
+{
+}
+
+PassRefPtr<FETile> FETile::create(Filter* filter)
+{
+ return adoptRef(new FETile(filter));
+}
+
+void FETile::apply()
+{
+// FIXME: See bug 47315. This is a hack to work around a compile failure, but is incorrect behavior otherwise.
+#if ENABLE(SVG)
+ if (hasResult())
+ return;
+ FilterEffect* in = inputEffect(0);
+ in->apply();
+ if (!in->hasResult())
+ return;
+
+ ImageBuffer* resultImage = createImageBufferResult();
+ if (!resultImage)
+ return;
+
+ setIsAlphaImage(in->isAlphaImage());
+
+ // Source input needs more attention. It has the size of the filterRegion but gives the
+ // size of the cutted sourceImage back. This is part of the specification and optimization.
+ FloatRect tileRect = in->maxEffectRect();
+ FloatPoint inMaxEffectLocation = tileRect.location();
+ FloatPoint maxEffectLocation = maxEffectRect().location();
+ if (in->filterEffectType() == FilterEffectTypeSourceInput) {
+ Filter* filter = this->filter();
+ tileRect = filter->filterRegion();
+ tileRect.scale(filter->filterResolution().width(), filter->filterResolution().height());
+ }
+
+ OwnPtr<ImageBuffer> tileImage;
+ if (!SVGImageBufferTools::createImageBuffer(tileRect, tileRect, tileImage, ColorSpaceDeviceRGB))
+ return;
+
+ GraphicsContext* tileImageContext = tileImage->context();
+ tileImageContext->translate(-inMaxEffectLocation.x(), -inMaxEffectLocation.y());
+ tileImageContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, in->absolutePaintRect().location());
+
+ RefPtr<Pattern> pattern = Pattern::create(tileImage->copyImage(), true, true);
+
+ AffineTransform patternTransform;
+ patternTransform.translate(inMaxEffectLocation.x() - maxEffectLocation.x(), inMaxEffectLocation.y() - maxEffectLocation.y());
+ pattern->setPatternSpaceTransform(patternTransform);
+ GraphicsContext* filterContext = resultImage->context();
+ filterContext->setFillPattern(pattern);
+ filterContext->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()));
+#endif
+}
+
+void FETile::dump()
+{
+}
+
+TextStream& FETile::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feTile";
+ FilterEffect::externalRepresentation(ts);
+ ts << "]\n";
+ inputEffect(0)->externalRepresentation(ts, indent + 1);
+
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/FETile.h b/Source/WebCore/platform/graphics/filters/FETile.h
new file mode 100644
index 0000000..9b02b4c
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FETile.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FETile_h
+#define FETile_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+#include "Filter.h"
+
+namespace WebCore {
+
+class FETile : public FilterEffect {
+public:
+ static PassRefPtr<FETile> create(Filter* filter);
+
+ virtual void apply();
+ virtual void dump();
+
+ virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(maxEffectRect()); }
+
+ virtual FilterEffectType filterEffectType() const { return FilterEffectTypeTile; }
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FETile(Filter*);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FETile_h
diff --git a/Source/WebCore/platform/graphics/filters/FETurbulence.cpp b/Source/WebCore/platform/graphics/filters/FETurbulence.cpp
new file mode 100644
index 0000000..f1a159b
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FETurbulence.cpp
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2010 Renata Hodovan <reni@inf.u-szeged.hu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FETurbulence.h"
+
+#include "Filter.h"
+
+#include <wtf/ByteArray.h>
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+/*
+ Produces results in the range [1, 2**31 - 2]. Algorithm is:
+ r = (a * r) mod m where a = randAmplitude = 16807 and
+ m = randMaximum = 2**31 - 1 = 2147483647, r = seed.
+ See [Park & Miller], CACM vol. 31 no. 10 p. 1195, Oct. 1988
+ To test: the algorithm should produce the result 1043618065
+ as the 10,000th generated number if the original seed is 1.
+*/
+static const int s_perlinNoise = 4096;
+static const long s_randMaximum = 2147483647; // 2**31 - 1
+static const int s_randAmplitude = 16807; // 7**5; primitive root of m
+static const int s_randQ = 127773; // m / a
+static const int s_randR = 2836; // m % a
+
+FETurbulence::FETurbulence(Filter* filter, TurbulanceType type, float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, bool stitchTiles)
+ : FilterEffect(filter)
+ , m_type(type)
+ , m_baseFrequencyX(baseFrequencyX)
+ , m_baseFrequencyY(baseFrequencyY)
+ , m_numOctaves(numOctaves)
+ , m_seed(seed)
+ , m_stitchTiles(stitchTiles)
+{
+}
+
+PassRefPtr<FETurbulence> FETurbulence::create(Filter* filter, TurbulanceType type, float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, bool stitchTiles)
+{
+ return adoptRef(new FETurbulence(filter, type, baseFrequencyX, baseFrequencyY, numOctaves, seed, stitchTiles));
+}
+
+TurbulanceType FETurbulence::type() const
+{
+ return m_type;
+}
+
+void FETurbulence::setType(TurbulanceType type)
+{
+ m_type = type;
+}
+
+float FETurbulence::baseFrequencyY() const
+{
+ return m_baseFrequencyY;
+}
+
+void FETurbulence::setBaseFrequencyY(float baseFrequencyY)
+{
+ m_baseFrequencyY = baseFrequencyY;
+}
+
+float FETurbulence::baseFrequencyX() const
+{
+ return m_baseFrequencyX;
+}
+
+void FETurbulence::setBaseFrequencyX(float baseFrequencyX)
+{
+ m_baseFrequencyX = baseFrequencyX;
+}
+
+float FETurbulence::seed() const
+{
+ return m_seed;
+}
+
+void FETurbulence::setSeed(float seed)
+{
+ m_seed = seed;
+}
+
+int FETurbulence::numOctaves() const
+{
+ return m_numOctaves;
+}
+
+void FETurbulence::setNumOctaves(bool numOctaves)
+{
+ m_numOctaves = numOctaves;
+}
+
+bool FETurbulence::stitchTiles() const
+{
+ return m_stitchTiles;
+}
+
+void FETurbulence::setStitchTiles(bool stitch)
+{
+ m_stitchTiles = stitch;
+}
+
+// The turbulence calculation code is an adapted version of what appears in the SVG 1.1 specification:
+// http://www.w3.org/TR/SVG11/filters.html#feTurbulence
+
+FETurbulence::PaintingData::PaintingData(long paintingSeed, const IntSize& paintingSize)
+ : seed(paintingSeed)
+ , width(0)
+ , height(0)
+ , wrapX(0)
+ , wrapY(0)
+ , channel(0)
+ , filterSize(paintingSize)
+{
+}
+
+// Compute pseudo random number.
+inline long FETurbulence::PaintingData::random()
+{
+ long result = s_randAmplitude * (seed % s_randQ) - s_randR * (seed / s_randQ);
+ if (result <= 0)
+ result += s_randMaximum;
+ seed = result;
+ return result;
+}
+
+inline float smoothCurve(float t)
+{
+ return t * t * (3 - 2 * t);
+}
+
+inline float linearInterpolation(float t, float a, float b)
+{
+ return a + t * (b - a);
+}
+
+inline void FETurbulence::initPaint(PaintingData& paintingData)
+{
+ float normalizationFactor;
+
+ // The seed value clamp to the range [1, s_randMaximum - 1].
+ if (paintingData.seed <= 0)
+ paintingData.seed = -(paintingData.seed % (s_randMaximum - 1)) + 1;
+ if (paintingData.seed > s_randMaximum - 1)
+ paintingData.seed = s_randMaximum - 1;
+
+ float* gradient;
+ for (int channel = 0; channel < 4; ++channel) {
+ for (int i = 0; i < s_blockSize; ++i) {
+ paintingData.latticeSelector[i] = i;
+ gradient = paintingData.gradient[channel][i];
+ gradient[0] = static_cast<float>((paintingData.random() % (2 * s_blockSize)) - s_blockSize) / s_blockSize;
+ gradient[1] = static_cast<float>((paintingData.random() % (2 * s_blockSize)) - s_blockSize) / s_blockSize;
+ normalizationFactor = sqrtf(gradient[0] * gradient[0] + gradient[1] * gradient[1]);
+ gradient[0] /= normalizationFactor;
+ gradient[1] /= normalizationFactor;
+ }
+ }
+ for (int i = s_blockSize - 1; i > 0; --i) {
+ int k = paintingData.latticeSelector[i];
+ int j = paintingData.random() % s_blockSize;
+ ASSERT(j >= 0);
+ ASSERT(j < 2 * s_blockSize + 2);
+ paintingData.latticeSelector[i] = paintingData.latticeSelector[j];
+ paintingData.latticeSelector[j] = k;
+ }
+ for (int i = 0; i < s_blockSize + 2; ++i) {
+ paintingData.latticeSelector[s_blockSize + i] = paintingData.latticeSelector[i];
+ for (int channel = 0; channel < 4; ++channel) {
+ paintingData.gradient[channel][s_blockSize + i][0] = paintingData.gradient[channel][i][0];
+ paintingData.gradient[channel][s_blockSize + i][1] = paintingData.gradient[channel][i][1];
+ }
+ }
+}
+
+inline void checkNoise(int& noiseValue, int limitValue, int newValue)
+{
+ if (noiseValue >= limitValue)
+ noiseValue -= newValue;
+ if (noiseValue >= limitValue - 1)
+ noiseValue -= newValue - 1;
+}
+
+float FETurbulence::noise2D(PaintingData& paintingData, const FloatPoint& noiseVector)
+{
+ struct Noise {
+ int noisePositionIntegerValue;
+ float noisePositionFractionValue;
+
+ Noise(float component)
+ {
+ float position = component + s_perlinNoise;
+ noisePositionIntegerValue = static_cast<int>(position);
+ noisePositionFractionValue = position - noisePositionIntegerValue;
+ }
+ };
+
+ Noise noiseX(noiseVector.x());
+ Noise noiseY(noiseVector.y());
+ float* q;
+ float sx, sy, a, b, u, v;
+
+ // If stitching, adjust lattice points accordingly.
+ if (m_stitchTiles) {
+ checkNoise(noiseX.noisePositionIntegerValue, paintingData.wrapX, paintingData.width);
+ checkNoise(noiseY.noisePositionIntegerValue, paintingData.wrapY, paintingData.height);
+ }
+
+ noiseX.noisePositionIntegerValue &= s_blockMask;
+ noiseY.noisePositionIntegerValue &= s_blockMask;
+ int latticeIndex = paintingData.latticeSelector[noiseX.noisePositionIntegerValue];
+ int nextLatticeIndex = paintingData.latticeSelector[(noiseX.noisePositionIntegerValue + 1) & s_blockMask];
+
+ sx = smoothCurve(noiseX.noisePositionFractionValue);
+ sy = smoothCurve(noiseY.noisePositionFractionValue);
+
+ // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement.
+ int temp = paintingData.latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue];
+ q = paintingData.gradient[paintingData.channel][temp];
+ u = noiseX.noisePositionFractionValue * q[0] + noiseY.noisePositionFractionValue * q[1];
+ temp = paintingData.latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue];
+ q = paintingData.gradient[paintingData.channel][temp];
+ v = (noiseX.noisePositionFractionValue - 1) * q[0] + noiseY.noisePositionFractionValue * q[1];
+ a = linearInterpolation(sx, u, v);
+ temp = paintingData.latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue + 1];
+ q = paintingData.gradient[paintingData.channel][temp];
+ u = noiseX.noisePositionFractionValue * q[0] + (noiseY.noisePositionFractionValue - 1) * q[1];
+ temp = paintingData.latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue + 1];
+ q = paintingData.gradient[paintingData.channel][temp];
+ v = (noiseX.noisePositionFractionValue - 1) * q[0] + (noiseY.noisePositionFractionValue - 1) * q[1];
+ b = linearInterpolation(sx, u, v);
+ return linearInterpolation(sy, a, b);
+}
+
+unsigned char FETurbulence::calculateTurbulenceValueForPoint(PaintingData& paintingData, const FloatPoint& point)
+{
+ float tileWidth = paintingData.filterSize.width();
+ ASSERT(tileWidth > 0);
+ float tileHeight = paintingData.filterSize.height();
+ ASSERT(tileHeight > 0);
+ // Adjust the base frequencies if necessary for stitching.
+ if (m_stitchTiles) {
+ // When stitching tiled turbulence, the frequencies must be adjusted
+ // so that the tile borders will be continuous.
+ if (m_baseFrequencyX) {
+ float lowFrequency = floorf(tileWidth * m_baseFrequencyX) / tileWidth;
+ float highFrequency = ceilf(tileWidth * m_baseFrequencyX) / tileWidth;
+ // BaseFrequency should be non-negative according to the standard.
+ if (m_baseFrequencyX / lowFrequency < highFrequency / m_baseFrequencyX)
+ m_baseFrequencyX = lowFrequency;
+ else
+ m_baseFrequencyX = highFrequency;
+ }
+ if (m_baseFrequencyY) {
+ float lowFrequency = floorf(tileHeight * m_baseFrequencyY) / tileHeight;
+ float highFrequency = ceilf(tileHeight * m_baseFrequencyY) / tileHeight;
+ if (m_baseFrequencyY / lowFrequency < highFrequency / m_baseFrequencyY)
+ m_baseFrequencyY = lowFrequency;
+ else
+ m_baseFrequencyY = highFrequency;
+ }
+ // Set up TurbulenceInitial stitch values.
+ paintingData.width = roundf(tileWidth * m_baseFrequencyX);
+ paintingData.wrapX = s_perlinNoise + paintingData.width;
+ paintingData.height = roundf(tileHeight * m_baseFrequencyY);
+ paintingData.wrapY = s_perlinNoise + paintingData.height;
+ }
+ float turbulenceFunctionResult = 0;
+ FloatPoint noiseVector(point.x() * m_baseFrequencyX, point.y() * m_baseFrequencyY);
+ float ratio = 1;
+ for (int octave = 0; octave < m_numOctaves; ++octave) {
+ if (m_type == FETURBULENCE_TYPE_FRACTALNOISE)
+ turbulenceFunctionResult += noise2D(paintingData, noiseVector) / ratio;
+ else
+ turbulenceFunctionResult += fabsf(noise2D(paintingData, noiseVector)) / ratio;
+ noiseVector.setX(noiseVector.x() * 2);
+ noiseVector.setY(noiseVector.y() * 2);
+ ratio *= 2;
+ if (m_stitchTiles) {
+ // Update stitch values. Subtracting s_perlinNoiseoise before the multiplication and
+ // adding it afterward simplifies to subtracting it once.
+ paintingData.width *= 2;
+ paintingData.wrapX = 2 * paintingData.wrapX - s_perlinNoise;
+ paintingData.height *= 2;
+ paintingData.wrapY = 2 * paintingData.wrapY - s_perlinNoise;
+ }
+ }
+
+ // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult * 255) + 255) / 2 by fractalNoise
+ // and (turbulenceFunctionResult * 255) by turbulence.
+ if (m_type == FETURBULENCE_TYPE_FRACTALNOISE)
+ turbulenceFunctionResult = turbulenceFunctionResult * 0.5f + 0.5f;
+ // Clamp result
+ turbulenceFunctionResult = std::max(std::min(turbulenceFunctionResult, 1.f), 0.f);
+ return static_cast<unsigned char>(turbulenceFunctionResult * 255);
+}
+
+void FETurbulence::apply()
+{
+ if (hasResult())
+ return;
+ ByteArray* pixelArray = createUnmultipliedImageResult();
+ if (!pixelArray)
+ return;
+
+ if (absolutePaintRect().isEmpty())
+ return;
+
+ PaintingData paintingData(m_seed, roundedIntSize(filterPrimitiveSubregion().size()));
+ initPaint(paintingData);
+
+ FloatRect filterRegion = absolutePaintRect();
+ FloatPoint point;
+ point.setY(filterRegion.y());
+ int indexOfPixelChannel = 0;
+ for (int y = 0; y < absolutePaintRect().height(); ++y) {
+ point.setY(point.y() + 1);
+ point.setX(filterRegion.x());
+ for (int x = 0; x < absolutePaintRect().width(); ++x) {
+ point.setX(point.x() + 1);
+ for (paintingData.channel = 0; paintingData.channel < 4; ++paintingData.channel, ++indexOfPixelChannel)
+ pixelArray->set(indexOfPixelChannel, calculateTurbulenceValueForPoint(paintingData, filter()->mapAbsolutePointToLocalPoint(point)));
+ }
+ }
+}
+
+void FETurbulence::dump()
+{
+}
+
+static TextStream& operator<<(TextStream& ts, const TurbulanceType& type)
+{
+ switch (type) {
+ case FETURBULENCE_TYPE_UNKNOWN:
+ ts << "UNKNOWN";
+ break;
+ case FETURBULENCE_TYPE_TURBULENCE:
+ ts << "TURBULANCE";
+ break;
+ case FETURBULENCE_TYPE_FRACTALNOISE:
+ ts << "NOISE";
+ break;
+ }
+ return ts;
+}
+
+TextStream& FETurbulence::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feTurbulence";
+ FilterEffect::externalRepresentation(ts);
+ ts << " type=\"" << type() << "\" "
+ << "baseFrequency=\"" << baseFrequencyX() << ", " << baseFrequencyY() << "\" "
+ << "seed=\"" << seed() << "\" "
+ << "numOctaves=\"" << numOctaves() << "\" "
+ << "stitchTiles=\"" << stitchTiles() << "\"]\n";
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/FETurbulence.h b/Source/WebCore/platform/graphics/filters/FETurbulence.h
new file mode 100644
index 0000000..1bad123
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FETurbulence.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2010 Renata Hodovan <reni@inf.u-szeged.hu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FETurbulence_h
+#define FETurbulence_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+#include "Filter.h"
+
+namespace WebCore {
+
+enum TurbulanceType {
+ FETURBULENCE_TYPE_UNKNOWN = 0,
+ FETURBULENCE_TYPE_FRACTALNOISE = 1,
+ FETURBULENCE_TYPE_TURBULENCE = 2
+};
+
+class FETurbulence : public FilterEffect {
+public:
+ static PassRefPtr<FETurbulence> create(Filter*, TurbulanceType, float, float, int, float, bool);
+
+ TurbulanceType type() const;
+ void setType(TurbulanceType);
+
+ float baseFrequencyY() const;
+ void setBaseFrequencyY(float);
+
+ float baseFrequencyX() const;
+ void setBaseFrequencyX(float);
+
+ float seed() const;
+ void setSeed(float);
+
+ int numOctaves() const;
+ void setNumOctaves(bool);
+
+ bool stitchTiles() const;
+ void setStitchTiles(bool);
+
+ virtual void apply();
+ virtual void dump();
+
+ virtual void determineAbsolutePaintRect() { setAbsolutePaintRect(maxEffectRect()); }
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ static const int s_blockSize = 256;
+ static const int s_blockMask = s_blockSize - 1;
+
+ struct PaintingData {
+ long seed;
+ int latticeSelector[2 * s_blockSize + 2];
+ float gradient[4][2 * s_blockSize + 2][2];
+ int width; // How much to subtract to wrap for stitching.
+ int height;
+ int wrapX; // Minimum value to wrap.
+ int wrapY;
+ int channel;
+ IntSize filterSize;
+
+ PaintingData(long paintingSeed, const IntSize& paintingSize);
+ inline long random();
+ };
+
+ FETurbulence(Filter*, TurbulanceType, float, float, int, float, bool);
+
+ inline void initPaint(PaintingData&);
+ float noise2D(PaintingData&, const FloatPoint&);
+ unsigned char calculateTurbulenceValueForPoint(PaintingData&, const FloatPoint&);
+
+ TurbulanceType m_type;
+ float m_baseFrequencyX;
+ float m_baseFrequencyY;
+ int m_numOctaves;
+ float m_seed;
+ bool m_stitchTiles;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FETurbulence_h
diff --git a/Source/WebCore/platform/graphics/filters/Filter.h b/Source/WebCore/platform/graphics/filters/Filter.h
new file mode 100644
index 0000000..33cf724
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/Filter.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef Filter_h
+#define Filter_h
+
+#if ENABLE(FILTERS)
+#include "FloatRect.h"
+#include "FloatSize.h"
+#include "ImageBuffer.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+ class FilterEffect;
+
+ class Filter : public RefCounted<Filter> {
+ public:
+ virtual ~Filter() { }
+
+ void setSourceImage(PassOwnPtr<ImageBuffer> sourceImage) { m_sourceImage = sourceImage; }
+ ImageBuffer* sourceImage() { return m_sourceImage.get(); }
+
+ FloatSize filterResolution() const { return m_filterResolution; }
+ void setFilterResolution(const FloatSize& filterResolution) { m_filterResolution = filterResolution; }
+
+ virtual float applyHorizontalScale(float value) const { return value * m_filterResolution.width(); }
+ virtual float applyVerticalScale(float value) const { return value * m_filterResolution.height(); }
+
+ virtual FloatRect sourceImageRect() const = 0;
+ virtual FloatRect filterRegion() const = 0;
+
+ virtual FloatPoint mapAbsolutePointToLocalPoint(const FloatPoint&) const { return FloatPoint(); }
+
+ virtual FloatRect filterRegionInUserSpace() const { return FloatRect(); }
+
+ virtual bool effectBoundingBoxMode() const = 0;
+
+ private:
+ OwnPtr<ImageBuffer> m_sourceImage;
+ FloatSize m_filterResolution;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // Filter_h
diff --git a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp b/Source/WebCore/platform/graphics/filters/FilterEffect.cpp
new file mode 100644
index 0000000..05c2a47
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FilterEffect.cpp
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+
+#include <wtf/ByteArray.h>
+
+namespace WebCore {
+
+FilterEffect::FilterEffect(Filter* filter)
+ : m_alphaImage(false)
+ , m_filter(filter)
+ , m_hasX(false)
+ , m_hasY(false)
+ , m_hasWidth(false)
+ , m_hasHeight(false)
+{
+ ASSERT(m_filter);
+}
+
+FilterEffect::~FilterEffect()
+{
+}
+
+void FilterEffect::determineAbsolutePaintRect()
+{
+ m_absolutePaintRect = IntRect();
+ unsigned size = m_inputEffects.size();
+ for (unsigned i = 0; i < size; ++i)
+ m_absolutePaintRect.unite(m_inputEffects.at(i)->absolutePaintRect());
+
+ // SVG specification wants us to clip to primitive subregion.
+ m_absolutePaintRect.intersect(m_maxEffectRect);
+}
+
+IntRect FilterEffect::requestedRegionOfInputImageData(const IntRect& effectRect) const
+{
+ ASSERT(hasResult());
+ IntPoint location = m_absolutePaintRect.location();
+ location.move(-effectRect.x(), -effectRect.y());
+ return IntRect(location, m_absolutePaintRect.size());
+}
+
+IntRect FilterEffect::drawingRegionOfInputImage(const IntRect& srcRect) const
+{
+ return IntRect(IntPoint(srcRect.x() - m_absolutePaintRect.x(),
+ srcRect.y() - m_absolutePaintRect.y()), srcRect.size());
+}
+
+FilterEffect* FilterEffect::inputEffect(unsigned number) const
+{
+ ASSERT(number < m_inputEffects.size());
+ return m_inputEffects.at(number).get();
+}
+
+ImageBuffer* FilterEffect::asImageBuffer()
+{
+ if (!hasResult())
+ return 0;
+ if (m_imageBufferResult)
+ return m_imageBufferResult.get();
+ m_imageBufferResult = ImageBuffer::create(m_absolutePaintRect.size(), ColorSpaceLinearRGB);
+ IntRect destinationRect(IntPoint(), m_absolutePaintRect.size());
+ if (m_premultipliedImageResult)
+ m_imageBufferResult->putPremultipliedImageData(m_premultipliedImageResult.get(), destinationRect.size(), destinationRect, IntPoint());
+ else
+ m_imageBufferResult->putUnmultipliedImageData(m_unmultipliedImageResult.get(), destinationRect.size(), destinationRect, IntPoint());
+ return m_imageBufferResult.get();
+}
+
+PassRefPtr<ByteArray> FilterEffect::asUnmultipliedImage(const IntRect& rect)
+{
+ RefPtr<ByteArray> imageData = ByteArray::create(rect.width() * rect.height() * 4);
+ copyUnmultipliedImage(imageData.get(), rect);
+ return imageData.release();
+}
+
+PassRefPtr<ByteArray> FilterEffect::asPremultipliedImage(const IntRect& rect)
+{
+ RefPtr<ByteArray> imageData = ByteArray::create(rect.width() * rect.height() * 4);
+ copyPremultipliedImage(imageData.get(), rect);
+ return imageData.release();
+}
+
+inline void FilterEffect::copyImageBytes(ByteArray* source, ByteArray* destination, const IntRect& rect)
+{
+ // Copy the necessary lines.
+ if (rect.x() < 0 || rect.y() < 0 || rect.bottom() > m_absolutePaintRect.width() || rect.bottom() > m_absolutePaintRect.height())
+ memset(destination->data(), 0, destination->length());
+
+ int xOrigin = rect.x();
+ int xDest = 0;
+ if (xOrigin < 0) {
+ xDest = -xOrigin;
+ xOrigin = 0;
+ }
+ int xEnd = rect.right();
+ if (xEnd > m_absolutePaintRect.width())
+ xEnd = m_absolutePaintRect.width();
+
+ int yOrigin = rect.y();
+ int yDest = 0;
+ if (yOrigin < 0) {
+ yDest = -yOrigin;
+ yOrigin = 0;
+ }
+ int yEnd = rect.bottom();
+ if (yEnd > m_absolutePaintRect.height())
+ yEnd = m_absolutePaintRect.height();
+
+ int size = (xEnd - xOrigin) * 4;
+ int destinationScanline = rect.width() * 4;
+ int sourceScanline = m_absolutePaintRect.width() * 4;
+ unsigned char *destinationPixel = destination->data() + ((yDest * rect.width()) + xDest) * 4;
+ unsigned char *sourcePixel = source->data() + ((yOrigin * m_absolutePaintRect.width()) + xOrigin) * 4;
+
+ while (yOrigin < yEnd) {
+ memcpy(destinationPixel, sourcePixel, size);
+ destinationPixel += destinationScanline;
+ sourcePixel += sourceScanline;
+ ++yOrigin;
+ }
+}
+
+void FilterEffect::copyUnmultipliedImage(ByteArray* destination, const IntRect& rect)
+{
+ ASSERT(hasResult());
+
+ if (!m_unmultipliedImageResult) {
+ // We prefer a conversion from the image buffer.
+ if (m_imageBufferResult)
+ m_unmultipliedImageResult = m_imageBufferResult->getUnmultipliedImageData(IntRect(IntPoint(), m_absolutePaintRect.size()));
+ else {
+ m_unmultipliedImageResult = ByteArray::create(m_absolutePaintRect.width() * m_absolutePaintRect.height() * 4);
+ unsigned char* sourceComponent = m_premultipliedImageResult->data();
+ unsigned char* destinationComponent = m_unmultipliedImageResult->data();
+ unsigned char* end = sourceComponent + (m_absolutePaintRect.width() * m_absolutePaintRect.height() * 4);
+ while (sourceComponent < end) {
+ int alpha = sourceComponent[3];
+ if (alpha) {
+ destinationComponent[0] = static_cast<int>(sourceComponent[0]) * 255 / alpha;
+ destinationComponent[1] = static_cast<int>(sourceComponent[1]) * 255 / alpha;
+ destinationComponent[2] = static_cast<int>(sourceComponent[2]) * 255 / alpha;
+ } else {
+ destinationComponent[0] = 0;
+ destinationComponent[1] = 0;
+ destinationComponent[2] = 0;
+ }
+ destinationComponent[3] = alpha;
+ sourceComponent += 4;
+ destinationComponent += 4;
+ }
+ }
+ }
+ copyImageBytes(m_unmultipliedImageResult.get(), destination, rect);
+}
+
+void FilterEffect::copyPremultipliedImage(ByteArray* destination, const IntRect& rect)
+{
+ ASSERT(hasResult());
+
+ if (!m_premultipliedImageResult) {
+ // We prefer a conversion from the image buffer.
+ if (m_imageBufferResult)
+ m_premultipliedImageResult = m_imageBufferResult->getPremultipliedImageData(IntRect(IntPoint(), m_absolutePaintRect.size()));
+ else {
+ m_premultipliedImageResult = ByteArray::create(m_absolutePaintRect.width() * m_absolutePaintRect.height() * 4);
+ unsigned char* sourceComponent = m_unmultipliedImageResult->data();
+ unsigned char* destinationComponent = m_premultipliedImageResult->data();
+ unsigned char* end = sourceComponent + (m_absolutePaintRect.width() * m_absolutePaintRect.height() * 4);
+ while (sourceComponent < end) {
+ int alpha = sourceComponent[3];
+ destinationComponent[0] = static_cast<int>(sourceComponent[0]) * alpha / 255;
+ destinationComponent[1] = static_cast<int>(sourceComponent[1]) * alpha / 255;
+ destinationComponent[2] = static_cast<int>(sourceComponent[2]) * alpha / 255;
+ destinationComponent[3] = alpha;
+ sourceComponent += 4;
+ destinationComponent += 4;
+ }
+ }
+ }
+ copyImageBytes(m_premultipliedImageResult.get(), destination, rect);
+}
+
+ImageBuffer* FilterEffect::createImageBufferResult()
+{
+ // Only one result type is allowed.
+ ASSERT(!hasResult());
+ determineAbsolutePaintRect();
+ if (m_absolutePaintRect.isEmpty())
+ return 0;
+ m_imageBufferResult = ImageBuffer::create(m_absolutePaintRect.size(), ColorSpaceLinearRGB);
+ if (!m_imageBufferResult)
+ return 0;
+ ASSERT(m_imageBufferResult->context());
+ return m_imageBufferResult.get();
+}
+
+ByteArray* FilterEffect::createUnmultipliedImageResult()
+{
+ // Only one result type is allowed.
+ ASSERT(!hasResult());
+ determineAbsolutePaintRect();
+ if (m_absolutePaintRect.isEmpty())
+ return 0;
+ m_unmultipliedImageResult = ByteArray::create(m_absolutePaintRect.width() * m_absolutePaintRect.height() * 4);
+ return m_unmultipliedImageResult.get();
+}
+
+ByteArray* FilterEffect::createPremultipliedImageResult()
+{
+ // Only one result type is allowed.
+ ASSERT(!hasResult());
+ determineAbsolutePaintRect();
+ if (m_absolutePaintRect.isEmpty())
+ return 0;
+ m_premultipliedImageResult = ByteArray::create(m_absolutePaintRect.width() * m_absolutePaintRect.height() * 4);
+ return m_premultipliedImageResult.get();
+}
+
+TextStream& FilterEffect::externalRepresentation(TextStream& ts, int) const
+{
+ // FIXME: We should dump the subRegions of the filter primitives here later. This isn't
+ // possible at the moment, because we need more detailed informations from the target object.
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/FilterEffect.h b/Source/WebCore/platform/graphics/filters/FilterEffect.h
new file mode 100644
index 0000000..2554d4b
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/FilterEffect.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FilterEffect_h
+#define FilterEffect_h
+
+#if ENABLE(FILTERS)
+#include "Filter.h"
+#include "FloatRect.h"
+#include "GraphicsContext.h"
+#include "ImageBuffer.h"
+#include "RenderTreeAsText.h"
+#include "TextStream.h"
+
+#include <wtf/PassOwnPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+typedef Vector<RefPtr<FilterEffect> > FilterEffectVector;
+
+enum FilterEffectType {
+ FilterEffectTypeUnknown,
+ FilterEffectTypeImage,
+ FilterEffectTypeTile,
+ FilterEffectTypeSourceInput
+};
+
+class FilterEffect : public RefCounted<FilterEffect> {
+public:
+ virtual ~FilterEffect();
+
+ bool hasResult() const { return m_imageBufferResult || m_unmultipliedImageResult || m_premultipliedImageResult; }
+ ImageBuffer* asImageBuffer();
+ PassRefPtr<ByteArray> asUnmultipliedImage(const IntRect&);
+ PassRefPtr<ByteArray> asPremultipliedImage(const IntRect&);
+ void copyUnmultipliedImage(ByteArray* destination, const IntRect&);
+ void copyPremultipliedImage(ByteArray* destination, const IntRect&);
+
+ FilterEffectVector& inputEffects() { return m_inputEffects; }
+ FilterEffect* inputEffect(unsigned) const;
+ unsigned numberOfEffectInputs() const { return m_inputEffects.size(); }
+
+ IntRect drawingRegionOfInputImage(const IntRect&) const;
+ IntRect requestedRegionOfInputImageData(const IntRect&) const;
+
+ // Solid black image with different alpha values.
+ bool isAlphaImage() const { return m_alphaImage; }
+ void setIsAlphaImage(bool alphaImage) { m_alphaImage = alphaImage; }
+
+ IntRect absolutePaintRect() const { return m_absolutePaintRect; }
+ void setAbsolutePaintRect(const IntRect& absolutePaintRect) { m_absolutePaintRect = absolutePaintRect; }
+
+ IntRect maxEffectRect() const { return m_maxEffectRect; }
+ void setMaxEffectRect(const IntRect& maxEffectRect) { m_maxEffectRect = maxEffectRect; }
+
+ virtual void apply() = 0;
+ virtual void dump() = 0;
+
+ virtual void determineAbsolutePaintRect();
+
+ virtual FilterEffectType filterEffectType() const { return FilterEffectTypeUnknown; }
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention = 0) const;
+
+public:
+ // The following functions are SVG specific and will move to RenderSVGResourceFilterPrimitive.
+ // See bug https://bugs.webkit.org/show_bug.cgi?id=45614.
+ bool hasX() const { return m_hasX; }
+ void setHasX(bool value) { m_hasX = value; }
+
+ bool hasY() const { return m_hasY; }
+ void setHasY(bool value) { m_hasY = value; }
+
+ bool hasWidth() const { return m_hasWidth; }
+ void setHasWidth(bool value) { m_hasWidth = value; }
+
+ bool hasHeight() const { return m_hasHeight; }
+ void setHasHeight(bool value) { m_hasHeight = value; }
+
+ FloatRect filterPrimitiveSubregion() const { return m_filterPrimitiveSubregion; }
+ void setFilterPrimitiveSubregion(const FloatRect& filterPrimitiveSubregion) { m_filterPrimitiveSubregion = filterPrimitiveSubregion; }
+
+ FloatRect effectBoundaries() const { return m_effectBoundaries; }
+ void setEffectBoundaries(const FloatRect& effectBoundaries) { m_effectBoundaries = effectBoundaries; }
+
+ Filter* filter() { return m_filter; }
+
+protected:
+ FilterEffect(Filter*);
+
+ ImageBuffer* createImageBufferResult();
+ ByteArray* createUnmultipliedImageResult();
+ ByteArray* createPremultipliedImageResult();
+
+private:
+ OwnPtr<ImageBuffer> m_imageBufferResult;
+ RefPtr<ByteArray> m_unmultipliedImageResult;
+ RefPtr<ByteArray> m_premultipliedImageResult;
+ FilterEffectVector m_inputEffects;
+
+ bool m_alphaImage;
+
+ IntRect m_absolutePaintRect;
+
+ // The maximum size of a filter primitive. In SVG this is the primitive subregion in absolute coordinate space.
+ // The absolute paint rect should never be bigger than m_maxEffectRect.
+ IntRect m_maxEffectRect;
+ Filter* m_filter;
+
+private:
+ inline void copyImageBytes(ByteArray* source, ByteArray* destination, const IntRect&);
+
+ // The following member variables are SVG specific and will move to RenderSVGResourceFilterPrimitive.
+ // See bug https://bugs.webkit.org/show_bug.cgi?id=45614.
+
+ // The subregion of a filter primitive according to the SVG Filter specification in local coordinates.
+ // This is SVG specific and needs to move to RenderSVGResourceFilterPrimitive.
+ FloatRect m_filterPrimitiveSubregion;
+
+ // x, y, width and height of the actual SVGFE*Element. Is needed to determine the subregion of the
+ // filter primitive on a later step.
+ FloatRect m_effectBoundaries;
+ bool m_hasX;
+ bool m_hasY;
+ bool m_hasWidth;
+ bool m_hasHeight;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FilterEffect_h
diff --git a/Source/WebCore/platform/graphics/filters/LightSource.cpp b/Source/WebCore/platform/graphics/filters/LightSource.cpp
new file mode 100644
index 0000000..de0691e
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/LightSource.cpp
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2010 Zoltan Herczeg <zherczeg@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "LightSource.h"
+
+#include "DistantLightSource.h"
+#include "PointLightSource.h"
+#include "RenderTreeAsText.h"
+#include "SpotLightSource.h"
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+void PointLightSource::initPaintingData(PaintingData&)
+{
+}
+
+void PointLightSource::updatePaintingData(PaintingData& paintingData, int x, int y, float z)
+{
+ paintingData.lightVector.setX(m_position.x() - x);
+ paintingData.lightVector.setY(m_position.y() - y);
+ paintingData.lightVector.setZ(m_position.z() - z);
+ paintingData.lightVectorLength = paintingData.lightVector.length();
+}
+
+// spot-light edge darkening depends on an absolute treshold
+// according to the SVG 1.1 SE light regression tests
+static const float antiAliasTreshold = 0.016f;
+
+void SpotLightSource::initPaintingData(PaintingData& paintingData)
+{
+ paintingData.privateColorVector = paintingData.colorVector;
+ paintingData.directionVector.setX(m_direction.x() - m_position.x());
+ paintingData.directionVector.setY(m_direction.y() - m_position.y());
+ paintingData.directionVector.setZ(m_direction.z() - m_position.z());
+ paintingData.directionVector.normalize();
+
+ if (!m_limitingConeAngle) {
+ paintingData.coneCutOffLimit = 0.0f;
+ paintingData.coneFullLight = -antiAliasTreshold;
+ } else {
+ float limitingConeAngle = m_limitingConeAngle;
+ if (limitingConeAngle < 0.0f)
+ limitingConeAngle = -limitingConeAngle;
+ if (limitingConeAngle > 90.0f)
+ limitingConeAngle = 90.0f;
+ paintingData.coneCutOffLimit = cosf(deg2rad(180.0f - limitingConeAngle));
+ paintingData.coneFullLight = paintingData.coneCutOffLimit - antiAliasTreshold;
+ }
+
+ // Optimization for common specularExponent values
+ if (!m_specularExponent)
+ paintingData.specularExponent = 0;
+ else if (m_specularExponent == 1.0f)
+ paintingData.specularExponent = 1;
+ else // It is neither 0.0f nor 1.0f
+ paintingData.specularExponent = 2;
+}
+
+void SpotLightSource::updatePaintingData(PaintingData& paintingData, int x, int y, float z)
+{
+ paintingData.lightVector.setX(m_position.x() - x);
+ paintingData.lightVector.setY(m_position.y() - y);
+ paintingData.lightVector.setZ(m_position.z() - z);
+ paintingData.lightVectorLength = paintingData.lightVector.length();
+
+ float cosineOfAngle = (paintingData.lightVector * paintingData.directionVector) / paintingData.lightVectorLength;
+ if (cosineOfAngle > paintingData.coneCutOffLimit) {
+ // No light is produced, scanlines are not updated
+ paintingData.colorVector.setX(0.0f);
+ paintingData.colorVector.setY(0.0f);
+ paintingData.colorVector.setZ(0.0f);
+ return;
+ }
+
+ // Set the color of the pixel
+ float lightStrength;
+ switch (paintingData.specularExponent) {
+ case 0:
+ lightStrength = 1.0f; // -cosineOfAngle ^ 0 == 1
+ break;
+ case 1:
+ lightStrength = -cosineOfAngle; // -cosineOfAngle ^ 1 == -cosineOfAngle
+ break;
+ default:
+ lightStrength = powf(-cosineOfAngle, m_specularExponent);
+ break;
+ }
+
+ if (cosineOfAngle > paintingData.coneFullLight)
+ lightStrength *= (paintingData.coneCutOffLimit - cosineOfAngle) / (paintingData.coneCutOffLimit - paintingData.coneFullLight);
+
+ if (lightStrength > 1.0f)
+ lightStrength = 1.0f;
+
+ paintingData.colorVector.setX(paintingData.privateColorVector.x() * lightStrength);
+ paintingData.colorVector.setY(paintingData.privateColorVector.y() * lightStrength);
+ paintingData.colorVector.setZ(paintingData.privateColorVector.z() * lightStrength);
+}
+
+void DistantLightSource::initPaintingData(PaintingData& paintingData)
+{
+ float azimuth = deg2rad(m_azimuth);
+ float elevation = deg2rad(m_elevation);
+ paintingData.lightVector.setX(cosf(azimuth) * cosf(elevation));
+ paintingData.lightVector.setY(sinf(azimuth) * cosf(elevation));
+ paintingData.lightVector.setZ(sinf(elevation));
+ paintingData.lightVectorLength = 1;
+}
+
+void DistantLightSource::updatePaintingData(PaintingData&, int, int, float)
+{
+}
+
+static TextStream& operator<<(TextStream& ts, const FloatPoint3D& p)
+{
+ ts << "x=" << p.x() << " y=" << p.y() << " z=" << p.z();
+ return ts;
+}
+
+TextStream& PointLightSource::externalRepresentation(TextStream& ts) const
+{
+ ts << "[type=POINT-LIGHT] ";
+ ts << "[position=\"" << position() << "\"]";
+ return ts;
+}
+
+TextStream& SpotLightSource::externalRepresentation(TextStream& ts) const
+{
+ ts << "[type=SPOT-LIGHT] ";
+ ts << "[position=\"" << position() << "\"]";
+ ts << "[direction=\"" << direction() << "\"]";
+ ts << "[specularExponent=\"" << specularExponent() << "\"]";
+ ts << "[limitingConeAngle=\"" << limitingConeAngle() << "\"]";
+ return ts;
+}
+
+TextStream& DistantLightSource::externalRepresentation(TextStream& ts) const
+{
+ ts << "[type=DISTANT-LIGHT] ";
+ ts << "[azimuth=\"" << azimuth() << "\"]";
+ ts << "[elevation=\"" << elevation() << "\"]";
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/LightSource.h b/Source/WebCore/platform/graphics/filters/LightSource.h
new file mode 100644
index 0000000..013e910
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/LightSource.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2010 Zoltan Herczeg <zherczeg@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef LightSource_h
+#define LightSource_h
+
+#if ENABLE(FILTERS)
+#include "FloatPoint3D.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+enum LightType {
+ LS_DISTANT,
+ LS_POINT,
+ LS_SPOT
+};
+
+class TextStream;
+
+class LightSource : public RefCounted<LightSource> {
+public:
+
+ // Light vectors must be calculated for every pixel during
+ // painting. It is expensive to pass all these arguments to
+ // a frequently called function, especially because not all
+ // light sources require all of them. Instead, we just pass
+ // a reference to the following structure
+ struct PaintingData {
+ // SVGFELighting also use them
+ FloatPoint3D lightVector;
+ FloatPoint3D colorVector;
+ float lightVectorLength;
+ // Private members
+ FloatPoint3D directionVector;
+ FloatPoint3D privateColorVector;
+ float coneCutOffLimit;
+ float coneFullLight;
+ int specularExponent;
+ };
+
+ LightSource(LightType type)
+ : m_type(type)
+ { }
+
+ virtual ~LightSource() { }
+
+ LightType type() const { return m_type; }
+ virtual TextStream& externalRepresentation(TextStream&) const = 0;
+
+ virtual void initPaintingData(PaintingData&) = 0;
+ // z is a float number, since it is the alpha value scaled by a user
+ // specified "surfaceScale" constant, which type is <number> in the SVG standard
+ virtual void updatePaintingData(PaintingData&, int x, int y, float z) = 0;
+
+private:
+ LightType m_type;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // LightSource_h
diff --git a/Source/WebCore/platform/graphics/filters/PointLightSource.h b/Source/WebCore/platform/graphics/filters/PointLightSource.h
new file mode 100644
index 0000000..163c829
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/PointLightSource.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PointLightSource_h
+#define PointLightSource_h
+
+#if ENABLE(FILTERS)
+#include "LightSource.h"
+
+namespace WebCore {
+
+class PointLightSource : public LightSource {
+public:
+ static PassRefPtr<PointLightSource> create(const FloatPoint3D& position)
+ {
+ return adoptRef(new PointLightSource(position));
+ }
+
+ const FloatPoint3D& position() const { return m_position; }
+
+ virtual void initPaintingData(PaintingData&);
+ virtual void updatePaintingData(PaintingData&, int x, int y, float z);
+
+ virtual TextStream& externalRepresentation(TextStream&) const;
+
+private:
+ PointLightSource(const FloatPoint3D& position)
+ : LightSource(LS_POINT)
+ , m_position(position)
+ {
+ }
+
+ FloatPoint3D m_position;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // PointLightSource_h
diff --git a/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp b/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp
new file mode 100644
index 0000000..2d2de00
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "SourceAlpha.h"
+
+#include "Color.h"
+#include "GraphicsContext.h"
+#include "PlatformString.h"
+#include "Filter.h"
+
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+PassRefPtr<SourceAlpha> SourceAlpha::create(Filter* filter)
+{
+ return adoptRef(new SourceAlpha(filter));
+}
+
+const AtomicString& SourceAlpha::effectName()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, s_effectName, ("SourceAlpha"));
+ return s_effectName;
+}
+
+void SourceAlpha::determineAbsolutePaintRect()
+{
+ Filter* filter = this->filter();
+ FloatRect paintRect = filter->sourceImageRect();
+ paintRect.scale(filter->filterResolution().width(), filter->filterResolution().height());
+ setAbsolutePaintRect(enclosingIntRect(paintRect));
+}
+
+void SourceAlpha::apply()
+{
+ if (hasResult())
+ return;
+ ImageBuffer* resultImage = createImageBufferResult();
+ Filter* filter = this->filter();
+ if (!resultImage || !filter->sourceImage())
+ return;
+
+ setIsAlphaImage(true);
+
+ FloatRect imageRect(FloatPoint(), absolutePaintRect().size());
+ GraphicsContext* filterContext = resultImage->context();
+ filterContext->save();
+ filterContext->clipToImageBuffer(filter->sourceImage(), imageRect);
+ filterContext->fillRect(imageRect, Color::black, ColorSpaceDeviceRGB);
+ filterContext->restore();
+}
+
+void SourceAlpha::dump()
+{
+}
+
+TextStream& SourceAlpha::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[SourceAlpha]\n";
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/SourceAlpha.h b/Source/WebCore/platform/graphics/filters/SourceAlpha.h
new file mode 100644
index 0000000..c6f95d3
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/SourceAlpha.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SourceAlpha_h
+#define SourceAlpha_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+
+#include "PlatformString.h"
+#include "Filter.h"
+
+namespace WebCore {
+
+class SourceAlpha : public FilterEffect {
+public:
+ static PassRefPtr<SourceAlpha> create(Filter*);
+
+ static const AtomicString& effectName();
+
+ virtual void apply();
+ virtual void dump();
+
+ virtual void determineAbsolutePaintRect();
+
+ virtual FilterEffectType filterEffectType() const { return FilterEffectTypeSourceInput; }
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ SourceAlpha(Filter* filter)
+ : FilterEffect(filter)
+ {
+ }
+};
+
+} //namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // SourceAlpha_h
diff --git a/Source/WebCore/platform/graphics/filters/SourceGraphic.cpp b/Source/WebCore/platform/graphics/filters/SourceGraphic.cpp
new file mode 100644
index 0000000..04082ad
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/SourceGraphic.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "SourceGraphic.h"
+
+#include "GraphicsContext.h"
+#include "PlatformString.h"
+#include "Filter.h"
+
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+PassRefPtr<SourceGraphic> SourceGraphic::create(Filter* filter)
+{
+ return adoptRef(new SourceGraphic(filter));
+}
+
+const AtomicString& SourceGraphic::effectName()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, s_effectName, ("SourceGraphic"));
+ return s_effectName;
+}
+
+void SourceGraphic::determineAbsolutePaintRect()
+{
+ Filter* filter = this->filter();
+ FloatRect paintRect = filter->sourceImageRect();
+ paintRect.scale(filter->filterResolution().width(), filter->filterResolution().height());
+ setAbsolutePaintRect(enclosingIntRect(paintRect));
+}
+
+void SourceGraphic::apply()
+{
+ if (hasResult())
+ return;
+ ImageBuffer* resultImage = createImageBufferResult();
+ Filter* filter = this->filter();
+ if (!resultImage || !filter->sourceImage())
+ return;
+
+ resultImage->context()->drawImageBuffer(filter->sourceImage(), ColorSpaceDeviceRGB, IntPoint());
+}
+
+void SourceGraphic::dump()
+{
+}
+
+TextStream& SourceGraphic::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[SourceGraphic]\n";
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/Source/WebCore/platform/graphics/filters/SourceGraphic.h b/Source/WebCore/platform/graphics/filters/SourceGraphic.h
new file mode 100644
index 0000000..97d6882
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/SourceGraphic.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SourceGraphic_h
+#define SourceGraphic_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+
+#include "Filter.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class SourceGraphic : public FilterEffect {
+public:
+ static PassRefPtr<SourceGraphic> create(Filter*);
+
+ static const AtomicString& effectName();
+
+ virtual void apply();
+ virtual void dump();
+
+ virtual void determineAbsolutePaintRect();
+
+ virtual FilterEffectType filterEffectType() const { return FilterEffectTypeSourceInput; }
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ SourceGraphic(Filter* filter)
+ : FilterEffect(filter)
+ {
+ }
+};
+
+} //namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // SourceGraphic_h
diff --git a/Source/WebCore/platform/graphics/filters/SpotLightSource.h b/Source/WebCore/platform/graphics/filters/SpotLightSource.h
new file mode 100644
index 0000000..cd6a614
--- /dev/null
+++ b/Source/WebCore/platform/graphics/filters/SpotLightSource.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SpotLightSource_h
+#define SpotLightSource_h
+
+#if ENABLE(FILTERS)
+#include "LightSource.h"
+
+namespace WebCore {
+
+class SpotLightSource : public LightSource {
+public:
+ static PassRefPtr<SpotLightSource> create(const FloatPoint3D& position,
+ const FloatPoint3D& direction, float specularExponent, float limitingConeAngle)
+ {
+ return adoptRef(new SpotLightSource(position, direction, specularExponent, limitingConeAngle));
+ }
+
+ const FloatPoint3D& position() const { return m_position; }
+ const FloatPoint3D& direction() const { return m_direction; }
+
+ float specularExponent() const { return m_specularExponent; }
+ float limitingConeAngle() const { return m_limitingConeAngle; }
+
+ virtual void initPaintingData(PaintingData&);
+ virtual void updatePaintingData(PaintingData&, int x, int y, float z);
+
+ virtual TextStream& externalRepresentation(TextStream&) const;
+
+private:
+ SpotLightSource(const FloatPoint3D& position, const FloatPoint3D& direction,
+ float specularExponent, float limitingConeAngle)
+ : LightSource(LS_SPOT)
+ , m_position(position)
+ , m_direction(direction)
+ , m_specularExponent(specularExponent)
+ , m_limitingConeAngle(limitingConeAngle)
+ {
+ }
+
+ FloatPoint3D m_position;
+ FloatPoint3D m_direction;
+
+ float m_specularExponent;
+ float m_limitingConeAngle;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // SpotLightSource_h