~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsContextQt.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2009-11-02 18:30:08 UTC
  • mfrom: (1.2.2 upstream)
  • mto: (15.2.5 experimental)
  • mto: This revision was merged to the branch mainline in revision 88.
  • Revision ID: james.westby@ubuntu.com-20091102183008-b6a4gcs128mvfb3m
Tags: upstream-4.6.0~beta1
ImportĀ upstreamĀ versionĀ 4.6.0~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
 */
35
35
 
36
36
#include "config.h"
 
37
#include "GraphicsContext.h"
37
38
 
38
39
#ifdef Q_WS_WIN
39
40
#include <windows.h>
40
41
#endif
41
42
 
42
 
#include "TransformationMatrix.h"
43
43
#include "Color.h"
44
44
#include "FloatConversion.h"
45
45
#include "Font.h"
46
 
#include "GraphicsContext.h"
47
46
#include "GraphicsContextPrivate.h"
48
47
#include "ImageBuffer.h"
 
48
#include "NotImplemented.h"
49
49
#include "Path.h"
50
50
#include "Pattern.h"
51
51
#include "Pen.h"
52
 
#include "NotImplemented.h"
 
52
#include "TransformationMatrix.h"
53
53
 
 
54
#include <QBrush>
54
55
#include <QDebug>
55
56
#include <QGradient>
56
 
#include <QPainter>
57
57
#include <QPaintDevice>
58
58
#include <QPaintEngine>
 
