[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

alex at webkit.org alex at webkit.org
Wed Dec 22 12:54:46 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit c08152d016e1e56625b8cb95d4b178b7a42d2495
Author: alex at webkit.org <alex at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Sep 1 16:10:32 2010 +0000

    2010-09-01  Alejandro G. Castro  <alex at igalia.com>
    
            Reviewed by Martin Robinson.
    
            [Gtk] very slow page scrolling on big -webkit-box-shadow areas
            https://bugs.webkit.org/show_bug.cgi?id=39582
    
            Add a new drawTiledShadow method to render a big shadow doing
            tiling of parts of a smaller shadow. We create the minimum shadow
            required to get the tiles we will use to render the real shadow
            and we use drawPattern with those tiles to create the shadow.
    
            * platform/graphics/GraphicsContext.h:
            * platform/graphics/cairo/FontCairo.cpp:
            (WebCore::Font::drawGlyphs):
            * platform/graphics/cairo/GraphicsContextCairo.cpp:
            (WebCore::drawPathShadow):
            (WebCore::drawBorderlessRectShadow):
            (WebCore::GraphicsContext::fillRect):
            (WebCore::GraphicsContext::applyPlatformShadow):
            (WebCore::GraphicsContext::createShadowMask):
            (WebCore::getPhase):
            (WebCore::GraphicsContext::drawTiledShadow):
            (WebCore::GraphicsContext::fillRoundedRect):
            * platform/graphics/cairo/ImageCairo.cpp:
            (WebCore::BitmapImage::draw):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@66607 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/platform/gtk/fast/box-shadow/basic-shadows-expected.checksum b/LayoutTests/platform/gtk/fast/box-shadow/basic-shadows-expected.checksum
index 758ef70..032916e 100644
--- a/LayoutTests/platform/gtk/fast/box-shadow/basic-shadows-expected.checksum
+++ b/LayoutTests/platform/gtk/fast/box-shadow/basic-shadows-expected.checksum
@@ -1 +1 @@
-14e95aae94168807ea3e1fb6623aea54
\ No newline at end of file
+6daac1f7e6af1534a5d83a808573a5c6
\ No newline at end of file
diff --git a/LayoutTests/platform/gtk/fast/box-shadow/basic-shadows-expected.png b/LayoutTests/platform/gtk/fast/box-shadow/basic-shadows-expected.png
index b3e4522..bf4ed66 100644
Binary files a/LayoutTests/platform/gtk/fast/box-shadow/basic-shadows-expected.png and b/LayoutTests/platform/gtk/fast/box-shadow/basic-shadows-expected.png differ
diff --git a/LayoutTests/platform/gtk/fast/css/shadow-multiple-expected.checksum b/LayoutTests/platform/gtk/fast/css/shadow-multiple-expected.checksum
index 91e54cb..8bfd6c7 100644
--- a/LayoutTests/platform/gtk/fast/css/shadow-multiple-expected.checksum
+++ b/LayoutTests/platform/gtk/fast/css/shadow-multiple-expected.checksum
@@ -1 +1 @@
-96c324cc4bea03ced82a13f5ef857a21
\ No newline at end of file
+8e0c3caad40d43b3f3960d9adec01751
\ No newline at end of file
diff --git a/LayoutTests/platform/gtk/fast/css/shadow-multiple-expected.png b/LayoutTests/platform/gtk/fast/css/shadow-multiple-expected.png
index 290d2d7..2db5780 100644
Binary files a/LayoutTests/platform/gtk/fast/css/shadow-multiple-expected.png and b/LayoutTests/platform/gtk/fast/css/shadow-multiple-expected.png differ
diff --git a/LayoutTests/platform/gtk/svg/css/stars-with-shadow-expected.checksum b/LayoutTests/platform/gtk/svg/css/stars-with-shadow-expected.checksum
index 9e07180..e7ccef3 100644
--- a/LayoutTests/platform/gtk/svg/css/stars-with-shadow-expected.checksum
+++ b/LayoutTests/platform/gtk/svg/css/stars-with-shadow-expected.checksum
@@ -1 +1 @@
-3a931000a7b4d2bb15ebc8c1184d4f45
\ No newline at end of file
+cf31a5f1ae3ef8dd8bba3df35e5ebb9b
\ No newline at end of file
diff --git a/LayoutTests/platform/gtk/svg/css/stars-with-shadow-expected.png b/LayoutTests/platform/gtk/svg/css/stars-with-shadow-expected.png
index c3679de..43e58d0 100644
Binary files a/LayoutTests/platform/gtk/svg/css/stars-with-shadow-expected.png and b/LayoutTests/platform/gtk/svg/css/stars-with-shadow-expected.png differ
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 69a3e58..b9fbda3 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,30 @@
+2010-09-01  Alejandro G. Castro  <alex at igalia.com>
+
+        Reviewed by Martin Robinson.
+
+        [Gtk] very slow page scrolling on big -webkit-box-shadow areas
+        https://bugs.webkit.org/show_bug.cgi?id=39582
+
+        Add a new drawTiledShadow method to render a big shadow doing
+        tiling of parts of a smaller shadow. We create the minimum shadow
+        required to get the tiles we will use to render the real shadow
+        and we use drawPattern with those tiles to create the shadow.
+
+        * platform/graphics/GraphicsContext.h:
+        * platform/graphics/cairo/FontCairo.cpp:
+        (WebCore::Font::drawGlyphs):
+        * platform/graphics/cairo/GraphicsContextCairo.cpp:
+        (WebCore::drawPathShadow):
+        (WebCore::drawBorderlessRectShadow):
+        (WebCore::GraphicsContext::fillRect):
+        (WebCore::GraphicsContext::applyPlatformShadow):
+        (WebCore::GraphicsContext::createShadowMask):
+        (WebCore::getPhase):
+        (WebCore::GraphicsContext::drawTiledShadow):
+        (WebCore::GraphicsContext::fillRoundedRect):
+        * platform/graphics/cairo/ImageCairo.cpp:
+        (WebCore::BitmapImage::draw):
+
 2010-09-01  Andrey Kosyakov  <caseq at chromium.org>
 
         Reviewed by Yury Semikhatsky.
diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h
index 93ef890..cb43f01 100644
--- a/WebCore/platform/graphics/GraphicsContext.h
+++ b/WebCore/platform/graphics/GraphicsContext.h
@@ -40,6 +40,7 @@
 #if PLATFORM(CG)
 typedef struct CGContext PlatformGraphicsContext;
 #elif PLATFORM(CAIRO)
+#include "PlatformRefPtrCairo.h"
 typedef struct _cairo PlatformGraphicsContext;
 #elif PLATFORM(OPENVG)
 namespace WebCore {
@@ -297,8 +298,11 @@ namespace WebCore {
         void setAlpha(float);
 #if PLATFORM(CAIRO)
         float getAlpha();
-        void createPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const Color& shadowColor, const FloatRect& shadowRect, float radius);
+        void applyPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const Color& shadowColor, const FloatRect& shadowRect, float radius);
+        PlatformRefPtr<cairo_surface_t> createShadowMask(PassOwnPtr<ImageBuffer>, const FloatRect&, float radius);
+
         static void calculateShadowBufferDimensions(IntSize& shadowBufferSize, FloatRect& shadowRect, float& radius, const FloatRect& sourceRect, const FloatSize& shadowOffset, float shadowBlur);
+        void drawTiledShadow(const IntRect& rect, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius, ColorSpace colorSpace);
 #endif
 
         void setCompositeOperation(CompositeOperator);
diff --git a/WebCore/platform/graphics/cairo/FontCairo.cpp b/WebCore/platform/graphics/cairo/FontCairo.cpp
index 5bfa3fb..cd5d362 100644
--- a/WebCore/platform/graphics/cairo/FontCairo.cpp
+++ b/WebCore/platform/graphics/cairo/FontCairo.cpp
@@ -113,7 +113,7 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
             cairo_restore(shadowCr);
         }
         cairo_translate(cr, 0.0, -extents.height);
