WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-44380-20100822001430.patch (text/plain), 10.12 KB, created by
Ariya Hidayat
on 2010-08-22 00:14:31 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Ariya Hidayat
Created:
2010-08-22 00:14:31 PDT
Size:
10.12 KB
patch
obsolete
>diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog >index d716f27aa6d0b18e11278a824f9833f731d0b9cb..db4d3d517a80bbe3d256c5c52224ca0bf7ffa179 100644 >--- a/WebCore/ChangeLog >+++ b/WebCore/ChangeLog >@@ -1,5 +1,27 @@ > 2010-08-21 Ariya Hidayat <ariya@sencha.com> > >+ Reviewed by NOBODY (OOPS!). >+ >+ [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 Ariya Hidayat <ariya@sencha.com> >+ > Reviewed by Kenneth Rohde Christiansen. > > [Qt] Faster bounding rect for the shadow clip region >diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h >index b0079e8904e148dc8f757ef674733886ff827da1..ead2ca548909d3df2ce65198757b92ddfcdbc968 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 7f9b427f8d4c54986a04ce7c6c584d9a43f682aa..83e291ddb893394e11ae23c067726ad1a89188f3 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 e114ebc864533450ea088b6f9fa00e9670e7bd06..7140340d78e4d48248cf01cf736fd2b1d05a91d7 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 840ef02a12839bcdee8476fc3af55460ab453588..c8e283c12de9f05056b7eb29ad966ba1481c774d 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())
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
krit
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 44380
:
65025
|
65037
|
65038
| 65050