59
#include <QPainter>
59
60
#include <QPainterPath>
60
61
#include <QPixmap>
61
62
#include <QPolygonF>
71
72
static inline QPainter::CompositionMode toQtCompositionMode(CompositeOperator op)
72
73
{
73
74
    switch (op) {
74
 
        case CompositeClear:
75
 
            return QPainter::CompositionMode_Clear;
76
 
        case CompositeCopy:
77
 
            return QPainter::CompositionMode_Source;
78
 
        case CompositeSourceOver:
79
 
            return QPainter::CompositionMode_SourceOver;
80
 
        case CompositeSourceIn:
81
 
            return QPainter::CompositionMode_SourceIn;
82
 
        case CompositeSourceOut:
83
 
            return QPainter::CompositionMode_SourceOut;
84
 
        case CompositeSourceAtop:
85
 
            return QPainter::CompositionMode_SourceAtop;
86
 
        case CompositeDestinationOver:
87
 
            return QPainter::CompositionMode_DestinationOver;
88
 
        case CompositeDestinationIn:
89
 
            return QPainter::CompositionMode_DestinationIn;
90
 
        case CompositeDestinationOut:
91
 
            return QPainter::CompositionMode_DestinationOut;
92
 
        case CompositeDestinationAtop:
93
 
            return QPainter::CompositionMode_DestinationAtop;
94
 
        case CompositeXOR:
95
 
            return QPainter::CompositionMode_Xor;
96
 
        case CompositePlusDarker:
97
 
            return QPainter::CompositionMode_SourceOver;
98
 
        case CompositeHighlight:
99
 
            return QPainter::CompositionMode_SourceOver;
100
 
        case CompositePlusLighter:
101
 
            return QPainter::CompositionMode_Plus;
 
75
    case CompositeClear:
 
76
        return QPainter::CompositionMode_Clear;
 
77
    case CompositeCopy:
 
78
        return QPainter::CompositionMode_Source;
 
79
    case CompositeSourceOver:
 
80
        return QPainter::CompositionMode_SourceOver;
 
81
    case CompositeSourceIn:
 
82
        return QPainter::CompositionMode_SourceIn;
 
83
    case CompositeSourceOut:
 
84
        return QPainter::CompositionMode_SourceOut;
 
85
    case CompositeSourceAtop:
 
86
        return QPainter::CompositionMode_SourceAtop;
 
87
    case CompositeDestinationOver:
 
88
        return QPainter::CompositionMode_DestinationOver;
 
89
    case CompositeDestinationIn:
 
90
        return QPainter::CompositionMode_DestinationIn;
 
91
    case CompositeDestinationOut:
 
92
        return QPainter::CompositionMode_DestinationOut;
 
93
    case CompositeDestinationAtop:
 
94
        return QPainter::CompositionMode_DestinationAtop;
 
95
    case CompositeXOR:
 
96
        return QPainter::CompositionMode_Xor;
 
97
    case CompositePlusDarker:
 
98
        // there is no exact match, but this is the closest
 
99
        return QPainter::CompositionMode_Darken;
 
100
    case CompositeHighlight:
 
101
        return QPainter::CompositionMode_SourceOver;
 
102
    case CompositePlusLighter:
 
103
        return QPainter::CompositionMode_Plus;
102
104
    }
103
105
 
104
106
    return QPainter::CompositionMode_SourceOver;
107
109
static inline Qt::PenCapStyle toQtLineCap(LineCap lc)
108
110
{
109
111
    switch (lc) {
110
 
        case ButtCap:
111
 
            return Qt::FlatCap;
112
 
        case RoundCap:
113
 
            return Qt::RoundCap;
114
 
        case SquareCap:
115
 
            return Qt::SquareCap;
 
112
    case ButtCap:
 
113
        return Qt::FlatCap;
 
114
    case RoundCap:
 
115
        return Qt::RoundCap;
 
116
    case SquareCap:
 
117
        return Qt::SquareCap;
116
118
    }
117
119
 
118
120
    return Qt::FlatCap;
121
123
static inline Qt::PenJoinStyle toQtLineJoin(LineJoin lj)
122
124
{
123
125
    switch (lj) {
124
 
        case MiterJoin:
125
 
            return Qt::SvgMiterJoin;
126
 
        case RoundJoin:
127
 
            return Qt::RoundJoin;
128
 
        case BevelJoin:
129
 
            return Qt::BevelJoin;
 
126
    case MiterJoin:
 
127
        return Qt::SvgMiterJoin;
 
128
    case RoundJoin:
 
129
        return Qt::RoundJoin;
 
130
    case BevelJoin:
 
131
        return Qt::BevelJoin;
130
132
    }
131
133
 
132
134
    return Qt::MiterJoin;
152
154
    return Qt::NoPen;
153
155
}
154
156
 
155
 
static inline QGradient applySpreadMethod(QGradient gradient, GradientSpreadMethod spreadMethod)
156
 
{
157
 
    switch (spreadMethod) {
158
 
        case SpreadMethodPad:
159
 
            gradient.setSpread(QGradient::PadSpread);
160
 
           break;
161
 
        case SpreadMethodReflect:
162
 
            gradient.setSpread(QGradient::ReflectSpread);
163
 
            break;
164
 
        case SpreadMethodRepeat:
165
 
            gradient.setSpread(QGradient::RepeatSpread);
166
 
            break;
167
 
    }
168
 
    return gradient;
169
 
}
170
 
 
171
157
static inline Qt::FillRule toQtFillRule(WindRule rule)
172
158
{
173
 
    switch(rule) {
 
159
    switch (rule) {
174
160
    case RULE_EVENODD:
175
161
        return Qt::OddEvenFill;
176
162
    case RULE_NONZERO:
180
166
    return Qt::OddEvenFill;
181
167
}
182
168
 
183
 
struct TransparencyLayer
184
 
{
 
169
struct TransparencyLayer {
185
170
    TransparencyLayer(const QPainter* p, const QRect &rect)
186
171
        : pixmap(rect.width(), rect.height())
187
172
    {
213
198
    TransparencyLayer & operator=(const TransparencyLayer &) { return *this; }
214
199
};
215
200
 
216
 
class GraphicsContextPlatformPrivate
217
 
{
 
201
class GraphicsContextPlatformPrivate {
218
202
public:
219
203
    GraphicsContextPlatformPrivate(QPainter* painter);
220
204
    ~GraphicsContextPlatformPrivate();
226
210
                return redirect;
227
211
 
228
212
            return painter;
229
 
        } else
230
 
            return &layers.top()->painter;
 
213
        }
 
214
        return &layers.top()->painter;
231
215
    }
232
216
 
233
217
    bool antiAliasingForRectsAndLines;
234
218
 
235
 
    QStack<TransparencyLayer *> layers;
 
219
    QStack<TransparencyLayer*> layers;
236
220
    QPainter* redirect;
237
221
 
238
222
    QBrush solidColor;
257
241
        antiAliasingForRectsAndLines = painter->testRenderHint(QPainter::Antialiasing);
258
242
        // FIXME: Maybe only enable in SVG mode?
259
243
        painter->setRenderHint(QPainter::Antialiasing, true);
260
 
    } else {
 
244
    } else
261
245
        antiAliasingForRectsAndLines = false;
262
 
    }
263
246
}
264
247
 
265
248
GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate()
280
263
 
281
264
GraphicsContext::~GraphicsContext()
282
265
{
283
 
    while(!m_data->layers.isEmpty())
 
266
    while (!m_data->layers.isEmpty())
284
267
        endTransparencyLayer();
285
268
 
286
269
    destroyGraphicsContextPrivate(m_common);
294
277
 
295
278
TransformationMatrix GraphicsContext::getCTM() const
296
279
{
297
 
    return platformContext()->combinedMatrix();
 
280
    QTransform matrix(platformContext()->combinedTransform());
 
281
    return TransformationMatrix(matrix.m11(), matrix.m12(), 0, matrix.m13(),
 
282
                                matrix.m21(), matrix.m22(), 0, matrix.m23(),
 
283
                                           0,            0, 1,            0,
 
284
                                matrix.m31(), matrix.m32(), 0, matrix.m33());
298
285
}
299
286
 
300
287
void GraphicsContext::savePlatformState()
307
294
    m_data->p()->restore();
308
295
 
309
296
    if (!m_data->currentPath.isEmpty() && m_common->state.pathTransform.isInvertible()) {
310
 
        QMatrix matrix = m_common->state.pathTransform;
 
297
        QTransform matrix = m_common->state.pathTransform;
311
298
        m_data->currentPath = m_data->currentPath * matrix;
312
299
    }
313
300
}
424
411
    if (paintingDisabled())
425
412
        return;
426
413
 
427
 
    QPainter *p = m_data->p();
 
414
    QPainter* p = m_data->p();
428
415
    const bool antiAlias = p->testRenderHint(QPainter::Antialiasing);
429
416
    p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines);
430
417
 
 
418
    IntSize shadowSize;
 
419
    int shadowBlur;
 
420
    Color shadowColor;
 
421
    if (getShadow(shadowSize, shadowBlur, shadowColor)) {
 
422
        IntRect shadowRect = rect;
 
423
        shadowRect.move(shadowSize.width(), shadowSize.height());
 
424
        shadowRect.inflate(static_cast<int>(p->pen().widthF()));
 
425
        p->fillRect(shadowRect, shadowColor);
 
426
    }
 
427
 
431
428
    p->drawRect(rect);
432
429
 
433
430
    p->setRenderHint(QPainter::Antialiasing, antiAlias);
434
431
}
435
432
 
