From e032708773086d3acf3af2983ea5dc8eece8aeb5 Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Mon, 13 May 2019 20:01:54 +0000 Subject: [PATCH] get rid of aliased coordinate delta Signed-off-by: Ivailo Monev --- src/gui/painting/qpaintengine_raster.cpp | 26 ++++++-------- src/gui/painting/qpaintengine_x11.cpp | 44 ++++++++++-------------- src/gui/painting/qpaintengine_x11_p.h | 7 ---- src/gui/painting/qrasterizer.cpp | 29 ++++------------ src/gui/qguicommon_p.h | 3 -- 5 files changed, 35 insertions(+), 74 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index b9d523654..5fd1a200f 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1433,10 +1433,10 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen) static inline QRect 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); + int x1 = qRound(rect.x()); + int y1 = qRound(rect.y()); + int x2 = qRound(rect.right()); + int y2 = qRound(rect.bottom()); if (x2 < x1) qSwap(x1, x2); @@ -1875,7 +1875,6 @@ 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); // Do whatever fillRect() does, but without premultiplying the color if it's already premultiplied. QRgb color = img.pixel(sr_l, sr_t); @@ -1949,11 +1948,9 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe d->initializeRasterizer(&d->image_filler_xform); d->rasterizer->setAntialiased(s->flags.antialiased); - const QPointF offs = s->flags.antialiased ? QPointF() : QPointF(aliasedCoordinateDelta, aliasedCoordinateDelta); - const QRectF &rect = r.normalized(); - const QPointF a = s->matrix.map((rect.topLeft() + rect.bottomLeft()) * 0.5f) - offs; - const QPointF b = s->matrix.map((rect.topRight() + rect.bottomRight()) * 0.5f) - offs; + const QPointF a = s->matrix.map((rect.topLeft() + rect.bottomLeft()) * 0.5f); + const QPointF b = s->matrix.map((rect.topRight() + rect.bottomRight()) * 0.5f); if (s->flags.tx_noshear) d->rasterizer->rasterizeLine(a, b, rect.height() / rect.width()); @@ -1962,13 +1959,12 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe return; } #endif - const qreal offs = s->flags.antialiased ? qreal(0) : aliasedCoordinateDelta; QPainterPath path; path.addRect(r); QTransform m = s->matrix; s->matrix = QTransform(m.m11(), m.m12(), m.m13(), m.m21(), m.m22(), m.m23(), - m.m31() - offs, m.m32() - offs, m.m33()); + m.m31(), m.m32(), m.m33()); fillPath(path, &d->image_filler_xform); s->matrix = m; } else { @@ -2297,11 +2293,9 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, { Q_D(QRasterPaintEngine); QRasterPaintEngineState *s = state(); - const QFixed offs = QFixed::fromReal(aliasedCoordinateDelta); if (fontEngine->type() == QFontEngine::Freetype) { QFontEngineFT *fe = static_cast(fontEngine); - const QFixed xOffs = fe->supportsSubPixelPositions() ? 0 : offs; QFontEngineFT::GlyphFormat neededFormat = painter()->device()->devType() == QInternal::Widget ? fe->defaultGlyphFormat() @@ -2375,8 +2369,8 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, }; alphaPenBlt(glyph->data, pitch, depth, - qFloor(positions[i].x + xOffs) + glyph->x, - qFloor(positions[i].y + offs) - glyph->y, + qFloor(positions[i].x) + glyph->x, + qFloor(positions[i].y) - glyph->y, glyph->width, glyph->height); } if (lockedFace) @@ -2418,7 +2412,7 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, continue; int x = qFloor(positions[i].x) + c.baseLineX - margin; - int y = qFloor(positions[i].y + offs) - c.baseLineY - margin; + int y = qFloor(positions[i].y) - c.baseLineY - margin; // printf("drawing [%d %d %d %d] baseline [%d %d], glyph: %d, to: %d %d, pos: %d %d\n", // c.x, c.y, diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index bdc15ebca..77465aa39 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -664,10 +664,10 @@ void QX11PaintEngine::drawLines(const QLine *lines, int lineCount) linef = d->matrix.map(QLineF(lines[i])); } if (clipLine(&linef, d->polygonClipper.boundingRect())) { - int x1 = qRound(linef.x1() + aliasedCoordinateDelta); - int y1 = qRound(linef.y1() + aliasedCoordinateDelta); - int x2 = qRound(linef.x2() + aliasedCoordinateDelta); - int y2 = qRound(linef.y2() + aliasedCoordinateDelta); + int x1 = qRound(linef.x1()); + int y1 = qRound(linef.y1()); + int x2 = qRound(linef.x2()); + int y2 = qRound(linef.y2()); XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2); } @@ -698,10 +698,10 @@ void QX11PaintEngine::drawLines(const QLineF *lines, int lineCount) for (int i = 0; i < lineCount; ++i) { QLineF linef = d->matrix.map(lines[i]); if (clipLine(&linef, d->polygonClipper.boundingRect())) { - int x1 = qRound(linef.x1() + aliasedCoordinateDelta); - int y1 = qRound(linef.y1() + aliasedCoordinateDelta); - int x2 = qRound(linef.x2() + aliasedCoordinateDelta); - int y2 = qRound(linef.y2() + aliasedCoordinateDelta); + int x1 = qRound(linef.x1()); + int y1 = qRound(linef.y1()); + int x2 = qRound(linef.x2()); + int y2 = qRound(linef.y2()); XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2); } @@ -1127,7 +1127,6 @@ void QX11PaintEngine::updateState(const QPaintEngineState &state) XSetFunction(qt_x11Data->display, d->gc_brush, function); } d->decidePathFallback(); - d->decideCoordAdjust(); } void QX11PaintEngine::updateRenderHints(QPainter::RenderHints hints) @@ -1483,15 +1482,11 @@ void QX11PaintEnginePrivate::fillPolygon_translated(const QPointF *polygonPoints QVarLengthArray translated_points(pointCount); QPointF offset(matrix.dx(), matrix.dy()); - qreal offs = adjust_coords ? aliasedCoordinateDelta : 0.0; - if (!qt_x11Data->use_xrender || !(render_hints & QPainter::Antialiasing)) - offset += QPointF(aliasedCoordinateDelta, aliasedCoordinateDelta); - for (int i = 0; i < pointCount; ++i) { translated_points[i] = polygonPoints[i] + offset; - translated_points[i].rx() = qRound(translated_points[i].x()) + offs; - translated_points[i].ry() = qRound(translated_points[i].y()) + offs; + translated_points[i].rx() = qRound(translated_points[i].x()); + translated_points[i].ry() = qRound(translated_points[i].y()); } fillPolygon_dev(translated_points.data(), pointCount, gcMode, mode); @@ -1662,8 +1657,8 @@ void QX11PaintEnginePrivate::strokePolygon_dev(const QPointF *polygonPoints, int if (clippedCount > 0) { QVarLengthArray xpoints(clippedCount); for (int i = 0; i < clippedCount; ++i) { - xpoints[i].x = qRound(clippedPoints[i].x + aliasedCoordinateDelta); - xpoints[i].y = qRound(clippedPoints[i].y + aliasedCoordinateDelta); + xpoints[i].x = qRound(clippedPoints[i].x); + xpoints[i].y = qRound(clippedPoints[i].y); } uint numberPoints = qMin(clippedCount, xlibMaxLinePoints); XPoint *pts = xpoints.data(); @@ -1710,8 +1705,6 @@ void QX11PaintEngine::drawPolygon(const QPointF *polygonPoints, int pointCount, void QX11PaintEnginePrivate::fillPath(const QPainterPath &path, QX11PaintEnginePrivate::GCMode gc_mode, bool transform) { - qreal offs = adjust_coords ? aliasedCoordinateDelta : 0.0; - QPainterPath clippedPath; QPainterPath clipPath; clipPath.addRect(polygonClipper.boundingRect()); @@ -1728,8 +1721,8 @@ void QX11PaintEnginePrivate::fillPath(const QPainterPath &path, QX11PaintEngineP for (int j = 0; j < polys.at(i).size(); ++j) { translated_points[j] = polys.at(i).at(j); if (!qt_x11Data->use_xrender || !(render_hints & QPainter::Antialiasing)) { - translated_points[j].rx() = qRound(translated_points[j].rx() + aliasedCoordinateDelta) + offs; - translated_points[j].ry() = qRound(translated_points[j].ry() + aliasedCoordinateDelta) + offs; + translated_points[j].rx() = qRound(translated_points[j].rx()); + translated_points[j].ry() = qRound(translated_points[j].ry()); } } @@ -2343,14 +2336,13 @@ void QX11PaintEngine::drawFreetype(const QPointF &p, const QTextItemInt &ti) QFixed xp = positions[i - 1].x; QFixed yp = positions[i - 1].y; - QFixed offs = QFixed::fromReal(aliasedCoordinateDelta); XGlyphElt32 elt; elt.glyphset = glyphSet; elt.chars = &glyphs[i - 1]; elt.nchars = 1; - elt.xOff = qRound(xp + offs); - elt.yOff = qRound(yp + offs); + elt.xOff = qRound(xp); + elt.yOff = qRound(yp); for (; i < glyphs.size(); ++i) { if (positions[i].x < t_min || positions[i].x > t_max || positions[i].y < t_min || positions[i].y > t_max) { @@ -2374,8 +2366,8 @@ void QX11PaintEngine::drawFreetype(const QPointF &p, const QTextItemInt &ti) &elt, 1); elt.chars = &glyphs[i]; elt.nchars = 1; - elt.xOff = qRound(xp + offs); - elt.yOff = qRound(yp + offs); + elt.xOff = qRound(xp); + elt.yOff = qRound(yp); } } XRenderCompositeText32(qt_x11Data->display, PictOpOver, src, d->picture, diff --git a/src/gui/painting/qpaintengine_x11_p.h b/src/gui/painting/qpaintengine_x11_p.h index 777ab8ea5..875bfb8fd 100644 --- a/src/gui/painting/qpaintengine_x11_p.h +++ b/src/gui/painting/qpaintengine_x11_p.h @@ -177,12 +177,6 @@ public: || has_complex_xform || (render_hints & QPainter::Antialiasing); } - void decideCoordAdjust() { - adjust_coords = !(render_hints & QPainter::Antialiasing) - && (has_alpha_pen - || (has_alpha_brush && has_pen && !has_alpha_pen) - || (cpen.style() > Qt::SolidLine)); - } void clipPolygon_dev(const QPolygonF &poly, QPolygonF *clipped_poly); void systemStateChanged(); @@ -213,7 +207,6 @@ public: uint has_non_scaling_xform : 1; uint has_custom_pen : 1; uint use_path_fallback : 1; - uint adjust_coords : 1; uint has_clipping : 1; uint adapted_brush_origin : 1; uint adapted_pen_origin : 1; diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp index 39c7bed28..3d52f26df 100644 --- a/src/gui/painting/qrasterizer.cpp +++ b/src/gui/painting/qrasterizer.cpp @@ -62,9 +62,6 @@ typedef int Q16Dot16; #define SPAN_BUFFER_SIZE 256 -#define COORD_ROUNDING 1 // 0: round up, 1: round down -#define COORD_OFFSET 32 // 26.6, 32 is half a pixel - static inline QT_FT_Vector PointToVector(const QPointF &p) { QT_FT_Vector result = { QT_FT_Pos(p.x() * 64), QT_FT_Pos(p.y() * 64) }; @@ -581,16 +578,11 @@ 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; - - 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) >> 6)); + int iBottom = qMin(m_bottom, int((b.y - 32) >> 6)); if (iTop <= iBottom) { - Q16Dot16 aFP = Q16Dot16Factor/2 + (a.x << 10) - COORD_ROUNDING; + Q16Dot16 aFP = Q16Dot16Factor/2 + (a.x << 10); if (b.x == a.x) { Line line = { qBound(m_leftFP, aFP, m_rightFP), 0, iTop, iBottom, winding }; @@ -790,13 +782,6 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, pb = npb; } - if (!d->antialiased) { - pa.rx() += (COORD_OFFSET - COORD_ROUNDING)/64.; - pa.ry() += (COORD_OFFSET - COORD_ROUNDING)/64.; - pb.rx() += (COORD_OFFSET - COORD_ROUNDING)/64.; - pb.ry() += (COORD_OFFSET - COORD_ROUNDING)/64.; - } - { // old delta const QPointF d0 = a - b; @@ -1191,8 +1176,8 @@ 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 iTopBound = qMax(d->clipRect.top(), int((min_y + 32) >> 6)); + int iBottomBound = qMin(d->clipRect.bottom(), int((max_y - 32) >> 6)); if (iTopBound > iBottomBound) return; @@ -1227,8 +1212,8 @@ void QRasterizer::rasterize(const QPainterPath &path, Qt::FillRule fillRule) QRectF bounds = path.controlPointRect(); - int iTopBound = qMax(d->clipRect.top(), int(bounds.top() + qreal(0.5) + (COORD_OFFSET - COORD_ROUNDING)/qreal(64.))); - int iBottomBound = qMin(d->clipRect.bottom(), int(bounds.bottom() - qreal(0.5) + (COORD_OFFSET - COORD_ROUNDING)/qreal(64.))); + int iTopBound = qMax(d->clipRect.top(), int(bounds.top() + qreal(0.5))); + int iBottomBound = qMin(d->clipRect.bottom(), int(bounds.bottom() - qreal(0.5))); if (iTopBound > iBottomBound) return; diff --git a/src/gui/qguicommon_p.h b/src/gui/qguicommon_p.h index b6a7ef4a5..f89fa9a63 100644 --- a/src/gui/qguicommon_p.h +++ b/src/gui/qguicommon_p.h @@ -251,9 +251,6 @@ static const char *const qt_question_xpm[] = { }; #endif -// use the same rounding as in qrasterizer.cpp (6 bit fixed point) -static const qreal aliasedCoordinateDelta = 0.5 - 0.015625; - QT_END_NAMESPACE #endif // QGUICOMMON_P_H