Changeset 65661 in webkit
- Timestamp:
- Aug 19, 2010 4:00:26 AM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r65659 r65661 1 2010-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 1 37 2010-08-19 Andreas Kling <andreas.kling@nokia.com> 2 38 -
trunk/WebCore/platform/graphics/GraphicsContext.h
r65569 r65661 295 295 #if PLATFORM(CAIRO) 296 296 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); 299 299 #endif 300 300 -
trunk/WebCore/platform/graphics/cairo/FontCairo.cpp
r63176 r65661 95 95 IntSize shadowBufferSize; 96 96 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); 99 99 100 100 // Draw shadow into a new ImageBuffer … … 103 103 cairo_t* shadowCr = shadowContext->platformContext(); 104 104 105 cairo_translate(shadowCr, kernelSize, extents.height + kernelSize);105 cairo_translate(shadowCr, radius, extents.height + radius); 106 106 107 107 cairo_set_scaled_font(shadowCr, font->platformData().scaledFont()); … … 114 114 } 115 115 cairo_translate(cr, 0.0, -extents.height); 116 context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, kernelSize);116 context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius); 117 117 #else 118 118 cairo_translate(cr, shadowSize.width(), shadowSize.height()); -
trunk/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
r65530 r65661 62 62 #include "GraphicsContextPrivate.h" 63 63 64 using namespace std; 65 64 66 #ifndef M_PI 65 67 #define M_PI 3.14159265358979323846 … … 174 176 } 175 177 176 void GraphicsContext::calculateShadowBufferDimensions(IntSize& shadowBufferSize, FloatRect& shadowRect, float& kernelSize, const FloatRect& sourceRect, const FloatSize& shadowSize, float shadowBlur)178 void GraphicsContext::calculateShadowBufferDimensions(IntSize& shadowBufferSize, FloatRect& shadowRect, float& radius, const FloatRect& sourceRect, const FloatSize& shadowSize, float shadowBlur) 177 179 { 178 180 #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); 184 185 185 186 // determine dimensions of shadow rect 186 187 shadowRect = FloatRect(sourceRect.location(), shadowBufferSize); 187 shadowRect.move(shadowSize.width() - kernelSize, shadowSize.height() - kernelSize);188 shadowRect.move(shadowSize.width() - radius, shadowSize.height() - radius); 188 189 #endif 189 190 } … … 210 211 IntSize shadowBufferSize; 211 212 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); 214 215 215 216 // Create suitably-sized ImageBuffer to hold the shadow. … … 219 220 cairo_t* shadowContext = shadowBuffer->context()->platformContext(); 220 221 copyContextProperties(cr, shadowContext); 221 cairo_translate(shadowContext, -rect.x() + kernelSize, -rect.y() + kernelSize);222 cairo_translate(shadowContext, -rect.x() + radius, -rect.y() + radius); 222 223 cairo_new_path(shadowContext); 223 224 cairo_append_path(shadowContext, path); … … 228 229 setPlatformStroke(context, shadowContext, gcp); 229 230 230 context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, kernelSize);231 context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius); 231 232 #endif 232 233 } … … 632 633 IntSize shadowBufferSize; 633 634 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); 636 637 637 638 // Draw shadow into a new ImageBuffer 638 639 OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize); 639 640 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); 643 644 #endif 644 645 } … … 921 922 } 922 923 923 void GraphicsContext::createPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const Color& shadowColor, const FloatRect& shadowRect, float kernelSize)924 void GraphicsContext::createPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const Color& shadowColor, const FloatRect& shadowRect, float radius) 924 925 { 925 926 #if ENABLE(FILTERS) 926 927 cairo_t* cr = m_data->cr; 927 928 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) { 930 934 setColor(cr, shadowColor); 931 935 cairo_mask_surface(cr, buffer->m_data.m_surface, shadowRect.x(), shadowRect.y()); 932 936 return; 933 937 } 934 935 // limit kernel size to 1000, this is what CG is doing.936 kernelSize = std::min(1000.f, kernelSize);937 938 938 939 // create filter … … 942 943 source->setScaledSubRegion(FloatRect(FloatPoint(), shadowRect.size())); 943 944 source->setIsAlphaImage(true); 944 RefPtr<FilterEffect> blur = FEGaussianBlur::create(source.get(), kernelSize, kernelSize);945 RefPtr<FilterEffect> blur = FEGaussianBlur::create(source.get(), sd, sd); 945 946 blur->setScaledSubRegion(FloatRect(FloatPoint(), shadowRect.size())); 946 947 blur->apply(filter.get()); -
trunk/WebCore/platform/graphics/cairo/ImageCairo.cpp
r65530 r65661 142 142 IntSize shadowBufferSize; 143 143 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); 146 146 shadowColor = colorWithOverrideAlpha(shadowColor.rgb(), (shadowColor.alpha() * context->getAlpha()) / 255.f); 147 147 … … 154 154 cairo_fill(shadowContext); 155 155 156 context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, kernelSize);156 context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius); 157 157 } 158 158 #endif -
trunk/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
r65153 r65661 201 201 } 202 202 203 float 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 203 209 } // namespace WebCore 204 210 -
trunk/WebCore/platform/graphics/filters/FEGaussianBlur.h
r65138 r65661 44 44 TextStream& externalRepresentation(TextStream&, int indent) const; 45 45 46 static float calculateStdDeviation(float); 47 46 48 private: 47 49 FEGaussianBlur(FilterEffect*, const float&, const float&);
Note: See TracChangeset
for help on using the changeset viewer.