2011-07-05 Igor Oliveira <igor.oliveira@openbossa.org>
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Jul 2011 21:29:42 +0000 (21:29 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Jul 2011 21:29:42 +0000 (21:29 +0000)
        [Qt] Add ShadowBlur support
        https://bugs.webkit.org/show_bug.cgi?id=62997

        Use ShadowBlur instead of ContextShadow to handle canvas and css shadows. ShadowBlur is
        a newer and platform independent shadow implementation.
        Qt QPainter does not have support for shadows so is necessary to create a layer support
        to draw complex shapes and fonts. The beginShadowLayer creates a temporary shadow buffer
        where the canvas can draw onto and endShadowLayer applies the blur filter, colors the
        shadow buffer and draw the final shadow to the graphics context.

        Reviewed by Andreas Kling.

        * WebCore.pro:
        * platform/graphics/GraphicsContext.cpp:
        * platform/graphics/GraphicsContext.h:
        * platform/graphics/ShadowBlur.cpp:
        (WebCore::ShadowBlur::ShadowBlur):
        (WebCore::ShadowBlur::setShadowValues):
        (WebCore::ShadowBlur::updateShadowBlurValues):
        (WebCore::ShadowBlur::clear):
        (WebCore::ShadowBlur::blurAndColorShadowBuffer):
        (WebCore::ShadowBlur::beginShadowLayer):
        (WebCore::ShadowBlur::endShadowLayer):
        * platform/graphics/ShadowBlur.h:
        (WebCore::ShadowBlur::type):
        * platform/graphics/qt/ContextShadowQt.cpp: Removed.
        * platform/graphics/qt/FontQt.cpp:
        (WebCore::drawTextCommon):
        (WebCore::Font::drawGlyphs):
        * platform/graphics/qt/GraphicsContextQt.cpp:
        (WebCore::GraphicsContextPlatformPrivate::mustUseShadowBlur):
        (WebCore::GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate):
        (WebCore::GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate):
        (WebCore::GraphicsContext::savePlatformState):
        (WebCore::GraphicsContext::restorePlatformState):
        (WebCore::GraphicsContext::fillPath):
        (WebCore::GraphicsContext::strokePath):
        (WebCore::GraphicsContext::fillRect):
        (WebCore::GraphicsContext::fillRoundedRect):
        (WebCore::GraphicsContext::shadowBlur):
        (WebCore::GraphicsContext::clipBounds):
        (WebCore::GraphicsContext::setPlatformShadow):
        (WebCore::GraphicsContext::clearPlatformShadow):
        * platform/graphics/qt/ImageQt.cpp:
        (WebCore::BitmapImage::draw):
        * platform/graphics/qt/StillImageQt.cpp:
        (WebCore::StillImage::draw):

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

Source/WebCore/ChangeLog
Source/WebCore/WebCore.pro
Source/WebCore/platform/graphics/GraphicsContext.cpp
Source/WebCore/platform/graphics/GraphicsContext.h
Source/WebCore/platform/graphics/ShadowBlur.cpp
Source/WebCore/platform/graphics/ShadowBlur.h
Source/WebCore/platform/graphics/qt/ContextShadowQt.cpp [deleted file]
Source/WebCore/platform/graphics/qt/FontQt.cpp
Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
Source/WebCore/platform/graphics/qt/ImageQt.cpp
Source/WebCore/platform/graphics/qt/StillImageQt.cpp

index 6dd0557f1db2b817f782293cd13c48ae2d944272..b4e98171904df7c9c62ee162be5ed97e318f6404 100644 (file)
@@ -1,3 +1,53 @@
+2011-07-05  Igor Oliveira  <igor.oliveira@openbossa.org>
+
+        [Qt] Add ShadowBlur support
+        https://bugs.webkit.org/show_bug.cgi?id=62997
+
+        Use ShadowBlur instead of ContextShadow to handle canvas and css shadows. ShadowBlur is
+        a newer and platform independent shadow implementation.
+        Qt QPainter does not have support for shadows so is necessary to create a layer support
+        to draw complex shapes and fonts. The beginShadowLayer creates a temporary shadow buffer
+        where the canvas can draw onto and endShadowLayer applies the blur filter, colors the
+        shadow buffer and draw the final shadow to the graphics context.
+
+        Reviewed by Andreas Kling.
+
+        * WebCore.pro:
+        * platform/graphics/GraphicsContext.cpp:
+        * platform/graphics/GraphicsContext.h:
+        * platform/graphics/ShadowBlur.cpp:
+        (WebCore::ShadowBlur::ShadowBlur):
+        (WebCore::ShadowBlur::setShadowValues):
+        (WebCore::ShadowBlur::updateShadowBlurValues):
+        (WebCore::ShadowBlur::clear):
+        (WebCore::ShadowBlur::blurAndColorShadowBuffer):
+        (WebCore::ShadowBlur::beginShadowLayer):
+        (WebCore::ShadowBlur::endShadowLayer):
+        * platform/graphics/ShadowBlur.h:
+        (WebCore::ShadowBlur::type):
+        * platform/graphics/qt/ContextShadowQt.cpp: Removed.
+        * platform/graphics/qt/FontQt.cpp:
+        (WebCore::drawTextCommon):
+        (WebCore::Font::drawGlyphs):
+        * platform/graphics/qt/GraphicsContextQt.cpp:
+        (WebCore::GraphicsContextPlatformPrivate::mustUseShadowBlur):
+        (WebCore::GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate):
+        (WebCore::GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate):
+        (WebCore::GraphicsContext::savePlatformState):
+        (WebCore::GraphicsContext::restorePlatformState):
+        (WebCore::GraphicsContext::fillPath):
+        (WebCore::GraphicsContext::strokePath):
+        (WebCore::GraphicsContext::fillRect):
+        (WebCore::GraphicsContext::fillRoundedRect):
+        (WebCore::GraphicsContext::shadowBlur):
+        (WebCore::GraphicsContext::clipBounds):
+        (WebCore::GraphicsContext::setPlatformShadow):
+        (WebCore::GraphicsContext::clearPlatformShadow):
+        * platform/graphics/qt/ImageQt.cpp:
+        (WebCore::BitmapImage::draw):
+        * platform/graphics/qt/StillImageQt.cpp:
+        (WebCore::StillImage::draw):
+
 2011-07-05  Sam Weinig  <sam@webkit.org>
 
         Null deref accessing CustomEvent.detail
index d78a13ce389e3e6f3a9e725e3692d8a22f5b9688..0e871edc777ee5a84b6919960db83ca0eb59894f 100644 (file)
@@ -978,7 +978,7 @@ SOURCES += \
     platform/graphics/FontFamily.cpp \
     platform/graphics/BitmapImage.cpp \
     platform/graphics/Color.cpp \
-    platform/graphics/ContextShadow.cpp \
+    platform/graphics/ShadowBlur.cpp \
     platform/graphics/FloatPoint3D.cpp \
     platform/graphics/FloatPoint.cpp \
     platform/graphics/FloatQuad.cpp \
@@ -1939,7 +1939,7 @@ HEADERS += \
     platform/mock/SpeechInputClientMock.h \
     platform/graphics/BitmapImage.h \
     platform/graphics/Color.h \
-    platform/graphics/ContextShadow.h \
+    platform/graphics/ShadowBlur.h \
     platform/graphics/filters/FEBlend.h \
     platform/graphics/filters/FEColorMatrix.h \
     platform/graphics/filters/FEComponentTransfer.h \
@@ -2521,7 +2521,6 @@ SOURCES += \
     page/qt/FrameQt.cpp \
     platform/graphics/qt/TransformationMatrixQt.cpp \
     platform/graphics/qt/ColorQt.cpp \
-    platform/graphics/qt/ContextShadowQt.cpp \
     platform/graphics/qt/FontQt.cpp \
     platform/graphics/qt/FontPlatformDataQt.cpp \
     platform/graphics/qt/FloatPointQt.cpp \
index 3b77b9f341104c4af9a402318711d83dbfe1c713..f3f99e475b228ed1314f9ae7e91ccc043d5e5da6 100644 (file)
@@ -585,7 +585,7 @@ void GraphicsContext::clipToImageBuffer(ImageBuffer* buffer, const FloatRect& re
     buffer->clip(this, rect);
 }
 
-#if !USE(CG)
+#if !USE(CG) && !PLATFORM(QT)
 IntRect GraphicsContext::clipBounds() const
 {
     ASSERT_NOT_REACHED();
index 360a7c5f4b212ad7908c1eff9b050b7bbb39bd74..063f76269c296bba7856b8e40b178d1747dc9ca8 100644 (file)
@@ -54,6 +54,7 @@ typedef class WebCore::SurfaceOpenVG PlatformGraphicsContext;
 #include <QPainter>
 namespace WebCore {
 class ContextShadow;
+class ShadowBlur;
 }
 typedef QPainter PlatformGraphicsContext;
 #elif PLATFORM(WX)
@@ -486,10 +487,14 @@ namespace WebCore {
         void takeOwnershipOfPlatformContext();
 #endif
 
-#if PLATFORM(QT) || USE(CAIRO)
+#if USE(CAIRO)
         ContextShadow* contextShadow();
 #endif
 
+#if PLATFORM(QT)
+        ShadowBlur* shadowBlur();
+#endif
+
 #if USE(CAIRO)
         GraphicsContext(cairo_t*);
 #endif
index 25fc9aa77e6910fd659fc120761642ca69d94ec6..fa735aa2f871a734a01ec975730183fb1dcaa86a 100644 (file)
@@ -175,12 +175,35 @@ ShadowBlur::ShadowBlur(const FloatSize& radius, const FloatSize& offset, const C
     , m_offset(offset)
     , m_layerImage(0)
     , m_shadowsIgnoreTransforms(false)
+{
+    updateShadowBlurValues();
+}
+
+ShadowBlur::ShadowBlur()
+    : m_type(NoShadow)
+    , m_blurRadius(0, 0)
+    , m_shadowsIgnoreTransforms(false)
+{
+}
+
+void ShadowBlur::setShadowValues(const FloatSize& radius, const FloatSize& offset, const Color& color, ColorSpace colorSpace, bool ignoreTransforms)
+{
+    m_blurRadius = radius;
+    m_offset = offset;
+    m_color = color;
+    m_colorSpace = colorSpace;
+    m_shadowsIgnoreTransforms = ignoreTransforms;
+
+    updateShadowBlurValues();
+}
+
+void ShadowBlur::updateShadowBlurValues()
 {
     // Limit blur radius to 128 to avoid lots of very expensive blurring.
     m_blurRadius = m_blurRadius.shrunkTo(FloatSize(128, 128));
 
     // The type of shadow is decided by the blur radius, shadow offset, and shadow color.
-    if (!m_color.isValid() || !color.alpha()) {
+    if (!m_color.isValid() || !m_color.alpha()) {
         // Can't paint the shadow with invalid or invisible color.
         m_type = NoShadow;
     } else if (m_blurRadius.width() > 0 || m_blurRadius.height() > 0) {
@@ -237,6 +260,14 @@ static void calculateLobes(int lobes[][2], float blurRadius, bool shadowsIgnoreT
     }
 }
 
+void ShadowBlur::clear()
+{
+    m_type = NoShadow;
+    m_color = Color();
+    m_blurRadius = FloatSize();
+    m_offset = FloatSize();
+}
+
 void ShadowBlur::blurLayerImage(unsigned char* imageData, const IntSize& size, int rowStride)
 {
     const int channels[4] = { 3, 0, 1, 3 };
@@ -828,9 +859,43 @@ void ShadowBlur::blurAndColorShadowBuffer(const IntSize& templateSize)
 
     // Mask the image with the shadow color.
     GraphicsContext* shadowContext = m_layerImage->context();
+    GraphicsContextStateSaver stateSaver(*shadowContext);
     shadowContext->setCompositeOperation(CompositeSourceIn);
     shadowContext->setFillColor(m_color, m_colorSpace);
     shadowContext->fillRect(FloatRect(0, 0, templateSize.width(), templateSize.height()));
 }
 
+GraphicsContext* ShadowBlur::beginShadowLayer(GraphicsContext *context, const FloatRect& layerArea)
+{
+    adjustBlurRadius(context);
+
+    IntRect layerRect = calculateLayerBoundingRect(context, layerArea, context->clipBounds());
+
+    if (layerRect.isEmpty())
+        return 0;
+
+    m_layerImage = ScratchBuffer::shared().getScratchBuffer(layerRect.size());
+
+    GraphicsContext* shadowContext = m_layerImage->context();
+    shadowContext->save();
+    shadowContext->clearRect(FloatRect(0, 0, m_layerSize.width(), m_layerSize.height()));
+
+    shadowContext->translate(m_layerContextTranslation);
+    return shadowContext;
+}
+
+void ShadowBlur::endShadowLayer(GraphicsContext* context)
+{
+    m_layerImage->context()->restore();
+
+    blurAndColorShadowBuffer(expandedIntSize(m_layerSize));
+    GraphicsContextStateSaver stateSave(*context);
+
+    context->clearShadow();
+    context->drawImageBuffer(m_layerImage, ColorSpaceDeviceRGB, roundedIntPoint(m_layerOrigin), IntRect(0, 0, m_layerSize.width(), m_layerSize.height()), context->compositeOperation());
+
+    m_layerImage = 0;
+    ScratchBuffer::shared().scheduleScratchBufferPurge();
+}
+
 } // namespace WebCore
index 202ff3d907335727a2a3e67d8821e22de367eded..99eea533090d0e66239cbac1f9e8b79b5e078e54 100644 (file)
@@ -44,17 +44,34 @@ class ImageBuffer;
 class ShadowBlur {
     WTF_MAKE_NONCOPYABLE(ShadowBlur);
 public:
+    enum ShadowType {
+        NoShadow,
+        SolidShadow,
+        BlurShadow
+    };
+
     ShadowBlur(const FloatSize& radius, const FloatSize& offset, const Color&, ColorSpace);
+    ShadowBlur();
+
+    void setShadowValues(const FloatSize&, const FloatSize& , const Color&, ColorSpace, bool ignoreTransforms = false);
 
     void setShadowsIgnoreTransforms(bool ignoreTransforms) { m_shadowsIgnoreTransforms = ignoreTransforms; }
     bool shadowsIgnoreTransforms() const { return m_shadowsIgnoreTransforms; }
 
+    GraphicsContext* beginShadowLayer(GraphicsContext*, const FloatRect& layerArea);
+    void endShadowLayer(GraphicsContext*);
+
     void drawRectShadow(GraphicsContext*, const FloatRect&, const RoundedIntRect::Radii&);
     void drawInsetShadow(GraphicsContext*, const FloatRect&, const FloatRect& holeRect, const RoundedIntRect::Radii& holeRadii);
 
     void blurLayerImage(unsigned char*, const IntSize&, int stride);
 
+    void clear();
+
+    ShadowType type() const { return m_type; }
 private:
+    void updateShadowBlurValues();
+
     void drawShadowBuffer(GraphicsContext*);
 
     void adjustBlurRadius(GraphicsContext*);
@@ -80,11 +97,6 @@ private:
     
     IntSize blurredEdgeSize() const;
     
-    enum ShadowType {
-        NoShadow,
-        SolidShadow,
-        BlurShadow
-    };
     
     ShadowType m_type;
 
diff --git a/Source/WebCore/platform/graphics/qt/ContextShadowQt.cpp b/Source/WebCore/platform/graphics/qt/ContextShadowQt.cpp
deleted file mode 100644 (file)
index 9eb31a7..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2010 Sencha, Inc.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ContextShadow.h"
-
-#include "AffineTransform.h"
-#include "GraphicsContext.h"
-#include <QPainter>
-#include <QTimerEvent>
-
-namespace WebCore {
-
-// ContextShadow needs a scratch image as the buffer for the blur filter.
-// Instead of creating and destroying the buffer for every operation,
-// we create a buffer which will be automatically purged via a timer.
-
-class ShadowBuffer: public QObject {
-public:
-    ShadowBuffer(QObject* parent = 0);
-
-    QImage* scratchImage(const QSize& size);
-
-    void schedulePurge();
-
-protected:
-    void timerEvent(QTimerEvent* event);
-
-private:
-    QImage image;
-    int timerId;
-};
-
-ShadowBuffer::ShadowBuffer(QObject* parent)
-    : QObject(parent)
-    , timerId(-1)
-{
-}
-
-QImage* ShadowBuffer::scratchImage(const QSize& size)
-{
-    int width = size.width();
-    int height = size.height();
-
-    // We do not need to recreate the buffer if the buffer is reasonably
-    // larger than the requested size. However, if the requested size is
-    // much smaller than our buffer, reduce our buffer so that we will not
-    // keep too many allocated pixels for too long.
-    if (!image.isNull() && (image.width() > width) && (image.height() > height))
-        if (((2 * width) > image.width()) && ((2 * height) > image.height())) {
-            image.fill(0);
-            return &image;
-        }
-
-    // Round to the nearest 32 pixels so we do not grow the buffer everytime
-    // there is larger request by 1 pixel.
-    width = (1 + (width >> 5)) << 5;
-    height = (1 + (height >> 5)) << 5;
-
-    image = QImage(width, height, QImage::Format_ARGB32_Premultiplied);
-    image.fill(0);
-    return &image;
-}
-
-void ShadowBuffer::schedulePurge()
-{
-    static const double BufferPurgeDelay = 2; // seconds
-    if (timerId >= 0)
-        killTimer(timerId);
-    timerId = startTimer(BufferPurgeDelay * 1000);
-}
-
-void ShadowBuffer::timerEvent(QTimerEvent* event)
-{
-    if (event->timerId() == timerId) {
-        killTimer(timerId);
-        image = QImage();
-    }
-    QObject::timerEvent(event);
-}
-
-Q_GLOBAL_STATIC(ShadowBuffer, scratchShadowBuffer)
-
-PlatformContext ContextShadow::beginShadowLayer(GraphicsContext* context, const FloatRect& layerArea)
-{
-    // Set m_blurDistance.
-    adjustBlurDistance(context);
-
-    PlatformContext p = context->platformContext();
-
-    QRect clipRect;
-    if (p->hasClipping())
-#if QT_VERSION >= QT_VERSION_CHECK(4, 8, 0)
-        clipRect = p->clipBoundingRect().toAlignedRect();
-#else
-        clipRect = p->clipRegion().boundingRect();
-#endif
-    else
-        clipRect = p->transform().inverted().mapRect(p->window());
-
-    // Set m_layerOrigin, m_layerContextTranslation, m_sourceRect.
-    IntRect clip(clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height());
-    IntRect layerRect = calculateLayerBoundingRect(context, layerArea, clip);
-
-    // Don't paint if we are totally outside the clip region.
-    if (layerRect.isEmpty())
-        return 0;
-
-    ShadowBuffer* shadowBuffer = scratchShadowBuffer();
-    QImage* shadowImage = shadowBuffer->scratchImage(layerRect.size());
-    m_layerImage = QImage(*shadowImage);
-
-    m_layerContext = new QPainter;
-    m_layerContext->begin(&m_layerImage);
-    m_layerContext->setFont(p->font());
-    m_layerContext->translate(m_layerContextTranslation);
-    return m_layerContext;
-}
-
-void ContextShadow::endShadowLayer(GraphicsContext* context)
-{
-    m_layerContext->end();
-    delete m_layerContext;
-    m_layerContext = 0;
-
-    if (m_type == BlurShadow) {
-        blurLayerImage(m_layerImage.bits(), IntSize(m_layerImage.width(), m_layerImage.height()),
-                       m_layerImage.bytesPerLine());
-    }
-
-    if (m_type != NoShadow) {
-        // "Colorize" with the right shadow color.
-        QPainter p(&m_layerImage);
-        p.setCompositionMode(QPainter::CompositionMode_SourceIn);
-        p.fillRect(m_layerImage.rect(), m_color.rgb());
-        p.end();
-    }
-
-    context->platformContext()->drawImage(m_layerOrigin, m_layerImage, m_sourceRect);
-
-    scratchShadowBuffer()->schedulePurge();
-}
-
-}
index a5a16e0fa032da367086d213e0b4d38a5ccfb24f..a212eef0e662de39dc9899fc524e83aed15846bc 100644 (file)
@@ -23,7 +23,6 @@
 #include "Font.h"
 
 #include "AffineTransform.h"
-#include "ContextShadow.h"
 #include "FontDescription.h"
 #include "FontFallbackList.h"
 #include "FontSelector.h"
@@ -34,6 +33,7 @@
 #include "GraphicsContext.h"
 #include "NotImplemented.h"
 #include "Pattern.h"
+#include "ShadowBlur.h"
 #include "TextRun.h"
 
 #include <QBrush>
@@ -142,40 +142,43 @@ static void drawTextCommon(GraphicsContext* ctx, const TextRun& run, const Float
             QRectF boundingRect(point.x() + x1, point.y() - ascent, x2 - x1, fm.height());
             QRectF clip = boundingRect;
 
-            ContextShadow* ctxShadow = ctx->contextShadow();
-
-            if (ctxShadow->m_type != ContextShadow::NoShadow) {
+            ShadowBlur* ctxShadow = ctx->shadowBlur();
+            if (ctxShadow->type() != ShadowBlur::NoShadow) {
+                const QPointF shadowOffset(ctx->state().shadowOffset.width(), ctx->state().shadowOffset.height());
                 qreal dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0;
-                if (ctxShadow->offset().x() > 0)
-                    dx2 = ctxShadow->offset().x();
+                if (shadowOffset.x() > 0)
+                    dx2 = shadowOffset.x();
                 else
-                    dx1 = -ctxShadow->offset().x();
-                if (ctxShadow->offset().y() > 0)
-                    dy2 = ctxShadow->offset().y();
+                    dx1 = -shadowOffset.x();
+                if (shadowOffset.y() > 0)
+                    dy2 = shadowOffset.y();
                 else
-                    dy1 = -ctxShadow->offset().y();
+                    dy1 = -shadowOffset.y();
                 // expand the clip rect to include the text shadow as well
+                const float blurDistance = ctx->state().shadowBlur;
                 clip.adjust(dx1, dx2, dy1, dy2);
-                clip.adjust(-ctxShadow->m_blurDistance, -ctxShadow->m_blurDistance, ctxShadow->m_blurDistance, ctxShadow->m_blurDistance);
+                clip.adjust(-blurDistance, -blurDistance, blurDistance, blurDistance);
             }
             p->save();
             p->setClipRect(clip.toRect(), Qt::IntersectClip);
             pt.setY(pt.y() - ascent);
 
-            if (ctxShadow->m_type != ContextShadow::NoShadow) {
-                ContextShadow* ctxShadow = ctx->contextShadow();
-                if (!ctxShadow->mustUseContextShadow(ctx)) {
+            if (ctxShadow->type() != ShadowBlur::NoShadow) {
+                ShadowBlur* ctxShadow = ctx->shadowBlur();
+                if (ctxShadow->type() != ShadowBlur::BlurShadow
+                    && (!ctxShadow->shadowsIgnoreTransforms() || ctx->getCTM().isIdentity())) {
                     p->save();
-                    p->setPen(ctxShadow->m_color);
-                    p->translate(ctxShadow->offset());
+                    p->setPen(ctx->state().shadowColor);
+                    p->translate(QPointF(ctx->state().shadowOffset.width(), ctx->state().shadowOffset.height()));
                     line.draw(p, pt);
                     p->restore();
                 } else {
-                    QPainter* shadowPainter = ctxShadow->beginShadowLayer(ctx, boundingRect);
-                    if (shadowPainter) {
+                    GraphicsContext* shadowContext = ctxShadow->beginShadowLayer(ctx, boundingRect);
+                    if (shadowContext) {
+                        QPainter* shadowPainter = shadowContext->platformContext();
                         // Since it will be blurred anyway, we don't care about render hints.
                         shadowPainter->setFont(p->font());
-                        shadowPainter->setPen(ctxShadow->m_color);
+                        shadowPainter->setPen(ctx->state().shadowColor);
                         line.draw(shadowPainter, pt);
                         ctxShadow->endShadowLayer(ctx);
                     }
@@ -201,40 +204,43 @@ static void drawTextCommon(GraphicsContext* ctx, const TextRun& run, const Float
     if (ctx->textDrawingMode() & TextModeStroke)
         textStrokePath.addText(pt, font, string);
 
-    ContextShadow* ctxShadow = ctx->contextShadow();
-    if (ctxShadow->m_type != ContextShadow::NoShadow) {
+    ShadowBlur* ctxShadow = ctx->shadowBlur();
+    if (ctx->hasShadow() && ctxShadow->type() != ShadowBlur::NoShadow) {
         if (ctx->textDrawingMode() & TextModeFill) {
-            if (ctxShadow->m_type != ContextShadow::BlurShadow) {
+            if (ctxShadow->type() != ShadowBlur::BlurShadow) {
                 p->save();
-                p->setPen(ctxShadow->m_color);
-                p->translate(ctxShadow->offset());
+                p->setPen(ctx->state().shadowColor);
+                p->translate(QPointF(ctx->state().shadowOffset.width(), ctx->state().shadowOffset.height()));
                 p->drawText(pt, string, flags, run.expansion());
                 p->restore();
             } else {
                 QFontMetrics fm(font);
                 QRectF boundingRect(pt.x(), point.y() - fm.ascent(), fm.width(string, -1, flags), fm.height());
-                QPainter* shadowPainter = ctxShadow->beginShadowLayer(ctx, boundingRect);
-                if (shadowPainter) {
+                GraphicsContext* shadowContext = ctxShadow->beginShadowLayer(ctx, boundingRect);
+                if (shadowContext) {
+                    QPainter* shadowPainter = shadowContext->platformContext();
                     // Since it will be blurred anyway, we don't care about render hints.
                     shadowPainter->setFont(p->font());
-                    shadowPainter->setPen(ctxShadow->m_color);
+                    shadowPainter->setPen(ctx->state().shadowColor);
                     shadowPainter->drawText(pt, string, flags, run.expansion());
                     ctxShadow->endShadowLayer(ctx);
                 }
             }
         } else if (ctx->textDrawingMode() & TextModeStroke) {
-            if (ctxShadow->m_type != ContextShadow::BlurShadow) {
-                p->translate(ctxShadow->offset());
-                p->strokePath(textStrokePath, QPen(ctxShadow->m_color));
-                p->translate(-ctxShadow->offset());
+            if (ctxShadow->type() != ShadowBlur::BlurShadow) {
+                const QPointF shadowOffset(ctx->state().shadowOffset.width(), ctx->state().shadowOffset.height());
+                p->translate(shadowOffset);
+                p->strokePath(textStrokePath, QPen(ctx->state().shadowColor));
+                p->translate(-shadowOffset);
             } else {
                 QFontMetrics fm(font);
                 QRectF boundingRect(pt.x(), point.y() - fm.ascent(), fm.width(string, -1, flags), fm.height());
-                QPainter* shadowPainter = ctxShadow->beginShadowLayer(ctx, boundingRect);
-                if (shadowPainter) {
+                GraphicsContext* shadowContext = ctxShadow->beginShadowLayer(ctx, boundingRect);
+                if (shadowContext) {
+                    QPainter* shadowPainter = shadowContext->platformContext();
                     // Since it will be blurred anyway, we don't care about render hints.
                     shadowPainter->setFont(p->font());
-                    shadowPainter->strokePath(textStrokePath, QPen(ctxShadow->m_color));
+                    shadowPainter->strokePath(textStrokePath, QPen(ctx->state().shadowColor));
                     ctxShadow->endShadowLayer(ctx);
                 }
             }
@@ -328,7 +334,7 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* fontData,
     ASSERT(!shouldStroke);
 
     // Shadowed text should always take the complex path.
-    ASSERT(context->contextShadow()->m_type == ContextShadow::NoShadow);
+    ASSERT(context->contextShadow()->type() == ShadowBlur::NoShadow);
 
     if (!shouldFill && !shouldStroke)
         return;
@@ -361,7 +367,7 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* fontData,
     QPainter* painter = context->platformContext();
 
     ContextShadow* shadow = context->contextShadow();
-    switch (shadow->m_type) {
+    switch (shadow->type()) {
     case ContextShadow::SolidShadow: {
         QPen previousPen = painter->pen();
         painter->setPen(shadow->m_color);
@@ -374,8 +380,9 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* fontData,
     case ContextShadow::BlurShadow: {
         qreal height = rawFont.ascent() + rawFont.descent() + 1;
         QRectF boundingRect(point.x(), point.y() - rawFont.ascent(), width, height);
-        QPainter* shadowPainter = shadow->beginShadowLayer(context, boundingRect);
-        if (shadowPainter) {
+        GraphicsContext* shadowContext = shadow->beginShadowLayer(context, boundingRect);
+        if (shadowContext) {
+            QPainter* shadowPainter = shadowContext->platformContext();
             shadowPainter->setPen(shadow->m_color);
             shadowPainter->drawGlyphRun(point, qtGlyphs);
             shadow->endShadowLayer(context);
index 7f112d45b2ef1239b095ca20dc67a28c0f871d9b..521a47e2669cb11192c173d668666248e584cf6f 100644 (file)
 
 #include "AffineTransform.h"
 #include "Color.h"
-#include "ContextShadow.h"
 #include "FloatConversion.h"
 #include "Font.h"
 #include "ImageBuffer.h"
 #include "NotImplemented.h"
 #include "Path.h"
 #include "Pattern.h"
+#include "ShadowBlur.h"
 #include "TransparencyLayer.h"
 
 #include <QBrush>
@@ -196,8 +196,23 @@ public:
     InterpolationQuality imageInterpolationQuality;
     bool initialSmoothPixmapTransformHint;
 
-    ContextShadow shadow;
-    QStack<ContextShadow> shadowStack;
+    ShadowBlur* shadow;
+
+    bool mustUseShadowBlur() const
+    {
+        // We can't avoid ShadowBlur, since the shadow has blur.
+        if (shadow->type() == ShadowBlur::BlurShadow)
+            return true;
+        // We can avoid ShadowBlur and optimize, since we're not drawing on a
+        // canvas and box shadows are affected by the transformation matrix.
+        if (!shadow->shadowsIgnoreTransforms())
+            return false;
+        // We can avoid ShadowBlur, since there are no transformations to apply to the canvas.
+        if (p()->combinedTransform().isIdentity())
+            return false;
+        // Otherwise, no chance avoiding ShadowBlur.
+        return true;
+    }
 
     QRectF clipBoundingRect() const
     {
@@ -221,6 +236,7 @@ GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate(QPainter* p, cons
     , solidColor(initialSolidColor)
     , imageInterpolationQuality(InterpolationDefault)
     , initialSmoothPixmapTransformHint(false)
+    , shadow(new ShadowBlur())
     , painter(p)
     , platformContextIsOwned(false)
 {
@@ -241,6 +257,7 @@ GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate(QPainter* p, cons
     initialSmoothPixmapTransformHint = painter->testRenderHint(QPainter::SmoothPixmapTransform);
 
     painter->setRenderHint(QPainter::Antialiasing, true);
+
 }
 
 GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate()
@@ -250,6 +267,7 @@ GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate()
 
     QPaintDevice* device = painter->device();
     painter->end();
+    delete shadow;
     delete painter;
     delete device;
 }
@@ -297,7 +315,6 @@ void GraphicsContext::savePlatformState()
     if (!m_data->layers.isEmpty() && !m_data->layers.top()->alphaMask.isNull())
         ++m_data->layers.top()->saveCounter;
     m_data->p()->save();
-    m_data->shadowStack.push(m_data->shadow);
 }
 
 void GraphicsContext::restorePlatformState()
@@ -308,10 +325,7 @@ void GraphicsContext::restorePlatformState()
 
     m_data->p()->restore();
 
-    if (m_data->shadowStack.isEmpty())
-        m_data->shadow = ContextShadow();
-    else
-        m_data->shadow = m_data->shadowStack.pop();
+    m_data->shadow->setShadowValues(FloatSize(m_state.shadowBlur, m_state.shadowBlur), m_state.shadowOffset, m_state.shadowColor, m_state.shadowColorSpace, m_state.shadowsIgnoreTransforms);
 }
 
 // Draws a filled rectangle with a stroked border.
@@ -495,31 +509,29 @@ void GraphicsContext::fillPath(const Path& path)
     platformPath.setFillRule(toQtFillRule(fillRule()));
 
     if (hasShadow()) {
-        ContextShadow* shadow = contextShadow();
-        if (shadow->mustUseContextShadow(this) || m_state.fillPattern || m_state.fillGradient)
+        ShadowBlur* shadow = shadowBlur();
+        if (m_data->mustUseShadowBlur() || m_state.fillPattern || m_state.fillGradient)
         {
-            QPainter* shadowPainter = shadow->beginShadowLayer(this, platformPath.controlPointRect());
-            if (shadowPainter) {
+            GraphicsContext* shadowContext = shadow->beginShadowLayer(this, platformPath.controlPointRect());
+            if (shadowContext) {
+                QPainter* shadowPainter = shadowContext->platformContext();
                 if (m_state.fillPattern) {
                     AffineTransform affine;
-                    shadowPainter->setOpacity(static_cast<qreal>(shadow->m_color.alpha()) / 255);
                     shadowPainter->fillPath(platformPath, QBrush(m_state.fillPattern->createPlatformPattern(affine)));
                 } else if (m_state.fillGradient) {
                     QBrush brush(*m_state.fillGradient->platformGradient());
                     brush.setTransform(m_state.fillGradient->gradientSpaceTransform());
-                    shadowPainter->setOpacity(static_cast<qreal>(shadow->m_color.alpha()) / 255);
                     shadowPainter->fillPath(platformPath, brush);
                 } else {
-                    QColor shadowColor = shadow->m_color;
-                    shadowColor.setAlphaF(shadowColor.alphaF() * p->brush().color().alphaF());
-                    shadowPainter->fillPath(platformPath, shadowColor);
+                    QColor shadowColor = m_state.shadowColor;
+                    shadowPainter->fillPath(platformPath, p->brush().color());
                 }
                 shadow->endShadowLayer(this);
             }
         } else {
-            QPointF offset = shadow->offset();
+            QPointF offset(m_state.shadowOffset.width(), m_state.shadowOffset.height());
             p->translate(offset);
-            QColor shadowColor = shadow->m_color;
+            QColor shadowColor = m_state.shadowColor;
             shadowColor.setAlphaF(shadowColor.alphaF() * p->brush().color().alphaF());
             p->fillPath(platformPath, shadowColor);
             p->translate(-offset);
@@ -547,30 +559,29 @@ void GraphicsContext::strokePath(const Path& path)
     platformPath.setFillRule(toQtFillRule(fillRule()));
 
     if (hasShadow()) {
-        ContextShadow* shadow = contextShadow();
-        if (shadow->mustUseContextShadow(this) || m_state.strokePattern || m_state.strokeGradient)
+        ShadowBlur* shadow = shadowBlur();
+        if (m_data->mustUseShadowBlur() || m_state.strokePattern || m_state.strokeGradient)
         {
             FloatRect boundingRect = platformPath.controlPointRect();
             boundingRect.inflate(pen.miterLimit() + pen.widthF());
-            QPainter* shadowPainter = shadow->beginShadowLayer(this, boundingRect);
-            if (shadowPainter) {
+            GraphicsContext* shadowContext = shadow->beginShadowLayer(this, boundingRect);
+            if (shadowContext) {
+                QPainter* shadowPainter = shadowContext->platformContext();
                 if (m_state.strokeGradient) {
                     QBrush brush(*m_state.strokeGradient->platformGradient());
                     brush.setTransform(m_state.strokeGradient->gradientSpaceTransform());
                     QPen shadowPen(pen);
                     shadowPen.setBrush(brush);
-                    shadowPainter->setOpacity(static_cast<qreal>(shadow->m_color.alpha()) / 255);
                     shadowPainter->strokePath(platformPath, shadowPen);
                 } else {
-                    shadowPainter->setOpacity(static_cast<qreal>(m_data->shadow.m_color.alpha()) / 255);
                     shadowPainter->strokePath(platformPath, pen);
                 }
                 shadow->endShadowLayer(this);
             }
         } else {
-            QPointF offset = shadow->offset();
+            QPointF offset(m_state.shadowOffset.width(), m_state.shadowOffset.height());
             p->translate(offset);
-            QColor shadowColor = shadow->m_color;
+            QColor shadowColor = m_state.shadowColor;
             shadowColor.setAlphaF(shadowColor.alphaF() * pen.color().alphaF());
             QPen shadowPen(pen);
             shadowPen.setColor(shadowColor);
@@ -668,44 +679,42 @@ void GraphicsContext::fillRect(const FloatRect& rect)
 
     QPainter* p = m_data->p();
     QRectF normalizedRect = rect.normalized();
-    ContextShadow* shadow = contextShadow();
+    ShadowBlur* shadow = shadowBlur();
 
     if (m_state.fillPattern) {
         QPixmap* image = m_state.fillPattern->tileImage()->nativeImageForCurrentFrame();
-        QPainter* shadowPainter = hasShadow() ? shadow->beginShadowLayer(this, normalizedRect) : 0;
-        if (shadowPainter) {
+        GraphicsContext* shadowContext = hasShadow() ? shadow->beginShadowLayer(this, normalizedRect) : 0;
+        if (shadowContext) {
+            QPainter* shadowPainter = shadowContext->platformContext();
             drawRepeatPattern(shadowPainter, image, normalizedRect, m_state.fillPattern->repeatX(), m_state.fillPattern->repeatY());
-            shadowPainter->setCompositionMode(QPainter::CompositionMode_SourceIn);
-            shadowPainter->fillRect(normalizedRect, shadow->m_color);
             shadow->endShadowLayer(this);
         }
         drawRepeatPattern(p, image, normalizedRect, m_state.fillPattern->repeatX(), m_state.fillPattern->repeatY());
     } else if (m_state.fillGradient) {
         QBrush brush(*m_state.fillGradient->platformGradient());
         brush.setTransform(m_state.fillGradient->gradientSpaceTransform());
-        QPainter* shadowPainter = hasShadow() ? shadow->beginShadowLayer(this, normalizedRect) : 0;
-        if (shadowPainter) {
+        GraphicsContext* shadowContext = hasShadow() ? shadow->beginShadowLayer(this, normalizedRect) : 0;
+        if (shadowContext) {
+            QPainter* shadowPainter = shadowContext->platformContext();
             shadowPainter->fillRect(normalizedRect, brush);
-            shadowPainter->setCompositionMode(QPainter::CompositionMode_SourceIn);
-            shadowPainter->fillRect(normalizedRect, shadow->m_color);
             shadow->endShadowLayer(this);
         }
         p->fillRect(normalizedRect, brush);
     } else {
         if (hasShadow()) {
-            if (shadow->mustUseContextShadow(this)) {
-                QPainter* shadowPainter = shadow->beginShadowLayer(this, normalizedRect);
-                if (shadowPainter) {
-                    shadowPainter->setOpacity(static_cast<qreal>(shadow->m_color.alpha()) / 255);
+            if (m_data->mustUseShadowBlur()) {
+                GraphicsContext* shadowContext = shadow->beginShadowLayer(this, normalizedRect);
+                if (shadowContext) {
+                    QPainter* shadowPainter = shadowContext->platformContext();
                     shadowPainter->fillRect(normalizedRect, p->brush());
                     shadow->endShadowLayer(this);
                 }
             } else {
                 // Solid rectangle fill with no blur shadow or transformations applied can be done
                 // faster without using the shadow layer at all.
-                QColor shadowColor = shadow->m_color;
+                QColor shadowColor = m_state.shadowColor;
                 shadowColor.setAlphaF(shadowColor.alphaF() * p->brush().color().alphaF());
-                p->fillRect(normalizedRect.translated(shadow->offset()), shadowColor);
+                p->fillRect(normalizedRect.translated(QPointF(m_state.shadowOffset.width(), m_state.shadowOffset.height())), shadowColor);
             }
         }
 
@@ -724,16 +733,20 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorS
     QRectF normalizedRect = rect.normalized();
 
     if (hasShadow()) {
-        ContextShadow* shadow = contextShadow();
-        if (shadow->mustUseContextShadow(this)) {
-            QPainter* shadowPainter = shadow->beginShadowLayer(this, normalizedRect);
-            if (shadowPainter) {
+        ShadowBlur* shadow = shadowBlur();
+        if (m_data->mustUseShadowBlur()) {
+            GraphicsContext* shadowContext = shadow->beginShadowLayer(this, normalizedRect);
+            if (shadowContext) {
+                QPainter* shadowPainter = shadowContext->platformContext();
                 shadowPainter->setCompositionMode(QPainter::CompositionMode_Source);
-                shadowPainter->fillRect(normalizedRect, shadow->m_color);
+                shadowPainter->fillRect(normalizedRect, m_state.shadowColor);
                 shadow->endShadowLayer(this);
             }
-        } else
-            p->fillRect(normalizedRect.translated(shadow->offset()), shadow->m_color);
+        } else {
+            QColor shadowColor = m_state.shadowColor;
+            shadowColor.setAlphaF(shadowColor.alphaF() * p->brush().color().alphaF());
+            p->fillRect(normalizedRect.translated(QPointF(m_state.shadowOffset.width(), m_state.shadowOffset.height())), shadowColor);
+        }
     }
 
     p->fillRect(normalizedRect, m_data->solidColor);
@@ -748,18 +761,20 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef
     path.addRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight);
     QPainter* p = m_data->p();
     if (hasShadow()) {
-        ContextShadow* shadow = contextShadow();
-        if (shadow->mustUseContextShadow(this)) {
-            QPainter* shadowPainter = shadow->beginShadowLayer(this, rect);
-            if (shadowPainter) {
+        ShadowBlur* shadow = shadowBlur();
+        if (m_data->mustUseShadowBlur()) {
+            GraphicsContext* shadowContext = shadow->beginShadowLayer(this, rect);
+            if (shadowContext) {
+                QPainter* shadowPainter = shadowContext->platformContext();
                 shadowPainter->setCompositionMode(QPainter::CompositionMode_Source);
-                shadowPainter->fillPath(path.platformPath(), QColor(m_data->shadow.m_color));
+                shadowPainter->fillPath(path.platformPath(), QColor(m_state.shadowColor));
                 shadow->endShadowLayer(this);
             }
         } else {
-            p->translate(m_data->shadow.offset());
-            p->fillPath(path.platformPath(), QColor(m_data->shadow.m_color));
-            p->translate(-m_data->shadow.offset());
+            const QPointF shadowOffset(m_state.shadowOffset.width(), m_state.shadowOffset.height());
+            p->translate(shadowOffset);
+            p->fillPath(path.platformPath(), QColor(m_state.shadowColor));
+            p->translate(-shadowOffset);
         }
     }
     p->fillPath(path.platformPath(), QColor(color));
@@ -770,9 +785,9 @@ bool GraphicsContext::inTransparencyLayer() const
     return m_data->layerCount;
 }
 
-ContextShadow* GraphicsContext::contextShadow()
+ShadowBlur* GraphicsContext::shadowBlur()
 {
-    return &m_data->shadow;
+    return m_data->shadow;
 }
 
 void GraphicsContext::clip(const IntRect& rect)
@@ -790,6 +805,18 @@ void GraphicsContext::clip(const FloatRect& rect)
 
     m_data->p()->setClipRect(rect, Qt::IntersectClip);
 }
+IntRect GraphicsContext::clipBounds() const
+{
+    QPainter* p = m_data->p();
+    QRectF clipRect;
+
+    if (p->hasClipping())
+        clipRect = m_data->clipBoundingRect();
+    else
+        clipRect = p->transform().inverted().mapRect(p->window());
+
+    return enclosingIntRect(clipRect);
+}
 
 void GraphicsContext::clipPath(const Path& path, WindRule clipRule)
 {
@@ -926,7 +953,7 @@ FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect, RoundingM
     return FloatRect(roundedOrigin, roundedLowerRight - roundedOrigin);
 }
 
-void GraphicsContext::setPlatformShadow(const FloatSize& size, float blur, const Color& color, ColorSpace)
+void GraphicsContext::setPlatformShadow(const FloatSize& size, float blur, const Color& color, ColorSpace colorSpace)
 {
     // Qt doesn't support shadows natively, they are drawn manually in the draw*
     // functions
@@ -935,16 +962,14 @@ void GraphicsContext::setPlatformShadow(const FloatSize& size, float blur, const
         // Meaning that this graphics context is associated with a CanvasRenderingContext
         // We flip the height since CG and HTML5 Canvas have opposite Y axis
         m_state.shadowOffset = FloatSize(size.width(), -size.height());
-        m_data->shadow = ContextShadow(color, blur, FloatSize(size.width(), -size.height()));
-    } else
-        m_data->shadow = ContextShadow(color, blur, FloatSize(size.width(), size.height()));
+    }
 
-    m_data->shadow.setShadowsIgnoreTransforms(m_state.shadowsIgnoreTransforms);
+    m_data->shadow->setShadowValues(FloatSize(m_state.shadowBlur, m_state.shadowBlur), m_state.shadowOffset, color, colorSpace, m_state.shadowsIgnoreTransforms);
 }
 
 void GraphicsContext::clearPlatformShadow()
 {
-    m_data->shadow.clear();
+    m_data->shadow->clear();
 }
 
 void GraphicsContext::pushTransparencyLayerInternal(const QRect &rect, qreal opacity, QPixmap& alphaMask)
index 0c8ce9ed7b5e8e9ab937eff98c5dcfce519fe01c..41ff8a6b3732c6d93bc1c9917d0ba672cc851df5 100644 (file)
 
 #include "AffineTransform.h"
 #include "BitmapImage.h"
-#include "ContextShadow.h"
 #include "FloatRect.h"
 #include "GraphicsContext.h"
 #include "ImageObserver.h"
 #include "PlatformString.h"
+#include "ShadowBlur.h"
 #include "StillImageQt.h"
 #include "qwebsettings.h"
 
@@ -224,11 +224,11 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
     CompositeOperator previousOperator = ctxt->compositeOperation();
     ctxt->setCompositeOperation(!image->hasAlpha() && op == CompositeSourceOver ? CompositeCopy : op);
 
-    ContextShadow* shadow = ctxt->contextShadow();
-    if (shadow->m_type != ContextShadow::NoShadow) {
-        QPainter* shadowPainter = shadow->beginShadowLayer(ctxt, normalizedDst);
-        if (shadowPainter) {
-            shadowPainter->setOpacity(static_cast<qreal>(shadow->m_color.alpha()) / 255);
+    if (ctxt->hasShadow()) {
+        ShadowBlur* shadow = ctxt->shadowBlur();
+        GraphicsContext* shadowContext = shadow->beginShadowLayer(ctxt, normalizedDst);
+        if (shadowContext) {
+            QPainter* shadowPainter = shadowContext->platformContext();
             shadowPainter->drawPixmap(normalizedDst, *image, normalizedSrc);
             shadow->endShadowLayer(ctxt);
         }
index 3b089958ca73d5f258e1e4376857b5086a65de74..cb2a4427a1b32dc803d00e31aef16d93473c2a4b 100644 (file)
@@ -28,9 +28,9 @@
 #include "config.h"
 #include "StillImageQt.h"
 
-#include "ContextShadow.h"
 #include "GraphicsContext.h"
 #include "IntSize.h"
+#include "ShadowBlur.h"
 
 #include <QPainter>
 
@@ -74,11 +74,11 @@ void StillImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
     CompositeOperator previousOperator = ctxt->compositeOperation();
     ctxt->setCompositeOperation(op);
 
-    ContextShadow* shadow = ctxt->contextShadow();
-    if (shadow->m_type != ContextShadow::NoShadow) {
-        QPainter* shadowPainter = shadow->beginShadowLayer(ctxt, normalizedDst);
-        if (shadowPainter) {
-            shadowPainter->setOpacity(static_cast<qreal>(shadow->m_color.alpha()) / 255);
+    if (ctxt->hasShadow()) {
+        ShadowBlur* shadow = ctxt->shadowBlur();
+        GraphicsContext* shadowContext = shadow->beginShadowLayer(ctxt, normalizedDst);
+        if (shadowContext) {
+            QPainter* shadowPainter = shadowContext->platformContext();
             shadowPainter->drawPixmap(normalizedDst, *m_pixmap, normalizedSrc);
             shadow->endShadowLayer(ctxt);
         }