436
 
// FIXME: Now that this is refactored, it should be shared by all contexts.
437
 
static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth,
438
 
                                        const StrokeStyle& penStyle)
439
 
{
440
 
    // For odd widths, we add in 0.5 to the appropriate x/y so that the float arithmetic
441
 
    // works out.  For example, with a border width of 3, KHTML will pass us (y1+y2)/2, e.g.,
442
 
    // (50+53)/2 = 103/2 = 51 when we want 51.5.  It is always true that an even width gave
443
 
    // us a perfect position, but an odd width gave us a position that is off by exactly 0.5.
444
 
    if (penStyle == DottedStroke || penStyle == DashedStroke) {
445
 
        if (p1.x() == p2.x()) {
446
 
            p1.setY(p1.y() + strokeWidth);
447
 
            p2.setY(p2.y() - strokeWidth);
448
 
        } else {
449
 
            p1.setX(p1.x() + strokeWidth);
450
 
            p2.setX(p2.x() - strokeWidth);
451
 
        }
452
 
    }
453
 
 
454
 
    if (((int) strokeWidth) % 2) {
455
 
        if (p1.x() == p2.x()) {
456
 
            // We're a vertical line.  Adjust our x.
457
 
            p1.setX(p1.x() + 0.5);
458
 
            p2.setX(p2.x() + 0.5);
459
 
        } else {
460
 
            // We're a horizontal line. Adjust our y.
461
 
            p1.setY(p1.y() + 0.5);
462
 
            p2.setY(p2.y() + 0.5);
463
 
        }
464
 
    }
465
 
}
466
 
 
467
433
// This is only used to draw borders.
468
434
void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
469
435
{
481
447
    FloatPoint p2 = point2;
482
448
    bool isVerticalLine = (p1.x() == p2.x());
483
449
 
484
 
    QPainter *p = m_data->p();
 
450
    QPainter* p = m_data->p();
485
451
    const bool antiAlias = p->testRenderHint(QPainter::Antialiasing);
486
452
    p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines);
487
453
    adjustLineToPixelBoundaries(p1, p2, width, style);
492
458
    if (textDrawingMode() == cTextFill && getShadow(shadowSize, shadowBlur, shadowColor)) {
493
459
        p->save();
494
460
        p->translate(shadowSize.width(), shadowSize.height());
495
 
        p->setPen(QColor(shadowColor));
 
461
        p->setPen(shadowColor);
496
462
        p->drawLine(p1, p2);
497
463
        p->restore();
498
464
    }
499
465
 
500
466
    int patWidth = 0;
501
467
    switch (style) {
502
 
        case NoStroke:
503
 
        case SolidStroke:
504
 
            break;
505
 
        case DottedStroke:
506
 
            patWidth = (int)width;
507
 
            break;
508
 
        case DashedStroke:
509
 
            patWidth = 3 * (int)width;
510
 
            break;
 
468
    case NoStroke:
 
469
    case SolidStroke:
 
470
        break;
 
471
    case DottedStroke:
 
472
        patWidth = static_cast<int>(width);
 
473
        break;
 
474
    case DashedStroke:
 
475
        patWidth = 3 * static_cast<int>(width);
 
476
        break;
511
477
    }
512
478
 
