get rid of aliased coordinate delta

Signed-off-by: Ivailo Monev <xakepa10@laimg.moc>
This commit is contained in:
Ivailo Monev 2019-05-13 20:01:54 +00:00
parent 142d67c13e
commit e032708773
5 changed files with 35 additions and 74 deletions

View file

@ -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<QFontEngineFT *>(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,

View file

@ -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<QPointF> 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<XPoint> 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,

View file

@ -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;

View file

@ -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;

View file

@ -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