Changeset 74187 in webkit


Ignore:
Timestamp:
Dec 16, 2010 6:44:16 AM (13 years ago)
Author:
xan@webkit.org
Message:

Revert "2010-12-15 Helder Correia <helder@sencha.com>"

[Qt] Canvas shadow offset should not be affected by any transformation
https://bugs.webkit.org/show_bug.cgi?id=50422

Breaks canvas tests in GTK+.

Location:
trunk
Files:
3 deleted
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r74186 r74187  
    242242        * compositing/reflections/remove-add-reflection-expected.txt: Added.
    243243        * compositing/reflections/remove-add-reflection.html: Added.
    244 
    245 2010-12-15  Helder Correia  <helder@sencha.com>
    246 
    247         Reviewed by Ariya Hidayat.
    248 
    249         [Qt] Canvas shadow offset should not be affected by any transformation
    250         https://bugs.webkit.org/show_bug.cgi?id=50422
    251 
    252         On a canvas context, shadows are currently affected by all
    253         transformations except scaling. According to the spec:
    254         http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#shadows
    255 
    256         "The shadowOffsetX and shadowOffsetY attributes specify the distance
    257         that the shadow will be offset in the positive horizontal and positive
    258         vertical distance respectively. Their values are in coordinate space
    259         units. They are not affected by the current transformation matrix."
    260 
    261         NOTE: this applies only to canvas, not to box shadows.
    262 
    263         Add new test to ensure that shadows are correctly transformed keeping
    264         the relative offset to the shape.
    265 
    266         * fast/canvas/canvas-scale-strokePath-shadow-expected.txt:
    267         * fast/canvas/canvas-transforms-fillRect-shadow-expected.txt: Added.
    268         * fast/canvas/canvas-transforms-fillRect-shadow.html: Added.
    269         * fast/canvas/script-tests/canvas-scale-fillPath-shadow.js:
    270         * fast/canvas/script-tests/canvas-scale-fillRect-shadow.js:
    271         * fast/canvas/script-tests/canvas-scale-strokePath-shadow.js: Now using
    272           a lineWidth > 1 to make it easier to test and more fair among all
    273           ports, since there can be different transformation smoothness or
    274           aliasing settings.
    275         * fast/canvas/script-tests/canvas-transforms-fillRect-shadow.js: Added.
    276244
    2772452010-12-15  Kenji Imasaki  <imasaki@chromium.org>
  • trunk/LayoutTests/fast/canvas/canvas-scale-strokePath-shadow-expected.txt

    r74154 r74187  
    3131PASS d[1] is 0
    3232PASS d[2] is 0
    33 PASS d[3] is around 149
     33PASS d[3] is around 20
    3434PASS d[0] is 255
    3535PASS d[1] is 0
    3636PASS d[2] is 0
    37 PASS d[3] is around 116
     37PASS d[3] is around 22
    3838PASS d[0] is 255
    3939PASS d[1] is 0
    4040PASS d[2] is 0
    41 PASS d[3] is around 115
     41PASS d[3] is around 28
    4242PASS d[0] is 255
    4343PASS d[1] is 0
    4444PASS d[2] is 0
    45 PASS d[3] is around 70
     45PASS d[3] is around 22
    4646PASS d[0] is 255
    4747PASS d[1] is 0
    4848PASS d[2] is 0
    49 PASS d[3] is around 70
     49PASS d[3] is around 15
    5050PASS d[0] is 255
    5151PASS d[1] is 0
    5252PASS d[2] is 0
    53 PASS d[3] is around 69
     53PASS d[3] is around 17
    5454PASS successfullyParsed is true
    5555
  • trunk/LayoutTests/fast/canvas/script-tests/canvas-scale-fillPath-shadow.js

    r74154 r74187  
    8080shouldBe('d[3]', '255');
    8181
    82 d = ctx.getImageData(298, 295, 1, 1).data;
     82d = ctx.getImageData(299, 295, 1, 1).data;
    8383shouldBe('d[0]', '255');
    8484shouldBe('d[1]', '0');
     
    8686shouldBe('d[3]', '255');
    8787
    88 d = ctx.getImageData(200, 298, 1, 1).data;
     88d = ctx.getImageData(200, 299, 1, 1).data;
    8989shouldBe('d[0]', '255');
    9090shouldBe('d[1]', '0');
     
    9999shouldBeAround('d[3]', '76');
    100100
    101 d = ctx.getImageData(298, 405, 1, 1).data;
     101d = ctx.getImageData(299, 405, 1, 1).data;
    102102shouldBe('d[0]', '255');
    103103shouldBe('d[1]', '0');
     
    105105shouldBeAround('d[3]', '76');
    106106
    107 d = ctx.getImageData(205, 498, 1, 1).data;
     107d = ctx.getImageData(205, 499, 1, 1).data;
    108108shouldBe('d[0]', '255');
    109109shouldBe('d[1]', '0');
  • trunk/LayoutTests/fast/canvas/script-tests/canvas-scale-fillRect-shadow.js

    r74154 r74187  
    5959shouldBe('d[3]', '255');
    6060
    61 d = ctx.getImageData(298, 298, 1, 1).data;
     61d = ctx.getImageData(299, 295, 1, 1).data;
    6262shouldBe('d[0]', '255');
    6363shouldBe('d[1]', '0');
     
    6565shouldBe('d[3]', '255');
    6666
    67 d = ctx.getImageData(201, 298, 1, 1).data;
     67d = ctx.getImageData(200, 299, 1, 1).data;
    6868shouldBe('d[0]', '255');
    6969shouldBe('d[1]', '0');
     
    7878shouldBeAround('d[3]', '76');
    7979
    80 d = ctx.getImageData(298, 405, 1, 1).data;
     80d = ctx.getImageData(299, 405, 1, 1).data;
    8181shouldBe('d[0]', '255');
    8282shouldBe('d[1]', '0');
     
    8484shouldBeAround('d[3]', '76');
    8585
    86 d = ctx.getImageData(205, 498, 1, 1).data;
     86d = ctx.getImageData(205, 499, 1, 1).data;
    8787shouldBe('d[0]', '255');
    8888shouldBe('d[1]', '0');
  • trunk/LayoutTests/fast/canvas/script-tests/canvas-scale-strokePath-shadow.js

    r74154 r74187  
    3636ctx.shadowOffsetY = 100;
    3737ctx.strokeStyle = 'rgba(0, 0, 255, 1)';
    38 ctx.lineWidth = 5;
    3938
    4039ctx.shadowColor = 'rgba(255, 0, 0, 1.0)';
     
    7877
    7978// Verify solid shadow.
    80 d = ctx.getImageData(250, 200, 1, 1).data;
     79d = ctx.getImageData(200, 205, 1, 1).data;
    8180shouldBe('d[0]', '255');
    8281shouldBe('d[1]', '0');
     
    8483shouldBe('d[3]', '255');
    8584
    86 d = ctx.getImageData(300, 290, 1, 1).data;
     85d = ctx.getImageData(299, 295, 1, 1).data;
    8786shouldBe('d[0]', '255');
    8887shouldBe('d[1]', '0');
     
    9089shouldBe('d[3]', '255');
    9190
    92 d = ctx.getImageData(200, 250, 1, 1).data;
     91d = ctx.getImageData(201, 299, 1, 1).data;
    9392shouldBe('d[0]', '255');
    9493shouldBe('d[1]', '0');
     
    9796
    9897// Verify solid alpha shadow.
    99 d = ctx.getImageData(201, 405, 1, 1).data;
     98d = ctx.getImageData(200, 405, 1, 1).data;
    10099shouldBe('d[0]', '255');
    101100shouldBe('d[1]', '0');
     
    103102shouldBeAround('d[3]', '76');
    104103
    105 d = ctx.getImageData(201, 500, 1, 1).data;
     104d = ctx.getImageData(299, 405, 1, 1).data;
    106105shouldBe('d[0]', '255');
    107106shouldBe('d[1]', '0');
     
    109108shouldBeAround('d[3]', '76');
    110109
    111 d = ctx.getImageData(300, 499, 1, 1).data;
     110d = ctx.getImageData(205, 499, 1, 1).data;
    112111shouldBe('d[0]', '255');
    113112shouldBe('d[1]', '0');
     
    116115
    117116// Verify blurry shadow.
    118 d = ctx.getImageData(404, 210, 1, 1).data;
     117d = ctx.getImageData(394, 208, 1, 1).data;
    119118shouldBe('d[0]', '255');
    120119shouldBe('d[1]', '0');
    121120shouldBe('d[2]', '0');
    122 shouldBeAround('d[3]', '149');
     121shouldBeAround('d[3]', '20');
    123122
    124 d = ctx.getImageData(505, 250, 1, 1).data;
     123d = ctx.getImageData(503, 301, 1, 1).data;
    125124shouldBe('d[0]', '255');
    126125shouldBe('d[1]', '0');
    127126shouldBe('d[2]', '0');
    128 shouldBeAround('d[3]', '116');
     127shouldBeAround('d[3]', '22');
    129128
    130 d = ctx.getImageData(450, 205, 1, 1).data;
     129d = ctx.getImageData(504, 250, 1, 1).data;
    131130shouldBe('d[0]', '255');
    132131shouldBe('d[1]', '0');
    133132shouldBe('d[2]', '0');
    134 shouldBeAround('d[3]', '115');
     133shouldBeAround('d[3]', '28');
    135134
    136135// Verify blurry alpha shadow.
    137 d = ctx.getImageData(505, 450, 1, 1).data;
     136d = ctx.getImageData(405, 405, 1, 1).data;
    138137shouldBe('d[0]', '255');
    139138shouldBe('d[1]', '0');
    140139shouldBe('d[2]', '0');
    141 shouldBeAround('d[3]', '70');
     140shouldBeAround('d[3]', '22');
    142141
    143 d = ctx.getImageData(505, 450, 1, 1).data;
     142d = ctx.getImageData(415, 495, 1, 1).data;
    144143shouldBe('d[0]', '255');
    145144shouldBe('d[1]', '0');
    146145shouldBe('d[2]', '0');
    147 shouldBeAround('d[3]', '70');
     146shouldBeAround('d[3]', '15');
    148147
    149 d = ctx.getImageData(450, 405, 1, 1).data;
     148d = ctx.getImageData(450, 504, 1, 1).data;
    150149shouldBe('d[0]', '255');
    151150shouldBe('d[1]', '0');
    152151shouldBe('d[2]', '0');
    153 shouldBeAround('d[3]', '69');
     152shouldBeAround('d[3]', '17');
    154153
    155154var successfullyParsed = true;
  • trunk/WebCore/ChangeLog

    r74186 r74187  
    349349        * platform/graphics/ca/GraphicsLayerCA.cpp:
    350350        (WebCore::GraphicsLayerCA::ensureStructuralLayer):
    351 
    352 2010-12-15  Helder Correia  <helder@sencha.com>
    353 
    354         Reviewed by Ariya Hidayat.
    355 
    356         [Qt] Canvas shadow offset should not be affected by any transformation
    357         https://bugs.webkit.org/show_bug.cgi?id=50422
    358 
    359         On a canvas context, shadows are currently affected by all
    360         transformations except scaling. According to the spec:
    361         http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#shadows
    362 
    363         "The shadowOffsetX and shadowOffsetY attributes specify the distance
    364         that the shadow will be offset in the positive horizontal and positive
    365         vertical distance respectively. Their values are in coordinate space
    366         units. They are not affected by the current transformation matrix."
    367 
    368         NOTE: this applies only to canvas, not to box shadows.
    369 
    370         Test: fast/canvas/canvas-transforms-fillRect-shadow.html
    371 
    372         * platform/graphics/ContextShadow.cpp:
    373         (WebCore::ContextShadow::ContextShadow):
    374         (WebCore::ContextShadow::calculateLayerBoundingRect):
    375         * platform/graphics/ContextShadow.h:
    376         (WebCore::ContextShadow::setShadowsIgnoreTransforms):
    377         (WebCore::ContextShadow::shadowsIgnoreTransforms):
    378         (WebCore::ContextShadow::offset):
    379         * platform/graphics/qt/ContextShadowQt.cpp:
    380         (WebCore::ContextShadow::beginShadowLayer):
    381         (WebCore::ContextShadow::endShadowLayer):
    382         * platform/graphics/qt/GraphicsContextQt.cpp:
    383         (WebCore::mustUseContextShadow):
    384         (WebCore::GraphicsContext::fillPath):
    385         (WebCore::GraphicsContext::strokePath):
    386         (WebCore::GraphicsContext::fillRect):
    387         (WebCore::GraphicsContext::fillRoundedRect):
    388         (WebCore::GraphicsContext::setPlatformShadow):
    389351
    3903522010-12-15  Timothy Hatcher  <timothy@apple.com>
  • trunk/WebCore/platform/graphics/ContextShadow.cpp

    r74154 r74187  
    4242    , m_blurDistance(0)
    4343    , m_layerContext(0)
    44     , m_shadowsIgnoreTransforms(false)
    4544{
    4645}
     
    5150    , m_offset(offset)
    5251    , m_layerContext(0)
    53     , m_shadowsIgnoreTransforms(false)
    5452{
    5553    // See comments in http://webkit.org/b/40793, it seems sensible
     
    152150}
    153151
    154 #if PLATFORM(QT)
    155 IntRect ContextShadow::calculateLayerBoundingRect(const PlatformContext p, const FloatRect& layerArea, const IntRect& clipRect)
    156 {
    157     // Calculate the destination of the blurred and/or transformed layer.
    158     FloatRect layerFloatRect;
    159     float inflation = 0;
    160 
    161     const QTransform transform = p->transform();
    162     if (m_shadowsIgnoreTransforms && !transform.isIdentity()) {
    163         QPolygonF transformedPolygon = transform.map(QPolygonF(layerArea));
    164         transformedPolygon.translate(offset());
    165         layerFloatRect = transform.inverted().map(transformedPolygon).boundingRect();
    166     } else {
    167         layerFloatRect = layerArea;
    168         layerFloatRect.move(m_offset);
    169     }
    170 
    171     // We expand the area by the blur radius to give extra space for the blur transition.
    172     if (m_type == BlurShadow) {
    173         layerFloatRect.inflate(m_blurDistance);
    174         inflation += m_blurDistance;
    175     }
    176 
    177     FloatRect unclippedLayerRect = layerFloatRect;
    178 
    179     if (!clipRect.contains(enclosingIntRect(layerFloatRect))) {
    180         // No need to have the buffer larger than the clip.
    181         layerFloatRect.intersect(clipRect);
    182 
    183         // If we are totally outside the clip region, we aren't painting at all.
    184         if (layerFloatRect.isEmpty())
    185             return IntRect(0, 0, 0, 0);
    186 
    187         // We adjust again because the pixels at the borders are still
    188         // potentially affected by the pixels outside the buffer.
    189         if (m_type == BlurShadow) {
    190             layerFloatRect.inflate(m_blurDistance);
    191             unclippedLayerRect.inflate(m_blurDistance);
    192             inflation += m_blurDistance;
    193         }
    194     }
    195 
    196     const int frameSize = inflation * 2;
    197     m_sourceRect = IntRect(0, 0, layerArea.width() + frameSize, layerArea.height() + frameSize);
    198 
    199     m_layerOrigin = FloatPoint(layerFloatRect.x(), layerFloatRect.y());
    200 
    201     const FloatPoint m_unclippedLayerOrigin = FloatPoint(unclippedLayerRect.x(), unclippedLayerRect.y());
    202     const FloatSize clippedOut = m_unclippedLayerOrigin - m_layerOrigin;
    203 
    204     // Set the origin as the top left corner of the scratch image, or, in case there's a clipped
    205     // out region, set the origin accordingly to the full bounding rect's top-left corner.
    206     const float translationX = -layerArea.x() + inflation - fabsf(clippedOut.width());
    207     const float translationY = -layerArea.y() + inflation - fabsf(clippedOut.height());
    208     m_layerContextTranslation = FloatPoint(translationX, translationY);
    209 
    210     return enclosingIntRect(layerFloatRect);
    211 }
    212 #endif
    213 
    214 #if PLATFORM(CAIRO)
    215152void ContextShadow::calculateLayerBoundingRect(const FloatRect& layerArea, const IntRect& clipRect)
    216153{
     
    237174    }
    238175}
    239 #endif
    240176
    241177} // namespace WebCore
  • trunk/WebCore/platform/graphics/ContextShadow.h

    r74154 r74187  
    107107    void endShadowLayer(PlatformContext);
    108108    static void purgeScratchBuffer();
    109     void setShadowsIgnoreTransforms(bool enable) { m_shadowsIgnoreTransforms = enable; }
    110     bool shadowsIgnoreTransforms() const { return m_shadowsIgnoreTransforms; }
    111109#if PLATFORM(CAIRO)
    112110    void drawRectShadow(GraphicsContext* context, const IntRect& rect, const IntSize& topLeftRadius = IntSize(), const IntSize& topRightRadius = IntSize(), const IntSize& bottomLeftRadius = IntSize(), const IntSize& bottomRightRadius = IntSize());
    113111#endif
     112
    114113#if PLATFORM(QT)
    115     QPointF offset() const { return QPointF(m_offset.width(), m_offset.height()); }
     114    QPointF offset() { return QPointF(m_offset.width(), m_offset.height()); }
    116115#endif
    117116
    118117
    119118private:
    120     // Buffer to where the temporary shadow will be drawn to.
     119    IntRect m_layerRect;
    121120    PlatformImage m_layerImage;
    122     // Context used to paint the shadow to the layer image.
    123121    PlatformContext m_layerContext;
    124 #if PLATFORM(QT)
    125     // Sub-rect of m_layerImage that contains the shadow pixels.
    126     FloatRect m_sourceRect;
    127     // Top-left corner of the (possibly clipped) bounding rect to draw the shadow to.
    128     FloatPoint m_layerOrigin;
    129     // Translation to apply to m_layerContext for the shadow to be correctly clipped.
    130     FloatPoint m_layerContextTranslation;
    131 #endif
    132 #if PLATFORM(CAIRO)
    133     // Enclosing int rect where shadow needs to be drawn to using the layer context.
    134     IntRect m_layerRect;
     122
    135123    // Used for reference when canvas scale(x,y) was called.
    136124    FloatRect m_unscaledLayerRect;
    137 #endif
    138     bool m_shadowsIgnoreTransforms;
    139125
    140126    void blurLayerImage(unsigned char*, const IntSize& imageSize, int stride);
     127    void calculateLayerBoundingRect(const FloatRect& layerArea, const IntRect& clipRect);
    141128#if PLATFORM(CAIRO)
    142     void calculateLayerBoundingRect(const FloatRect& layerArea, const IntRect& clipRect);
    143129    void drawRectShadowWithoutTiling(PlatformContext context, const IntRect& shadowRect, const IntSize& topLeftRadius, const IntSize& topRightRadius, const IntSize& bottomLeftRadius, const IntSize& bottomRightRadius, float alpha);
    144 #else
    145     IntRect calculateLayerBoundingRect(const PlatformContext, const FloatRect& layerArea, const IntRect& clipRect);
    146130#endif
    147131};
  • trunk/WebCore/platform/graphics/qt/ContextShadowQt.cpp

    r74154 r74187  
    115115        clipRect = p->transform().inverted().mapRect(p->window());
    116116
    117     // Set m_layerOrigin, m_layerContextTranslation, m_sourceRect.
    118     IntRect clip(clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height());
    119     IntRect layerRect = calculateLayerBoundingRect(p, layerArea, clip);
     117    m_unscaledLayerRect = layerArea;
     118    calculateLayerBoundingRect(layerArea, IntRect(clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height()));
    120119
    121120    // Don't paint if we are totally outside the clip region.
    122     if (layerRect.isEmpty())
     121    if (m_layerRect.isEmpty())
    123122        return 0;
    124123
    125124    ShadowBuffer* shadowBuffer = scratchShadowBuffer();
    126     QImage* shadowImage = shadowBuffer->scratchImage(layerRect.size());
     125    QImage* shadowImage = shadowBuffer->scratchImage(m_layerRect.size());
    127126    m_layerImage = QImage(*shadowImage);
    128127
     
    130129    m_layerContext->begin(&m_layerImage);
    131130    m_layerContext->setFont(p->font());
    132     m_layerContext->translate(m_layerContextTranslation);
     131    m_layerContext->translate(m_offset.width(), m_offset.height());
     132
     133    // The origin is now the top left corner of the scratch image.
     134    m_layerContext->translate(-m_layerRect.x(), -m_layerRect.y());
     135
    133136    return m_layerContext;
    134137}
     
    153156    }
    154157
    155     p->drawImage(m_layerOrigin, m_layerImage, m_sourceRect);
     158    const QTransform transform = p->transform();
     159    if (transform.isScaling()) {
     160        qreal x = m_unscaledLayerRect.x() + m_offset.width()  / transform.m11() - m_blurDistance;
     161        qreal y = m_unscaledLayerRect.y() + m_offset.height() / transform.m22() - m_blurDistance;
     162        p->drawImage(QPointF(x, y), m_layerImage);
     163    } else
     164        p->drawImage(m_layerRect.topLeft(), m_layerImage);
    156165
    157166    scratchShadowBuffer()->schedulePurge();
  • trunk/WebCore/platform/graphics/qt/GraphicsContextQt.cpp

    r74154 r74187  
    5454
    5555#include <QBrush>
     56#include <QDebug>
    5657#include <QGradient>
    5758#include <QPaintDevice>
     
    175176}
    176177
    177 static inline bool mustUseContextShadow(QPainter* painter, ContextShadow* shadow)
    178 {
    179     if (shadow->m_type == ContextShadow::BlurShadow)
    180         // We can't avoid ContextShadow, since the shadow has blur.
    181         return true;
    182     if (!shadow->shadowsIgnoreTransforms())
    183         // We can avoid ContextShadow and optimize, since we're not drawing on a canvas and box
    184         // shadows are affected by the transformation matrix.
    185         return false;
    186     if (painter->transform().isIdentity())
    187         // We can avoid ContextShadow, since there are no transformations to apply to the canvas.
    188         return false;
    189     // Otherwise, no chance avoiding ContextShadow.
    190     return true;
    191 }
    192 
    193178class GraphicsContextPlatformPrivate : public Noncopyable {
    194179public:
     
    522507    if (m_data->hasShadow()) {
    523508        ContextShadow* shadow = contextShadow();
    524         if (mustUseContextShadow(p, shadow) || m_state.fillPattern || m_state.fillGradient)
     509        if (shadow->m_type != ContextShadow::BlurShadow
     510            && !m_state.fillPattern && !m_state.fillGradient)
    525511        {
     512            QPointF offset = shadow->offset();
     513            const QTransform& transform = p->transform();
     514            if (transform.isScaling()) {
     515                // If scaling is required, find the new coord for shadow origin,
     516                // so that the relative offset to its shape is kept.
     517                QPointF translatedOffset(offset.x() / transform.m11(),
     518                                         offset.y() / transform.m22());
     519                platformPath.translate(translatedOffset);
     520                p->fillPath(platformPath, QColor(shadow->m_color));
     521                platformPath.translate(-translatedOffset);
     522            } else {
     523                p->translate(offset);
     524                p->fillPath(platformPath, QColor(shadow->m_color));
     525                p->translate(-offset);
     526            }
     527        } else {
    526528            QPainter* shadowPainter = shadow->beginShadowLayer(p, platformPath.controlPointRect());
    527529            if (shadowPainter) {
     
    530532                shadow->endShadowLayer(p);
    531533            }
    532         } else {
    533             QPointF offset = shadow->offset();
    534             p->translate(offset);
    535             p->fillPath(platformPath, QColor(shadow->m_color));
    536             p->translate(-offset);
    537534        }
     535
    538536    }
    539537    if (m_state.fillPattern) {
     
    560558    if (m_data->hasShadow()) {
    561559        ContextShadow* shadow = contextShadow();
    562         if (mustUseContextShadow(p, shadow) || m_state.strokePattern || m_state.strokeGradient)
     560
     561        if (shadow->m_type != ContextShadow::BlurShadow
     562            && !m_state.strokePattern && !m_state.strokeGradient)
    563563        {
     564            QPen shadowPen(pen);
     565            shadowPen.setColor(m_data->shadow.m_color);
     566            QPointF offset = shadow->offset();
     567            const QTransform& transform = p->transform();
     568            if (transform.isScaling()) {
     569                // If scaling is required, find the new coord for shadow origin,
     570                // so that the relative offset to its shape is kept.
     571                QPointF translatedOffset(offset.x() / transform.m11(),
     572                                         offset.y() / transform.m22());
     573                platformPath.translate(translatedOffset);
     574                p->strokePath(platformPath, shadowPen);
     575                platformPath.translate(-translatedOffset);
     576            } else {
     577                p->translate(offset);
     578                p->strokePath(platformPath, shadowPen);
     579                p->translate(-offset);
     580            }
     581        } else {
    564582            FloatRect boundingRect = platformPath.controlPointRect();
    565583            boundingRect.inflate(pen.miterLimit() + pen.widthF());
     
    570588                shadow->endShadowLayer(p);
    571589            }
    572         } else {
    573             QPen shadowPen(pen);
    574             shadowPen.setColor(m_data->shadow.m_color);
    575             QPointF offset = shadow->offset();
    576             p->translate(offset);
    577             p->strokePath(platformPath, shadowPen);
    578             p->translate(-offset);
    579590        }
    580591    }
     
    696707    } else {
    697708        if (m_data->hasShadow()) {
    698             if (mustUseContextShadow(p, shadow)) {
     709            if (shadow->m_type == ContextShadow::BlurShadow) {
    699710                QPainter* shadowPainter = shadow->beginShadowLayer(p, normalizedRect);
    700711                if (shadowPainter) {
     
    704715                }
    705716            } else {
    706                 // Solid rectangle fill with no blur shadow or transformations applied can be done
    707                 // faster without using the shadow layer at all.
     717                // Solid rectangle fill with no blur shadow can be done faster
     718                // without using the shadow layer at all.
    708719                QColor shadowColor = shadow->m_color;
    709720                shadowColor.setAlphaF(shadowColor.alphaF() * p->brush().color().alphaF());
    710                 p->fillRect(normalizedRect.translated(shadow->offset()), shadowColor);
     721                const QTransform& transform = p->transform();
     722                if (transform.isScaling()) {
     723                    p->fillRect(normalizedRect.translated(static_cast<qreal>(shadow->offset().x()) / transform.m11(),
     724                                                          static_cast<qreal>(shadow->offset().y()  / transform.m22())),
     725                                shadowColor);
     726                } else
     727                    p->fillRect(normalizedRect.translated(shadow->offset()), shadowColor);
    711728            }
    712729        }
     
    728745    if (m_data->hasShadow()) {
    729746        ContextShadow* shadow = contextShadow();
    730         if (mustUseContextShadow(p, shadow)) {
     747
     748        if (shadow->m_type != ContextShadow::BlurShadow) {
     749            // We do not need any layer for simple shadow.
     750            p->fillRect(normalizedRect.translated(shadow->offset()), shadow->m_color);
     751        } else {
    731752            QPainter* shadowPainter = shadow->beginShadowLayer(p, normalizedRect);
    732753            if (shadowPainter) {
     
    735756                shadow->endShadowLayer(p);
    736757            }
    737         } else
    738             p->fillRect(normalizedRect.translated(shadow->offset()), shadow->m_color);
     758        }
    739759    }
    740760
     
    752772    if (m_data->hasShadow()) {
    753773        ContextShadow* shadow = contextShadow();
    754         if (mustUseContextShadow(p, shadow)) {
     774
     775        if (shadow->m_type != ContextShadow::BlurShadow) {
     776            // We do not need any layer for simple shadow.
     777            p->translate(m_data->shadow.offset());
     778            p->fillPath(path.platformPath(), QColor(m_data->shadow.m_color));
     779            p->translate(-m_data->shadow.offset());
     780        } else {
    755781            QPainter* shadowPainter = shadow->beginShadowLayer(p, rect);
    756782            if (shadowPainter) {
     
    759785                shadow->endShadowLayer(p);
    760786            }
    761         } else {
    762             p->translate(m_data->shadow.offset());
    763             p->fillPath(path.platformPath(), QColor(m_data->shadow.m_color));
    764             p->translate(-m_data->shadow.offset());
    765787        }
    766788    }
     
    932954        m_state.shadowOffset = FloatSize(size.width(), -size.height());
    933955        m_data->shadow = ContextShadow(color, blur, FloatSize(size.width(), -size.height()));
    934     } else
     956    } else {
    935957        m_data->shadow = ContextShadow(color, blur, FloatSize(size.width(), size.height()));
    936 
    937     m_data->shadow.setShadowsIgnoreTransforms(m_state.shadowsIgnoreTransforms);
     958    }
    938959}
    939960
Note: See TracChangeset for help on using the changeset viewer.