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:
the existent image data will be invalidated, so that isNull() is guaranteed
to return true in this case.
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.
QtWidgets
---------
* QInputContext removed as well as related getters and setters on QWidget and QApplication.
if (clipLine(rx1, ry1, rx2, ry2))
return;
if (clipLine(rx1, ry1, rx2, ry2))
return;
+ const int half = legacyRounding ? 31 : 0;
int x1 = toF26Dot6(rx1) + half;
int y1 = toF26Dot6(ry1) + half;
int x2 = toF26Dot6(rx2) + half;
int x1 = toF26Dot6(rx1) + half;
int y1 = toF26Dot6(ry1) + half;
int x2 = toF26Dot6(rx2) + half;
if (stroker->clipLine(rx1, ry1, rx2, ry2))
return;
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;
int x1 = toF26Dot6(rx1) + half;
int y1 = toF26Dot6(ry1) + half;
int x2 = toF26Dot6(rx2) + half;
patternSize(0),
patternLength(0),
patternOffset(0),
patternSize(0),
patternLength(0),
patternOffset(0),
current_span(0),
lastDir(LeftToRight),
lastAxisAligned(false)
{ setup(); }
current_span(0),
lastDir(LeftToRight),
lastAxisAligned(false)
{ setup(); }
~QCosmeticStroker() { free(pattern); free(reversePattern); }
~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);
void drawLine(const QPointF &p1, const QPointF &p2);
void drawPath(const QVectorPath &path);
void drawPoints(const QPoint *points, int num);
int patternLength;
int patternOffset;
int patternLength;
int patternOffset;
enum { NSPANS = 255 };
QT_FT_Span spans[NSPANS];
int current_span;
enum { NSPANS = 255 };
QT_FT_Span spans[NSPANS];
int current_span;
painter->setRenderHint(QPainter::SmoothPixmapTransform, nh & QPainter::SmoothPixmapTransform);
if (xored & QPainter::NonCosmeticDefaultPen)
painter->setRenderHint(QPainter::NonCosmeticDefaultPen, nh & QPainter::NonCosmeticDefaultPen);
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: {
break; }
case QPaintBufferPrivate::Cmd_SetOpacity: {
flags.fast_pen = true;
flags.antialiased = false;
flags.bilinear = false;
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;
flags.fast_text = true;
flags.int_xform = true;
flags.tx_noshear = true;
s->flags.antialiased = bool(s->renderHints & QPainter::Antialiasing);
s->flags.bilinear = bool(s->renderHints & QPainter::SmoothPixmapTransform);
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;
if (was_aa != s->flags.antialiased)
s->strokeFlags |= DirtyHints;
QRectVectorPath path;
if (s->flags.fast_pen) {
QCosmeticStroker stroker(s, d->deviceRect);
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);
for (int i = 0; i < rectCount; ++i) {
path.set(rects[i]);
stroker.drawPath(path);
QRectVectorPath path;
if (s->flags.fast_pen) {
QCosmeticStroker stroker(s, d->deviceRect);
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);
for (int i = 0; i < rectCount; ++i) {
path.set(rects[i]);
stroker.drawPath(path);
if (s->flags.fast_pen) {
QCosmeticStroker stroker(s, d->deviceRect);
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()
stroker.drawPath(path);
} else if (s->flags.non_complex_pen && path.shape() == QVectorPath::LinesHint) {
qreal width = s->lastPen.isCosmetic()
QPaintEngineEx::stroke(path, 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);
if (x2 < x1)
qSwap(x1, x2);
QVectorPath vp((qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode));
if (s->flags.fast_pen) {
QCosmeticStroker stroker(s, d->deviceRect);
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);
stroker.drawPath(vp);
} else {
QPaintEngineEx::stroke(vp, s->lastPen);
if (s->flags.fast_pen) {
QCosmeticStroker stroker(s, d->deviceRect);
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);
stroker.drawPath(vp);
} else {
QPaintEngineEx::stroke(vp, s->lastPen);
// 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;
// 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);
// Do whatever fillRect() does, but without premultiplying the color if it's already premultiplied.
QRgb color = img.pixel(sr_l, sr_t);
if (s->flags.tx_noshear || s->matrix.type() == QTransform::TxScale) {
d->initializeRasterizer(&d->image_filler_xform);
d->rasterizer->setAntialiased(s->flags.antialiased);
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;
const QRectF &rect = r.normalized();
const QPointF a = s->matrix.map((rect.topLeft() + rect.bottomLeft()) * 0.5f) - offs;
- 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;
QPainterPath path;
path.addRect(r);
QTransform m = s->matrix;
if (s->flags.tx_noshear || s->matrix.type() == QTransform::TxScale) {
d->initializeRasterizer(&d->image_filler_xform);
d->rasterizer->setAntialiased(s->flags.antialiased);
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);
const QRectF &rect = r.normalized();
const QPointF a = s->matrix.map((rect.topLeft() + rect.bottomLeft()) * 0.5f);
rightShift = 3; // divide by 8
int margin = fontEngine->glyphMargin(glyphType);
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) {
const uchar *bits = image.bits();
for (int i=0; i<numGlyphs; ++i) {
}
QCosmeticStroker stroker(s, d->deviceRect);
}
QCosmeticStroker stroker(s, d->deviceRect);
+ stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
stroker.drawPoints(points, pointCount);
}
stroker.drawPoints(points, pointCount);
}
}
QCosmeticStroker stroker(s, d->deviceRect);
}
QCosmeticStroker stroker(s, d->deviceRect);
+ stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
stroker.drawPoints(points, pointCount);
}
stroker.drawPoints(points, pointCount);
}
if (s->flags.fast_pen) {
QCosmeticStroker stroker(s, d->deviceRect);
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());
for (int i=0; i<lineCount; ++i) {
const QLine &l = lines[i];
stroker.drawLine(l.p1(), l.p2());
return;
if (s->flags.fast_pen) {
QCosmeticStroker stroker(s, d->deviceRect);
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());
for (int i=0; i<lineCount; ++i) {
QLineF line = lines[i];
stroker.drawLine(line.p1(), line.p2());
QRasterPaintEngineState *s = q->state();
rasterizer->setAntialiased(s->flags.antialiased);
QRasterPaintEngineState *s = q->state();
rasterizer->setAntialiased(s->flags.antialiased);
+ rasterizer->setLegacyRoundingEnabled(s->flags.legacy_rounding);
QRect clipRect(deviceRect);
ProcessSpans blend;
QRect clipRect(deviceRect);
ProcessSpans blend;
if (!s->flags.antialiased) {
rasterizer->setAntialiased(s->flags.antialiased);
if (!s->flags.antialiased) {
rasterizer->setAntialiased(s->flags.antialiased);
+ rasterizer->setLegacyRoundingEnabled(s->flags.legacy_rounding);
rasterizer->setClipRect(deviceRect);
rasterizer->initialize(callback, userData);
rasterizer->setClipRect(deviceRect);
rasterizer->initialize(callback, userData);
uint non_complex_pen : 1; // can use rasterizer, rather than stroker
uint antialiased : 1;
uint bilinear : 1;
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;
uint fast_text : 1;
uint int_xform : 1;
uint tx_noshear : 1;
bool setClipRectInDeviceCoords(const QRect &r, Qt::ClipOperation op);
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);
inline void ensureBrush(const QBrush &brush) {
if (!qbrush_fast_equals(state()->lastBrush, brush) || (brush.style() != Qt::NoBrush && state()->fillFlags))
updateBrush(brush);
of 0 (which otherwise enables QPen::isCosmetic()) as being a non-cosmetic
pen with a width of 1.
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}
\sa renderHints(), setRenderHint(), {QPainter#Rendering
Quality}{Rendering Quality}, {Concentric Circles Example}
TextAntialiasing = 0x02,
SmoothPixmapTransform = 0x04,
HighQualityAntialiasing = 0x08,
TextAntialiasing = 0x02,
SmoothPixmapTransform = 0x04,
HighQualityAntialiasing = 0x08,
- NonCosmeticDefaultPen = 0x10
+ NonCosmeticDefaultPen = 0x10,
+ Qt4CompatiblePainting = 0x20
};
Q_DECLARE_FLAGS(RenderHints, RenderHint)
};
Q_DECLARE_FLAGS(RenderHints, RenderHint)
~QScanConverter();
void begin(int top, int bottom, int left, int right,
~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,
void end();
void mergeCurve(const QT_FT_Vector &a, const QT_FT_Vector &b,
Q16Dot16 m_rightFP;
int m_fillRuleMask;
Q16Dot16 m_rightFP;
int m_fillRuleMask;
{
public:
bool antialiased;
{
public:
bool antialiased;
ProcessSpans blend;
void *data;
QRect clipRect;
ProcessSpans blend;
void *data;
QRect clipRect;
}
void QScanConverter::begin(int top, int bottom, int left, int right,
}
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;
{
m_top = top;
m_bottom = bottom;
m_lines.reset();
m_fillRuleMask = fillRule == Qt::WindingFill ? ~0x0 : 0x1;
m_lines.reset();
m_fillRuleMask = fillRule == Qt::WindingFill ? ~0x0 : 0x1;
+ m_legacyRounding = legacyRounding;
m_spanBuffer = spanBuffer;
}
m_spanBuffer = spanBuffer;
}
- 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));
- 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 };
if (b.x == a.x) {
Line line = { qBound(m_leftFP, aFP, m_rightFP), 0, iTop, iBottom, winding };
QRasterizer::QRasterizer()
: d(new QRasterizerPrivate)
{
QRasterizer::QRasterizer()
: d(new QRasterizerPrivate)
{
+ d->legacyRounding = false;
}
QRasterizer::~QRasterizer()
}
QRasterizer::~QRasterizer()
d->clipRect = 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);
static Q16Dot16 intersectPixelFP(int x, Q16Dot16 top, Q16Dot16 bottom, Q16Dot16 leftIntersectX, Q16Dot16 rightIntersectX, Q16Dot16 slope, Q16Dot16 invSlope)
{
Q16Dot16 leftX = IntToQ16Dot16(x);
+ 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.;
pa.rx() += (COORD_OFFSET - COORD_ROUNDING)/64.;
pa.ry() += (COORD_OFFSET - COORD_ROUNDING)/64.;
pb.rx() += (COORD_OFFSET - COORD_ROUNDING)/64.;
max_y = qMax(p.y, max_y);
}
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;
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) {
int first = 0;
for (int i = 0; i < outline->n_contours; ++i) {
QRectF bounds = path.controlPointRect();
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;
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 };
int subpathStart = 0;
QT_FT_Vector last = { 0, 0 };
void setAntialiased(bool antialiased);
void setClipRect(const QRect &clipRect);
void setAntialiased(bool antialiased);
void setClipRect(const QRect &clipRect);
+ void setLegacyRoundingEnabled(bool legacyRoundingEnabled);
void initialize(ProcessSpans blend, void *data);
void initialize(ProcessSpans blend, void *data);
if (opt->state & (State_Sunken | State_On)) {
ir.adjust(2, 2, -2, -2);
p->setBrush(opt->palette.foreground());
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->setRenderHint(QPainter::Qt4CompatiblePainting, oldQt4CompatiblePainting);
}
break; }
case PE_FrameFocusRect:
}
break; }
case PE_FrameFocusRect:
p->translate(sx + bsx, sy + bsy);
p->setPen(opt->palette.buttonText().color());
p->setBrush(opt->palette.buttonText());
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; }
p->drawPolygon(a);
p->restore();
break; }
}
p->setPen(tb->palette.mid().color().darker(150));
}
p->setPen(tb->palette.mid().color().darker(150));
+ bool oldQt4CompatiblePainting = p->testRenderHint(QPainter::Qt4CompatiblePainting);
+ p->setRenderHint(QPainter::Qt4CompatiblePainting);
+ 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);
p->setPen(tb->palette.light().color());
if (tb->direction != Qt::RightToLeft) {
p->drawLine(0, 2, tb->rect.width() - d, 2);
p->setPen(Qt::NoPen);
p->setBrush(pal.button());
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]);
p->drawPolygon(arrow);
a = QStyleHelper::angle(QPointF(width / 2, height / 2), arrow[0]);
imagePainter.translate(sx + bsx, sy + bsy);
imagePainter.setPen(opt->palette.buttonText().color());
imagePainter.setBrush(opt->palette.buttonText());
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);
if (!(opt->state & State_Enabled)) {
imagePainter.translate(1, 1);
+ p->setRenderHint(QPainter::Qt4CompatiblePainting);
bool down = opt->state & State_Sunken;
bool enabled = opt->state & State_Enabled;
bool on = opt->state & State_On;
bool down = opt->state & State_Sunken;
bool enabled = opt->state & State_Enabled;
bool on = opt->state & State_On;
}
QBrush oldBrush = p->brush();
}
QBrush oldBrush = p->brush();
+ bool oldQt4CompatiblePainting = p->testRenderHint(QPainter::Qt4CompatiblePainting);
p->setPen(Qt::NoPen);
p->setBrush(handleBrush);
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);
Qt::BGMode oldMode = p->backgroundMode();
p->setBackgroundMode(Qt::OpaqueMode);
p->drawRect(x1, y1, x2-x1+1, y2-y1+1);
p->drawLine(x2, y2-1, x2+d, y2-1-d);
break;
}
p->drawLine(x2, y2-1, x2+d, y2-1-d);
break;
}
+ p->setRenderHint(QPainter::Qt4CompatiblePainting, oldQt4CompatiblePainting);
{ // unclipped
pixmapUnclipped.fill(Qt::white);
QPainter p(&pixmapUnclipped);
{ // unclipped
pixmapUnclipped.fill(Qt::white);
QPainter p(&pixmapUnclipped);
+ p.setRenderHint(QPainter::Qt4CompatiblePainting);
p.translate(offset, offset);
p.setPen(QPen(Qt::black));
p.drawLine(line);
p.translate(offset, offset);
p.setPen(QPen(Qt::black));
p.drawLine(line);
pixmapClipped.fill(Qt::white);
QPainter p(&pixmapClipped);
pixmapClipped.fill(Qt::white);
QPainter p(&pixmapClipped);
+ p.setRenderHint(QPainter::Qt4CompatiblePainting);
p.translate(offset, offset);
p.setClipRect(clip);
p.setPen(QPen(Qt::black));
p.translate(offset, offset);
p.setClipRect(clip);
p.setPen(QPen(Qt::black));
image.fill(0xffffffff);
QPainter p(&image);
p.setPen(pen);
image.fill(0xffffffff);
QPainter p(&image);
p.setPen(pen);
+ p.setRenderHint(QPainter::Qt4CompatiblePainting);
p.drawLine(QLine(0, 0+4, 0+4, 0));
p.end();
p.drawLine(QLine(0, 0+4, 0+4, 0));
p.end();
QTransform transform(0.368567, 0, 0, 0, 0.368567, 0, 0.0289, 0.0289, 1);
QPainter p(&image);
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);
p.setTransform(transform);
p.setBrush(Qt::red);
p.setPen(Qt::NoPen);
image.fill(0xffffffff);
p.begin(&image);
image.fill(0xffffffff);
p.begin(&image);
+ p.setRenderHint(QPainter::Qt4CompatiblePainting);
p.setTransform(transform);
p.drawRect(QRect(14, 14, 39, 39));
p.end();
p.setTransform(transform);
p.drawRect(QRect(14, 14, 39, 39));
p.end();
image.fill(QColor(Qt::white).rgb());
QPainter p(&image);
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());
p.setPen(Qt::NoPen);
p.setBrush(Qt::black);
p.translate(offset - expectedBounds.left(), offset - expectedBounds.top());
void tst_QPainter::drawPath3()
{
void tst_QPainter::drawPath3()
{
-#if !defined(Q_OS_WINCE)
- QImage imgA(400, 400, QImage::Format_RGB32);
-#else
QImage imgA(100, 100, QImage::Format_RGB32);
QImage imgA(100, 100, QImage::Format_RGB32);
imgA.fill(0xffffff);
QImage imgB = imgA;
imgA.fill(0xffffff);
QImage imgB = imgA;
{
pixmap.fill(Qt::white);
QPainter p(&pixmap);
{
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);
p.setPen(usePen ? QPen(Qt::black) : QPen(Qt::NoPen));
p.setBrush(Qt::black);
p.drawRoundRect(rect);
baseLine.fill(Qt::white);
{
QPainter p(&baseLine);
baseLine.fill(Qt::white);
{
QPainter p(&baseLine);
+ p.setRenderHint(QPainter::Qt4CompatiblePainting);
p.drawText(0, fm.ascent(), QString::fromLatin1("e"));
}
p.drawText(0, fm.ascent(), QString::fromLatin1("e"));
}
{
QPainter p(&comparison);
{
QPainter p(&comparison);
+ p.setRenderHint(QPainter::Qt4CompatiblePainting);
p.drawText(QPointF(i / 12.0, fm.ascent()), QString::fromLatin1("e"));
}
p.drawText(QPointF(i / 12.0, fm.ascent()), QString::fromLatin1("e"));
}