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

ariya at webkit.org ariya at webkit.org
Wed Dec 22 12:24:44 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 25811d124626a9b77b736117dde297b8d5a2c7bf
Author: ariya at webkit.org <ariya at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Sun Aug 22 07:30:48 2010 +0000

    [Qt] Layer approach to support generic shadow handling
    https://bugs.webkit.org/show_bug.cgi?id=44380
    
    Patch by Ariya Hidayat <ariya at sencha.com> on 2010-08-22
    Reviewed by Dirk Schulze.
    
    The pair beginShadowLayer and endShadowLayer creates a temporary image
    where the caller can draw onto, using the returned QPainter. When
    endShadowLayer is called, the temporary image will be filtered, using
    the specified shadow color and blur radius, and drawn to the graphics
    context.
    
    * platform/graphics/GraphicsContext.h:
    * platform/graphics/qt/ContextShadow.cpp:
    (WebCore::ContextShadow::beginShadowLayer):
    (WebCore::ContextShadow::endShadowLayer):
    * platform/graphics/qt/ContextShadow.h:
    * platform/graphics/qt/GraphicsContextQt.cpp:
    (WebCore::GraphicsContext::fillRect):
    (WebCore::GraphicsContext::contextShadow):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@65782 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index e28ad87..d94bf9a 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,25 @@
+2010-08-22  Ariya Hidayat  <ariya at sencha.com>
+
+        Reviewed by Dirk Schulze.
+
+        [Qt] Layer approach to support generic shadow handling
+        https://bugs.webkit.org/show_bug.cgi?id=44380
+
+        The pair beginShadowLayer and endShadowLayer creates a temporary image
+        where the caller can draw onto, using the returned QPainter. When
+        endShadowLayer is called, the temporary image will be filtered, using
+        the specified shadow color and blur radius, and drawn to the graphics
+        context.
+
+        * platform/graphics/GraphicsContext.h:
+        * platform/graphics/qt/ContextShadow.cpp:
+        (WebCore::ContextShadow::beginShadowLayer):
+        (WebCore::ContextShadow::endShadowLayer):
+        * platform/graphics/qt/ContextShadow.h:
+        * platform/graphics/qt/GraphicsContextQt.cpp:
+        (WebCore::GraphicsContext::fillRect):
+        (WebCore::GraphicsContext::contextShadow):
+
 2010-08-21  Eric Carlson  <eric.carlson at apple.com>
 
         Reviewed by Dan Bernstein.
diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h
index b0079e8..ead2ca5 100644
--- a/WebCore/platform/graphics/GraphicsContext.h
+++ b/WebCore/platform/graphics/GraphicsContext.h
@@ -48,6 +48,9 @@ class SurfaceOpenVG;
 typedef class WebCore::SurfaceOpenVG PlatformGraphicsContext;
 #elif PLATFORM(QT)
 #include <QPainter>
+namespace WebCore {
+class ContextShadow;
+}
 typedef QPainter PlatformGraphicsContext;
 #elif PLATFORM(WX)
 class wxGCDC;
@@ -396,6 +399,7 @@ namespace WebCore {
         void pushTransparencyLayerInternal(const QRect &rect, qreal opacity, QPixmap& alphaMask);
         QPen pen();
         static QPainter::CompositionMode toQtCompositionMode(CompositeOperator op);
+        ContextShadow* contextShadow();
 #endif
 
 #if PLATFORM(GTK)
diff --git a/WebCore/platform/graphics/qt/ContextShadow.cpp b/WebCore/platform/graphics/qt/ContextShadow.cpp
index 7f9b427..83e291d 100644
--- a/WebCore/platform/graphics/qt/ContextShadow.cpp
+++ b/WebCore/platform/graphics/qt/ContextShadow.cpp
@@ -267,60 +267,65 @@ static void shadowBlur(QImage& image, int radius, const QColor& shadowColor)
     p.end();
 }
 