-        context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
+        context->applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
 #else
         cairo_translate(cr, shadowOffset.width(), shadowOffset.height());
         cairo_show_glyphs(cr, glyphs, numGlyphs);
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
index 683c144..cf91338 100644
--- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
+++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
@@ -44,6 +44,7 @@
 #include "NotImplemented.h"
 #include "Path.h"
 #include "Pattern.h"
+#include "PlatformRefPtrCairo.h"
 #include "SimpleFontData.h"
 #include "SourceGraphic.h"
 
@@ -228,7 +229,7 @@ static inline void drawPathShadow(GraphicsContext* context, GraphicsContextPriva
     if (strokeShadow)
         setPlatformStroke(context, shadowContext, gcp);
 
-    context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
+    context->applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
 #endif
 }
 
@@ -623,6 +624,20 @@ void GraphicsContext::fillRect(const FloatRect& rect)
 static void drawBorderlessRectShadow(GraphicsContext* context, const FloatRect& rect, const Color& rectColor)
 {
 #if ENABLE(FILTERS)
+    AffineTransform transform = context->getCTM();
+    // drawTiledShadow still does not work with rotations.
+    if ((transform.isIdentityOrTranslationOrFlipped())) {
+        cairo_t* cr = context->platformContext();
+        cairo_save(cr);
+        appendWebCorePathToCairoContext(cr, Path::createRectangle(rect));
+        FloatSize corner;
+        IntRect shadowRect(rect);
+        context->drawTiledShadow(shadowRect, corner, corner, corner, corner, DeviceColorSpace);
+        cairo_restore(cr);
+
+        return;
+    }
+
     FloatSize shadowOffset;
     float shadowBlur;
     Color shadowColor;
@@ -640,7 +655,7 @@ static void drawBorderlessRectShadow(GraphicsContext* context, const FloatRect&
     GraphicsContext* shadowContext = shadowBuffer->context();
     shadowContext->fillRect(FloatRect(FloatPoint(radius, radius), rect.size()), rectColor, DeviceColorSpace);
 
-    context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
+    context->applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
 #endif
 }
 
@@ -921,20 +936,25 @@ void GraphicsContext::setPlatformShadow(FloatSize const& size, float, Color cons
     }
 }
 