513
479
    if (patWidth) {
536
502
        if (patWidth == 1)
537
503
            patternOffset = 1.0f;
538
504
        else {
539
 
            bool evenNumberOfSegments = numSegments % 2 == 0;
 
505
            bool evenNumberOfSegments = !(numSegments % 2);
540
506
            if (remainder)
541
507
                evenNumberOfSegments = !evenNumberOfSegments;
542
508
            if (evenNumberOfSegments) {
584
550
    if (paintingDisabled() || strokeStyle() == NoStroke || strokeThickness() <= 0.0f || !strokeColor().alpha())
585
551
        return;
586
552
 
587
 
    QPainter *p = m_data->p();
 
553
    QPainter* p = m_data->p();
588
554
    const bool antiAlias = p->testRenderHint(QPainter::Antialiasing);
589
 
    p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines);
 
555
    p->setRenderHint(QPainter::Antialiasing, true);
590
556
 
591
 
    p->drawArc(rect, startAngle * 16, angleSpan * 16);
 
557
    IntSize shadowSize;
 
558
    int shadowBlur;
 
559
    Color shadowColor;
 
560
    startAngle *= 16;
 
561
    angleSpan *= 16;
 
562
    if (getShadow(shadowSize, shadowBlur, shadowColor)) {
 
563
        p->save();
 
564
        p->translate(shadowSize.width(), shadowSize.height());
 
565
        QPen pen(p->pen());
 
566
        pen.setColor(shadowColor);
 
567
        p->setPen(pen);
 
568
        p->drawArc(rect, startAngle, angleSpan);
 
569
        p->restore();
 
570
    }
 
571
    p->drawArc(rect, startAngle, angleSpan);
592
572
 
593
573
    p->setRenderHint(QPainter::Antialiasing, antiAlias);
594
574
}
606
586
    for (size_t i = 0; i < npoints; i++)
607
587
        polygon[i] = points[i];
608
588
 
609
 
    QPainter *p = m_data->p();
 
589
    QPainter* p = m_data->p();
610
590
    p->save();
611
591
    p->setRenderHint(QPainter::Antialiasing, shouldAntialias);
 
592
    IntSize shadowSize;
 
593
    int shadowBlur;
 
594
    Color shadowColor;
 
595
    if (getShadow(shadowSize, shadowBlur, shadowColor)) {
 
596
        p->save();
 
597
        p->translate(shadowSize.width(), shadowSize.height());
 
598
        if (p->brush().style() != Qt::NoBrush)
 
599
            p->setBrush(QBrush(shadowColor));
 
600
        QPen pen(p->pen());
 
601
        if (pen.style() != Qt::NoPen) {
 
602
            pen.setColor(shadowColor);
 
603
            p->setPen(pen);
 
604
        }
 
605
        p->drawConvexPolygon(polygon);
 
606
        p->restore();
 
607
    }
612
608
    p->drawConvexPolygon(polygon);
613
609
    p->restore();
614
610
}
618
614
    if (paintingDisabled())
619
615
        return QPen();
620
616
 
621
 
    QPainter *p = m_data->p();
 
617
    QPainter* p = m_data->p();
622
618
    return p->pen();
623
619
}
624
620
 
 
621
static void inline drawFilledShadowPath(GraphicsContext* context, QPainter* p, const QPainterPath *path)
 
622
{
 
623
    IntSize shadowSize;
 
624
    int shadowBlur;
 
625
    Color shadowColor;
 
626
    if (context->getShadow(shadowSize, shadowBlur, shadowColor)) {
 
627
        p->translate(shadowSize.width(), shadowSize.height());
 
628
        p->fillPath(*path, QBrush(shadowColor));
 
629
        p->translate(-shadowSize.width(), -shadowSize.height());
 
630
    }
 
631
}
 
632
 
