summaryrefslogtreecommitdiffstats
path: root/WebCore/svg/graphics
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2010-05-21 16:53:46 +0100
committerKristian Monsen <kristianm@google.com>2010-05-25 10:24:15 +0100
commit6c2af9490927c3c5959b5cb07461b646f8b32f6c (patch)
treef7111b9b22befab472616c1d50ec94eb50f1ec8c /WebCore/svg/graphics
parenta149172322a9067c14e8b474a53e63649aa17cad (diff)
downloadexternal_webkit-6c2af9490927c3c5959b5cb07461b646f8b32f6c.zip
external_webkit-6c2af9490927c3c5959b5cb07461b646f8b32f6c.tar.gz
external_webkit-6c2af9490927c3c5959b5cb07461b646f8b32f6c.tar.bz2
Merge WebKit at r59636: Initial merge by git
Change-Id: I59b289c4e6b18425f06ce41cc9d34c522515de91
Diffstat (limited to 'WebCore/svg/graphics')
-rw-r--r--WebCore/svg/graphics/filters/SVGDistantLightSource.h49
-rw-r--r--WebCore/svg/graphics/filters/SVGFEConvolveMatrix.cpp47
-rw-r--r--WebCore/svg/graphics/filters/SVGFEConvolveMatrix.h2
-rw-r--r--WebCore/svg/graphics/filters/SVGFEDiffuseLighting.cpp37
-rw-r--r--WebCore/svg/graphics/filters/SVGFEDiffuseLighting.h80
-rw-r--r--WebCore/svg/graphics/filters/SVGFEDisplacementMap.cpp43
-rw-r--r--WebCore/svg/graphics/filters/SVGFEDisplacementMap.h2
-rw-r--r--WebCore/svg/graphics/filters/SVGFEFlood.cpp9
-rw-r--r--WebCore/svg/graphics/filters/SVGFEFlood.h2
-rw-r--r--WebCore/svg/graphics/filters/SVGFEImage.cpp8
-rw-r--r--WebCore/svg/graphics/filters/SVGFEImage.h2
-rw-r--r--WebCore/svg/graphics/filters/SVGFELighting.cpp272
-rw-r--r--WebCore/svg/graphics/filters/SVGFELighting.h100
-rw-r--r--WebCore/svg/graphics/filters/SVGFEMerge.cpp19
-rw-r--r--WebCore/svg/graphics/filters/SVGFEMerge.h2
-rw-r--r--WebCore/svg/graphics/filters/SVGFEMorphology.cpp30
-rw-r--r--WebCore/svg/graphics/filters/SVGFEMorphology.h2
-rw-r--r--WebCore/svg/graphics/filters/SVGFEOffset.cpp8
-rw-r--r--WebCore/svg/graphics/filters/SVGFEOffset.h2
-rw-r--r--WebCore/svg/graphics/filters/SVGFESpecularLighting.cpp39
-rw-r--r--WebCore/svg/graphics/filters/SVGFESpecularLighting.h66
-rw-r--r--WebCore/svg/graphics/filters/SVGFETile.cpp8
-rw-r--r--WebCore/svg/graphics/filters/SVGFETile.h2
-rw-r--r--WebCore/svg/graphics/filters/SVGFETurbulence.cpp38
-rw-r--r--WebCore/svg/graphics/filters/SVGFETurbulence.h2
-rw-r--r--WebCore/svg/graphics/filters/SVGLightSource.cpp105
-rw-r--r--WebCore/svg/graphics/filters/SVGLightSource.h57
-rw-r--r--WebCore/svg/graphics/filters/SVGPointLightSource.h36
-rw-r--r--WebCore/svg/graphics/filters/SVGSpotLightSource.h70
29 files changed, 815 insertions, 324 deletions
diff --git a/WebCore/svg/graphics/filters/SVGDistantLightSource.h b/WebCore/svg/graphics/filters/SVGDistantLightSource.h
index db9b59d..97853db 100644
--- a/WebCore/svg/graphics/filters/SVGDistantLightSource.h
+++ b/WebCore/svg/graphics/filters/SVGDistantLightSource.h
@@ -28,29 +28,32 @@
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 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;
- };
+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
diff --git a/WebCore/svg/graphics/filters/SVGFEConvolveMatrix.cpp b/WebCore/svg/graphics/filters/SVGFEConvolveMatrix.cpp
index 5197215..916b2f9 100644
--- a/WebCore/svg/graphics/filters/SVGFEConvolveMatrix.cpp
+++ b/WebCore/svg/graphics/filters/SVGFEConvolveMatrix.cpp
@@ -142,34 +142,41 @@ void FEConvolveMatrix::dump()
{
}
-static TextStream& operator<<(TextStream& ts, EdgeModeType t)
+static TextStream& operator<<(TextStream& ts, const EdgeModeType& type)
{
- switch (t)
+ 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;
+ 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) const
+TextStream& FEConvolveMatrix::externalRepresentation(TextStream& ts, int indent) const
{
- ts << "[type=CONVOLVE-MATRIX] ";
+ writeIndent(ts, indent);
+ ts << "[feConvolveMatrix";
FilterEffect::externalRepresentation(ts);
- ts << " [order " << m_kernelSize << "]"
- << " [kernel matrix=" << m_kernelMatrix << "]"
- << " [divisor=" << m_divisor << "]"
- << " [bias=" << m_bias << "]"
- << " [target " << m_targetOffset << "]"
- << " [edge mode=" << m_edgeMode << "]"
- << " [kernel unit length " << m_kernelUnitLength << "]"
- << " [preserve alpha=" << m_preserveAlpha << "]";
+ 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";
+ m_in->externalRepresentation(ts, indent + 1);
+ m_in2->externalRepresentation(ts, indent + 1);
return ts;
}
diff --git a/WebCore/svg/graphics/filters/SVGFEConvolveMatrix.h b/WebCore/svg/graphics/filters/SVGFEConvolveMatrix.h
index f850412..8e3a9bd 100644
--- a/WebCore/svg/graphics/filters/SVGFEConvolveMatrix.h
+++ b/WebCore/svg/graphics/filters/SVGFEConvolveMatrix.h
@@ -71,7 +71,7 @@ namespace WebCore {
virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return calculateUnionOfChildEffectSubregions(filter, m_in.get(), m_in2.get()); }
void apply(Filter*);
void dump();
- TextStream& externalRepresentation(TextStream& ts) const;
+ TextStream& externalRepresentation(TextStream&, int indent) const;
private:
FEConvolveMatrix(FilterEffect*, FilterEffect*, const FloatSize&, const float&, const float&,
diff --git a/WebCore/svg/graphics/filters/SVGFEDiffuseLighting.cpp b/WebCore/svg/graphics/filters/SVGFEDiffuseLighting.cpp
index 93921df..f8d0b4e 100644
--- a/WebCore/svg/graphics/filters/SVGFEDiffuseLighting.cpp
+++ b/WebCore/svg/graphics/filters/SVGFEDiffuseLighting.cpp
@@ -22,29 +22,22 @@
#include "config.h"
#if ENABLE(SVG) && ENABLE(FILTERS)
-#include "SVGLightSource.h"
#include "SVGFEDiffuseLighting.h"
+
+#include "SVGLightSource.h"
#include "SVGRenderTreeAsText.h"
-#include "Filter.h"
namespace WebCore {
-FEDiffuseLighting::FEDiffuseLighting(FilterEffect* in , const Color& lightingColor, const float& surfaceScale,
- const float& diffuseConstant, const float& kernelUnitLengthX, const float& kernelUnitLengthY, PassRefPtr<LightSource> lightSource)
- : FilterEffect()
- , m_in(in)
- , m_lightingColor(lightingColor)
- , m_surfaceScale(surfaceScale)
- , m_diffuseConstant(diffuseConstant)
- , m_kernelUnitLengthX(kernelUnitLengthX)
- , m_kernelUnitLengthY(kernelUnitLengthY)
- , m_lightSource(lightSource)
+FEDiffuseLighting::FEDiffuseLighting(FilterEffect* in, const Color& lightingColor, float surfaceScale,
+ float diffuseConstant, float kernelUnitLengthX, float kernelUnitLengthY, PassRefPtr<LightSource> lightSource)
+ : FELighting(DiffuseLighting, in, lightingColor, surfaceScale, diffuseConstant, 0.0f, 0.0f, kernelUnitLengthX, kernelUnitLengthY, lightSource)
{
}
PassRefPtr<FEDiffuseLighting> FEDiffuseLighting::create(FilterEffect* in , const Color& lightingColor,
- const float& surfaceScale, const float& diffuseConstant, const float& kernelUnitLengthX,
- const float& kernelUnitLengthY, PassRefPtr<LightSource> lightSource)
+ float surfaceScale, float diffuseConstant, float kernelUnitLengthX,
+ float kernelUnitLengthY, PassRefPtr<LightSource> lightSource)
{
return adoptRef(new FEDiffuseLighting(in, lightingColor, surfaceScale, diffuseConstant, kernelUnitLengthX, kernelUnitLengthY, lightSource));
}
@@ -113,21 +106,19 @@ void FEDiffuseLighting::setLightSource(PassRefPtr<LightSource> lightSource)
m_lightSource = lightSource;
}
-void FEDiffuseLighting::apply(Filter*)
-{
-}
-
void FEDiffuseLighting::dump()
{
}
-TextStream& FEDiffuseLighting::externalRepresentation(TextStream& ts) const
+TextStream& FEDiffuseLighting::externalRepresentation(TextStream& ts, int indent) const
{
- ts << "[type=DIFFUSE-LIGHTING] ";
+ writeIndent(ts, indent);
+ ts << "[feDiffuseLighting";
FilterEffect::externalRepresentation(ts);
- ts << " [surface scale=" << m_surfaceScale << "]"
- << " [diffuse constant=" << m_diffuseConstant << "]"
- << " [kernel unit length " << m_kernelUnitLengthX << ", " << m_kernelUnitLengthY << "]";
+ ts << " surfaceScale=\"" << m_surfaceScale << "\" "
+ << "diffuseConstant=\"" << m_diffuseConstant << "\" "
+ << "kernelUnitLength=\"" << m_kernelUnitLengthX << ", " << m_kernelUnitLengthY << "\"]\n";
+ m_in->externalRepresentation(ts, indent + 1);
return ts;
}
diff --git a/WebCore/svg/graphics/filters/SVGFEDiffuseLighting.h b/WebCore/svg/graphics/filters/SVGFEDiffuseLighting.h
index bf7f28e..3fccb19 100644
--- a/WebCore/svg/graphics/filters/SVGFEDiffuseLighting.h
+++ b/WebCore/svg/graphics/filters/SVGFEDiffuseLighting.h
@@ -23,55 +23,43 @@
#define SVGFEDiffuseLighting_h
#if ENABLE(SVG) && ENABLE(FILTERS)
-#include "Color.h"
-#include "FilterEffect.h"
-#include "Filter.h"
+#include "SVGFELighting.h"
namespace WebCore {
- class LightSource;
-
- class FEDiffuseLighting : public FilterEffect {
- public:
- static PassRefPtr<FEDiffuseLighting> create(FilterEffect*, const Color&, const float&, const float&,
- const float&, const 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 FloatRect uniteChildEffectSubregions(Filter* filter) { return calculateUnionOfChildEffectSubregions(filter, m_in.get()); }
- void apply(Filter*);
- void dump();
- TextStream& externalRepresentation(TextStream& ts) const;
-
- private:
- FEDiffuseLighting(FilterEffect*, const Color&, const float&, const float&,
- const float&, const float&, PassRefPtr<LightSource>);
-
- RefPtr<FilterEffect> m_in;
- Color m_lightingColor;
- float m_surfaceScale;
- float m_diffuseConstant;
- float m_kernelUnitLengthX;
- float m_kernelUnitLengthY;
- RefPtr<LightSource> m_lightSource;
- };
+class LightSource;
+
+class FEDiffuseLighting : public FELighting {
+public:
+ static PassRefPtr<FEDiffuseLighting> create(FilterEffect*, 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>);
+
+ void dump();
+ TextStream& externalRepresentation(TextStream&, int indent) const;
+
+private:
+ FEDiffuseLighting(FilterEffect*, const Color&, float, float,
+ float, float, PassRefPtr<LightSource>);
+};
} // namespace WebCore
diff --git a/WebCore/svg/graphics/filters/SVGFEDisplacementMap.cpp b/WebCore/svg/graphics/filters/SVGFEDisplacementMap.cpp
index 4610b7d..9374eda 100644
--- a/WebCore/svg/graphics/filters/SVGFEDisplacementMap.cpp
+++ b/WebCore/svg/graphics/filters/SVGFEDisplacementMap.cpp
@@ -133,31 +133,38 @@ void FEDisplacementMap::dump()
{
}
-static TextStream& operator<<(TextStream& ts, ChannelSelectorType t)
+static TextStream& operator<<(TextStream& ts, const ChannelSelectorType& type)
{
- switch (t)
- {
- 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;
+ 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) const
+TextStream& FEDisplacementMap::externalRepresentation(TextStream& ts, int indent) const
{
- ts << "[type=DISPLACEMENT-MAP] ";
+ writeIndent(ts, indent);
+ ts << "[feDisplacementMap";
FilterEffect::externalRepresentation(ts);
- ts << "[scale=" << m_scale << "]"
- << " [x channel selector=" << m_xChannelSelector << "]"
- << " [y channel selector=" << m_yChannelSelector << "]";
+ ts << " scale=\"" << m_scale << "\" "
+ << "xChannelSelector=\"" << m_xChannelSelector << "\" "
+ << "yChannelSelector=\"" << m_yChannelSelector << "\"]\n";
+ m_in->externalRepresentation(ts, indent + 1);
+ m_in2->externalRepresentation(ts, indent + 1);
return ts;
}
diff --git a/WebCore/svg/graphics/filters/SVGFEDisplacementMap.h b/WebCore/svg/graphics/filters/SVGFEDisplacementMap.h
index 007f6ba..139bd2a 100644
--- a/WebCore/svg/graphics/filters/SVGFEDisplacementMap.h
+++ b/WebCore/svg/graphics/filters/SVGFEDisplacementMap.h
@@ -54,7 +54,7 @@ namespace WebCore {
virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return calculateUnionOfChildEffectSubregions(filter, m_in.get(), m_in2.get()); }
void apply(Filter*);
void dump();
- TextStream& externalRepresentation(TextStream& ts) const;
+ TextStream& externalRepresentation(TextStream&, int indent) const;
private:
FEDisplacementMap(FilterEffect*, FilterEffect*, ChannelSelectorType,
diff --git a/WebCore/svg/graphics/filters/SVGFEFlood.cpp b/WebCore/svg/graphics/filters/SVGFEFlood.cpp
index 648bf54..d65c382 100644
--- a/WebCore/svg/graphics/filters/SVGFEFlood.cpp
+++ b/WebCore/svg/graphics/filters/SVGFEFlood.cpp
@@ -77,12 +77,13 @@ void FEFlood::dump()
{
}
-TextStream& FEFlood::externalRepresentation(TextStream& ts) const
+TextStream& FEFlood::externalRepresentation(TextStream& ts, int indent) const
{
- ts << "[type=FLOOD] ";
+ writeIndent(ts, indent);
+ ts << "[feFlood";
FilterEffect::externalRepresentation(ts);
- ts << " [color=" << floodColor() << "]"
- << " [opacity=" << floodOpacity() << "]";
+ ts << " flood-color=\"" << floodColor() << "\" "
+ << "flood-opacity=\"" << floodOpacity() << "\"]\n";
return ts;
}
diff --git a/WebCore/svg/graphics/filters/SVGFEFlood.h b/WebCore/svg/graphics/filters/SVGFEFlood.h
index 91795dd..3db906b 100644
--- a/WebCore/svg/graphics/filters/SVGFEFlood.h
+++ b/WebCore/svg/graphics/filters/SVGFEFlood.h
@@ -41,7 +41,7 @@ namespace WebCore {
void apply(Filter*);
void dump();
- TextStream& externalRepresentation(TextStream& ts) const;
+ TextStream& externalRepresentation(TextStream&, int indent) const;
private:
FEFlood(const Color&, const float&);
diff --git a/WebCore/svg/graphics/filters/SVGFEImage.cpp b/WebCore/svg/graphics/filters/SVGFEImage.cpp
index 950203a..0614116 100644
--- a/WebCore/svg/graphics/filters/SVGFEImage.cpp
+++ b/WebCore/svg/graphics/filters/SVGFEImage.cpp
@@ -66,10 +66,14 @@ void FEImage::dump()
{
}
-TextStream& FEImage::externalRepresentation(TextStream& ts) const
+TextStream& FEImage::externalRepresentation(TextStream& ts, int indent) const
{
- ts << "[type=IMAGE] ";
+ ASSERT(m_image);
+ IntSize imageSize = m_image->size();
+ writeIndent(ts, indent);
+ ts << "[feImage";
FilterEffect::externalRepresentation(ts);
+ ts << " image-size=\"" << imageSize.width() << "x" << imageSize.height() << "\"]\n";
// FIXME: should this dump also object returned by SVGFEImage::image() ?
return ts;
}
diff --git a/WebCore/svg/graphics/filters/SVGFEImage.h b/WebCore/svg/graphics/filters/SVGFEImage.h
index 01e9522..3702d2b 100644
--- a/WebCore/svg/graphics/filters/SVGFEImage.h
+++ b/WebCore/svg/graphics/filters/SVGFEImage.h
@@ -35,7 +35,7 @@ namespace WebCore {
void apply(Filter*);
void dump();
- TextStream& externalRepresentation(TextStream& ts) const;
+ TextStream& externalRepresentation(TextStream&, int indent) const;
private:
FEImage(RefPtr<Image>, SVGPreserveAspectRatio);
diff --git a/WebCore/svg/graphics/filters/SVGFELighting.cpp b/WebCore/svg/graphics/filters/SVGFELighting.cpp
new file mode 100644
index 0000000..980e936
--- /dev/null
+++ b/WebCore/svg/graphics/filters/SVGFELighting.cpp
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2010 University of Szeged
+ * Copyright (C) 2010 Zoltan Herczeg
+ * All rights reserved.
+ *
+ * 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(SVG) && ENABLE(FILTERS)
+#include "SVGFELighting.h"
+
+#include "CanvasPixelArray.h"
+#include "ImageData.h"
+#include "SVGLightSource.h"
+
+namespace WebCore {
+
+FELighting::FELighting(LightingType lightingType, FilterEffect* in, const Color& lightingColor, float surfaceScale,
+ float diffuseConstant, float specularConstant, float specularExponent,
+ float kernelUnitLengthX, float kernelUnitLengthY, PassRefPtr<LightSource> lightSource)
+ : FilterEffect()
+ , m_lightingType(lightingType)
+ , m_in(in)
+ , 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);
+
+ALWAYS_INLINE int FELighting::LightingData::upLeftPixelValue()
+{
+ return static_cast<int>(pixels->get(offset - widthMultipliedByPixelSize - cPixelSize + cAlphaChannelOffset));
+}
+
+ALWAYS_INLINE int FELighting::LightingData::upPixelValue()
+{
+ return static_cast<int>(pixels->get(offset - widthMultipliedByPixelSize + cAlphaChannelOffset));
+}
+
+ALWAYS_INLINE int FELighting::LightingData::upRightPixelValue()
+{
+ return static_cast<int>(pixels->get(offset - widthMultipliedByPixelSize + cPixelSize + cAlphaChannelOffset));
+}
+
+ALWAYS_INLINE int FELighting::LightingData::leftPixelValue()
+{
+ return static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+}
+
+ALWAYS_INLINE int FELighting::LightingData::centerPixelValue()
+{
+ return static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+}
+
+ALWAYS_INLINE int FELighting::LightingData::rightPixelValue()
+{
+ return static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+}
+
+ALWAYS_INLINE int FELighting::LightingData::downLeftPixelValue()
+{
+ return static_cast<int>(pixels->get(offset + widthMultipliedByPixelSize - cPixelSize + cAlphaChannelOffset));
+}
+
+ALWAYS_INLINE int FELighting::LightingData::downPixelValue()
+{
+ return static_cast<int>(pixels->get(offset + widthMultipliedByPixelSize + cAlphaChannelOffset));
+}
+
+ALWAYS_INLINE int FELighting::LightingData::downRightPixelValue()
+{
+ return static_cast<int>(pixels->get(offset + widthMultipliedByPixelSize + cPixelSize + cAlphaChannelOffset));
+}
+
+ALWAYS_INLINE void FELighting::setPixel(LightingData& data, LightSource::PaintingData& paintingData,
+ int lightX, int lightY, float factorX, int normalX, float factorY, int normalY)
+{
+ m_lightSource->updatePaintingData(paintingData, lightX, lightY, static_cast<float>(data.pixels->get(data.offset + 3)) * data.surfaceScale);
+
+ data.normalVector.setX(factorX * static_cast<float>(normalX) * data.surfaceScale);
+ data.normalVector.setY(factorY * static_cast<float>(normalY) * data.surfaceScale);
+ data.normalVector.setZ(1.0f);
+ data.normalVector.normalize();
+
+ if (m_lightingType == FELighting::DiffuseLighting)
+ data.lightStrength = m_diffuseConstant * (data.normalVector * paintingData.lightVector);
+ else {
+ FloatPoint3D halfwayVector = paintingData.lightVector;
+ halfwayVector.setZ(halfwayVector.z() + 1.0f);
+ halfwayVector.normalize();
+ if (m_specularExponent == 1.0f)
+ data.lightStrength = m_specularConstant * (data.normalVector * halfwayVector);
+ else
+ data.lightStrength = m_specularConstant * powf(data.normalVector * halfwayVector, m_specularExponent);
+ }
+
+ if (data.lightStrength > 1.0f)
+ data.lightStrength = 1.0f;
+ if (data.lightStrength < 0.0f)
+ data.lightStrength = 0.0f;
+
+ data.pixels->set(data.offset, static_cast<unsigned char>(data.lightStrength * paintingData.colorVector.x()));
+ data.pixels->set(data.offset + 1, static_cast<unsigned char>(data.lightStrength * paintingData.colorVector.y()));
+ data.pixels->set(data.offset + 2, static_cast<unsigned char>(data.lightStrength * paintingData.colorVector.z()));
+}
+
+bool FELighting::drawLighting(CanvasPixelArray* 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
+ data.offset = 0;
+ setPixel(data, paintingData, 0, 0,
+ -2.0f / 3.0f, -2 * data.centerPixelValue() + 2 * data.rightPixelValue() - data.downPixelValue() + data.downRightPixelValue(),
+ -2.0f / 3.0f, -2 * data.centerPixelValue() - data.rightPixelValue() + 2 * data.downPixelValue() + data.downRightPixelValue());
+
+ // Top/Right pixel
+ data.offset = data.widthMultipliedByPixelSize - cPixelSize;
+ setPixel(data, paintingData, data.widthDecreasedByOne, 0,
+ -2.0f / 3.0f, -2 * data.leftPixelValue() + 2 * data.centerPixelValue() - data.downLeftPixelValue() + data.downPixelValue(),
+ -2.0f / 3.0f, -data.leftPixelValue() - 2 * data.centerPixelValue() + data.downLeftPixelValue() + 2 * data.downPixelValue());
+
+ // Bottom/Left pixel
+ data.offset = data.heightDecreasedByOne * data.widthMultipliedByPixelSize;
+ setPixel(data, paintingData, 0, data.heightDecreasedByOne,
+ -2.0f / 3.0f, -data.upPixelValue() + data.upRightPixelValue() - 2 * data.centerPixelValue() + 2 * data.rightPixelValue(),
+ -2.0f / 3.0f, -2 * data.upPixelValue() - data.upRightPixelValue() + 2 * data.centerPixelValue() + data.rightPixelValue());
+
+ // Bottom/Right pixel
+ data.offset = height * data.widthMultipliedByPixelSize - cPixelSize;
+ setPixel(data, paintingData, data.widthDecreasedByOne, data.heightDecreasedByOne,
+ -2.0f / 3.0f, -data.upLeftPixelValue() + data.upPixelValue() - 2 * data.leftPixelValue() + 2 * data.centerPixelValue(),
+ -2.0f / 3.0f, -data.upLeftPixelValue() - 2 * data.upPixelValue() + data.leftPixelValue() + 2 * data.centerPixelValue());
+
+ if (width >= 3) {
+ // Top line
+ data.offset = cPixelSize;
+ for (int x = 1; x < data.widthDecreasedByOne; ++x, data.offset += cPixelSize) {
+ setPixel(data, paintingData, x, 0,
+ -1.0f / 3.0f, -2 * data.leftPixelValue() + 2 * data.rightPixelValue() - data.downLeftPixelValue() + data.downRightPixelValue(),
+ -1.0f / 2.0f, -data.leftPixelValue() - 2 * data.centerPixelValue() - data.rightPixelValue() + data.downLeftPixelValue() + 2 * data.downPixelValue() + data.downRightPixelValue());
+ }
+ // Bottom line
+ data.offset = data.heightDecreasedByOne * data.widthMultipliedByPixelSize + cPixelSize;
+ for (int x = 1; x < data.widthDecreasedByOne; ++x, data.offset += cPixelSize) {
+ setPixel(data, paintingData, x, data.heightDecreasedByOne,
+ -1.0f / 3.0f, -data.upLeftPixelValue() + data.upRightPixelValue() - 2 * data.leftPixelValue() + 2 * data.rightPixelValue(),
+ -1.0f / 2.0f, -data.upLeftPixelValue() - 2 * data.upPixelValue() - data.upRightPixelValue() + data.leftPixelValue() + 2 * data.centerPixelValue() + data.rightPixelValue());
+ }
+ }
+
+ if (height >= 3) {
+ // Left line
+ data.offset = data.widthMultipliedByPixelSize;
+ for (int y = 1; y < data.heightDecreasedByOne; ++y, data.offset += data.widthMultipliedByPixelSize) {
+ setPixel(data, paintingData, 0, y,
+ -1.0f / 2.0f, -data.upPixelValue() + data.upRightPixelValue() - 2 * data.centerPixelValue() + 2 * data.rightPixelValue() - data.downPixelValue() + data.downRightPixelValue(),
+ -1.0f / 3.0f, -2 * data.upPixelValue() - data.upRightPixelValue() + 2 * data.downPixelValue() + data.downRightPixelValue());
+ }
+ // Right line
+ data.offset = data.widthMultipliedByPixelSize + data.widthMultipliedByPixelSize - cPixelSize;
+ for (int y = 1; y < data.heightDecreasedByOne; ++y, data.offset += data.widthMultipliedByPixelSize) {
+ setPixel(data, paintingData, data.widthDecreasedByOne, y,
+ -1.0f / 2.0f, -data.upLeftPixelValue() + data.upPixelValue() -2 * data.leftPixelValue() + 2 * data.centerPixelValue() - data.downLeftPixelValue() + data.downPixelValue(),
+ -1.0f / 3.0f, -data.upLeftPixelValue() - 2 * data.upPixelValue() + data.downLeftPixelValue() + 2 * data.downPixelValue());
+ }
+ }
+
+ if (width >= 3 && height >= 3) {
+ // Interior pixels
+ for (int y = 1; y < data.heightDecreasedByOne; ++y) {
+ data.offset = y * data.widthMultipliedByPixelSize + cPixelSize;
+ for (int x = 1; x < data.widthDecreasedByOne; ++x, data.offset += cPixelSize) {
+ setPixel(data, paintingData, x, y,
+ -1.0f / 4.0f, -data.upLeftPixelValue() + data.upRightPixelValue() - 2 * data.leftPixelValue() + 2 * data.rightPixelValue() - data.downLeftPixelValue() + data.downRightPixelValue(),
+ -1.0f / 4.0f, -data.upLeftPixelValue() - 2 * data.upPixelValue() - data.upRightPixelValue() + data.downLeftPixelValue() + 2 * data.downPixelValue() + data.downRightPixelValue());
+ }
+ }
+ }
+
+ int totalSize = data.widthMultipliedByPixelSize * height;
+ if (m_lightingType == DiffuseLighting) {
+ for (int i = 3; i < totalSize; i += 4)
+ data.pixels->set(i, cOpaqueAlpha);
+ } else {
+ for (int i = 0; i < totalSize; i += 4) {
+ 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(Filter* filter)
+{
+ m_in->apply(filter);
+ if (!m_in->resultImage())
+ return;
+
+ if (!getEffectContext())
+ return;
+
+ setIsAlphaImage(false);
+
+ IntRect effectDrawingRect = calculateDrawingIntRect(m_in->scaledSubRegion());
+
+ RefPtr<ImageData> srcImageData(m_in->resultImage()->getUnmultipliedImageData(effectDrawingRect));
+ CanvasPixelArray* srcPixelArray(srcImageData->data());
+
+ // 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
+
+ if (drawLighting(srcPixelArray, effectDrawingRect.width(), effectDrawingRect.height()))
+ resultImage()->putUnmultipliedImageData(srcImageData.get(), IntRect(IntPoint(), effectDrawingRect.size()), effectDrawingRect.location());
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG) && ENABLE(FILTERS)
diff --git a/WebCore/svg/graphics/filters/SVGFELighting.h b/WebCore/svg/graphics/filters/SVGFELighting.h
new file mode 100644
index 0000000..731871f
--- /dev/null
+++ b/WebCore/svg/graphics/filters/SVGFELighting.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2010 University of Szeged
+ * Copyright (C) 2010 Zoltan Herczeg
+ * All rights reserved.
+ *
+ * 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 SVGFELighting_h
+#define SVGFELighting_h
+
+#if ENABLE(SVG) && ENABLE(FILTERS)
+#include "Color.h"
+#include "Filter.h"
+#include "FilterEffect.h"
+#include "SVGLightSource.h"
+#include <wtf/AlwaysInline.h>
+
+// Common base class for FEDiffuseLighting and FESpecularLighting
+
+namespace WebCore {
+
+class CanvasPixelArray;
+
+class FELighting : public FilterEffect {
+public:
+ virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return calculateUnionOfChildEffectSubregions(filter, m_in.get()); }
+ void apply(Filter*);
+
+protected:
+ enum LightingType {
+ DiffuseLighting,
+ SpecularLighting
+ };
+
+ struct LightingData {
+ FloatPoint3D normalVector;
+ CanvasPixelArray* pixels;
+ float lightStrength;
+ float surfaceScale;
+ int offset;
+ int widthMultipliedByPixelSize;
+ int widthDecreasedByOne;
+ int heightDecreasedByOne;
+
+ ALWAYS_INLINE int upLeftPixelValue();
+ ALWAYS_INLINE int upPixelValue();
+ ALWAYS_INLINE int upRightPixelValue();
+ ALWAYS_INLINE int leftPixelValue();
+ ALWAYS_INLINE int centerPixelValue();
+ ALWAYS_INLINE int rightPixelValue();
+ ALWAYS_INLINE int downLeftPixelValue();
+ ALWAYS_INLINE int downPixelValue();
+ ALWAYS_INLINE int downRightPixelValue();
+ };
+
+ FELighting(LightingType, FilterEffect*, const Color&, float, float, float,
+ float, float, float, PassRefPtr<LightSource>);
+
+ bool drawLighting(CanvasPixelArray*, int, int);
+ ALWAYS_INLINE void setPixel(LightingData&, LightSource::PaintingData&,
+ int lightX, int lightY, float factorX, int normalX, float factorY, int normalY);
+
+ LightingType m_lightingType;
+ RefPtr<FilterEffect> m_in;
+ 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(SVG) && ENABLE(FILTERS)
+
+#endif // SVGFELighting_h
diff --git a/WebCore/svg/graphics/filters/SVGFEMerge.cpp b/WebCore/svg/graphics/filters/SVGFEMerge.cpp
index 6ea0fb9..c6f312f 100644
--- a/WebCore/svg/graphics/filters/SVGFEMerge.cpp
+++ b/WebCore/svg/graphics/filters/SVGFEMerge.cpp
@@ -87,20 +87,17 @@ void FEMerge::dump()
{
}
-TextStream& FEMerge::externalRepresentation(TextStream& ts) const
+TextStream& FEMerge::externalRepresentation(TextStream& ts, int indent) const
{
- ts << "[type=MERGE] ";
+ writeIndent(ts, indent);
+ ts << "[feMerge";
FilterEffect::externalRepresentation(ts);
- ts << "[merge inputs=[";
- unsigned x = 0;
- unsigned size = m_mergeInputs.size();
- while (x < size) {
- ts << m_mergeInputs[x];
- x++;
- if (x < m_mergeInputs.size())
- ts << ", ";
+ ts << " mergeNodes=\"" << m_mergeInputs.size() << "\"]\n";
+ if (!m_mergeInputs.isEmpty()) {
+ const Vector<RefPtr<FilterEffect> >::const_iterator end = m_mergeInputs.end();
+ for (Vector<RefPtr<FilterEffect> >::const_iterator it = m_mergeInputs.begin(); it != end; ++it)
+ (*it)->externalRepresentation(ts, indent + 1);
}
- ts << "]]";
return ts;
}
diff --git a/WebCore/svg/graphics/filters/SVGFEMerge.h b/WebCore/svg/graphics/filters/SVGFEMerge.h
index 7653be3..77b311f 100644
--- a/WebCore/svg/graphics/filters/SVGFEMerge.h
+++ b/WebCore/svg/graphics/filters/SVGFEMerge.h
@@ -39,7 +39,7 @@ namespace WebCore {
virtual FloatRect uniteChildEffectSubregions(Filter*);
void apply(Filter*);
void dump();
- TextStream& externalRepresentation(TextStream& ts) const;
+ TextStream& externalRepresentation(TextStream&, int indent) const;
private:
FEMerge(const Vector<RefPtr<FilterEffect> >&);
diff --git a/WebCore/svg/graphics/filters/SVGFEMorphology.cpp b/WebCore/svg/graphics/filters/SVGFEMorphology.cpp
index 5204a46..1c5ea27 100644
--- a/WebCore/svg/graphics/filters/SVGFEMorphology.cpp
+++ b/WebCore/svg/graphics/filters/SVGFEMorphology.cpp
@@ -157,26 +157,30 @@ void FEMorphology::dump()
{
}
-static TextStream& operator<<(TextStream& ts, MorphologyOperatorType t)
+static TextStream& operator<<(TextStream& ts, const MorphologyOperatorType& type)
{
- switch (t)
- {
- case FEMORPHOLOGY_OPERATOR_UNKNOWN:
- ts << "UNKNOWN"; break;
- case FEMORPHOLOGY_OPERATOR_ERODE:
- ts << "ERODE"; break;
- case FEMORPHOLOGY_OPERATOR_DILATE:
- ts << "DILATE"; break;
+ 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) const
+TextStream& FEMorphology::externalRepresentation(TextStream& ts, int indent) const
{
- ts << "[type=MORPHOLOGY] ";
+ writeIndent(ts, indent);
+ ts << "[feMorphology";
FilterEffect::externalRepresentation(ts);
- ts << " [operator type=" << morphologyOperator() << "]"
- << " [radius x=" << radiusX() << " y=" << radiusY() << "]";
+ ts << " operator=\"" << morphologyOperator() << "\" "
+ << "radius=\"" << radiusX() << ", " << radiusY() << "\"]\n";
+ m_in->externalRepresentation(ts, indent + 1);
return ts;
}
diff --git a/WebCore/svg/graphics/filters/SVGFEMorphology.h b/WebCore/svg/graphics/filters/SVGFEMorphology.h
index 6a321c8..c0b2f95 100644
--- a/WebCore/svg/graphics/filters/SVGFEMorphology.h
+++ b/WebCore/svg/graphics/filters/SVGFEMorphology.h
@@ -49,7 +49,7 @@ namespace WebCore {
virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return calculateUnionOfChildEffectSubregions(filter, m_in.get()); }
void apply(Filter*);
void dump();
- TextStream& externalRepresentation(TextStream& ts) const;
+ TextStream& externalRepresentation(TextStream&, int indent) const;
private:
FEMorphology(FilterEffect*, MorphologyOperatorType, float radiusX, float radiusY);
diff --git a/WebCore/svg/graphics/filters/SVGFEOffset.cpp b/WebCore/svg/graphics/filters/SVGFEOffset.cpp
index 0066c3e..5386f1c 100644
--- a/WebCore/svg/graphics/filters/SVGFEOffset.cpp
+++ b/WebCore/svg/graphics/filters/SVGFEOffset.cpp
@@ -98,11 +98,13 @@ void FEOffset::dump()
{
}
-TextStream& FEOffset::externalRepresentation(TextStream& ts) const
+TextStream& FEOffset::externalRepresentation(TextStream& ts, int indent) const
{
- ts << "[type=OFFSET] ";
+ writeIndent(ts, indent);
+ ts << "[feOffset";
FilterEffect::externalRepresentation(ts);
- ts << " [dx=" << dx() << " dy=" << dy() << "]";
+ ts << " dx=\"" << dx() << "\" dy=\"" << dy() << "\"]\n";
+ m_in->externalRepresentation(ts, indent + 1);
return ts;
}
diff --git a/WebCore/svg/graphics/filters/SVGFEOffset.h b/WebCore/svg/graphics/filters/SVGFEOffset.h
index 8435db1..a6ded47 100644
--- a/WebCore/svg/graphics/filters/SVGFEOffset.h
+++ b/WebCore/svg/graphics/filters/SVGFEOffset.h
@@ -41,7 +41,7 @@ namespace WebCore {
virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return calculateUnionOfChildEffectSubregions(filter, m_in.get()); }
void apply(Filter*);
void dump();
- TextStream& externalRepresentation(TextStream& ts) const;
+ TextStream& externalRepresentation(TextStream&, int indent) const;
private:
FEOffset(FilterEffect*, const float&, const float&);
diff --git a/WebCore/svg/graphics/filters/SVGFESpecularLighting.cpp b/WebCore/svg/graphics/filters/SVGFESpecularLighting.cpp
index 0b43aba..fbf9d44 100644
--- a/WebCore/svg/graphics/filters/SVGFESpecularLighting.cpp
+++ b/WebCore/svg/graphics/filters/SVGFESpecularLighting.cpp
@@ -23,29 +23,22 @@
#if ENABLE(SVG) && ENABLE(FILTERS)
#include "SVGFESpecularLighting.h"
+
+#include "SVGLightSource.h"
#include "SVGRenderTreeAsText.h"
-#include "Filter.h"
namespace WebCore {
-FESpecularLighting::FESpecularLighting(FilterEffect* in, const Color& lightingColor, const float& surfaceScale,
- const float& specularConstant, const float& specularExponent, const float& kernelUnitLengthX,
- const float& kernelUnitLengthY, PassRefPtr<LightSource> lightSource)
- : FilterEffect()
- , m_in(in)
- , m_lightingColor(lightingColor)
- , m_surfaceScale(surfaceScale)
- , m_specularConstant(specularConstant)
- , m_specularExponent(specularExponent)
- , m_kernelUnitLengthX(kernelUnitLengthX)
- , m_kernelUnitLengthY(kernelUnitLengthY)
- , m_lightSource(lightSource)
+FESpecularLighting::FESpecularLighting(FilterEffect* in, const Color& lightingColor, float surfaceScale,
+ float specularConstant, float specularExponent, float kernelUnitLengthX,
+ float kernelUnitLengthY, PassRefPtr<LightSource> lightSource)
+ : FELighting(SpecularLighting, in, lightingColor, surfaceScale, 0.0f, specularConstant, specularExponent, kernelUnitLengthX, kernelUnitLengthY, lightSource)
{
}
PassRefPtr<FESpecularLighting> FESpecularLighting::create(FilterEffect* in, const Color& lightingColor,
- const float& surfaceScale, const float& specularConstant, const float& specularExponent,
- const float& kernelUnitLengthX, const float& kernelUnitLengthY, PassRefPtr<LightSource> lightSource)
+ float surfaceScale, float specularConstant, float specularExponent,
+ float kernelUnitLengthX, float kernelUnitLengthY, PassRefPtr<LightSource> lightSource)
{
return adoptRef(new FESpecularLighting(in, lightingColor, surfaceScale, specularConstant, specularExponent,
kernelUnitLengthX, kernelUnitLengthY, lightSource));
@@ -125,21 +118,19 @@ void FESpecularLighting::setLightSource(PassRefPtr<LightSource> lightSource)
m_lightSource = lightSource;
}
-void FESpecularLighting::apply(Filter*)
-{
-}
-
void FESpecularLighting::dump()
{
}
-TextStream& FESpecularLighting::externalRepresentation(TextStream& ts) const
+TextStream& FESpecularLighting::externalRepresentation(TextStream& ts, int indent) const
{
- ts << "[type=SPECULAR-LIGHTING] ";
+ writeIndent(ts, indent);
+ ts << "[feSpecularLighting";
FilterEffect::externalRepresentation(ts);
- ts << " [surface scale=" << m_surfaceScale << "]"
- << " [specual constant=" << m_specularConstant << "]"
- << " [specular exponent=" << m_specularExponent << "]";
+ ts << " surfaceScale=\"" << m_surfaceScale << "\" "
+ << "specualConstant=\"" << m_specularConstant << "\" "
+ << "specularExponent=\"" << m_specularExponent << "\"]\n";
+ m_in->externalRepresentation(ts, indent + 1);
return ts;
}
diff --git a/WebCore/svg/graphics/filters/SVGFESpecularLighting.h b/WebCore/svg/graphics/filters/SVGFESpecularLighting.h
index f4947fd..366056e 100644
--- a/WebCore/svg/graphics/filters/SVGFESpecularLighting.h
+++ b/WebCore/svg/graphics/filters/SVGFESpecularLighting.h
@@ -23,58 +23,44 @@
#define SVGFESpecularLighting_h
#if ENABLE(SVG) && ENABLE(FILTERS)
-#include "Color.h"
-#include "FilterEffect.h"
-#include "SVGLightSource.h"
-#include "Filter.h"
+#include "SVGFELighting.h"
namespace WebCore {
- class FESpecularLighting : public FilterEffect {
- public:
- static PassRefPtr<FESpecularLighting> create(FilterEffect*, const Color&, const float&, const float&,
- const float&, const float&, const float&, PassRefPtr<LightSource>);
- virtual ~FESpecularLighting();
+class FESpecularLighting : public FELighting {
+public:
+ static PassRefPtr<FESpecularLighting> create(FilterEffect*, const Color&, float, float,
+ float, float, float, PassRefPtr<LightSource>);
+ virtual ~FESpecularLighting();
- Color lightingColor() const;
- void setLightingColor(const Color&);
+ Color lightingColor() const;
+ void setLightingColor(const Color&);
- float surfaceScale() const;
- void setSurfaceScale(float);
+ float surfaceScale() const;
+ void setSurfaceScale(float);
- float specularConstant() const;
- void setSpecularConstant(float);
+ float specularConstant() const;
+ void setSpecularConstant(float);
- float specularExponent() const;
- void setSpecularExponent(float);
+ float specularExponent() const;
+ void setSpecularExponent(float);
- float kernelUnitLengthX() const;
- void setKernelUnitLengthX(float);
+ float kernelUnitLengthX() const;
+ void setKernelUnitLengthX(float);
- float kernelUnitLengthY() const;
- void setKernelUnitLengthY(float);
+ float kernelUnitLengthY() const;
+ void setKernelUnitLengthY(float);
- const LightSource* lightSource() const;
- void setLightSource(PassRefPtr<LightSource>);
+ const LightSource* lightSource() const;
+ void setLightSource(PassRefPtr<LightSource>);
- virtual FloatRect uniteEffectRect(Filter* filter) { return calculateUnionOfChildEffectSubregions(filter, m_in.get()); }
- void apply(Filter*);
- void dump();
- TextStream& externalRepresentation(TextStream& ts) const;
+ void dump();
+ TextStream& externalRepresentation(TextStream&, int indent) const;
- private:
- FESpecularLighting(FilterEffect*, const Color&, const float&, const float&, const float&,
- const float&, const float&, PassRefPtr<LightSource>);
-
- RefPtr<FilterEffect> m_in;
- Color m_lightingColor;
- float m_surfaceScale;
- float m_specularConstant;
- float m_specularExponent;
- float m_kernelUnitLengthX;
- float m_kernelUnitLengthY;
- RefPtr<LightSource> m_lightSource;
- };
+private:
+ FESpecularLighting(FilterEffect*, const Color&, float, float, float,
+ float, float, PassRefPtr<LightSource>);
+};
} // namespace WebCore
diff --git a/WebCore/svg/graphics/filters/SVGFETile.cpp b/WebCore/svg/graphics/filters/SVGFETile.cpp
index 5bc2129..1b0a59b 100644
--- a/WebCore/svg/graphics/filters/SVGFETile.cpp
+++ b/WebCore/svg/graphics/filters/SVGFETile.cpp
@@ -87,10 +87,14 @@ void FETile::dump()
{
}
-TextStream& FETile::externalRepresentation(TextStream& ts) const
+TextStream& FETile::externalRepresentation(TextStream& ts, int indent) const
{
- ts << "[type=TILE]";
+ writeIndent(ts, indent);
+ ts << "[feTile";
FilterEffect::externalRepresentation(ts);
+ ts << "]\n";
+ m_in->externalRepresentation(ts, indent + 1);
+
return ts;
}
diff --git a/WebCore/svg/graphics/filters/SVGFETile.h b/WebCore/svg/graphics/filters/SVGFETile.h
index c845085..e11e4ab 100644
--- a/WebCore/svg/graphics/filters/SVGFETile.h
+++ b/WebCore/svg/graphics/filters/SVGFETile.h
@@ -35,7 +35,7 @@ namespace WebCore {
virtual FloatRect uniteChildEffectSubregions(Filter*);
void apply(Filter*);
void dump();
- TextStream& externalRepresentation(TextStream& ts) const;
+ TextStream& externalRepresentation(TextStream&, int indent) const;
private:
FETile(FilterEffect*);
diff --git a/WebCore/svg/graphics/filters/SVGFETurbulence.cpp b/WebCore/svg/graphics/filters/SVGFETurbulence.cpp
index 542c576..db4b0bb 100644
--- a/WebCore/svg/graphics/filters/SVGFETurbulence.cpp
+++ b/WebCore/svg/graphics/filters/SVGFETurbulence.cpp
@@ -114,30 +114,32 @@ void FETurbulence::dump()
{
}
-static TextStream& operator<<(TextStream& ts, TurbulanceType t)
-{
- switch (t)
- {
- case FETURBULENCE_TYPE_UNKNOWN:
- ts << "UNKNOWN"; break;
- case FETURBULENCE_TYPE_TURBULENCE:
- ts << "TURBULANCE"; break;
- case FETURBULENCE_TYPE_FRACTALNOISE:
- ts << "NOISE"; break;
+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) const
+TextStream& FETurbulence::externalRepresentation(TextStream& ts, int indent) const
{
- ts << "[type=TURBULENCE] ";
+ writeIndent(ts, indent);
+ ts << "[feTurbulence";
FilterEffect::externalRepresentation(ts);
- ts << " [turbulence type=" << type() << "]"
- << " [base frequency x=" << baseFrequencyX() << " y=" << baseFrequencyY() << "]"
- << " [seed=" << seed() << "]"
- << " [num octaves=" << numOctaves() << "]"
- << " [stitch tiles=" << stitchTiles() << "]";
-
+ ts << " type=\"" << type() << "\" "
+ << "baseFrequency=\"" << baseFrequencyX() << ", " << baseFrequencyY() << "\" "
+ << "seed=\"" << seed() << "\" "
+ << "numOctaves=\"" << numOctaves() << "\" "
+ << "stitchTiles=\"" << stitchTiles() << "\"]\n";
return ts;
}
diff --git a/WebCore/svg/graphics/filters/SVGFETurbulence.h b/WebCore/svg/graphics/filters/SVGFETurbulence.h
index e7f40f6..bed0637 100644
--- a/WebCore/svg/graphics/filters/SVGFETurbulence.h
+++ b/WebCore/svg/graphics/filters/SVGFETurbulence.h
@@ -59,7 +59,7 @@ namespace WebCore {
void apply(Filter*);
void dump();
- TextStream& externalRepresentation(TextStream& ts) const;
+ TextStream& externalRepresentation(TextStream&, int indent) const;
private:
FETurbulence(TurbulanceType, const float&, const float&, const int&, const float&,
diff --git a/WebCore/svg/graphics/filters/SVGLightSource.cpp b/WebCore/svg/graphics/filters/SVGLightSource.cpp
index 9176b4c..2a04af6 100644
--- a/WebCore/svg/graphics/filters/SVGLightSource.cpp
+++ b/WebCore/svg/graphics/filters/SVGLightSource.cpp
@@ -2,6 +2,7 @@
Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
2004, 2005 Rob Buis <buis@kde.org>
2005 Eric Seidel <eric@webkit.org>
+ 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
@@ -22,13 +23,115 @@
#include "config.h"
#if ENABLE(SVG) && ENABLE(FILTERS)
+#include "SVGLightSource.h"
+
+#include "SVGDistantLightSource.h"
#include "SVGPointLightSource.h"
#include "SVGRenderTreeAsText.h"
#include "SVGSpotLightSource.h"
-#include "SVGDistantLightSource.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.lightVector.normalize();
+}
+
+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 = cosf(deg2rad(92.0f));
+ } else {
+ float limitingConeAngle = m_limitingConeAngle;
+ if (limitingConeAngle < 0.0f)
+ limitingConeAngle = 0.0f;
+ else if (limitingConeAngle > 90.0f)
+ limitingConeAngle = 90.0f;
+ paintingData.coneCutOffLimit = cosf(deg2rad(180.0f - limitingConeAngle));
+ limitingConeAngle -= 2.0f;
+ if (limitingConeAngle < 0.0f)
+ limitingConeAngle = 0.0f;
+ paintingData.coneFullLight = cosf(deg2rad(180.0f - limitingConeAngle));
+ }
+
+ // 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.lightVector.normalize();
+
+ float cosineOfAngle = paintingData.lightVector * paintingData.directionVector;
+ 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));
+}
+
+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();
diff --git a/WebCore/svg/graphics/filters/SVGLightSource.h b/WebCore/svg/graphics/filters/SVGLightSource.h
index 6f0075c..d97366c 100644
--- a/WebCore/svg/graphics/filters/SVGLightSource.h
+++ b/WebCore/svg/graphics/filters/SVGLightSource.h
@@ -3,6 +3,7 @@
2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
2004, 2005 Rob Buis <buis@kde.org>
2005 Eric Seidel <eric@webkit.org>
+ 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
@@ -24,33 +25,57 @@
#define SVGLightSource_h
#if ENABLE(SVG) && ENABLE(FILTERS)
+#include "FloatPoint3D.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
- enum LightType {
- LS_DISTANT,
- LS_POINT,
- LS_SPOT
+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;
+ // Private members
+ FloatPoint3D directionVector;
+ FloatPoint3D privateColorVector;
+ float coneCutOffLimit;
+ float coneFullLight;
+ int specularExponent;
};
- class TextStream;
+ LightSource(LightType type)
+ : m_type(type)
+ { }
- class LightSource : public RefCounted<LightSource> {
- public:
- LightSource(LightType type)
- : m_type(type)
- { }
+ virtual ~LightSource() { }
- virtual ~LightSource() { }
+ LightType type() const { return m_type; }
+ virtual TextStream& externalRepresentation(TextStream&) const = 0;
- 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;
- };
+private:
+ LightType m_type;
+};
} // namespace WebCore
diff --git a/WebCore/svg/graphics/filters/SVGPointLightSource.h b/WebCore/svg/graphics/filters/SVGPointLightSource.h
index 1e966cc..0c55ebf 100644
--- a/WebCore/svg/graphics/filters/SVGPointLightSource.h
+++ b/WebCore/svg/graphics/filters/SVGPointLightSource.h
@@ -24,31 +24,33 @@
#define SVGPointLightSource_h
#if ENABLE(SVG) && ENABLE(FILTERS)
-#include "FloatPoint3D.h"
#include "SVGLightSource.h"
namespace WebCore {
- class PointLightSource : public LightSource {
- public:
- static PassRefPtr<PointLightSource> create(const FloatPoint3D& position)
- {
- return adoptRef(new PointLightSource(position));
- }
+class PointLightSource : public LightSource {
+public:
+ static PassRefPtr<PointLightSource> create(const FloatPoint3D& position)
+ {
+ return adoptRef(new PointLightSource(position));
+ }
- const FloatPoint3D& position() const { return m_position; }
+ const FloatPoint3D& position() const { return m_position; }
- virtual TextStream& externalRepresentation(TextStream&) const;
+ virtual void initPaintingData(PaintingData&);
+ virtual void updatePaintingData(PaintingData&, int x, int y, float z);
- private:
- PointLightSource(const FloatPoint3D& position)
- : LightSource(LS_POINT)
- , m_position(position)
- {
- }
+ virtual TextStream& externalRepresentation(TextStream&) const;
- FloatPoint3D m_position;
- };
+private:
+ PointLightSource(const FloatPoint3D& position)
+ : LightSource(LS_POINT)
+ , m_position(position)
+ {
+ }
+
+ FloatPoint3D m_position;
+};
} // namespace WebCore
diff --git a/WebCore/svg/graphics/filters/SVGSpotLightSource.h b/WebCore/svg/graphics/filters/SVGSpotLightSource.h
index 05280d2..2542947 100644
--- a/WebCore/svg/graphics/filters/SVGSpotLightSource.h
+++ b/WebCore/svg/graphics/filters/SVGSpotLightSource.h
@@ -24,44 +24,46 @@
#define SVGSpotLightSource_h
#if ENABLE(SVG) && ENABLE(FILTERS)
-#include "FloatPoint3D.h"
#include "SVGLightSource.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 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;
- };
+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