Changeset 65661 in webkit


Ignore:
Timestamp:
Aug 19, 2010 4:00:26 AM (14 years ago)
Author:
alex
Message:

2010-08-19 Alejandro G. Castro <alex@igalia.com>

Reviewed by Dirk Schulze.

[GTK] The size of the shadow image uses the standard deviation
size instead of the blur radius
https://bugs.webkit.org/show_bug.cgi?id=40793

The kernelSize variable was renamed to radius and recalculated
considering the CSS3 specification
http://www.w3.org/TR/css3-background/#the-box-shadow, and the
visual result of other browsers. The HTML5 canvas shadow standard
deviation calculation that was used, was not appropiate for the
blur distance specified in the CSS3.

  • platform/graphics/GraphicsContext.h:
  • platform/graphics/cairo/FontCairo.cpp: (WebCore::Font::drawGlyphs):
  • platform/graphics/cairo/GraphicsContextCairo.cpp: (WebCore::GraphicsContext::calculateShadowBufferDimensions): Changed the calculation, now we use the parameter in the style directly as recomended in the CSS3 standard. (WebCore::drawPathShadow): (WebCore::drawBorderlessRectShadow): (WebCore::GraphicsContext::createPlatformShadow): We get the standard deviation from the radius using the new function and we create the filter with that deviation.
  • platform/graphics/cairo/ImageCairo.cpp: (WebCore::BitmapImage::draw):
  • platform/graphics/filters/FEGaussianBlur.cpp: (WebCore::FEGaussianBlur::calculateStdDeviation): Added this function that gets the standard deviation from the blur radius. Required in the CSS3 case where we have this radio and we need the deviation to initialize the algorithm.
  • platform/graphics/filters/FEGaussianBlur.h:
