Changeset 84410 in webkit
- Timestamp:
- Apr 20, 2011 1:05:27 PM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/Android.mk
r84222 r84410 556 556 platform/graphics/RoundedIntRect.cpp \ 557 557 platform/graphics/SegmentedFontData.cpp \ 558 platform/graphics/ShadowBlur.cpp \ 558 559 platform/graphics/SimpleFontData.cpp \ 559 560 platform/graphics/StringTruncator.cpp \ -
trunk/Source/WebCore/CMakeLists.txt
r84224 r84410 1109 1109 platform/graphics/RoundedIntRect.cpp 1110 1110 platform/graphics/SegmentedFontData.cpp 1111 platform/graphics/ShadowBlur.cpp 1111 1112 platform/graphics/SimpleFontData.cpp 1112 1113 platform/graphics/StringTruncator.cpp -
trunk/Source/WebCore/ChangeLog
r84394 r84410 1 2011-04-20 Dirk Schulze <krit@webkit.org> 2 3 Reviewed by Simon Fraser. 4 5 SVG feDropShadow implementation of SVG Filters 1.2 6 https://bugs.webkit.org/show_bug.cgi?id=52513 7 8 Support different radii for horizontal and vertical blurring in ShadowBlur. This is a preperation for feDropShadow. 9 feDropShadow is a new shorthand filter effect for the up-comming Filter 1.0 specification and will use ShadowBlur. 10 feGaussianBlur might make use of ShadowBlur as well later (on SourceAlpha input). 11 Added ShadowBlur to remaining platforms. 12 13 The changes can't be tested before the changes in feGaussianBlur or feDropShadow. Current behavior is not affected. 14 15 * Android.mk: 16 * CMakeLists.txt: 17 * GNUmakefile.list.am: 18 * WebCore.pro: 19 * platform/graphics/FloatSize.h: 20 (WebCore::FloatSize::scale): 21 * platform/graphics/ShadowBlur.cpp: 22 (WebCore::ScratchBuffer::ScratchBuffer): 23 (WebCore::ScratchBuffer::setLastShadowValues): 24 (WebCore::ScratchBuffer::setLastInsetShadowValues): 25 (WebCore::ScratchBuffer::matchesLastShadow): 26 (WebCore::ScratchBuffer::matchesLastInsetShadow): 27 (WebCore::ScratchBuffer::clearScratchBuffer): 28 (WebCore::ShadowBlur::ShadowBlur): 29 (WebCore::calculateLobes): 30 (WebCore::ShadowBlur::blurLayerImage): 31 (WebCore::ShadowBlur::adjustBlurRadius): 32 (WebCore::ShadowBlur::calculateLayerBoundingRect): 33 (WebCore::computeSliceSizesFromRadii): 34 (WebCore::ShadowBlur::templateSize): 35 (WebCore::ShadowBlur::drawInsetShadowWithTiling): 36 (WebCore::ShadowBlur::drawRectShadowWithTiling): 37 (WebCore::ShadowBlur::drawLayerPieces): 38 * platform/graphics/ShadowBlur.h: 39 * platform/graphics/cg/GraphicsContextCG.cpp: 40 (WebCore::GraphicsContext::fillRect): 41 (WebCore::GraphicsContext::fillRoundedRect): 42 (WebCore::GraphicsContext::fillRectWithRoundedHole): 43 1 44 2011-04-19 Roland Steiner <rolandsteiner@chromium.org> 2 45 -
trunk/Source/WebCore/GNUmakefile.list.am
r84224 r84410 2464 2464 Source/WebCore/platform/graphics/SegmentedFontData.cpp \ 2465 2465 Source/WebCore/platform/graphics/SegmentedFontData.h \ 2466 Source/WebCore/platform/graphics/ShadowBlur.cpp \ 2467 Source/WebCore/platform/graphics/ShadowBlur.h \ 2466 2468 Source/WebCore/platform/graphics/SimpleFontData.cpp \ 2467 2469 Source/WebCore/platform/graphics/SimpleFontData.h \ -
trunk/Source/WebCore/WebCore.pro
r84224 r84410 996 996 platform/graphics/RoundedIntRect.cpp \ 997 997 platform/graphics/SegmentedFontData.cpp \ 998 platform/graphics/ShadowBlur.cpp \ 998 999 platform/graphics/SimpleFontData.cpp \ 999 1000 platform/graphics/TiledBackingStore.cpp \ … … 1972 1973 platform/graphics/qt/TransparencyLayer.h \ 1973 1974 platform/graphics/SegmentedFontData.h \ 1975 platform/graphics/ShadowBlur.h \ 1974 1976 platform/graphics/SimpleFontData.h \ 1975 1977 platform/graphics/Tile.h \ -
trunk/Source/WebCore/platform/graphics/FloatSize.h
r84101 r84410 66 66 float aspectRatio() const { return m_width / m_height; } 67 67 68 void scale(float scale) 68 void scale(float s) { scale(s, s); } 69 70 void scale(float scaleX, float scaleY) 69 71 { 70 m_width *= scale ;71 m_height *= scale ;72 m_width *= scaleX; 73 m_height *= scaleY; 72 74 } 73 75 -
trunk/Source/WebCore/platform/graphics/ShadowBlur.cpp
r83422 r84410 43 43 namespace WebCore { 44 44 45 enum { 46 leftLobe = 0, 47 rightLobe = 1 48 }; 49 45 50 static inline int roundUpToMultipleOf32(int d) 46 51 { … … 55 60 ScratchBuffer() 56 61 : m_purgeTimer(this, &ScratchBuffer::timerFired) 57 , m_lastRadius(0)58 62 , m_lastWasInset(false) 59 63 #if !ASSERT_DISABLED … … 80 84 } 81 85 82 void setLastShadowValues( floatradius, const Color& color, ColorSpace colorSpace, const FloatRect& shadowRect, const RoundedIntRect::Radii& radii)86 void setLastShadowValues(const FloatSize& radius, const Color& color, ColorSpace colorSpace, const FloatRect& shadowRect, const RoundedIntRect::Radii& radii) 83 87 { 84 88 m_lastWasInset = false; … … 90 94 } 91 95 92 void setLastInsetShadowValues( floatradius, const Color& color, ColorSpace colorSpace, const FloatRect& bounds, const FloatRect& shadowRect, const RoundedIntRect::Radii& radii)96 void setLastInsetShadowValues(const FloatSize& radius, const Color& color, ColorSpace colorSpace, const FloatRect& bounds, const FloatRect& shadowRect, const RoundedIntRect::Radii& radii) 93 97 { 94 98 m_lastWasInset = true; … … 101 105 } 102 106 103 bool matchesLastShadow( floatradius, const Color& color, ColorSpace colorSpace, const FloatRect& shadowRect, const RoundedIntRect::Radii& radii) const107 bool matchesLastShadow(const FloatSize& radius, const Color& color, ColorSpace colorSpace, const FloatRect& shadowRect, const RoundedIntRect::Radii& radii) const 104 108 { 105 109 if (m_lastWasInset) … … 108 112 } 109 113 110 bool matchesLastInsetShadow( floatradius, const Color& color, ColorSpace colorSpace, const FloatRect& bounds, const FloatRect& shadowRect, const RoundedIntRect::Radii& radii) const114 bool matchesLastInsetShadow(const FloatSize& radius, const Color& color, ColorSpace colorSpace, const FloatRect& bounds, const FloatRect& shadowRect, const RoundedIntRect::Radii& radii) const 111 115 { 112 116 if (!m_lastWasInset) … … 138 142 { 139 143 m_imageBuffer = 0; 140 m_lastRadius = 0;144 m_lastRadius = FloatSize(); 141 145 } 142 146 … … 149 153 Color m_lastColor; 150 154 ColorSpace m_lastColorSpace; 151 floatm_lastRadius;155 FloatSize m_lastRadius; 152 156 bool m_lastWasInset; 153 157 … … 165 169 static const int templateSideLength = 1; 166 170 167 ShadowBlur::ShadowBlur( floatradius, const FloatSize& offset, const Color& color, ColorSpace colorSpace)171 ShadowBlur::ShadowBlur(const FloatSize& radius, const FloatSize& offset, const Color& color, ColorSpace colorSpace) 168 172 : m_color(color) 169 173 , m_colorSpace(colorSpace) … … 174 178 { 175 179 // Limit blur radius to 128 to avoid lots of very expensive blurring. 176 m_blurRadius = m in<float>(m_blurRadius, 128);180 m_blurRadius = m_blurRadius.shrunkTo(FloatSize(128, 128)); 177 181 178 182 // The type of shadow is decided by the blur radius, shadow offset, and shadow color. … … 180 184 // Can't paint the shadow with invalid or invisible color. 181 185 m_type = NoShadow; 182 } else if (m_blurRadius > 0) {186 } else if (m_blurRadius.width() > 0 || m_blurRadius.height() > 0) { 183 187 // Shadow is always blurred, even the offset is zero. 184 188 m_type = BlurShadow; … … 193 197 static const int blurSumShift = 15; 194 198 195 void ShadowBlur::blurLayerImage(unsigned char* imageData, const IntSize& size, int rowStride) 196 { 197 const int channels[4] = { 3, 0, 1, 3 }; 198 199 // Takes a two dimensional array with three rows and two columns for the lobes. 200 static void calculateLobes(int lobes[][2], float blurRadius, bool shadowsIgnoreTransforms) 201 { 199 202 int diameter; 200 if ( m_shadowsIgnoreTransforms)201 diameter = max(2, static_cast<int>(floorf((2 / 3.f) * m_blurRadius))); // Canvas shadow. FIXME: we should adjust the blur radius higher up.203 if (shadowsIgnoreTransforms) 204 diameter = max(2, static_cast<int>(floorf((2 / 3.f) * blurRadius))); // Canvas shadow. FIXME: we should adjust the blur radius higher up. 202 205 else { 203 206 // http://dev.w3.org/csswg/css3-background/#box-shadow … … 206 209 // However, shadows rendered according to that spec will extend a little further than m_blurRadius, 207 210 // so we apply a fudge factor to bring the radius down slightly. 208 float stdDev = m_blurRadius / 2;211 float stdDev = blurRadius / 2; 209 212 const float gaussianKernelFactor = 3 / 4.f * sqrtf(2 * piFloat); 210 213 const float fudgeFactor = 0.88f; … … 212 215 } 213 216 214 enum {215 leftLobe = 0,216 rightLobe = 1217 };218 219 int lobes[3][2]; // indexed by pass, and left/right lobe220 221 217 if (diameter & 1) { 222 218 // if d is odd, use three box-blurs of size 'd', centered on the output pixel. … … 240 236 lobes[2][rightLobe] = lobeSize; 241 237 } 238 } 239 240 void ShadowBlur::blurLayerImage(unsigned char* imageData, const IntSize& size, int rowStride) 241 { 242 const int channels[4] = { 3, 0, 1, 3 }; 243 244 int lobes[3][2]; // indexed by pass, and left/right lobe 245 calculateLobes(lobes, m_blurRadius.width(), m_shadowsIgnoreTransforms); 242 246 243 247 // First pass is horizontal. … … 249 253 // Two stages: horizontal and vertical 250 254 for (int pass = 0; pass < 2; ++pass) { 255 if (pass && m_blurRadius.width() != m_blurRadius.height()) 256 calculateLobes(lobes, m_blurRadius.height(), m_shadowsIgnoreTransforms); 251 257 unsigned char* pixels = imageData; 252 258 … … 334 340 + yUnitChange.height() * yUnitChange.height()); 335 341 336 // blurLayerImage() does not support per-axis blurring, so calculate a balanced scaling. 337 // FIXME: does AffineTransform.xScale()/yScale() help? 338 const float scale = sqrtf(xAxisScale * yAxisScale); 339 m_blurRadius = roundf(m_blurRadius / scale); 342 // Scale blur radius 343 m_blurRadius.scale(1 / xAxisScale, 1 / yAxisScale); 340 344 } 341 345 342 346 IntRect ShadowBlur::calculateLayerBoundingRect(GraphicsContext* context, const FloatRect& shadowedRect, const IntRect& clipRect) 343 347 { 344 const float roundedRadius = ceilf(m_blurRadius);348 const IntSize roundedRadius = expandedIntSize(m_blurRadius); 345 349 346 350 // Calculate the destination of the blurred and/or transformed layer. 347 351 FloatRect layerRect; 348 float inflation = 0;352 IntSize inflation; 349 353 350 354 const AffineTransform transform = context->getCTM(); … … 360 364 // We expand the area by the blur radius to give extra space for the blur transition. 361 365 if (m_type == BlurShadow) { 362 layerRect.inflate(roundedRadius); 366 layerRect.inflateX(roundedRadius.width()); 367 layerRect.inflateY(roundedRadius.height()); 363 368 inflation = roundedRadius; 364 369 } … … 374 379 // Pixels at the edges can be affected by pixels outside the buffer, 375 380 // so intersect with the clip inflated by the blur. 376 if (m_type == BlurShadow) 377 inflatedClip.inflate(roundedRadius); 381 if (m_type == BlurShadow) { 382 inflatedClip.inflateX(roundedRadius.width()); 383 inflatedClip.inflateY(roundedRadius.height()); 384 } 378 385 379 386 layerRect.intersect(inflatedClip); 380 387 } 381 388 382 const float frameSize = inflation * 2; 383 m_sourceRect = FloatRect(0, 0, shadowedRect.width() + frameSize, shadowedRect.height() + frameSize); 389 IntSize frameSize = inflation; 390 frameSize.scale(2); 391 m_sourceRect = FloatRect(0, 0, shadowedRect.width() + frameSize.width(), shadowedRect.height() + frameSize.height()); 384 392 m_layerOrigin = FloatPoint(layerRect.x(), layerRect.y()); 385 393 m_layerSize = layerRect.size(); … … 390 398 // Set the origin as the top left corner of the scratch image, or, in case there's a clipped 391 399 // out region, set the origin accordingly to the full bounding rect's top-left corner. 392 float translationX = -shadowedRect.x() + inflation - fabsf(clippedOut.width());393 float translationY = -shadowedRect.y() + inflation - fabsf(clippedOut.height());400 float translationX = -shadowedRect.x() + inflation.width() - fabsf(clippedOut.width()); 401 float translationY = -shadowedRect.y() + inflation.height() - fabsf(clippedOut.height()); 394 402 m_layerContextTranslation = FloatSize(translationX, translationY); 395 403 … … 419 427 } 420 428 421 static void computeSliceSizesFromRadii( inttwiceRadius, const RoundedIntRect::Radii& radii, int& leftSlice, int& rightSlice, int& topSlice, int& bottomSlice)422 { 423 leftSlice = twiceRadius + max(radii.topLeft().width(), radii.bottomLeft().width());424 rightSlice = twiceRadius + max(radii.topRight().width(), radii.bottomRight().width());425 426 topSlice = twiceRadius + max(radii.topLeft().height(), radii.topRight().height());427 bottomSlice = twiceRadius + max(radii.bottomLeft().height(), radii.bottomRight().height());429 static void computeSliceSizesFromRadii(const IntSize& twiceRadius, const RoundedIntRect::Radii& radii, int& leftSlice, int& rightSlice, int& topSlice, int& bottomSlice) 430 { 431 leftSlice = twiceRadius.width() + max(radii.topLeft().width(), radii.bottomLeft().width()); 432 rightSlice = twiceRadius.width() + max(radii.topRight().width(), radii.bottomRight().width()); 433 434 topSlice = twiceRadius.height() + max(radii.topLeft().height(), radii.topRight().height()); 435 bottomSlice = twiceRadius.height() + max(radii.bottomLeft().height(), radii.bottomRight().height()); 428 436 } 429 437 … … 436 444 int topSlice; 437 445 int bottomSlice; 438 computeSliceSizesFromRadii(2 * ceilf(m_blurRadius), radii, leftSlice, rightSlice, topSlice, bottomSlice); 446 IntSize twiceRadius = expandedIntSize(m_blurRadius); 447 twiceRadius.scale(2); 448 449 computeSliceSizesFromRadii(twiceRadius, radii, leftSlice, rightSlice, topSlice, bottomSlice); 439 450 440 451 return IntSize(templateSideLength + leftSlice + rightSlice, … … 610 621 graphicsContext->clearShadow(); 611 622 612 const float roundedRadius = ceilf(m_blurRadius);613 const float twiceRadius = roundedRadius * 2;623 const IntSize roundedRadius = expandedIntSize(m_blurRadius); 624 const IntSize twiceRadius = IntSize(roundedRadius.width() * 2, roundedRadius.height() * 2); 614 625 615 626 m_layerImage = ScratchBuffer::shared().getScratchBuffer(templateSize); … … 619 630 // Draw the rectangle with hole. 620 631 FloatRect templateBounds(0, 0, templateSize.width(), templateSize.height()); 621 FloatRect templateHole = FloatRect(roundedRadius , roundedRadius, templateSize.width() - twiceRadius, templateSize.height() - twiceRadius);632 FloatRect templateHole = FloatRect(roundedRadius.width(), roundedRadius.height(), templateSize.width() - twiceRadius.width(), templateSize.height() - twiceRadius.height()); 622 633 623 634 if (!ScratchBuffer::shared().matchesLastInsetShadow(m_blurRadius, m_color, m_colorSpace, templateBounds, templateHole, radii)) { … … 650 661 destHoleRect.move(m_offset); 651 662 FloatRect destHoleBounds = destHoleRect; 652 destHoleBounds.inflate(roundedRadius); 663 destHoleBounds.inflateX(roundedRadius.width()); 664 destHoleBounds.inflateY(roundedRadius.height()); 653 665 654 666 // Fill the external part of the shadow (which may be visible because of offset). … … 676 688 graphicsContext->clearShadow(); 677 689 678 const float roundedRadius = ceilf(m_blurRadius);679 const float twiceRadius = roundedRadius * 2;690 const IntSize roundedRadius = expandedIntSize(m_blurRadius); 691 const IntSize twiceRadius = IntSize(roundedRadius.width() * 2, roundedRadius.height() * 2); 680 692 681 693 m_layerImage = ScratchBuffer::shared().getScratchBuffer(templateSize); … … 683 695 return; 684 696 685 FloatRect templateShadow = FloatRect(roundedRadius , roundedRadius, templateSize.width() - twiceRadius, templateSize.height() - twiceRadius);697 FloatRect templateShadow = FloatRect(roundedRadius.width(), roundedRadius.height(), templateSize.width() - twiceRadius.width(), templateSize.height() - twiceRadius.height()); 686 698 687 699 if (!ScratchBuffer::shared().matchesLastShadow(m_blurRadius, m_color, m_colorSpace, templateShadow, radii)) { … … 708 720 FloatRect shadowBounds = shadowedRect; 709 721 shadowBounds.move(m_offset.width(), m_offset.height()); 710 shadowBounds.inflate(roundedRadius); 722 shadowBounds.inflateX(roundedRadius.width()); 723 shadowBounds.inflateY(roundedRadius.height()); 711 724 712 725 drawLayerPieces(graphicsContext, shadowBounds, radii, roundedRadius, templateSize, OuterShadow); … … 718 731 } 719 732 720 void ShadowBlur::drawLayerPieces(GraphicsContext* graphicsContext, const FloatRect& shadowBounds, const RoundedIntRect::Radii& radii, floatroundedRadius, const IntSize& templateSize, ShadowDirection direction)721 { 722 const float twiceRadius = roundedRadius * 2;733 void ShadowBlur::drawLayerPieces(GraphicsContext* graphicsContext, const FloatRect& shadowBounds, const RoundedIntRect::Radii& radii, const IntSize& roundedRadius, const IntSize& templateSize, ShadowDirection direction) 734 { 735 const IntSize twiceRadius = IntSize(roundedRadius.width() * 2, roundedRadius.height() * 2); 723 736 724 737 int leftSlice; -
trunk/Source/WebCore/platform/graphics/ShadowBlur.h
r83422 r84410 45 45 WTF_MAKE_NONCOPYABLE(ShadowBlur); 46 46 public: 47 ShadowBlur( floatradius, const FloatSize& offset, const Color&, ColorSpace);47 ShadowBlur(const FloatSize& radius, const FloatSize& offset, const Color&, ColorSpace); 48 48 49 49 void setShadowsIgnoreTransforms(bool ignoreTransforms) { m_shadowsIgnoreTransforms = ignoreTransforms; } … … 73 73 void drawInsetShadowWithTiling(GraphicsContext*, const FloatRect&, const FloatRect& holeRect, const RoundedIntRect::Radii&, const IntSize& shadowTemplateSize); 74 74 75 void drawLayerPieces(GraphicsContext*, const FloatRect& shadowBounds, const RoundedIntRect::Radii&, floatroundedRadius, const IntSize& templateSize, ShadowDirection);75 void drawLayerPieces(GraphicsContext*, const FloatRect& shadowBounds, const RoundedIntRect::Radii&, const IntSize& roundedRadius, const IntSize& templateSize, ShadowDirection); 76 76 77 77 void blurShadowBuffer(const IntSize& templateSize); … … 88 88 Color m_color; 89 89 ColorSpace m_colorSpace; 90 floatm_blurRadius;90 FloatSize m_blurRadius; 91 91 FloatSize m_offset; 92 92 -
trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
r84273 r84410 703 703 CGContextSetShadowWithColor(platformContext(), CGSizeZero, 0, 0); 704 704 705 ShadowBlur contextShadow( shadowBlur, m_state.shadowOffset, m_state.shadowColor, m_state.shadowColorSpace);705 ShadowBlur contextShadow(FloatSize(shadowBlur, shadowBlur), m_state.shadowOffset, m_state.shadowColor, m_state.shadowColorSpace); 706 706 contextShadow.drawRectShadow(this, rect, RoundedIntRect::Radii()); 707 707 } … … 732 732 CGContextSetShadowWithColor(platformContext(), CGSizeZero, 0, 0); 733 733 734 ShadowBlur contextShadow( shadowBlur, m_state.shadowOffset, m_state.shadowColor, m_state.shadowColorSpace);734 ShadowBlur contextShadow(FloatSize(shadowBlur, shadowBlur), m_state.shadowOffset, m_state.shadowColor, m_state.shadowColorSpace); 735 735 contextShadow.drawRectShadow(this, rect, RoundedIntRect::Radii()); 736 736 } … … 765 765 CGContextSetShadowWithColor(platformContext(), CGSizeZero, 0, 0); 766 766 767 ShadowBlur contextShadow( shadowBlur, m_state.shadowOffset, m_state.shadowColor, m_state.shadowColorSpace);767 ShadowBlur contextShadow(FloatSize(shadowBlur, shadowBlur), m_state.shadowOffset, m_state.shadowColor, m_state.shadowColorSpace); 768 768 contextShadow.drawRectShadow(this, rect, RoundedIntRect::Radii(topLeft, topRight, bottomLeft, bottomRight)); 769 769 } … … 817 817 CGContextSetShadowWithColor(platformContext(), CGSizeZero, 0, 0); 818 818 819 ShadowBlur contextShadow( shadowBlur, m_state.shadowOffset, m_state.shadowColor, m_state.shadowColorSpace);819 ShadowBlur contextShadow(FloatSize(shadowBlur, shadowBlur), m_state.shadowOffset, m_state.shadowColor, m_state.shadowColorSpace); 820 820 contextShadow.drawInsetShadow(this, rect, roundedHoleRect.rect(), roundedHoleRect.radii()); 821 821 }
Note: See TracChangeset
for help on using the changeset viewer.