71
72
static inline QPainter::CompositionMode toQtCompositionMode(CompositeOperator op)
75
return QPainter::CompositionMode_Clear;
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;
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;
76
return QPainter::CompositionMode_Clear;
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;
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;
104
106
return QPainter::CompositionMode_SourceOver;
295
278
TransformationMatrix GraphicsContext::getCTM() const
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(),
284
matrix.m31(), matrix.m32(), 0, matrix.m33());
300
287
void GraphicsContext::savePlatformState()
424
411
if (paintingDisabled())
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);
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);
431
428
p->drawRect(rect);
433
430
p->setRenderHint(QPainter::Antialiasing, antiAlias);
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)
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);
449
p1.setX(p1.x() + strokeWidth);
450
p2.setX(p2.x() - strokeWidth);
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);
460
// We're a horizontal line. Adjust our y.
461
p1.setY(p1.y() + 0.5);
462
p2.setY(p2.y() + 0.5);
467
433
// This is only used to draw borders.
468
434
void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
584
550
if (paintingDisabled() || strokeStyle() == NoStroke || strokeThickness() <= 0.0f || !strokeColor().alpha())
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);
591
p->drawArc(rect, startAngle * 16, angleSpan * 16);
562
if (getShadow(shadowSize, shadowBlur, shadowColor)) {
564
p->translate(shadowSize.width(), shadowSize.height());
566
pen.setColor(shadowColor);
568
p->drawArc(rect, startAngle, angleSpan);
571
p->drawArc(rect, startAngle, angleSpan);
593
573
p->setRenderHint(QPainter::Antialiasing, antiAlias);
606
586
for (size_t i = 0; i < npoints; i++)
607
587
polygon[i] = points[i];
609
QPainter *p = m_data->p();
589
QPainter* p = m_data->p();
611
591
p->setRenderHint(QPainter::Antialiasing, shouldAntialias);
595
if (getShadow(shadowSize, shadowBlur, shadowColor)) {
597
p->translate(shadowSize.width(), shadowSize.height());
598
if (p->brush().style() != Qt::NoBrush)
599
p->setBrush(QBrush(shadowColor));
601
if (pen.style() != Qt::NoPen) {
602
pen.setColor(shadowColor);
605
p->drawConvexPolygon(polygon);
612
608
p->drawConvexPolygon(polygon);
618
614
if (paintingDisabled())
621
QPainter *p = m_data->p();
617
QPainter* p = m_data->p();
621
static void inline drawFilledShadowPath(GraphicsContext* context, QPainter* p, const QPainterPath *path)
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());
625
633
void GraphicsContext::fillPath()
627
635
if (paintingDisabled())
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()));
634
switch (m_common->state.fillColorSpace) {
635
case SolidColorSpace:
636
if (fillColor().alpha())
637
p->fillPath(path, p->brush());
639
case PatternColorSpace: {
640
TransformationMatrix affine;
641
p->fillPath(path, QBrush(m_common->state.fillPattern->createPlatformPattern(affine)));
644
case GradientColorSpace:
645
QGradient* gradient = m_common->state.fillGradient->platformGradient();
646
*gradient = applySpreadMethod(*gradient, spreadMethod());
647
p->fillPath(path, QBrush(*gradient));
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());
650
case PatternColorSpace: {
651
TransformationMatrix affine;
652
p->fillPath(path, QBrush(m_common->state.fillPattern->createPlatformPattern(affine)));
655
case GradientColorSpace:
656
QBrush brush(*m_common->state.fillGradient->platformGradient());
657
brush.setTransform(m_common->state.fillGradient->gradientSpaceTransform());
658
p->fillPath(path, brush);
650
662
m_data->currentPath = QPainterPath();
655
667
if (paintingDisabled())
658
QPainter *p = m_data->p();
670
QPainter* p = m_data->p();
660
672
QPainterPath path = m_data->currentPath;
661
673
path.setFillRule(toQtFillRule(fillRule()));
663
switch (m_common->state.strokeColorSpace) {
664
case SolidColorSpace:
665
if (strokeColor().alpha())
666
p->strokePath(path, pen);
668
case PatternColorSpace: {
669
TransformationMatrix affine;
670
pen.setBrush(QBrush(m_common->state.strokePattern->createPlatformPattern(affine)));
672
p->strokePath(path, pen);
675
case GradientColorSpace: {
676
QGradient* gradient = m_common->state.strokeGradient->platformGradient();
677
*gradient = applySpreadMethod(*gradient, spreadMethod());
678
pen.setBrush(QBrush(*gradient));
680
p->strokePath(path, pen);
675
if ((m_common->state.strokeColorSpace != SolidColorSpace)
676
|| (strokeColor().alpha())) {
680
if (getShadow(shadowSize, shadowBlur, shadowColor)) {
681
QTransform t(p->worldTransform());
682
p->translate(shadowSize.width(), shadowSize.height());
684
shadowPen.setColor(shadowColor);
685
p->strokePath(path, shadowPen);
686
p->setWorldTransform(t);
688
switch (m_common->state.strokeColorSpace) {
689
case SolidColorSpace:
690
if (strokeColor().alpha())
691
p->strokePath(path, pen);
693
case PatternColorSpace: {
694
TransformationMatrix affine;
695
pen.setBrush(QBrush(m_common->state.strokePattern->createPlatformPattern(affine)));
697
p->strokePath(path, pen);
700
case GradientColorSpace: {
701
QBrush brush(*m_common->state.strokeGradient->platformGradient());
702
brush.setTransform(m_common->state.strokeGradient->gradientSpaceTransform());
705
p->strokePath(path, pen);
684
710
m_data->currentPath = QPainterPath();
713
static inline void drawBorderlessRectShadow(GraphicsContext* context, QPainter* p, const FloatRect& rect)
718
if (context->getShadow(shadowSize, shadowBlur, shadowColor)) {
719
FloatRect shadowRect(rect);
720
shadowRect.move(shadowSize.width(), shadowSize.height());
721
p->fillRect(shadowRect, shadowColor);
687
725
void GraphicsContext::fillRect(const FloatRect& rect)
689
727
if (paintingDisabled())
692
QPainter *p = m_data->p();
730
QPainter* p = m_data->p();
694
switch (m_common->state.fillColorSpace) {
695
case SolidColorSpace:
696
if (fillColor().alpha())
697
p->fillRect(rect, p->brush());
699
case PatternColorSpace: {
700
TransformationMatrix affine;
701
p->fillRect(rect, QBrush(m_common->state.fillPattern->createPlatformPattern(affine)));
704
case GradientColorSpace:
705
p->fillRect(rect, QBrush(*(m_common->state.fillGradient.get()->platformGradient())));
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());
740
case PatternColorSpace: {
741
TransformationMatrix affine;
742
p->fillRect(rect, QBrush(m_common->state.fillPattern->createPlatformPattern(affine)));
745
case GradientColorSpace:
746
QBrush brush(*m_common->state.fillGradient->platformGradient());
747
brush.setTransform(m_common->state.fillGradient->gradientSpaceTransform());
748
p->fillRect(rect, brush);
711
754
void GraphicsContext::fillRect(const FloatRect& rect, const Color& c)
841
886
return FloatRect(QRectF(result));
844
void GraphicsContext::setPlatformShadow(const IntSize& pos, int blur, const Color &color)
889
void GraphicsContext::setPlatformShadow(const IntSize& size, int, const Color&)
846
891
// Qt doesn't support shadows natively, they are drawn manually in the draw*
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());
850
901
void GraphicsContext::clearPlatformShadow()
1120
1171
rect.width() - (thickness * 2), rect.height() - (thickness * 2)));
1122
1173
path.setFillRule(Qt::OddEvenFill);
1123
m_data->p()->setClipPath(path, Qt::IntersectClip);
1175
QPainter* p = m_data->p();
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);
1126
1183
void GraphicsContext::concatCTM(const TransformationMatrix& transform)
1128
1185
if (paintingDisabled())
1131
m_data->p()->setMatrix(transform, true);
1188
m_data->p()->setWorldTransform(transform, true);
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);
1142
void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
1200
void GraphicsContext::setURLForRect(const KURL&, const IntRect&)
1144
1202
notImplemented();
1147
void GraphicsContext::setPlatformFont(const Font& aFont)
1149
if (paintingDisabled())
1151
m_data->p()->setFont(aFont.font());
1154
1205
void GraphicsContext::setPlatformStrokeColor(const Color& color)
1156
1207
if (paintingDisabled())
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);