Changeset 49402 in webkit


Ignore:
Timestamp:
Oct 9, 2009 1:51:19 PM (14 years ago)
Author:
krit@webkit.org
Message:

2009-10-09 Dirk Schulze <krit@webkit.org>

Reviewed by Oliver Hunt.

SVG Filter feGaussianBlur implementation is missing
https://bugs.webkit.org/show_bug.cgi?id=28141

This is the implementation of GaussianBlur filter for SVG.

There is already a test for feGaussianBlur
Test: svg/W3C-SVG-1.1/filters-gauss-01-b-w3c.svg

Test: svg/filters/feGaussianBlur.svg

  • platform/graphics/filters/FilterEffect.cpp: (WebCore::FilterEffect::FilterEffect):
  • platform/graphics/filters/FilterEffect.h: (WebCore::FilterEffect::isAlphaImage): (WebCore::FilterEffect::setIsAlphaImage):
  • platform/graphics/filters/SourceAlpha.cpp: (WebCore::SourceAlpha::apply):
  • svg/graphics/filters/SVGFEGaussianBlur.cpp: (WebCore::boxBlur): (WebCore::FEGaussianBlur::apply):

Test for feGaussianBlur implementation

  • platform/mac/svg/filters/feGaussianBlur-expected.checksum: Added.
  • platform/mac/svg/filters/feGaussianBlur-expected.png: Added.
  • platform/mac/svg/filters/feGaussianBlur-expected.txt: Added.
  • svg/filters/feGaussianBlur.svg: Added.
