1/* 2 * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com> 3 * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> 4 * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> 5 * Copyright (C) 2005 Eric Seidel <eric@webkit.org> 6 * Copyright (C) 2010 Zoltan Herczeg <zherczeg@webkit.org> 7 * Copyright (C) 2011 University of Szeged 8 * Copyright (C) 2011 Renata Hodovan <reni@webkit.org> 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 27 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include "config.h" 33#include "platform/graphics/filters/SpotLightSource.h" 34 35#include "platform/text/TextStream.h" 36 37namespace WebCore { 38 39// spot-light edge darkening depends on an absolute treshold 40// according to the SVG 1.1 SE light regression tests 41static const float antiAliasTreshold = 0.016f; 42 43void SpotLightSource::initPaintingData(PaintingData& paintingData) const 44{ 45 paintingData.privateColorVector = paintingData.colorVector; 46 paintingData.directionVector.setX(m_direction.x() - m_position.x()); 47 paintingData.directionVector.setY(m_direction.y() - m_position.y()); 48 paintingData.directionVector.setZ(m_direction.z() - m_position.z()); 49 paintingData.directionVector.normalize(); 50 51 if (!m_limitingConeAngle) { 52 paintingData.coneCutOffLimit = 0.0f; 53 paintingData.coneFullLight = -antiAliasTreshold; 54 } else { 55 float limitingConeAngle = m_limitingConeAngle; 56 if (limitingConeAngle < 0.0f) 57 limitingConeAngle = -limitingConeAngle; 58 if (limitingConeAngle > 90.0f) 59 limitingConeAngle = 90.0f; 60 paintingData.coneCutOffLimit = cosf(deg2rad(180.0f - limitingConeAngle)); 61 paintingData.coneFullLight = paintingData.coneCutOffLimit - antiAliasTreshold; 62 } 63} 64 65void SpotLightSource::updatePaintingData(PaintingData& paintingData, int x, int y, float z) const 66{ 67 paintingData.lightVector.setX(m_position.x() - x); 68 paintingData.lightVector.setY(m_position.y() - y); 69 paintingData.lightVector.setZ(m_position.z() - z); 70 paintingData.lightVectorLength = paintingData.lightVector.length(); 71 72 float cosineOfAngle = (paintingData.lightVector * paintingData.directionVector) / paintingData.lightVectorLength; 73 if (cosineOfAngle > paintingData.coneCutOffLimit) { 74 // No light is produced, scanlines are not updated 75 paintingData.colorVector.setX(0.0f); 76 paintingData.colorVector.setY(0.0f); 77 paintingData.colorVector.setZ(0.0f); 78 return; 79 } 80 81 // Set the color of the pixel 82 float lightStrength; 83 if (1.0f == m_specularExponent) { 84 lightStrength = -cosineOfAngle; // -cosineOfAngle ^ 1 == -cosineOfAngle 85 } else { 86 lightStrength = powf(-cosineOfAngle, m_specularExponent); 87 } 88 89 if (cosineOfAngle > paintingData.coneFullLight) 90 lightStrength *= (paintingData.coneCutOffLimit - cosineOfAngle) / (paintingData.coneCutOffLimit - paintingData.coneFullLight); 91 92 if (lightStrength > 1.0f) 93 lightStrength = 1.0f; 94 95 paintingData.colorVector.setX(paintingData.privateColorVector.x() * lightStrength); 96 paintingData.colorVector.setY(paintingData.privateColorVector.y() * lightStrength); 97 paintingData.colorVector.setZ(paintingData.privateColorVector.z() * lightStrength); 98} 99 100bool SpotLightSource::setX(float x) 101{ 102 if (m_position.x() == x) 103 return false; 104 m_position.setX(x); 105 return true; 106} 107 108bool SpotLightSource::setY(float y) 109{ 110 if (m_position.y() == y) 111 return false; 112 m_position.setY(y); 113 return true; 114} 115 116bool SpotLightSource::setZ(float z) 117{ 118 if (m_position.z() == z) 119 return false; 120 m_position.setZ(z); 121 return true; 122} 123 124bool SpotLightSource::setPointsAtX(float pointsAtX) 125{ 126 if (m_direction.x() == pointsAtX) 127 return false; 128 m_direction.setX(pointsAtX); 129 return true; 130} 131 132bool SpotLightSource::setPointsAtY(float pointsAtY) 133{ 134 if (m_direction.y() == pointsAtY) 135 return false; 136 m_direction.setY(pointsAtY); 137 return true; 138} 139 140bool SpotLightSource::setPointsAtZ(float pointsAtZ) 141{ 142 if (m_direction.z() == pointsAtZ) 143 return false; 144 m_direction.setZ(pointsAtZ); 145 return true; 146} 147 148bool SpotLightSource::setSpecularExponent(float specularExponent) 149{ 150 specularExponent = std::min(std::max(specularExponent, 1.0f), 128.0f); 151 if (m_specularExponent == specularExponent) 152 return false; 153 m_specularExponent = specularExponent; 154 return true; 155} 156 157bool SpotLightSource::setLimitingConeAngle(float limitingConeAngle) 158{ 159 if (m_limitingConeAngle == limitingConeAngle) 160 return false; 161 m_limitingConeAngle = limitingConeAngle; 162 return true; 163} 164 165static TextStream& operator<<(TextStream& ts, const FloatPoint3D& p) 166{ 167 ts << "x=" << p.x() << " y=" << p.y() << " z=" << p.z(); 168 return ts; 169} 170 171TextStream& SpotLightSource::externalRepresentation(TextStream& ts) const 172{ 173 ts << "[type=SPOT-LIGHT] "; 174 ts << "[position=\"" << position() << "\"]"; 175 ts << "[direction=\"" << direction() << "\"]"; 176 ts << "[specularExponent=\"" << specularExponent() << "\"]"; 177 ts << "[limitingConeAngle=\"" << limitingConeAngle() << "\"]"; 178 return ts; 179} 180 181}; // namespace WebCore 182