Fixed inconsistent QPainter fill rules for aliased painting.
authorSamuel Rødal <samuel.rodal@digia.com>
Wed, 10 Oct 2012 10:38:07 +0000 (12:38 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Fri, 19 Oct 2012 00:43:05 +0000 (02:43 +0200)
Qt 5 is the time to get rid of all the old inconsistencies in the raster
paint engine caused by trying to preserve the old X11 based
coordinate system where (0, 0) is in the center of the top-left pixel
instead of the upper left corner of said pixel. However, this was only
adhered for line drawing and path / rect filling, and not for image or
pixmap drawing and not at all when doing antialiased painting. By
defining the antialiased coordinate system as being the right one and
letting the aliased fill rules follow from that we finally end up with
some consistent behavior that doesn't lead to surprises and workarounds
in application code.

It is still possible for applications to get the old behavior by
setting the QPainter::Qt4CompatiblePainting render hint. This should
make porting easier for the few cases where an application relies on the
aliased fill rules we used to have in Qt 4.

Task-number: QTBUG-27500
Change-Id: If86b95e77d838ec83033d64af86632b9a73c74a9
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
13 files changed:
dist/changes-5.0.0
src/gui/painting/qcosmeticstroker.cpp
src/gui/painting/qcosmeticstroker_p.h
src/gui/painting/qpaintbuffer.cpp
src/gui/painting/qpaintengine_raster.cpp
src/gui/painting/qpaintengine_raster_p.h
src/gui/painting/qpainter.cpp
src/gui/painting/qpainter.h
src/gui/painting/qrasterizer.cpp
src/gui/painting/qrasterizer_p.h
src/widgets/styles/qcommonstyle.cpp
src/widgets/styles/qwindowsstyle.cpp
tests/auto/gui/painting/qpainter/tst_qpainter.cpp

index 5773647..0014760 100644 (file)
@@ -508,6 +508,15 @@ QtGui
   the existent image data will be invalidated, so that isNull() is guaranteed
   to return true in this case.
 
+* Behavioral change regarding QPainter fill rules when not using antialiased
+  painting: The fill rules have changed so that the aliased and antialiased
+  coordinate systems match. Earlier there used to be an offset of slightly less
+  than half a pixel when doing sub-pixel rendering, in order to be consistent
+  with the old X11 paint engine. The new behavior should be more predictable and
+  gives the same consistent rounding for images / pixmaps as for paths and
+  rectangle filling. It's possible to still get the old behavior by setting the
+  QPainter::Qt4CompatiblePainting render hint.
+
 QtWidgets
 ---------
 * QInputContext removed as well as related getters and setters on QWidget and QApplication.
index f99edc6..2eab7b2 100644 (file)
@@ -414,7 +414,7 @@ void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal
     if (clipLine(rx1, ry1, rx2, ry2))
         return;
 
-    const int half = 31;
+    const int half = legacyRounding ? 31 : 0;
     int x1 = toF26Dot6(rx1) + half;
     int y1 = toF26Dot6(ry1) + half;
     int x2 = toF26Dot6(rx2) + half;
@@ -707,7 +707,7 @@ static void drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
     if (stroker->clipLine(rx1, ry1, rx2, ry2))
         return;
 
-    static const int half = 31;
+    const int half = stroker->legacyRounding ? 31 : 0;
     int x1 = toF26Dot6(rx1) + half;
     int y1 = toF26Dot6(ry1) + half;
     int x2 = toF26Dot6(rx2) + half;
index f71b87d..467eb7a 100644 (file)
@@ -93,11 +93,16 @@ public:
           patternSize(0),
           patternLength(0),
           patternOffset(0),
+          legacyRounding(false),
           current_span(0),
           lastDir(LeftToRight),
           lastAxisAligned(false)
     { setup(); }
+
     ~QCosmeticStroker() { free(pattern); free(reversePattern); }
+
+    void setLegacyRoundingEnabled(bool legacyRoundingEnabled) { legacyRounding = legacyRoundingEnabled; }
+
     void drawLine(const QPointF &p1, const QPointF &p2);
     void drawPath(const QVectorPath &path);
     void drawPoints(const QPoint *points, int num);
@@ -119,6 +124,8 @@ public:
     int patternLength;
     int patternOffset;
 
+    bool legacyRounding;
+
     enum { NSPANS = 255 };
     QT_FT_Span spans[NSPANS];
     int current_span;
index a2bac58..1e5a00e 100644 (file)
@@ -1467,6 +1467,8 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd)
             painter->setRenderHint(QPainter::SmoothPixmapTransform, nh & QPainter::SmoothPixmapTransform);
         if (xored & QPainter::NonCosmeticDefaultPen)
             painter->setRenderHint(QPainter::NonCosmeticDefaultPen, nh & QPainter::NonCosmeticDefaultPen);
