From d690b141064541d6fcc2a9608308f39435a89213 Mon Sep 17 00:00:00 2001 From: aavit Date: Thu, 19 May 2011 09:27:19 +0200 Subject: Revert "Fix how subpixel positions are intepreted in an aliased grid." This reverts commit 69fc9e594e6d5da87bff42707973683f84b67c93. Conflicts: src/gui/painting/qpaintengine_raster.cpp src/gui/painting/qrasterizer.cpp (cherry picked from commit f8e85838c5531b56c2175cbdb9c24db426f7fd89) Change-Id: I4f936404000e6fa88887d0fbe3fbde92c8edd259 Reviewed-on: http://codereview.qt.nokia.com/603 Reviewed-by: Qt Sanity Bot Reviewed-by: Lars Knoll --- src/gui/painting/qoutlinemapper.cpp | 9 +++++++ src/gui/painting/qoutlinemapper_p.h | 8 ++++++- src/gui/painting/qpaintengine_raster.cpp | 40 ++++++++++++++++++++++---------- src/gui/painting/qrasterizer.cpp | 4 ++-- 4 files changed, 46 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/gui/painting/qoutlinemapper.cpp b/src/gui/painting/qoutlinemapper.cpp index 7c17c1b46e..8b607b28b8 100644 --- a/src/gui/painting/qoutlinemapper.cpp +++ b/src/gui/painting/qoutlinemapper.cpp @@ -47,6 +47,8 @@ QT_BEGIN_NAMESPACE +static const qreal aliasedCoordinateDelta = 0.5 - 0.015625; + #define qreal_to_fixed_26_6(f) (int(f * 64)) @@ -214,6 +216,13 @@ void QOutlineMapper::endOutline() elements = m_elements_dev.data(); } + if (m_round_coords) { + // round coordinates to match outlines drawn with drawLine_midpoint_i + for (int i = 0; i < m_elements.size(); ++i) + elements[i] = QPointF(qFloor(elements[i].x() + aliasedCoordinateDelta), + qFloor(elements[i].y() + aliasedCoordinateDelta)); + } + controlPointRect = boundingRect(elements, element_count); #ifdef QT_DEBUG_CONVERT diff --git a/src/gui/painting/qoutlinemapper_p.h b/src/gui/painting/qoutlinemapper_p.h index 1432d6fc4b..388858ca44 100644 --- a/src/gui/painting/qoutlinemapper_p.h +++ b/src/gui/painting/qoutlinemapper_p.h @@ -95,7 +95,8 @@ public: m_tags(0), m_contours(0), m_polygon_dev(0), - m_in_clip_elements(false) + m_in_clip_elements(false), + m_round_coords(false) { } @@ -201,6 +202,8 @@ public: QT_FT_Outline *convertPath(const QPainterPath &path); QT_FT_Outline *convertPath(const QVectorPath &path); + void setCoordinateRounding(bool coordinateRounding) { m_round_coords = coordinateRounding; } + inline QPainterPath::ElementType *elementTypes() const { return m_element_types.size() == 0 ? 0 : m_element_types.data(); } public: @@ -234,6 +237,9 @@ public: bool m_valid; bool m_in_clip_elements; + +private: + bool m_round_coords; }; QT_END_NAMESPACE diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index e2ce35af64..135db20e27 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -127,6 +127,9 @@ void dumpClip(int width, int height, const QClipData *clip); // 4 pixels. #define int_dim(pos, dim) (int(pos+dim) - int(pos)) +// use the same rounding as in qrasterizer.cpp (6 bit fixed point) +static const qreal aliasedCoordinateDelta = 0.5 - 0.015625; + #ifdef Q_WS_WIN extern bool qt_cleartype_enabled; #endif @@ -1666,10 +1669,10 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen) static inline QRect toNormalizedFillRect(const QRectF &rect) { - int x1 = qRound(rect.x()); - int y1 = qRound(rect.y()); - int x2 = qRound(rect.right()); - int y2 = qRound(rect.bottom()); + int x1 = qRound(rect.x() + aliasedCoordinateDelta); + int y1 = qRound(rect.y() + aliasedCoordinateDelta); + int x2 = qRound(rect.right() + aliasedCoordinateDelta); + int y2 = qRound(rect.bottom() + aliasedCoordinateDelta); if (x2 < x1) qSwap(x1, x2); @@ -1939,7 +1942,9 @@ void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, Poly // Do the fill... ensureBrush(); if (s->brushData.blend) { + d->outlineMapper->setCoordinateRounding(s->penData.blend && s->flags.fast_pen && s->lastPen.brush().isOpaque()); fillPolygon(points, pointCount, mode); + d->outlineMapper->setCoordinateRounding(false); } } @@ -1986,6 +1991,7 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg if (s->brushData.blend) { // Compose polygon fill.., ensureOutlineMapper(); + d->outlineMapper->setCoordinateRounding(s->penData.blend != 0); d->outlineMapper->beginOutline(mode == WindingMode ? Qt::WindingFill : Qt::OddEvenFill); d->outlineMapper->moveTo(*points); const QPoint *p = points; @@ -1999,6 +2005,7 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg ProcessSpans brushBlend = d->getBrushFunc(d->outlineMapper->controlPointRect, &s->brushData); d->rasterize(d->outlineMapper->outline(), brushBlend, &s->brushData, d->rasterBuffer.data()); + d->outlineMapper->setCoordinateRounding(false); } } @@ -2248,7 +2255,10 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe int sr_b = qCeil(sr.bottom()) - 1; if (s->matrix.type() <= QTransform::TxScale && !s->flags.antialiased && sr_l == sr_r && sr_t == sr_b) { + // 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); @@ -2392,9 +2402,11 @@ 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); - const QPointF b = s->matrix.map((rect.topRight() + rect.bottomRight()) * 0.5f); + 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; if (s->flags.tx_noshear) d->rasterizer->rasterizeLine(a, b, rect.height() / rect.width()); @@ -2403,12 +2415,13 @@ 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(), m.m32(), m.m33()); + m.m31() - offs, m.m32() - offs, m.m33()); fillPath(path, &d->image_filler_xform); s->matrix = m; } else { @@ -2860,6 +2873,7 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, rightShift = 3; // divide by 8 int margin = cache->glyphMargin(); + const QFixed offs = QFixed::fromReal(aliasedCoordinateDelta); const uchar *bits = image.bits(); for (int i=0; isetFontScale(matrix.m11()); ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); + const QFixed aliasDelta = QFixed::fromReal(aliasedCoordinateDelta); for (int i=0; igetCharacterData(glyphs[i], tmetrics, glyphBitmapBytes, glyphBitmapSize); - const int x = qFloor(positions[i].x + tmetrics.HorizBearingX()); - const int y = qFloor(positions[i].y - tmetrics.HorizBearingY()); + const int x = qFloor(positions[i].x + metrics.x + aliasDelta); + const int y = qFloor(positions[i].y + metrics.y + aliasDelta); alphaPenBlt(glyphBitmapBytes, glyphBitmapSize.iWidth, 8, x, y, glyphBitmapSize.iWidth, glyphBitmapSize.iHeight); } @@ -3086,7 +3101,7 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte || (fontEngine->type() == QFontEngine::Proxy && !(static_cast(fontEngine)->drawAsOutline())) )) { - fontEngine->draw(this, qFloor(p.x()), qFloor(p.y()), ti); + fontEngine->draw(this, qFloor(p.x() + aliasedCoordinateDelta), qFloor(p.y() + aliasedCoordinateDelta), ti); return; } #endif // Q_WS_QWS @@ -3109,6 +3124,7 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte for(int i = 0; i < glyphs.size(); i++) { QImage img = fontEngine->alphaMapForGlyph(glyphs[i]); glyph_metrics_t metrics = fontEngine->boundingBox(glyphs[i]); + // ### hm, perhaps an QFixed offs = QFixed::fromReal(aliasedCoordinateDelta) is needed here? alphaPenBlt(img.bits(), img.bytesPerLine(), img.depth(), qRound(positions[i].x + metrics.x), qRound(positions[i].y + metrics.y), diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp index 6c5edbc44d..1d3f581b88 100644 --- a/src/gui/painting/qrasterizer.cpp +++ b/src/gui/painting/qrasterizer.cpp @@ -62,8 +62,8 @@ typedef int Q16Dot16; #define SPAN_BUFFER_SIZE 256 -#define COORD_ROUNDING 0 // 0: round up, 1: round down -#define COORD_OFFSET 0 // 26.6, 32 is half a pixel +#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) { -- cgit v1.2.3