-void GraphicsContext::createPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const Color& shadowColor, const FloatRect& shadowRect, float radius)
+void GraphicsContext::applyPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const Color& shadowColor, const FloatRect& shadowRect, float radius)
 {
 #if ENABLE(FILTERS)
-    cairo_t* cr = m_data->cr;
+    setColor(m_data->cr, shadowColor);
+    PlatformRefPtr<cairo_surface_t> shadowMask(createShadowMask(buffer, shadowRect, radius));
+    cairo_mask_surface(m_data->cr, shadowMask.get(), shadowRect.x(), shadowRect.y());
+#endif
+}
 
-    // calculate the standard deviation
-    float sd = FEGaussianBlur::calculateStdDeviation(radius);
+PlatformRefPtr<cairo_surface_t> GraphicsContext::createShadowMask(PassOwnPtr<ImageBuffer> buffer, const FloatRect& shadowRect, float radius)
+{
+#if ENABLE(FILTERS)
+    if (!radius)
+        return buffer->m_data.m_surface;
 
-    // draw the shadow without blurring, if radius is zero
-    if (!radius || !sd) {
-        setColor(cr, shadowColor);
-        cairo_mask_surface(cr, buffer->m_data.m_surface, shadowRect.x(), shadowRect.y());
-        return;
-    }
+    FloatPoint blurRadius = FloatPoint(radius, radius);
+    float sd = FEGaussianBlur::calculateStdDeviation(radius);
+    if (!sd)
+        return buffer->m_data.m_surface;
 
     // create filter
     RefPtr<Filter> filter = ImageBufferFilter::create();
@@ -945,14 +965,11 @@ void GraphicsContext::createPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const
     RefPtr<FilterEffect> blur = FEGaussianBlur::create(source.get(), sd, sd);
     blur->setScaledSubRegion(FloatRect(FloatPoint(), shadowRect.size()));
     blur->apply(filter.get());
-
-    // Mask the filter with the shadow color and draw it to the context.
-    // Masking makes it possible to just blur the alpha channel.
-    setColor(cr, shadowColor);
-    cairo_mask_surface(cr, blur->resultImage()->m_data.m_surface, shadowRect.x(), shadowRect.y());
+    return blur->resultImage()->m_data.m_surface;
 #endif
 }
 