Location:
trunk
Files:
4 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r49400 r49402  
     12009-10-09  Dirk Schulze  <krit@webkit.org>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        Test for feGaussianBlur implementation
     6
     7        * platform/mac/svg/filters/feGaussianBlur-expected.checksum: Added.
     8        * platform/mac/svg/filters/feGaussianBlur-expected.png: Added.
     9        * platform/mac/svg/filters/feGaussianBlur-expected.txt: Added.
     10        * svg/filters/feGaussianBlur.svg: Added.
     11
    1122009-10-09  Dirk Schulze  <krit@webkit.org>
    213
  • trunk/WebCore/ChangeLog

    r49401 r49402  
     12009-10-09  Dirk Schulze  <krit@webkit.org>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        SVG Filter feGaussianBlur implementation is missing
     6        [https://bugs.webkit.org/show_bug.cgi?id=28141]
     7
     8        This is the implementation of GaussianBlur filter for SVG.
     9
     10        There is already a test for feGaussianBlur
     11        Test: svg/W3C-SVG-1.1/filters-gauss-01-b-w3c.svg
     12
     13        Test: svg/filters/feGaussianBlur.svg
     14
     15        * platform/graphics/filters/FilterEffect.cpp:
     16        (WebCore::FilterEffect::FilterEffect):
     17        * platform/graphics/filters/FilterEffect.h:
     18        (WebCore::FilterEffect::isAlphaImage):
     19        (WebCore::FilterEffect::setIsAlphaImage):
     20        * platform/graphics/filters/SourceAlpha.cpp:
     21        (WebCore::SourceAlpha::apply):
     22        * svg/graphics/filters/SVGFEGaussianBlur.cpp:
     23        (WebCore::boxBlur):
     24        (WebCore::FEGaussianBlur::apply):
     25
    1262009-10-09  Philippe Normand  <pnormand@igalia.com>
    227
  • trunk/WebCore/platform/graphics/filters/FilterEffect.cpp

    r47456 r49402  
    3434    , m_hasWidth(false)
    3535    , m_hasHeight(false)
     36    , m_alphaImage(false)
    3637{
    3738}
  • trunk/WebCore/platform/graphics/filters/FilterEffect.h

    r47456 r49402  
    8080        IntRect calculateDrawingIntRect(const FloatRect&);
    8181
     82        // black image with different alpha values
     83        bool isAlphaImage() { return m_alphaImage; }
     84        void setIsAlphaImage(bool alphaImage) { m_alphaImage = alphaImage; }
     85
    8286        virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return filter->filterRegion(); }
    8387        virtual FloatRect calculateEffectRect(Filter*);
     
    103107        bool m_hasHeight : 1;
    104108
     109        bool m_alphaImage;
     110
    105111        FloatRect m_subRegion;
    106112        FloatRect m_unionOfChildEffectSubregions;
  • trunk/WebCore/platform/graphics/filters/SourceAlpha.cpp

    r49153 r49402  
    6060        return;
    6161
     62    setIsAlphaImage(true);
     63
    6264    FloatRect imageRect(FloatPoint(), filter->sourceImage()->image()->size());
    6365    filterContext->save();
  • trunk/WebCore/svg/graphics/filters/SVGFEGaussianBlur.cpp

    r44296 r49402  
    33                  2004, 2005 Rob Buis <buis@kde.org>
    44                  2005 Eric Seidel <eric@webkit.org>
     5                  2009 Dirk Schulze <krit@webkit.org>
    56
    67    This library is free software; you can redistribute it and/or
     
    2425#if ENABLE(SVG) && ENABLE(FILTERS)
    2526#include "SVGFEGaussianBlur.h"
     27
     28#include "CanvasPixelArray.h"
     29#include "Filter.h"
     30#include "GraphicsContext.h"
     31#include "ImageData.h"
    2632#include "SVGRenderTreeAsText.h"
    27 #include "Filter.h"
     33#include <math.h>
    2834
    2935namespace WebCore {
     
    6268}
    6369
    64 void FEGaussianBlur::apply(Filter*)
     70void boxBlur(CanvasPixelArray*& srcPixelArray, CanvasPixelArray*& dstPixelArray,
     71                 unsigned dx, int stride, int strideLine, int effectWidth, int effectHeight, bool alphaImage)
    6572{
     73    int dxLeft = static_cast<int>(floor(dx / 2));
     74    int dxRight = dx - dxLeft;
     75
     76    for (int y = 0; y < effectHeight; ++y) {
     77        int line = y * strideLine;
     78        for (int channel = 3; channel >= 0; --channel) {
     79            int sum = 0;
     80            // Fill the kernel
     81            int maxKernelSize = std::min(dxRight, effectWidth);
     82            for (int i = 0; i < maxKernelSize; ++i)
     83                sum += srcPixelArray->get(line + i * stride + channel);
     84
     85            // Blurring
     86            for (int x = 0; x < effectWidth; ++x) {
     87                int pixelByteOffset = line + x * stride + channel;
     88                dstPixelArray->set(pixelByteOffset, static_cast<unsigned char>(sum / dx));
     89                if (x >= dxLeft)
     90                    sum -= srcPixelArray->get(pixelByteOffset - dxLeft * stride);
     91                if (x + dxRight < effectWidth)
     92                    sum += srcPixelArray->get(pixelByteOffset + dxRight * stride);
     93            }
     94            if (alphaImage) // Source image is black, it just has different alpha values
     95                break;
     96        }
     97    }
     98}
     99
     100void FEGaussianBlur::apply(Filter* filter)
     101{
     102    m_in->apply(filter);
     103    if (!m_in->resultImage())
     104        return;
     105
     106    if (!getEffectContext())
     107        return;
     108
     109    setIsAlphaImage(m_in->isAlphaImage());
     110
     111    if (m_x == 0 || m_y == 0)
     112        return;
     113
     114    unsigned sdx = static_cast<unsigned>(floor(m_x * 3 * sqrt(2 * M_PI) / 4.f + 0.5f));
     115    unsigned sdy = static_cast<unsigned>(floor(m_y * 3 * sqrt(2 * M_PI) / 4.f + 0.5f));
     116
     117    IntRect effectDrawingRect = calculateDrawingIntRect(m_in->subRegion());
     118    RefPtr<ImageData> srcImageData(m_in->resultImage()->getPremultipliedImageData(effectDrawingRect));
     119    CanvasPixelArray* srcPixelArray(srcImageData->data());
     120
     121    IntRect imageRect(IntPoint(), resultImage()->size());
     122    RefPtr<ImageData> tmpImageData = ImageData::create(imageRect.width(), imageRect.height());
     123    CanvasPixelArray* tmpPixelArray(tmpImageData->data());
     124
     125    int stride = 4 * imageRect.width();
     126    for (int i = 0; i < 3; ++i) {
     127        boxBlur(srcPixelArray, tmpPixelArray, sdx, 4, stride, imageRect.width(), imageRect.height(), isAlphaImage());
     128        boxBlur(tmpPixelArray, srcPixelArray, sdy, stride, 4, imageRect.height(), imageRect.width(), isAlphaImage());
     129    }
     130
     131    resultImage()->putPremultipliedImageData(srcImageData.get(), imageRect, IntPoint());
    66132}
    67133
Note: See TracChangeset for help on using the changeset viewer.