| Index: Source/core/platform/graphics/ShadowBlur.cpp
|
| diff --git a/Source/core/platform/graphics/ShadowBlur.cpp b/Source/core/platform/graphics/ShadowBlur.cpp
|
| deleted file mode 100644
|
| index aa0bf4c0fb9562b87d41d5e47a3c547943cc421c..0000000000000000000000000000000000000000
|
| --- a/Source/core/platform/graphics/ShadowBlur.cpp
|
| +++ /dev/null
|
| @@ -1,198 +0,0 @@
|
| -/*
|
| - * Copyright (C) 2011 Apple Inc. All rights reserved.
|
| - * Copyright (C) 2010 Sencha, Inc. All rights reserved.
|
| - * Copyright (C) 2010 Igalia S.L. All rights reserved.
|
| - * Copyright (C) Research In Motion Limited 2011. 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 APPLE INC. ``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 APPLE COMPUTER, INC. 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"
|
| -#include "core/platform/graphics/ShadowBlur.h"
|
| -
|
| -#include "wtf/MathExtras.h"
|
| -#include <algorithm>
|
| -
|
| -using namespace std;
|
| -
|
| -namespace WebCore {
|
| -
|
| -enum {
|
| - leftLobe = 0,
|
| - rightLobe = 1
|
| -};
|
| -
|
| -ShadowBlur::ShadowBlur(const FloatSize& radius, const FloatSize& offset, const Color& color)
|
| - : m_color(color)
|
| - , m_blurRadius(radius)
|
| - , m_offset(offset)
|
| - , m_shadowsIgnoreTransforms(false)
|
| -{
|
| - updateShadowBlurValues();
|
| -}
|
| -
|
| -void ShadowBlur::updateShadowBlurValues()
|
| -{
|
| - // Limit blur radius to 128 to avoid lots of very expensive blurring.
|
| - m_blurRadius = m_blurRadius.shrunkTo(FloatSize(128, 128));
|
| -
|
| - // The type of shadow is decided by the blur radius, shadow offset, and shadow color.
|
| - if (!m_color.isValid() || !m_color.alpha()) {
|
| - // Can't paint the shadow with invalid or invisible color.
|
| - m_type = NoShadow;
|
| - } else if (m_blurRadius.width() > 0 || m_blurRadius.height() > 0) {
|
| - // Shadow is always blurred, even the offset is zero.
|
| - m_type = BlurShadow;
|
| - } else if (!m_offset.width() && !m_offset.height()) {
|
| - // Without blur and zero offset means the shadow is fully hidden.
|
| - m_type = NoShadow;
|
| - } else
|
| - m_type = SolidShadow;
|
| -}
|
| -
|
| -// Instead of integer division, we use 17.15 for fixed-point division.
|
| -static const int blurSumShift = 15;
|
| -
|
| -// Takes a two dimensional array with three rows and two columns for the lobes.
|
| -static void calculateLobes(int lobes[][2], float blurRadius, bool shadowsIgnoreTransforms)
|
| -{
|
| - int diameter;
|
| - if (shadowsIgnoreTransforms)
|
| - diameter = max(2, static_cast<int>(floorf((2 / 3.f) * blurRadius))); // Canvas shadow. FIXME: we should adjust the blur radius higher up.
|
| - else {
|
| - // http://dev.w3.org/csswg/css3-background/#box-shadow
|
| - // Approximate a Gaussian blur with a standard deviation equal to half the blur radius,
|
| - // which http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement tell us how to do.
|
| - // However, shadows rendered according to that spec will extend a little further than m_blurRadius,
|
| - // so we apply a fudge factor to bring the radius down slightly.
|
| - float stdDev = blurRadius / 2;
|
| - const float gaussianKernelFactor = 3 / 4.f * sqrtf(2 * piFloat);
|
| - const float fudgeFactor = 0.88f;
|
| - diameter = max(2, static_cast<int>(floorf(stdDev * gaussianKernelFactor * fudgeFactor + 0.5f)));
|
| - }
|
| -
|
| - if (diameter & 1) {
|
| - // if d is odd, use three box-blurs of size 'd', centered on the output pixel.
|
| - int lobeSize = (diameter - 1) / 2;
|
| - lobes[0][leftLobe] = lobeSize;
|
| - lobes[0][rightLobe] = lobeSize;
|
| - lobes[1][leftLobe] = lobeSize;
|
| - lobes[1][rightLobe] = lobeSize;
|
| - lobes[2][leftLobe] = lobeSize;
|
| - lobes[2][rightLobe] = lobeSize;
|
| - } else {
|
| - // if d is even, two box-blurs of size 'd' (the first one centered on the pixel boundary
|
| - // between the output pixel and the one to the left, the second one centered on the pixel
|
| - // boundary between the output pixel and the one to the right) and one box blur of size 'd+1' centered on the output pixel
|
| - int lobeSize = diameter / 2;
|
| - lobes[0][leftLobe] = lobeSize;
|
| - lobes[0][rightLobe] = lobeSize - 1;
|
| - lobes[1][leftLobe] = lobeSize - 1;
|
| - lobes[1][rightLobe] = lobeSize;
|
| - lobes[2][leftLobe] = lobeSize;
|
| - lobes[2][rightLobe] = lobeSize;
|
| - }
|
| -}
|
| -
|
| -void ShadowBlur::blurLayerImage(unsigned char* imageData, const IntSize& size, int rowStride)
|
| -{
|
| - const int channels[4] = { 3, 0, 1, 3 };
|
| -
|
| - int lobes[3][2]; // indexed by pass, and left/right lobe
|
| - calculateLobes(lobes, m_blurRadius.width(), m_shadowsIgnoreTransforms);
|
| -
|
| - // First pass is horizontal.
|
| - int stride = 4;
|
| - int delta = rowStride;
|
| - int final = size.height();
|
| - int dim = size.width();
|
| -
|
| - // Two stages: horizontal and vertical
|
| - for (int pass = 0; pass < 2; ++pass) {
|
| - unsigned char* pixels = imageData;
|
| -
|
| - if (!pass && !m_blurRadius.width())
|
| - final = 0; // Do no work if horizonal blur is zero.
|
| -
|
| - for (int j = 0; j < final; ++j, pixels += delta) {
|
| - // For each step, we blur the alpha in a channel and store the result
|
| - // in another channel for the subsequent step.
|
| - // We use sliding window algorithm to accumulate the alpha values.
|
| - // This is much more efficient than computing the sum of each pixels
|
| - // covered by the box kernel size for each x.
|
| - for (int step = 0; step < 3; ++step) {
|
| - int side1 = lobes[step][leftLobe];
|
| - int side2 = lobes[step][rightLobe];
|
| - int pixelCount = side1 + 1 + side2;
|
| - int invCount = ((1 << blurSumShift) + pixelCount - 1) / pixelCount;
|
| - int ofs = 1 + side2;
|
| - int alpha1 = pixels[channels[step]];
|
| - int alpha2 = pixels[(dim - 1) * stride + channels[step]];
|
| -
|
| - unsigned char* ptr = pixels + channels[step + 1];
|
| - unsigned char* prev = pixels + stride + channels[step];
|
| - unsigned char* next = pixels + ofs * stride + channels[step];
|
| -
|
| - int i;
|
| - int sum = side1 * alpha1 + alpha1;
|
| - int limit = (dim < side2 + 1) ? dim : side2 + 1;
|
| -
|
| - for (i = 1; i < limit; ++i, prev += stride)
|
| - sum += *prev;
|
| -
|
| - if (limit <= side2)
|
| - sum += (side2 - limit + 1) * alpha2;
|
| -
|
| - limit = (side1 < dim) ? side1 : dim;
|
| - for (i = 0; i < limit; ptr += stride, next += stride, ++i, ++ofs) {
|
| - *ptr = (sum * invCount) >> blurSumShift;
|
| - sum += ((ofs < dim) ? *next : alpha2) - alpha1;
|
| - }
|
| -
|
| - prev = pixels + channels[step];
|
| - for (; ofs < dim; ptr += stride, prev += stride, next += stride, ++i, ++ofs) {
|
| - *ptr = (sum * invCount) >> blurSumShift;
|
| - sum += (*next) - (*prev);
|
| - }
|
| -
|
| - for (; i < dim; ptr += stride, prev += stride, ++i) {
|
| - *ptr = (sum * invCount) >> blurSumShift;
|
| - sum += alpha2 - (*prev);
|
| - }
|
| - }
|
| - }
|
| -
|
| - // Last pass is vertical.
|
| - stride = rowStride;
|
| - delta = 4;
|
| - final = size.width();
|
| - dim = size.height();
|
| -
|
| - if (!m_blurRadius.height())
|
| - break;
|
| -
|
| - if (m_blurRadius.width() != m_blurRadius.height())
|
| - calculateLobes(lobes, m_blurRadius.height(), m_shadowsIgnoreTransforms);
|
| - }
|
| -}
|
| -
|
| -} // namespace WebCore
|
|
|