+
 void GraphicsContext::clearPlatformShadow()
 {
     notImplemented();
@@ -1218,6 +1235,200 @@ void GraphicsContext::clipOutEllipseInRect(const IntRect& r)
     clipOut(p);
 }
 
+static inline FloatPoint getPhase(const FloatRect& dest, const FloatRect& tile)
+{
+    FloatPoint phase = dest.location();
+    phase.move(-tile.x(), -tile.y());
+
+    return phase;
+}
+
+/*
+  This function uses tiling to improve the performance of the shadow
+  drawing of rounded rectangles. The code basically does the following
+  steps:
+
+     1. Calculate the minimum rectangle size required to create the
+     tiles
+
+     2. If that size is smaller than the real rectangle render the new
+     small rectangle and its shadow in a new surface, in other case
+     render the shadow of the real rectangle in the destination
+     surface.
+
+     3. Calculate the sizes and positions of the tiles and their
+     destinations and use drawPattern to render the final shadow. The
+     code divides the rendering in 8 tiles:
+
+        1 | 2 | 3
+       -----------
+        4 |   | 5
+       -----------
+        6 | 7 | 8
+
+     The corners are directly copied from the small rectangle to the
+     real one and the side tiles are 1 pixel width, we use them as
+
+     tiles to cover the destination side. The corner tiles are bigger
+     than just the side of the rounded corner, we need to increase it
+     because the modifications caused by the corner over the blur
+     effect. We fill the central part with solid color to complete the
+     shadow.
+ */
+void GraphicsContext::drawTiledShadow(const IntRect& rect, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius, ColorSpace colorSpace)
+{
+#if ENABLE(FILTERS)
+    FloatSize shadowSize;
+    float shadowBlur;
+    Color shadowColor;
+    if (!getShadow(shadowSize, shadowBlur, shadowColor))
+        return;
+
+    // Calculate filter values to create appropriate shadow.
+    cairo_t* cr = m_data->cr;
+
+    IntSize shadowBufferSize;
+    FloatRect shadowRect;
+    float blurRadius = 0;
+    GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, blurRadius, rect, shadowSize, shadowBlur);
+
+    // Size of the tiling side.
+    int sideTileWidth = 1;
+    float radiusTwice = blurRadius * 2;
+
+    // Find the extra space needed from the curve of the corners.
+    int extraWidthFromCornerRadii = radiusTwice + max(topLeftRadius.width(), bottomLeftRadius.width()) +
+                                    radiusTwice + max(topRightRadius.width(), bottomRightRadius.width());
+    int extraHeightFromCornerRadii = radiusTwice + max(topLeftRadius.height(), topRightRadius.height()) +
+                                     radiusTwice + max(bottomLeftRadius.height(), bottomRightRadius.height());
+
+    // The length of a side of the buffer is the enough space for four blur radii,
+    // the radii of the corners, and then 1 pixel to draw the side tiles.
+    IntSize smallBufferSize = IntSize(sideTileWidth + extraWidthFromCornerRadii,
+                                      sideTileWidth + extraHeightFromCornerRadii);
+
+    if ((smallBufferSize.width() > shadowBufferSize.width()) || (smallBufferSize.height() > shadowBufferSize.height()) || (blurRadius <= 0)) {
+        // Create suitably-sized ImageBuffer to hold the shadow.
+        OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize);
+        if (!shadowBuffer)
+            return;
+
+        // Draw shadow into a new ImageBuffer.
+        cairo_t* shadowContext = shadowBuffer->context()->platformContext();
+        copyContextProperties(cr, shadowContext);
+        cairo_translate(shadowContext, -rect.x() + blurRadius, -rect.y() + blurRadius);
+        cairo_new_path(shadowContext);
+        cairo_path_t* path = cairo_copy_path(cr);
+        cairo_append_path(shadowContext, path);
+        cairo_path_destroy(path);
+
+        setPlatformFill(this, shadowContext, m_common);
+
+        applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, blurRadius);
+
+        return;
+    }
+
+    OwnPtr<ImageBuffer> smallBuffer = ImageBuffer::create(smallBufferSize);
+    if (!smallBuffer)
+        return;
+
+    IntRect smallRect = IntRect(blurRadius, blurRadius, smallBufferSize.width() - radiusTwice, smallBufferSize.height() - radiusTwice);
+
+    // Draw shadow into a new ImageBuffer.
+    cairo_t* smallBufferContext = smallBuffer->context()->platformContext();
+    copyContextProperties(cr, smallBufferContext);
+    appendWebCorePathToCairoContext(smallBuffer->context()->platformContext(), Path::createRoundedRectangle(smallRect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius));
+    setPlatformFill(this, smallBufferContext, m_common);
+
+    OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(smallBufferSize);
+    if (!shadowBuffer)
+        return;
+
+    smallRect.setSize(smallBufferSize);
+
+    PlatformRefPtr<cairo_surface_t> shadowMask(createShadowMask(smallBuffer.release(), smallRect, blurRadius));
+
+    cairo_t* shadowContext = shadowBuffer->context()->platformContext();
+    setColor(shadowContext, shadowColor);
+    cairo_mask_surface(shadowContext, shadowMask.get(), 0, 0);
+
+    // Fill the internal part of the shadow.
+    shadowRect.inflate(-radiusTwice);
+    if (!shadowRect.isEmpty()) {
+        cairo_save(cr);
+        appendWebCorePathToCairoContext(cr, Path::createRoundedRectangle(shadowRect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius));
+        setColor(cr, shadowColor);
+        cairo_fill(cr);
+        cairo_restore(cr);
+    }
+    shadowRect.inflate(radiusTwice);
+
+    // Draw top side.
+    FloatRect tileRect = FloatRect(radiusTwice + topLeftRadius.width(), 0, sideTileWidth, radiusTwice);
+    FloatRect destRect = tileRect;
+    destRect.move(shadowRect.x(), shadowRect.y());
+    destRect.setWidth(shadowRect.width() - topLeftRadius.width() - topRightRadius.width() - blurRadius * 4);
+    FloatPoint phase = getPhase(destRect, tileRect);
+    AffineTransform patternTransform;
+    patternTransform.makeIdentity();
+    shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);
+
+    // Draw the bottom side.
+    tileRect = FloatRect(radiusTwice + bottomLeftRadius.width(), smallBufferSize.height() - radiusTwice, sideTileWidth, radiusTwice);
+    destRect = tileRect;
+    destRect.move(shadowRect.x(), shadowRect.y() + radiusTwice + rect.height() - smallBufferSize.height());
+    destRect.setWidth(shadowRect.width() - bottomLeftRadius.width() - bottomRightRadius.width() - blurRadius * 4);
+    phase = getPhase(destRect, tileRect);
+    shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);
+
+    // Draw the right side.
+    tileRect = FloatRect(smallBufferSize.width() - radiusTwice, radiusTwice + topRightRadius.height(), radiusTwice, sideTileWidth);
+    destRect = tileRect;
+    destRect.move(shadowRect.x() + radiusTwice + rect.width() - smallBufferSize.width(), shadowRect.y());
+    destRect.setHeight(shadowRect.height() - topRightRadius.height() - bottomRightRadius.height() - blurRadius * 4);
+    phase = getPhase(destRect, tileRect);
+    shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);
+
+    // Draw the left side.
+    tileRect = FloatRect(0, radiusTwice + topLeftRadius.height(), radiusTwice, sideTileWidth);
+    destRect = tileRect;
+    destRect.move(shadowRect.x(), shadowRect.y());
+    destRect.setHeight(shadowRect.height() - topLeftRadius.height() - bottomLeftRadius.height() - blurRadius * 4);
+    phase = FloatPoint(destRect.x() - tileRect.x(), destRect.y() - tileRect.y());
+    shadowBuffer->drawPattern(this, tileRect, patternTransform,
+                              phase, colorSpace, CompositeSourceOver, destRect);
+
+    // Draw the top left corner.
+    tileRect = FloatRect(0, 0, radiusTwice + topLeftRadius.width(), radiusTwice + topLeftRadius.height());
+    destRect = tileRect;
+    destRect.move(shadowRect.x(), shadowRect.y());
+    phase = getPhase(destRect, tileRect);
+    shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);
+
+    // Draw the top right corner.
+    tileRect = FloatRect(smallBufferSize.width() - radiusTwice - topRightRadius.width(), 0, radiusTwice + topRightRadius.width(), radiusTwice + topRightRadius.height());
+    destRect = tileRect;
+    destRect.move(shadowRect.x() + rect.width() - smallBufferSize.width() + radiusTwice, shadowRect.y());
+    phase = getPhase(destRect, tileRect);
+    shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);
+
+    // Draw the bottom right corner.
+    tileRect = FloatRect(smallBufferSize.width() - radiusTwice - bottomRightRadius.width(), smallBufferSize.height() - radiusTwice - bottomRightRadius.height(), radiusTwice + bottomRightRadius.width(), radiusTwice + bottomRightRadius.height());
+    destRect = tileRect;
+    destRect.move(shadowRect.x() + rect.width() - smallBufferSize.width() + radiusTwice, shadowRect.y() + rect.height() - smallBufferSize.height() + radiusTwice);
+    phase = getPhase(destRect, tileRect);
+    shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);
+
+    // Draw the bottom left corner.
+    tileRect = FloatRect(0, smallBufferSize.height() - radiusTwice - bottomLeftRadius.height(), radiusTwice + bottomLeftRadius.width(), radiusTwice + bottomLeftRadius.height());
+    destRect = tileRect;
+    destRect.move(shadowRect.x(), shadowRect.y() + rect.height() - smallBufferSize.height() + radiusTwice);
+    phase = getPhase(destRect, tileRect);
+    shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);
+#endif
+}
+
 void GraphicsContext::fillRoundedRect(const IntRect& r, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color, ColorSpace colorSpace)
 {
     if (paintingDisabled())
@@ -1227,7 +1438,12 @@ void GraphicsContext::fillRoundedRect(const IntRect& r, const IntSize& topLeft,
     cairo_save(cr);
     appendWebCorePathToCairoContext(cr, Path::createRoundedRectangle(r, topLeft, topRight, bottomLeft, bottomRight));
     setColor(cr, color);
-    drawPathShadow(this, m_common, true, false);
+    AffineTransform transform = this->getCTM();
+    // drawTiledShadow still does not work with rotations.
+    if (transform.isIdentityOrTranslationOrFlipped())
+        drawTiledShadow(r, topLeft, topRight, bottomLeft, bottomRight, colorSpace);
+    else
+        drawPathShadow(this, m_common, true, false);
     cairo_fill(cr);
     cairo_restore(cr);
 }
diff --git a/WebCore/platform/graphics/cairo/ImageCairo.cpp b/WebCore/platform/graphics/cairo/ImageCairo.cpp
index 3b02ad8..904e819 100644
--- a/WebCore/platform/graphics/cairo/ImageCairo.cpp
+++ b/WebCore/platform/graphics/cairo/ImageCairo.cpp
@@ -153,7 +153,7 @@ void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const Flo
         cairo_rectangle(shadowContext, 0, 0, dstRect.width(), dstRect.height());
         cairo_fill(shadowContext);
 
-        context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
+        context->applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
     }
 #endif
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list