625
633
void GraphicsContext::fillPath()
626
634
{
627
635
    if (paintingDisabled())
628
636
        return;
629
637
 
630
 
    QPainter *p = m_data->p();
 
638
    QPainter* p = m_data->p();
631
639
    QPainterPath path = m_data->currentPath;
632
640
    path.setFillRule(toQtFillRule(fillRule()));
633
641
 
634
 
    switch (m_common->state.fillColorSpace) {
635
 
    case SolidColorSpace:
636
 
        if (fillColor().alpha())
637
 
            p->fillPath(path, p->brush());
638
 
        break;
639
 
    case PatternColorSpace: {
640
 
        TransformationMatrix affine;
641
 
        p->fillPath(path, QBrush(m_common->state.fillPattern->createPlatformPattern(affine)));
642
 
        break;
643
 
    }
644
 
    case GradientColorSpace:
645
 
        QGradient* gradient = m_common->state.fillGradient->platformGradient();
646
 
        *gradient = applySpreadMethod(*gradient, spreadMethod());  
647
 
        p->fillPath(path, QBrush(*gradient));
648
 
        break;
 
642
    if ((m_common->state.fillColorSpace != SolidColorSpace)
 
643
            || (fillColor().alpha())) {
 
644
        drawFilledShadowPath(this, p, &path);
 
645
        switch (m_common->state.fillColorSpace) {
 
646
        case SolidColorSpace:
 
647
            if (fillColor().alpha())
 
648
                p->fillPath(path, p->brush());
 
649
            break;
 
650
        case PatternColorSpace: {
 
651
            TransformationMatrix affine;
 
652
            p->fillPath(path, QBrush(m_common->state.fillPattern->createPlatformPattern(affine)));
 
653
            break;
 
654
        }
 
655
        case GradientColorSpace:
 
656
            QBrush brush(*m_common->state.fillGradient->platformGradient());
 
657
            brush.setTransform(m_common->state.fillGradient->gradientSpaceTransform());
 
658
            p->fillPath(path, brush);
 
659
            break;
 
660
        }
649
661
    }
650
662
    m_data->currentPath = QPainterPath();
651
663
}
655
667
    if (paintingDisabled())
656
668
        return;
657
669
 
658
 
    QPainter *p = m_data->p();
659
 
    QPen pen = p->pen();
 
670
    QPainter* p = m_data->p();
 
671
    QPen pen(p->pen());
660
672
    QPainterPath path = m_data->currentPath;
661
673
    path.setFillRule(toQtFillRule(fillRule()));
662
674
 
663
 
    switch (m_common->state.strokeColorSpace) {
664
 
    case SolidColorSpace:
665
 
        if (strokeColor().alpha())
666
 
            p->strokePath(path, pen);
667
 
        break;
668
 
    case PatternColorSpace: {
669
 
        TransformationMatrix affine;
670
 
        pen.setBrush(QBrush(m_common->state.strokePattern->createPlatformPattern(affine)));
671
 
        p->setPen(pen);
672
 
        p->strokePath(path, pen);
673
 
        break;
674
 
    }
675
 
    case GradientColorSpace: {
676
 
        QGradient* gradient = m_common->state.strokeGradient->platformGradient();
677
 
        *gradient = applySpreadMethod(*gradient, spreadMethod()); 
678
 
        pen.setBrush(QBrush(*gradient));
679
 
        p->setPen(pen);
680
 
        p->strokePath(path, pen);
681
 
        break;
682
 
    }
 
675
    if ((m_common->state.strokeColorSpace != SolidColorSpace)
 
676
            || (strokeColor().alpha())) {
 
677
        IntSize shadowSize;
 
678
        int shadowBlur;
 
679
        Color shadowColor;
 
680
        if (getShadow(shadowSize, shadowBlur, shadowColor)) {
 
681
            QTransform t(p->worldTransform());
 
682
            p->translate(shadowSize.width(), shadowSize.height());
 
683
            QPen shadowPen(pen);
 
684
            shadowPen.setColor(shadowColor);
 
685
            p->strokePath(path, shadowPen);
 
686
            p->setWorldTransform(t);
 
687
        }
 
688
        switch (m_common->state.strokeColorSpace) {
 
689
        case SolidColorSpace:
 
690
            if (strokeColor().alpha())
 
691
                p->strokePath(path, pen);
 
692
            break;
 
693
        case PatternColorSpace: {
 
694
            TransformationMatrix affine;
 
695
            pen.setBrush(QBrush(m_common->state.strokePattern->createPlatformPattern(affine)));
 
696
            p->setPen(pen);
 
697
            p->strokePath(path, pen);
 
698
            break;
 
699
        }
 
700
        case GradientColorSpace: {
 
701
            QBrush brush(*m_common->state.strokeGradient->platformGradient());
 
702
            brush.setTransform(m_common->state.strokeGradient->gradientSpaceTransform());
 
703
            pen.setBrush(brush);
 
704
            p->setPen(pen);
 
705
            p->strokePath(path, pen);
 
706
            break;
 
707
        }
 
708
        }
683
709
    }
684
710
    m_data->currentPath = QPainterPath();
685
711
}
686
712
 
 
713
static inline void drawBorderlessRectShadow(GraphicsContext* context, QPainter* p, const FloatRect& rect)
 
714
{
 
715
    IntSize shadowSize;
 
716
    int shadowBlur;
 
717
    Color shadowColor;
 
718
    if (context->getShadow(shadowSize, shadowBlur, shadowColor)) {
 
719
        FloatRect shadowRect(rect);
 
720
        shadowRect.move(shadowSize.width(), shadowSize.height());
 
721
        p->fillRect(shadowRect, shadowColor);
 
722
    }
 
723
}
 
724
 
687
725
void GraphicsContext::fillRect(const FloatRect& rect)
688
726
{
689
727
    if (paintingDisabled())
690
728
        return;
691
729
 
692
 
    QPainter *p = m_data->p();
 
730
    QPainter* p = m_data->p();
693
731
 
694
 
    switch (m_common->state.fillColorSpace) {
695
 
    case SolidColorSpace:
696
 
        if (fillColor().alpha())
697
 
            p->fillRect(rect, p->brush());
698
 
        break;
699
 
    case PatternColorSpace: {
700
 
        TransformationMatrix affine;
701
 
        p->fillRect(rect, QBrush(m_common->state.fillPattern->createPlatformPattern(affine)));
702
 
        break;
703
 
    }
704
 
    case GradientColorSpace:
705
 
        p->fillRect(rect, QBrush(*(m_common->state.fillGradient.get()->platformGradient())));
706
 
        break;
707
 
    }
708
 
    m_data->currentPath = QPainterPath();
 
732
    if ((m_common->state.fillColorSpace != SolidColorSpace)
 
733
            || (fillColor().alpha())) {
 
734
        drawBorderlessRectShadow(this, p, rect);
 
735
        switch (m_common->state.fillColorSpace) {
 
736
        case SolidColorSpace:
 
737
            if (fillColor().alpha())
 
738
                p->fillRect(rect, p->brush());
 
739
            break;
 
740
        case PatternColorSpace: {
 
741
            TransformationMatrix affine;
 
742
            p->fillRect(rect, QBrush(m_common->state.fillPattern->createPlatformPattern(affine)));
 
743
            break;
 
744
        }
 
745
        case GradientColorSpace:
 
746
            QBrush brush(*m_common->state.fillGradient->platformGradient());
 
747
            brush.setTransform(m_common->state.fillGradient->gradientSpaceTransform());
 
748
            p->fillRect(rect, brush);
 
749
            break;
 
750
        }
 
751
    }
709
752
}
710
753
 
711
754
void GraphicsContext::fillRect(const FloatRect& rect, const Color& c)
713
756
    if (paintingDisabled())
714
757
        return;
715
758
 
716
 
    m_data->solidColor.setColor(QColor(c));
717
 
    m_data->p()->fillRect(rect, m_data->solidColor);
 
759
    m_data->solidColor.setColor(c);
 
760
    QPainter* p = m_data->p();
 
761
    drawBorderlessRectShadow(this, p, rect);
 
762
    p->fillRect(rect, m_data->solidColor);
718
763
}
719
764
 
