Fixed inconsistent QPainter fill rules for aliased painting.
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>
This commit is contained in:
parent
ae3ad0ad21
commit
7b8e10ddd0
9
dist/changes-5.0.0
vendored
9
dist/changes-5.0.0
vendored
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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: {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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}
|
||||
|
||||
|
@ -94,7 +94,8 @@ public:
|
||||
TextAntialiasing = 0x02,
|
||||
SmoothPixmapTransform = 0x04,
|
||||
HighQualityAntialiasing = 0x08,
|
||||
NonCosmeticDefaultPen = 0x10
|
||||
NonCosmeticDefaultPen = 0x10,
|
||||
Qt4CompatiblePainting = 0x20
|
||||
};
|
||||
|
||||
Q_DECLARE_FLAGS(RenderHints, RenderHint)
|
||||
|
@ -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 iTop = qMax(m_top, int((a.y + 32 - COORD_ROUNDING) >> 6));
|
||||
int iBottom = qMin(m_bottom, int((b.y - 32 - COORD_ROUNDING) >> 6));
|
||||
int rounding = m_legacyRounding ? COORD_ROUNDING : 0;
|
||||
|
||||
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 };
|
||||
|
@ -74,6 +74,7 @@ public:
|
||||
|
||||
void setAntialiased(bool antialiased);
|
||||
void setClipRect(const QRect &clipRect);
|
||||
void setLegacyRoundingEnabled(bool legacyRoundingEnabled);
|
||||
|
||||
void initialize(ProcessSpans blend, void *data);
|
||||
|
||||
|
@ -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]);
|
||||
|
@ -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;
|
||||
|
@ -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"));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user