-void ContextShadow::drawShadowRect(QPainter* p, const QRectF& rect)
+QPainter* ContextShadow::beginShadowLayer(QPainter* p, const QRectF &rect)
 {
-    if (type == NoShadow)
-        return;
+    // We expand the area by the blur radius * 2 to give extra space
+    // for the blur transition.
+    int extra = (type == BlurShadow) ? blurRadius * 2 : 0;
 
-    if (type == BlurShadow) {
-        QRectF shadowRect = rect.translated(offset);
+    QRectF shadowRect = rect.translated(offset);
+    QRectF bufferRect = shadowRect.adjusted(-extra, -extra, extra, extra);
+    m_layerRect = bufferRect.toAlignedRect();
 
-        // We expand the area by the blur radius * 2 to give extra space
-        // for the blur transition.
-        int extra = blurRadius * 2;
-        QRectF bufferRect = shadowRect.adjusted(-extra, -extra, extra, extra);
-        QRect alignedBufferRect = bufferRect.toAlignedRect();
-
-        QRect clipRect;
-        if (p->hasClipping())
+    QRect clipRect;
+    if (p->hasClipping())
 #if QT_VERSION >= QT_VERSION_CHECK(4, 8, 0)
-            clipRect = p->clipBoundingRect();
+        clipRect = p->clipBoundingRect();
 #else
-            clipRect = p->clipRegion().boundingRect();
+        clipRect = p->clipRegion().boundingRect();
 #endif
-        else
-            clipRect = p->transform().inverted().mapRect(p->window());
+    else
+        clipRect = p->transform().inverted().mapRect(p->window());
 
-        if (!clipRect.contains(alignedBufferRect)) {
+    if (!clipRect.contains(m_layerRect)) {
 
-            // No need to have the buffer larger that the clip.
-            alignedBufferRect = alignedBufferRect.intersected(clipRect);
-            if (alignedBufferRect.isEmpty())
-                return;
+        // No need to have the buffer larger than the clip.
+        m_layerRect = m_layerRect.intersected(clipRect);
+        if (m_layerRect.isEmpty())
+            return 0;
 
-            // We adjust again because the pixels at the borders are still
-            // potentially affected by the pixels outside the buffer.
-            alignedBufferRect.adjust(-extra, -extra, extra, extra);
-        }
+        // We adjust again because the pixels at the borders are still
+        // potentially affected by the pixels outside the buffer.
+        if (type == BlurShadow)
+            m_layerRect.adjust(-extra, -extra, extra, extra);
+    }
 
-        ShadowBuffer* shadowBuffer = scratchShadowBuffer();
-        QImage* shadowImage = shadowBuffer->scratchImage(alignedBufferRect.size());
-        QPainter shadowPainter(shadowImage);
+    ShadowBuffer* shadowBuffer = scratchShadowBuffer();
+    QImage* shadowImage = shadowBuffer->scratchImage(m_layerRect.size());
+    m_layerImage = QImage(*shadowImage);
 
-        shadowPainter.fillRect(shadowRect.translated(-alignedBufferRect.topLeft()), color);
-        shadowPainter.end();
+    m_layerPainter = new QPainter;
+    m_layerPainter->begin(&m_layerImage);
+    m_layerPainter->translate(offset);
 
-        shadowBlur(*shadowImage, blurRadius, color);
+    // The origin is now the top left corner of the scratch image.
+    m_layerPainter->translate(-m_layerRect.topLeft());
 
-        p->drawImage(alignedBufferRect.topLeft(), *shadowImage);
+    return m_layerPainter;
+}
 
-        shadowBuffer->schedulePurge();
+void ContextShadow::endShadowLayer(QPainter* p)
+{
+    m_layerPainter->end();
+    delete m_layerPainter;
+    m_layerPainter = 0;
 
-        return;
-    }
+    if (type == BlurShadow)
+        shadowBlur(m_layerImage, blurRadius, color);
 
-    p->fillRect(rect.translated(offset), color);
-}
+    p->drawImage(m_layerRect.topLeft(), m_layerImage);
 
+    scratchShadowBuffer()->schedulePurge();
+}
 
 }
diff --git a/WebCore/platform/graphics/qt/ContextShadow.h b/WebCore/platform/graphics/qt/ContextShadow.h
index e114ebc..7140340 100644
--- a/WebCore/platform/graphics/qt/ContextShadow.h
+++ b/WebCore/platform/graphics/qt/ContextShadow.h
@@ -58,12 +58,35 @@ public:
 
     void clear();
 
-    // Draws the shadow for colored rectangle (can't be filled with pattern
-    // or gradient) according to the shadow parameters.
-    // Note: 'rect' specifies the rectangle which casts the shadow,
-    // NOT the bounding box of the shadow.
-    void drawShadowRect(QPainter* p, const QRectF& rect);
+    // The pair beginShadowLayer and endShadowLayer creates a temporary image
+    // where the caller can draw onto, using the returned QPainter. This
+    // QPainter instance must be used only to draw between the call to
+    // beginShadowLayer and endShadowLayer.
+    //
+    // Note: multiple/nested shadow layer is NOT allowed.
+    //
+    // The current clip region will be used to optimize the size of the
+    // temporary image. Thus, the original painter should not change any
+    // clipping until endShadowLayer.
+    // If the shadow will be completely outside the clipping region,
+    // beginShadowLayer will return 0.
+    //
+    // The returned QPainter will have the transformation matrix and clipping
+    // properly initialized to start doing the painting (no need to account
+    // for the shadow offset), however it will not have the same render hints,
+    // pen, brush, etc as the passed QPainter. This is intentional, usually
+    // shadow has different properties than the shape which casts the shadow.
+    //
+    // Once endShadowLayer is called, the temporary image will be drawn
+    // with the original painter. If blur radius is specified, the shadow
+    // will be filtered first.
+    QPainter* beginShadowLayer(QPainter* p, const QRectF& rect);
+    void endShadowLayer(QPainter* p);
 
+private:
+    QRect m_layerRect;
+    QImage m_layerImage;
+    QPainter* m_layerPainter;
 };
 
 } // namespace WebCore
diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index 840ef02..c8e283c 100644
--- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -695,11 +695,25 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorS
 
     m_data->solidColor.setColor(color);
     QPainter* p = m_data->p();
+    QRectF normalizedRect = rect.normalized();
 
-    if (m_data->hasShadow())
-        m_data->shadow.drawShadowRect(p, rect);
+    if (m_data->hasShadow()) {
+        ContextShadow* shadow = contextShadow();
 
-    p->fillRect(rect, m_data->solidColor);
+        if (shadow->type != ContextShadow::BlurShadow) {
+            // We do not need any layer for simple shadow.
+            p->fillRect(normalizedRect.translated(shadow->offset), shadow->color);
+        } else {
+            QPainter* shadowPainter = shadow->beginShadowLayer(p, normalizedRect);
+            if (shadowPainter) {
+                shadowPainter->setCompositionMode(QPainter::CompositionMode_Source);
+                shadowPainter->fillRect(normalizedRect, shadow->color);
+                shadow->endShadowLayer(p);
+            }
+        }
+    }
+
+    p->fillRect(normalizedRect, m_data->solidColor);
 }
 
 void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color, ColorSpace colorSpace)
@@ -741,6 +755,11 @@ PlatformPath* GraphicsContext::currentPath()
     return &m_data->currentPath;
 }
 
+ContextShadow* GraphicsContext::contextShadow()
+{
+    return &m_data->shadow;
+}
+
 void GraphicsContext::clip(const FloatRect& rect)
 {
     if (paintingDisabled())

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list