720
765
void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color)
723
768
        return;
724
769
 
725
770
    Path path = Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight);
726
 
    m_data->p()->fillPath(*path.platformPath(), QColor(color));
 
771
    QPainter* p = m_data->p();
 
772
    drawFilledShadowPath(this, p, path.platformPath());
 
773
    p->fillPath(*path.platformPath(), QColor(color));
727
774
}
728
775
 
729
776
void GraphicsContext::beginPath()
761
808
    if (paintingDisabled())
762
809
        return;
763
810
 
764
 
    QPainter *p = m_data->p();
 
811
    QPainter* p = m_data->p();
765
812
    QPainterPath newPath = m_data->currentPath;
766
813
    newPath.setFillRule(clipRule == RULE_EVENODD ? Qt::OddEvenFill : Qt::WindingFill);
767
814
    p->setClipPath(newPath);
772
819
 * RenderTheme handles drawing focus on widgets which 
773
820
 * need it.
774
821
 */
775
 
Color focusRingColor() { return Color(0, 0, 0); }
776
822
void GraphicsContext::drawFocusRing(const Color& color)
777
823
{
778
824
    if (paintingDisabled())
781
827
    const Vector<IntRect>& rects = focusRingRects();
782
828
    unsigned rectCount = rects.size();
783
829
 
784
 
    if (rects.size() == 0)
 
830
    if (!rects.size())
785
831
        return;
786
832
 
787
 
    QPainter *p = m_data->p();
 
833
    QPainter* p = m_data->p();
788
834
    const bool antiAlias = p->testRenderHint(QPainter::Antialiasing);
789
835
    p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines);
790
836
 
805
851
    QPainterPath newPath = stroker.createStroke(path);
806
852
    p->strokePath(newPath, nPen);
807
853
#else
808
 
    for (int i = 0; i < rectCount; ++i)
 
854
    for (unsigned i = 0; i < rectCount; ++i)
809
855
        p->drawRect(QRectF(rects[i]));
810
856
#endif
811
857
    p->setPen(oldPen);
814
860
    p->setRenderHint(QPainter::Antialiasing, antiAlias);
815
861
}
816
862
 
817
 
void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing)
 
863
void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool)
818
864
{
819
865
    if (paintingDisabled())
820
866
        return;
823
869
    drawLine(origin, endPoint);
824
870
}
825
871
 
826
 
void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint&,
827
 
                                                         int width, bool grammar)
 
872
void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint&, int, bool)
828
873
{
829
874
    if (paintingDisabled())
830
875
        return;
841
886
    return FloatRect(QRectF(result));
842
887
}
843
888
 
844
 
void GraphicsContext::setPlatformShadow(const IntSize& pos, int blur, const Color &color)
 
889
void GraphicsContext::setPlatformShadow(const IntSize& size, int, const Color&)
845
890
{
846
891
    // Qt doesn't support shadows natively, they are drawn manually in the draw*
847
892
    // functions
 
893
 
 
894
    if (m_common->state.shadowsIgnoreTransforms) {
 
895
        // Meaning that this graphics context is associated with a CanvasRenderingContext
 
896
        // We flip the height since CG and HTML5 Canvas have opposite Y axis
 
897
        m_common->state.shadowSize = IntSize(size.width(), -size.height());
 
898
    }
848
899
}
849
900
 
850
901
void GraphicsContext::clearPlatformShadow()
860
911
 
861
912
    int x, y, w, h;
862
913
    x = y = 0;
