Changeset 90406 in webkit


Ignore:
Timestamp:
Jul 5, 2011 2:29:42 PM (13 years ago)
Author:
commit-queue@webkit.org
Message:

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):
Location:
trunk/Source/WebCore
Files:
1 deleted
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r90405 r90406  
     12011-07-05  Igor Oliveira  <igor.oliveira@openbossa.org>
     2
     3        [Qt] Add ShadowBlur support
     4        https://bugs.webkit.org/show_bug.cgi?id=62997
     5
     6        Use ShadowBlur instead of ContextShadow to handle canvas and css shadows. ShadowBlur is
     7        a newer and platform independent shadow implementation.
     8        Qt QPainter does not have support for shadows so is necessary to create a layer support
     9        to draw complex shapes and fonts. The beginShadowLayer creates a temporary shadow buffer
     10        where the canvas can draw onto and endShadowLayer applies the blur filter, colors the
     11        shadow buffer and draw the final shadow to the graphics context.
     12
     13        Reviewed by Andreas Kling.
     14
     15        * WebCore.pro:
     16        * platform/graphics/GraphicsContext.cpp:
     17        * platform/graphics/GraphicsContext.h:
     18        * platform/graphics/ShadowBlur.cpp:
     19        (WebCore::ShadowBlur::ShadowBlur):
     20        (WebCore::ShadowBlur::setShadowValues):
     21        (WebCore::ShadowBlur::updateShadowBlurValues):
     22        (WebCore::ShadowBlur::clear):
     23        (WebCore::ShadowBlur::blurAndColorShadowBuffer):
     24        (WebCore::ShadowBlur::beginShadowLayer):
     25        (WebCore::ShadowBlur::endShadowLayer):
     26        * platform/graphics/ShadowBlur.h:
     27        (WebCore::ShadowBlur::type):
     28        * platform/graphics/qt/ContextShadowQt.cpp: Removed.
     29        * platform/graphics/qt/FontQt.cpp:
     30        (WebCore::drawTextCommon):
     31        (WebCore::Font::drawGlyphs):
     32        * platform/graphics/qt/GraphicsContextQt.cpp:
     33        (WebCore::GraphicsContextPlatformPrivate::mustUseShadowBlur):
     34        (WebCore::GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate):
     35        (WebCore::GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate):
     36        (WebCore::GraphicsContext::savePlatformState):
     37        (WebCore::GraphicsContext::restorePlatformState):
     38        (WebCore::GraphicsContext::fillPath):
     39        (WebCore::GraphicsContext::strokePath):
     40        (WebCore::GraphicsContext::fillRect):
     41        (WebCore::GraphicsContext::fillRoundedRect):
     42        (WebCore::GraphicsContext::shadowBlur):
     43        (WebCore::GraphicsContext::clipBounds):
     44        (WebCore::GraphicsContext::setPlatformShadow):
     45        (WebCore::GraphicsContext::clearPlatformShadow):
     46        * platform/graphics/qt/ImageQt.cpp:
     47        (WebCore::BitmapImage::draw):
     48        * platform/graphics/qt/StillImageQt.cpp:
     49        (WebCore::StillImage::draw):
     50
    1512011-07-05  Sam Weinig  <sam@webkit.org>
    252
  • trunk/Source/WebCore/WebCore.pro

    r90341 r90406  
    979979    platform/graphics/BitmapImage.cpp \
    980980    platform/graphics/Color.cpp \
    981     platform/graphics/ContextShadow.cpp \
     981    platform/graphics/ShadowBlur.cpp \
    982982    platform/graphics/FloatPoint3D.cpp \
    983983    platform/graphics/FloatPoint.cpp \
     
    19401940    platform/graphics/BitmapImage.h \
    19411941    platform/graphics/Color.h \
    1942     platform/graphics/ContextShadow.h \
     1942    platform/graphics/ShadowBlur.h \
    19431943    platform/graphics/filters/FEBlend.h \
    19441944    platform/graphics/filters/FEColorMatrix.h \
     
    25222522    platform/graphics/qt/TransformationMatrixQt.cpp \
    25232523    platform/graphics/qt/ColorQt.cpp \
    2524     platform/graphics/qt/ContextShadowQt.cpp \
    25252524    platform/graphics/qt/FontQt.cpp \
    25262525    platform/graphics/qt/FontPlatformDataQt.cpp \
  • trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp

    r89221 r90406  
    586586}
    587587
    588 #if !USE(CG)
     588#if !USE(CG) && !PLATFORM(QT)
    589589IntRect GraphicsContext::clipBounds() const
    590590{
  • trunk/Source/WebCore/platform/graphics/GraphicsContext.h

    r90057 r90406  
    5555namespace WebCore {
    5656class ContextShadow;
     57class ShadowBlur;
    5758}
    5859typedef QPainter PlatformGraphicsContext;
     
    487488#endif
    488489
    489 #if PLATFORM(QT) || USE(CAIRO)
     490#if USE(CAIRO)
    490491        ContextShadow* contextShadow();
     492#endif
     493
     494#if PLATFORM(QT)
     495        ShadowBlur* shadowBlur();
    491496#endif
    492497
  • trunk/Source/WebCore/platform/graphics/ShadowBlur.cpp

    r87009 r90406  
    177177    , m_shadowsIgnoreTransforms(false)
    178178{
     179    updateShadowBlurValues();
     180}
     181
     182ShadowBlur::ShadowBlur()
     183    : m_type(NoShadow)
     184    , m_blurRadius(0, 0)
     185    , m_shadowsIgnoreTransforms(false)
     186{
     187}
     188
     189void ShadowBlur::setShadowValues(const FloatSize& radius, const FloatSize& offset, const Color& color, ColorSpace colorSpace, bool ignoreTransforms)
     190{
     191    m_blurRadius = radius;
     192    m_offset = offset;
     193    m_color = color;
     194    m_colorSpace = colorSpace;
     195    m_shadowsIgnoreTransforms = ignoreTransforms;
     196
     197    updateShadowBlurValues();
     198}
     199
     200void ShadowBlur::updateShadowBlurValues()
     201{
    179202    // Limit blur radius to 128 to avoid lots of very expensive blurring.
    180203    m_blurRadius = m_blurRadius.shrunkTo(FloatSize(128, 128));
    181204
    182205    // The type of shadow is decided by the blur radius, shadow offset, and shadow color.
    183     if (!m_color.isValid() || !color.alpha()) {
     206    if (!m_color.isValid() || !m_color.alpha()) {
    184207        // Can't paint the shadow with invalid or invisible color.
    185208        m_type = NoShadow;
     
    238261}
    239262
     263void ShadowBlur::clear()
     264{
     265    m_type = NoShadow;
     266    m_color = Color();
     267    m_blurRadius = FloatSize();
     268    m_offset = FloatSize();
     269}
     270
    240271void ShadowBlur::blurLayerImage(unsigned char* imageData, const IntSize& size, int rowStride)
    241272{
     
    829860    // Mask the image with the shadow color.
    830861    GraphicsContext* shadowContext = m_layerImage->context();
     862    GraphicsContextStateSaver stateSaver(*shadowContext);
    831863    shadowContext->setCompositeOperation(CompositeSourceIn);
    832864    shadowContext->setFillColor(m_color, m_colorSpace);
     
    834866}
    835867
     868GraphicsContext* ShadowBlur::beginShadowLayer(GraphicsContext *context, const FloatRect& layerArea)
     869{
     870    adjustBlurRadius(context);
     871
     872    IntRect layerRect = calculateLayerBoundingRect(context, layerArea, context->clipBounds());
     873
     874    if (layerRect.isEmpty())
     875        return 0;
     876
     877    m_layerImage = ScratchBuffer::shared().getScratchBuffer(layerRect.size());
     878
     879    GraphicsContext* shadowContext = m_layerImage->context();
     880    shadowContext->save();
     881    shadowContext->clearRect(FloatRect(0, 0, m_layerSize.width(), m_layerSize.height()));
     882
     883    shadowContext->translate(m_layerContextTranslation);
     884    return shadowContext;
     885}
     886
     887void ShadowBlur::endShadowLayer(GraphicsContext* context)
     888{
     889    m_layerImage->context()->restore();
     890
     891    blurAndColorShadowBuffer(expandedIntSize(m_layerSize));
     892    GraphicsContextStateSaver stateSave(*context);
     893
     894    context->clearShadow();
     895    context->drawImageBuffer(m_layerImage, ColorSpaceDeviceRGB, roundedIntPoint(m_layerOrigin), IntRect(0, 0, m_layerSize.width(), m_layerSize.height()), context->compositeOperation());
     896
     897    m_layerImage = 0;
     898    ScratchBuffer::shared().scheduleScratchBufferPurge();
     899}
     900
    836901} // namespace WebCore
  • trunk/Source/WebCore/platform/graphics/ShadowBlur.h

    r85299 r90406  
    4545    WTF_MAKE_NONCOPYABLE(ShadowBlur);
    4646public:
     47    enum ShadowType {
     48        NoShadow,
     49        SolidShadow,
     50        BlurShadow
     51    };
     52
    4753    ShadowBlur(const FloatSize& radius, const FloatSize& offset, const Color&, ColorSpace);
     54    ShadowBlur();
     55
     56    void setShadowValues(const FloatSize&, const FloatSize& , const Color&, ColorSpace, bool ignoreTransforms = false);
    4857
    4958    void setShadowsIgnoreTransforms(bool ignoreTransforms) { m_shadowsIgnoreTransforms = ignoreTransforms; }
    5059    bool shadowsIgnoreTransforms() const { return m_shadowsIgnoreTransforms; }
     60
     61    GraphicsContext* beginShadowLayer(GraphicsContext*, const FloatRect& layerArea);
     62    void endShadowLayer(GraphicsContext*);
    5163
    5264    void drawRectShadow(GraphicsContext*, const FloatRect&, const RoundedIntRect::Radii&);
     
    5567    void blurLayerImage(unsigned char*, const IntSize&, int stride);
    5668
     69    void clear();
     70
     71    ShadowType type() const { return m_type; }
    5772private:
     73    void updateShadowBlurValues();
     74
    5875    void drawShadowBuffer(GraphicsContext*);
    5976
     
    8198    IntSize blurredEdgeSize() const;
    8299   
    83     enum ShadowType {
    84         NoShadow,
    85         SolidShadow,
    86         BlurShadow
    87     };
    88100   
    89101    ShadowType m_type;
  • trunk/Source/WebCore/platform/graphics/qt/FontQt.cpp

    r89606 r90406  
    2424
    2525#include "AffineTransform.h"
    26 #include "ContextShadow.h"
    2726#include "FontDescription.h"
    2827#include "FontFallbackList.h"
     
    3534#include "NotImplemented.h"
    3635#include "Pattern.h"
     36#include "ShadowBlur.h"
    3737#include "TextRun.h"
    3838
     
    143143            QRectF clip = boundingRect;
    144144
    145             ContextShadow* ctxShadow = ctx->contextShadow();
    146 
    147             if (ctxShadow->m_type != ContextShadow::NoShadow) {
     145            ShadowBlur* ctxShadow = ctx->shadowBlur();
     146            if (ctxShadow->type() != ShadowBlur::NoShadow) {
     147                const QPointF shadowOffset(ctx->state().shadowOffset.width(), ctx->state().shadowOffset.height());
    148148                qreal dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0;
    149                 if (ctxShadow->offset().x() > 0)
    150                     dx2 = ctxShadow->offset().x();
     149                if (shadowOffset.x() > 0)
     150                    dx2 = shadowOffset.x();
    151151                else
    152                     dx1 = -ctxShadow->offset().x();
    153                 if (ctxShadow->offset().y() > 0)
    154                     dy2 = ctxShadow->offset().y();
     152                    dx1 = -shadowOffset.x();
     153                if (shadowOffset.y() > 0)
     154                    dy2 = shadowOffset.y();
    155155                else
    156                     dy1 = -ctxShadow->offset().y();
     156                    dy1 = -shadowOffset.y();
    157157                // expand the clip rect to include the text shadow as well
     158                const float blurDistance = ctx->state().shadowBlur;
    158159                clip.adjust(dx1, dx2, dy1, dy2);
    159                 clip.adjust(-ctxShadow->m_blurDistance, -ctxShadow->m_blurDistance, ctxShadow->m_blurDistance, ctxShadow->m_blurDistance);
     160                clip.adjust(-blurDistance, -blurDistance, blurDistance, blurDistance);
    160161            }
    161162            p->save();
     
    163164            pt.setY(pt.y() - ascent);
    164165
    165             if (ctxShadow->m_type != ContextShadow::NoShadow) {
    166                 ContextShadow* ctxShadow = ctx->contextShadow();
    167                 if (!ctxShadow->mustUseContextShadow(ctx)) {
     166            if (ctxShadow->type() != ShadowBlur::NoShadow) {
     167                ShadowBlur* ctxShadow = ctx->shadowBlur();
     168                if (ctxShadow->type() != ShadowBlur::BlurShadow
     169                    && (!ctxShadow->shadowsIgnoreTransforms() || ctx->getCTM().isIdentity())) {
    168170                    p->save();
    169                     p->setPen(ctxShadow->m_color);
    170                     p->translate(ctxShadow->offset());
     171                    p->setPen(ctx->state().shadowColor);
     172                    p->translate(QPointF(ctx->state().shadowOffset.width(), ctx->state().shadowOffset.height()));
    171173                    line.draw(p, pt);
    172174                    p->restore();
    173175                } else {
    174                     QPainter* shadowPainter = ctxShadow->beginShadowLayer(ctx, boundingRect);
    175                     if (shadowPainter) {
     176                    GraphicsContext* shadowContext = ctxShadow->beginShadowLayer(ctx, boundingRect);
     177                    if (shadowContext) {
     178                        QPainter* shadowPainter = shadowContext->platformContext();
    176179                        // Since it will be blurred anyway, we don't care about render hints.
    177180                        shadowPainter->setFont(p->font());
    178                         shadowPainter->setPen(ctxShadow->m_color);
     181                        shadowPainter->setPen(ctx->state().shadowColor);
    179182                        line.draw(shadowPainter, pt);
    180183                        ctxShadow->endShadowLayer(ctx);
     
    202205        textStrokePath.addText(pt, font, string);
    203206
    204     ContextShadow* ctxShadow = ctx->contextShadow();
    205     if (ctxShadow->m_type != ContextShadow::NoShadow) {
     207    ShadowBlur* ctxShadow = ctx->shadowBlur();
     208    if (ctx->hasShadow() && ctxShadow->type() != ShadowBlur::NoShadow) {
    206209        if (ctx->textDrawingMode() & TextModeFill) {
    207             if (ctxShadow->m_type != ContextShadow::BlurShadow) {
     210            if (ctxShadow->type() != ShadowBlur::BlurShadow) {
    208211                p->save();
    209                 p->setPen(ctxShadow->m_color);
    210                 p->translate(ctxShadow->offset());
     212                p->setPen(ctx->state().shadowColor);
     213                p->translate(QPointF(ctx->state().shadowOffset.width(), ctx->state().shadowOffset.height()));
    211214                p->drawText(pt, string, flags, run.expansion());
    212215                p->restore();
     
    214217                QFontMetrics fm(font);
    215218                QRectF boundingRect(pt.x(), point.y() - fm.ascent(), fm.width(string, -1, flags), fm.height());
    216                 QPainter* shadowPainter = ctxShadow->beginShadowLayer(ctx, boundingRect);
    217                 if (shadowPainter) {
     219                GraphicsContext* shadowContext = ctxShadow->beginShadowLayer(ctx, boundingRect);
     220                if (shadowContext) {
     221                    QPainter* shadowPainter = shadowContext->platformContext();
    218222                    // Since it will be blurred anyway, we don't care about render hints.
    219223                    shadowPainter->setFont(p->font());
    220                     shadowPainter->setPen(ctxShadow->m_color);
     224                    shadowPainter->setPen(ctx->state().shadowColor);
    221225                    shadowPainter->drawText(pt, string, flags, run.expansion());
    222226                    ctxShadow->endShadowLayer(ctx);
     
    224228            }
    225229        } else if (ctx->textDrawingMode() & TextModeStroke) {
    226             if (ctxShadow->m_type != ContextShadow::BlurShadow) {
    227                 p->translate(ctxShadow->offset());
    228                 p->strokePath(textStrokePath, QPen(ctxShadow->m_color));
    229                 p->translate(-ctxShadow->offset());
     230            if (ctxShadow->type() != ShadowBlur::BlurShadow) {
     231                const QPointF shadowOffset(ctx->state().shadowOffset.width(), ctx->state().shadowOffset.height());
     232                p->translate(shadowOffset);
     233                p->strokePath(textStrokePath, QPen(ctx->state().shadowColor));
     234                p->translate(-shadowOffset);
    230235            } else {
    231236                QFontMetrics fm(font);
    232237                QRectF boundingRect(pt.x(), point.y() - fm.ascent(), fm.width(string, -1, flags), fm.height());
    233                 QPainter* shadowPainter = ctxShadow->beginShadowLayer(ctx, boundingRect);
    234                 if (shadowPainter) {
     238                GraphicsContext* shadowContext = ctxShadow->beginShadowLayer(ctx, boundingRect);
     239                if (shadowContext) {
     240                    QPainter* shadowPainter = shadowContext->platformContext();
    235241                    // Since it will be blurred anyway, we don't care about render hints.
    236242                    shadowPainter->setFont(p->font());
    237                     shadowPainter->strokePath(textStrokePath, QPen(ctxShadow->m_color));
     243                    shadowPainter->strokePath(textStrokePath, QPen(ctx->state().shadowColor));
    238244                    ctxShadow->endShadowLayer(ctx);
    239245                }
     
    329335
    330336    // Shadowed text should always take the complex path.
    331     ASSERT(context->contextShadow()->m_type == ContextShadow::NoShadow);
     337    ASSERT(context->contextShadow()->type() == ShadowBlur::NoShadow);
    332338
    333339    if (!shouldFill && !shouldStroke)
     
    362368
    363369    ContextShadow* shadow = context->contextShadow();
    364     switch (shadow->m_type) {
     370    switch (shadow->type()) {
    365371    case ContextShadow::SolidShadow: {
    366372        QPen previousPen = painter->pen();
     
    375381        qreal height = rawFont.ascent() + rawFont.descent() + 1;
    376382        QRectF boundingRect(point.x(), point.y() - rawFont.ascent(), width, height);
    377         QPainter* shadowPainter = shadow->beginShadowLayer(context, boundingRect);
    378         if (shadowPainter) {
     383        GraphicsContext* shadowContext = shadow->beginShadowLayer(context, boundingRect);
     384        if (shadowContext) {
     385            QPainter* shadowPainter = shadowContext->platformContext();
    379386            shadowPainter->setPen(shadow->m_color);
    380387            shadowPainter->drawGlyphRun(point, qtGlyphs);
  • trunk/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp

    r90020 r90406  
    4545#include "AffineTransform.h"
    4646#include "Color.h"
    47 #include "ContextShadow.h"
    4847#include "FloatConversion.h"
    4948#include "Font.h"
     
    5251#include "Path.h"
    5352#include "Pattern.h"
     53#include "ShadowBlur.h"
    5454#include "TransparencyLayer.h"
    5555
     
    197197    bool initialSmoothPixmapTransformHint;
    198198
    199     ContextShadow shadow;
    200     QStack<ContextShadow> shadowStack;
     199    ShadowBlur* shadow;
     200
     201    bool mustUseShadowBlur() const
     202    {
     203        // We can't avoid ShadowBlur, since the shadow has blur.
     204        if (shadow->type() == ShadowBlur::BlurShadow)
     205            return true;
     206        // We can avoid ShadowBlur and optimize, since we're not drawing on a
     207        // canvas and box shadows are affected by the transformation matrix.
     208        if (!shadow->shadowsIgnoreTransforms())
     209            return false;
     210        // We can avoid ShadowBlur, since there are no transformations to apply to the canvas.
     211        if (p()->combinedTransform().isIdentity())
     212            return false;
     213        // Otherwise, no chance avoiding ShadowBlur.
     214        return true;
     215    }
    201216
    202217    QRectF clipBoundingRect() const
     
    222237    , imageInterpolationQuality(InterpolationDefault)
    223238    , initialSmoothPixmapTransformHint(false)
     239    , shadow(new ShadowBlur())
    224240    , painter(p)
    225241    , platformContextIsOwned(false)
     
    242258
    243259    painter->setRenderHint(QPainter::Antialiasing, true);
     260
    244261}
    245262
     
    251268    QPaintDevice* device = painter->device();
    252269    painter->end();
     270    delete shadow;
    253271    delete painter;
    254272    delete device;
     
    298316        ++m_data->layers.top()->saveCounter;
    299317    m_data->p()->save();
    300     m_data->shadowStack.push(m_data->shadow);
    301318}
    302319
     
    309326    m_data->p()->restore();
    310327
    311     if (m_data->shadowStack.isEmpty())
    312         m_data->shadow = ContextShadow();
    313     else
    314         m_data->shadow = m_data->shadowStack.pop();
     328    m_data->shadow->setShadowValues(FloatSize(m_state.shadowBlur, m_state.shadowBlur), m_state.shadowOffset, m_state.shadowColor, m_state.shadowColorSpace, m_state.shadowsIgnoreTransforms);
    315329}
    316330
     
    496510
    497511    if (hasShadow()) {
    498         ContextShadow* shadow = contextShadow();
    499         if (shadow->mustUseContextShadow(this) || m_state.fillPattern || m_state.fillGradient)
     512        ShadowBlur* shadow = shadowBlur();
     513        if (m_data->mustUseShadowBlur() || m_state.fillPattern || m_state.fillGradient)
    500514        {
    501             QPainter* shadowPainter = shadow->beginShadowLayer(this, platformPath.controlPointRect());
    502             if (shadowPainter) {
     515            GraphicsContext* shadowContext = shadow->beginShadowLayer(this, platformPath.controlPointRect());
     516            if (shadowContext) {
     517                QPainter* shadowPainter = shadowContext->platformContext();
    503518                if (m_state.fillPattern) {
    504519                    AffineTransform affine;
    505                     shadowPainter->setOpacity(static_cast<qreal>(shadow->m_color.alpha()) / 255);
    506520                    shadowPainter->fillPath(platformPath, QBrush(m_state.fillPattern->createPlatformPattern(affine)));
    507521                } else if (m_state.fillGradient) {
    508522                    QBrush brush(*m_state.fillGradient->platformGradient());
    509523                    brush.setTransform(m_state.fillGradient->gradientSpaceTransform());
    510                     shadowPainter->setOpacity(static_cast<qreal>(shadow->m_color.alpha()) / 255);
    511524                    shadowPainter->fillPath(platformPath, brush);
    512525                } else {
    513                     QColor shadowColor = shadow->m_color;
    514                     shadowColor.setAlphaF(shadowColor.alphaF() * p->brush().color().alphaF());
    515                     shadowPainter->fillPath(platformPath, shadowColor);
     526                    QColor shadowColor = m_state.shadowColor;
     527                    shadowPainter->fillPath(platformPath, p->brush().color());
    516528                }
    517529                shadow->endShadowLayer(this);
    518530            }
    519531        } else {
    520             QPointF offset = shadow->offset();
     532            QPointF offset(m_state.shadowOffset.width(), m_state.shadowOffset.height());
    521533            p->translate(offset);
    522             QColor shadowColor = shadow->m_color;
     534            QColor shadowColor = m_state.shadowColor;
    523535            shadowColor.setAlphaF(shadowColor.alphaF() * p->brush().color().alphaF());
    524536            p->fillPath(platformPath, shadowColor);
     
    548560
    549561    if (hasShadow()) {
    550         ContextShadow* shadow = contextShadow();
    551         if (shadow->mustUseContextShadow(this) || m_state.strokePattern || m_state.strokeGradient)
     562        ShadowBlur* shadow = shadowBlur();
     563        if (m_data->mustUseShadowBlur() || m_state.strokePattern || m_state.strokeGradient)
    552564        {
    553565            FloatRect boundingRect = platformPath.controlPointRect();
    554566            boundingRect.inflate(pen.miterLimit() + pen.widthF());
    555             QPainter* shadowPainter = shadow->beginShadowLayer(this, boundingRect);
    556             if (shadowPainter) {
     567            GraphicsContext* shadowContext = shadow->beginShadowLayer(this, boundingRect);
     568            if (shadowContext) {
     569                QPainter* shadowPainter = shadowContext->platformContext();
    557570                if (m_state.strokeGradient) {
    558571                    QBrush brush(*m_state.strokeGradient->platformGradient());
     
    560573                    QPen shadowPen(pen);
    561574                    shadowPen.setBrush(brush);
    562                     shadowPainter->setOpacity(static_cast<qreal>(shadow->m_color.alpha()) / 255);
    563575                    shadowPainter->strokePath(platformPath, shadowPen);
    564576                } else {
    565                     shadowPainter->setOpacity(static_cast<qreal>(m_data->shadow.m_color.alpha()) / 255);
    566577                    shadowPainter->strokePath(platformPath, pen);
    567578                }
     
    569580            }
    570581        } else {
    571             QPointF offset = shadow->offset();
     582            QPointF offset(m_state.shadowOffset.width(), m_state.shadowOffset.height());
    572583            p->translate(offset);
    573             QColor shadowColor = shadow->m_color;
     584            QColor shadowColor = m_state.shadowColor;
    574585            shadowColor.setAlphaF(shadowColor.alphaF() * pen.color().alphaF());
    575586            QPen shadowPen(pen);
     
    669680    QPainter* p = m_data->p();
    670681    QRectF normalizedRect = rect.normalized();
    671     ContextShadow* shadow = contextShadow();
     682    ShadowBlur* shadow = shadowBlur();
    672683
    673684    if (m_state.fillPattern) {
    674685        QPixmap* image = m_state.fillPattern->tileImage()->nativeImageForCurrentFrame();
    675         QPainter* shadowPainter = hasShadow() ? shadow->beginShadowLayer(this, normalizedRect) : 0;
    676         if (shadowPainter) {
     686        GraphicsContext* shadowContext = hasShadow() ? shadow->beginShadowLayer(this, normalizedRect) : 0;
     687        if (shadowContext) {
     688            QPainter* shadowPainter = shadowContext->platformContext();
    677689            drawRepeatPattern(shadowPainter, image, normalizedRect, m_state.fillPattern->repeatX(), m_state.fillPattern->repeatY());
    678             shadowPainter->setCompositionMode(QPainter::CompositionMode_SourceIn);
    679             shadowPainter->fillRect(normalizedRect, shadow->m_color);
    680690            shadow->endShadowLayer(this);
    681691        }
     
    684694        QBrush brush(*m_state.fillGradient->platformGradient());
    685695        brush.setTransform(m_state.fillGradient->gradientSpaceTransform());
    686         QPainter* shadowPainter = hasShadow() ? shadow->beginShadowLayer(this, normalizedRect) : 0;
    687         if (shadowPainter) {
     696        GraphicsContext* shadowContext = hasShadow() ? shadow->beginShadowLayer(this, normalizedRect) : 0;
     697        if (shadowContext) {
     698            QPainter* shadowPainter = shadowContext->platformContext();
    688699            shadowPainter->fillRect(normalizedRect, brush);
    689             shadowPainter->setCompositionMode(QPainter::CompositionMode_SourceIn);
    690             shadowPainter->fillRect(normalizedRect, shadow->m_color);
    691700            shadow->endShadowLayer(this);
    692701        }
     
    694703    } else {
    695704        if (hasShadow()) {
    696             if (shadow->mustUseContextShadow(this)) {
    697                 QPainter* shadowPainter = shadow->beginShadowLayer(this, normalizedRect);
    698                 if (shadowPainter) {
    699                     shadowPainter->setOpacity(static_cast<qreal>(shadow->m_color.alpha()) / 255);
     705            if (m_data->mustUseShadowBlur()) {
     706                GraphicsContext* shadowContext = shadow->beginShadowLayer(this, normalizedRect);
     707                if (shadowContext) {
     708                    QPainter* shadowPainter = shadowContext->platformContext();
    700709                    shadowPainter->fillRect(normalizedRect, p->brush());
    701710                    shadow->endShadowLayer(this);
     
    704713                // Solid rectangle fill with no blur shadow or transformations applied can be done
    705714                // faster without using the shadow layer at all.
    706                 QColor shadowColor = shadow->m_color;
     715                QColor shadowColor = m_state.shadowColor;
    707716                shadowColor.setAlphaF(shadowColor.alphaF() * p->brush().color().alphaF());
    708                 p->fillRect(normalizedRect.translated(shadow->offset()), shadowColor);
     717                p->fillRect(normalizedRect.translated(QPointF(m_state.shadowOffset.width(), m_state.shadowOffset.height())), shadowColor);
    709718            }
    710719        }
     
    725734
    726735    if (hasShadow()) {
    727         ContextShadow* shadow = contextShadow();
    728         if (shadow->mustUseContextShadow(this)) {
    729             QPainter* shadowPainter = shadow->beginShadowLayer(this, normalizedRect);
    730             if (shadowPainter) {
     736        ShadowBlur* shadow = shadowBlur();
     737        if (m_data->mustUseShadowBlur()) {
     738            GraphicsContext* shadowContext = shadow->beginShadowLayer(this, normalizedRect);
     739            if (shadowContext) {
     740                QPainter* shadowPainter = shadowContext->platformContext();
    731741                shadowPainter->setCompositionMode(QPainter::CompositionMode_Source);
    732                 shadowPainter->fillRect(normalizedRect, shadow->m_color);
    733                 shadow->endShadowLayer(this);
    734             }
    735         } else
    736             p->fillRect(normalizedRect.translated(shadow->offset()), shadow->m_color);
    737     }
    738 
    739     p->fillRect(normalizedRect, m_data->solidColor);
    740 }
    741 
    742 void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color, ColorSpace colorSpace)
    743 {
    744     if (paintingDisabled() || !color.isValid())
    745         return;
    746 
    747     Path path;
    748     path.addRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight);
    749     QPainter* p = m_data->p();
    750     if (hasShadow()) {
    751         ContextShadow* shadow = contextShadow();
    752         if (shadow->mustUseContextShadow(this)) {
    753             QPainter* shadowPainter = shadow->beginShadowLayer(this, rect);
    754             if (shadowPainter) {
    755                 shadowPainter->setCompositionMode(QPainter::CompositionMode_Source);
    756                 shadowPainter->fillPath(path.platformPath(), QColor(m_data->shadow.m_color));
     742                shadowPainter->fillRect(normalizedRect, m_state.shadowColor);
    757743                shadow->endShadowLayer(this);
    758744            }
    759745        } else {
    760             p->translate(m_data->shadow.offset());
    761             p->fillPath(path.platformPath(), QColor(m_data->shadow.m_color));
    762             p->translate(-m_data->shadow.offset());
     746            QColor shadowColor = m_state.shadowColor;
     747            shadowColor.setAlphaF(shadowColor.alphaF() * p->brush().color().alphaF());
     748            p->fillRect(normalizedRect.translated(QPointF(m_state.shadowOffset.width(), m_state.shadowOffset.height())), shadowColor);
    763749        }
    764750    }
     751
     752    p->fillRect(normalizedRect, m_data->solidColor);
     753}
     754
     755void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color, ColorSpace colorSpace)
     756{
     757    if (paintingDisabled() || !color.isValid())
     758        return;
     759
     760    Path path;
     761    path.addRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight);
     762    QPainter* p = m_data->p();
     763    if (hasShadow()) {
     764        ShadowBlur* shadow = shadowBlur();
     765        if (m_data->mustUseShadowBlur()) {
     766            GraphicsContext* shadowContext = shadow->beginShadowLayer(this, rect);
     767            if (shadowContext) {
     768                QPainter* shadowPainter = shadowContext->platformContext();
     769                shadowPainter->setCompositionMode(QPainter::CompositionMode_Source);
     770                shadowPainter->fillPath(path.platformPath(), QColor(m_state.shadowColor));
     771                shadow->endShadowLayer(this);
     772            }
     773        } else {
     774            const QPointF shadowOffset(m_state.shadowOffset.width(), m_state.shadowOffset.height());
     775            p->translate(shadowOffset);
     776            p->fillPath(path.platformPath(), QColor(m_state.shadowColor));
     777            p->translate(-shadowOffset);
     778        }
     779    }
    765780    p->fillPath(path.platformPath(), QColor(color));
    766781}
     
    771786}
    772787
    773 ContextShadow* GraphicsContext::contextShadow()
    774 {
    775     return &m_data->shadow;
     788ShadowBlur* GraphicsContext::shadowBlur()
     789{
     790    return m_data->shadow;
    776791}
    777792
     
    790805
    791806    m_data->p()->setClipRect(rect, Qt::IntersectClip);
     807}
     808IntRect GraphicsContext::clipBounds() const
     809{
     810    QPainter* p = m_data->p();
     811    QRectF clipRect;
     812
     813    if (p->hasClipping())
     814        clipRect = m_data->clipBoundingRect();
     815    else
     816        clipRect = p->transform().inverted().mapRect(p->window());
     817
     818    return enclosingIntRect(clipRect);
    792819}
    793820
     
    927954}
    928955
    929 void GraphicsContext::setPlatformShadow(const FloatSize& size, float blur, const Color& color, ColorSpace)
     956void GraphicsContext::setPlatformShadow(const FloatSize& size, float blur, const Color& color, ColorSpace colorSpace)
    930957{
    931958    // Qt doesn't support shadows natively, they are drawn manually in the draw*
     
    936963        // We flip the height since CG and HTML5 Canvas have opposite Y axis
    937964        m_state.shadowOffset = FloatSize(size.width(), -size.height());
    938         m_data->shadow = ContextShadow(color, blur, FloatSize(size.width(), -size.height()));
    939     } else
    940         m_data->shadow = ContextShadow(color, blur, FloatSize(size.width(), size.height()));
    941 
    942     m_data->shadow.setShadowsIgnoreTransforms(m_state.shadowsIgnoreTransforms);
     965    }
     966
     967    m_data->shadow->setShadowValues(FloatSize(m_state.shadowBlur, m_state.shadowBlur), m_state.shadowOffset, color, colorSpace, m_state.shadowsIgnoreTransforms);
    943968}
    944969
    945970void GraphicsContext::clearPlatformShadow()
    946971{
    947     m_data->shadow.clear();
     972    m_data->shadow->clear();
    948973}
    949974
  • trunk/Source/WebCore/platform/graphics/qt/ImageQt.cpp

    r76415 r90406  
    3535#include "AffineTransform.h"
    3636#include "BitmapImage.h"
    37 #include "ContextShadow.h"
    3837#include "FloatRect.h"
    3938#include "GraphicsContext.h"
    4039#include "ImageObserver.h"
    4140#include "PlatformString.h"
     41#include "ShadowBlur.h"
    4242#include "StillImageQt.h"
    4343#include "qwebsettings.h"
     
    225225    ctxt->setCompositeOperation(!image->hasAlpha() && op == CompositeSourceOver ? CompositeCopy : op);
    226226
    227     ContextShadow* shadow = ctxt->contextShadow();
    228     if (shadow->m_type != ContextShadow::NoShadow) {
    229         QPainter* shadowPainter = shadow->beginShadowLayer(ctxt, normalizedDst);
    230         if (shadowPainter) {
    231             shadowPainter->setOpacity(static_cast<qreal>(shadow->m_color.alpha()) / 255);
     227    if (ctxt->hasShadow()) {
     228        ShadowBlur* shadow = ctxt->shadowBlur();
     229        GraphicsContext* shadowContext = shadow->beginShadowLayer(ctxt, normalizedDst);
     230        if (shadowContext) {
     231            QPainter* shadowPainter = shadowContext->platformContext();
    232232            shadowPainter->drawPixmap(normalizedDst, *image, normalizedSrc);
    233233            shadow->endShadowLayer(ctxt);
  • trunk/Source/WebCore/platform/graphics/qt/StillImageQt.cpp

    r74947 r90406  
    2929#include "StillImageQt.h"
    3030
    31 #include "ContextShadow.h"
    3231#include "GraphicsContext.h"
    3332#include "IntSize.h"
     33#include "ShadowBlur.h"
    3434
    3535#include <QPainter>
     
    7575    ctxt->setCompositeOperation(op);
    7676
    77     ContextShadow* shadow = ctxt->contextShadow();
    78     if (shadow->m_type != ContextShadow::NoShadow) {
    79         QPainter* shadowPainter = shadow->beginShadowLayer(ctxt, normalizedDst);
    80         if (shadowPainter) {
    81             shadowPainter->setOpacity(static_cast<qreal>(shadow->m_color.alpha()) / 255);
     77    if (ctxt->hasShadow()) {
     78        ShadowBlur* shadow = ctxt->shadowBlur();
     79        GraphicsContext* shadowContext = shadow->beginShadowLayer(ctxt, normalizedDst);
     80        if (shadowContext) {
     81            QPainter* shadowPainter = shadowContext->platformContext();
    8282            shadowPainter->drawPixmap(normalizedDst, *m_pixmap, normalizedSrc);
    8383            shadow->endShadowLayer(ctxt);
Note: See TracChangeset for help on using the changeset viewer.