[Qt] Add support for tiled shadow blur
authorallan.jensen@digia.com <allan.jensen@digia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 Mar 2013 14:04:32 +0000 (14:04 +0000)
committerallan.jensen@digia.com <allan.jensen@digia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 Mar 2013 14:04:32 +0000 (14:04 +0000)
https://bugs.webkit.org/show_bug.cgi?id=90082

Reviewed by Noam Rosenthal.

Use the optimized ShadowBlur::drawRectShadow as long as we do not
have a rotating transform. Such a transform would go through the
slow path in ShadowBlur anyway, and would end up using a transformed
TransparencyLayer with an alphaMap which causes scaling artifacts
for us.

Tested by fast/canvas/canvas-scale-fillRect-shadow.html
and fast/canvas/canvas-transforms-fillRect-shadow.html

* platform/graphics/ShadowBlur.cpp:
(WebCore::ShadowBlur::drawInsetShadowWithTiling):
    Handle scaling transforms when shadows ignore transforms.
(WebCore::ShadowBlur::drawRectShadowWithTiling):
    Ditto.
* platform/graphics/qt/GraphicsContextQt.cpp:
(WebCore::GraphicsContext::fillRect):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@145810 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/ShadowBlur.cpp
Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp

index 57a1f49..8d758f6 100644 (file)
@@ -1,3 +1,27 @@
+2013-03-14  Allan Sandfeld Jensen  <allan.jensen@digia.com>
+
+        [Qt] Add support for tiled shadow blur
+        https://bugs.webkit.org/show_bug.cgi?id=90082
+
+        Reviewed by Noam Rosenthal.
+
+        Use the optimized ShadowBlur::drawRectShadow as long as we do not
+        have a rotating transform. Such a transform would go through the
+        slow path in ShadowBlur anyway, and would end up using a transformed
+        TransparencyLayer with an alphaMap which causes scaling artifacts
+        for us.
+
+        Tested by fast/canvas/canvas-scale-fillRect-shadow.html
+        and fast/canvas/canvas-transforms-fillRect-shadow.html
+
+        * platform/graphics/ShadowBlur.cpp:
+        (WebCore::ShadowBlur::drawInsetShadowWithTiling):
+            Handle scaling transforms when shadows ignore transforms.
+        (WebCore::ShadowBlur::drawRectShadowWithTiling):
+            Ditto.
+        * platform/graphics/qt/GraphicsContextQt.cpp:
+        (WebCore::GraphicsContext::fillRect):
+
 2013-03-12  Andrey Kosyakov  <caseq@chromium.org>
 
         Web Inspector: do not aggregate non-main thread timeline events, handle them in a generic fashion
index 5c92612..e48aa1d 100644 (file)
@@ -679,12 +679,17 @@ void ShadowBlur::drawInsetShadowWithTiling(GraphicsContext* graphicsContext, con
 
         blurAndColorShadowBuffer(templateSize);
     }
+    FloatSize offset = m_offset;
+    if (shadowsIgnoreTransforms()) {
+        AffineTransform transform = graphicsContext->getCTM();
+        offset.scale(1 / transform.xScale(), 1 / transform.yScale());
+    }
 
     FloatRect boundingRect = rect;
-    boundingRect.move(m_offset);
+    boundingRect.move(offset);
 
     FloatRect destHoleRect = holeRect;
-    destHoleRect.move(m_offset);
+    destHoleRect.move(offset);
     FloatRect destHoleBounds = destHoleRect;
     destHoleBounds.inflateX(edgeSize.width());
     destHoleBounds.inflateY(edgeSize.height());
@@ -736,9 +741,14 @@ void ShadowBlur::drawRectShadowWithTiling(GraphicsContext* graphicsContext, cons
 
         blurAndColorShadowBuffer(templateSize);
     }
+    FloatSize offset = m_offset;
+    if (shadowsIgnoreTransforms()) {
+        AffineTransform transform = graphicsContext->getCTM();
+        offset.scale(1 / transform.xScale(), 1 / transform.yScale());
+    }
 
     FloatRect shadowBounds = shadowedRect;
-    shadowBounds.move(m_offset.width(), m_offset.height());
+    shadowBounds.move(offset);
     shadowBounds.inflateX(edgeSize.width());
     shadowBounds.inflateY(edgeSize.height());
 
index ef2b718..984fe69 100644 (file)
@@ -802,12 +802,17 @@ void GraphicsContext::fillRect(const FloatRect& rect)
     } else {
         if (hasShadow()) {
             if (shadow->mustUseShadowBlur(this)) {
-                GraphicsContext* shadowContext = shadow->beginShadowLayer(this, normalizedRect);
-                if (shadowContext) {
-                    QPainter* shadowPainter = shadowContext->platformContext();
-                    shadowPainter->fillRect(normalizedRect, p->brush());
-                    shadow->endShadowLayer(this);
-                }
+                // drawRectShadowWithTiling does not work with rotations, and the fallback of
+                // drawing though clipToImageBuffer() produces scaling artifacts for us.
+                if (!getCTM().preservesAxisAlignment()) {
+                    GraphicsContext* shadowContext = shadow->beginShadowLayer(this, normalizedRect);
+                    if (shadowContext) {
+                        QPainter* shadowPainter = shadowContext->platformContext();
+                        shadowPainter->fillRect(normalizedRect, p->brush());
+                        shadow->endShadowLayer(this);
+                    }
+                } else
+                    shadow->drawRectShadow(this, rect, RoundedRect::Radii());
             } else {
                 // Solid rectangle fill with no blur shadow or transformations applied can be done
                 // faster without using the shadow layer at all.