863
 
    QPainter *p = m_data->p();
864
 
    const QPaintDevice *device = p->device();
 
914
    QPainter* p = m_data->p();
 
915
    const QPaintDevice* device = p->device();
865
916
    w = device->width();
866
917
    h = device->height();
867
918
 
883
934
    if (paintingDisabled())
884
935
        return;
885
936
 
886
 
    TransparencyLayer *layer = m_data->layers.pop();
 
937
    TransparencyLayer* layer = m_data->layers.pop();
887
938
    layer->painter.end();
888
939
 
889
 
    QPainter *p = m_data->p();
 
940
    QPainter* p = m_data->p();
890
941
    p->save();
891
942
    p->resetTransform();
892
943
    p->setOpacity(layer->opacity);
901
952
    if (paintingDisabled())
902
953
        return;
903
954
 
904
 
    QPainter *p = m_data->p();
 
955
    QPainter* p = m_data->p();
905
956
    QPainter::CompositionMode currentCompositionMode = p->compositionMode();
906
957
    if (p->paintEngine()->hasFeature(QPaintEngine::PorterDuff))
907
958
        p->setCompositionMode(QPainter::CompositionMode_Source);
928
979
    if (paintingDisabled())
929
980
        return;
930
981
 
931
 
    QPainter *p = m_data->p();
 
982
    QPainter* p = m_data->p();
932
983
    QPen nPen = p->pen();
933
984
    nPen.setCapStyle(toQtLineCap(lc));
934
985
    p->setPen(nPen);
960
1011
    if (paintingDisabled())
961
1012
        return;
962
1013
 
963
 
    QPainter *p = m_data->p();
 
1014
    QPainter* p = m_data->p();
964
1015
    QPen nPen = p->pen();
965
1016
    nPen.setJoinStyle(toQtLineJoin(lj));
966
1017
    p->setPen(nPen);
971
1022
    if (paintingDisabled())
972
1023
        return;
973
1024
 
974
 
    QPainter *p = m_data->p();
 
1025
    QPainter* p = m_data->p();
975
1026
    QPen nPen = p->pen();
976
1027
    nPen.setMiterLimit(limit);
977
1028
    p->setPen(nPen);
981
1032
{
982
1033
    if (paintingDisabled())
983
1034
        return;
984
 
    QPainter *p = m_data->p();
 
1035
    QPainter* p = m_data->p();
985
1036
    p->setOpacity(opacity);
986
1037
}
987
1038
 
1007
1058
    if (paintingDisabled())
1008
1059
        return;
1009
1060
 
1010
 
    QPainter *p = m_data->p();
 
1061
    QPainter* p = m_data->p();
1011
1062
    QRectF clipBounds = p->clipPath().boundingRect();
1012
1063
    QPainterPath clippedOut = *path.platformPath();
1013
1064
    QPainterPath newClip;
1026
1077
    m_data->p()->translate(x, y);
1027
1078
 
1028
1079
    if (!m_data->currentPath.isEmpty()) {
1029
 
        QMatrix matrix;
 
1080
        QTransform matrix;
1030
1081
        m_data->currentPath = m_data->currentPath * matrix.translate(-x, -y);
1031
1082
        m_common->state.pathTransform.translate(x, y);
1032
1083
    }
1048
1099
    m_data->p()->rotate(180/M_PI*radians);
1049
1100
 
1050
1101
    if (!m_data->currentPath.isEmpty()) {
1051
 
        QMatrix matrix;
 
1102
        QTransform matrix;
1052
1103
        m_data->currentPath = m_data->currentPath * matrix.rotate(-180/M_PI*radians);
1053
1104
        m_common->state.pathTransform.rotate(radians);
1054
1105
    }
1062
1113
    m_data->p()->scale(s.width(), s.height());
1063
1114
 
1064
1115
    if (!m_data->currentPath.isEmpty()) {
1065
 
        QMatrix matrix;
 
1116
        QTransform matrix;
1066
1117
        m_data->currentPath = m_data->currentPath * matrix.scale(1 / s.width(), 1 / s.height());
1067
 
        m_common->state.pathTransform.scale(s.width(), s.height());
 
1118
        m_common->state.pathTransform.scaleNonUniform(s.width(), s.height());
1068
1119
    }
1069
1120
}
1070
1121
 
1073
1124
    if (paintingDisabled())
1074
1125
        return;
1075
1126
 
1076
 
    QPainter *p = m_data->p();
 
1127
    QPainter* p = m_data->p();
1077
1128
    QRectF clipBounds = p->clipPath().boundingRect();
1078
1129
    QPainterPath newClip;
1079
1130
    newClip.setFillRule(Qt::OddEvenFill);
1088
1139
    if (paintingDisabled())
1089
1140
        return;
1090
1141
 
1091
 
    QPainter *p = m_data->p();
 
1142
    QPainter* p = m_data->p();
1092
1143
    QRectF clipBounds = p->clipPath().boundingRect();
1093
1144
    QPainterPath newClip;