Location:
trunk/WebCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r65659 r65661  
     12010-08-19  Alejandro G. Castro  <alex@igalia.com>
     2
     3        Reviewed by Dirk Schulze.
     4
     5        [GTK] The size of the shadow image uses the standard deviation
     6        size instead of the blur radius
     7        https://bugs.webkit.org/show_bug.cgi?id=40793
     8
     9        The kernelSize variable was renamed to radius and recalculated
     10        considering the CSS3 specification
     11        http://www.w3.org/TR/css3-background/#the-box-shadow, and the
     12        visual result of other browsers. The HTML5 canvas shadow standard
     13        deviation calculation that was used, was not appropiate for the
     14        blur distance specified in the CSS3.
     15
     16        * platform/graphics/GraphicsContext.h:
     17        * platform/graphics/cairo/FontCairo.cpp:
     18        (WebCore::Font::drawGlyphs):
     19        * platform/graphics/cairo/GraphicsContextCairo.cpp:
     20        (WebCore::GraphicsContext::calculateShadowBufferDimensions):
     21        Changed the calculation, now we use the parameter in the style
     22        directly as recomended in the CSS3 standard.
     23        (WebCore::drawPathShadow):
     24        (WebCore::drawBorderlessRectShadow):
     25        (WebCore::GraphicsContext::createPlatformShadow): We get the
     26        standard deviation from the radius using the new function and we
     27        create the filter with that deviation.
     28        * platform/graphics/cairo/ImageCairo.cpp:
     29        (WebCore::BitmapImage::draw):
     30        * platform/graphics/filters/FEGaussianBlur.cpp:
     31        (WebCore::FEGaussianBlur::calculateStdDeviation):  Added this
     32        function that gets the standard deviation from the blur
     33        radius. Required in the CSS3 case where we have this radio and we
     34        need the deviation to initialize the algorithm.
     35        * platform/graphics/filters/FEGaussianBlur.h:
     36
    1372010-08-19  Andreas Kling  <andreas.kling@nokia.com>
    238
  • trunk/WebCore/platform/graphics/GraphicsContext.h

    r65569 r65661  
    295295#if PLATFORM(CAIRO)
    296296        float getAlpha();
    297         void createPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const Color& shadowColor, const FloatRect& shadowRect, float kernelSize);
    298         static void calculateShadowBufferDimensions(IntSize& shadowBufferSize, FloatRect& shadowRect, float& kernelSize, const FloatRect& sourceRect, const FloatSize& shadowSize, float shadowBlur);
     297        void createPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const Color& shadowColor, const FloatRect& shadowRect, float radius);
     298        static void calculateShadowBufferDimensions(IntSize& shadowBufferSize, FloatRect& shadowRect, float& radius, const FloatRect& sourceRect, const FloatSize& shadowSize, float shadowBlur);
    299299#endif
    300300
  • trunk/WebCore/platform/graphics/cairo/FontCairo.cpp

    r63176 r65661  
    9595        IntSize shadowBufferSize;
    9696        FloatRect shadowRect;
    97         float kernelSize = 0.f;
    98         GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, kernelSize, rect, shadowSize, shadowBlur);
     97        float radius = 0;
     98        context->calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, rect, shadowSize, shadowBlur);
    9999
    100100        // Draw shadow into a new ImageBuffer
     
    103103        cairo_t* shadowCr = shadowContext->platformContext();
    104104
    105         cairo_translate(shadowCr, kernelSize, extents.height + kernelSize);
     105        cairo_translate(shadowCr, radius, extents.height + radius);
    106106
    107107        cairo_set_scaled_font(shadowCr, font->platformData().scaledFont());
     
    114114        }
    115115        cairo_translate(cr, 0.0, -extents.height);
    116         context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, kernelSize);
     116        context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
    117117#else
    118118        cairo_translate(cr, shadowSize.width(), shadowSize.height());
  • trunk/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp

    r65530 r65661  
    6262#include "GraphicsContextPrivate.h"
    6363
     64using namespace std;
     65
    6466#ifndef M_PI
    6567#define M_PI 3.14159265358979323846
     
    174176}
    175177
    176 void GraphicsContext::calculateShadowBufferDimensions(IntSize& shadowBufferSize, FloatRect& shadowRect, float& kernelSize, const FloatRect& sourceRect, const FloatSize& shadowSize, float shadowBlur)
     178void GraphicsContext::calculateShadowBufferDimensions(IntSize& shadowBufferSize, FloatRect& shadowRect, float& radius, const FloatRect& sourceRect, const FloatSize& shadowSize, float shadowBlur)
    177179{
    178180#if ENABLE(FILTERS)
    179     // calculate the kernel size according to the HTML5 canvas shadow specification
    180     kernelSize = (shadowBlur < 8 ? shadowBlur / 2.f : sqrt(shadowBlur * 2.f));
    181     int blurRadius = ceil(kernelSize);
    182 
    183     shadowBufferSize = IntSize(sourceRect.width() + blurRadius * 2, sourceRect.height() + blurRadius * 2);
     181    // limit radius to 128
     182    radius = min(128.f, max(shadowBlur, 0.f));
     183
     184    shadowBufferSize = IntSize(sourceRect.width() + radius * 2, sourceRect.height() + radius * 2);
    184185
    185186    // determine dimensions of shadow rect
    186187    shadowRect = FloatRect(sourceRect.location(), shadowBufferSize);
    187     shadowRect.move(shadowSize.width() - kernelSize, shadowSize.height() - kernelSize);
     188    shadowRect.move(shadowSize.width() - radius, shadowSize.height() - radius);
    188189#endif
    189190}
     
    210211    IntSize shadowBufferSize;
    211212    FloatRect shadowRect;
    212     float kernelSize = 0;
    213     GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, kernelSize, rect, shadowSize, shadowBlur);
     213    float radius = 0;
     214    GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, rect, shadowSize, shadowBlur);
    214215
    215216    // Create suitably-sized ImageBuffer to hold the shadow.
     
    219220    cairo_t* shadowContext = shadowBuffer->context()->platformContext();
    220221    copyContextProperties(cr, shadowContext);
    221     cairo_translate(shadowContext, -rect.x() + kernelSize, -rect.y() + kernelSize);
     222    cairo_translate(shadowContext, -rect.x() + radius, -rect.y() + radius);
    222223    cairo_new_path(shadowContext);
    223224    cairo_append_path(shadowContext, path);
     
    228229        setPlatformStroke(context, shadowContext, gcp);
    229230
    230     context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, kernelSize);
     231    context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
    231232#endif
    232233}
     
    632633    IntSize shadowBufferSize;
    633634    FloatRect shadowRect;
    634     float kernelSize = 0;
    635     GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, kernelSize, rect, shadowSize, shadowBlur);
     635    float radius = 0;
     636    GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, rect, shadowSize, shadowBlur);
    636637
    637638    // Draw shadow into a new ImageBuffer
    638639    OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize);
    639640    GraphicsContext* shadowContext = shadowBuffer->context();
    640     shadowContext->fillRect(FloatRect(FloatPoint(kernelSize, kernelSize), rect.size()), rectColor, DeviceColorSpace);
    641 
    642     context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, kernelSize);
     641    shadowContext->fillRect(FloatRect(FloatPoint(radius, radius), rect.size()), rectColor, DeviceColorSpace);
     642
     643    context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
    643644#endif
    644645}
     
    921922}
    922923
    923 void GraphicsContext::createPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const Color& shadowColor, const FloatRect& shadowRect, float kernelSize)
     924void GraphicsContext::createPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const Color& shadowColor, const FloatRect& shadowRect, float radius)
    924925{
    925926#if ENABLE(FILTERS)
    926927    cairo_t* cr = m_data->cr;
    927928
    928     // draw the shadow without blurring, if kernelSize is zero
    929     if (!kernelSize) {
     929    // calculate the standard deviation
     930    float sd = FEGaussianBlur::calculateStdDeviation(radius);
     931
     932    // draw the shadow without blurring, if radius is zero
     933    if (!radius || !sd) {
    930934        setColor(cr, shadowColor);
    931935        cairo_mask_surface(cr, buffer->m_data.m_surface, shadowRect.x(), shadowRect.y());
    932936        return;
    933937    }
    934 
    935     // limit kernel size to 1000, this is what CG is doing.
    936     kernelSize = std::min(1000.f, kernelSize);
    937938
    938939    // create filter
     
    942943    source->setScaledSubRegion(FloatRect(FloatPoint(), shadowRect.size()));
    943944    source->setIsAlphaImage(true);
    944     RefPtr<FilterEffect> blur = FEGaussianBlur::create(source.get(), kernelSize, kernelSize);
     945    RefPtr<FilterEffect> blur = FEGaussianBlur::create(source.get(), sd, sd);
    945946    blur->setScaledSubRegion(FloatRect(FloatPoint(), shadowRect.size()));
    946947    blur->apply(filter.get());
  • trunk/WebCore/platform/graphics/cairo/ImageCairo.cpp

    r65530 r65661  
    142142        IntSize shadowBufferSize;
    143143        FloatRect shadowRect;
    144         float kernelSize (0.0);
    145         GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, kernelSize, dstRect, shadowSize, shadowBlur);
     144        float radius = 0;
     145        context->calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, dstRect, shadowSize, shadowBlur);
    146146        shadowColor = colorWithOverrideAlpha(shadowColor.rgb(), (shadowColor.alpha() *  context->getAlpha()) / 255.f);
    147147
     
    154154        cairo_fill(shadowContext);
    155155
    156         context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, kernelSize);
     156        context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
    157157    }
    158158#endif
  • trunk/WebCore/platform/graphics/filters/FEGaussianBlur.cpp

    r65153 r65661  
    201201}
    202202
     203float FEGaussianBlur::calculateStdDeviation(float radius)
     204{
     205    // Blur radius represents 2/3 times the kernel size, the dest pixel is half of the radius applied 3 times
     206    return max((radius * 2 / 3.f - 0.5f) / gGaussianKernelFactor, 0.f);
     207}
     208
    203209} // namespace WebCore
    204210
  • trunk/WebCore/platform/graphics/filters/FEGaussianBlur.h

    r65138 r65661  
    4444    TextStream& externalRepresentation(TextStream&, int indent) const;
    4545
     46    static float calculateStdDeviation(float);
     47
    4648private:
    4749    FEGaussianBlur(FilterEffect*, const float&, const float&);
Note: See TracChangeset for help on using the changeset viewer.