diff options
author | Steve Block <steveblock@google.com> | 2011-05-18 13:36:51 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2011-05-24 15:38:28 +0100 |
commit | 2fc2651226baac27029e38c9d6ef883fa32084db (patch) | |
tree | e396d4bf89dcce6ed02071be66212495b1df1dec /Source/WebCore/platform/graphics/filters | |
parent | b3725cedeb43722b3b175aaeff70552e562d2c94 (diff) | |
download | external_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.zip external_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.tar.gz external_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.tar.bz2 |
Merge WebKit at r78450: Initial merge by git.
Change-Id: I6d3e5f1f868ec266a0aafdef66182ddc3f265dc1
Diffstat (limited to 'Source/WebCore/platform/graphics/filters')
12 files changed, 479 insertions, 115 deletions
diff --git a/Source/WebCore/platform/graphics/filters/DistantLightSource.cpp b/Source/WebCore/platform/graphics/filters/DistantLightSource.cpp new file mode 100644 index 0000000..4c3b49b --- /dev/null +++ b/Source/WebCore/platform/graphics/filters/DistantLightSource.cpp @@ -0,0 +1,80 @@ +/* + * 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> + * Copyright (C) 2011 University of Szeged + * Copyright (C) 2011 Renata Hodovan <reni@webkit.org> + * + * 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 "DistantLightSource.h" + +#include "RenderTreeAsText.h" + +namespace WebCore { + +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) +{ +} + +bool DistantLightSource::setAzimuth(float azimuth) +{ + if (m_azimuth == azimuth) + return false; + m_azimuth = azimuth; + return true; +} + +bool DistantLightSource::setElevation(float elevation) +{ + if (m_elevation == elevation) + return false; + m_elevation = elevation; + return true; +} + +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/DistantLightSource.h b/Source/WebCore/platform/graphics/filters/DistantLightSource.h index d5d474f..1e19c62 100644 --- a/Source/WebCore/platform/graphics/filters/DistantLightSource.h +++ b/Source/WebCore/platform/graphics/filters/DistantLightSource.h @@ -36,7 +36,9 @@ public: } float azimuth() const { return m_azimuth; } + bool setAzimuth(float); float elevation() const { return m_elevation; } + bool setElevation(float); virtual void initPaintingData(PaintingData&); virtual void updatePaintingData(PaintingData&, int x, int y, float z); diff --git a/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp b/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp index a8a825a..5f9d049 100644 --- a/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp +++ b/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp @@ -52,9 +52,12 @@ Color FEDiffuseLighting::lightingColor() const return m_lightingColor; } -void FEDiffuseLighting::setLightingColor(const Color& lightingColor) +bool FEDiffuseLighting::setLightingColor(const Color& lightingColor) { + if (m_lightingColor == lightingColor) + return false; m_lightingColor = lightingColor; + return true; } float FEDiffuseLighting::surfaceScale() const @@ -62,9 +65,12 @@ float FEDiffuseLighting::surfaceScale() const return m_surfaceScale; } -void FEDiffuseLighting::setSurfaceScale(float surfaceScale) +bool FEDiffuseLighting::setSurfaceScale(float surfaceScale) { + if (m_surfaceScale == surfaceScale) + return false; m_surfaceScale = surfaceScale; + return true; } float FEDiffuseLighting::diffuseConstant() const @@ -72,9 +78,12 @@ float FEDiffuseLighting::diffuseConstant() const return m_diffuseConstant; } -void FEDiffuseLighting::setDiffuseConstant(float diffuseConstant) +bool FEDiffuseLighting::setDiffuseConstant(float diffuseConstant) { + if (m_diffuseConstant == diffuseConstant) + return false; m_diffuseConstant = diffuseConstant; + return true; } float FEDiffuseLighting::kernelUnitLengthX() const @@ -82,9 +91,12 @@ float FEDiffuseLighting::kernelUnitLengthX() const return m_kernelUnitLengthX; } -void FEDiffuseLighting::setKernelUnitLengthX(float kernelUnitLengthX) +bool FEDiffuseLighting::setKernelUnitLengthX(float kernelUnitLengthX) { + if (m_kernelUnitLengthX == kernelUnitLengthX) + return false; m_kernelUnitLengthX = kernelUnitLengthX; + return true; } float FEDiffuseLighting::kernelUnitLengthY() const @@ -92,9 +104,12 @@ float FEDiffuseLighting::kernelUnitLengthY() const return m_kernelUnitLengthY; } -void FEDiffuseLighting::setKernelUnitLengthY(float kernelUnitLengthY) +bool FEDiffuseLighting::setKernelUnitLengthY(float kernelUnitLengthY) { + if (m_kernelUnitLengthY == kernelUnitLengthY) + return false; m_kernelUnitLengthY = kernelUnitLengthY; + return true; } const LightSource* FEDiffuseLighting::lightSource() const diff --git a/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.h b/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.h index b58b47a..5f20651 100644 --- a/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.h +++ b/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.h @@ -36,19 +36,19 @@ public: virtual ~FEDiffuseLighting(); Color lightingColor() const; - void setLightingColor(const Color&); + bool setLightingColor(const Color&); float surfaceScale() const; - void setSurfaceScale(float); + bool setSurfaceScale(float); float diffuseConstant() const; - void setDiffuseConstant(float); + bool setDiffuseConstant(float); float kernelUnitLengthX() const; - void setKernelUnitLengthX(float); + bool setKernelUnitLengthX(float); float kernelUnitLengthY() const; - void setKernelUnitLengthY(float); + bool setKernelUnitLengthY(float); const LightSource* lightSource() const; void setLightSource(PassRefPtr<LightSource>); diff --git a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp b/Source/WebCore/platform/graphics/filters/FilterEffect.cpp index 85154b5..f07d00c 100644 --- a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp +++ b/Source/WebCore/platform/graphics/filters/FilterEffect.cpp @@ -77,6 +77,16 @@ FilterEffect* FilterEffect::inputEffect(unsigned number) const return m_inputEffects.at(number).get(); } +void FilterEffect::clearResult() +{ + if (m_imageBufferResult) + m_imageBufferResult.clear(); + if (m_unmultipliedImageResult) + m_unmultipliedImageResult.clear(); + if (m_premultipliedImageResult) + m_premultipliedImageResult.clear(); +} + ImageBuffer* FilterEffect::asImageBuffer() { if (!hasResult()) @@ -109,7 +119,7 @@ PassRefPtr<ByteArray> FilterEffect::asPremultipliedImage(const IntRect& rect) 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()) + if (rect.x() < 0 || rect.y() < 0 || rect.maxY() > m_absolutePaintRect.width() || rect.maxY() > m_absolutePaintRect.height()) memset(destination->data(), 0, destination->length()); int xOrigin = rect.x(); @@ -118,7 +128,7 @@ inline void FilterEffect::copyImageBytes(ByteArray* source, ByteArray* destinati xDest = -xOrigin; xOrigin = 0; } - int xEnd = rect.right(); + int xEnd = rect.maxX(); if (xEnd > m_absolutePaintRect.width()) xEnd = m_absolutePaintRect.width(); @@ -128,7 +138,7 @@ inline void FilterEffect::copyImageBytes(ByteArray* source, ByteArray* destinati yDest = -yOrigin; yOrigin = 0; } - int yEnd = rect.bottom(); + int yEnd = rect.maxY(); if (yEnd > m_absolutePaintRect.height()) yEnd = m_absolutePaintRect.height(); diff --git a/Source/WebCore/platform/graphics/filters/FilterEffect.h b/Source/WebCore/platform/graphics/filters/FilterEffect.h index 062dd1b..2de8ac5 100644 --- a/Source/WebCore/platform/graphics/filters/FilterEffect.h +++ b/Source/WebCore/platform/graphics/filters/FilterEffect.h @@ -53,6 +53,7 @@ public: virtual ~FilterEffect(); bool hasResult() const { return m_imageBufferResult || m_unmultipliedImageResult || m_premultipliedImageResult; } + void clearResult(); ImageBuffer* asImageBuffer(); PassRefPtr<ByteArray> asUnmultipliedImage(const IntRect&); PassRefPtr<ByteArray> asPremultipliedImage(const IntRect&); diff --git a/Source/WebCore/platform/graphics/filters/LightSource.cpp b/Source/WebCore/platform/graphics/filters/LightSource.cpp index de0691e..cf262e8 100644 --- a/Source/WebCore/platform/graphics/filters/LightSource.cpp +++ b/Source/WebCore/platform/graphics/filters/LightSource.cpp @@ -3,6 +3,7 @@ * 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> + * Copyright (C) 2011 Renata Hodovan <reni@webkit.org>, University of Szeged. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -33,136 +34,80 @@ namespace WebCore { -void PointLightSource::initPaintingData(PaintingData&) +bool LightSource::setAzimuth(float azimuth) { + if (m_type == LS_DISTANT) + return static_cast<DistantLightSource*>(this)->setAzimuth(azimuth); + return false; } -void PointLightSource::updatePaintingData(PaintingData& paintingData, int x, int y, float z) +bool LightSource::setElevation(float elevation) { - 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(); + if (m_type == LS_DISTANT) + return static_cast<DistantLightSource*>(this)->setElevation(elevation); + return false; } -// 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) +bool LightSource::setX(float x) { - 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; + if (m_type == LS_SPOT) + return static_cast<SpotLightSource*>(this)->setX(x); + if (m_type == LS_POINT) + return static_cast<PointLightSource*>(this)->setX(x); + return false; } -void SpotLightSource::updatePaintingData(PaintingData& paintingData, int x, int y, float z) +bool LightSource::setY(float y) { - 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); + if (m_type == LS_SPOT) + return static_cast<SpotLightSource*>(this)->setY(y); + if (m_type == LS_POINT) + return static_cast<PointLightSource*>(this)->setY(y); + return false; } -void DistantLightSource::initPaintingData(PaintingData& paintingData) +bool LightSource::setZ(float z) { - 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; + if (m_type == LS_SPOT) + return static_cast<SpotLightSource*>(this)->setZ(z); + if (m_type == LS_POINT) + return static_cast<PointLightSource*>(this)->setZ(z); + return false; } -void DistantLightSource::updatePaintingData(PaintingData&, int, int, float) +bool LightSource::setPointsAtX(float pointsAtX) { + if (m_type == LS_SPOT) + return static_cast<SpotLightSource*>(this)->setPointsAtX(pointsAtX); + return false; } -static TextStream& operator<<(TextStream& ts, const FloatPoint3D& p) +bool LightSource::setPointsAtY(float pointsAtY) { - ts << "x=" << p.x() << " y=" << p.y() << " z=" << p.z(); - return ts; + if (m_type == LS_SPOT) + return static_cast<SpotLightSource*>(this)->setPointsAtY(pointsAtY); + return false; } -TextStream& PointLightSource::externalRepresentation(TextStream& ts) const +bool LightSource::setPointsAtZ(float pointsAtZ) { - ts << "[type=POINT-LIGHT] "; - ts << "[position=\"" << position() << "\"]"; - return ts; + if (m_type == LS_SPOT) + return static_cast<SpotLightSource*>(this)->setPointsAtZ(pointsAtZ); + return false; } -TextStream& SpotLightSource::externalRepresentation(TextStream& ts) const +bool LightSource::setSpecularExponent(float specularExponent) { - ts << "[type=SPOT-LIGHT] "; - ts << "[position=\"" << position() << "\"]"; - ts << "[direction=\"" << direction() << "\"]"; - ts << "[specularExponent=\"" << specularExponent() << "\"]"; - ts << "[limitingConeAngle=\"" << limitingConeAngle() << "\"]"; - return ts; + if (m_type == LS_SPOT) + return static_cast<SpotLightSource*>(this)->setSpecularExponent(specularExponent); + return false; } -TextStream& DistantLightSource::externalRepresentation(TextStream& ts) const +bool LightSource::setLimitingConeAngle(float limitingConeAngle) { - ts << "[type=DISTANT-LIGHT] "; - ts << "[azimuth=\"" << azimuth() << "\"]"; - ts << "[elevation=\"" << elevation() << "\"]"; - return ts; + if (m_type == LS_SPOT) + return static_cast<SpotLightSource*>(this)->setLimitingConeAngle(limitingConeAngle); + return false; } } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/filters/LightSource.h b/Source/WebCore/platform/graphics/filters/LightSource.h index 013e910..24c319a 100644 --- a/Source/WebCore/platform/graphics/filters/LightSource.h +++ b/Source/WebCore/platform/graphics/filters/LightSource.h @@ -74,6 +74,17 @@ public: // specified "surfaceScale" constant, which type is <number> in the SVG standard virtual void updatePaintingData(PaintingData&, int x, int y, float z) = 0; + bool setAzimuth(float); + bool setElevation(float); + bool setX(float); + bool setY(float); + bool setZ(float); + bool setPointsAtX(float); + bool setPointsAtY(float); + bool setPointsAtZ(float); + bool setSpecularExponent(float); + bool setLimitingConeAngle(float); + private: LightType m_type; }; diff --git a/Source/WebCore/platform/graphics/filters/PointLightSource.cpp b/Source/WebCore/platform/graphics/filters/PointLightSource.cpp new file mode 100644 index 0000000..207ed8e --- /dev/null +++ b/Source/WebCore/platform/graphics/filters/PointLightSource.cpp @@ -0,0 +1,91 @@ +/* + * 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> + * Copyright (C) 2011 University of Szeged + * Copyright (C) 2011 Renata Hodovan <reni@webkit.org> + * + * 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 "PointLightSource.h" + +#include "TextStream.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(); +} + +bool PointLightSource::setX(float x) +{ + if (m_position.x() == x) + return false; + m_position.setX(x); + return true; +} + +bool PointLightSource::setY(float y) +{ + if (m_position.y() == y) + return false; + m_position.setY(y); + return true; +} + +bool PointLightSource::setZ(float z) +{ + if (m_position.z() == z) + return false; + m_position.setZ(z); + return true; +} + +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; +} + +}; // namespace WebCore + +#endif // ENABLE(FILTERS) diff --git a/Source/WebCore/platform/graphics/filters/PointLightSource.h b/Source/WebCore/platform/graphics/filters/PointLightSource.h index 163c829..a93bf2c 100644 --- a/Source/WebCore/platform/graphics/filters/PointLightSource.h +++ b/Source/WebCore/platform/graphics/filters/PointLightSource.h @@ -36,6 +36,9 @@ public: } const FloatPoint3D& position() const { return m_position; } + bool setX(float); + bool setY(float); + bool setZ(float); virtual void initPaintingData(PaintingData&); virtual void updatePaintingData(PaintingData&, int x, int y, float z); diff --git a/Source/WebCore/platform/graphics/filters/SpotLightSource.cpp b/Source/WebCore/platform/graphics/filters/SpotLightSource.cpp new file mode 100644 index 0000000..648fcae --- /dev/null +++ b/Source/WebCore/platform/graphics/filters/SpotLightSource.cpp @@ -0,0 +1,198 @@ +/* + * 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> + * Copyright (C) 2011 University of Szeged + * Copyright (C) 2011 Renata Hodovan <reni@webkit.org> + * + * 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 "SpotLightSource.h" + +#include "TextStream.h" + +namespace WebCore { + +// 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); +} + +bool SpotLightSource::setX(float x) +{ + if (m_position.x() == x) + return false; + m_position.setX(x); + return true; +} + +bool SpotLightSource::setY(float y) +{ + if (m_position.y() == y) + return false; + m_position.setY(y); + return true; +} + +bool SpotLightSource::setZ(float z) +{ + if (m_position.z() == z) + return false; + m_position.setZ(z); + return true; +} + +bool SpotLightSource::setPointsAtX(float pointsAtX) +{ + if (m_direction.x() == pointsAtX) + return false; + m_direction.setX(pointsAtX); + return true; +} + +bool SpotLightSource::setPointsAtY(float pointsAtY) +{ + if (m_direction.y() == pointsAtY) + return false; + m_direction.setY(pointsAtY); + return true; +} + +bool SpotLightSource::setPointsAtZ(float pointsAtZ) +{ + if (m_direction.z() == pointsAtZ) + return false; + m_direction.setZ(pointsAtZ); + return true; +} + +bool SpotLightSource::setSpecularExponent(float specularExponent) +{ + if (m_specularExponent == specularExponent) + return false; + m_specularExponent = specularExponent; + return true; +} + +bool SpotLightSource::setLimitingConeAngle(float limitingConeAngle) +{ + if (m_limitingConeAngle == limitingConeAngle) + return false; + m_limitingConeAngle = limitingConeAngle; + return true; +} + +static TextStream& operator<<(TextStream& ts, const FloatPoint3D& p) +{ + ts << "x=" << p.x() << " y=" << p.y() << " z=" << p.z(); + 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; +} + +}; // namespace WebCore + +#endif // ENABLE(FILTERS) diff --git a/Source/WebCore/platform/graphics/filters/SpotLightSource.h b/Source/WebCore/platform/graphics/filters/SpotLightSource.h index cd6a614..b4f1b61 100644 --- a/Source/WebCore/platform/graphics/filters/SpotLightSource.h +++ b/Source/WebCore/platform/graphics/filters/SpotLightSource.h @@ -37,10 +37,18 @@ public: } const FloatPoint3D& position() const { return m_position; } + bool setX(float); + bool setY(float); + bool setZ(float); const FloatPoint3D& direction() const { return m_direction; } + bool setPointsAtX(float); + bool setPointsAtY(float); + bool setPointsAtZ(float); float specularExponent() const { return m_specularExponent; } + bool setSpecularExponent(float); float limitingConeAngle() const { return m_limitingConeAngle; } + bool setLimitingConeAngle(float); virtual void initPaintingData(PaintingData&); virtual void updatePaintingData(PaintingData&, int x, int y, float z); |