1094
1145
    newClip.setFillRule(Qt::OddEvenFill);
1120
1171
                           rect.width() - (thickness * 2), rect.height() - (thickness * 2)));
1121
1172
 
1122
1173
    path.setFillRule(Qt::OddEvenFill);
1123
 
    m_data->p()->setClipPath(path, Qt::IntersectClip);
 
1174
 
 
1175
    QPainter* p = m_data->p();
 
1176
 
 
1177
    const bool antiAlias = p->testRenderHint(QPainter::Antialiasing);
 
1178
    p->setRenderHint(QPainter::Antialiasing, true);
 
1179
    p->setClipPath(path, Qt::IntersectClip);
 
1180
    p->setRenderHint(QPainter::Antialiasing, antiAlias);
1124
1181
}
1125
1182
 
1126
1183
void GraphicsContext::concatCTM(const TransformationMatrix& transform)
1128
1185
    if (paintingDisabled())
1129
1186
        return;
1130
1187
 
1131
 
    m_data->p()->setMatrix(transform, true);
 
1188
    m_data->p()->setWorldTransform(transform, true);
1132
1189
 
1133
 
    // Transformations to the context shouldn't transform the currentPath. 
1134
 
    // We have to undo every change made to the context from the currentPath to avoid wrong drawings.
 
1190
    // Transformations to the context shouldn't transform the currentPath.
 
1191
    // We have to undo every change made to the context from the currentPath
 
1192
    // to avoid wrong drawings.
1135
1193
    if (!m_data->currentPath.isEmpty() && transform.isInvertible()) {
1136
 
        QMatrix matrix = transform.inverse();
 
1194
        QTransform matrix = transform.inverse();
1137
1195
        m_data->currentPath = m_data->currentPath * matrix;
1138
1196
        m_common->state.pathTransform.multiply(transform);
1139
1197
    }
1140
1198
}
1141
1199
 
1142
 
void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
 
1200
void GraphicsContext::setURLForRect(const KURL&, const IntRect&)
1143
1201
{
1144
1202
    notImplemented();
1145
1203
}
1146
1204
 
1147
 
void GraphicsContext::setPlatformFont(const Font& aFont)
1148
 
{
1149
 
    if (paintingDisabled())
1150
 
        return;
1151
 
    m_data->p()->setFont(aFont.font());
1152
 
}
1153
 
 
1154
1205
void GraphicsContext::setPlatformStrokeColor(const Color& color)
1155
1206
{
1156
1207
    if (paintingDisabled())
1157
1208
        return;
1158
 
    QPainter *p = m_data->p();
 
1209
    QPainter* p = m_data->p();
1159
1210
    QPen newPen(p->pen());
1160
1211
    newPen.setColor(color);
1161
1212
    p->setPen(newPen);
1165
1216
{
1166
1217
    if (paintingDisabled())
1167
1218
        return;
1168
 
    QPainter *p = m_data->p();
 
1219
    QPainter* p = m_data->p();
1169
1220
    QPen newPen(p->pen());
1170
1221
    newPen.setStyle(toQPenStyle(strokeStyle));
1171
1222
    p->setPen(newPen);
1175
1226
{
1176
1227
    if (paintingDisabled())
1177
1228
        return;
1178
 
    QPainter *p = m_data->p();
 
1229
    QPainter* p = m_data->p();
1179
1230
    QPen newPen(p->pen());
1180
1231
    newPen.setWidthF(thickness);
1181
1232
    p->setPen(newPen);
1188
1239
    m_data->p()->setBrush(QBrush(color));
1189
1240
}
1190
1241
 
1191
 
void GraphicsContext::setUseAntialiasing(bool enable)
 
1242
void GraphicsContext::setPlatformShouldAntialias(bool enable)
1192
1243
{
1193
1244
    if (paintingDisabled())
1194
1245
        return;
1196
1247
}
1197
1248
 
1198
1249
#ifdef Q_WS_WIN
1199
 
#include <windows.h>
1200
1250
 
1201
1251
HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap)
1202
1252
{
1221
1271
    bitmapInfo.bmiHeader.biClrImportant  = 0;
1222
1272
 
1223
1273
    void* pixels = 0;
1224
 
    HBITMAP bitmap = ::CreateDIBSection(NULL, &bitmapInfo, DIB_RGB_COLORS, &pixels, 0, 0);
 
1274
    HBITMAP bitmap = ::CreateDIBSection(0, &bitmapInfo, DIB_RGB_COLORS, &pixels, 0, 0);
1225
1275
    if (!bitmap)
1226
1276
        return 0;
1227
1277
 
1239
1289
        memset(bmpInfo.bmBits, 0, bufferSize);
1240
1290
    }
1241
1291
 
1242
 
#if !PLATFORM(WIN_CE)
 
1292
#if !PLATFORM(WINCE)
1243
1293
    // Make sure we can do world transforms.
1244
1294
    SetGraphicsMode(bitmapDC, GM_ADVANCED);
1245
1295