QSpanData: use isAffine() instead of rolling your own test
[profile/ivi/qtbase.git] / src / gui / painting / qpaintengine_raster.cpp
index 1a63ced..0e9129f 100644 (file)
@@ -1072,9 +1072,11 @@ void QRasterPaintEnginePrivate::systemStateChanged()
     exDeviceRect = deviceRect;
 
     Q_Q(QRasterPaintEngine);
-    q->state()->strokeFlags |= QPaintEngine::DirtyClipRegion;
-    q->state()->fillFlags |= QPaintEngine::DirtyClipRegion;
-    q->state()->pixmapFlags |= QPaintEngine::DirtyClipRegion;
+    if (q->state()) {
+        q->state()->strokeFlags |= QPaintEngine::DirtyClipRegion;
+        q->state()->fillFlags |= QPaintEngine::DirtyClipRegion;
+        q->state()->pixmapFlags |= QPaintEngine::DirtyClipRegion;
+    }
 }
 
 void QRasterPaintEnginePrivate::updateMatrixData(QSpanData *spanData, const QBrush &b, const QTransform &m)
@@ -2143,9 +2145,10 @@ void QRasterPaintEngine::drawImage(const QPointF &p, const QImage &img)
 
     Q_D(QRasterPaintEngine);
     QRasterPaintEngineState *s = state();
+    qreal scale = img.devicePixelRatio();
 
-    if (s->matrix.type() > QTransform::TxTranslate) {
-        drawImage(QRectF(p.x(), p.y(), img.width(), img.height()),
+    if (scale > 1.0 ||  s->matrix.type() > QTransform::TxTranslate) {
+        drawImage(QRectF(p.x(), p.y(), img.width() / scale, img.height() / scale),
                   img,
                   QRectF(0, 0, img.width(), img.height()));
     } else {
@@ -2349,6 +2352,22 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
                     return;
                 }
             } else {
+                // Test for optimized high-dpi case: 2x source on 2x target. (Could be generalized to nX.)
+                bool sourceRect2x = r.width() * 2 == sr.width() && r.height() * 2 == sr.height();
+                bool scale2x = (s->matrix.m11() == qreal(2)) && (s->matrix.m22() == qreal(2));
+                if (s->matrix.type() == QTransform::TxScale && sourceRect2x && scale2x) {
+                    SrcOverBlendFunc func = qBlendFunctions[d->rasterBuffer->format][img.format()];
+                    if (func) {
+                        QPointF pt(r.x() * 2 + s->matrix.dx(), r.y() * 2 + s->matrix.dy());
+                        if (!clip) {
+                            d->drawImage(pt, img, func, d->deviceRect, s->intOpacity, sr.toRect());
+                            return;
+                        } else if (clip->hasRectClip) {
+                            d->drawImage(pt, img, func, clip->clipRect, s->intOpacity, sr.toRect());
+                            return;
+                        }
+                    }
+                }
                 SrcOverScaleFunc func = qScaleFunctions[d->rasterBuffer->format][img.format()];
                 if (func && (!clip || clip->hasRectClip)) {
                     func(d->rasterBuffer->buffer(), d->rasterBuffer->bytesPerLine(),
@@ -2787,7 +2806,7 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
 
             alphaPenBlt(alphaMap->bits(), alphaMap->bytesPerLine(), alphaMap->depth(),
                         qFloor(positions[i].x) + offset.x(),
-                        qFloor(positions[i].y) + offset.y(),
+                        qRound(positions[i].y) + offset.y(),
                         alphaMap->width(), alphaMap->height());
 
             fontEngine->unlockAlphaMapForGlyph();
@@ -2818,7 +2837,6 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
             rightShift = 3; // divide by 8
 
         int margin = fontEngine->glyphMargin(glyphType);
-        const QFixed offs = s->flags.legacy_rounding ? QFixed::fromReal(aliasedCoordinateDelta) : QFixed();
         const uchar *bits = image.bits();
         for (int i=0; i<numGlyphs; ++i) {
 
@@ -2829,7 +2847,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 = qRound(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,
@@ -2993,7 +3011,7 @@ void QRasterPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
     ensureRasterState();
 
     QFontEngine *fontEngine = textItem->fontEngine();
-    if (shouldDrawCachedGlyphs(fontEngine, state()->matrix)) {
+    if (!supportsTransformations(fontEngine)) {
         drawCachedGlyphs(textItem->numGlyphs, textItem->glyphs, textItem->glyphPositions,
                          fontEngine);
     } else if (state()->matrix.type() < QTransform::TxProject) {
@@ -3292,7 +3310,7 @@ bool QRasterPaintEngine::supportsTransformations(QFontEngine *fontEngine) const
 */
 bool QRasterPaintEngine::supportsTransformations(QFontEngine *fontEngine, const QTransform &m) const
 {
-    if (m.type() >= QTransform::TxProject)
+    if (fontEngine->supportsTransformations(m))
         return true;
 
     return !shouldDrawCachedGlyphs(fontEngine, m);
@@ -4570,7 +4588,7 @@ void QSpanData::setupMatrix(const QTransform &matrix, int bilin)
     txop = inv.type();
     bilinear = bilin;
 
-    const bool affine = !m13 && !m23;
+    const bool affine = inv.isAffine();
     fast_matrix = affine
         && m11 * m11 + m21 * m21 < 1e4
         && m12 * m12 + m22 * m22 < 1e4