+        if (xored & QPainter::Qt4CompatiblePainting)
+            painter->setRenderHint(QPainter::Qt4CompatiblePainting, nh & QPainter::Qt4CompatiblePainting);
         break; }
 
     case QPaintBufferPrivate::Cmd_SetOpacity: {
index 5228fdc..e0eab8d 100644 (file)
@@ -644,6 +644,7 @@ QRasterPaintEngineState::QRasterPaintEngineState()
     flags.fast_pen = true;
     flags.antialiased = false;
     flags.bilinear = false;
+    flags.legacy_rounding = false;
     flags.fast_text = true;
     flags.int_xform = true;
     flags.tx_noshear = true;
@@ -927,6 +928,7 @@ void QRasterPaintEngine::renderHintsChanged()
 
     s->flags.antialiased = bool(s->renderHints & QPainter::Antialiasing);
     s->flags.bilinear = bool(s->renderHints & QPainter::SmoothPixmapTransform);
+    s->flags.legacy_rounding = !bool(s->renderHints & QPainter::Antialiasing) && bool(s->renderHints & QPainter::Qt4CompatiblePainting);
 
     if (was_aa != s->flags.antialiased)
         s->strokeFlags |= DirtyHints;
@@ -1524,6 +1526,7 @@ void QRasterPaintEngine::drawRects(const QRect *rects, int rectCount)
         QRectVectorPath path;
         if (s->flags.fast_pen) {
             QCosmeticStroker stroker(s, d->deviceRect);
+            stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
             for (int i = 0; i < rectCount; ++i) {
                 path.set(rects[i]);
                 stroker.drawPath(path);
@@ -1570,6 +1573,7 @@ void QRasterPaintEngine::drawRects(const QRectF *rects, int rectCount)
             QRectVectorPath path;
             if (s->flags.fast_pen) {
                 QCosmeticStroker stroker(s, d->deviceRect);
+                stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
                 for (int i = 0; i < rectCount; ++i) {
                     path.set(rects[i]);
                     stroker.drawPath(path);
@@ -1603,6 +1607,7 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
 
     if (s->flags.fast_pen) {
         QCosmeticStroker stroker(s, d->deviceRect);
+        stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
         stroker.drawPath(path);
     } else if (s->flags.non_complex_pen && path.shape() == QVectorPath::LinesHint) {
         qreal width = s->lastPen.isCosmetic()
@@ -1658,12 +1663,16 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
         QPaintEngineEx::stroke(path, pen);
 }
 
-static inline QRect toNormalizedFillRect(const QRectF &rect)
+QRect QRasterPaintEngine::toNormalizedFillRect(const QRectF &rect)
 {
-    int x1 = qRound(rect.x() + aliasedCoordinateDelta);
-    int y1 = qRound(rect.y() + aliasedCoordinateDelta);
-    int x2 = qRound(rect.right() + aliasedCoordinateDelta);
-    int y2 = qRound(rect.bottom() + aliasedCoordinateDelta);
+    QRasterPaintEngineState *s = state();
+
+    qreal delta = s->flags.legacy_rounding ? aliasedCoordinateDelta : qreal(0);
+
+    int x1 = qRound(rect.x() + delta);
+    int y1 = qRound(rect.y() + delta);
+    int x2 = qRound(rect.right() + delta);
+    int y2 = qRound(rect.bottom() + delta);
 
     if (x2 < x1)
         qSwap(x1, x2);
@@ -1941,6 +1950,7 @@ void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, Poly
         QVectorPath vp((qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode));
         if (s->flags.fast_pen) {
             QCosmeticStroker stroker(s, d->deviceRect);
+            stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
             stroker.drawPath(vp);
         } else {
             QPaintEngineEx::stroke(vp, s->lastPen);
@@ -2005,6 +2015,7 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg
 
         if (s->flags.fast_pen) {
             QCosmeticStroker stroker(s, d->deviceRect);
+            stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
             stroker.drawPath(vp);
         } else {
             QPaintEngineEx::stroke(vp, s->lastPen);
@@ -2233,7 +2244,9 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
         // as fillRect will apply the aliased coordinate delta we need to
         // subtract it here as we don't use it for image drawing
         QTransform old = s->matrix;
-        s->matrix = s->matrix * QTransform::fromTranslate(-aliasedCoordinateDelta, -aliasedCoordinateDelta);
+
+        if (s->flags.legacy_rounding)
+            s->matrix = s->matrix * QTransform::fromTranslate(-aliasedCoordinateDelta, -aliasedCoordinateDelta);
 
         // Do whatever fillRect() does, but without premultiplying the color if it's already premultiplied.
         QRgb color = img.pixel(sr_l, sr_t);
@@ -2376,8 +2389,9 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
         if (s->flags.tx_noshear || s->matrix.type() == QTransform::TxScale) {
             d->initializeRasterizer(&d->image_filler_xform);
             d->rasterizer->setAntialiased(s->flags.antialiased);
+            d->rasterizer->setLegacyRoundingEnabled(s->flags.legacy_rounding);
 
-            const QPointF offs = s->flags.antialiased ? QPointF() : QPointF(aliasedCoordinateDelta, aliasedCoordinateDelta);
+            const QPointF offs = s->flags.legacy_rounding ? QPointF(aliasedCoordinateDelta, aliasedCoordinateDelta) : QPointF();
 
             const QRectF &rect = r.normalized();
             const QPointF a = s->matrix.map((rect.topLeft() + rect.bottomLeft()) * 0.5f) - offs;
@@ -2390,7 +2404,7 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
             return;
         }
 #endif
-        const qreal offs = s->flags.antialiased ? qreal(0) : aliasedCoordinateDelta;
+        const qreal offs = s->flags.legacy_rounding ? aliasedCoordinateDelta : qreal(0);
         QPainterPath path;
         path.addRect(r);
         QTransform m = s->matrix;
@@ -2471,6 +2485,7 @@ void QRasterPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap,
         if (s->flags.tx_noshear || s->matrix.type() == QTransform::TxScale) {
             d->initializeRasterizer(&d->image_filler_xform);
             d->rasterizer->setAntialiased(s->flags.antialiased);
+            d->rasterizer->setLegacyRoundingEnabled(s->flags.legacy_rounding);
 
             const QRectF &rect = r.normalized();
             const QPointF a = s->matrix.map((rect.topLeft() + rect.bottomLeft()) * 0.5f);
@@ -2802,7 +2817,7 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
             rightShift = 3; // divide by 8
 
         int margin = fontEngine->glyphMargin(glyphType);
-        const QFixed offs = QFixed::fromReal(aliasedCoordinateDelta);
+        const QFixed offs = s->flags.legacy_rounding ? QFixed::fromReal(aliasedCoordinateDelta) : QFixed();
         const uchar *bits = image.bits();
         for (int i=0; i<numGlyphs; ++i) {
 
@@ -3078,6 +3093,7 @@ void QRasterPaintEngine::drawPoints(const QPointF *points, int pointCount)
     }
 
     QCosmeticStroker stroker(s, d->deviceRect);
+    stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
     stroker.drawPoints(points, pointCount);
 }
 
@@ -3097,6 +3113,7 @@ void QRasterPaintEngine::drawPoints(const QPoint *points, int pointCount)
     }
 
     QCosmeticStroker stroker(s, d->deviceRect);
+    stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
     stroker.drawPoints(points, pointCount);
 }
 
@@ -3117,6 +3134,7 @@ void QRasterPaintEngine::drawLines(const QLine *lines, int lineCount)
 
     if (s->flags.fast_pen) {
         QCosmeticStroker stroker(s, d->deviceRect);
+        stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
         for (int i=0; i<lineCount; ++i) {
             const QLine &l = lines[i];
             stroker.drawLine(l.p1(), l.p2());
@@ -3188,6 +3206,7 @@ void QRasterPaintEngine::drawLines(const QLineF *lines, int lineCount)
         return;
     if (s->flags.fast_pen) {
         QCosmeticStroker stroker(s, d->deviceRect);
+        stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
         for (int i=0; i<lineCount; ++i) {
             QLineF line = lines[i];
             stroker.drawLine(line.p1(), line.p2());
@@ -3420,6 +3439,7 @@ void QRasterPaintEnginePrivate::initializeRasterizer(QSpanData *data)
     QRasterPaintEngineState *s = q->state();
 
     rasterizer->setAntialiased(s->flags.antialiased);
+    rasterizer->setLegacyRoundingEnabled(s->flags.legacy_rounding);
 
     QRect clipRect(deviceRect);
     ProcessSpans blend;
@@ -3484,6 +3504,7 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
 
     if (!s->flags.antialiased) {
         rasterizer->setAntialiased(s->flags.antialiased);
+        rasterizer->setLegacyRoundingEnabled(s->flags.legacy_rounding);
         rasterizer->setClipRect(deviceRect);
         rasterizer->initialize(callback, userData);
 
index e1beff0..8fb72ed 100644 (file)
@@ -110,6 +110,7 @@ public:
         uint non_complex_pen : 1;           // can use rasterizer, rather than stroker
         uint antialiased : 1;
         uint bilinear : 1;
+        uint legacy_rounding : 1;
         uint fast_text : 1;
         uint int_xform : 1;
         uint tx_noshear : 1;
@@ -246,6 +247,8 @@ private:
 
     bool setClipRectInDeviceCoords(const QRect &r, Qt::ClipOperation op);
 
+    QRect toNormalizedFillRect(const QRectF &rect);
+
     inline void ensureBrush(const QBrush &brush) {
         if (!qbrush_fast_equals(state()->lastBrush, brush) || (brush.style() != Qt::NoBrush && state()->fillFlags))
             updateBrush(brush);
index 02555b6..69267b2 100644 (file)
@@ -1421,6 +1421,11 @@ void QPainterPrivate::updateState(QPainterState *newState)
     of 0 (which otherwise enables QPen::isCosmetic()) as being a non-cosmetic
     pen with a width of 1.
 
+    \value Qt4CompatiblePainting Compatibility hint telling the engine to use the
+    same X11 based fill rules as in Qt 4, where aliased rendering is offset
+    by slightly less than half a pixel. Potentially useful when porting a
+    Qt 4 application to Qt 5.
+
     \sa renderHints(), setRenderHint(), {QPainter#Rendering
     Quality}{Rendering Quality}, {Concentric Circles Example}
 
index c6c0e39..a393b29 100644 (file)
@@ -94,7 +94,8 @@ public:
         TextAntialiasing = 0x02,
         SmoothPixmapTransform = 0x04,
         HighQualityAntialiasing = 0x08,
-        NonCosmeticDefaultPen = 0x10
+        NonCosmeticDefaultPen = 0x10,
+        Qt4CompatiblePainting = 0x20
     };
 
     Q_DECLARE_FLAGS(RenderHints, RenderHint)
index fca037b..e418f2c 100644 (file)
@@ -129,7 +129,7 @@ public:
     ~QScanConverter();
 
     void begin(int top, int bottom, int left, int right,
-               Qt::FillRule fillRule, QSpanBuffer *spanBuffer);
+               Qt::FillRule fillRule, bool legacyRounding, QSpanBuffer *spanBuffer);
     void end();
 
     void mergeCurve(const QT_FT_Vector &a, const QT_FT_Vector &b,
@@ -177,6 +177,7 @@ private:
     Q16Dot16 m_rightFP;
 
     int m_fillRuleMask;
+    bool m_legacyRounding;
 
     int m_x;
     int m_y;
@@ -196,6 +197,7 @@ class QRasterizerPrivate
 {
 public:
     bool antialiased;
+    bool legacyRounding;
     ProcessSpans blend;
     void *data;
     QRect clipRect;
@@ -219,7 +221,8 @@ QScanConverter::~QScanConverter()
 }
 
 void QScanConverter::begin(int top, int bottom, int left, int right,
-                           Qt::FillRule fillRule, QSpanBuffer *spanBuffer)
+                           Qt::FillRule fillRule, bool legacyRounding,
+                           QSpanBuffer *spanBuffer)
 {
     m_top = top;
     m_bottom = bottom;
@@ -229,6 +232,7 @@ void QScanConverter::begin(int top, int bottom, int left, int right,
     m_lines.reset();
 
     m_fillRuleMask = fillRule == Qt::WindingFill ? ~0x0 : 0x1;
+    m_legacyRounding = legacyRounding;
     m_spanBuffer = spanBuffer;
 }
 
@@ -595,16 +599,20 @@ void QScanConverter::mergeLine(QT_FT_Vector a, QT_FT_Vector b)
         winding = -1;
     }
 
-    a.x += COORD_OFFSET;
-    a.y += COORD_OFFSET;
-    b.x += COORD_OFFSET;
-    b.y += COORD_OFFSET;
+    if (m_legacyRounding) {
+        a.x += COORD_OFFSET;
+        a.y += COORD_OFFSET;
+        b.x += COORD_OFFSET;
+        b.y += COORD_OFFSET;
+    }
+
+    int rounding = m_legacyRounding ? COORD_ROUNDING : 0;
 
-    int iTop = qMax(m_top, int((a.y + 32 - COORD_ROUNDING) >> 6));
-    int iBottom = qMin(m_bottom, int((b.y - 32 - COORD_ROUNDING) >> 6));
+    int iTop = qMax(m_top, int((a.y + 32 - rounding) >> 6));
+    int iBottom = qMin(m_bottom, int((b.y - 32 - rounding) >> 6));
 
     if (iTop <= iBottom) {
-        Q16Dot16 aFP = Q16Dot16Factor/2 + (a.x << 10) - COORD_ROUNDING;
+        Q16Dot16 aFP = Q16Dot16Factor/2 + (a.x << 10) - rounding;
 
         if (b.x == a.x) {
             Line line = { qBound(m_leftFP, aFP, m_rightFP), 0, iTop, iBottom, winding };
@@ -635,6 +643,7 @@ void QScanConverter::mergeLine(QT_FT_Vector a, QT_FT_Vector b)
 QRasterizer::QRasterizer()
     : d(new QRasterizerPrivate)
 {
+    d->legacyRounding = false;
 }
 
 QRasterizer::~QRasterizer()
@@ -658,6 +667,11 @@ void QRasterizer::setClipRect(const QRect &clipRect)
     d->clipRect = clipRect;
 }
 
+void QRasterizer::setLegacyRoundingEnabled(bool legacyRoundingEnabled)
+{
+    d->legacyRounding = legacyRoundingEnabled;
+}
+
 static Q16Dot16 intersectPixelFP(int x, Q16Dot16 top, Q16Dot16 bottom, Q16Dot16 leftIntersectX, Q16Dot16 rightIntersectX, Q16Dot16 slope, Q16Dot16 invSlope)
 {
     Q16Dot16 leftX = IntToQ16Dot16(x);
@@ -775,7 +789,7 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
         pb = npb;
     }
 
-    if (!d->antialiased) {
+    if (!d->antialiased && d->legacyRounding) {
         pa.rx() += (COORD_OFFSET - COORD_ROUNDING)/64.;
         pa.ry() += (COORD_OFFSET - COORD_ROUNDING)/64.;
         pb.rx() += (COORD_OFFSET - COORD_ROUNDING)/64.;
@@ -1174,13 +1188,15 @@ void QRasterizer::rasterize(const QT_FT_Outline *outline, Qt::FillRule fillRule)
         max_y = qMax(p.y, max_y);
     }
 
-    int iTopBound = qMax(d->clipRect.top(), int((min_y + 32 + COORD_OFFSET - COORD_ROUNDING) >> 6));
-    int iBottomBound = qMin(d->clipRect.bottom(), int((max_y - 32 + COORD_OFFSET - COORD_ROUNDING) >> 6));
+    int rounding = d->legacyRounding ? COORD_OFFSET - COORD_ROUNDING : 0;
+
+    int iTopBound = qMax(d->clipRect.top(), int((min_y + 32 + rounding) >> 6));
+    int iBottomBound = qMin(d->clipRect.bottom(), int((max_y - 32 + rounding) >> 6));
 
     if (iTopBound > iBottomBound)
         return;
 
-    d->scanConverter.begin(iTopBound, iBottomBound, d->clipRect.left(), d->clipRect.right(), fillRule, &buffer);
+    d->scanConverter.begin(iTopBound, iBottomBound, d->clipRect.left(), d->clipRect.right(), fillRule, d->legacyRounding, &buffer);
 
     int first = 0;
     for (int i = 0; i < outline->n_contours; ++i) {
@@ -1210,13 +1226,15 @@ void QRasterizer::rasterize(const QPainterPath &path, Qt::FillRule fillRule)
 
     QRectF bounds = path.controlPointRect();
 
-    int iTopBound = qMax(d->clipRect.top(), int(bounds.top() + 0.5 + (COORD_OFFSET - COORD_ROUNDING)/64.));
-    int iBottomBound = qMin(d->clipRect.bottom(), int(bounds.bottom() - 0.5 + (COORD_OFFSET - COORD_ROUNDING)/64.));
+    double rounding = d->legacyRounding ? (COORD_OFFSET - COORD_ROUNDING) / 64. : 0.0;
+
+    int iTopBound = qMax(d->clipRect.top(), int(bounds.top() + 0.5 + rounding));
+    int iBottomBound = qMin(d->clipRect.bottom(), int(bounds.bottom() - 0.5 + rounding));
 
     if (iTopBound > iBottomBound)
         return;
 
-    d->scanConverter.begin(iTopBound, iBottomBound, d->clipRect.left(), d->clipRect.right(), fillRule, &buffer);
+    d->scanConverter.begin(iTopBound, iBottomBound, d->clipRect.left(), d->clipRect.right(), fillRule, d->legacyRounding, &buffer);
 
     int subpathStart = 0;
     QT_FT_Vector last = { 0, 0 };
index 48e9982..f535db8 100644 (file)
@@ -74,6 +74,7 @@ public:
 
     void setAntialiased(bool antialiased);
     void setClipRect(const QRect &clipRect);
+    void setLegacyRoundingEnabled(bool legacyRoundingEnabled);
 
     void initialize(ProcessSpans blend, void *data);
 
index e6e2e75..4dd92c1 100644 (file)
@@ -174,7 +174,10 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q
         if (opt->state & (State_Sunken | State_On)) {
             ir.adjust(2, 2, -2, -2);
             p->setBrush(opt->palette.foreground());
+            bool oldQt4CompatiblePainting = p->testRenderHint(QPainter::Qt4CompatiblePainting);
+            p->setRenderHint(QPainter::Qt4CompatiblePainting);
             p->drawEllipse(ir);
+            p->setRenderHint(QPainter::Qt4CompatiblePainting, oldQt4CompatiblePainting);
         }
         break; }
     case PE_FrameFocusRect:
@@ -530,6 +533,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q
         p->translate(sx + bsx, sy + bsy);
         p->setPen(opt->palette.buttonText().color());
         p->setBrush(opt->palette.buttonText());
+        p->setRenderHint(QPainter::Qt4CompatiblePainting);
         p->drawPolygon(a);
         p->restore();
         break; }
@@ -1579,7 +1583,10 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
             }
 
             p->setPen(tb->palette.mid().color().darker(150));
+            bool oldQt4CompatiblePainting = p->testRenderHint(QPainter::Qt4CompatiblePainting);
+            p->setRenderHint(QPainter::Qt4CompatiblePainting);
             p->drawPolygon(a);
+            p->setRenderHint(QPainter::Qt4CompatiblePainting, oldQt4CompatiblePainting);
             p->setPen(tb->palette.light().color());
             if (tb->direction != Qt::RightToLeft) {
                 p->drawLine(0, 2, tb->rect.width() - d, 2);
@@ -3487,6 +3494,7 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl
 
             p->setPen(Qt::NoPen);
             p->setBrush(pal.button());
+            p->setRenderHint(QPainter::Qt4CompatiblePainting);
             p->drawPolygon(arrow);
 
             a = QStyleHelper::angle(QPointF(width / 2, height / 2), arrow[0]);
index 4df68a7..9e5e65d 100644 (file)
@@ -1243,6 +1243,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
                 imagePainter.translate(sx + bsx, sy + bsy);
                 imagePainter.setPen(opt->palette.buttonText().color());
                 imagePainter.setBrush(opt->palette.buttonText());
+                imagePainter.setRenderHint(QPainter::Qt4CompatiblePainting);
 
                 if (!(opt->state & State_Enabled)) {
                     imagePainter.translate(1, 1);
@@ -1381,6 +1382,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
             }
 
             p->save();
+            p->setRenderHint(QPainter::Qt4CompatiblePainting);
             bool down = opt->state & State_Sunken;
             bool enabled = opt->state & State_Enabled;
             bool on = opt->state & State_On;
@@ -2487,8 +2489,10 @@ void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComp
                 }
 
                 QBrush oldBrush = p->brush();
+                bool oldQt4CompatiblePainting = p->testRenderHint(QPainter::Qt4CompatiblePainting);
                 p->setPen(Qt::NoPen);
                 p->setBrush(handleBrush);
+                p->setRenderHint(QPainter::Qt4CompatiblePainting);
                 Qt::BGMode oldMode = p->backgroundMode();
                 p->setBackgroundMode(Qt::OpaqueMode);
                 p->drawRect(x1, y1, x2-x1+1, y2-y1+1);
@@ -2571,6 +2575,7 @@ void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComp
                     p->drawLine(x2, y2-1, x2+d, y2-1-d);
                     break;
                 }
+                p->setRenderHint(QPainter::Qt4CompatiblePainting, oldQt4CompatiblePainting);
             }
         }
         break;
index 1371694..24be319 100644 (file)
@@ -830,6 +830,7 @@ void tst_QPainter::drawLine()
     { // unclipped
         pixmapUnclipped.fill(Qt::white);
         QPainter p(&pixmapUnclipped);
+        p.setRenderHint(QPainter::Qt4CompatiblePainting);
         p.translate(offset, offset);
         p.setPen(QPen(Qt::black));
         p.drawLine(line);
@@ -856,6 +857,7 @@ void tst_QPainter::drawLine()
 
         pixmapClipped.fill(Qt::white);
         QPainter p(&pixmapClipped);
+        p.setRenderHint(QPainter::Qt4CompatiblePainting);
         p.translate(offset, offset);
         p.setClipRect(clip);
         p.setPen(QPen(Qt::black));
@@ -892,6 +894,7 @@ void tst_QPainter::drawLine_task121143()
     image.fill(0xffffffff);
     QPainter p(&image);
     p.setPen(pen);
+    p.setRenderHint(QPainter::Qt4CompatiblePainting);
     p.drawLine(QLine(0, 0+4, 0+4, 0));
     p.end();
 
@@ -1028,6 +1031,7 @@ void tst_QPainter::drawRect2()
         QTransform transform(0.368567, 0, 0, 0, 0.368567, 0, 0.0289, 0.0289, 1);
 
         QPainter p(&image);
+        p.setRenderHint(QPainter::Qt4CompatiblePainting);
         p.setTransform(transform);
         p.setBrush(Qt::red);
         p.setPen(Qt::NoPen);
@@ -1038,6 +1042,7 @@ void tst_QPainter::drawRect2()
         image.fill(0xffffffff);
 
         p.begin(&image);
+        p.setRenderHint(QPainter::Qt4CompatiblePainting);
         p.setTransform(transform);
         p.drawRect(QRect(14, 14, 39, 39));
         p.end();
@@ -1184,6 +1189,7 @@ void tst_QPainter::drawPath()
     image.fill(QColor(Qt::white).rgb());
 
     QPainter p(&image);
+    p.setRenderHint(QPainter::Qt4CompatiblePainting);
     p.setPen(Qt::NoPen);
     p.setBrush(Qt::black);
     p.translate(offset - expectedBounds.left(), offset - expectedBounds.top());
@@ -1246,11 +1252,7 @@ void tst_QPainter::drawPath2()
 
 void tst_QPainter::drawPath3()
 {
-#if !defined(Q_OS_WINCE)
-    QImage imgA(400, 400, QImage::Format_RGB32);
-#else
     QImage imgA(100, 100, QImage::Format_RGB32);
-#endif
     imgA.fill(0xffffff);
     QImage imgB = imgA;
 
@@ -1413,6 +1415,7 @@ void tst_QPainter::drawRoundRect()
     {
         pixmap.fill(Qt::white);
         QPainter p(&pixmap);
+        p.setRenderHint(QPainter::Qt4CompatiblePainting);
         p.setPen(usePen ? QPen(Qt::black) : QPen(Qt::NoPen));
         p.setBrush(Qt::black);
         p.drawRoundRect(rect);
@@ -4185,6 +4188,7 @@ void tst_QPainter::drawText_subPixelPositionsInRaster_qtbug5053()
     baseLine.fill(Qt::white);
     {
         QPainter p(&baseLine);
+        p.setRenderHint(QPainter::Qt4CompatiblePainting);
         p.drawText(0, fm.ascent(), QString::fromLatin1("e"));
     }
 
@@ -4195,6 +4199,7 @@ void tst_QPainter::drawText_subPixelPositionsInRaster_qtbug5053()
 
         {
             QPainter p(&comparison);
+            p.setRenderHint(QPainter::Qt4CompatiblePainting);
             p.drawText(QPointF(i / 12.0, fm.ascent()), QString::fromLatin1("e"));
         }